From 419234d5958b8ec4f5e2ba8ed2e77916f844ded1 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Wed, 16 Jan 2019 10:27:59 +0100 Subject: 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: Kirill Tkhai Fixes: fd22d62ed0c3 ("fuse: no fc->lock for iqueue parts") Signed-off-by: Miklos Szeredi --- fs/fuse/file.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'fs/fuse') diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 8342df29815d..b0c32a74082f 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -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 - * writeback. If yes, then iterate write requests, to see if there's one - * already added for a page at this offset. If there's none, then insert this - * new request onto the auxiliary list, otherwise reuse the existing one by + * writeback. If yes, then iterate auxiliary write requests, to see if there's + * one already added for a page at this offset. If there's none, then insert + * this new request onto the auxiliary list, otherwise reuse the existing one by * copying the new page contents over to the old temporary page. */ 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; - 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; WARN_ON(tmp->inode != new_req->inode); curr_index = tmp->misc.write.in.offset >> PAGE_SHIFT; - if (tmp->num_pages == 1 && curr_index == page->index && - test_bit(FR_PENDING, &tmp->flags)) { + if (curr_index == page->index) { + WARN_ON(tmp->num_pages != 1); + WARN_ON(!test_bit(FR_PENDING, &tmp->flags)); copy_highpage(tmp->pages[0], page); break; } -- cgit v1.2.3-59-g8ed1b