diff options
Diffstat (limited to 'fs/nfs/pnfs_dev.c')
-rw-r--r-- | fs/nfs/pnfs_dev.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/fs/nfs/pnfs_dev.c b/fs/nfs/pnfs_dev.c index c65e133ce9c0..5944d4b369a2 100644 --- a/fs/nfs/pnfs_dev.c +++ b/fs/nfs/pnfs_dev.c | |||
@@ -174,6 +174,7 @@ nfs4_init_deviceid_node(struct nfs4_deviceid_node *d, | |||
174 | const struct nfs4_deviceid *id) | 174 | const struct nfs4_deviceid *id) |
175 | { | 175 | { |
176 | INIT_HLIST_NODE(&d->node); | 176 | INIT_HLIST_NODE(&d->node); |
177 | INIT_HLIST_NODE(&d->tmpnode); | ||
177 | d->ld = ld; | 178 | d->ld = ld; |
178 | d->nfs_client = nfs_client; | 179 | d->nfs_client = nfs_client; |
179 | d->deviceid = *id; | 180 | d->deviceid = *id; |
@@ -238,24 +239,29 @@ static void | |||
238 | _deviceid_purge_client(const struct nfs_client *clp, long hash) | 239 | _deviceid_purge_client(const struct nfs_client *clp, long hash) |
239 | { | 240 | { |
240 | struct nfs4_deviceid_node *d; | 241 | struct nfs4_deviceid_node *d; |
241 | struct hlist_node *n, *next; | 242 | struct hlist_node *n; |
242 | HLIST_HEAD(tmp); | 243 | HLIST_HEAD(tmp); |
243 | 244 | ||
245 | spin_lock(&nfs4_deviceid_lock); | ||
244 | rcu_read_lock(); | 246 | rcu_read_lock(); |
245 | hlist_for_each_entry_rcu(d, n, &nfs4_deviceid_cache[hash], node) | 247 | hlist_for_each_entry_rcu(d, n, &nfs4_deviceid_cache[hash], node) |
246 | if (d->nfs_client == clp && atomic_read(&d->ref)) { | 248 | if (d->nfs_client == clp && atomic_read(&d->ref)) { |
247 | hlist_del_init_rcu(&d->node); | 249 | hlist_del_init_rcu(&d->node); |
248 | hlist_add_head(&d->node, &tmp); | 250 | hlist_add_head(&d->tmpnode, &tmp); |
249 | } | 251 | } |
250 | rcu_read_unlock(); | 252 | rcu_read_unlock(); |
253 | spin_unlock(&nfs4_deviceid_lock); | ||
251 | 254 | ||
252 | if (hlist_empty(&tmp)) | 255 | if (hlist_empty(&tmp)) |
253 | return; | 256 | return; |
254 | 257 | ||
255 | synchronize_rcu(); | 258 | synchronize_rcu(); |
256 | hlist_for_each_entry_safe(d, n, next, &tmp, node) | 259 | while (!hlist_empty(&tmp)) { |
260 | d = hlist_entry(tmp.first, struct nfs4_deviceid_node, tmpnode); | ||
261 | hlist_del(&d->tmpnode); | ||
257 | if (atomic_dec_and_test(&d->ref)) | 262 | if (atomic_dec_and_test(&d->ref)) |
258 | d->ld->free_deviceid_node(d); | 263 | d->ld->free_deviceid_node(d); |
264 | } | ||
259 | } | 265 | } |
260 | 266 | ||
261 | void | 267 | void |
@@ -263,8 +269,8 @@ nfs4_deviceid_purge_client(const struct nfs_client *clp) | |||
263 | { | 269 | { |
264 | long h; | 270 | long h; |
265 | 271 | ||
266 | spin_lock(&nfs4_deviceid_lock); | 272 | if (!(clp->cl_exchange_flags & EXCHGID4_FLAG_USE_PNFS_MDS)) |
273 | return; | ||
267 | for (h = 0; h < NFS4_DEVICE_ID_HASH_SIZE; h++) | 274 | for (h = 0; h < NFS4_DEVICE_ID_HASH_SIZE; h++) |
268 | _deviceid_purge_client(clp, h); | 275 | _deviceid_purge_client(clp, h); |
269 | spin_unlock(&nfs4_deviceid_lock); | ||
270 | } | 276 | } |