Matthew Wilcox <willy@xxxxxxxxxxxxx> wrote: > On Wed, Nov 03, 2021 at 02:58:12PM +0000, David Howells wrote: > > Matthew Wilcox <willy@xxxxxxxxxxxxx> wrote: > > > > > > + len = (size >= start + gran) ? gran : size - start; > > > > > > This seems like the most complicated way to write this ... how about: > > > > > > size_t len = min_t(loff_t, isize - start, folio_size(folio)); > > > > I was trying to hedge against isize-start going negative. Can this code race > > against truncate? truncate_setsize() changes i_size *before* invalidating the > > pages. > > We should check for isize < start separately, and skip the writeback > entirely. So, something like the following static int v9fs_vfs_write_folio_locked(struct folio *folio) { struct inode *inode = folio_inode(folio); struct v9fs_inode *v9inode = V9FS_I(inode); loff_t start = folio_pos(folio); loff_t i_size = i_size_read(inode); struct iov_iter from; size_t len = folio_size(folio); int err; if (start >= i_size) return 0; /* Simultaneous truncation occurred */ len = min_t(loff_t, i_size - start, len); iov_iter_xarray(&from, ..., start, len); ... } David