2 Subject: Revert "NFS: Allow redirtying of a completed unstable write."
3 Patch-mainline: REVERT patch from 2.6.27
6 mainline commit e468bae97d243fe0e1515abaa1f7d0edf1476ad0
7 introduces a BUG() that is apprently fairly easy to trigger.
8 As it is just making a minor performance enhancement, it is best to
9 revert the patch until the issue is better understood.
11 Acked-by: NeilBrown <neilb@suse.de>
12 Signed-off-by: Neil Brown <neilb@suse.de>
15 fs/nfs/write.c | 65 ++++++++++++++++++++++++++++-----------------------------
16 1 file changed, 33 insertions(+), 32 deletions(-)
20 @@ -284,9 +284,12 @@ static int nfs_page_async_flush(struct n
22 spin_lock(&inode->i_lock);
24 - if (test_bit(PG_CLEAN, &req->wb_flags)) {
25 + if (test_bit(PG_NEED_COMMIT, &req->wb_flags)) {
26 + /* This request is marked for commit */
27 spin_unlock(&inode->i_lock);
29 + nfs_clear_page_tag_locked(req);
30 + nfs_pageio_complete(pgio);
33 if (nfs_set_page_writeback(page) != 0) {
34 spin_unlock(&inode->i_lock);
35 @@ -460,6 +463,19 @@ nfs_mark_request_dirty(struct nfs_page *
36 __set_page_dirty_nobuffers(req->wb_page);
40 + * Check if a request is dirty
43 +nfs_dirty_request(struct nfs_page *req)
45 + struct page *page = req->wb_page;
47 + if (page == NULL || test_bit(PG_NEED_COMMIT, &req->wb_flags))
49 + return !PageWriteback(page);
52 #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
54 * Add a request to the inode's commit list.
55 @@ -472,7 +488,7 @@ nfs_mark_request_commit(struct nfs_page
57 spin_lock(&inode->i_lock);
59 - set_bit(PG_CLEAN, &(req)->wb_flags);
60 + set_bit(PG_NEED_COMMIT, &(req)->wb_flags);
61 radix_tree_tag_set(&nfsi->nfs_page_tree,
64 @@ -483,19 +499,6 @@ nfs_mark_request_commit(struct nfs_page
65 __mark_inode_dirty(inode, I_DIRTY_DATASYNC);
69 -nfs_clear_request_commit(struct nfs_page *req)
71 - struct page *page = req->wb_page;
73 - if (test_and_clear_bit(PG_CLEAN, &(req)->wb_flags)) {
74 - dec_zone_page_state(page, NR_UNSTABLE_NFS);
75 - dec_bdi_stat(page_file_mapping(page)->backing_dev_info, BDI_RECLAIMABLE);
82 int nfs_write_need_commit(struct nfs_write_data *data)
84 @@ -505,7 +508,7 @@ int nfs_write_need_commit(struct nfs_wri
86 int nfs_reschedule_unstable_write(struct nfs_page *req)
88 - if (test_and_clear_bit(PG_NEED_COMMIT, &req->wb_flags)) {
89 + if (test_bit(PG_NEED_COMMIT, &req->wb_flags)) {
90 nfs_mark_request_commit(req);
93 @@ -521,12 +524,6 @@ nfs_mark_request_commit(struct nfs_page
98 -nfs_clear_request_commit(struct nfs_page *req)
104 int nfs_write_need_commit(struct nfs_write_data *data)
106 @@ -584,8 +581,11 @@ static void nfs_cancel_commit_list(struc
108 while(!list_empty(head)) {
109 req = nfs_list_entry(head->next);
110 + dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
111 + dec_bdi_stat(req->wb_page->mapping->backing_dev_info,
113 nfs_list_remove_request(req);
114 - nfs_clear_request_commit(req);
115 + clear_bit(PG_NEED_COMMIT, &(req)->wb_flags);
116 nfs_inode_remove_request(req);
117 nfs_unlock_request(req);
119 @@ -657,7 +657,8 @@ static struct nfs_page *nfs_try_to_updat
120 * Note: nfs_flush_incompatible() will already
121 * have flushed out requests having wrong owners.
124 + if (!nfs_dirty_request(req)
126 || end < req->wb_offset)
129 @@ -673,10 +674,6 @@ static struct nfs_page *nfs_try_to_updat
130 spin_lock(&inode->i_lock);
133 - if (nfs_clear_request_commit(req))
134 - radix_tree_tag_clear(&NFS_I(inode)->nfs_page_tree,
135 - req->wb_index, NFS_PAGE_TAG_COMMIT);
137 /* Okay, the request matches. Update the region */
138 if (offset < req->wb_offset) {
139 req->wb_offset = offset;
140 @@ -758,7 +755,8 @@ int nfs_flush_incompatible(struct file *
141 req = nfs_page_find_request(page);
144 - do_flush = req->wb_page != page || req->wb_context != ctx;
145 + do_flush = req->wb_page != page || req->wb_context != ctx
146 + || !nfs_dirty_request(req);
147 nfs_release_request(req);
150 @@ -1363,7 +1361,10 @@ static void nfs_commit_release(void *cal
151 while (!list_empty(&data->pages)) {
152 req = nfs_list_entry(data->pages.next);
153 nfs_list_remove_request(req);
154 - nfs_clear_request_commit(req);
155 + clear_bit(PG_NEED_COMMIT, &(req)->wb_flags);
156 + dec_zone_page_state(req->wb_page, NR_UNSTABLE_NFS);
157 + dec_bdi_stat(req->wb_page->mapping->backing_dev_info,
160 dprintk("NFS: commit (%s/%lld %d@%lld)",
161 req->wb_context->path.dentry->d_inode->i_sb->s_id,
162 @@ -1539,7 +1540,7 @@ int nfs_wb_page_cancel(struct inode *ino
163 req = nfs_page_find_request(page);
166 - if (test_bit(PG_CLEAN, &req->wb_flags)) {
167 + if (test_bit(PG_NEED_COMMIT, &req->wb_flags)) {
168 nfs_release_request(req);