FAILED: patch "[PATCH] NFSv4.1/pnfs: Fix atomicity of commit list updates" failed to apply to 4.0-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.0-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
Quoted 1 line
From
86d80f973434de24d8a807a92cd59d5ced7bd519Mon Sep 17 00:00:00 2001
From: Trond Myklebust <[email protected]>
Date: Fri, 31 Jul 2015 16:24:30 -0400
Subject: [PATCH] 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().
fs/nfs/internal.h +10 -5
@@ -490,6 +490,9 @@ void nfs_retry_commit(struct list_head *page_list,void nfs_commitdata_release (struct nfs_commit_data *data);void nfs_request_add_commit_list (struct nfs_page *req,struct list_head *dst,struct nfs_commit_info *cinfo); +void nfs_request_add_commit_list_locked (struct nfs_page *req, +struct list_head *dst, +struct nfs_commit_info *cinfo);void nfs_request_remove_commit_list (struct nfs_page *req,struct nfs_commit_info *cinfo); void nfs_init_cinfo(struct nfs_commit_info *cinfo,
@@ -623,13 +626,15 @@ void nfs_super_set_maxbytes(struct super_block *sb, __u64 maxfilesize)* Record the page as unstable and mark its inode as dirty. */ static inline -void nfs_mark_page_unstable (struct page *page) +void nfs_mark_page_unstable (struct page *page,struct nfs_commit_info *cinfo) { -struct inode *inode =page_file_mapping (page)->host; +if (!cinfo->dreq) { +struct inode *inode =page_file_mapping (page)->host; -inc_zone_page_state (page,NR_UNSTABLE_NFS ); -inc_wb_stat (&inode_to_bdi (inode)->wb,WB_RECLAIMABLE ); -__mark_inode_dirty (inode,I_DIRTY_DATASYNC ); +inc_zone_page_state (page,NR_UNSTABLE_NFS ); +inc_wb_stat (&inode_to_bdi (inode)->wb,WB_RECLAIMABLE ); +__mark_inode_dirty (inode,I_DIRTY_DATASYNC ); + } }/*
fs/nfs/pnfs_nfs.c +3 -2
@@ -863,9 +863,10 @@ pnfs_layout_mark_request_commit(struct nfs_page *req, }set_bit (PG_COMMIT_TO_DS , &req->wb_flags); cinfo->ds->nwritten++; -spin_unlock (cinfo->lock); -nfs_request_add_commit_list (req, list, cinfo); +nfs_request_add_commit_list_locked (req, list, cinfo); +spin_unlock (cinfo->lock); +nfs_mark_page_unstable (req->wb_page, cinfo); }EXPORT_SYMBOL_GPL (pnfs_layout_mark_request_commit);
fs/nfs/write.c +24 -5
@@ -768,6 +768,28 @@ nfs_page_search_commits_for_head_request_locked(struct nfs_inode *nfsi, }/** +* nfs_request_add_commit_list_locked - add request to a commit list +* @req: pointer to a struct nfs_page +* @dst: commit list head +* @cinfo: holds list lock and accounting info +* +* This sets the PG_CLEAN bit, updates the cinfo count of +* number of outstanding requests requiring a commit as well as +* the MM page stats. +* +* The caller must hold the cinfo->lock, and the nfs_page lock. +*/ +void +nfs_request_add_commit_list_locked (struct nfs_page *req,struct list_head *dst, +struct nfs_commit_info *cinfo) +{ +set_bit (PG_CLEAN , &req->wb_flags); +nfs_list_add_request (req, dst); + cinfo->mds->ncommit++; +} +EXPORT_SYMBOL_GPL (nfs_request_add_commit_list_locked); + +/** * nfs_request_add_commit_list - add request to a commit list * @req: pointer to a struct nfs_page * @dst: commit list head
@@ -784,13 +806,10 @@ void nfs_request_add_commit_list(struct nfs_page *req, struct list_head *dst, struct nfs_commit_info *cinfo) { - set_bit(PG_CLEAN, &(req)->wb_flags); spin_lock(cinfo->lock); -nfs_list_add_request (req, dst); - cinfo->mds->ncommit++; +nfs_request_add_commit_list_locked (req, dst, cinfo);spin_unlock (cinfo->lock); -if (!cinfo->dreq) -nfs_mark_page_unstable (req->wb_page); +nfs_mark_page_unstable (req->wb_page, cinfo); }EXPORT_SYMBOL_GPL (nfs_request_add_commit_list);