Commit 419234d5 authored by Miklos Szeredi's avatar Miklos Szeredi

fuse: only reuse auxiliary request in fuse_writepage_in_flight()

Don't reuse the queued request, even if it only contains a single page.
This is needed because previous locking changes (spliting out
fiq->waitq.lock from fc->lock) broke the assumption that request will
remain in FR_PENDING at least until the new page contents are copied.

This fix removes a slight optimization for a rare corner case, so we really
shoudln't care.
Reported-by: default avatarKirill Tkhai <ktkhai@virtuozzo.com>
Fixes: fd22d62e ("fuse: no fc->lock for iqueue parts")
Signed-off-by: default avatarMiklos Szeredi <mszeredi@redhat.com>
parent 7f305ca1
...@@ -1746,9 +1746,9 @@ static void fuse_writepages_send(struct fuse_fill_wb_data *data) ...@@ -1746,9 +1746,9 @@ static void fuse_writepages_send(struct fuse_fill_wb_data *data)
/* /*
* First recheck under fi->lock if the offending offset is still under * First recheck under fi->lock if the offending offset is still under
* writeback. If yes, then iterate write requests, to see if there's one * writeback. If yes, then iterate auxiliary write requests, to see if there's
* already added for a page at this offset. If there's none, then insert this * one already added for a page at this offset. If there's none, then insert
* new request onto the auxiliary list, otherwise reuse the existing one by * this new request onto the auxiliary list, otherwise reuse the existing one by
* copying the new page contents over to the old temporary page. * copying the new page contents over to the old temporary page.
*/ */
static bool fuse_writepage_in_flight(struct fuse_req *new_req, static bool fuse_writepage_in_flight(struct fuse_req *new_req,
...@@ -1771,13 +1771,14 @@ static bool fuse_writepage_in_flight(struct fuse_req *new_req, ...@@ -1771,13 +1771,14 @@ static bool fuse_writepage_in_flight(struct fuse_req *new_req,
} }
new_req->num_pages = 1; new_req->num_pages = 1;
for (tmp = old_req; tmp != NULL; tmp = tmp->misc.write.next) { for (tmp = old_req->misc.write.next; tmp; tmp = tmp->misc.write.next) {
pgoff_t curr_index; pgoff_t curr_index;
WARN_ON(tmp->inode != new_req->inode); WARN_ON(tmp->inode != new_req->inode);
curr_index = tmp->misc.write.in.offset >> PAGE_SHIFT; curr_index = tmp->misc.write.in.offset >> PAGE_SHIFT;
if (tmp->num_pages == 1 && curr_index == page->index && if (curr_index == page->index) {
test_bit(FR_PENDING, &tmp->flags)) { WARN_ON(tmp->num_pages != 1);
WARN_ON(!test_bit(FR_PENDING, &tmp->flags));
copy_highpage(tmp->pages[0], page); copy_highpage(tmp->pages[0], page);
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment