Re: [PATCH 05/15] xfs: remove the xfile_pread/pwrite APIs

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

 



On Wed, Jan 03, 2024 at 08:41:16AM +0000, Christoph Hellwig wrote:
> All current and pending xfile users use the xfile_obj_load
> and xfile_obj_store API, so make those the actual implementation.
> 
> Signed-off-by: Christoph Hellwig <hch@xxxxxx>
> ---
>  .../xfs/xfs-online-fsck-design.rst            | 10 +---
>  fs/xfs/scrub/trace.h                          |  4 +-
>  fs/xfs/scrub/xfile.c                          | 54 +++++++++----------
>  fs/xfs/scrub/xfile.h                          | 32 +----------
>  4 files changed, 30 insertions(+), 70 deletions(-)
> 
> diff --git a/Documentation/filesystems/xfs/xfs-online-fsck-design.rst b/Documentation/filesystems/xfs/xfs-online-fsck-design.rst
> index 352516feef6ffe..324d5ec921e8e5 100644
> --- a/Documentation/filesystems/xfs/xfs-online-fsck-design.rst
> +++ b/Documentation/filesystems/xfs/xfs-online-fsck-design.rst
> @@ -1915,19 +1915,13 @@ four of those five higher level data structures.
>  The fifth use case is discussed in the :ref:`realtime summary <rtsummary>` case
>  study.
>  
> -The most general storage interface supported by the xfile enables the reading
> -and writing of arbitrary quantities of data at arbitrary offsets in the xfile.
> -This capability is provided by ``xfile_pread`` and ``xfile_pwrite`` functions,
> -which behave similarly to their userspace counterparts.
>  XFS is very record-based, which suggests that the ability to load and store
>  complete records is important.
>  To support these cases, a pair of ``xfile_obj_load`` and ``xfile_obj_store``
> -functions are provided to read and persist objects into an xfile.
> -They are internally the same as pread and pwrite, except that they treat any
> -error as an out of memory error.
> +functions are provided to read and persist objects into an xfile that unlike
> +the pread and pwrite system calls treat any error as an out of memory error.

I don't think we need to mention pread and pwrite anymore.

"To support these cases, a pair of ``xfile_obj_load`` and ``xfile_obj_store``
functions are provided to read and persist objects into an xfile.  An errors
encountered here are treated as an out of memory error."

>  For online repair, squashing error conditions in this manner is an acceptable
>  behavior because the only reaction is to abort the operation back to userspace.
> -All five xfile usecases can be serviced by these four functions.
>  
>  However, no discussion of file access idioms is complete without answering the
>  question, "But what about mmap?"
> diff --git a/fs/xfs/scrub/trace.h b/fs/xfs/scrub/trace.h
> index ed9e044f6d603c..e6156d000fc615 100644
> --- a/fs/xfs/scrub/trace.h
> +++ b/fs/xfs/scrub/trace.h
> @@ -903,8 +903,8 @@ DECLARE_EVENT_CLASS(xfile_class,
>  DEFINE_EVENT(xfile_class, name, \
>  	TP_PROTO(struct xfile *xf, loff_t pos, unsigned long long bytecount), \
>  	TP_ARGS(xf, pos, bytecount))
> -DEFINE_XFILE_EVENT(xfile_pread);
> -DEFINE_XFILE_EVENT(xfile_pwrite);
> +DEFINE_XFILE_EVENT(xfile_obj_load);
> +DEFINE_XFILE_EVENT(xfile_obj_store);

Want to shorten the names to xfile_load and xfile_store?  That's really
what they're doing anyway.

With those changes,
Reviewed-by: Darrick J. Wong <djwong@xxxxxxxxxx>

--D


>  DEFINE_XFILE_EVENT(xfile_seek_data);
>  DEFINE_XFILE_EVENT(xfile_get_page);
>  DEFINE_XFILE_EVENT(xfile_put_page);
> diff --git a/fs/xfs/scrub/xfile.c b/fs/xfs/scrub/xfile.c
> index 87654cdd5ac6f9..9e25ecf3dc2fec 100644
> --- a/fs/xfs/scrub/xfile.c
> +++ b/fs/xfs/scrub/xfile.c
> @@ -118,13 +118,11 @@ xfile_destroy(
>  }
>  
>  /*
> - * Read a memory object directly from the xfile's page cache.  Unlike regular
> - * pread, we return -E2BIG and -EFBIG for reads that are too large or at too
> - * high an offset, instead of truncating the read.  Otherwise, we return
> - * bytes read or an error code, like regular pread.
> + * Load an object.  Since we're treating this file as "memory", any error or
> + * short IO is treated as a failure to allocate memory.
>   */
> -ssize_t
> -xfile_pread(
> +int
> +xfile_obj_load(
>  	struct xfile		*xf,
>  	void			*buf,
>  	size_t			count,
> @@ -133,16 +131,15 @@ xfile_pread(
>  	struct inode		*inode = file_inode(xf->file);
>  	struct address_space	*mapping = inode->i_mapping;
>  	struct page		*page = NULL;
> -	ssize_t			read = 0;
>  	unsigned int		pflags;
>  	int			error = 0;
>  
>  	if (count > MAX_RW_COUNT)
> -		return -E2BIG;
> +		return -ENOMEM;
>  	if (inode->i_sb->s_maxbytes - pos < count)
> -		return -EFBIG;
> +		return -ENOMEM;
>  
> -	trace_xfile_pread(xf, pos, count);
> +	trace_xfile_obj_load(xf, pos, count);
>  
>  	pflags = memalloc_nofs_save();
>  	while (count > 0) {
> @@ -160,8 +157,10 @@ xfile_pread(
>  				__GFP_NOWARN);
>  		if (IS_ERR(page)) {
>  			error = PTR_ERR(page);
> -			if (error != -ENOMEM)
> +			if (error != -ENOMEM) {
> +				error = -ENOMEM;
>  				break;
> +			}
>  
>  			memset(buf, 0, len);
>  			goto advance;
> @@ -185,23 +184,18 @@ xfile_pread(
>  		count -= len;
>  		pos += len;
>  		buf += len;
> -		read += len;
>  	}
>  	memalloc_nofs_restore(pflags);
>  
> -	if (read > 0)
> -		return read;
>  	return error;
>  }
>  
>  /*
> - * Write a memory object directly to the xfile's page cache.  Unlike regular
> - * pwrite, we return -E2BIG and -EFBIG for writes that are too large or at too
> - * high an offset, instead of truncating the write.  Otherwise, we return
> - * bytes written or an error code, like regular pwrite.
> + * Store an object.  Since we're treating this file as "memory", any error or
> + * short IO is treated as a failure to allocate memory.
>   */
> -ssize_t
> -xfile_pwrite(
> +int
> +xfile_obj_store(
>  	struct xfile		*xf,
>  	const void		*buf,
>  	size_t			count,
> @@ -211,16 +205,15 @@ xfile_pwrite(
>  	struct address_space	*mapping = inode->i_mapping;
>  	const struct address_space_operations *aops = mapping->a_ops;
>  	struct page		*page = NULL;
> -	ssize_t			written = 0;
>  	unsigned int		pflags;
>  	int			error = 0;
>  
>  	if (count > MAX_RW_COUNT)
> -		return -E2BIG;
> +		return -ENOMEM;
>  	if (inode->i_sb->s_maxbytes - pos < count)
> -		return -EFBIG;
> +		return -ENOMEM;
>  
> -	trace_xfile_pwrite(xf, pos, count);
> +	trace_xfile_obj_store(xf, pos, count);
>  
>  	pflags = memalloc_nofs_save();
>  	while (count > 0) {
> @@ -239,8 +232,10 @@ xfile_pwrite(
>  		 */
>  		error = aops->write_begin(NULL, mapping, pos, len, &page,
>  				&fsdata);
> -		if (error)
> +		if (error) {
> +			error = -ENOMEM;
>  			break;
> +		}
>  
>  		/*
>  		 * xfile pages must never be mapped into userspace, so we skip
> @@ -259,13 +254,14 @@ xfile_pwrite(
>  		ret = aops->write_end(NULL, mapping, pos, len, len, page,
>  				fsdata);
>  		if (ret < 0) {
> -			error = ret;
> +			error = -ENOMEM;
>  			break;
>  		}
>  
> -		written += ret;
> -		if (ret != len)
> +		if (ret != len) {
> +			error = -ENOMEM;
>  			break;
> +		}
>  
>  		count -= ret;
>  		pos += ret;
> @@ -273,8 +269,6 @@ xfile_pwrite(
>  	}
>  	memalloc_nofs_restore(pflags);
>  
> -	if (written > 0)
> -		return written;
>  	return error;
>  }
>  
> diff --git a/fs/xfs/scrub/xfile.h b/fs/xfs/scrub/xfile.h
> index c602d11560d8ee..f0e11febf216a7 100644
> --- a/fs/xfs/scrub/xfile.h
> +++ b/fs/xfs/scrub/xfile.h
> @@ -29,38 +29,10 @@ struct xfile {
>  int xfile_create(const char *description, loff_t isize, struct xfile **xfilep);
>  void xfile_destroy(struct xfile *xf);
>  
> -ssize_t xfile_pread(struct xfile *xf, void *buf, size_t count, loff_t pos);
> -ssize_t xfile_pwrite(struct xfile *xf, const void *buf, size_t count,
> +int xfile_obj_load(struct xfile *xf, void *buf, size_t count, loff_t pos);
> +int xfile_obj_store(struct xfile *xf, const void *buf, size_t count,
>  		loff_t pos);
>  
> -/*
> - * Load an object.  Since we're treating this file as "memory", any error or
> - * short IO is treated as a failure to allocate memory.
> - */
> -static inline int
> -xfile_obj_load(struct xfile *xf, void *buf, size_t count, loff_t pos)
> -{
> -	ssize_t	ret = xfile_pread(xf, buf, count, pos);
> -
> -	if (ret < 0 || ret != count)
> -		return -ENOMEM;
> -	return 0;
> -}
> -
> -/*
> - * Store an object.  Since we're treating this file as "memory", any error or
> - * short IO is treated as a failure to allocate memory.
> - */
> -static inline int
> -xfile_obj_store(struct xfile *xf, const void *buf, size_t count, loff_t pos)
> -{
> -	ssize_t	ret = xfile_pwrite(xf, buf, count, pos);
> -
> -	if (ret < 0 || ret != count)
> -		return -ENOMEM;
> -	return 0;
> -}
> -
>  loff_t xfile_seek_data(struct xfile *xf, loff_t pos);
>  
>  int xfile_get_page(struct xfile *xf, loff_t offset, unsigned int len,
> -- 
> 2.39.2
> 
> 




[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Bugtraq]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux