]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.fixes/nfs-write.c-bug-removal.patch
Updated xen patches taken from suse.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.fixes / nfs-write.c-bug-removal.patch
1 From: ffilz@us.ibm.com
2 Subject: Revert "NFS: Allow redirtying of a completed unstable write."
3 Patch-mainline: REVERT patch from 2.6.27
4 References: 442267
5
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.
10
11 Acked-by: NeilBrown <neilb@suse.de>
12 Signed-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 }