]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - src/patches/suse-2.6.27.25/patches.fixes/nfs-write.c-bug-removal.patch
Reenabled linux-xen and xen-image build
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.fixes / nfs-write.c-bug-removal.patch
CommitLineData
00e5a55c
BS
1From: ffilz@us.ibm.com
2Subject: Revert "NFS: Allow redirtying of a completed unstable write."
3Patch-mainline: REVERT patch from 2.6.27
4References: 442267
5
6mainline commit e468bae97d243fe0e1515abaa1f7d0edf1476ad0
7introduces a BUG() that is apprently fairly easy to trigger.
8As it is just making a minor performance enhancement, it is best to
9revert the patch until the issue is better understood.
10
11Acked-by: NeilBrown <neilb@suse.de>
12Signed-off-by: Neil Brown <neilb@suse.de>
13
14---
15 fs/nfs/write.c | 65 ++++++++++++++++++++++++++++-----------------------------
16 1 file changed, 33 insertions(+), 32 deletions(-)
17
18--- a/fs/nfs/write.c
19+++ b/fs/nfs/write.c
20@@ -284,9 +284,12 @@ static int nfs_page_async_flush(struct n
21 return ret;
22 spin_lock(&inode->i_lock);
23 }
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);
28- BUG();
29+ nfs_clear_page_tag_locked(req);
30+ nfs_pageio_complete(pgio);
31+ return 0;
32 }
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);
37 }
38
39+/*
40+ * Check if a request is dirty
41+ */
42+static inline int
43+nfs_dirty_request(struct nfs_page *req)
44+{
45+ struct page *page = req->wb_page;
46+
47+ if (page == NULL || test_bit(PG_NEED_COMMIT, &req->wb_flags))
48+ return 0;
49+ return !PageWriteback(page);
50+}
51+
52 #if defined(CONFIG_NFS_V3) || defined(CONFIG_NFS_V4)
53 /*
54 * Add a request to the inode's commit list.
55@@ -472,7 +488,7 @@ nfs_mark_request_commit(struct nfs_page
56
57 spin_lock(&inode->i_lock);
58 nfsi->ncommit++;
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,
62 req->wb_index,
63 NFS_PAGE_TAG_COMMIT);
64@@ -483,19 +499,6 @@ nfs_mark_request_commit(struct nfs_page
65 __mark_inode_dirty(inode, I_DIRTY_DATASYNC);
66 }
67
68-static int
69-nfs_clear_request_commit(struct nfs_page *req)
70-{
71- struct page *page = req->wb_page;
72-
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);
76- return 1;
77- }
78- return 0;
79-}
80-
81 static inline
82 int nfs_write_need_commit(struct nfs_write_data *data)
83 {
84@@ -505,7 +508,7 @@ int nfs_write_need_commit(struct nfs_wri
85 static inline
86 int nfs_reschedule_unstable_write(struct nfs_page *req)
87 {
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);
91 return 1;
92 }
93@@ -521,12 +524,6 @@ nfs_mark_request_commit(struct nfs_page
94 {
95 }
96
97-static inline int
98-nfs_clear_request_commit(struct nfs_page *req)
99-{
100- return 0;
101-}
102-
103 static inline
104 int nfs_write_need_commit(struct nfs_write_data *data)
105 {
106@@ -584,8 +581,11 @@ static void nfs_cancel_commit_list(struc
107
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,
112+ BDI_RECLAIMABLE);
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);
118 }
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.
122 */
123- if (offset > rqend
124+ if (!nfs_dirty_request(req)
125+ || offset > rqend
126 || end < req->wb_offset)
127 goto out_flushme;
128
129@@ -673,10 +674,6 @@ static struct nfs_page *nfs_try_to_updat
130 spin_lock(&inode->i_lock);
131 }
132
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);
136-
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);
142 if (req == NULL)
143 return 0;
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);
148 if (!do_flush)
149 return 0;
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,
158+ BDI_RECLAIMABLE);
159
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);
164 if (req == NULL)
165 goto out;
166- if (test_bit(PG_CLEAN, &req->wb_flags)) {
167+ if (test_bit(PG_NEED_COMMIT, &req->wb_flags)) {
168 nfs_release_request(req);
169 break;
170 }