summaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2017-07-12 19:10:57 -0400
committerAnna Schumaker <Anna.Schumaker@Netapp.com>2017-07-19 15:28:21 -0400
commit41181886459b281ed1346369f27b3c3bb8e2dde3 (patch)
tree6e459cf7aa4d69be2022e2fa03e8136052b537d0 /fs
parente39928f942ff7a9d1cb9005423e9e35a0a4bb2e0 (diff)
NFS: Fix another COMMIT race in pNFS
We must make sure that cinfo->ds->ncommitting is in sync with the commit list, since it is checked as part of pnfs_commit_list(). Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/pnfs_nfs.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c
index 3e6de85faf42..7ceb86627e54 100644
--- a/fs/nfs/pnfs_nfs.c
+++ b/fs/nfs/pnfs_nfs.c
@@ -187,6 +187,7 @@ static void pnfs_generic_retry_commit(struct nfs_commit_info *cinfo, int idx)
187 struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds; 187 struct pnfs_ds_commit_info *fl_cinfo = cinfo->ds;
188 struct pnfs_commit_bucket *bucket; 188 struct pnfs_commit_bucket *bucket;
189 struct pnfs_layout_segment *freeme; 189 struct pnfs_layout_segment *freeme;
190 struct list_head *pos;
190 LIST_HEAD(pages); 191 LIST_HEAD(pages);
191 int i; 192 int i;
192 193
@@ -197,6 +198,8 @@ static void pnfs_generic_retry_commit(struct nfs_commit_info *cinfo, int idx)
197 continue; 198 continue;
198 freeme = bucket->clseg; 199 freeme = bucket->clseg;
199 bucket->clseg = NULL; 200 bucket->clseg = NULL;
201 list_for_each(pos, &bucket->committing)
202 cinfo->ds->ncommitting--;
200 list_splice_init(&bucket->committing, &pages); 203 list_splice_init(&bucket->committing, &pages);
201 spin_unlock(&cinfo->inode->i_lock); 204 spin_unlock(&cinfo->inode->i_lock);
202 nfs_retry_commit(&pages, freeme, cinfo, i); 205 nfs_retry_commit(&pages, freeme, cinfo, i);
@@ -247,9 +250,12 @@ void pnfs_fetch_commit_bucket_list(struct list_head *pages,
247 struct nfs_commit_info *cinfo) 250 struct nfs_commit_info *cinfo)
248{ 251{
249 struct pnfs_commit_bucket *bucket; 252 struct pnfs_commit_bucket *bucket;
253 struct list_head *pos;
250 254
251 bucket = &cinfo->ds->buckets[data->ds_commit_index]; 255 bucket = &cinfo->ds->buckets[data->ds_commit_index];
252 spin_lock(&cinfo->inode->i_lock); 256 spin_lock(&cinfo->inode->i_lock);
257 list_for_each(pos, &bucket->committing)
258 cinfo->ds->ncommitting--;
253 list_splice_init(&bucket->committing, pages); 259 list_splice_init(&bucket->committing, pages);
254 data->lseg = bucket->clseg; 260 data->lseg = bucket->clseg;
255 bucket->clseg = NULL; 261 bucket->clseg = NULL;
@@ -334,7 +340,6 @@ pnfs_generic_commit_pagelist(struct inode *inode, struct list_head *mds_pages,
334 } 340 }
335 } 341 }
336out: 342out:
337 cinfo->ds->ncommitting = 0;
338 return PNFS_ATTEMPTED; 343 return PNFS_ATTEMPTED;
339} 344}
340EXPORT_SYMBOL_GPL(pnfs_generic_commit_pagelist); 345EXPORT_SYMBOL_GPL(pnfs_generic_commit_pagelist);