From: "Darrick J. Wong" <djwong@kernel.org>
To: Miklos Szeredi <mszeredi@redhat.com>
Cc: linux-fsdevel@vger.kernel.org, Al Viro <viro@ZenIV.linux.org.uk>,
linux-kernel@vger.kernel.org, Christoph Hellwig <hch@lst.de>
Subject: Re: [PATCH v2 10/18] xfs: convert to miscattr
Date: Mon, 22 Mar 2021 15:51:31 -0700 [thread overview]
Message-ID: <20210322225131.GE22094@magnolia> (raw)
In-Reply-To: <20210322144916.137245-11-mszeredi@redhat.com>
On Mon, Mar 22, 2021 at 03:49:08PM +0100, Miklos Szeredi wrote:
> Use the miscattr API to let the VFS handle locking, permission checking and
> conversion.
>
> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
> Cc: Darrick J. Wong <djwong@kernel.org>
> ---
> fs/xfs/libxfs/xfs_fs.h | 4 -
> fs/xfs/xfs_ioctl.c | 316 ++++++++++++-----------------------------
> fs/xfs/xfs_ioctl.h | 11 ++
> fs/xfs/xfs_ioctl32.c | 2 -
> fs/xfs/xfs_ioctl32.h | 2 -
> fs/xfs/xfs_iops.c | 7 +
> 6 files changed, 107 insertions(+), 235 deletions(-)
>
> diff --git a/fs/xfs/libxfs/xfs_fs.h b/fs/xfs/libxfs/xfs_fs.h
> index 6fad140d4c8e..6bf7d8b7d743 100644
> --- a/fs/xfs/libxfs/xfs_fs.h
> +++ b/fs/xfs/libxfs/xfs_fs.h
> @@ -770,8 +770,6 @@ struct xfs_scrub_metadata {
> /*
> * ioctl commands that are used by Linux filesystems
> */
> -#define XFS_IOC_GETXFLAGS FS_IOC_GETFLAGS
> -#define XFS_IOC_SETXFLAGS FS_IOC_SETFLAGS
> #define XFS_IOC_GETVERSION FS_IOC_GETVERSION
>
> /*
> @@ -782,8 +780,6 @@ struct xfs_scrub_metadata {
> #define XFS_IOC_ALLOCSP _IOW ('X', 10, struct xfs_flock64)
> #define XFS_IOC_FREESP _IOW ('X', 11, struct xfs_flock64)
> #define XFS_IOC_DIOINFO _IOR ('X', 30, struct dioattr)
> -#define XFS_IOC_FSGETXATTR FS_IOC_FSGETXATTR
> -#define XFS_IOC_FSSETXATTR FS_IOC_FSSETXATTR
> #define XFS_IOC_ALLOCSP64 _IOW ('X', 36, struct xfs_flock64)
> #define XFS_IOC_FREESP64 _IOW ('X', 37, struct xfs_flock64)
> #define XFS_IOC_GETBMAP _IOWR('X', 38, struct getbmap)
> diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
> index 99dfe89a8d08..e27e3ff9a651 100644
> --- a/fs/xfs/xfs_ioctl.c
> +++ b/fs/xfs/xfs_ioctl.c
> @@ -40,6 +40,7 @@
>
> #include <linux/mount.h>
> #include <linux/namei.h>
> +#include <linux/miscattr.h>
>
> /*
> * xfs_find_handle maps from userspace xfs_fsop_handlereq structure to
> @@ -1053,97 +1054,51 @@ xfs_ioc_ag_geometry(
> * Linux extended inode flags interface.
> */
>
> -STATIC unsigned int
> -xfs_merge_ioc_xflags(
> - unsigned int flags,
> - unsigned int start)
> -{
> - unsigned int xflags = start;
> -
> - if (flags & FS_IMMUTABLE_FL)
> - xflags |= FS_XFLAG_IMMUTABLE;
> - else
> - xflags &= ~FS_XFLAG_IMMUTABLE;
> - if (flags & FS_APPEND_FL)
> - xflags |= FS_XFLAG_APPEND;
> - else
> - xflags &= ~FS_XFLAG_APPEND;
> - if (flags & FS_SYNC_FL)
> - xflags |= FS_XFLAG_SYNC;
> - else
> - xflags &= ~FS_XFLAG_SYNC;
> - if (flags & FS_NOATIME_FL)
> - xflags |= FS_XFLAG_NOATIME;
> - else
> - xflags &= ~FS_XFLAG_NOATIME;
> - if (flags & FS_NODUMP_FL)
> - xflags |= FS_XFLAG_NODUMP;
> - else
> - xflags &= ~FS_XFLAG_NODUMP;
> - if (flags & FS_DAX_FL)
> - xflags |= FS_XFLAG_DAX;
> - else
> - xflags &= ~FS_XFLAG_DAX;
> -
> - return xflags;
> -}
> -
> -STATIC unsigned int
> -xfs_di2lxflags(
> - uint16_t di_flags,
> - uint64_t di_flags2)
> -{
> - unsigned int flags = 0;
> -
> - if (di_flags & XFS_DIFLAG_IMMUTABLE)
> - flags |= FS_IMMUTABLE_FL;
> - if (di_flags & XFS_DIFLAG_APPEND)
> - flags |= FS_APPEND_FL;
> - if (di_flags & XFS_DIFLAG_SYNC)
> - flags |= FS_SYNC_FL;
> - if (di_flags & XFS_DIFLAG_NOATIME)
> - flags |= FS_NOATIME_FL;
> - if (di_flags & XFS_DIFLAG_NODUMP)
> - flags |= FS_NODUMP_FL;
> - if (di_flags2 & XFS_DIFLAG2_DAX) {
> - flags |= FS_DAX_FL;
> - }
> - return flags;
> -}
> -
> static void
> xfs_fill_fsxattr(
> struct xfs_inode *ip,
> bool attr,
> - struct fsxattr *fa)
> + struct miscattr *ma)
> {
> struct xfs_ifork *ifp = attr ? ip->i_afp : &ip->i_df;
Hm, could you replace "bool attr" with "int whichfork"? The new
signature and first line of code becomes:
static void
xfs_fill_fsxattr(
struct xfs_inode *ip,
int whichfork,
struct miscattr *ma)
{
struct xfs_ifork *ifp = XFS_IFORK_PTR(ip, whichfork);
...and then the two wrappers of xfs_fill_fsxattr become:
STATIC int
xfs_ioc_fsgetxattra(
struct xfs_inode *ip,
void __user *arg)
{
struct miscattr ma;
xfs_ilock(ip, XFS_ILOCK_SHARED);
xfs_fill_fsxattr(ip, XFS_ATTR_FORK, &ma);
xfs_iunlock(ip, XFS_ILOCK_SHARED);
return fsxattr_copy_to_user(&ma, arg);
}
int
xfs_miscattr_get(
struct dentry *dentry,
struct miscattr *ma)
{
struct xfs_inode *ip = XFS_I(d_inode(dentry));
xfs_ilock(ip, XFS_ILOCK_SHARED);
xfs_fill_fsxattr(ip, XFS_DATA_FORK, ma);
xfs_iunlock(ip, XFS_ILOCK_SHARED);
return 0;
}
This makes it clearer that FSGETXATTRA reports on the extended attributes
fork, and regular GETFLAGS/FSGETXATTR reports on the data fork.
> - simple_fill_fsxattr(fa, xfs_ip2xflags(ip));
> - fa->fsx_extsize = ip->i_d.di_extsize << ip->i_mount->m_sb.sb_blocklog;
> - fa->fsx_cowextsize = ip->i_d.di_cowextsize <<
> + miscattr_fill_xflags(ma, xfs_ip2xflags(ip));
> + ma->flags &= ~FS_PROJINHERIT_FL; /* Accidental? */
Yes, this was an oversight when ext4/f2fs added PROJINHERIT_FL.
> + ma->fsx_extsize = ip->i_d.di_extsize << ip->i_mount->m_sb.sb_blocklog;
> + ma->fsx_cowextsize = ip->i_d.di_cowextsize <<
> ip->i_mount->m_sb.sb_blocklog;
> - fa->fsx_projid = ip->i_d.di_projid;
> + ma->fsx_projid = ip->i_d.di_projid;
> if (ifp && (ifp->if_flags & XFS_IFEXTENTS))
> - fa->fsx_nextents = xfs_iext_count(ifp);
> + ma->fsx_nextents = xfs_iext_count(ifp);
> else
> - fa->fsx_nextents = xfs_ifork_nextents(ifp);
> + ma->fsx_nextents = xfs_ifork_nextents(ifp);
> }
>
> STATIC int
> -xfs_ioc_fsgetxattr(
> +xfs_ioc_fsgetxattra(
> xfs_inode_t *ip,
> - int attr,
> void __user *arg)
> {
> - struct fsxattr fa;
> + struct miscattr ma;
>
> xfs_ilock(ip, XFS_ILOCK_SHARED);
> - xfs_fill_fsxattr(ip, attr, &fa);
> + xfs_fill_fsxattr(ip, true, &ma);
> + xfs_iunlock(ip, XFS_ILOCK_SHARED);
> +
> + return fsxattr_copy_to_user(&ma, arg);
> +}
> +
> +int
> +xfs_miscattr_get(
> + struct dentry *dentry,
> + struct miscattr *ma)
> +{
> + xfs_inode_t *ip = XFS_I(d_inode(dentry));
Please don't use struct typedefs. We're trying to get rid of these.
struct xfs_inode *ip = XFS_I(...);
> +
> + xfs_ilock(ip, XFS_ILOCK_SHARED);
> + xfs_fill_fsxattr(ip, false, ma);
> xfs_iunlock(ip, XFS_ILOCK_SHARED);
>
> - if (copy_to_user(arg, &fa, sizeof(fa)))
> - return -EFAULT;
> return 0;
> }
>
> @@ -1210,37 +1165,37 @@ static int
> xfs_ioctl_setattr_xflags(
> struct xfs_trans *tp,
> struct xfs_inode *ip,
> - struct fsxattr *fa)
> + struct miscattr *ma)
> {
> struct xfs_mount *mp = ip->i_mount;
> uint64_t di_flags2;
>
> /* Can't change realtime flag if any extents are allocated. */
> if ((ip->i_df.if_nextents || ip->i_delayed_blks) &&
> - XFS_IS_REALTIME_INODE(ip) != (fa->fsx_xflags & FS_XFLAG_REALTIME))
> + XFS_IS_REALTIME_INODE(ip) != (ma->fsx_xflags & FS_XFLAG_REALTIME))
> return -EINVAL;
>
> /* If realtime flag is set then must have realtime device */
> - if (fa->fsx_xflags & FS_XFLAG_REALTIME) {
> + if (ma->fsx_xflags & FS_XFLAG_REALTIME) {
> if (mp->m_sb.sb_rblocks == 0 || mp->m_sb.sb_rextsize == 0 ||
> (ip->i_d.di_extsize % mp->m_sb.sb_rextsize))
> return -EINVAL;
> }
>
> /* Clear reflink if we are actually able to set the rt flag. */
> - if ((fa->fsx_xflags & FS_XFLAG_REALTIME) && xfs_is_reflink_inode(ip))
> + if ((ma->fsx_xflags & FS_XFLAG_REALTIME) && xfs_is_reflink_inode(ip))
> ip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK;
>
> /* Don't allow us to set DAX mode for a reflinked file for now. */
> - if ((fa->fsx_xflags & FS_XFLAG_DAX) && xfs_is_reflink_inode(ip))
> + if ((ma->fsx_xflags & FS_XFLAG_DAX) && xfs_is_reflink_inode(ip))
> return -EINVAL;
>
> /* diflags2 only valid for v3 inodes. */
> - di_flags2 = xfs_flags2diflags2(ip, fa->fsx_xflags);
> + di_flags2 = xfs_flags2diflags2(ip, ma->fsx_xflags);
> if (di_flags2 && !xfs_sb_version_has_v3inode(&mp->m_sb))
> return -EINVAL;
>
> - ip->i_d.di_flags = xfs_flags2diflags(ip, fa->fsx_xflags);
> + ip->i_d.di_flags = xfs_flags2diflags(ip, ma->fsx_xflags);
> ip->i_d.di_flags2 = di_flags2;
>
> xfs_diflags_to_iflags(ip, false);
> @@ -1253,7 +1208,7 @@ xfs_ioctl_setattr_xflags(
> static void
> xfs_ioctl_setattr_prepare_dax(
> struct xfs_inode *ip,
> - struct fsxattr *fa)
> + struct miscattr *ma)
> {
> struct xfs_mount *mp = ip->i_mount;
> struct inode *inode = VFS_I(ip);
> @@ -1265,9 +1220,9 @@ xfs_ioctl_setattr_prepare_dax(
> (mp->m_flags & XFS_MOUNT_DAX_NEVER))
> return;
>
> - if (((fa->fsx_xflags & FS_XFLAG_DAX) &&
> + if (((ma->fsx_xflags & FS_XFLAG_DAX) &&
> !(ip->i_d.di_flags2 & XFS_DIFLAG2_DAX)) ||
> - (!(fa->fsx_xflags & FS_XFLAG_DAX) &&
> + (!(ma->fsx_xflags & FS_XFLAG_DAX) &&
> (ip->i_d.di_flags2 & XFS_DIFLAG2_DAX)))
> d_mark_dontcache(inode);
> }
> @@ -1280,10 +1235,9 @@ xfs_ioctl_setattr_prepare_dax(
> */
> static struct xfs_trans *
> xfs_ioctl_setattr_get_trans(
> - struct file *file,
> + struct xfs_inode *ip,
> struct xfs_dquot *pdqp)
> {
> - struct xfs_inode *ip = XFS_I(file_inode(file));
> struct xfs_mount *mp = ip->i_mount;
> struct xfs_trans *tp;
> int error = -EROFS;
> @@ -1299,24 +1253,11 @@ xfs_ioctl_setattr_get_trans(
> if (error)
> goto out_error;
>
> - /*
> - * CAP_FOWNER overrides the following restrictions:
> - *
> - * The user ID of the calling process must be equal to the file owner
> - * ID, except in cases where the CAP_FSETID capability is applicable.
> - */
> - if (!inode_owner_or_capable(file_mnt_user_ns(file), VFS_I(ip))) {
> - error = -EPERM;
> - goto out_cancel;
> - }
> -
> if (mp->m_flags & XFS_MOUNT_WSYNC)
> xfs_trans_set_sync(tp);
>
> return tp;
>
> -out_cancel:
> - xfs_trans_cancel(tp);
> out_error:
> return ERR_PTR(error);
> }
> @@ -1340,25 +1281,28 @@ xfs_ioctl_setattr_get_trans(
> static int
> xfs_ioctl_setattr_check_extsize(
> struct xfs_inode *ip,
> - struct fsxattr *fa)
> + struct miscattr *ma)
> {
> struct xfs_mount *mp = ip->i_mount;
> xfs_extlen_t size;
> xfs_fsblock_t extsize_fsb;
>
> + if (!ma->xattr_valid)
> + return 0;
> +
> if (S_ISREG(VFS_I(ip)->i_mode) && ip->i_df.if_nextents &&
> - ((ip->i_d.di_extsize << mp->m_sb.sb_blocklog) != fa->fsx_extsize))
> + ((ip->i_d.di_extsize << mp->m_sb.sb_blocklog) != ma->fsx_extsize))
> return -EINVAL;
>
> - if (fa->fsx_extsize == 0)
> + if (ma->fsx_extsize == 0)
> return 0;
>
> - extsize_fsb = XFS_B_TO_FSB(mp, fa->fsx_extsize);
> + extsize_fsb = XFS_B_TO_FSB(mp, ma->fsx_extsize);
> if (extsize_fsb > MAXEXTLEN)
> return -EINVAL;
>
> if (XFS_IS_REALTIME_INODE(ip) ||
> - (fa->fsx_xflags & FS_XFLAG_REALTIME)) {
> + (ma->fsx_xflags & FS_XFLAG_REALTIME)) {
> size = mp->m_sb.sb_rextsize << mp->m_sb.sb_blocklog;
> } else {
> size = mp->m_sb.sb_blocksize;
> @@ -1366,7 +1310,7 @@ xfs_ioctl_setattr_check_extsize(
> return -EINVAL;
> }
>
> - if (fa->fsx_extsize % size)
> + if (ma->fsx_extsize % size)
> return -EINVAL;
>
> return 0;
> @@ -1390,22 +1334,25 @@ xfs_ioctl_setattr_check_extsize(
> static int
> xfs_ioctl_setattr_check_cowextsize(
> struct xfs_inode *ip,
> - struct fsxattr *fa)
> + struct miscattr *ma)
> {
> struct xfs_mount *mp = ip->i_mount;
> xfs_extlen_t size;
> xfs_fsblock_t cowextsize_fsb;
>
> - if (!(fa->fsx_xflags & FS_XFLAG_COWEXTSIZE))
> + if (!ma->xattr_valid)
> + return 0;
> +
> + if (!(ma->fsx_xflags & FS_XFLAG_COWEXTSIZE))
> return 0;
>
> if (!xfs_sb_version_hasreflink(&ip->i_mount->m_sb))
> return -EINVAL;
>
> - if (fa->fsx_cowextsize == 0)
> + if (ma->fsx_cowextsize == 0)
> return 0;
>
> - cowextsize_fsb = XFS_B_TO_FSB(mp, fa->fsx_cowextsize);
> + cowextsize_fsb = XFS_B_TO_FSB(mp, ma->fsx_cowextsize);
> if (cowextsize_fsb > MAXEXTLEN)
> return -EINVAL;
>
> @@ -1413,7 +1360,7 @@ xfs_ioctl_setattr_check_cowextsize(
> if (cowextsize_fsb > mp->m_sb.sb_agblocks / 2)
> return -EINVAL;
>
> - if (fa->fsx_cowextsize % size)
> + if (ma->fsx_cowextsize % size)
> return -EINVAL;
>
> return 0;
> @@ -1422,23 +1369,25 @@ xfs_ioctl_setattr_check_cowextsize(
> static int
> xfs_ioctl_setattr_check_projid(
> struct xfs_inode *ip,
> - struct fsxattr *fa)
> + struct miscattr *ma)
> {
> + if (!ma->xattr_valid)
> + return 0;
> +
> /* Disallow 32bit project ids if projid32bit feature is not enabled. */
> - if (fa->fsx_projid > (uint16_t)-1 &&
> + if (ma->fsx_projid > (uint16_t)-1 &&
> !xfs_sb_version_hasprojid32bit(&ip->i_mount->m_sb))
> return -EINVAL;
> return 0;
> }
>
> -STATIC int
> -xfs_ioctl_setattr(
> - struct file *file,
> - struct fsxattr *fa)
> +int
> +xfs_miscattr_set(
> + struct user_namespace *mnt_userns,
> + struct dentry *dentry,
> + struct miscattr *ma)
> {
> - struct user_namespace *mnt_userns = file_mnt_user_ns(file);
> - struct xfs_inode *ip = XFS_I(file_inode(file));
> - struct fsxattr old_fa;
> + xfs_inode_t *ip = XFS_I(d_inode(dentry));
Same thing here about struct typedefs.
> struct xfs_mount *mp = ip->i_mount;
> struct xfs_trans *tp;
> struct xfs_dquot *pdqp = NULL;
> @@ -1447,7 +1396,15 @@ xfs_ioctl_setattr(
>
> trace_xfs_ioctl_setattr(ip);
>
> - error = xfs_ioctl_setattr_check_projid(ip, fa);
> + if (!ma->xattr_valid) {
> + /* FS_PROJINHERIT_FL not accepted, deliberate? */
No. I think this is an oversight from when ext4/f2fs added
PROJINHERIT_FL and forgot to update XFS.
> + if (ma->flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL |
> + FS_NOATIME_FL | FS_NODUMP_FL |
> + FS_SYNC_FL | FS_DAX_FL))
> + return -EOPNOTSUPP;
> + }
> +
> + error = xfs_ioctl_setattr_check_projid(ip, ma);
> if (error)
> return error;
>
> @@ -1459,39 +1416,36 @@ xfs_ioctl_setattr(
> * If the IDs do change before we take the ilock, we're covered
> * because the i_*dquot fields will get updated anyway.
> */
> - if (XFS_IS_QUOTA_ON(mp)) {
> + if (ma->xattr_valid && XFS_IS_QUOTA_ON(mp)) {
> error = xfs_qm_vop_dqalloc(ip, VFS_I(ip)->i_uid,
> - VFS_I(ip)->i_gid, fa->fsx_projid,
> + VFS_I(ip)->i_gid, ma->fsx_projid,
> XFS_QMOPT_PQUOTA, NULL, NULL, &pdqp);
> if (error)
> return error;
> }
>
> - xfs_ioctl_setattr_prepare_dax(ip, fa);
> + xfs_ioctl_setattr_prepare_dax(ip, ma);
>
> - tp = xfs_ioctl_setattr_get_trans(file, pdqp);
> + tp = xfs_ioctl_setattr_get_trans(ip, pdqp);
(Heh, and now the ip -> file -> ip churn cycle is complete. :/)
Does this build on -rc4?
--D
> if (IS_ERR(tp)) {
> error = PTR_ERR(tp);
> goto error_free_dquots;
> }
>
> - xfs_fill_fsxattr(ip, false, &old_fa);
> - error = vfs_ioc_fssetxattr_check(VFS_I(ip), &old_fa, fa);
> - if (error)
> - goto error_trans_cancel;
> -
> - error = xfs_ioctl_setattr_check_extsize(ip, fa);
> + error = xfs_ioctl_setattr_check_extsize(ip, ma);
> if (error)
> goto error_trans_cancel;
>
> - error = xfs_ioctl_setattr_check_cowextsize(ip, fa);
> + error = xfs_ioctl_setattr_check_cowextsize(ip, ma);
> if (error)
> goto error_trans_cancel;
>
> - error = xfs_ioctl_setattr_xflags(tp, ip, fa);
> + error = xfs_ioctl_setattr_xflags(tp, ip, ma);
> if (error)
> goto error_trans_cancel;
>
> + if (!ma->xattr_valid)
> + goto skip_xattr;
> /*
> * Change file ownership. Must be the owner or privileged. CAP_FSETID
> * overrides the following restrictions:
> @@ -1505,12 +1459,12 @@ xfs_ioctl_setattr(
> VFS_I(ip)->i_mode &= ~(S_ISUID|S_ISGID);
>
> /* Change the ownerships and register project quota modifications */
> - if (ip->i_d.di_projid != fa->fsx_projid) {
> + if (ip->i_d.di_projid != ma->fsx_projid) {
> if (XFS_IS_QUOTA_RUNNING(mp) && XFS_IS_PQUOTA_ON(mp)) {
> olddquot = xfs_qm_vop_chown(tp, ip,
> &ip->i_pdquot, pdqp);
> }
> - ip->i_d.di_projid = fa->fsx_projid;
> + ip->i_d.di_projid = ma->fsx_projid;
> }
>
> /*
> @@ -1519,16 +1473,17 @@ xfs_ioctl_setattr(
> * are set on the inode then unconditionally clear the extent size hint.
> */
> if (ip->i_d.di_flags & (XFS_DIFLAG_EXTSIZE | XFS_DIFLAG_EXTSZINHERIT))
> - ip->i_d.di_extsize = fa->fsx_extsize >> mp->m_sb.sb_blocklog;
> + ip->i_d.di_extsize = ma->fsx_extsize >> mp->m_sb.sb_blocklog;
> else
> ip->i_d.di_extsize = 0;
> if (xfs_sb_version_has_v3inode(&mp->m_sb) &&
> (ip->i_d.di_flags2 & XFS_DIFLAG2_COWEXTSIZE))
> - ip->i_d.di_cowextsize = fa->fsx_cowextsize >>
> + ip->i_d.di_cowextsize = ma->fsx_cowextsize >>
> mp->m_sb.sb_blocklog;
> else
> ip->i_d.di_cowextsize = 0;
>
> +skip_xattr:
> error = xfs_trans_commit(tp);
>
> /*
> @@ -1546,91 +1501,6 @@ xfs_ioctl_setattr(
> return error;
> }
>
> -STATIC int
> -xfs_ioc_fssetxattr(
> - struct file *filp,
> - void __user *arg)
> -{
> - struct fsxattr fa;
> - int error;
> -
> - if (copy_from_user(&fa, arg, sizeof(fa)))
> - return -EFAULT;
> -
> - error = mnt_want_write_file(filp);
> - if (error)
> - return error;
> - error = xfs_ioctl_setattr(filp, &fa);
> - mnt_drop_write_file(filp);
> - return error;
> -}
> -
> -STATIC int
> -xfs_ioc_getxflags(
> - xfs_inode_t *ip,
> - void __user *arg)
> -{
> - unsigned int flags;
> -
> - flags = xfs_di2lxflags(ip->i_d.di_flags, ip->i_d.di_flags2);
> - if (copy_to_user(arg, &flags, sizeof(flags)))
> - return -EFAULT;
> - return 0;
> -}
> -
> -STATIC int
> -xfs_ioc_setxflags(
> - struct xfs_inode *ip,
> - struct file *filp,
> - void __user *arg)
> -{
> - struct xfs_trans *tp;
> - struct fsxattr fa;
> - struct fsxattr old_fa;
> - unsigned int flags;
> - int error;
> -
> - if (copy_from_user(&flags, arg, sizeof(flags)))
> - return -EFAULT;
> -
> - if (flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | \
> - FS_NOATIME_FL | FS_NODUMP_FL | \
> - FS_SYNC_FL | FS_DAX_FL))
> - return -EOPNOTSUPP;
> -
> - fa.fsx_xflags = xfs_merge_ioc_xflags(flags, xfs_ip2xflags(ip));
> -
> - error = mnt_want_write_file(filp);
> - if (error)
> - return error;
> -
> - xfs_ioctl_setattr_prepare_dax(ip, &fa);
> -
> - tp = xfs_ioctl_setattr_get_trans(filp, NULL);
> - if (IS_ERR(tp)) {
> - error = PTR_ERR(tp);
> - goto out_drop_write;
> - }
> -
> - xfs_fill_fsxattr(ip, false, &old_fa);
> - error = vfs_ioc_fssetxattr_check(VFS_I(ip), &old_fa, &fa);
> - if (error) {
> - xfs_trans_cancel(tp);
> - goto out_drop_write;
> - }
> -
> - error = xfs_ioctl_setattr_xflags(tp, ip, &fa);
> - if (error) {
> - xfs_trans_cancel(tp);
> - goto out_drop_write;
> - }
> -
> - error = xfs_trans_commit(tp);
> -out_drop_write:
> - mnt_drop_write_file(filp);
> - return error;
> -}
> -
> static bool
> xfs_getbmap_format(
> struct kgetbmap *p,
> @@ -2137,16 +2007,8 @@ xfs_file_ioctl(
> case XFS_IOC_GETVERSION:
> return put_user(inode->i_generation, (int __user *)arg);
>
> - case XFS_IOC_FSGETXATTR:
> - return xfs_ioc_fsgetxattr(ip, 0, arg);
> case XFS_IOC_FSGETXATTRA:
> - return xfs_ioc_fsgetxattr(ip, 1, arg);
> - case XFS_IOC_FSSETXATTR:
> - return xfs_ioc_fssetxattr(filp, arg);
> - case XFS_IOC_GETXFLAGS:
> - return xfs_ioc_getxflags(ip, arg);
> - case XFS_IOC_SETXFLAGS:
> - return xfs_ioc_setxflags(ip, filp, arg);
> + return xfs_ioc_fsgetxattra(ip, arg);
>
> case XFS_IOC_GETBMAP:
> case XFS_IOC_GETBMAPA:
> diff --git a/fs/xfs/xfs_ioctl.h b/fs/xfs/xfs_ioctl.h
> index bab6a5a92407..3cb4a9d8cde0 100644
> --- a/fs/xfs/xfs_ioctl.h
> +++ b/fs/xfs/xfs_ioctl.h
> @@ -47,6 +47,17 @@ xfs_handle_to_dentry(
> void __user *uhandle,
> u32 hlen);
>
> +extern int
> +xfs_miscattr_get(
> + struct dentry *dentry,
> + struct miscattr *ma);
> +
> +extern int
> +xfs_miscattr_set(
> + struct user_namespace *mnt_userns,
> + struct dentry *dentry,
> + struct miscattr *ma);
> +
> extern long
> xfs_file_ioctl(
> struct file *filp,
> diff --git a/fs/xfs/xfs_ioctl32.c b/fs/xfs/xfs_ioctl32.c
> index 33c09ec8e6c0..e6506773ba55 100644
> --- a/fs/xfs/xfs_ioctl32.c
> +++ b/fs/xfs/xfs_ioctl32.c
> @@ -484,8 +484,6 @@ xfs_file_compat_ioctl(
> }
> #endif
> /* long changes size, but xfs only copiese out 32 bits */
> - case XFS_IOC_GETXFLAGS_32:
> - case XFS_IOC_SETXFLAGS_32:
> case XFS_IOC_GETVERSION_32:
> cmd = _NATIVE_IOC(cmd, long);
> return xfs_file_ioctl(filp, cmd, p);
> diff --git a/fs/xfs/xfs_ioctl32.h b/fs/xfs/xfs_ioctl32.h
> index 053de7d894cd..9929482bf358 100644
> --- a/fs/xfs/xfs_ioctl32.h
> +++ b/fs/xfs/xfs_ioctl32.h
> @@ -17,8 +17,6 @@
> */
>
> /* stock kernel-level ioctls we support */
> -#define XFS_IOC_GETXFLAGS_32 FS_IOC32_GETFLAGS
> -#define XFS_IOC_SETXFLAGS_32 FS_IOC32_SETFLAGS
> #define XFS_IOC_GETVERSION_32 FS_IOC32_GETVERSION
>
> /*
> diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
> index 66ebccb5a6ff..124c6a9f3872 100644
> --- a/fs/xfs/xfs_iops.c
> +++ b/fs/xfs/xfs_iops.c
> @@ -21,6 +21,7 @@
> #include "xfs_dir2.h"
> #include "xfs_iomap.h"
> #include "xfs_error.h"
> +#include "xfs_ioctl.h"
>
> #include <linux/posix_acl.h>
> #include <linux/security.h>
> @@ -1152,6 +1153,8 @@ static const struct inode_operations xfs_inode_operations = {
> .listxattr = xfs_vn_listxattr,
> .fiemap = xfs_vn_fiemap,
> .update_time = xfs_vn_update_time,
> + .miscattr_get = xfs_miscattr_get,
> + .miscattr_set = xfs_miscattr_set,
> };
>
> static const struct inode_operations xfs_dir_inode_operations = {
> @@ -1177,6 +1180,8 @@ static const struct inode_operations xfs_dir_inode_operations = {
> .listxattr = xfs_vn_listxattr,
> .update_time = xfs_vn_update_time,
> .tmpfile = xfs_vn_tmpfile,
> + .miscattr_get = xfs_miscattr_get,
> + .miscattr_set = xfs_miscattr_set,
> };
>
> static const struct inode_operations xfs_dir_ci_inode_operations = {
> @@ -1202,6 +1207,8 @@ static const struct inode_operations xfs_dir_ci_inode_operations = {
> .listxattr = xfs_vn_listxattr,
> .update_time = xfs_vn_update_time,
> .tmpfile = xfs_vn_tmpfile,
> + .miscattr_get = xfs_miscattr_get,
> + .miscattr_set = xfs_miscattr_set,
> };
>
> static const struct inode_operations xfs_symlink_inode_operations = {
> --
> 2.30.2
>
next prev parent reply other threads:[~2021-03-22 22:52 UTC|newest]
Thread overview: 33+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-03-22 14:48 [PATCH v2 00/18] new kAPI for FS_IOC_[GS]ETFLAGS/FS_IOC_FS[GS]ETXATTR Miklos Szeredi
2021-03-22 14:48 ` [PATCH v2 01/18] vfs: add miscattr ops Miklos Szeredi
2021-03-22 22:33 ` Darrick J. Wong
2021-03-23 5:21 ` Amir Goldstein
2021-03-23 11:22 ` David Sterba
2021-03-24 8:06 ` Christian Brauner
2021-03-24 5:02 ` Al Viro
2021-03-24 8:45 ` Miklos Szeredi
2021-03-24 12:26 ` Al Viro
2021-03-24 13:45 ` Miklos Szeredi
2021-03-24 8:21 ` Christian Brauner
2021-03-22 14:49 ` [PATCH v2 02/18] ecryptfs: stack " Miklos Szeredi
2021-03-22 14:49 ` [PATCH v2 03/18] ovl: " Miklos Szeredi
2021-03-24 5:09 ` Al Viro
2021-03-24 5:18 ` Al Viro
2021-03-22 14:49 ` [PATCH v2 04/18] btrfs: convert to miscattr Miklos Szeredi
2021-03-23 11:41 ` David Sterba
2021-03-22 14:49 ` [PATCH v2 05/18] ext2: " Miklos Szeredi
2021-03-22 14:49 ` [PATCH v2 06/18] ext4: " Miklos Szeredi
2021-03-22 14:49 ` [PATCH v2 07/18] f2fs: " Miklos Szeredi
2021-03-22 14:49 ` [PATCH v2 08/18] gfs2: " Miklos Szeredi
2021-03-22 14:49 ` [PATCH v2 09/18] orangefs: " Miklos Szeredi
2021-03-22 14:49 ` [PATCH v2 10/18] xfs: " Miklos Szeredi
2021-03-22 22:51 ` Darrick J. Wong [this message]
2021-03-22 14:49 ` [PATCH v2 11/18] efivars: " Miklos Szeredi
2021-03-22 14:49 ` [PATCH v2 12/18] hfsplus: " Miklos Szeredi
2021-03-22 14:49 ` [PATCH v2 13/18] jfs: " Miklos Szeredi
2021-03-22 14:49 ` [PATCH v2 14/18] nilfs2: " Miklos Szeredi
2021-03-22 14:49 ` [PATCH v2 15/18] ocfs2: " Miklos Szeredi
2021-03-22 14:49 ` [PATCH v2 16/18] reiserfs: " Miklos Szeredi
2021-03-22 14:49 ` [PATCH v2 17/18] ubifs: " Miklos Szeredi
2021-03-22 14:49 ` [PATCH v2 18/18] vfs: remove unused ioctl helpers Miklos Szeredi
2021-03-22 22:51 ` 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=20210322225131.GE22094@magnolia \
--to=djwong@kernel.org \
--cc=hch@lst.de \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mszeredi@redhat.com \
--cc=viro@ZenIV.linux.org.uk \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.