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);
}
Ejemplo n.º 2
0
/*
 * 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);
}