From: "Darrick J. Wong" <darrick.wong@oracle.com>
To: Christoph Hellwig <hch@lst.de>
Cc: linux-xfs@vger.kernel.org, linux-fsdevel@vger.kernel.org
Subject: Re: [PATCH 2/4] fs: add generic UNRESVSP and ZERO_RANGE ioctl handlers
Date: Thu, 24 Oct 2019 22:44:52 -0700 [thread overview]
Message-ID: <20191025054452.GF913374@magnolia> (raw)
In-Reply-To: <20191025023609.22295-3-hch@lst.de>
On Fri, Oct 25, 2019 at 11:36:07AM +0900, Christoph Hellwig wrote:
> These use the same scheme as the pre-existing mapping of the XFS
> RESVP ioctls to ->falloc, so just extend it and remove the XFS
> implementation.
>
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> ---
> fs/compat_ioctl.c | 32 ++++++++++++++++---
> fs/ioctl.c | 12 +++++--
> fs/xfs/xfs_ioctl.c | 72 +++++++-----------------------------------
> fs/xfs/xfs_ioctl.h | 1 -
> fs/xfs/xfs_ioctl32.c | 7 ++--
> include/linux/falloc.h | 3 ++
> include/linux/fs.h | 2 +-
> 7 files changed, 54 insertions(+), 75 deletions(-)
>
> diff --git a/fs/compat_ioctl.c b/fs/compat_ioctl.c
> index a7ec2d3dff92..7d920dda2811 100644
> --- a/fs/compat_ioctl.c
> +++ b/fs/compat_ioctl.c
> @@ -480,11 +480,14 @@ struct space_resv_32 {
> __s32 l_pad[4]; /* reserve area */
> };
>
> -#define FS_IOC_RESVSP_32 _IOW ('X', 40, struct space_resv_32)
> +#define FS_IOC_RESVSP_32 _IOW ('X', 40, struct space_resv_32)
> +#define FS_IOC_UNRESVSP_32 _IOW ('X', 41, struct space_resv_32)
> #define FS_IOC_RESVSP64_32 _IOW ('X', 42, struct space_resv_32)
> +#define FS_IOC_UNRESVSP64_32 _IOW ('X', 43, struct space_resv_32)
> +#define FS_IOC_ZERO_RANGE_32 _IOW ('X', 57, struct space_resv_32)
>
> /* just account for different alignment */
> -static int compat_ioctl_preallocate(struct file *file,
> +static int compat_ioctl_preallocate(struct file *file, int mode,
> struct space_resv_32 __user *p32)
> {
> struct space_resv __user *p = compat_alloc_user_space(sizeof(*p));
> @@ -498,7 +501,7 @@ static int compat_ioctl_preallocate(struct file *file,
> copy_in_user(&p->l_pad, &p32->l_pad, 4*sizeof(u32)))
> return -EFAULT;
>
> - return ioctl_preallocate(file, p);
> + return ioctl_preallocate(file, mode, p);
> }
> #endif
>
> @@ -1022,13 +1025,32 @@ COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd,
> #if defined(CONFIG_IA64) || defined(CONFIG_X86_64)
> case FS_IOC_RESVSP_32:
> case FS_IOC_RESVSP64_32:
> - error = compat_ioctl_preallocate(f.file, compat_ptr(arg));
> + error = compat_ioctl_preallocate(f.file, 0, compat_ptr(arg));
> + goto out_fput;
> + case FS_IOC_UNRESVSP_32:
> + case FS_IOC_UNRESVSP64_32:
> + error = compat_ioctl_preallocate(f.file, FALLOC_FL_PUNCH_HOLE,
> + compat_ptr(arg));
> + goto out_fput;
> + case FS_IOC_ZERO_RANGE_32:
> + error = compat_ioctl_preallocate(f.file, FALLOC_FL_ZERO_RANGE,
> + compat_ptr(arg));
> goto out_fput;
> #else
> case FS_IOC_RESVSP:
> case FS_IOC_RESVSP64:
> - error = ioctl_preallocate(f.file, compat_ptr(arg));
> + error = ioctl_preallocate(f.file, 0, compat_ptr(arg));
> + goto out_fput;
> + case FS_IOC_UNRESVSP:
> + case FS_IOC_UNRESVSP64:
> + error = ioctl_preallocate(f.file, FALLOC_FL_PUNCH_HOLE,
> + compat_ptr(arg));
> goto out_fput;
> + case FS_IOC_ZERO_RANGE:
> + error = ioctl_preallocate(f.file, FALLOC_FL_ZERO_RANGE,
> + compat_ptr(arg));
> + goto out_fput;
> + }
> #endif
>
> case FICLONE:
> diff --git a/fs/ioctl.c b/fs/ioctl.c
> index fef3a6bf7c78..55c7cfb0e599 100644
> --- a/fs/ioctl.c
> +++ b/fs/ioctl.c
> @@ -466,7 +466,7 @@ EXPORT_SYMBOL(generic_block_fiemap);
> * Only the l_start, l_len and l_whence fields of the 'struct space_resv'
> * are used here, rest are ignored.
> */
> -int ioctl_preallocate(struct file *filp, void __user *argp)
> +int ioctl_preallocate(struct file *filp, int mode, void __user *argp)
> {
> struct inode *inode = file_inode(filp);
> struct space_resv sr;
> @@ -487,7 +487,8 @@ int ioctl_preallocate(struct file *filp, void __user *argp)
> return -EINVAL;
> }
>
> - return vfs_fallocate(filp, FALLOC_FL_KEEP_SIZE, sr.l_start, sr.l_len);
> + return vfs_fallocate(filp, mode | FALLOC_FL_KEEP_SIZE, sr.l_start,
> + sr.l_len);
> }
>
> static int file_ioctl(struct file *filp, unsigned int cmd,
> @@ -503,7 +504,12 @@ static int file_ioctl(struct file *filp, unsigned int cmd,
> return put_user(i_size_read(inode) - filp->f_pos, p);
> case FS_IOC_RESVSP:
> case FS_IOC_RESVSP64:
> - return ioctl_preallocate(filp, p);
> + return ioctl_preallocate(filp, 0, p);
> + case FS_IOC_UNRESVSP:
> + case FS_IOC_UNRESVSP64:
> + return ioctl_preallocate(filp, FALLOC_FL_PUNCH_HOLE, p);
> + case FS_IOC_ZERO_RANGE:
> + return ioctl_preallocate(filp, FALLOC_FL_ZERO_RANGE, p);
> }
>
> return vfs_ioctl(filp, cmd, arg);
> diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
> index da4aaa75cfd3..3fe1543f9f02 100644
> --- a/fs/xfs/xfs_ioctl.c
> +++ b/fs/xfs/xfs_ioctl.c
> @@ -588,13 +588,12 @@ xfs_attrmulti_by_handle(
> int
> xfs_ioc_space(
> struct file *filp,
> - unsigned int cmd,
> xfs_flock64_t *bf)
> {
> struct inode *inode = file_inode(filp);
> struct xfs_inode *ip = XFS_I(inode);
> struct iattr iattr;
> - enum xfs_prealloc_flags flags = 0;
> + enum xfs_prealloc_flags flags = XFS_PREALLOC_CLEAR;
> uint iolock = XFS_IOLOCK_EXCL | XFS_MMAPLOCK_EXCL;
> int error;
>
> @@ -635,65 +634,21 @@ xfs_ioc_space(
> goto out_unlock;
> }
>
> - /*
> - * length of <= 0 for resv/unresv/zero is invalid. length for
> - * alloc/free is ignored completely and we have no idea what userspace
> - * might have set it to, so set it to zero to allow range
> - * checks to pass.
> - */
> - switch (cmd) {
> - case XFS_IOC_ZERO_RANGE:
> - case XFS_IOC_UNRESVSP:
> - case XFS_IOC_UNRESVSP64:
> - if (bf->l_len <= 0) {
> - error = -EINVAL;
> - goto out_unlock;
> - }
> - break;
> - default:
> - bf->l_len = 0;
> - break;
> - }
> -
> - if (bf->l_start < 0 ||
> - bf->l_start > inode->i_sb->s_maxbytes ||
> - bf->l_start + bf->l_len < 0 ||
> - bf->l_start + bf->l_len >= inode->i_sb->s_maxbytes) {
> + if (bf->l_start < 0 || bf->l_start > inode->i_sb->s_maxbytes) {
> error = -EINVAL;
> goto out_unlock;
> }
>
> - switch (cmd) {
> - case XFS_IOC_ZERO_RANGE:
> - flags |= XFS_PREALLOC_SET;
> - error = xfs_zero_file_space(ip, bf->l_start, bf->l_len);
> - break;
> - case XFS_IOC_UNRESVSP:
> - case XFS_IOC_UNRESVSP64:
> - error = xfs_free_file_space(ip, bf->l_start, bf->l_len);
> - break;
> - case XFS_IOC_ALLOCSP:
> - case XFS_IOC_ALLOCSP64:
> - case XFS_IOC_FREESP:
> - case XFS_IOC_FREESP64:
> - flags |= XFS_PREALLOC_CLEAR;
> - if (bf->l_start > XFS_ISIZE(ip)) {
> - error = xfs_alloc_file_space(ip, XFS_ISIZE(ip),
> - bf->l_start - XFS_ISIZE(ip), 0);
> - if (error)
> - goto out_unlock;
> - }
> -
> - iattr.ia_valid = ATTR_SIZE;
> - iattr.ia_size = bf->l_start;
> -
> - error = xfs_vn_setattr_size(file_dentry(filp), &iattr);
> - break;
> - default:
> - ASSERT(0);
> - error = -EINVAL;
> + if (bf->l_start > XFS_ISIZE(ip)) {
> + error = xfs_alloc_file_space(ip, XFS_ISIZE(ip),
> + bf->l_start - XFS_ISIZE(ip), 0);
> + if (error)
> + goto out_unlock;
> }
>
> + iattr.ia_valid = ATTR_SIZE;
> + iattr.ia_size = bf->l_start;
> + error = xfs_vn_setattr_size(file_dentry(filp), &iattr);
> if (error)
> goto out_unlock;
>
> @@ -2113,16 +2068,13 @@ xfs_file_ioctl(
> return xfs_ioc_setlabel(filp, mp, arg);
> case XFS_IOC_ALLOCSP:
> case XFS_IOC_FREESP:
> - case XFS_IOC_UNRESVSP:
> case XFS_IOC_ALLOCSP64:
> - case XFS_IOC_FREESP64:
> - case XFS_IOC_UNRESVSP64:
> - case XFS_IOC_ZERO_RANGE: {
> + case XFS_IOC_FREESP64: {
Ok, so this hoists everything to the vfs except for ALLOCSP and FREESP,
which seems to be ... "set new size; allocate between old and new EOF if
appropriate"?
I'm asking because I was never really clear on what those things are
supposed to do. :)
--D
> xfs_flock64_t bf;
>
> if (copy_from_user(&bf, arg, sizeof(bf)))
> return -EFAULT;
> - return xfs_ioc_space(filp, cmd, &bf);
> + return xfs_ioc_space(filp, &bf);
> }
> case XFS_IOC_DIOINFO: {
> struct dioattr da;
> diff --git a/fs/xfs/xfs_ioctl.h b/fs/xfs/xfs_ioctl.h
> index 654c0bb1bcf8..25ef178cbb74 100644
> --- a/fs/xfs/xfs_ioctl.h
> +++ b/fs/xfs/xfs_ioctl.h
> @@ -9,7 +9,6 @@
> extern int
> xfs_ioc_space(
> struct file *filp,
> - unsigned int cmd,
> xfs_flock64_t *bf);
>
> int
> diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
> index 257b7caf7fed..3c0d518e1039 100644
> --- a/fs/xfs/xfs_ioctl32.c
> +++ b/fs/xfs/xfs_ioctl32.c
> @@ -557,16 +557,13 @@ xfs_file_compat_ioctl(
> case XFS_IOC_ALLOCSP_32:
> case XFS_IOC_FREESP_32:
> case XFS_IOC_ALLOCSP64_32:
> - case XFS_IOC_FREESP64_32:
> - case XFS_IOC_RESVSP64_32:
> - case XFS_IOC_UNRESVSP64_32:
> - case XFS_IOC_ZERO_RANGE_32: {
> + case XFS_IOC_FREESP64_32: {
> struct xfs_flock64 bf;
>
> if (xfs_compat_flock64_copyin(&bf, arg))
> return -EFAULT;
> cmd = _NATIVE_IOC(cmd, struct xfs_flock64);
> - return xfs_ioc_space(filp, cmd, &bf);
> + return xfs_ioc_space(filp, &bf);
> }
> case XFS_IOC_FSGEOMETRY_V1_32:
> return xfs_compat_ioc_fsgeometry_v1(mp, arg);
> diff --git a/include/linux/falloc.h b/include/linux/falloc.h
> index 674d59f4d6ce..f5c73f0ec22d 100644
> --- a/include/linux/falloc.h
> +++ b/include/linux/falloc.h
> @@ -20,7 +20,10 @@ struct space_resv {
> };
>
> #define FS_IOC_RESVSP _IOW('X', 40, struct space_resv)
> +#define FS_IOC_UNRESVSP _IOW('X', 41, struct space_resv)
> #define FS_IOC_RESVSP64 _IOW('X', 42, struct space_resv)
> +#define FS_IOC_UNRESVSP64 _IOW('X', 43, struct space_resv)
> +#define FS_IOC_ZERO_RANGE _IOW('X', 57, struct space_resv)
>
> #define FALLOC_FL_SUPPORTED_MASK (FALLOC_FL_KEEP_SIZE | \
> FALLOC_FL_PUNCH_HOLE | \
> diff --git a/include/linux/fs.h b/include/linux/fs.h
> index e0d909d35763..2b5692207c1d 100644
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
> @@ -2547,7 +2547,7 @@ extern int finish_no_open(struct file *file, struct dentry *dentry);
>
> /* fs/ioctl.c */
>
> -extern int ioctl_preallocate(struct file *filp, void __user *argp);
> +extern int ioctl_preallocate(struct file *filp, int mode, void __user *argp);
>
> /* fs/dcache.c */
> extern void __init vfs_caches_init_early(void);
> --
> 2.20.1
>
next prev parent reply other threads:[~2019-10-25 5:45 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-10-25 2:36 clean up xfs space management interfaces Christoph Hellwig
2019-10-25 2:36 ` [PATCH 1/4] xfs: don't implement XFS_IOC_RESVSP / XFS_IOC_RESVSP64 directly Christoph Hellwig
2019-10-25 5:32 ` Darrick J. Wong
2019-10-25 2:36 ` [PATCH 2/4] fs: add generic UNRESVSP and ZERO_RANGE ioctl handlers Christoph Hellwig
2019-10-25 5:44 ` Darrick J. Wong [this message]
2019-10-25 9:50 ` Christoph Hellwig
2019-10-26 20:56 ` Dave Chinner
2019-10-27 15:19 ` Christoph Hellwig
2019-10-25 2:36 ` [PATCH 3/4] xfs: disable xfs_ioc_space for always COW inodes Christoph Hellwig
2019-10-25 5:45 ` Darrick J. Wong
2019-10-25 2:36 ` [PATCH 4/4] xfs: consolidate preallocation in xfs_file_fallocate Christoph Hellwig
2019-10-25 5:48 ` Darrick J. Wong
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20191025054452.GF913374@magnolia \
--to=darrick.wong@oracle.com \
--cc=hch@lst.de \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-xfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).