aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2017-07-12 19:10:56 -0400
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2017-07-19 15:28:21 -0400
commite39928f942ff7a9d1cb9005423e9e35a0a4bb2e0 (patch)
treea146f72402513255e27a62729cc51a499e919bba
parent89a6814d9b665b196aa3a102f96b6dc7e8cb669e (diff)
NFS: Fix a COMMIT race in pNFS
We must make sure that cinfo->ds->nwritten is in sync with the commit list, since it is checked as part of pnfs_scan_commit_lists(). Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
-rw-r--r--fs/nfs/pnfs_nfs.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c
index d40755a0984b..3e6de85faf42 100644
--- a/fs/nfs/pnfs_nfs.c
+++ b/fs/nfs/pnfs_nfs.c
@@ -159,13 +159,18 @@ void pnfs_generic_recover_commit_reqs(struct list_head *dst,
159{ 159{
160 struct pnfs_commit_bucket *b; 160 struct pnfs_commit_bucket *b;
161 struct pnfs_layout_segment *freeme; 161 struct pnfs_layout_segment *freeme;
162 int nwritten;
162 int i; 163 int i;
163 164
164 lockdep_assert_held(&cinfo->inode->i_lock); 165 lockdep_assert_held(&cinfo->inode->i_lock);
165restart: 166restart:
166 for (i = 0, b = cinfo->ds->buckets; i < cinfo->ds->nbuckets; i++, b++) { 167 for (i = 0, b = cinfo->ds->buckets; i < cinfo->ds->nbuckets; i++, b++) {
167 if (pnfs_generic_transfer_commit_list(&b->written, dst, 168 nwritten = pnfs_generic_transfer_commit_list(&b->written,
168 cinfo, 0)) { 169 dst, cinfo, 0);
170 if (!nwritten)
171 continue;
172 cinfo->ds->nwritten -= nwritten;
173 if (list_empty(&b->written)) {
169 freeme = b->wlseg; 174 freeme = b->wlseg;
170 b->wlseg = NULL; 175 b->wlseg = NULL;
171 spin_unlock(&cinfo->inode->i_lock); 176 spin_unlock(&cinfo->inode->i_lock);
@@ -174,7 +179,6 @@ restart:
174 goto restart; 179 goto restart;
175 } 180 }
176 } 181 }
177 cinfo->ds->nwritten = 0;
178} 182}
179EXPORT_SYMBOL_GPL(pnfs_generic_recover_commit_reqs); 183EXPORT_SYMBOL_GPL(pnfs_generic_recover_commit_reqs);
180 184