aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/write.c
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2015-07-31 16:24:30 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2015-08-10 19:08:13 -0400
commit86d80f973434de24d8a807a92cd59d5ced7bd519 (patch)
treed1c6aa87eac0551a3d65a7bdd0a2b1bc49f4c29a /fs/nfs/write.c
parent74d33293e467df61de1b1d8b2fbe29e550dec33b (diff)
NFSv4.1/pnfs: Fix atomicity of commit list updates
pnfs_layout_mark_request_commit() needs to ensure that it adds the request to the commit list atomically with all the other updates in order to prevent corruption to buckets[ds_commit_idx].wlseg due to races with pnfs_generic_clear_request_commit(). Fixes: 338d00cfef07d ("pnfs: Refactor the *_layout_mark_request_commit...") Cc: stable@vger.kernel.org # v4.0+ Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Diffstat (limited to 'fs/nfs/write.c')
-rw-r--r--fs/nfs/write.c29
1 files changed, 24 insertions, 5 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index 75a35a1afa79..fdee9270ca15 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -768,6 +768,28 @@ nfs_page_search_commits_for_head_request_locked(struct nfs_inode *nfsi,
768} 768}
769 769
770/** 770/**
771 * nfs_request_add_commit_list_locked - add request to a commit list
772 * @req: pointer to a struct nfs_page
773 * @dst: commit list head
774 * @cinfo: holds list lock and accounting info
775 *
776 * This sets the PG_CLEAN bit, updates the cinfo count of
777 * number of outstanding requests requiring a commit as well as
778 * the MM page stats.
779 *
780 * The caller must hold the cinfo->lock, and the nfs_page lock.
781 */
782void
783nfs_request_add_commit_list_locked(struct nfs_page *req, struct list_head *dst,
784 struct nfs_commit_info *cinfo)
785{
786 set_bit(PG_CLEAN, &req->wb_flags);
787 nfs_list_add_request(req, dst);
788 cinfo->mds->ncommit++;
789}
790EXPORT_SYMBOL_GPL(nfs_request_add_commit_list_locked);
791
792/**
771 * nfs_request_add_commit_list - add request to a commit list 793 * nfs_request_add_commit_list - add request to a commit list
772 * @req: pointer to a struct nfs_page 794 * @req: pointer to a struct nfs_page
773 * @dst: commit list head 795 * @dst: commit list head
@@ -784,13 +806,10 @@ void
784nfs_request_add_commit_list(struct nfs_page *req, struct list_head *dst, 806nfs_request_add_commit_list(struct nfs_page *req, struct list_head *dst,
785 struct nfs_commit_info *cinfo) 807 struct nfs_commit_info *cinfo)
786{ 808{
787 set_bit(PG_CLEAN, &(req)->wb_flags);
788 spin_lock(cinfo->lock); 809 spin_lock(cinfo->lock);
789 nfs_list_add_request(req, dst); 810 nfs_request_add_commit_list_locked(req, dst, cinfo);
790 cinfo->mds->ncommit++;
791 spin_unlock(cinfo->lock); 811 spin_unlock(cinfo->lock);
792 if (!cinfo->dreq) 812 nfs_mark_page_unstable(req->wb_page, cinfo);
793 nfs_mark_page_unstable(req->wb_page);
794} 813}
795EXPORT_SYMBOL_GPL(nfs_request_add_commit_list); 814EXPORT_SYMBOL_GPL(nfs_request_add_commit_list);
796 815