aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2015-03-09 15:23:35 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2015-03-27 12:32:24 -0400
commit84a80f62f71beac20a426709c04b49f2bd352291 (patch)
tree8a6da9805e36e26425a2e482e6233dabebca60ca /fs/nfs
parent2854475f6c612d59901d51c358abd05643278b53 (diff)
NFSv4.1: Convert pNFS deviceid to use kfree_rcu()
Use of synchronize_rcu() when unmounting and potentially freeing a lot of deviceids is problematic. There really is no reason why we can't just use kfree_rcu() here. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r--fs/nfs/blocklayout/dev.c2
-rw-r--r--fs/nfs/filelayout/filelayoutdev.c2
-rw-r--r--fs/nfs/flexfilelayout/flexfilelayoutdev.c2
-rw-r--r--fs/nfs/objlayout/objio_osd.c2
-rw-r--r--fs/nfs/pnfs.h1
-rw-r--r--fs/nfs/pnfs_dev.c6
6 files changed, 7 insertions, 8 deletions
diff --git a/fs/nfs/blocklayout/dev.c b/fs/nfs/blocklayout/dev.c
index 5aed4f98df41..e535599a0719 100644
--- a/fs/nfs/blocklayout/dev.c
+++ b/fs/nfs/blocklayout/dev.c
@@ -33,7 +33,7 @@ bl_free_deviceid_node(struct nfs4_deviceid_node *d)
33 container_of(d, struct pnfs_block_dev, node); 33 container_of(d, struct pnfs_block_dev, node);
34 34
35 bl_free_device(dev); 35 bl_free_device(dev);
36 kfree(dev); 36 kfree_rcu(dev, node.rcu);
37} 37}
38 38
39static int 39static int
diff --git a/fs/nfs/filelayout/filelayoutdev.c b/fs/nfs/filelayout/filelayoutdev.c
index 4f372e224603..4946ef40ba87 100644
--- a/fs/nfs/filelayout/filelayoutdev.c
+++ b/fs/nfs/filelayout/filelayoutdev.c
@@ -55,7 +55,7 @@ nfs4_fl_free_deviceid(struct nfs4_file_layout_dsaddr *dsaddr)
55 nfs4_pnfs_ds_put(ds); 55 nfs4_pnfs_ds_put(ds);
56 } 56 }
57 kfree(dsaddr->stripe_indices); 57 kfree(dsaddr->stripe_indices);
58 kfree(dsaddr); 58 kfree_rcu(dsaddr, id_node.rcu);
59} 59}
60 60
61/* Decode opaque device data and return the result */ 61/* Decode opaque device data and return the result */
diff --git a/fs/nfs/flexfilelayout/flexfilelayoutdev.c b/fs/nfs/flexfilelayout/flexfilelayoutdev.c
index e2c01f204a95..77a2d026aa12 100644
--- a/fs/nfs/flexfilelayout/flexfilelayoutdev.c
+++ b/fs/nfs/flexfilelayout/flexfilelayoutdev.c
@@ -30,7 +30,7 @@ void nfs4_ff_layout_free_deviceid(struct nfs4_ff_layout_ds *mirror_ds)
30{ 30{
31 nfs4_print_deviceid(&mirror_ds->id_node.deviceid); 31 nfs4_print_deviceid(&mirror_ds->id_node.deviceid);
32 nfs4_pnfs_ds_put(mirror_ds->ds); 32 nfs4_pnfs_ds_put(mirror_ds->ds);
33 kfree(mirror_ds); 33 kfree_rcu(mirror_ds, id_node.rcu);
34} 34}
35 35
36/* Decode opaque device data and construct new_ds using it */ 36/* Decode opaque device data and construct new_ds using it */
diff --git a/fs/nfs/objlayout/objio_osd.c b/fs/nfs/objlayout/objio_osd.c
index 24e1d7403c0b..8b5e0e687d5e 100644
--- a/fs/nfs/objlayout/objio_osd.c
+++ b/fs/nfs/objlayout/objio_osd.c
@@ -57,7 +57,7 @@ objio_free_deviceid_node(struct nfs4_deviceid_node *d)
57 57
58 dprintk("%s: free od=%p\n", __func__, de->od.od); 58 dprintk("%s: free od=%p\n", __func__, de->od.od);
59 osduld_put_device(de->od.od); 59 osduld_put_device(de->od.od);
60 kfree(de); 60 kfree_rcu(d, rcu);
61} 61}
62 62
63struct objio_segment { 63struct objio_segment {
diff --git a/fs/nfs/pnfs.h b/fs/nfs/pnfs.h
index 635f0865671c..a1fc16c971a7 100644
--- a/fs/nfs/pnfs.h
+++ b/fs/nfs/pnfs.h
@@ -302,6 +302,7 @@ struct nfs4_deviceid_node {
302 unsigned long flags; 302 unsigned long flags;
303 unsigned long timestamp_unavailable; 303 unsigned long timestamp_unavailable;
304 struct nfs4_deviceid deviceid; 304 struct nfs4_deviceid deviceid;
305 struct rcu_head rcu;
305 atomic_t ref; 306 atomic_t ref;
306}; 307};
307 308
diff --git a/fs/nfs/pnfs_dev.c b/fs/nfs/pnfs_dev.c
index aa2ec0015183..bf23ac97d57d 100644
--- a/fs/nfs/pnfs_dev.c
+++ b/fs/nfs/pnfs_dev.c
@@ -175,8 +175,8 @@ __nfs4_find_get_deviceid(struct nfs_server *server,
175 rcu_read_lock(); 175 rcu_read_lock();
176 d = _lookup_deviceid(server->pnfs_curr_ld, server->nfs_client, id, 176 d = _lookup_deviceid(server->pnfs_curr_ld, server->nfs_client, id,
177 hash); 177 hash);
178 if (d != NULL) 178 if (d != NULL && !atomic_inc_not_zero(&d->ref))
179 atomic_inc(&d->ref); 179 d = NULL;
180 rcu_read_unlock(); 180 rcu_read_unlock();
181 return d; 181 return d;
182} 182}
@@ -236,7 +236,6 @@ nfs4_delete_deviceid(const struct pnfs_layoutdriver_type *ld,
236 } 236 }
237 hlist_del_init_rcu(&d->node); 237 hlist_del_init_rcu(&d->node);
238 spin_unlock(&nfs4_deviceid_lock); 238 spin_unlock(&nfs4_deviceid_lock);
239 synchronize_rcu();
240 239
241 /* balance the initial ref set in pnfs_insert_deviceid */ 240 /* balance the initial ref set in pnfs_insert_deviceid */
242 if (atomic_dec_and_test(&d->ref)) 241 if (atomic_dec_and_test(&d->ref))
@@ -321,7 +320,6 @@ _deviceid_purge_client(const struct nfs_client *clp, long hash)
321 if (hlist_empty(&tmp)) 320 if (hlist_empty(&tmp))
322 return; 321 return;
323 322
324 synchronize_rcu();
325 while (!hlist_empty(&tmp)) { 323 while (!hlist_empty(&tmp)) {
326 d = hlist_entry(tmp.first, struct nfs4_deviceid_node, tmpnode); 324 d = hlist_entry(tmp.first, struct nfs4_deviceid_node, tmpnode);
327 hlist_del(&d->tmpnode); 325 hlist_del(&d->tmpnode);