diff options
author | Benny Halevy <bhalevy@panasas.com> | 2009-04-01 09:22:14 -0400 |
---|---|---|
committer | Benny Halevy <bhalevy@panasas.com> | 2009-06-17 13:46:37 -0400 |
commit | 510b81756f18922a4c5b555e8145f4fed5beb569 (patch) | |
tree | 9253ad2063b37292b3cf8c7425cbf6882807882a /fs/nfs/nfs4proc.c | |
parent | ce5039c1be1fd04c2d9b1af80d41a6d003f2e20c (diff) |
nfs41: find slot
Find a free slot using bitmap-based allocation.
Use the optimized ffz function to find a zero bit
in the bitmap that indicates a free slot, starting
the search from the 'lowest_free_slotid' position.
If found, mark the slot as used in the bitmap, get
the slot's slotid and seqid, and update max_slotid
to be used by the SEQUENCE operation.
Also, update lowest_free_slotid for next search.
If no free slot was found the caller has to wait
for a free slot (outside the scope of this function)
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfs41: find slot return slotid]
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[use find_first_zero_bit for nfs4_find_slot as per review comment 21/85.]
[use NFS4_MAX_SLOT_TABLE rather than NFS4_NO_SLOT]
[nfs41: rpc_sleep_on slot_tbl_waitq must be called under slot_tbl_lock]
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.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 90aed76e593b..a0946a0d116e 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -273,6 +273,39 @@ static void renew_lease(const struct nfs_server *server, unsigned long timestamp | |||
273 | 273 | ||
274 | #if defined(CONFIG_NFS_V4_1) | 274 | #if defined(CONFIG_NFS_V4_1) |
275 | 275 | ||
276 | /* | ||
277 | * nfs4_find_slot - efficiently look for a free slot | ||
278 | * | ||
279 | * nfs4_find_slot looks for an unset bit in the used_slots bitmap. | ||
280 | * If found, we mark the slot as used, update the highest_used_slotid, | ||
281 | * and respectively set up the sequence operation args. | ||
282 | * The slot number is returned if found, or NFS4_MAX_SLOT_TABLE otherwise. | ||
283 | */ | ||
284 | static u8 | ||
285 | nfs4_find_slot(struct nfs4_slot_table *tbl, struct rpc_task *task) | ||
286 | { | ||
287 | int slotid; | ||
288 | u8 ret_id = NFS4_MAX_SLOT_TABLE; | ||
289 | BUILD_BUG_ON((u8)NFS4_MAX_SLOT_TABLE != (int)NFS4_MAX_SLOT_TABLE); | ||
290 | |||
291 | spin_lock(&tbl->slot_tbl_lock); | ||
292 | dprintk("--> %s used_slots=%04lx highest_used=%d max_slots=%d\n", | ||
293 | __func__, tbl->used_slots[0], tbl->highest_used_slotid, | ||
294 | tbl->max_slots); | ||
295 | slotid = find_first_zero_bit(tbl->used_slots, tbl->max_slots); | ||
296 | if (slotid >= tbl->max_slots) | ||
297 | goto out; | ||
298 | __set_bit(slotid, tbl->used_slots); | ||
299 | if (slotid > tbl->highest_used_slotid) | ||
300 | tbl->highest_used_slotid = slotid; | ||
301 | ret_id = slotid; | ||
302 | out: | ||
303 | dprintk("<-- %s used_slots=%04lx highest_used=%d slotid=%d \n", | ||
304 | __func__, tbl->used_slots[0], tbl->highest_used_slotid, ret_id); | ||
305 | spin_unlock(&tbl->slot_tbl_lock); | ||
306 | return ret_id; | ||
307 | } | ||
308 | |||
276 | static int nfs41_setup_sequence(struct nfs4_session *session, | 309 | static int nfs41_setup_sequence(struct nfs4_session *session, |
277 | struct nfs4_sequence_args *args, | 310 | struct nfs4_sequence_args *args, |
278 | struct nfs4_sequence_res *res, | 311 | struct nfs4_sequence_res *res, |