diff options
Diffstat (limited to 'fs/nfs/nfs4session.c')
-rw-r--r-- | fs/nfs/nfs4session.c | 54 |
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 | ||
138 | static 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 | */ | ||
155 | bool 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 | */ | ||
168 | struct 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 | |||
167 | out: | ||
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); |