On Fri, Nov 08, 2024 at 04:12:50PM -0800, Joanne Koong wrote: > Add support for folios larger than one page size for non-writeback > writes. > > Signed-off-by: Joanne Koong <joannelkoong@xxxxxxxxx> > --- > fs/fuse/file.c | 29 ++++++++++++++++++----------- > 1 file changed, 18 insertions(+), 11 deletions(-) > > diff --git a/fs/fuse/file.c b/fs/fuse/file.c > index a89fdc55a40b..6ee23ab9b7f2 100644 > --- a/fs/fuse/file.c > +++ b/fs/fuse/file.c > @@ -1146,19 +1146,15 @@ static ssize_t fuse_fill_write_pages(struct fuse_io_args *ia, > num = min(num, max_pages << PAGE_SHIFT); > > ap->args.in_pages = true; > - ap->descs[0].offset = offset; > > while (num) { > size_t tmp; > struct folio *folio; > pgoff_t index = pos >> PAGE_SHIFT; > - unsigned int bytes = min(PAGE_SIZE - offset, num); > - > - again: > - err = -EFAULT; > - if (fault_in_iov_iter_readable(ii, bytes)) > - break; > + unsigned int bytes; > + unsigned int folio_offset; > > + again: > folio = __filemap_get_folio(mapping, index, FGP_WRITEBEGIN, > mapping_gfp_mask(mapping)); > if (IS_ERR(folio)) { > @@ -1166,10 +1162,20 @@ static ssize_t fuse_fill_write_pages(struct fuse_io_args *ia, > break; > } > > + folio_offset = ((index - folio->index) << PAGE_SHIFT) + offset; > + bytes = min(folio_size(folio) - folio_offset, num); > + > + err = -EFAULT; > + if (fault_in_iov_iter_readable(ii, bytes)) { > + folio_unlock(folio); > + folio_put(folio); > + break; > + } This is a deadlock potentially. mmap the file, then buffered write to it with the mmaped region and you will deadlock because fault_in_iov_iter_readable() will try to lock the folio to submit the read, and you're already holding the lock from the __filemap_get_folio() call. If you look at iomap_write_iter it does a the fault_in_iov_iter_readable() call before getting the folio, and it just uses the mapping_max_folio_size() value to fault in larger chunks for whatever folio we manage to grab. Thanks, Josef