aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4session.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4session.c')
-rw-r--r--fs/nfs/nfs4session.c54
1 files changed, 42 insertions, 12 deletions
diff --git a/fs/nfs/nfs4session.c b/fs/nfs/nfs4session.c
index e23366effcfb..332d06e64fa9 100644
--- a/fs/nfs/nfs4session.c
+++ b/fs/nfs/nfs4session.c
@@ -135,6 +135,43 @@ static struct nfs4_slot *nfs4_find_or_create_slot(struct nfs4_slot_table *tbl,
135 return ERR_PTR(-ENOMEM); 135 return ERR_PTR(-ENOMEM);
136} 136}
137 137
138static void nfs4_lock_slot(struct nfs4_slot_table *tbl,
139 struct nfs4_slot *slot)
140{
141 u32 slotid = slot->slot_nr;
142
143 __set_bit(slotid, tbl->used_slots);
144 if (slotid > tbl->highest_used_slotid ||
145 tbl->highest_used_slotid == NFS4_NO_SLOT)
146 tbl->highest_used_slotid = slotid;
147 slot->generation = tbl->generation;
148}
149
150/*
151 * nfs4_try_to_lock_slot - Given a slot try to allocate it
152 *
153 * Note: must be called with the slot_tbl_lock held.
154 */
155bool nfs4_try_to_lock_slot(struct nfs4_slot_table *tbl, struct nfs4_slot *slot)
156{
157 if (nfs4_test_locked_slot(tbl, slot->slot_nr))
158 return false;
159 nfs4_lock_slot(tbl, slot);
160 return true;
161}
162
163/*
164 * nfs4_lookup_slot - Find a slot but don't allocate it
165 *
166 * Note: must be called with the slot_tbl_lock held.
167 */
168struct nfs4_slot *nfs4_lookup_slot(struct nfs4_slot_table *tbl, u32 slotid)
169{
170 if (slotid <= tbl->max_slotid)
171 return nfs4_find_or_create_slot(tbl, slotid, 1, GFP_NOWAIT);
172 return ERR_PTR(-E2BIG);
173}
174
138/* 175/*
139 * nfs4_alloc_slot - efficiently look for a free slot 176 * nfs4_alloc_slot - efficiently look for a free slot
140 * 177 *
@@ -153,18 +190,11 @@ struct nfs4_slot *nfs4_alloc_slot(struct nfs4_slot_table *tbl)
153 __func__, tbl->used_slots[0], tbl->highest_used_slotid, 190 __func__, tbl->used_slots[0], tbl->highest_used_slotid,
154 tbl->max_slotid + 1); 191 tbl->max_slotid + 1);
155 slotid = find_first_zero_bit(tbl->used_slots, tbl->max_slotid + 1); 192 slotid = find_first_zero_bit(tbl->used_slots, tbl->max_slotid + 1);
156 if (slotid > tbl->max_slotid) 193 if (slotid <= tbl->max_slotid) {
157 goto out; 194 ret = nfs4_find_or_create_slot(tbl, slotid, 1, GFP_NOWAIT);
158 ret = nfs4_find_or_create_slot(tbl, slotid, 1, GFP_NOWAIT); 195 if (!IS_ERR(ret))
159 if (IS_ERR(ret)) 196 nfs4_lock_slot(tbl, ret);
160 goto out; 197 }
161 __set_bit(slotid, tbl->used_slots);
162 if (slotid > tbl->highest_used_slotid ||
163 tbl->highest_used_slotid == NFS4_NO_SLOT)
164 tbl->highest_used_slotid = slotid;
165 ret->generation = tbl->generation;
166
167out:
168 dprintk("<-- %s used_slots=%04lx highest_used=%u slotid=%u\n", 198 dprintk("<-- %s used_slots=%04lx highest_used=%u slotid=%u\n",
169 __func__, tbl->used_slots[0], tbl->highest_used_slotid, 199 __func__, tbl->used_slots[0], tbl->highest_used_slotid,
170 !IS_ERR(ret) ? ret->slot_nr : NFS4_NO_SLOT); 200 !IS_ERR(ret) ? ret->slot_nr : NFS4_NO_SLOT);