diff options
author | Trond Myklebust <trond.myklebust@primarydata.com> | 2015-03-09 15:23:35 -0400 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@primarydata.com> | 2015-03-27 12:32:24 -0400 |
commit | 84a80f62f71beac20a426709c04b49f2bd352291 (patch) | |
tree | 8a6da9805e36e26425a2e482e6233dabebca60ca /fs/nfs | |
parent | 2854475f6c612d59901d51c358abd05643278b53 (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.c | 2 | ||||
-rw-r--r-- | fs/nfs/filelayout/filelayoutdev.c | 2 | ||||
-rw-r--r-- | fs/nfs/flexfilelayout/flexfilelayoutdev.c | 2 | ||||
-rw-r--r-- | fs/nfs/objlayout/objio_osd.c | 2 | ||||
-rw-r--r-- | fs/nfs/pnfs.h | 1 | ||||
-rw-r--r-- | fs/nfs/pnfs_dev.c | 6 |
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 | ||
39 | static int | 39 | static 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 | ||
63 | struct objio_segment { | 63 | struct 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); |