diff options
author | Josef Bacik <josef@toxicpanda.com> | 2024-03-01 11:49:56 -0500 |
---|---|---|
committer | Trond Myklebust <trond.myklebust@hammerspace.com> | 2024-03-09 09:14:51 -0500 |
commit | 094501358e7a165071673e754c3925683683057f (patch) | |
tree | 1b1b28334638d38f5b1f46439eb38ffae2b1b697 | |
parent | b326df4a8ec6ef53e2e2f1c2cbf14f8a20e85baa (diff) | |
download | lwn-094501358e7a165071673e754c3925683683057f.tar.gz lwn-094501358e7a165071673e754c3925683683057f.zip |
nfs: properly protect nfs_direct_req fields
We protect accesses to the nfs_direct_req fields with the dreq->lock
ever where except nfs_direct_commit_complete. This isn't a huge deal,
but it does lead to confusion, and we could potentially end up setting
NFS_ODIRECT_RESCHED_WRITES in one thread where we've had an error in
another. Clean this up to properly protect ->error and ->flags in the
commit completion path.
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
-rw-r--r-- | fs/nfs/direct.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index c03926a1cc73..befcc167e25f 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c @@ -606,6 +606,7 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data) trace_nfs_direct_commit_complete(dreq); + spin_lock(&dreq->lock); if (status < 0) { /* Errors in commit are fatal */ dreq->error = status; @@ -613,6 +614,7 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data) } else { status = dreq->error; } + spin_unlock(&dreq->lock); nfs_init_cinfo_from_dreq(&cinfo, dreq); @@ -625,7 +627,10 @@ static void nfs_direct_commit_complete(struct nfs_commit_data *data) spin_unlock(&dreq->lock); nfs_release_request(req); } else if (!nfs_write_match_verf(verf, req)) { - dreq->flags = NFS_ODIRECT_RESCHED_WRITES; + spin_lock(&dreq->lock); + if (dreq->flags == 0) + dreq->flags = NFS_ODIRECT_RESCHED_WRITES; + spin_unlock(&dreq->lock); /* * Despite the reboot, the write was successful, * so reset wb_nio. |