On Wed, Apr 14, 2021 at 2:22 PM Peng Tao <bergwolf@xxxxxxxxx> wrote: > > > --- a/fs/fuse/file.c > > +++ b/fs/fuse/file.c > > @@ -1117,17 +1117,12 @@ static ssize_t fuse_send_write_pages(str > > count = ia->write.out.size; > > for (i = 0; i < ap->num_pages; i++) { > > struct page *page = ap->pages[i]; > > + bool page_locked = ap->page_locked && (i == ap->num_pages - 1); > Any reason for just handling the last locked page in the page array? > To be specific, it look like the first page in the array can also be > partial dirty and locked? In that case the first partial page will be locked, and it'll break out of the loop... > > > > - if (!err && !offset && count >= PAGE_SIZE) > > - SetPageUptodate(page); > > - > > - if (count > PAGE_SIZE - offset) > > - count -= PAGE_SIZE - offset; > > - else > > - count = 0; > > - offset = 0; > > - > > - unlock_page(page); > > + if (err) > > + ClearPageUptodate(page); > > + if (page_locked) > > + unlock_page(page); > > put_page(page); > > } > > > > @@ -1191,6 +1186,16 @@ static ssize_t fuse_fill_write_pages(str > > if (offset == PAGE_SIZE) > > offset = 0; > > > > + /* If we copied full page, mark it uptodate */ > > + if (tmp == PAGE_SIZE) > > + SetPageUptodate(page); > > + > > + if (PageUptodate(page)) { > > + unlock_page(page); > > + } else { > > + ap->page_locked = true; > > + break; ... here, and send it as a separate WRITE request. So the multi-page case with a partial & non-uptodate head page will always result in the write request being split into two (even if there's no partial tail page). Thanks, Miklos