static void nfs4_callback_free_slot(struct nfs4_session *session) { struct nfs4_slot_table *tbl = &session->bc_slot_table; spin_lock(&tbl->slot_tbl_lock); /* * Let the state manager know callback processing done. * A single slot, so highest used slotid is either 0 or -1 */ tbl->highest_used_slotid = NFS4_NO_SLOT; nfs4_slot_tbl_drain_complete(tbl); spin_unlock(&tbl->slot_tbl_lock); }
/* * nfs4_free_slot - free a slot and efficiently update slot table. * * freeing a slot is trivially done by clearing its respective bit * in the bitmap. * If the freed slotid equals highest_used_slotid we want to update it * so that the server would be able to size down the slot table if needed, * otherwise we know that the highest_used_slotid is still in use. * When updating highest_used_slotid there may be "holes" in the bitmap * so we need to scan down from highest_used_slotid to 0 looking for the now * highest slotid in use. * If none found, highest_used_slotid is set to NFS4_NO_SLOT. * * Must be called while holding tbl->slot_tbl_lock */ void nfs4_free_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot) { u32 slotid = slot->slot_nr; /* clear used bit in bitmap */ __clear_bit(slotid, tbl->used_slots); /* update highest_used_slotid when it is freed */ if (slotid == tbl->highest_used_slotid) { u32 new_max = find_last_bit(tbl->used_slots, slotid); if (new_max < slotid) tbl->highest_used_slotid = new_max; else { tbl->highest_used_slotid = NFS4_NO_SLOT; nfs4_slot_tbl_drain_complete(tbl); } } dprintk("%s: slotid %u highest_used_slotid %u\n", __func__, slotid, tbl->highest_used_slotid); }