|
@@ -273,6 +273,42 @@ static void renew_lease(const struct nfs_server *server, unsigned long timestamp
|
|
|
|
|
|
#if defined(CONFIG_NFS_V4_1)
|
|
|
|
|
|
+/*
|
|
|
+ * 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 -1.
|
|
|
+ */
|
|
|
+static void
|
|
|
+nfs4_free_slot(struct nfs4_slot_table *tbl, u8 free_slotid)
|
|
|
+{
|
|
|
+ int slotid = free_slotid;
|
|
|
+
|
|
|
+ spin_lock(&tbl->slot_tbl_lock);
|
|
|
+ /* 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) {
|
|
|
+ slotid = find_last_bit(tbl->used_slots, tbl->max_slots);
|
|
|
+ if (slotid >= 0 && slotid < tbl->max_slots)
|
|
|
+ tbl->highest_used_slotid = slotid;
|
|
|
+ else
|
|
|
+ tbl->highest_used_slotid = -1;
|
|
|
+ }
|
|
|
+ rpc_wake_up_next(&tbl->slot_tbl_waitq);
|
|
|
+ spin_unlock(&tbl->slot_tbl_lock);
|
|
|
+ dprintk("%s: free_slotid %u highest_used_slotid %d\n", __func__,
|
|
|
+ free_slotid, tbl->highest_used_slotid);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* nfs4_find_slot - efficiently look for a free slot
|
|
|
*
|