Skip to content

Commit f792e3a

Browse files
committed
afs: Fix where page->private is set during write
In afs, page->private is set to indicate the dirty region of a page. This is done in afs_write_begin(), but that can't take account of whether the copy into the page actually worked. Fix this by moving the change of page->private into afs_write_end(). Fixes: 4343d00 ("afs: Get rid of the afs_writeback record") Signed-off-by: David Howells <[email protected]>
1 parent 21db2cd commit f792e3a

File tree

1 file changed

+26
-15
lines changed

1 file changed

+26
-15
lines changed

fs/afs/write.c

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -135,23 +135,8 @@ int afs_write_begin(struct file *file, struct address_space *mapping,
135135
if (!test_bit(AFS_VNODE_NEW_CONTENT, &vnode->flags) &&
136136
(to < f || from > t))
137137
goto flush_conflicting_write;
138-
if (from < f)
139-
f = from;
140-
if (to > t)
141-
t = to;
142-
} else {
143-
f = from;
144-
t = to;
145138
}
146139

147-
priv = (unsigned long)t << AFS_PRIV_SHIFT;
148-
priv |= f;
149-
trace_afs_page_dirty(vnode, tracepoint_string("begin"),
150-
page->index, priv);
151-
if (PagePrivate(page))
152-
set_page_private(page, priv);
153-
else
154-
attach_page_private(page, (void *)priv);
155140
*_page = page;
156141
_leave(" = 0");
157142
return 0;
@@ -185,6 +170,9 @@ int afs_write_end(struct file *file, struct address_space *mapping,
185170
{
186171
struct afs_vnode *vnode = AFS_FS_I(file_inode(file));
187172
struct key *key = afs_file_key(file);
173+
unsigned long priv;
174+
unsigned int f, from = pos & (PAGE_SIZE - 1);
175+
unsigned int t, to = from + copied;
188176
loff_t i_size, maybe_i_size;
189177
int ret;
190178

@@ -216,6 +204,29 @@ int afs_write_end(struct file *file, struct address_space *mapping,
216204
SetPageUptodate(page);
217205
}
218206

207+
if (PagePrivate(page)) {
208+
priv = page_private(page);
209+
f = priv & AFS_PRIV_MAX;
210+
t = priv >> AFS_PRIV_SHIFT;
211+
if (from < f)
212+
f = from;
213+
if (to > t)
214+
t = to;
215+
priv = (unsigned long)t << AFS_PRIV_SHIFT;
216+
priv |= f;
217+
set_page_private(page, priv);
218+
trace_afs_page_dirty(vnode, tracepoint_string("dirty+"),
219+
page->index, priv);
220+
} else {
221+
f = from;
222+
t = to;
223+
priv = (unsigned long)t << AFS_PRIV_SHIFT;
224+
priv |= f;
225+
attach_page_private(page, (void *)priv);
226+
trace_afs_page_dirty(vnode, tracepoint_string("dirty"),
227+
page->index, priv);
228+
}
229+
219230
set_page_dirty(page);
220231
if (PageDirty(page))
221232
_debug("dirtied");

0 commit comments

Comments
 (0)