Re: [PATCH v7 04/19] iov_iter: Turn iov_iter_fault_in_readable into fault_in_iov_iter_readable

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Aug 27, 2021 at 11:56:44PM +0300, Kari Argillander wrote:
> On Fri, Aug 27, 2021 at 06:49:11PM +0200, Andreas Gruenbacher wrote:
> > Turn iov_iter_fault_in_readable into a function that returns the number
> > of bytes not faulted in (similar to copy_to_user) instead of returning a
> > non-zero value when any of the requested pages couldn't be faulted in.
> > This supports the existing users that require all pages to be faulted in
> > as well as new users that are happy if any pages can be faulted in at
> > all.
> > 
> > Rename iov_iter_fault_in_readable to fault_in_iov_iter_readable to make
> > sure that this change doesn't silently break things.
> 
> At least this patch will break ntfs3 which is in next. It has been there
> just couple weeks so I understand. I added Konstantin and ntfs3 list so
> that we know what is going on. Can you please info if and when do we
> need rebase.
> 
> We are in situation that ntfs3 might get in 5.15, but it is uncertain so
> it would be best that we solve this. Just info is enough.

I forget to add permalink for the thread.
lore.kernel.org/linux-fsdevel/20210827164926.1726765-1-agruenba@xxxxxxxxxx/

Please do not respond this message. I dropped people from CC.

> 
> Argillander
> 
> > 
> > Signed-off-by: Andreas Gruenbacher <agruenba@xxxxxxxxxx>
> > ---
> >  fs/btrfs/file.c        |  2 +-
> >  fs/f2fs/file.c         |  2 +-
> >  fs/fuse/file.c         |  2 +-
> >  fs/iomap/buffered-io.c |  2 +-
> >  fs/ntfs/file.c         |  2 +-
> >  include/linux/uio.h    |  2 +-
> >  lib/iov_iter.c         | 33 +++++++++++++++++++++------------
> >  mm/filemap.c           |  2 +-
> >  8 files changed, 28 insertions(+), 19 deletions(-)
> > 
> > diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c
> > index ee34497500e1..281c77cfe91a 100644
> > --- a/fs/btrfs/file.c
> > +++ b/fs/btrfs/file.c
> > @@ -1698,7 +1698,7 @@ static noinline ssize_t btrfs_buffered_write(struct kiocb *iocb,
> >  		 * Fault pages before locking them in prepare_pages
> >  		 * to avoid recursive lock
> >  		 */
> > -		if (unlikely(iov_iter_fault_in_readable(i, write_bytes))) {
> > +		if (unlikely(fault_in_iov_iter_readable(i, write_bytes))) {
> >  			ret = -EFAULT;
> >  			break;
> >  		}
> > diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
> > index 6afd4562335f..b04b6c909a8b 100644
> > --- a/fs/f2fs/file.c
> > +++ b/fs/f2fs/file.c
> > @@ -4259,7 +4259,7 @@ static ssize_t f2fs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
> >  		size_t target_size = 0;
> >  		int err;
> >  
> > -		if (iov_iter_fault_in_readable(from, iov_iter_count(from)))
> > +		if (fault_in_iov_iter_readable(from, iov_iter_count(from)))
> >  			set_inode_flag(inode, FI_NO_PREALLOC);
> >  
> >  		if ((iocb->ki_flags & IOCB_NOWAIT)) {
> > diff --git a/fs/fuse/file.c b/fs/fuse/file.c
> > index 97f860cfc195..da49ef71dab5 100644
> > --- a/fs/fuse/file.c
> > +++ b/fs/fuse/file.c
> > @@ -1160,7 +1160,7 @@ static ssize_t fuse_fill_write_pages(struct fuse_io_args *ia,
> >  
> >   again:
> >  		err = -EFAULT;
> > -		if (iov_iter_fault_in_readable(ii, bytes))
> > +		if (fault_in_iov_iter_readable(ii, bytes))
> >  			break;
> >  
> >  		err = -ENOMEM;
> > diff --git a/fs/iomap/buffered-io.c b/fs/iomap/buffered-io.c
> > index 87ccb3438bec..7dc42dd3a724 100644
> > --- a/fs/iomap/buffered-io.c
> > +++ b/fs/iomap/buffered-io.c
> > @@ -749,7 +749,7 @@ iomap_write_actor(struct inode *inode, loff_t pos, loff_t length, void *data,
> >  		 * same page as we're writing to, without it being marked
> >  		 * up-to-date.
> >  		 */
> > -		if (unlikely(iov_iter_fault_in_readable(i, bytes))) {
> > +		if (unlikely(fault_in_iov_iter_readable(i, bytes))) {
> >  			status = -EFAULT;
> >  			break;
> >  		}
> > diff --git a/fs/ntfs/file.c b/fs/ntfs/file.c
> > index ab4f3362466d..a43adeacd930 100644
> > --- a/fs/ntfs/file.c
> > +++ b/fs/ntfs/file.c
> > @@ -1829,7 +1829,7 @@ static ssize_t ntfs_perform_write(struct file *file, struct iov_iter *i,
> >  		 * pages being swapped out between us bringing them into memory
> >  		 * and doing the actual copying.
> >  		 */
> > -		if (unlikely(iov_iter_fault_in_readable(i, bytes))) {
> > +		if (unlikely(fault_in_iov_iter_readable(i, bytes))) {
> >  			status = -EFAULT;
> >  			break;
> >  		}
> > diff --git a/include/linux/uio.h b/include/linux/uio.h
> > index 82c3c3e819e0..12d30246c2e9 100644
> > --- a/include/linux/uio.h
> > +++ b/include/linux/uio.h
> > @@ -119,7 +119,7 @@ size_t copy_page_from_iter_atomic(struct page *page, unsigned offset,
> >  				  size_t bytes, struct iov_iter *i);
> >  void iov_iter_advance(struct iov_iter *i, size_t bytes);
> >  void iov_iter_revert(struct iov_iter *i, size_t bytes);
> > -int iov_iter_fault_in_readable(const struct iov_iter *i, size_t bytes);
> > +size_t fault_in_iov_iter_readable(const struct iov_iter *i, size_t bytes);
> >  size_t iov_iter_single_seg_count(const struct iov_iter *i);
> >  size_t copy_page_to_iter(struct page *page, size_t offset, size_t bytes,
> >  			 struct iov_iter *i);
> > diff --git a/lib/iov_iter.c b/lib/iov_iter.c
> > index 069cedd9d7b4..082ab155496d 100644
> > --- a/lib/iov_iter.c
> > +++ b/lib/iov_iter.c
> > @@ -430,33 +430,42 @@ static size_t copy_page_to_iter_pipe(struct page *page, size_t offset, size_t by
> >  }
> >  
> >  /*
> > + * fault_in_iov_iter_readable - fault in iov iterator for reading
> > + * @i: iterator
> > + * @size: maximum length
> > + *
> >   * Fault in one or more iovecs of the given iov_iter, to a maximum length of
> > - * bytes.  For each iovec, fault in each page that constitutes the iovec.
> > + * @size.  For each iovec, fault in each page that constitutes the iovec.
> > + *
> > + * Returns the number of bytes not faulted in (like copy_to_user() and
> > + * copy_from_user()).
> >   *
> > - * Return 0 on success, or non-zero if the memory could not be accessed (i.e.
> > - * because it is an invalid address).
> > + * Always returns 0 for non-userspace iterators.
> >   */
> > -int iov_iter_fault_in_readable(const struct iov_iter *i, size_t bytes)
> > +size_t fault_in_iov_iter_readable(const struct iov_iter *i, size_t size)
> >  {
> >  	if (iter_is_iovec(i)) {
> > +		size_t count = min(size, iov_iter_count(i));
> >  		const struct iovec *p;
> >  		size_t skip;
> >  
> > -		if (bytes > i->count)
> > -			bytes = i->count;
> > -		for (p = i->iov, skip = i->iov_offset; bytes; p++, skip = 0) {
> > -			size_t len = min(bytes, p->iov_len - skip);
> > +		size -= count;
> > +		for (p = i->iov, skip = i->iov_offset; count; p++, skip = 0) {
> > +			size_t len = min(count, p->iov_len - skip);
> > +			size_t ret;
> >  
> >  			if (unlikely(!len))
> >  				continue;
> > -			if (fault_in_readable(p->iov_base + skip, len))
> > -				return -EFAULT;
> > -			bytes -= len;
> > +			ret = fault_in_readable(p->iov_base + skip, len);
> > +			count -= len - ret;
> > +			if (ret)
> > +				break;
> >  		}
> > +		return count + size;
> >  	}
> >  	return 0;
> >  }
> > -EXPORT_SYMBOL(iov_iter_fault_in_readable);
> > +EXPORT_SYMBOL(fault_in_iov_iter_readable);
> >  
> >  void iov_iter_init(struct iov_iter *i, unsigned int direction,
> >  			const struct iovec *iov, unsigned long nr_segs,
> > diff --git a/mm/filemap.c b/mm/filemap.c
> > index 4dec3bc7752e..83af8a534339 100644
> > --- a/mm/filemap.c
> > +++ b/mm/filemap.c
> > @@ -3643,7 +3643,7 @@ ssize_t generic_perform_write(struct file *file,
> >  		 * same page as we're writing to, without it being marked
> >  		 * up-to-date.
> >  		 */
> > -		if (unlikely(iov_iter_fault_in_readable(i, bytes))) {
> > +		if (unlikely(fault_in_iov_iter_readable(i, bytes))) {
> >  			status = -EFAULT;
> >  			break;
> >  		}
> > -- 
> > 2.26.3
> > 
> 




[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux