diff options
author | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-07-23 19:58:30 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-07-23 19:58:30 -0700 |
commit | 24a81a2c258177ba334838a372651f784953b03a (patch) | |
tree | 6c3ea896b8a690ed43def034f3f5b885069397b4 /fs/nfs/filelayout/filelayout.c | |
parent | 91c17449fe04adfb12ff9523f62e9cd0d658a88d (diff) | |
parent | 520eccdfe187591a51ea9ab4c1a024ae4d0f68d9 (diff) |
Merge 4.13-rc2 into char-misc-next
We want the char/misc driver fixes in here as well to handle future
changes.
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs/nfs/filelayout/filelayout.c')
-rw-r--r-- | fs/nfs/filelayout/filelayout.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/fs/nfs/filelayout/filelayout.c b/fs/nfs/filelayout/filelayout.c index 080fc6b278bd..44c638b7876c 100644 --- a/fs/nfs/filelayout/filelayout.c +++ b/fs/nfs/filelayout/filelayout.c @@ -542,6 +542,10 @@ filelayout_check_deviceid(struct pnfs_layout_hdr *lo, struct nfs4_file_layout_dsaddr *dsaddr; int status = -EINVAL; + /* Is the deviceid already set? If so, we're good. */ + if (fl->dsaddr != NULL) + return 0; + /* find and reference the deviceid */ d = nfs4_find_get_deviceid(NFS_SERVER(lo->plh_inode), &fl->deviceid, lo->plh_lc_cred, gfp_flags); @@ -553,8 +557,6 @@ filelayout_check_deviceid(struct pnfs_layout_hdr *lo, if (filelayout_test_devid_unavailable(&dsaddr->id_node)) goto out_put; - fl->dsaddr = dsaddr; - if (fl->first_stripe_index >= dsaddr->stripe_count) { dprintk("%s Bad first_stripe_index %u\n", __func__, fl->first_stripe_index); @@ -570,6 +572,13 @@ filelayout_check_deviceid(struct pnfs_layout_hdr *lo, goto out_put; } status = 0; + + /* + * Atomic compare and xchange to ensure we don't scribble + * over a non-NULL pointer. + */ + if (cmpxchg(&fl->dsaddr, NULL, dsaddr) != NULL) + goto out_put; out: return status; out_put: |