aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4proc.c
diff options
context:
space:
mode:
authorAndy Adamson <andros@netapp.com>2009-04-01 09:22:16 -0400
committerBenny Halevy <bhalevy@panasas.com>2009-06-17 13:46:39 -0400
commite2c4ab3ce2ecc527672bd7e29a594c50d3ec0477 (patch)
tree12043a6659ebbd9f4f51c4b0079e652db9ed8ed4 /fs/nfs/nfs4proc.c
parentfbcd4abcb3841f85578985c09c6df85aa41b0ae8 (diff)
nfs41: free slot
Free a slot in the slot table. Mark the slot as free in the bitmap-based allocation table by clearing a bit corresponding to the slotid. Update lowest_free_slotid if freed slotid is lower than that. Update highest_used_slotid. In the case the freed slotid equals the highest_used_slotid, scan downwards for the next highest used slotid using the optimized fls* functions. Finally, wake up thread waiting on slot_tbl_waitq for a free slot to become available. Signed-off-by: Benny Halevy <bhalevy@panasas.com> [nfs41: free slot use slotid] Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Benny Halevy <bhalevy@panasas.com> [nfs41: use find_first_zero_bit for nfs4_find_slot] While at it, obliterate lowest_free_slotid and fix-up related comments. As per review comment 21/85. Signed-off-by: Benny Halevy <bhalevy@panasas.com> [nfs41: use __clear_bit for nfs4_free_slot] While at it, fix-up function comment. Part of review comment 22/85. Signed-off-by: Benny Halevy <bhalevy@panasas.com> [nfs41: use find_last_bit in nfs4_free_slot to determine highest used slot.] Signed-off-by: Benny Halevy <bhalevy@panasas.com> [nfs41: rpc_sleep_on slot_tbl_waitq must be called under slot_tbl_lock] Otherwise there's a race (we've hit) with nfs4_free_slot where nfs41_setup_sequence sees a full slot table, unlocks slot_tbl_lock, nfs4_free_slots happen concurrently and call rpc_wake_up_next where there's nobody to wake up yet, context goes back to nfs41_setup_sequence which goes to sleep when the slot table is actually empty now and there's no-one to wake it up anymore. Signed-off-by: Benny Halevy <bhalevy@panasas.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/nfs4proc.c')
-rw-r--r--fs/nfs/nfs4proc.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
index c9618080317e..b6308f6740ec 100644
--- a/fs/nfs/nfs4proc.c
+++ b/fs/nfs/nfs4proc.c
@@ -274,6 +274,42 @@ static void renew_lease(const struct nfs_server *server, unsigned long timestamp
274#if defined(CONFIG_NFS_V4_1) 274#if defined(CONFIG_NFS_V4_1)
275 275
276/* 276/*
277 * nfs4_free_slot - free a slot and efficiently update slot table.
278 *
279 * freeing a slot is trivially done by clearing its respective bit
280 * in the bitmap.
281 * If the freed slotid equals highest_used_slotid we want to update it
282 * so that the server would be able to size down the slot table if needed,
283 * otherwise we know that the highest_used_slotid is still in use.
284 * When updating highest_used_slotid there may be "holes" in the bitmap
285 * so we need to scan down from highest_used_slotid to 0 looking for the now
286 * highest slotid in use.
287 * If none found, highest_used_slotid is set to -1.
288 */
289static void
290nfs4_free_slot(struct nfs4_slot_table *tbl, u8 free_slotid)
291{
292 int slotid = free_slotid;
293
294 spin_lock(&tbl->slot_tbl_lock);
295 /* clear used bit in bitmap */
296 __clear_bit(slotid, tbl->used_slots);
297
298 /* update highest_used_slotid when it is freed */
299 if (slotid == tbl->highest_used_slotid) {
300 slotid = find_last_bit(tbl->used_slots, tbl->max_slots);
301 if (slotid >= 0 && slotid < tbl->max_slots)
302 tbl->highest_used_slotid = slotid;
303 else
304 tbl->highest_used_slotid = -1;
305 }
306 rpc_wake_up_next(&tbl->slot_tbl_waitq);
307 spin_unlock(&tbl->slot_tbl_lock);
308 dprintk("%s: free_slotid %u highest_used_slotid %d\n", __func__,
309 free_slotid, tbl->highest_used_slotid);
310}
311
312/*
277 * nfs4_find_slot - efficiently look for a free slot 313 * nfs4_find_slot - efficiently look for a free slot
278 * 314 *
279 * nfs4_find_slot looks for an unset bit in the used_slots bitmap. 315 * nfs4_find_slot looks for an unset bit in the used_slots bitmap.