diff options
author | Jeff Layton <jlayton@poochiereds.net> | 2016-04-21 20:51:58 -0400 |
---|---|---|
committer | Anna Schumaker <Anna.Schumaker@Netapp.com> | 2016-05-09 09:05:40 -0400 |
commit | 57f3f4c0cd50e90aa92eec20d9c309dd67c594a5 (patch) | |
tree | 19652693dacecdead7fecf42dc3a1bb64051eca7 /fs/nfs | |
parent | 547a637630c61b9e1dae9abce2b44ce7076244af (diff) |
nfs: have ff_layout_get_ds_cred take a reference to the cred
In later patches, we're going to want to allow the creds to be updated
when we get a new layout with updated creds. Have this function take
a reference to the cred that is later put once the call has been
dispatched.
Also, prepare for this change by ensuring we follow RCU rules when
getting a reference to the cred as well.
Signed-off-by: Jeff Layton <jeff.layton@primarydata.com>
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/flexfilelayout/flexfilelayout.c | 15 | ||||
-rw-r--r-- | fs/nfs/flexfilelayout/flexfilelayoutdev.c | 30 |
2 files changed, 35 insertions, 10 deletions
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c index 3b398f7b4637..1f46043c181e 100644 --- a/fs/nfs/flexfilelayout/flexfilelayout.c +++ b/fs/nfs/flexfilelayout/flexfilelayout.c | |||
@@ -1712,7 +1712,7 @@ ff_layout_read_pagelist(struct nfs_pgio_header *hdr) | |||
1712 | goto out_failed; | 1712 | goto out_failed; |
1713 | 1713 | ||
1714 | ds_cred = ff_layout_get_ds_cred(lseg, idx, hdr->cred); | 1714 | ds_cred = ff_layout_get_ds_cred(lseg, idx, hdr->cred); |
1715 | if (IS_ERR(ds_cred)) | 1715 | if (!ds_cred) |
1716 | goto out_failed; | 1716 | goto out_failed; |
1717 | 1717 | ||
1718 | vers = nfs4_ff_layout_ds_version(lseg, idx); | 1718 | vers = nfs4_ff_layout_ds_version(lseg, idx); |
@@ -1737,7 +1737,7 @@ ff_layout_read_pagelist(struct nfs_pgio_header *hdr) | |||
1737 | vers == 3 ? &ff_layout_read_call_ops_v3 : | 1737 | vers == 3 ? &ff_layout_read_call_ops_v3 : |
1738 | &ff_layout_read_call_ops_v4, | 1738 | &ff_layout_read_call_ops_v4, |
1739 | 0, RPC_TASK_SOFTCONN); | 1739 | 0, RPC_TASK_SOFTCONN); |
1740 | 1740 | put_rpccred(ds_cred); | |
1741 | return PNFS_ATTEMPTED; | 1741 | return PNFS_ATTEMPTED; |
1742 | 1742 | ||
1743 | out_failed: | 1743 | out_failed: |
@@ -1769,7 +1769,7 @@ ff_layout_write_pagelist(struct nfs_pgio_header *hdr, int sync) | |||
1769 | return PNFS_NOT_ATTEMPTED; | 1769 | return PNFS_NOT_ATTEMPTED; |
1770 | 1770 | ||
1771 | ds_cred = ff_layout_get_ds_cred(lseg, idx, hdr->cred); | 1771 | ds_cred = ff_layout_get_ds_cred(lseg, idx, hdr->cred); |
1772 | if (IS_ERR(ds_cred)) | 1772 | if (!ds_cred) |
1773 | return PNFS_NOT_ATTEMPTED; | 1773 | return PNFS_NOT_ATTEMPTED; |
1774 | 1774 | ||
1775 | vers = nfs4_ff_layout_ds_version(lseg, idx); | 1775 | vers = nfs4_ff_layout_ds_version(lseg, idx); |
@@ -1798,6 +1798,7 @@ ff_layout_write_pagelist(struct nfs_pgio_header *hdr, int sync) | |||
1798 | vers == 3 ? &ff_layout_write_call_ops_v3 : | 1798 | vers == 3 ? &ff_layout_write_call_ops_v3 : |
1799 | &ff_layout_write_call_ops_v4, | 1799 | &ff_layout_write_call_ops_v4, |
1800 | sync, RPC_TASK_SOFTCONN); | 1800 | sync, RPC_TASK_SOFTCONN); |
1801 | put_rpccred(ds_cred); | ||
1801 | return PNFS_ATTEMPTED; | 1802 | return PNFS_ATTEMPTED; |
1802 | } | 1803 | } |
1803 | 1804 | ||
@@ -1824,7 +1825,7 @@ static int ff_layout_initiate_commit(struct nfs_commit_data *data, int how) | |||
1824 | struct rpc_clnt *ds_clnt; | 1825 | struct rpc_clnt *ds_clnt; |
1825 | struct rpc_cred *ds_cred; | 1826 | struct rpc_cred *ds_cred; |
1826 | u32 idx; | 1827 | u32 idx; |
1827 | int vers; | 1828 | int vers, ret; |
1828 | struct nfs_fh *fh; | 1829 | struct nfs_fh *fh; |
1829 | 1830 | ||
1830 | idx = calc_ds_index_from_commit(lseg, data->ds_commit_index); | 1831 | idx = calc_ds_index_from_commit(lseg, data->ds_commit_index); |
@@ -1838,7 +1839,7 @@ static int ff_layout_initiate_commit(struct nfs_commit_data *data, int how) | |||
1838 | goto out_err; | 1839 | goto out_err; |
1839 | 1840 | ||
1840 | ds_cred = ff_layout_get_ds_cred(lseg, idx, data->cred); | 1841 | ds_cred = ff_layout_get_ds_cred(lseg, idx, data->cred); |
1841 | if (IS_ERR(ds_cred)) | 1842 | if (!ds_cred) |
1842 | goto out_err; | 1843 | goto out_err; |
1843 | 1844 | ||
1844 | vers = nfs4_ff_layout_ds_version(lseg, idx); | 1845 | vers = nfs4_ff_layout_ds_version(lseg, idx); |
@@ -1854,10 +1855,12 @@ static int ff_layout_initiate_commit(struct nfs_commit_data *data, int how) | |||
1854 | if (fh) | 1855 | if (fh) |
1855 | data->args.fh = fh; | 1856 | data->args.fh = fh; |
1856 | 1857 | ||
1857 | return nfs_initiate_commit(ds_clnt, data, ds->ds_clp->rpc_ops, | 1858 | ret = nfs_initiate_commit(ds_clnt, data, ds->ds_clp->rpc_ops, |
1858 | vers == 3 ? &ff_layout_commit_call_ops_v3 : | 1859 | vers == 3 ? &ff_layout_commit_call_ops_v3 : |
1859 | &ff_layout_commit_call_ops_v4, | 1860 | &ff_layout_commit_call_ops_v4, |
1860 | how, RPC_TASK_SOFTCONN); | 1861 | how, RPC_TASK_SOFTCONN); |
1862 | put_rpccred(ds_cred); | ||
1863 | return ret; | ||
1861 | out_err: | 1864 | out_err: |
1862 | pnfs_generic_prepare_to_resend_writes(data); | 1865 | pnfs_generic_prepare_to_resend_writes(data); |
1863 | pnfs_generic_commit_release(data); | 1866 | pnfs_generic_commit_release(data); |
diff --git a/fs/nfs/flexfilelayout/flexfilelayoutdev.c b/fs/nfs/flexfilelayout/flexfilelayoutdev.c index a0dbf94d15ae..baee22929174 100644 --- a/fs/nfs/flexfilelayout/flexfilelayoutdev.c +++ b/fs/nfs/flexfilelayout/flexfilelayoutdev.c | |||
@@ -338,6 +338,25 @@ static int ff_layout_update_mirror_cred(struct nfs4_ff_layout_mirror *mirror, | |||
338 | return 0; | 338 | return 0; |
339 | } | 339 | } |
340 | 340 | ||
341 | static struct rpc_cred * | ||
342 | ff_layout_get_mirror_cred(struct nfs4_ff_layout_mirror *mirror, u32 iomode) | ||
343 | { | ||
344 | struct rpc_cred *cred, **pcred; | ||
345 | |||
346 | pcred = &mirror->cred; | ||
347 | |||
348 | rcu_read_lock(); | ||
349 | do { | ||
350 | cred = rcu_dereference(*pcred); | ||
351 | if (!cred) | ||
352 | break; | ||
353 | |||
354 | cred = get_rpccred_rcu(cred); | ||
355 | } while(!cred); | ||
356 | rcu_read_unlock(); | ||
357 | return cred; | ||
358 | } | ||
359 | |||
341 | struct nfs_fh * | 360 | struct nfs_fh * |
342 | nfs4_ff_layout_select_ds_fh(struct pnfs_layout_segment *lseg, u32 mirror_idx) | 361 | nfs4_ff_layout_select_ds_fh(struct pnfs_layout_segment *lseg, u32 mirror_idx) |
343 | { | 362 | { |
@@ -435,10 +454,13 @@ ff_layout_get_ds_cred(struct pnfs_layout_segment *lseg, u32 ds_idx, | |||
435 | struct nfs4_ff_layout_mirror *mirror = FF_LAYOUT_COMP(lseg, ds_idx); | 454 | struct nfs4_ff_layout_mirror *mirror = FF_LAYOUT_COMP(lseg, ds_idx); |
436 | struct rpc_cred *cred; | 455 | struct rpc_cred *cred; |
437 | 456 | ||
438 | if (mirror && mirror->cred) | 457 | if (mirror) { |
439 | cred = mirror->cred; | 458 | cred = ff_layout_get_mirror_cred(mirror, lseg->pls_range.iomode); |
440 | else | 459 | if (!cred) |
441 | cred = mdscred; | 460 | cred = get_rpccred(mdscred); |
461 | } else { | ||
462 | cred = get_rpccred(mdscred); | ||
463 | } | ||
442 | return cred; | 464 | return cred; |
443 | } | 465 | } |
444 | 466 | ||