From patchwork Mon Mar 22 14:48:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miklos Szeredi X-Patchwork-Id: 12155001 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F40E3C433E2 for ; Mon, 22 Mar 2021 14:50:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B12A9619B0 for ; Mon, 22 Mar 2021 14:50:24 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230369AbhCVOtz (ORCPT ); Mon, 22 Mar 2021 10:49:55 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:36211 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230010AbhCVOtY (ORCPT ); Mon, 22 Mar 2021 10:49:24 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1616424563; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=DXbEjcMCbvNU6S4qvMlPuf7lzew18iwJveqHO6cinQ8=; b=iuGbRwiVuMZqVFO8KvtAelilZ0Lp2QNaK18FlRPW97wkIVbAvhz3281OV2grCaSwEhKdtS fyRjr6GxFyrSnR24FFhatizfBI98f9yjjOktzWfvAyrCS/cz2DK5YfLIBnSMAbdisBcwlJ zINkN8YZdyDwQIM1m0RPRZ5Ob00PydM= Received: from mail-ed1-f72.google.com (mail-ed1-f72.google.com [209.85.208.72]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-337-MBUAili1OgejZDe4C3qmXA-1; Mon, 22 Mar 2021 10:49:21 -0400 X-MC-Unique: MBUAili1OgejZDe4C3qmXA-1 Received: by mail-ed1-f72.google.com with SMTP id n20so27700531edr.8 for ; Mon, 22 Mar 2021 07:49:21 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=DXbEjcMCbvNU6S4qvMlPuf7lzew18iwJveqHO6cinQ8=; b=cDpjPYkJOcPcNNwRc7K36F9s0LPjaZcBRFPlNi63WOUqDPv7aO2r7+CbILZXGs/az/ ZQOIHz/zlHKx7OiJlwI7bT6lSJRNBb4xu34i81IzKYJBRzFFoO0uKbJifQlQGYgILMOH I/Y8hjESuHUxI8t6iu91Tmx7/OZP4rJccqrIV7M8jZYCKEZlrjMfUG/ElcxIhwN3hm1l RiYUkzhIfgibXluEZDaFCXkf9/P4/KqjZ83OA1/yFq9InejblNYwih+LnBcFlQVdYFmZ 8FMZthlnqZP5Rax5XCtvEHd1n4qHGd1NNrBTZ0SmFv7mXTtzhYDrVHYb3HeQRqlSWMt4 bltQ== X-Gm-Message-State: AOAM533pj0Igck2JA9N4kTCTMpopLSTyYxK8YvQRz2+94wtf/H4f5cSr iALB0KDgRJ42GU4LicDsOMoBnYWaEaSM7eEKCS7atGdH11ixMLXZWa18Mv43rD+8qWlJILBkdV3 rYbf48igr4d9ty0c7sSworACxVlRl96ZK2gOD722Urp8vPnFjMFA4bixuRHXSyfdckgC6Ble3ID C/LQ== X-Received: by 2002:a17:906:5e50:: with SMTP id b16mr137488eju.272.1616424560048; Mon, 22 Mar 2021 07:49:20 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwjROlOrU01V2lgFg2EPOrwWkuY3keIINplQIYL/IKJvGLaz6DL9KnTEXfDw87ZCUnvFk7HqQ== X-Received: by 2002:a17:906:5e50:: with SMTP id b16mr137457eju.272.1616424559679; Mon, 22 Mar 2021 07:49:19 -0700 (PDT) Received: from miu.piliscsaba.redhat.com (catv-86-101-169-67.catv.broadband.hu. [86.101.169.67]) by smtp.gmail.com with ESMTPSA id r4sm9793117ejd.125.2021.03.22.07.49.18 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Mar 2021 07:49:19 -0700 (PDT) From: Miklos Szeredi To: linux-fsdevel@vger.kernel.org Cc: Al Viro , linux-kernel@vger.kernel.org, Christoph Hellwig Subject: [PATCH v2 01/18] vfs: add miscattr ops Date: Mon, 22 Mar 2021 15:48:59 +0100 Message-Id: <20210322144916.137245-2-mszeredi@redhat.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210322144916.137245-1-mszeredi@redhat.com> References: <20210322144916.137245-1-mszeredi@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org There's a substantial amount of boilerplate in filesystems handling FS_IOC_[GS]ETFLAGS/ FS_IOC_FS[GS]ETXATTR ioctls. Also due to userspace buffers being involved in the ioctl API this is difficult to stack, as shown by overlayfs issues related to these ioctls. Introduce a new internal API named "miscattr" (fsxattr can be confused with xattr, xflags is inappropriate, since this is more than just flags). There's significant overlap between flags and xflags and this API handles the conversions automatically, so filesystems may choose which one to use. In ->miscattr_get() a hint is provided to the filesystem whether flags or xattr are being requested by userspace, but in this series this hint is ignored by all filesystems, since generating all the attributes is cheap. If a filesystem doesn't implemement the miscattr API, just fall back to f_op->ioctl(). When all filesystems are converted, the fallback can be removed. 32bit compat ioctls are now handled by the generic code as well. Signed-off-by: Miklos Szeredi --- Documentation/filesystems/locking.rst | 5 + Documentation/filesystems/vfs.rst | 15 ++ fs/ioctl.c | 329 ++++++++++++++++++++++++++ include/linux/fs.h | 4 + include/linux/miscattr.h | 53 +++++ 5 files changed, 406 insertions(+) create mode 100644 include/linux/miscattr.h diff --git a/Documentation/filesystems/locking.rst b/Documentation/filesystems/locking.rst index b7dcc86c92a4..a5aa2046d48f 100644 --- a/Documentation/filesystems/locking.rst +++ b/Documentation/filesystems/locking.rst @@ -80,6 +80,9 @@ prototypes:: struct file *, unsigned open_flag, umode_t create_mode); int (*tmpfile) (struct inode *, struct dentry *, umode_t); + int (*miscattr_set)(struct user_namespace *mnt_userns, + struct dentry *dentry, struct miscattr *ma); + int (*miscattr_get)(struct dentry *dentry, struct miscattr *ma); locking rules: all may block @@ -107,6 +110,8 @@ fiemap: no update_time: no atomic_open: shared (exclusive if O_CREAT is set in open flags) tmpfile: no +miscattr_get: no or exclusive +miscattr_set: exclusive ============ ============================================= diff --git a/Documentation/filesystems/vfs.rst b/Documentation/filesystems/vfs.rst index 2049bbf5e388..f125ce6c3b47 100644 --- a/Documentation/filesystems/vfs.rst +++ b/Documentation/filesystems/vfs.rst @@ -441,6 +441,9 @@ As of kernel 2.6.22, the following members are defined: unsigned open_flag, umode_t create_mode); int (*tmpfile) (struct user_namespace *, struct inode *, struct dentry *, umode_t); int (*set_acl)(struct user_namespace *, struct inode *, struct posix_acl *, int); + int (*miscattr_set)(struct user_namespace *mnt_userns, + struct dentry *dentry, struct miscattr *ma); + int (*miscattr_get)(struct dentry *dentry, struct miscattr *ma); }; Again, all methods are called without any locks being held, unless @@ -588,6 +591,18 @@ otherwise noted. atomically creating, opening and unlinking a file in given directory. +``miscattr_get`` + called on ioctl(FS_IOC_GETFLAGS) and ioctl(FS_IOC_FSGETXATTR) to + retrieve miscellaneous filesystem flags and attributes. Also + called before the relevant SET operation to check what is being + changed (in this case with i_rwsem locked exclusive). If unset, + then fall back to f_op->ioctl(). + +``miscattr_set`` + called on ioctl(FS_IOC_SETFLAGS) and ioctl(FS_IOC_FSSETXATTR) to + change miscellaneous filesystem flags and attributes. Callers hold + i_rwsem exclusive. If unset, then fall back to f_op->ioctl(). + The Address Space Object ======================== diff --git a/fs/ioctl.c b/fs/ioctl.c index 4e6cc0a7d69c..e5f3820809a4 100644 --- a/fs/ioctl.c +++ b/fs/ioctl.c @@ -19,6 +19,9 @@ #include #include #include +#include +#include +#include #include "internal.h" @@ -657,6 +660,311 @@ static int ioctl_file_dedupe_range(struct file *file, return ret; } +/** + * miscattr_fill_xflags - initialize miscattr with xflags + * @ma: miscattr pointer + * @xflags: FS_XFLAG_* flags + * + * Set ->fsx_xflags, ->xattr_valid and ->flags (translated xflags). All + * other fields are zeroed. + */ +void miscattr_fill_xflags(struct miscattr *ma, u32 xflags) +{ + memset(ma, 0, sizeof(*ma)); + ma->xattr_valid = true; + ma->fsx_xflags = xflags; + if (ma->fsx_xflags & FS_XFLAG_IMMUTABLE) + ma->flags |= FS_IMMUTABLE_FL; + if (ma->fsx_xflags & FS_XFLAG_APPEND) + ma->flags |= FS_APPEND_FL; + if (ma->fsx_xflags & FS_XFLAG_SYNC) + ma->flags |= FS_SYNC_FL; + if (ma->fsx_xflags & FS_XFLAG_NOATIME) + ma->flags |= FS_NOATIME_FL; + if (ma->fsx_xflags & FS_XFLAG_NODUMP) + ma->flags |= FS_NODUMP_FL; + if (ma->fsx_xflags & FS_XFLAG_DAX) + ma->flags |= FS_DAX_FL; + if (ma->fsx_xflags & FS_XFLAG_PROJINHERIT) + ma->flags |= FS_PROJINHERIT_FL; +} +EXPORT_SYMBOL(miscattr_fill_xflags); + +/** + * miscattr_fill_flags - initialize miscattr with flags + * @ma: miscattr pointer + * @flags: FS_*_FL flags + * + * Set ->flags, ->flags_valid and ->fsx_xflags (translated flags). + * All other fields are zeroed. + */ +void miscattr_fill_flags(struct miscattr *ma, u32 flags) +{ + memset(ma, 0, sizeof(*ma)); + ma->flags_valid = true; + ma->flags = flags; + if (ma->flags & FS_SYNC_FL) + ma->fsx_xflags |= FS_XFLAG_SYNC; + if (ma->flags & FS_IMMUTABLE_FL) + ma->fsx_xflags |= FS_XFLAG_IMMUTABLE; + if (ma->flags & FS_APPEND_FL) + ma->fsx_xflags |= FS_XFLAG_APPEND; + if (ma->flags & FS_NODUMP_FL) + ma->fsx_xflags |= FS_XFLAG_NODUMP; + if (ma->flags & FS_NOATIME_FL) + ma->fsx_xflags |= FS_XFLAG_NOATIME; + if (ma->flags & FS_DAX_FL) + ma->fsx_xflags |= FS_XFLAG_DAX; + if (ma->flags & FS_PROJINHERIT_FL) + ma->fsx_xflags |= FS_XFLAG_PROJINHERIT; +} +EXPORT_SYMBOL(miscattr_fill_flags); + +/** + * vfs_miscattr_get - retrieve miscellaneous inode attributes + * @dentry: the object to retrieve from + * @ma: miscattr pointer + * + * Call i_op->miscattr_get() callback, if exists. + * + * Returns 0 on success, or a negative error on failure. + */ +int vfs_miscattr_get(struct dentry *dentry, struct miscattr *ma) +{ + struct inode *inode = d_inode(dentry); + + if (d_is_special(dentry)) + return -ENOTTY; + + if (!inode->i_op->miscattr_get) + return -ENOIOCTLCMD; + + return inode->i_op->miscattr_get(dentry, ma); +} +EXPORT_SYMBOL(vfs_miscattr_get); + +/** + * fsxattr_copy_to_user - copy fsxattr to userspace. + * @ma: miscattr pointer + * @ufa: fsxattr user pointer + * + * Returns 0 on success, or -EFAULT on failure. + */ +int fsxattr_copy_to_user(const struct miscattr *ma, struct fsxattr __user *ufa) +{ + struct fsxattr fa = { + .fsx_xflags = ma->fsx_xflags, + .fsx_extsize = ma->fsx_extsize, + .fsx_nextents = ma->fsx_nextents, + .fsx_projid = ma->fsx_projid, + .fsx_cowextsize = ma->fsx_cowextsize, + }; + + if (copy_to_user(ufa, &fa, sizeof(fa))) + return -EFAULT; + + return 0; +} +EXPORT_SYMBOL(fsxattr_copy_to_user); + +static int fsxattr_copy_from_user(struct miscattr *ma, + struct fsxattr __user *ufa) +{ + struct fsxattr fa; + + if (copy_from_user(&fa, ufa, sizeof(fa))) + return -EFAULT; + + miscattr_fill_xflags(ma, fa.fsx_xflags); + ma->fsx_extsize = fa.fsx_extsize; + ma->fsx_nextents = fa.fsx_nextents; + ma->fsx_projid = fa.fsx_projid; + ma->fsx_cowextsize = fa.fsx_cowextsize; + + return 0; +} + +/* + * Generic function to check FS_IOC_FSSETXATTR/FS_IOC_SETFLAGS values and reject + * any invalid configurations. + * + * Note: must be called with inode lock held. + */ +static int miscattr_set_prepare(struct inode *inode, + const struct miscattr *old_ma, + struct miscattr *ma) +{ + int err; + + /* + * The IMMUTABLE and APPEND_ONLY flags can only be changed by + * the relevant capability. + */ + if ((ma->flags ^ old_ma->flags) & (FS_APPEND_FL | FS_IMMUTABLE_FL) && + !capable(CAP_LINUX_IMMUTABLE)) + return -EPERM; + + err = fscrypt_prepare_setflags(inode, old_ma->flags, ma->flags); + if (err) + return err; + + /* + * Project Quota ID state is only allowed to change from within the init + * namespace. Enforce that restriction only if we are trying to change + * the quota ID state. Everything else is allowed in user namespaces. + */ + if (current_user_ns() != &init_user_ns) { + if (old_ma->fsx_projid != ma->fsx_projid) + return -EINVAL; + if ((old_ma->fsx_xflags ^ ma->fsx_xflags) & + FS_XFLAG_PROJINHERIT) + return -EINVAL; + } + + /* Check extent size hints. */ + if ((ma->fsx_xflags & FS_XFLAG_EXTSIZE) && !S_ISREG(inode->i_mode)) + return -EINVAL; + + if ((ma->fsx_xflags & FS_XFLAG_EXTSZINHERIT) && + !S_ISDIR(inode->i_mode)) + return -EINVAL; + + if ((ma->fsx_xflags & FS_XFLAG_COWEXTSIZE) && + !S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode)) + return -EINVAL; + + /* + * It is only valid to set the DAX flag on regular files and + * directories on filesystems. + */ + if ((ma->fsx_xflags & FS_XFLAG_DAX) && + !(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) + return -EINVAL; + + /* Extent size hints of zero turn off the flags. */ + if (ma->fsx_extsize == 0) + ma->fsx_xflags &= ~(FS_XFLAG_EXTSIZE | FS_XFLAG_EXTSZINHERIT); + if (ma->fsx_cowextsize == 0) + ma->fsx_xflags &= ~FS_XFLAG_COWEXTSIZE; + + return 0; +} + +/** + * vfs_miscattr_set - change miscellaneous inode attributes + * @dentry: the object to change + * @ma: miscattr pointer + * + * After verifying permissions, call i_op->miscattr_set() callback, if + * exists. + * + * Verifying attributes involves retrieving current attributes with + * i_op->miscattr_get(), this also allows initilaizing attributes that have + * not been set by the caller to current values. Inode lock is held + * thoughout to prevent racing with another instance. + * + * Returns 0 on success, or a negative error on failure. + */ +int vfs_miscattr_set(struct user_namespace *mnt_userns, struct dentry *dentry, + struct miscattr *ma) +{ + struct inode *inode = d_inode(dentry); + struct miscattr old_ma = {}; + int err; + + if (d_is_special(dentry)) + return -ENOTTY; + + if (!inode->i_op->miscattr_set) + return -ENOIOCTLCMD; + + if (!inode_owner_or_capable(mnt_userns, inode)) + return -EPERM; + + inode_lock(inode); + err = vfs_miscattr_get(dentry, &old_ma); + if (!err) { + /* initialize missing bits from old_ma */ + if (ma->flags_valid) { + ma->fsx_xflags |= old_ma.fsx_xflags & ~FS_XFLAG_COMMON; + ma->fsx_extsize = old_ma.fsx_extsize; + ma->fsx_nextents = old_ma.fsx_nextents; + ma->fsx_projid = old_ma.fsx_projid; + ma->fsx_cowextsize = old_ma.fsx_cowextsize; + } else { + ma->flags |= old_ma.flags & ~FS_COMMON_FL; + } + err = miscattr_set_prepare(inode, &old_ma, ma); + if (!err) + err = inode->i_op->miscattr_set(mnt_userns, dentry, ma); + } + inode_unlock(inode); + + return err; +} +EXPORT_SYMBOL(vfs_miscattr_set); + +static int ioctl_getflags(struct file *file, void __user *argp) +{ + struct miscattr ma = { .flags_valid = true }; /* hint only */ + unsigned int flags; + int err; + + err = vfs_miscattr_get(file_dentry(file), &ma); + if (!err) { + flags = ma.flags; + if (copy_to_user(argp, &flags, sizeof(flags))) + err = -EFAULT; + } + return err; +} + +static int ioctl_setflags(struct file *file, void __user *argp) +{ + struct miscattr ma; + unsigned int flags; + int err; + + if (copy_from_user(&flags, argp, sizeof(flags))) + return -EFAULT; + + err = mnt_want_write_file(file); + if (!err) { + miscattr_fill_flags(&ma, flags); + err = vfs_miscattr_set(file_mnt_user_ns(file), file_dentry(file), &ma); + mnt_drop_write_file(file); + } + return err; +} + +static int ioctl_fsgetxattr(struct file *file, void __user *argp) +{ + struct miscattr ma = { .xattr_valid = true }; /* hint only */ + int err; + + err = vfs_miscattr_get(file_dentry(file), &ma); + if (!err) + err = fsxattr_copy_to_user(&ma, argp); + + return err; +} + +static int ioctl_fssetxattr(struct file *file, void __user *argp) +{ + struct miscattr ma; + int err; + + err = fsxattr_copy_from_user(&ma, argp); + if (!err) { + err = mnt_want_write_file(file); + if (!err) { + err = vfs_miscattr_set(file_mnt_user_ns(file), file_dentry(file), &ma); + mnt_drop_write_file(file); + } + } + return err; +} + /* * do_vfs_ioctl() is not for drivers and not intended to be EXPORT_SYMBOL()'d. * It's just a simple helper for sys_ioctl and compat_sys_ioctl. @@ -727,6 +1035,18 @@ static int do_vfs_ioctl(struct file *filp, unsigned int fd, return put_user(i_size_read(inode) - filp->f_pos, (int __user *)argp); + case FS_IOC_GETFLAGS: + return ioctl_getflags(filp, argp); + + case FS_IOC_SETFLAGS: + return ioctl_setflags(filp, argp); + + case FS_IOC_FSGETXATTR: + return ioctl_fsgetxattr(filp, argp); + + case FS_IOC_FSSETXATTR: + return ioctl_fssetxattr(filp, argp); + default: if (S_ISREG(inode->i_mode)) return file_ioctl(filp, cmd, argp); @@ -827,6 +1147,15 @@ COMPAT_SYSCALL_DEFINE3(ioctl, unsigned int, fd, unsigned int, cmd, break; #endif + /* + * These access 32-bit values anyway so no further handling is + * necessary. + */ + case FS_IOC32_GETFLAGS: + case FS_IOC32_SETFLAGS: + cmd = (cmd == FS_IOC32_GETFLAGS) ? + FS_IOC_GETFLAGS : FS_IOC_SETFLAGS; + fallthrough; /* * everything else in do_vfs_ioctl() takes either a compatible * pointer argument or no argument -- call it with a modified diff --git a/include/linux/fs.h b/include/linux/fs.h index ec8f3ddf4a6a..9e7f6a592a70 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -70,6 +70,7 @@ struct fsverity_info; struct fsverity_operations; struct fs_context; struct fs_parameter_spec; +struct miscattr; extern void __init inode_init(void); extern void __init inode_init_early(void); @@ -1963,6 +1964,9 @@ struct inode_operations { struct dentry *, umode_t); int (*set_acl)(struct user_namespace *, struct inode *, struct posix_acl *, int); + int (*miscattr_set)(struct user_namespace *mnt_userns, + struct dentry *dentry, struct miscattr *ma); + int (*miscattr_get)(struct dentry *dentry, struct miscattr *ma); } ____cacheline_aligned; static inline ssize_t call_read_iter(struct file *file, struct kiocb *kio, diff --git a/include/linux/miscattr.h b/include/linux/miscattr.h new file mode 100644 index 000000000000..13683eb6ac78 --- /dev/null +++ b/include/linux/miscattr.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef _LINUX_MISCATTR_H +#define _LINUX_MISCATTR_H + +/* Flags shared betwen flags/xflags */ +#define FS_COMMON_FL \ + (FS_SYNC_FL | FS_IMMUTABLE_FL | FS_APPEND_FL | \ + FS_NODUMP_FL | FS_NOATIME_FL | FS_DAX_FL | \ + FS_PROJINHERIT_FL) + +#define FS_XFLAG_COMMON \ + (FS_XFLAG_SYNC | FS_XFLAG_IMMUTABLE | FS_XFLAG_APPEND | \ + FS_XFLAG_NODUMP | FS_XFLAG_NOATIME | FS_XFLAG_DAX | \ + FS_XFLAG_PROJINHERIT) + +struct miscattr { + u32 flags; /* flags (FS_IOC_GETFLAGS/FS_IOC_SETFLAGS) */ + /* struct fsxattr: */ + u32 fsx_xflags; /* xflags field value (get/set) */ + u32 fsx_extsize; /* extsize field value (get/set)*/ + u32 fsx_nextents; /* nextents field value (get) */ + u32 fsx_projid; /* project identifier (get/set) */ + u32 fsx_cowextsize; /* CoW extsize field value (get/set)*/ + /* selectors: */ + bool flags_valid:1; + bool xattr_valid:1; +}; + +int fsxattr_copy_to_user(const struct miscattr *ma, struct fsxattr __user *ufa); + +void miscattr_fill_xflags(struct miscattr *ma, u32 xflags); +void miscattr_fill_flags(struct miscattr *ma, u32 flags); + +/** + * miscattr_has_xattr - check for extentended flags/attributes + * @ma: miscattr pointer + * + * Returns true if any attributes are present that are not represented in + * ->flags. + */ +static inline bool miscattr_has_xattr(const struct miscattr *ma) +{ + return ma->xattr_valid && + ((ma->fsx_xflags & ~FS_XFLAG_COMMON) || ma->fsx_extsize != 0 || + ma->fsx_projid != 0 || ma->fsx_cowextsize != 0); +} + +int vfs_miscattr_get(struct dentry *dentry, struct miscattr *ma); +int vfs_miscattr_set(struct user_namespace *mnt_userns, struct dentry *dentry, + struct miscattr *ma); + +#endif /* _LINUX_MISCATTR_H */ From patchwork Mon Mar 22 14:49:00 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miklos Szeredi X-Patchwork-Id: 12155009 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 42144C433E6 for ; Mon, 22 Mar 2021 14:50:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1473A619A2 for ; Mon, 22 Mar 2021 14:50:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231305AbhCVOt4 (ORCPT ); Mon, 22 Mar 2021 10:49:56 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:57754 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230477AbhCVOtZ (ORCPT ); Mon, 22 Mar 2021 10:49:25 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1616424564; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Su5HH4RiF+W/Zr5XDd86GPqq3KJsWhOK7dETED+hxaI=; b=i799UTxEC8iAPs9h7oEzYXAJpzFB+3IpTmd0Ha8n62HlEDtNMlRrHud1sTyLVTxLgS/MeI eBEA502GNhxJdRHaZh8Lyy2FMBPjOmGMn84TV1nKWIx7HhwMHZ4ekM+U6d1Q52AU3dQ9AK S8MfEZlKc1C+0awg49gPHOiYG1QpNc8= Received: from mail-ed1-f71.google.com (mail-ed1-f71.google.com [209.85.208.71]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-573-8OdorIFhNrqJuQ3t2qU--Q-1; Mon, 22 Mar 2021 10:49:22 -0400 X-MC-Unique: 8OdorIFhNrqJuQ3t2qU--Q-1 Received: by mail-ed1-f71.google.com with SMTP id w18so24706766edu.5 for ; Mon, 22 Mar 2021 07:49:22 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Su5HH4RiF+W/Zr5XDd86GPqq3KJsWhOK7dETED+hxaI=; b=mnw7SbB0ngThNNguqCiFrKUzsoj3eqX8LdWImxZEGfoMIB2gsrRkJqOnFxaumEFp2M vJcDrg/HBJkZb8cU8Ii+dz+C/UyjTmO/chrpGR23Fx0YdRNUxMDOg/7d7Pj7xnU0HHOa GllEbwULN12wROnaCtbaWt9hNxC5oI8Vf1/z51jFOFYTMveIhtKDHSm97aYjjHI4RUUn vzPvnrIcPUWQpEUJD89C/2Qjz3cz5faC1y5sCI8nQZod9XO3KpItRP5RPs7USKRJfusy Xpbyfrp91p1TEQv8TWETC0xDAujGTF25qZC5l9n+5opR4eB5JZko83HWR1uy6etnTEdD asFw== X-Gm-Message-State: AOAM532MBKLeEuHDxr5ruqDE6RdKZgY0Z1FPP5J5Zwtoqu8sjyBWM64D Ik9P085rz2sx5wC0jy26Q+V5wi86lKZRlRRyxTMUhjivPUPy+M/naeHmMMtM/gtH/XvOiE+oD7H c6DNjzzyQ1C4RWu4AY9w7PcgCf1BXon96f2G7xNFFYRVmdtCtSfsR2rs+S8FY3aJJYsv03KJqSv QFnA== X-Received: by 2002:a17:906:51c3:: with SMTP id v3mr65664ejk.497.1616424561580; Mon, 22 Mar 2021 07:49:21 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz3OTZYNqLusMjJIntln1ZMQ1gkH4GazIa2cCJ6OLVDvjZ2gcIA2IzzCvXPSaXbODU31M4uvQ== X-Received: by 2002:a17:906:51c3:: with SMTP id v3mr65645ejk.497.1616424561419; Mon, 22 Mar 2021 07:49:21 -0700 (PDT) Received: from miu.piliscsaba.redhat.com (catv-86-101-169-67.catv.broadband.hu. [86.101.169.67]) by smtp.gmail.com with ESMTPSA id r4sm9793117ejd.125.2021.03.22.07.49.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Mar 2021 07:49:20 -0700 (PDT) From: Miklos Szeredi To: linux-fsdevel@vger.kernel.org Cc: Al Viro , linux-kernel@vger.kernel.org, Christoph Hellwig , Tyler Hicks Subject: [PATCH v2 02/18] ecryptfs: stack miscattr ops Date: Mon, 22 Mar 2021 15:49:00 +0100 Message-Id: <20210322144916.137245-3-mszeredi@redhat.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210322144916.137245-1-mszeredi@redhat.com> References: <20210322144916.137245-1-mszeredi@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Add stacking for the miscattr operations. Signed-off-by: Miklos Szeredi Cc: Tyler Hicks --- fs/ecryptfs/inode.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index 18e9285fbb4c..b7d18583c50f 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "ecryptfs_kernel.h" @@ -1118,6 +1119,23 @@ static int ecryptfs_removexattr(struct dentry *dentry, struct inode *inode, return rc; } +static int ecryptfs_miscattr_get(struct dentry *dentry, struct miscattr *ma) +{ + return vfs_miscattr_get(ecryptfs_dentry_to_lower(dentry), ma); +} + +static int ecryptfs_miscattr_set(struct user_namespace *mnt_userns, + struct dentry *dentry, struct miscattr *ma) +{ + struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); + int rc; + + rc = vfs_miscattr_set(&init_user_ns, lower_dentry, ma); + fsstack_copy_attr_all(d_inode(dentry), d_inode(lower_dentry)); + + return rc; +} + const struct inode_operations ecryptfs_symlink_iops = { .get_link = ecryptfs_get_link, .permission = ecryptfs_permission, @@ -1139,6 +1157,8 @@ const struct inode_operations ecryptfs_dir_iops = { .permission = ecryptfs_permission, .setattr = ecryptfs_setattr, .listxattr = ecryptfs_listxattr, + .miscattr_get = ecryptfs_miscattr_get, + .miscattr_set = ecryptfs_miscattr_set, }; const struct inode_operations ecryptfs_main_iops = { @@ -1146,6 +1166,8 @@ const struct inode_operations ecryptfs_main_iops = { .setattr = ecryptfs_setattr, .getattr = ecryptfs_getattr, .listxattr = ecryptfs_listxattr, + .miscattr_get = ecryptfs_miscattr_get, + .miscattr_set = ecryptfs_miscattr_set, }; static int ecryptfs_xattr_get(const struct xattr_handler *handler, From patchwork Mon Mar 22 14:49:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miklos Szeredi X-Patchwork-Id: 12155011 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 60D66C433C1 for ; Mon, 22 Mar 2021 14:50:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3834D619A6 for ; Mon, 22 Mar 2021 14:50:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231322AbhCVOt6 (ORCPT ); Mon, 22 Mar 2021 10:49:58 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:57264 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230492AbhCVOtZ (ORCPT ); Mon, 22 Mar 2021 10:49:25 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1616424565; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=EGYFcZIgz7V4SyvxtDTIzKTncUqnpA6CZvB0bGEcNv8=; b=PhEfmnbs8H2GzuE8gmTcs9036PMlr3IkS0BT+D8L9L0INygMJth7CgZ+kOgi8/t6wXZur2 Oa1LG0TlHUml/cyWP2FLp/2HEdV8UhX1ReV8K2/jWdB/GodaAPs9Chzu1u3PB/YvpxLajR NLTJhfxiYoNFZHD3GdyBvya3QSDjN5E= Received: from mail-ej1-f69.google.com (mail-ej1-f69.google.com [209.85.218.69]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-493-43S75rGRO-eur5XpXclEqQ-1; Mon, 22 Mar 2021 10:49:23 -0400 X-MC-Unique: 43S75rGRO-eur5XpXclEqQ-1 Received: by mail-ej1-f69.google.com with SMTP id au15so20098873ejc.8 for ; Mon, 22 Mar 2021 07:49:23 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=EGYFcZIgz7V4SyvxtDTIzKTncUqnpA6CZvB0bGEcNv8=; b=tRURMv09OYMc3UUWAvMGK8Dgg1o3o4VMrG4SXZPbdW3ddOGFbHm03sLCWFeRq08SLn yUmoTxQJqa9D5LAK6Y2hjpEJeEjlfgjKnsHuWNKzYvyyaGEeAIv1Vg2UTJUnCh8An6UB QqejudeT1+FPMLElviwcAP3xOXYAzdkehRsY8FfT3t1cIcBIoxqINv2tvAVmgiQjzkgk ntstm67SPmkyxWQOwitetLyB7zblOj9ihmtmcz7kRBUwnHuAPuc2MY8PqUo0rn9qPnwr gsX1njLT869ZhsOIsek8LhvbMAFgWmz1AFkbMF2yblPJHpWrhHWfDeUWfYhkn7Bxv1S6 4G3g== X-Gm-Message-State: AOAM530Dd7Dk7WbmzPPxl1g67x7ZhgsW6X56RX+93BR+DnGblvAAslsW /+O1LxHbgcebn0ZZvoJdjSTOXQM2XT+6wscROkRyRednmRIJT55LzHakmNAQis5Kcrd56BHDO87 /8q2Jjv5moG4qWZcrmO2/BI5CMXD1aW8Jr/nekc1exWeQt81ABlnsJlWSY7ClgqUJQOIvBLaKKA mltQ== X-Received: by 2002:a17:906:ae88:: with SMTP id md8mr132574ejb.264.1616424562465; Mon, 22 Mar 2021 07:49:22 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzzkql8FbFnQsCmMCsOiz5ks4FVtEnlZIw5Q3bV5H0qEzH+Ljhf8TMKKFEr6QaZUostPU0wRA== X-Received: by 2002:a17:906:ae88:: with SMTP id md8mr132558ejb.264.1616424562275; Mon, 22 Mar 2021 07:49:22 -0700 (PDT) Received: from miu.piliscsaba.redhat.com (catv-86-101-169-67.catv.broadband.hu. [86.101.169.67]) by smtp.gmail.com with ESMTPSA id r4sm9793117ejd.125.2021.03.22.07.49.21 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Mar 2021 07:49:21 -0700 (PDT) From: Miklos Szeredi To: linux-fsdevel@vger.kernel.org Cc: Al Viro , linux-kernel@vger.kernel.org, Christoph Hellwig Subject: [PATCH v2 03/18] ovl: stack miscattr ops Date: Mon, 22 Mar 2021 15:49:01 +0100 Message-Id: <20210322144916.137245-4-mszeredi@redhat.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210322144916.137245-1-mszeredi@redhat.com> References: <20210322144916.137245-1-mszeredi@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Add stacking for the miscattr operations. Add hack for calling security_file_ioctl() for now. Probably better to have a pair of specific hooks for these operations. Signed-off-by: Miklos Szeredi --- fs/overlayfs/dir.c | 2 ++ fs/overlayfs/inode.c | 77 ++++++++++++++++++++++++++++++++++++++++ fs/overlayfs/overlayfs.h | 3 ++ 3 files changed, 82 insertions(+) diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c index 836f14b9d3a6..3cf091d0d0ff 100644 --- a/fs/overlayfs/dir.c +++ b/fs/overlayfs/dir.c @@ -1301,4 +1301,6 @@ const struct inode_operations ovl_dir_inode_operations = { .listxattr = ovl_listxattr, .get_acl = ovl_get_acl, .update_time = ovl_update_time, + .miscattr_get = ovl_miscattr_get, + .miscattr_set = ovl_miscattr_set, }; diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c index 003cf83bf78a..4915eea6d115 100644 --- a/fs/overlayfs/inode.c +++ b/fs/overlayfs/inode.c @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include "overlayfs.h" @@ -500,6 +502,79 @@ static int ovl_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, return err; } +/* + * Work around the fact that security_file_ioctl() takes a file argument. + * Introducing security_inode_miscattr_get/set() hooks would solve this issue + * properly. + */ +static int ovl_security_miscattr(struct dentry *dentry, struct miscattr *ma, + bool set) +{ + struct path realpath; + struct file *file; + unsigned int cmd; + int err; + + ovl_path_real(dentry, &realpath); + file = dentry_open(&realpath, O_RDONLY, current_cred()); + if (IS_ERR(file)) + return PTR_ERR(file); + + if (set) + cmd = ma->xattr_valid ? FS_IOC_FSSETXATTR : FS_IOC_SETFLAGS; + else + cmd = ma->xattr_valid ? FS_IOC_FSGETXATTR : FS_IOC_GETFLAGS; + + err = security_file_ioctl(file, cmd, 0); + fput(file); + + return err; +} + +int ovl_miscattr_set(struct user_namespace *mnt_userns, + struct dentry *dentry, struct miscattr *ma) +{ + struct inode *inode = d_inode(dentry); + struct dentry *upperdentry; + const struct cred *old_cred; + int err; + + err = ovl_want_write(dentry); + if (err) + goto out; + + err = ovl_copy_up(dentry); + if (!err) { + upperdentry = ovl_dentry_upper(dentry); + + old_cred = ovl_override_creds(inode->i_sb); + err = ovl_security_miscattr(dentry, ma, true); + if (!err) + err = vfs_miscattr_set(&init_user_ns, upperdentry, ma); + revert_creds(old_cred); + ovl_copyflags(ovl_inode_real(inode), inode); + } + ovl_drop_write(dentry); +out: + return err; +} + +int ovl_miscattr_get(struct dentry *dentry, struct miscattr *ma) +{ + struct inode *inode = d_inode(dentry); + struct dentry *realdentry = ovl_dentry_real(dentry); + const struct cred *old_cred; + int err; + + old_cred = ovl_override_creds(inode->i_sb); + err = ovl_security_miscattr(dentry, ma, false); + if (!err) + err = vfs_miscattr_get(realdentry, ma); + revert_creds(old_cred); + + return err; +} + static const struct inode_operations ovl_file_inode_operations = { .setattr = ovl_setattr, .permission = ovl_permission, @@ -508,6 +583,8 @@ static const struct inode_operations ovl_file_inode_operations = { .get_acl = ovl_get_acl, .update_time = ovl_update_time, .fiemap = ovl_fiemap, + .miscattr_get = ovl_miscattr_get, + .miscattr_set = ovl_miscattr_set, }; static const struct inode_operations ovl_symlink_inode_operations = { diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index 95cff83786a5..abd4d1316897 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -521,6 +521,9 @@ int __init ovl_aio_request_cache_init(void); void ovl_aio_request_cache_destroy(void); long ovl_ioctl(struct file *file, unsigned int cmd, unsigned long arg); long ovl_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg); +int ovl_miscattr_get(struct dentry *dentry, struct miscattr *ma); +int ovl_miscattr_set(struct user_namespace *mnt_userns, + struct dentry *dentry, struct miscattr *ma); /* copy_up.c */ int ovl_copy_up(struct dentry *dentry); From patchwork Mon Mar 22 14:49:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miklos Szeredi X-Patchwork-Id: 12155003 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7A3AEC433E5 for ; Mon, 22 Mar 2021 14:50:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 535DE6197F for ; Mon, 22 Mar 2021 14:50:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231351AbhCVOuB (ORCPT ); Mon, 22 Mar 2021 10:50:01 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:41394 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230509AbhCVOt1 (ORCPT ); Mon, 22 Mar 2021 10:49:27 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1616424566; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=NiR4kCL1vxhhgSeZhWIAluTciOjNo4o2vBMlvjqiGuM=; b=PcD0P4b/Gqm4Ecf7IPaemtAWjTOuuAZIm0/P4RLW9sMZUeK7wPtA87EOlXIJ69G3bH8KBc qtvDFW06twh7AqNk+y7ULzPwQWz6igHXI+lLoLryOsYjVwEXEYLfLwyiPrDvw8+bVjLYM3 wT9shasdhUTc6J9YrdFwVT+BxR8/WMg= Received: from mail-ej1-f71.google.com (mail-ej1-f71.google.com [209.85.218.71]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-106-Ev9c-NHcOKm3Mv-lyxTKGg-1; Mon, 22 Mar 2021 10:49:25 -0400 X-MC-Unique: Ev9c-NHcOKm3Mv-lyxTKGg-1 Received: by mail-ej1-f71.google.com with SMTP id a22so18198877ejx.10 for ; Mon, 22 Mar 2021 07:49:25 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=NiR4kCL1vxhhgSeZhWIAluTciOjNo4o2vBMlvjqiGuM=; b=sx0eFLbyzIMLctJ+7MEm3t0G4S+lKqCz47pmpcY1RRV0n665wql6A8Nd7IzJkUItor IkxWpufEoiRrCGMfmM5gx69qb87hr6y0enbplACQJcrDdGzhxnWd/3wG0Ps4uvP8RXEs xpCjqo3gtPWRhO0AAamsHRcis9pwqF6dd8PaYuReKL4mJ6o3NS5WZkzA+cbzJ9h1Zvkl JVwMRth6FgnE77u7qlyISV9KxgFXeA1Ay4JzD580YbFybMWacOJaQP133hnBg2hMWwWB NJ7AAYYmselLCl9doOC5+ryUISBKmTZTWtuIZwEXx/0yPDbklhce0VNUSZ66TkXqlAQM kPaA== X-Gm-Message-State: AOAM530nmZmMkf9ese/r6eEqtCgdIaA+y+0ZC/9M9ZmLctcRaKOnL0q6 sFA6CZ8viC2x73rad0WrmsTwEUsZW9neWPgSDK7n4PhyFfZ1Wvrz6MauH0Bkx93e5M8J7H0v9tp OCbn7f1cA1L0wxkY70Vk/X6VuxRwa+KXeqyiGGia9q22PFXCnZHzFpf/3Xij2Ei3S8uy4AvLQSG PEDQ== X-Received: by 2002:a17:906:6c93:: with SMTP id s19mr100468ejr.151.1616424563881; Mon, 22 Mar 2021 07:49:23 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwNCSOpbDxbwtV+2VfwBblXUo3YrAcDoEaE30kGY+hW/OY8M7Lff1NVzsrhmgRDVaufXbTDww== X-Received: by 2002:a17:906:6c93:: with SMTP id s19mr100440ejr.151.1616424563553; Mon, 22 Mar 2021 07:49:23 -0700 (PDT) Received: from miu.piliscsaba.redhat.com (catv-86-101-169-67.catv.broadband.hu. [86.101.169.67]) by smtp.gmail.com with ESMTPSA id r4sm9793117ejd.125.2021.03.22.07.49.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Mar 2021 07:49:23 -0700 (PDT) From: Miklos Szeredi To: linux-fsdevel@vger.kernel.org Cc: Al Viro , linux-kernel@vger.kernel.org, Christoph Hellwig , David Sterba Subject: [PATCH v2 04/18] btrfs: convert to miscattr Date: Mon, 22 Mar 2021 15:49:02 +0100 Message-Id: <20210322144916.137245-5-mszeredi@redhat.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210322144916.137245-1-mszeredi@redhat.com> References: <20210322144916.137245-1-mszeredi@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Use the miscattr API to let the VFS handle locking, permission checking and conversion. Signed-off-by: Miklos Szeredi Cc: David Sterba --- fs/btrfs/ctree.h | 3 + fs/btrfs/inode.c | 4 + fs/btrfs/ioctl.c | 249 +++++++++-------------------------------------- 3 files changed, 52 insertions(+), 204 deletions(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index bd659354d043..c79886675c16 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -3184,6 +3184,9 @@ void btrfs_update_inode_bytes(struct btrfs_inode *inode, /* ioctl.c */ long btrfs_ioctl(struct file *file, unsigned int cmd, unsigned long arg); long btrfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg); +int btrfs_miscattr_get(struct dentry *dentry, struct miscattr *ma); +int btrfs_miscattr_set(struct user_namespace *mnt_userns, + struct dentry *dentry, struct miscattr *ma); int btrfs_ioctl_get_supported_features(void __user *arg); void btrfs_sync_inode_flags_to_i_flags(struct inode *inode); int __pure btrfs_is_empty_uuid(u8 *uuid); diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 2e1c282c202d..e21642f17396 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -10556,6 +10556,8 @@ static const struct inode_operations btrfs_dir_inode_operations = { .set_acl = btrfs_set_acl, .update_time = btrfs_update_time, .tmpfile = btrfs_tmpfile, + .miscattr_get = btrfs_miscattr_get, + .miscattr_set = btrfs_miscattr_set, }; static const struct file_operations btrfs_dir_file_operations = { @@ -10609,6 +10611,8 @@ static const struct inode_operations btrfs_file_inode_operations = { .get_acl = btrfs_get_acl, .set_acl = btrfs_set_acl, .update_time = btrfs_update_time, + .miscattr_get = btrfs_miscattr_get, + .miscattr_set = btrfs_miscattr_set, }; static const struct inode_operations btrfs_special_inode_operations = { .getattr = btrfs_getattr, diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 072e77726e94..5ce445a9a331 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "ctree.h" #include "disk-io.h" #include "export.h" @@ -153,16 +154,6 @@ void btrfs_sync_inode_flags_to_i_flags(struct inode *inode) new_fl); } -static int btrfs_ioctl_getflags(struct file *file, void __user *arg) -{ - struct btrfs_inode *binode = BTRFS_I(file_inode(file)); - unsigned int flags = btrfs_inode_flags_to_fsflags(binode->flags); - - if (copy_to_user(arg, &flags, sizeof(flags))) - return -EFAULT; - return 0; -} - /* * Check if @flags are a supported and valid set of FS_*_FL flags and that * the old and new flags are not conflicting @@ -201,9 +192,34 @@ static int check_fsflags_compatible(struct btrfs_fs_info *fs_info, return 0; } -static int btrfs_ioctl_setflags(struct file *file, void __user *arg) +bool btrfs_exclop_start(struct btrfs_fs_info *fs_info, + enum btrfs_exclusive_operation type) { - struct inode *inode = file_inode(file); + return !cmpxchg(&fs_info->exclusive_operation, BTRFS_EXCLOP_NONE, type); +} + +void btrfs_exclop_finish(struct btrfs_fs_info *fs_info) +{ + WRITE_ONCE(fs_info->exclusive_operation, BTRFS_EXCLOP_NONE); + sysfs_notify(&fs_info->fs_devices->fsid_kobj, NULL, "exclusive_operation"); +} + +/* + * Set flags/xflags from the internal inode flags. The remaining items of + * fsxattr are zeroed. + */ +int btrfs_miscattr_get(struct dentry *dentry, struct miscattr *ma) +{ + struct btrfs_inode *binode = BTRFS_I(d_inode(dentry)); + + miscattr_fill_flags(ma, btrfs_inode_flags_to_fsflags(binode->flags)); + return 0; +} + +int btrfs_miscattr_set(struct user_namespace *mnt_userns, + struct dentry *dentry, struct miscattr *ma) +{ + struct inode *inode = d_inode(dentry); struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); struct btrfs_inode *binode = BTRFS_I(inode); struct btrfs_root *root = binode->root; @@ -213,34 +229,21 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) const char *comp = NULL; u32 binode_flags; - if (!inode_owner_or_capable(&init_user_ns, inode)) - return -EPERM; - if (btrfs_root_readonly(root)) return -EROFS; - if (copy_from_user(&fsflags, arg, sizeof(fsflags))) - return -EFAULT; - - ret = mnt_want_write_file(file); - if (ret) - return ret; + if (miscattr_has_xattr(ma)) + return -EOPNOTSUPP; - inode_lock(inode); - fsflags = btrfs_mask_fsflags_for_type(inode, fsflags); + fsflags = btrfs_mask_fsflags_for_type(inode, ma->flags); old_fsflags = btrfs_inode_flags_to_fsflags(binode->flags); - - ret = vfs_ioc_setflags_prepare(inode, old_fsflags, fsflags); - if (ret) - goto out_unlock; - ret = check_fsflags(old_fsflags, fsflags); if (ret) - goto out_unlock; + return ret; ret = check_fsflags_compatible(fs_info, fsflags); if (ret) - goto out_unlock; + return ret; binode_flags = binode->flags; if (fsflags & FS_SYNC_FL) @@ -263,6 +266,13 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) binode_flags |= BTRFS_INODE_NOATIME; else binode_flags &= ~BTRFS_INODE_NOATIME; + + /* if coming from FS_IOC_FSSETXATTR then skip unconverted flags */ + if (!ma->flags_valid) { + trans = btrfs_start_transaction(root, 1); + goto update_flags; + } + if (fsflags & FS_DIRSYNC_FL) binode_flags |= BTRFS_INODE_DIRSYNC; else @@ -303,10 +313,8 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) binode_flags |= BTRFS_INODE_NOCOMPRESS; } else if (fsflags & FS_COMPR_FL) { - if (IS_SWAPFILE(inode)) { - ret = -ETXTBSY; - goto out_unlock; - } + if (IS_SWAPFILE(inode)) + return -ETXTBSY; binode_flags |= BTRFS_INODE_COMPRESS; binode_flags &= ~BTRFS_INODE_NOCOMPRESS; @@ -323,10 +331,8 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) * 2 for properties */ trans = btrfs_start_transaction(root, 3); - if (IS_ERR(trans)) { - ret = PTR_ERR(trans); - goto out_unlock; - } + if (IS_ERR(trans)) + return PTR_ERR(trans); if (comp) { ret = btrfs_set_prop(trans, inode, "btrfs.compression", comp, @@ -344,6 +350,7 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) } } +update_flags: binode->flags = binode_flags; btrfs_sync_inode_flags_to_i_flags(inode); inode_inc_iversion(inode); @@ -352,158 +359,6 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) out_end_trans: btrfs_end_transaction(trans); - out_unlock: - inode_unlock(inode); - mnt_drop_write_file(file); - return ret; -} - -/* - * Translate btrfs internal inode flags to xflags as expected by the - * FS_IOC_FSGETXATT ioctl. Filter only the supported ones, unknown flags are - * silently dropped. - */ -static unsigned int btrfs_inode_flags_to_xflags(unsigned int flags) -{ - unsigned int xflags = 0; - - if (flags & BTRFS_INODE_APPEND) - xflags |= FS_XFLAG_APPEND; - if (flags & BTRFS_INODE_IMMUTABLE) - xflags |= FS_XFLAG_IMMUTABLE; - if (flags & BTRFS_INODE_NOATIME) - xflags |= FS_XFLAG_NOATIME; - if (flags & BTRFS_INODE_NODUMP) - xflags |= FS_XFLAG_NODUMP; - if (flags & BTRFS_INODE_SYNC) - xflags |= FS_XFLAG_SYNC; - - return xflags; -} - -/* Check if @flags are a supported and valid set of FS_XFLAGS_* flags */ -static int check_xflags(unsigned int flags) -{ - if (flags & ~(FS_XFLAG_APPEND | FS_XFLAG_IMMUTABLE | FS_XFLAG_NOATIME | - FS_XFLAG_NODUMP | FS_XFLAG_SYNC)) - return -EOPNOTSUPP; - return 0; -} - -bool btrfs_exclop_start(struct btrfs_fs_info *fs_info, - enum btrfs_exclusive_operation type) -{ - return !cmpxchg(&fs_info->exclusive_operation, BTRFS_EXCLOP_NONE, type); -} - -void btrfs_exclop_finish(struct btrfs_fs_info *fs_info) -{ - WRITE_ONCE(fs_info->exclusive_operation, BTRFS_EXCLOP_NONE); - sysfs_notify(&fs_info->fs_devices->fsid_kobj, NULL, "exclusive_operation"); -} - -/* - * Set the xflags from the internal inode flags. The remaining items of fsxattr - * are zeroed. - */ -static int btrfs_ioctl_fsgetxattr(struct file *file, void __user *arg) -{ - struct btrfs_inode *binode = BTRFS_I(file_inode(file)); - struct fsxattr fa; - - simple_fill_fsxattr(&fa, btrfs_inode_flags_to_xflags(binode->flags)); - if (copy_to_user(arg, &fa, sizeof(fa))) - return -EFAULT; - - return 0; -} - -static int btrfs_ioctl_fssetxattr(struct file *file, void __user *arg) -{ - struct inode *inode = file_inode(file); - struct btrfs_inode *binode = BTRFS_I(inode); - struct btrfs_root *root = binode->root; - struct btrfs_trans_handle *trans; - struct fsxattr fa, old_fa; - unsigned old_flags; - unsigned old_i_flags; - int ret = 0; - - if (!inode_owner_or_capable(&init_user_ns, inode)) - return -EPERM; - - if (btrfs_root_readonly(root)) - return -EROFS; - - if (copy_from_user(&fa, arg, sizeof(fa))) - return -EFAULT; - - ret = check_xflags(fa.fsx_xflags); - if (ret) - return ret; - - if (fa.fsx_extsize != 0 || fa.fsx_projid != 0 || fa.fsx_cowextsize != 0) - return -EOPNOTSUPP; - - ret = mnt_want_write_file(file); - if (ret) - return ret; - - inode_lock(inode); - - old_flags = binode->flags; - old_i_flags = inode->i_flags; - - simple_fill_fsxattr(&old_fa, - btrfs_inode_flags_to_xflags(binode->flags)); - ret = vfs_ioc_fssetxattr_check(inode, &old_fa, &fa); - if (ret) - goto out_unlock; - - if (fa.fsx_xflags & FS_XFLAG_SYNC) - binode->flags |= BTRFS_INODE_SYNC; - else - binode->flags &= ~BTRFS_INODE_SYNC; - if (fa.fsx_xflags & FS_XFLAG_IMMUTABLE) - binode->flags |= BTRFS_INODE_IMMUTABLE; - else - binode->flags &= ~BTRFS_INODE_IMMUTABLE; - if (fa.fsx_xflags & FS_XFLAG_APPEND) - binode->flags |= BTRFS_INODE_APPEND; - else - binode->flags &= ~BTRFS_INODE_APPEND; - if (fa.fsx_xflags & FS_XFLAG_NODUMP) - binode->flags |= BTRFS_INODE_NODUMP; - else - binode->flags &= ~BTRFS_INODE_NODUMP; - if (fa.fsx_xflags & FS_XFLAG_NOATIME) - binode->flags |= BTRFS_INODE_NOATIME; - else - binode->flags &= ~BTRFS_INODE_NOATIME; - - /* 1 item for the inode */ - trans = btrfs_start_transaction(root, 1); - if (IS_ERR(trans)) { - ret = PTR_ERR(trans); - goto out_unlock; - } - - btrfs_sync_inode_flags_to_i_flags(inode); - inode_inc_iversion(inode); - inode->i_ctime = current_time(inode); - ret = btrfs_update_inode(trans, root, BTRFS_I(inode)); - - btrfs_end_transaction(trans); - -out_unlock: - if (ret) { - binode->flags = old_flags; - inode->i_flags = old_i_flags; - } - - inode_unlock(inode); - mnt_drop_write_file(file); - return ret; } @@ -4898,10 +4753,6 @@ long btrfs_ioctl(struct file *file, unsigned int void __user *argp = (void __user *)arg; switch (cmd) { - case FS_IOC_GETFLAGS: - return btrfs_ioctl_getflags(file, argp); - case FS_IOC_SETFLAGS: - return btrfs_ioctl_setflags(file, argp); case FS_IOC_GETVERSION: return btrfs_ioctl_getversion(file, argp); case FS_IOC_GETFSLABEL: @@ -5027,10 +4878,6 @@ long btrfs_ioctl(struct file *file, unsigned int return btrfs_ioctl_get_features(fs_info, argp); case BTRFS_IOC_SET_FEATURES: return btrfs_ioctl_set_features(file, argp); - case FS_IOC_FSGETXATTR: - return btrfs_ioctl_fsgetxattr(file, argp); - case FS_IOC_FSSETXATTR: - return btrfs_ioctl_fssetxattr(file, argp); case BTRFS_IOC_GET_SUBVOL_INFO: return btrfs_ioctl_get_subvol_info(file, argp); case BTRFS_IOC_GET_SUBVOL_ROOTREF: @@ -5050,12 +4897,6 @@ long btrfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) * handling is necessary. */ switch (cmd) { - case FS_IOC32_GETFLAGS: - cmd = FS_IOC_GETFLAGS; - break; - case FS_IOC32_SETFLAGS: - cmd = FS_IOC_SETFLAGS; - break; case FS_IOC32_GETVERSION: cmd = FS_IOC_GETVERSION; break; From patchwork Mon Mar 22 14:49:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miklos Szeredi X-Patchwork-Id: 12155025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C144EC433E9 for ; Mon, 22 Mar 2021 14:50:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9CE4C619B2 for ; Mon, 22 Mar 2021 14:50:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231359AbhCVOuC (ORCPT ); Mon, 22 Mar 2021 10:50:02 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:28629 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230510AbhCVOt2 (ORCPT ); Mon, 22 Mar 2021 10:49:28 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1616424568; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=5u9SppafS3lTo/ie9QXPmsGSZMKkK44cjZgzUVYcroI=; b=P4XOGpPNE7WbGeAcSx6P6UmAvCSVUEQajMk5Pu5K01Wlh//d0KfhHYjKTnzaZGpzjLgLCd T8UF/u/rU6+hBCRChV+KVNJfeRTml84W7NNjBDr7kXBouA725yslYzNNyNqyGXoFYmLxcH X8EsdwsYcWhfh8HGblxb0A2PKJyj2dg= Received: from mail-ej1-f72.google.com (mail-ej1-f72.google.com [209.85.218.72]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-233-mQYY0wX3MluKU3TjMxYtBg-1; Mon, 22 Mar 2021 10:49:26 -0400 X-MC-Unique: mQYY0wX3MluKU3TjMxYtBg-1 Received: by mail-ej1-f72.google.com with SMTP id 11so19935449ejz.20 for ; Mon, 22 Mar 2021 07:49:26 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=5u9SppafS3lTo/ie9QXPmsGSZMKkK44cjZgzUVYcroI=; b=Wxyi1UYW40y+SulzOotSgbs3rxBBZ3o0DOAVbYY7nyZ8ehyYh+XKSUYG16/q0kw2cr 8E7NTN8fsTtIjo3JIz1lhKLHfoz2T+GNRWbuvijRtmqoGmr90xro9ybMtwyrdeTIL5DT oLY4HM+tHT6k0RPMgchNo3hfME4QXwUcLot1QGhWYUXT/LpXAgvPQPLeI9RvGGqhx/xr USq57R3NXNawbSmMSO+qLB+n0DUvMkngL4gzXbwYMazaBAAftYvkXwu+ZFN6E3mcALPp QmETRmrwMFR7lNAuVqSv/0CZ1NKsFWaz2iuYsPVtmtSnqSCdoBDcgdL1CmYBMaFWieqz ipcA== X-Gm-Message-State: AOAM533SD3cQ4YaFE8KTDC7d5uxWnr/+treVcnj0F50cvlMPI2TlcFeq mfBEZlfrg01ii441DloO/H3JTDVczZ5RwxWJuiSP+zVrT/dJ29xVK8Y4mvdAsmxfpek8wTagsig tkuqa86bBrM8C5Ne7VGr/KzfqmND4pI50k2d36KepS0LjSyKgMI9qvZ6pGZ5VUACwTgiJJUO5Lx HQaQ== X-Received: by 2002:a17:907:7684:: with SMTP id jv4mr92168ejc.231.1616424565138; Mon, 22 Mar 2021 07:49:25 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwYAiu8PvvALtGPtq/A7nK6wwCGYCNDiiqLXYXy9QiYeyDoQytSdKjdcHqPHnUrG3yYlgtjtQ== X-Received: by 2002:a17:907:7684:: with SMTP id jv4mr92149ejc.231.1616424564916; Mon, 22 Mar 2021 07:49:24 -0700 (PDT) Received: from miu.piliscsaba.redhat.com (catv-86-101-169-67.catv.broadband.hu. [86.101.169.67]) by smtp.gmail.com with ESMTPSA id r4sm9793117ejd.125.2021.03.22.07.49.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Mar 2021 07:49:24 -0700 (PDT) From: Miklos Szeredi To: linux-fsdevel@vger.kernel.org Cc: Al Viro , linux-kernel@vger.kernel.org, Christoph Hellwig , Jan Kara Subject: [PATCH v2 05/18] ext2: convert to miscattr Date: Mon, 22 Mar 2021 15:49:03 +0100 Message-Id: <20210322144916.137245-6-mszeredi@redhat.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210322144916.137245-1-mszeredi@redhat.com> References: <20210322144916.137245-1-mszeredi@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Use the miscattr API to let the VFS handle locking, permission checking and conversion. Signed-off-by: Miklos Szeredi Cc: Jan Kara --- fs/ext2/ext2.h | 7 ++-- fs/ext2/file.c | 2 ++ fs/ext2/ioctl.c | 88 ++++++++++++++++++------------------------------- fs/ext2/namei.c | 2 ++ 4 files changed, 39 insertions(+), 60 deletions(-) diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h index 3309fb2d327a..b58f27b1412b 100644 --- a/fs/ext2/ext2.h +++ b/fs/ext2/ext2.h @@ -283,8 +283,6 @@ static inline __u32 ext2_mask_flags(umode_t mode, __u32 flags) /* * ioctl commands */ -#define EXT2_IOC_GETFLAGS FS_IOC_GETFLAGS -#define EXT2_IOC_SETFLAGS FS_IOC_SETFLAGS #define EXT2_IOC_GETVERSION FS_IOC_GETVERSION #define EXT2_IOC_SETVERSION FS_IOC_SETVERSION #define EXT2_IOC_GETRSVSZ _IOR('f', 5, long) @@ -293,8 +291,6 @@ static inline __u32 ext2_mask_flags(umode_t mode, __u32 flags) /* * ioctl commands in 32 bit emulation */ -#define EXT2_IOC32_GETFLAGS FS_IOC32_GETFLAGS -#define EXT2_IOC32_SETFLAGS FS_IOC32_SETFLAGS #define EXT2_IOC32_GETVERSION FS_IOC32_GETVERSION #define EXT2_IOC32_SETVERSION FS_IOC32_SETVERSION @@ -772,6 +768,9 @@ extern int ext2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, u64 start, u64 len); /* ioctl.c */ +extern int ext2_miscattr_get(struct dentry *dentry, struct miscattr *ma); +extern int ext2_miscattr_set(struct user_namespace *mnt_userns, + struct dentry *dentry, struct miscattr *ma); extern long ext2_ioctl(struct file *, unsigned int, unsigned long); extern long ext2_compat_ioctl(struct file *, unsigned int, unsigned long); diff --git a/fs/ext2/file.c b/fs/ext2/file.c index 96044f5dbc0e..096c03612129 100644 --- a/fs/ext2/file.c +++ b/fs/ext2/file.c @@ -204,4 +204,6 @@ const struct inode_operations ext2_file_inode_operations = { .get_acl = ext2_get_acl, .set_acl = ext2_set_acl, .fiemap = ext2_fiemap, + .miscattr_get = ext2_miscattr_get, + .miscattr_set = ext2_miscattr_set, }; diff --git a/fs/ext2/ioctl.c b/fs/ext2/ioctl.c index b399cbb7022d..f841d4439c62 100644 --- a/fs/ext2/ioctl.c +++ b/fs/ext2/ioctl.c @@ -16,69 +16,51 @@ #include #include #include +#include - -long ext2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +int ext2_miscattr_get(struct dentry *dentry, struct miscattr *ma) { - struct inode *inode = file_inode(filp); - struct ext2_inode_info *ei = EXT2_I(inode); - unsigned int flags; - unsigned short rsv_window_size; - int ret; + struct ext2_inode_info *ei = EXT2_I(d_inode(dentry)); - ext2_debug ("cmd = %u, arg = %lu\n", cmd, arg); + miscattr_fill_flags(ma, ei->i_flags & EXT2_FL_USER_VISIBLE); - switch (cmd) { - case EXT2_IOC_GETFLAGS: - flags = ei->i_flags & EXT2_FL_USER_VISIBLE; - return put_user(flags, (int __user *) arg); - case EXT2_IOC_SETFLAGS: { - unsigned int oldflags; + return 0; +} - ret = mnt_want_write_file(filp); - if (ret) - return ret; +int ext2_miscattr_set(struct user_namespace *mnt_userns, + struct dentry *dentry, struct miscattr *ma) +{ + struct inode *inode = d_inode(dentry); + struct ext2_inode_info *ei = EXT2_I(inode); - if (!inode_owner_or_capable(&init_user_ns, inode)) { - ret = -EACCES; - goto setflags_out; - } + if (miscattr_has_xattr(ma)) + return -EOPNOTSUPP; - if (get_user(flags, (int __user *) arg)) { - ret = -EFAULT; - goto setflags_out; - } + /* Is it quota file? Do not allow user to mess with it */ + if (IS_NOQUOTA(inode)) + return -EPERM; - flags = ext2_mask_flags(inode->i_mode, flags); + ei->i_flags = (ei->i_flags & ~EXT2_FL_USER_MODIFIABLE) | + (ma->flags & EXT2_FL_USER_MODIFIABLE); - inode_lock(inode); - /* Is it quota file? Do not allow user to mess with it */ - if (IS_NOQUOTA(inode)) { - inode_unlock(inode); - ret = -EPERM; - goto setflags_out; - } - oldflags = ei->i_flags; + ext2_set_inode_flags(inode); + inode->i_ctime = current_time(inode); + mark_inode_dirty(inode); - ret = vfs_ioc_setflags_prepare(inode, oldflags, flags); - if (ret) { - inode_unlock(inode); - goto setflags_out; - } + return 0; +} - flags = flags & EXT2_FL_USER_MODIFIABLE; - flags |= oldflags & ~EXT2_FL_USER_MODIFIABLE; - ei->i_flags = flags; - ext2_set_inode_flags(inode); - inode->i_ctime = current_time(inode); - inode_unlock(inode); +long ext2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + struct inode *inode = file_inode(filp); + struct ext2_inode_info *ei = EXT2_I(inode); + unsigned short rsv_window_size; + int ret; - mark_inode_dirty(inode); -setflags_out: - mnt_drop_write_file(filp); - return ret; - } + ext2_debug ("cmd = %u, arg = %lu\n", cmd, arg); + + switch (cmd) { case EXT2_IOC_GETVERSION: return put_user(inode->i_generation, (int __user *) arg); case EXT2_IOC_SETVERSION: { @@ -163,12 +145,6 @@ long ext2_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { /* These are just misnamed, they actually get/put from/to user an int */ switch (cmd) { - case EXT2_IOC32_GETFLAGS: - cmd = EXT2_IOC_GETFLAGS; - break; - case EXT2_IOC32_SETFLAGS: - cmd = EXT2_IOC_SETFLAGS; - break; case EXT2_IOC32_GETVERSION: cmd = EXT2_IOC_GETVERSION; break; diff --git a/fs/ext2/namei.c b/fs/ext2/namei.c index 3367384d344d..c0fd2e025d49 100644 --- a/fs/ext2/namei.c +++ b/fs/ext2/namei.c @@ -427,6 +427,8 @@ const struct inode_operations ext2_dir_inode_operations = { .get_acl = ext2_get_acl, .set_acl = ext2_set_acl, .tmpfile = ext2_tmpfile, + .miscattr_get = ext2_miscattr_get, + .miscattr_set = ext2_miscattr_set, }; const struct inode_operations ext2_special_inode_operations = { From patchwork Mon Mar 22 14:49:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miklos Szeredi X-Patchwork-Id: 12155015 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 24AD5C433EB for ; Mon, 22 Mar 2021 14:50:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 044086192D for ; Mon, 22 Mar 2021 14:50:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231368AbhCVOuE (ORCPT ); Mon, 22 Mar 2021 10:50:04 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]:58925 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229673AbhCVOta (ORCPT ); Mon, 22 Mar 2021 10:49:30 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1616424569; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=jSkZ7B7k6S9HW5Wm1R5UscAP6nymq2s7HdqB6of48Yk=; b=YhHqjLWSVyAARwHG2whhz6+P/xaWaQer/apmVjGH6DNdyjD2s9bmG81/Gj4osBim4JgsRF H+Vg59cN8a4xMEWraVk138jmZQuMdI2fehSY5nvGBzrKahDBi+hMsdi293ho/NQUOb3GIm dU5NCxhjpWLkZmhIQm4me2CHfCOmax0= Received: from mail-ej1-f71.google.com (mail-ej1-f71.google.com [209.85.218.71]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-222-xw0WqGyfMBuoIQogxwjkAQ-1; Mon, 22 Mar 2021 10:49:27 -0400 X-MC-Unique: xw0WqGyfMBuoIQogxwjkAQ-1 Received: by mail-ej1-f71.google.com with SMTP id rl7so19905378ejb.16 for ; Mon, 22 Mar 2021 07:49:27 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=jSkZ7B7k6S9HW5Wm1R5UscAP6nymq2s7HdqB6of48Yk=; b=osO6HwZer9i0nRjwJb8v+1ATM2jzH9pT37tuMgzYF3+P/fb2gV12E6RKyN+JJ72dZZ oVPavSAv8uaoUy6PDdlXMm+WqwEE0XMyYqs2hdrUE2Z9jb80nwmjtiOvoL1U5MhqsYk6 6TZlJe/RnsbFhmrS8C8XjmtgBNGwwvBfx2f3QSsGMLYuD9itBm0mzukEwzifqP0YryOj Ai7REh5SQeaIzMiRg66KyXrXeHynMHzqHELIUAKLiaVo5tGIxapbOLnFGDmlPH/us4f6 Cvz3hn5udeD9w1ZwsLc3CGT0iILi2eXuSphhWwhj+O9TdqbgtNxglho6hESbNgfx8meX PPxw== X-Gm-Message-State: AOAM532dVB18rI0vSpO1CoCpJxPvAV+zQd0NSwD0PJP3ucxsceKP/csf bR7rH2NbGu6E1ZaUFY07ha5OxLLSmfg2AvD3JBGHbsb3IOeQddyblV1A1DA/SalY99h4gIiGXB0 ON9yW+idyEOf6fc+B5iRLrzy963dxvKCngUUWZhDg8g31rzF2kGXKbR88aPhX7dX6MLQRvfiqzv SbUg== X-Received: by 2002:a17:906:f896:: with SMTP id lg22mr144577ejb.124.1616424566169; Mon, 22 Mar 2021 07:49:26 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyJcNBUxdVQM3A9V32QrO3V4zWs0898V1EC9zTeWG+6Wlr1ZoBNEfJku2kI7KICsBc65gZdfg== X-Received: by 2002:a17:906:f896:: with SMTP id lg22mr144552ejb.124.1616424565928; Mon, 22 Mar 2021 07:49:25 -0700 (PDT) Received: from miu.piliscsaba.redhat.com (catv-86-101-169-67.catv.broadband.hu. [86.101.169.67]) by smtp.gmail.com with ESMTPSA id r4sm9793117ejd.125.2021.03.22.07.49.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Mar 2021 07:49:25 -0700 (PDT) From: Miklos Szeredi To: linux-fsdevel@vger.kernel.org Cc: Al Viro , linux-kernel@vger.kernel.org, Christoph Hellwig , "Theodore Ts'o" Subject: [PATCH v2 06/18] ext4: convert to miscattr Date: Mon, 22 Mar 2021 15:49:04 +0100 Message-Id: <20210322144916.137245-7-mszeredi@redhat.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210322144916.137245-1-mszeredi@redhat.com> References: <20210322144916.137245-1-mszeredi@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Use the miscattr API to let the VFS handle locking, permission checking and conversion. Signed-off-by: Miklos Szeredi Cc: "Theodore Ts'o" --- fs/ext4/ext4.h | 12 +-- fs/ext4/file.c | 2 + fs/ext4/ioctl.c | 210 ++++++++++-------------------------------------- fs/ext4/namei.c | 2 + 4 files changed, 51 insertions(+), 175 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 644fd69185d3..35de98f69fde 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -472,15 +472,6 @@ struct flex_groups { EXT4_VERITY_FL | \ EXT4_INLINE_DATA_FL) -/* Flags we can manipulate with through FS_IOC_FSSETXATTR */ -#define EXT4_FL_XFLAG_VISIBLE (EXT4_SYNC_FL | \ - EXT4_IMMUTABLE_FL | \ - EXT4_APPEND_FL | \ - EXT4_NODUMP_FL | \ - EXT4_NOATIME_FL | \ - EXT4_PROJINHERIT_FL | \ - EXT4_DAX_FL) - /* Flags that should be inherited by new inodes from their parent. */ #define EXT4_FL_INHERITED (EXT4_SECRM_FL | EXT4_UNRM_FL | EXT4_COMPR_FL |\ EXT4_SYNC_FL | EXT4_NODUMP_FL | EXT4_NOATIME_FL |\ @@ -2925,6 +2916,9 @@ extern int ext4_ind_remove_space(handle_t *handle, struct inode *inode, /* ioctl.c */ extern long ext4_ioctl(struct file *, unsigned int, unsigned long); extern long ext4_compat_ioctl(struct file *, unsigned int, unsigned long); +int ext4_miscattr_set(struct user_namespace *mnt_userns, + struct dentry *dentry, struct miscattr *ma); +int ext4_miscattr_get(struct dentry *dentry, struct miscattr *ma); extern void ext4_reset_inode_seed(struct inode *inode); /* migrate.c */ diff --git a/fs/ext4/file.c b/fs/ext4/file.c index 194f5d00fa32..1681372573db 100644 --- a/fs/ext4/file.c +++ b/fs/ext4/file.c @@ -919,5 +919,7 @@ const struct inode_operations ext4_file_inode_operations = { .get_acl = ext4_get_acl, .set_acl = ext4_set_acl, .fiemap = ext4_fiemap, + .miscattr_get = ext4_miscattr_get, + .miscattr_set = ext4_miscattr_set, }; diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index a2cf35066f46..88aeb97df039 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "ext4_jbd2.h" #include "ext4.h" #include @@ -344,11 +345,6 @@ static int ext4_ioctl_setflags(struct inode *inode, goto flags_out; oldflags = ei->i_flags; - - err = vfs_ioc_setflags_prepare(inode, oldflags, flags); - if (err) - goto flags_out; - /* * The JOURNAL_DATA flag can only be changed by * the relevant capability. @@ -459,9 +455,8 @@ static int ext4_ioctl_setflags(struct inode *inode, } #ifdef CONFIG_QUOTA -static int ext4_ioctl_setproject(struct file *filp, __u32 projid) +static int ext4_ioctl_setproject(struct inode *inode, __u32 projid) { - struct inode *inode = file_inode(filp); struct super_block *sb = inode->i_sb; struct ext4_inode_info *ei = EXT4_I(inode); int err, rc; @@ -545,7 +540,7 @@ static int ext4_ioctl_setproject(struct file *filp, __u32 projid) return err; } #else -static int ext4_ioctl_setproject(struct file *filp, __u32 projid) +static int ext4_ioctl_setproject(struct inode *inode, __u32 projid) { if (projid != EXT4_DEF_PROJID) return -EOPNOTSUPP; @@ -553,56 +548,6 @@ static int ext4_ioctl_setproject(struct file *filp, __u32 projid) } #endif -/* Transfer internal flags to xflags */ -static inline __u32 ext4_iflags_to_xflags(unsigned long iflags) -{ - __u32 xflags = 0; - - if (iflags & EXT4_SYNC_FL) - xflags |= FS_XFLAG_SYNC; - if (iflags & EXT4_IMMUTABLE_FL) - xflags |= FS_XFLAG_IMMUTABLE; - if (iflags & EXT4_APPEND_FL) - xflags |= FS_XFLAG_APPEND; - if (iflags & EXT4_NODUMP_FL) - xflags |= FS_XFLAG_NODUMP; - if (iflags & EXT4_NOATIME_FL) - xflags |= FS_XFLAG_NOATIME; - if (iflags & EXT4_PROJINHERIT_FL) - xflags |= FS_XFLAG_PROJINHERIT; - if (iflags & EXT4_DAX_FL) - xflags |= FS_XFLAG_DAX; - return xflags; -} - -#define EXT4_SUPPORTED_FS_XFLAGS (FS_XFLAG_SYNC | FS_XFLAG_IMMUTABLE | \ - FS_XFLAG_APPEND | FS_XFLAG_NODUMP | \ - FS_XFLAG_NOATIME | FS_XFLAG_PROJINHERIT | \ - FS_XFLAG_DAX) - -/* Transfer xflags flags to internal */ -static inline unsigned long ext4_xflags_to_iflags(__u32 xflags) -{ - unsigned long iflags = 0; - - if (xflags & FS_XFLAG_SYNC) - iflags |= EXT4_SYNC_FL; - if (xflags & FS_XFLAG_IMMUTABLE) - iflags |= EXT4_IMMUTABLE_FL; - if (xflags & FS_XFLAG_APPEND) - iflags |= EXT4_APPEND_FL; - if (xflags & FS_XFLAG_NODUMP) - iflags |= EXT4_NODUMP_FL; - if (xflags & FS_XFLAG_NOATIME) - iflags |= EXT4_NOATIME_FL; - if (xflags & FS_XFLAG_PROJINHERIT) - iflags |= EXT4_PROJINHERIT_FL; - if (xflags & FS_XFLAG_DAX) - iflags |= EXT4_DAX_FL; - - return iflags; -} - static int ext4_shutdown(struct super_block *sb, unsigned long arg) { struct ext4_sb_info *sbi = EXT4_SB(sb); @@ -770,15 +715,52 @@ static long ext4_ioctl_group_add(struct file *file, return err; } -static void ext4_fill_fsxattr(struct inode *inode, struct fsxattr *fa) +int ext4_miscattr_get(struct dentry *dentry, struct miscattr *ma) { + struct inode *inode = d_inode(dentry); struct ext4_inode_info *ei = EXT4_I(inode); + u32 flags = ei->i_flags & EXT4_FL_USER_VISIBLE; - simple_fill_fsxattr(fa, ext4_iflags_to_xflags(ei->i_flags & - EXT4_FL_USER_VISIBLE)); + if (S_ISREG(inode->i_mode)) + flags &= ~FS_PROJINHERIT_FL; + miscattr_fill_flags(ma, flags); if (ext4_has_feature_project(inode->i_sb)) - fa->fsx_projid = from_kprojid(&init_user_ns, ei->i_projid); + ma->fsx_projid = from_kprojid(&init_user_ns, ei->i_projid); + + return 0; +} + +int ext4_miscattr_set(struct user_namespace *mnt_userns, + struct dentry *dentry, struct miscattr *ma) +{ + struct inode *inode = d_inode(dentry); + u32 flags = ma->flags; + int err = -EOPNOTSUPP; + + ext4_fc_start_update(inode); + if (flags & ~EXT4_FL_USER_VISIBLE) + goto out; + + /* + * chattr(1) grabs flags via GETFLAGS, modifies the result and + * passes that to SETFLAGS. So we cannot easily make SETFLAGS + * more restrictive than just silently masking off visible but + * not settable flags as we always did. + */ + flags &= EXT4_FL_USER_MODIFIABLE; + if (ext4_mask_flags(inode->i_mode, flags) != flags) + goto out; + err = ext4_ioctl_check_immutable(inode, ma->fsx_projid, flags); + if (err) + goto out; + err = ext4_ioctl_setflags(inode, flags); + if (err) + goto out; + err = ext4_ioctl_setproject(inode, ma->fsx_projid); +out: + ext4_fc_stop_update(inode); + return err; } /* So that the fiemap access checks can't overflow on 32 bit machines. */ @@ -816,55 +798,13 @@ static long __ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct inode *inode = file_inode(filp); struct super_block *sb = inode->i_sb; - struct ext4_inode_info *ei = EXT4_I(inode); struct user_namespace *mnt_userns = file_mnt_user_ns(filp); - unsigned int flags; ext4_debug("cmd = %u, arg = %lu\n", cmd, arg); switch (cmd) { case FS_IOC_GETFSMAP: return ext4_ioc_getfsmap(sb, (void __user *)arg); - case FS_IOC_GETFLAGS: - flags = ei->i_flags & EXT4_FL_USER_VISIBLE; - if (S_ISREG(inode->i_mode)) - flags &= ~EXT4_PROJINHERIT_FL; - return put_user(flags, (int __user *) arg); - case FS_IOC_SETFLAGS: { - int err; - - if (!inode_owner_or_capable(mnt_userns, inode)) - return -EACCES; - - if (get_user(flags, (int __user *) arg)) - return -EFAULT; - - if (flags & ~EXT4_FL_USER_VISIBLE) - return -EOPNOTSUPP; - /* - * chattr(1) grabs flags via GETFLAGS, modifies the result and - * passes that to SETFLAGS. So we cannot easily make SETFLAGS - * more restrictive than just silently masking off visible but - * not settable flags as we always did. - */ - flags &= EXT4_FL_USER_MODIFIABLE; - if (ext4_mask_flags(inode->i_mode, flags) != flags) - return -EOPNOTSUPP; - - err = mnt_want_write_file(filp); - if (err) - return err; - - inode_lock(inode); - err = ext4_ioctl_check_immutable(inode, - from_kprojid(&init_user_ns, ei->i_projid), - flags); - if (!err) - err = ext4_ioctl_setflags(inode, flags); - inode_unlock(inode); - mnt_drop_write_file(filp); - return err; - } case EXT4_IOC_GETVERSION: case EXT4_IOC_GETVERSION_OLD: return put_user(inode->i_generation, (int __user *) arg); @@ -1246,60 +1186,6 @@ static long __ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) case EXT4_IOC_GET_ES_CACHE: return ext4_ioctl_get_es_cache(filp, arg); - case FS_IOC_FSGETXATTR: - { - struct fsxattr fa; - - ext4_fill_fsxattr(inode, &fa); - - if (copy_to_user((struct fsxattr __user *)arg, - &fa, sizeof(fa))) - return -EFAULT; - return 0; - } - case FS_IOC_FSSETXATTR: - { - struct fsxattr fa, old_fa; - int err; - - if (copy_from_user(&fa, (struct fsxattr __user *)arg, - sizeof(fa))) - return -EFAULT; - - /* Make sure caller has proper permission */ - if (!inode_owner_or_capable(mnt_userns, inode)) - return -EACCES; - - if (fa.fsx_xflags & ~EXT4_SUPPORTED_FS_XFLAGS) - return -EOPNOTSUPP; - - flags = ext4_xflags_to_iflags(fa.fsx_xflags); - if (ext4_mask_flags(inode->i_mode, flags) != flags) - return -EOPNOTSUPP; - - err = mnt_want_write_file(filp); - if (err) - return err; - - inode_lock(inode); - ext4_fill_fsxattr(inode, &old_fa); - err = vfs_ioc_fssetxattr_check(inode, &old_fa, &fa); - if (err) - goto out; - flags = (ei->i_flags & ~EXT4_FL_XFLAG_VISIBLE) | - (flags & EXT4_FL_XFLAG_VISIBLE); - err = ext4_ioctl_check_immutable(inode, fa.fsx_projid, flags); - if (err) - goto out; - err = ext4_ioctl_setflags(inode, flags); - if (err) - goto out; - err = ext4_ioctl_setproject(filp, fa.fsx_projid); -out: - inode_unlock(inode); - mnt_drop_write_file(filp); - return err; - } case EXT4_IOC_SHUTDOWN: return ext4_shutdown(sb, arg); @@ -1340,12 +1226,6 @@ long ext4_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { /* These are just misnamed, they actually get/put from/to user an int */ switch (cmd) { - case FS_IOC32_GETFLAGS: - cmd = FS_IOC_GETFLAGS; - break; - case FS_IOC32_SETFLAGS: - cmd = FS_IOC_SETFLAGS; - break; case EXT4_IOC32_GETVERSION: cmd = EXT4_IOC_GETVERSION; break; @@ -1405,8 +1285,6 @@ long ext4_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case EXT4_IOC_CLEAR_ES_CACHE: case EXT4_IOC_GETSTATE: case EXT4_IOC_GET_ES_CACHE: - case FS_IOC_FSGETXATTR: - case FS_IOC_FSSETXATTR: break; default: return -ENOIOCTLCMD; diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 686bf982c84e..4a77c54266bf 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -4144,6 +4144,8 @@ const struct inode_operations ext4_dir_inode_operations = { .get_acl = ext4_get_acl, .set_acl = ext4_set_acl, .fiemap = ext4_fiemap, + .miscattr_get = ext4_miscattr_get, + .miscattr_set = ext4_miscattr_set, }; const struct inode_operations ext4_special_inode_operations = { From patchwork Mon Mar 22 14:49:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miklos Szeredi X-Patchwork-Id: 12155005 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7B82DC433F1 for ; Mon, 22 Mar 2021 14:50:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3AE4861992 for ; Mon, 22 Mar 2021 14:50:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231378AbhCVOuF (ORCPT ); Mon, 22 Mar 2021 10:50:05 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:39944 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231131AbhCVOtb (ORCPT ); Mon, 22 Mar 2021 10:49:31 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1616424570; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=a4V1N4pT6t9ImhrwS/GWO9w5PZTKJq9H+K8Q+fWnhkw=; b=f5xf6e6cjBiLhC560fQT72C1YTIoutjdgxDciLWnZ2N5fCayV2Psqqgg/2sLGqgJrF8ahw e7dvz2TLqsOd+WbDyoeB9HYi/qlkCpbtdxSLfO1Vq6BQFsBqvkC5xFUa+JhNOvaZqmkDrr v1qY1UGV9smlbmlgtVQsvHHfG4mWwCo= Received: from mail-ed1-f72.google.com (mail-ed1-f72.google.com [209.85.208.72]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-441-trIpEUsSM5SYjX7t-aYIbQ-1; Mon, 22 Mar 2021 10:49:29 -0400 X-MC-Unique: trIpEUsSM5SYjX7t-aYIbQ-1 Received: by mail-ed1-f72.google.com with SMTP id bm8so14387807edb.4 for ; Mon, 22 Mar 2021 07:49:28 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=a4V1N4pT6t9ImhrwS/GWO9w5PZTKJq9H+K8Q+fWnhkw=; b=e4sudjtge7l8CNsaMlS59rilHZNFnLs71iljIikJrr8n+l+I2eLT7Gtbcg76UR/VXz KerQpb/nFOYLwqqRZkwC9wW8nxNA0NVH5MzS2KWlKA/cS+9db+MNC8Hq+R0aoucGxlW1 w4StkrLIO6Kdp6UHvOOXj2ho2RKyQh5Mg6x5ZQLG0wokHRCayKghBWgKJhPkJBsG2UYc ZJy1ZN21M/mAmoFzotuMogNbq2O8ZOhlA+2IgDbByIF35WDtLmIA2VFs9XMxUOlnZWc3 Tg43OjGp+R3eiisE4IX/953hiplx+gq9RB8K35vjc+eouPCBDUYZ/UmLZuVDxZXEJ3ej WvGg== X-Gm-Message-State: AOAM532HgMVg47Oti61uDo2O+qjxpnY/wZLlLTpUIxonFYwp1+sEaOaI 1+T7WFqpw467EdHpny95mkTqekPRkr1a/4Oio0di2TKObfZSE1dOYRDHRYJufdnqlSuj+erXKzc zNjkW+UHRR9feOQKWsr5arVUZrLcMUagfw8XjDQCnkxXgByzxL+2i+6G43WlKveD/OSv3kMzgyq UM0Q== X-Received: by 2002:a17:906:1352:: with SMTP id x18mr59953ejb.545.1616424567251; Mon, 22 Mar 2021 07:49:27 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxTLGBsqc7+9spg/2GW58Y1L4HGC9RBd2to6IM+kEf0f94IQ2RxtyBMHRQp5Gc/mgQAGyQSRQ== X-Received: by 2002:a17:906:1352:: with SMTP id x18mr59934ejb.545.1616424567062; Mon, 22 Mar 2021 07:49:27 -0700 (PDT) Received: from miu.piliscsaba.redhat.com (catv-86-101-169-67.catv.broadband.hu. [86.101.169.67]) by smtp.gmail.com with ESMTPSA id r4sm9793117ejd.125.2021.03.22.07.49.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Mar 2021 07:49:26 -0700 (PDT) From: Miklos Szeredi To: linux-fsdevel@vger.kernel.org Cc: Al Viro , linux-kernel@vger.kernel.org, Christoph Hellwig , Jaegeuk Kim Subject: [PATCH v2 07/18] f2fs: convert to miscattr Date: Mon, 22 Mar 2021 15:49:05 +0100 Message-Id: <20210322144916.137245-8-mszeredi@redhat.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210322144916.137245-1-mszeredi@redhat.com> References: <20210322144916.137245-1-mszeredi@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Use the miscattr API to let the VFS handle locking, permission checking and conversion. Signed-off-by: Miklos Szeredi Cc: Jaegeuk Kim --- fs/f2fs/f2fs.h | 3 + fs/f2fs/file.c | 213 ++++++++---------------------------------------- fs/f2fs/namei.c | 2 + 3 files changed, 40 insertions(+), 178 deletions(-) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index e2d302ae3a46..9236fd3dc7e5 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -3194,6 +3194,9 @@ int f2fs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, int f2fs_truncate_hole(struct inode *inode, pgoff_t pg_start, pgoff_t pg_end); void f2fs_truncate_data_blocks_range(struct dnode_of_data *dn, int count); int f2fs_precache_extents(struct inode *inode); +int f2fs_miscattr_get(struct dentry *dentry, struct miscattr *ma); +int f2fs_miscattr_set(struct user_namespace *mnt_userns, + struct dentry *dentry, struct miscattr *ma); long f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg); int f2fs_transfer_project_quota(struct inode *inode, kprojid_t kprojid); diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index d26ff2ae3f5e..504e5bedabac 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "f2fs.h" #include "node.h" @@ -990,6 +991,8 @@ const struct inode_operations f2fs_file_inode_operations = { .set_acl = f2fs_set_acl, .listxattr = f2fs_listxattr, .fiemap = f2fs_fiemap, + .miscattr_get = f2fs_miscattr_get, + .miscattr_set = f2fs_miscattr_set, }; static int fill_zero(struct inode *inode, pgoff_t index, @@ -1952,67 +1955,6 @@ static inline u32 f2fs_fsflags_to_iflags(u32 fsflags) return iflags; } -static int f2fs_ioc_getflags(struct file *filp, unsigned long arg) -{ - struct inode *inode = file_inode(filp); - struct f2fs_inode_info *fi = F2FS_I(inode); - u32 fsflags = f2fs_iflags_to_fsflags(fi->i_flags); - - if (IS_ENCRYPTED(inode)) - fsflags |= FS_ENCRYPT_FL; - if (IS_VERITY(inode)) - fsflags |= FS_VERITY_FL; - if (f2fs_has_inline_data(inode) || f2fs_has_inline_dentry(inode)) - fsflags |= FS_INLINE_DATA_FL; - if (is_inode_flag_set(inode, FI_PIN_FILE)) - fsflags |= FS_NOCOW_FL; - - fsflags &= F2FS_GETTABLE_FS_FL; - - return put_user(fsflags, (int __user *)arg); -} - -static int f2fs_ioc_setflags(struct file *filp, unsigned long arg) -{ - struct inode *inode = file_inode(filp); - struct f2fs_inode_info *fi = F2FS_I(inode); - u32 fsflags, old_fsflags; - u32 iflags; - int ret; - - if (!inode_owner_or_capable(&init_user_ns, inode)) - return -EACCES; - - if (get_user(fsflags, (int __user *)arg)) - return -EFAULT; - - if (fsflags & ~F2FS_GETTABLE_FS_FL) - return -EOPNOTSUPP; - fsflags &= F2FS_SETTABLE_FS_FL; - - iflags = f2fs_fsflags_to_iflags(fsflags); - if (f2fs_mask_flags(inode->i_mode, iflags) != iflags) - return -EOPNOTSUPP; - - ret = mnt_want_write_file(filp); - if (ret) - return ret; - - inode_lock(inode); - - old_fsflags = f2fs_iflags_to_fsflags(fi->i_flags); - ret = vfs_ioc_setflags_prepare(inode, old_fsflags, fsflags); - if (ret) - goto out; - - ret = f2fs_setflags_common(inode, iflags, - f2fs_fsflags_to_iflags(F2FS_SETTABLE_FS_FL)); -out: - inode_unlock(inode); - mnt_drop_write_file(filp); - return ret; -} - static int f2fs_ioc_getversion(struct file *filp, unsigned long arg) { struct inode *inode = file_inode(filp); @@ -3019,9 +2961,8 @@ int f2fs_transfer_project_quota(struct inode *inode, kprojid_t kprojid) return err; } -static int f2fs_ioc_setproject(struct file *filp, __u32 projid) +static int f2fs_ioc_setproject(struct inode *inode, __u32 projid) { - struct inode *inode = file_inode(filp); struct f2fs_inode_info *fi = F2FS_I(inode); struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct page *ipage; @@ -3082,7 +3023,7 @@ int f2fs_transfer_project_quota(struct inode *inode, kprojid_t kprojid) return 0; } -static int f2fs_ioc_setproject(struct file *filp, __u32 projid) +static int f2fs_ioc_setproject(struct inode *inode, __u32 projid) { if (projid != F2FS_DEF_PROJID) return -EOPNOTSUPP; @@ -3090,123 +3031,55 @@ static int f2fs_ioc_setproject(struct file *filp, __u32 projid) } #endif -/* FS_IOC_FSGETXATTR and FS_IOC_FSSETXATTR support */ - -/* - * To make a new on-disk f2fs i_flag gettable via FS_IOC_FSGETXATTR and settable - * via FS_IOC_FSSETXATTR, add an entry for it to f2fs_xflags_map[], and add its - * FS_XFLAG_* equivalent to F2FS_SUPPORTED_XFLAGS. - */ - -static const struct { - u32 iflag; - u32 xflag; -} f2fs_xflags_map[] = { - { F2FS_SYNC_FL, FS_XFLAG_SYNC }, - { F2FS_IMMUTABLE_FL, FS_XFLAG_IMMUTABLE }, - { F2FS_APPEND_FL, FS_XFLAG_APPEND }, - { F2FS_NODUMP_FL, FS_XFLAG_NODUMP }, - { F2FS_NOATIME_FL, FS_XFLAG_NOATIME }, - { F2FS_PROJINHERIT_FL, FS_XFLAG_PROJINHERIT }, -}; - -#define F2FS_SUPPORTED_XFLAGS ( \ - FS_XFLAG_SYNC | \ - FS_XFLAG_IMMUTABLE | \ - FS_XFLAG_APPEND | \ - FS_XFLAG_NODUMP | \ - FS_XFLAG_NOATIME | \ - FS_XFLAG_PROJINHERIT) - -/* Convert f2fs on-disk i_flags to FS_IOC_FS{GET,SET}XATTR flags */ -static inline u32 f2fs_iflags_to_xflags(u32 iflags) -{ - u32 xflags = 0; - int i; - - for (i = 0; i < ARRAY_SIZE(f2fs_xflags_map); i++) - if (iflags & f2fs_xflags_map[i].iflag) - xflags |= f2fs_xflags_map[i].xflag; - - return xflags; -} - -/* Convert FS_IOC_FS{GET,SET}XATTR flags to f2fs on-disk i_flags */ -static inline u32 f2fs_xflags_to_iflags(u32 xflags) -{ - u32 iflags = 0; - int i; - - for (i = 0; i < ARRAY_SIZE(f2fs_xflags_map); i++) - if (xflags & f2fs_xflags_map[i].xflag) - iflags |= f2fs_xflags_map[i].iflag; - - return iflags; -} - -static void f2fs_fill_fsxattr(struct inode *inode, struct fsxattr *fa) +int f2fs_miscattr_get(struct dentry *dentry, struct miscattr *ma) { + struct inode *inode = d_inode(dentry); struct f2fs_inode_info *fi = F2FS_I(inode); + u32 fsflags = f2fs_iflags_to_fsflags(fi->i_flags); - simple_fill_fsxattr(fa, f2fs_iflags_to_xflags(fi->i_flags)); - - if (f2fs_sb_has_project_quota(F2FS_I_SB(inode))) - fa->fsx_projid = from_kprojid(&init_user_ns, fi->i_projid); -} + if (IS_ENCRYPTED(inode)) + fsflags |= FS_ENCRYPT_FL; + if (IS_VERITY(inode)) + fsflags |= FS_VERITY_FL; + if (f2fs_has_inline_data(inode) || f2fs_has_inline_dentry(inode)) + fsflags |= FS_INLINE_DATA_FL; + if (is_inode_flag_set(inode, FI_PIN_FILE)) + fsflags |= FS_NOCOW_FL; -static int f2fs_ioc_fsgetxattr(struct file *filp, unsigned long arg) -{ - struct inode *inode = file_inode(filp); - struct fsxattr fa; + miscattr_fill_flags(ma, fsflags & F2FS_GETTABLE_FS_FL); - f2fs_fill_fsxattr(inode, &fa); + if (f2fs_sb_has_project_quota(F2FS_I_SB(inode))) + ma->fsx_projid = from_kprojid(&init_user_ns, fi->i_projid); - if (copy_to_user((struct fsxattr __user *)arg, &fa, sizeof(fa))) - return -EFAULT; return 0; } -static int f2fs_ioc_fssetxattr(struct file *filp, unsigned long arg) +int f2fs_miscattr_set(struct user_namespace *mnt_userns, + struct dentry *dentry, struct miscattr *ma) { - struct inode *inode = file_inode(filp); - struct fsxattr fa, old_fa; + struct inode *inode = d_inode(dentry); + u32 fsflags = ma->flags, mask = F2FS_SETTABLE_FS_FL; u32 iflags; int err; - if (copy_from_user(&fa, (struct fsxattr __user *)arg, sizeof(fa))) - return -EFAULT; - - /* Make sure caller has proper permission */ - if (!inode_owner_or_capable(&init_user_ns, inode)) - return -EACCES; - - if (fa.fsx_xflags & ~F2FS_SUPPORTED_XFLAGS) + if (unlikely(f2fs_cp_error(F2FS_I_SB(inode)))) + return -EIO; + if (!f2fs_is_checkpoint_ready(F2FS_I_SB(inode))) + return -ENOSPC; + if (fsflags & ~F2FS_GETTABLE_FS_FL) return -EOPNOTSUPP; + fsflags &= F2FS_SETTABLE_FS_FL; + if (!ma->flags_valid) + mask &= FS_COMMON_FL; - iflags = f2fs_xflags_to_iflags(fa.fsx_xflags); + iflags = f2fs_fsflags_to_iflags(fsflags); if (f2fs_mask_flags(inode->i_mode, iflags) != iflags) return -EOPNOTSUPP; - err = mnt_want_write_file(filp); - if (err) - return err; - - inode_lock(inode); - - f2fs_fill_fsxattr(inode, &old_fa); - err = vfs_ioc_fssetxattr_check(inode, &old_fa, &fa); - if (err) - goto out; - - err = f2fs_setflags_common(inode, iflags, - f2fs_xflags_to_iflags(F2FS_SUPPORTED_XFLAGS)); - if (err) - goto out; + err = f2fs_setflags_common(inode, iflags, f2fs_fsflags_to_iflags(mask)); + if (!err) + err = f2fs_ioc_setproject(inode, ma->fsx_projid); - err = f2fs_ioc_setproject(filp, fa.fsx_projid); -out: - inode_unlock(inode); - mnt_drop_write_file(filp); return err; } @@ -4233,10 +4106,6 @@ static int f2fs_ioc_compress_file(struct file *filp, unsigned long arg) static long __f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { switch (cmd) { - case FS_IOC_GETFLAGS: - return f2fs_ioc_getflags(filp, arg); - case FS_IOC_SETFLAGS: - return f2fs_ioc_setflags(filp, arg); case FS_IOC_GETVERSION: return f2fs_ioc_getversion(filp, arg); case F2FS_IOC_START_ATOMIC_WRITE: @@ -4285,10 +4154,6 @@ static long __f2fs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) return f2fs_ioc_flush_device(filp, arg); case F2FS_IOC_GET_FEATURES: return f2fs_ioc_get_features(filp, arg); - case FS_IOC_FSGETXATTR: - return f2fs_ioc_fsgetxattr(filp, arg); - case FS_IOC_FSSETXATTR: - return f2fs_ioc_fssetxattr(filp, arg); case F2FS_IOC_GET_PIN_FILE: return f2fs_ioc_get_pin_file(filp, arg); case F2FS_IOC_SET_PIN_FILE: @@ -4518,12 +4383,6 @@ long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) return -ENOSPC; switch (cmd) { - case FS_IOC32_GETFLAGS: - cmd = FS_IOC_GETFLAGS; - break; - case FS_IOC32_SETFLAGS: - cmd = FS_IOC_SETFLAGS; - break; case FS_IOC32_GETVERSION: cmd = FS_IOC_GETVERSION; break; @@ -4552,8 +4411,6 @@ long f2fs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case F2FS_IOC_DEFRAGMENT: case F2FS_IOC_FLUSH_DEVICE: case F2FS_IOC_GET_FEATURES: - case FS_IOC_FSGETXATTR: - case FS_IOC_FSSETXATTR: case F2FS_IOC_GET_PIN_FILE: case F2FS_IOC_SET_PIN_FILE: case F2FS_IOC_PRECACHE_EXTENTS: diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c index 17bd072a5d39..c69d6ccc3ad8 100644 --- a/fs/f2fs/namei.c +++ b/fs/f2fs/namei.c @@ -1327,6 +1327,8 @@ const struct inode_operations f2fs_dir_inode_operations = { .set_acl = f2fs_set_acl, .listxattr = f2fs_listxattr, .fiemap = f2fs_fiemap, + .miscattr_get = f2fs_miscattr_get, + .miscattr_set = f2fs_miscattr_set, }; const struct inode_operations f2fs_symlink_inode_operations = { From patchwork Mon Mar 22 14:49:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miklos Szeredi X-Patchwork-Id: 12155007 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0985CC433EC for ; Mon, 22 Mar 2021 14:50:26 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DDBC2619B6 for ; Mon, 22 Mar 2021 14:50:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231373AbhCVOuE (ORCPT ); Mon, 22 Mar 2021 10:50:04 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:53394 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230341AbhCVOtb (ORCPT ); Mon, 22 Mar 2021 10:49:31 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1616424571; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=m0UT6buOCuHiMZiz7dgH8JIkhEVns2iHBom9UOEBNqw=; b=PDzWdknNKOKhansqCz6adfx91fg210Z65qdbye8BAr2zU5QNX69qaXN++qotSZVI0ZxsZ6 f6qR2AnDCAO/7GWZVSuhXftcyjcGoJjPd9K5WcYOf/+JZiZPFIEWT3NUfRlLnB3B98UIqh eTC6NiF/hzZYJJubkGakcJVJ4US2g4g= Received: from mail-ej1-f72.google.com (mail-ej1-f72.google.com [209.85.218.72]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-597-LgorbzdDPcamZdM7hXbekQ-1; Mon, 22 Mar 2021 10:49:29 -0400 X-MC-Unique: LgorbzdDPcamZdM7hXbekQ-1 Received: by mail-ej1-f72.google.com with SMTP id e13so19897246ejd.21 for ; Mon, 22 Mar 2021 07:49:29 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=m0UT6buOCuHiMZiz7dgH8JIkhEVns2iHBom9UOEBNqw=; b=ni1+rYEwbvQ8l1g4VTTtkqmJgLx/8ZuTkZKDnw127ORa51BRRjzHUVt/2aXb4SzeMm 5G6skuqASgf0er7+autZcDioB3xkhknFE+1tAYHa6hZxpnXfdgNJ8UD7HRJsO3XQ4Nh1 SeEiehhvrAiMxYYR2rqanR9yHa00eSEjmO5jFezBt3D1ZZ6x1gJf3/1rYCT3jU8VhdOJ XtCBaayFDfdBGhWAInTCnUmVlno06TzE+zZ+87PLu9xOo26wU65sSZ7bNvk2JiP8sSJW am/vREeTz42Z982rZO2lZcLg9khtHtyodjOvDtSSjRIj0VZ621zrVYbiXquBjPFBOoF0 IbRQ== X-Gm-Message-State: AOAM530Pvf2q6vYVHVil4h/oYt1x2h9UTlsMjc0BDTx7jYPbhaHfOFwk Zbc6E+6/zmBCZ5Nr9zroaekzz5OihJX0xLNRAC8gSvNfEmVpIq1dVDM2KIiw4j4Tzvdqa/6eZPh +OgFdh40LrfJ9XXJqYpqpmpWrttxYdTEr6b2AIIq5JLnUzJXE8OgM1k5FNnbHe9+DLzxpBw/JZG SYuQ== X-Received: by 2002:aa7:c450:: with SMTP id n16mr25328823edr.16.1616424568149; Mon, 22 Mar 2021 07:49:28 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzqQo93gPshAMY/nkGLVOa42liJvcoNs+fvYz3SgxSrOfsT/nVV8MKZ138x086vyC6g1I53Tg== X-Received: by 2002:aa7:c450:: with SMTP id n16mr25328799edr.16.1616424567953; Mon, 22 Mar 2021 07:49:27 -0700 (PDT) Received: from miu.piliscsaba.redhat.com (catv-86-101-169-67.catv.broadband.hu. [86.101.169.67]) by smtp.gmail.com with ESMTPSA id r4sm9793117ejd.125.2021.03.22.07.49.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Mar 2021 07:49:27 -0700 (PDT) From: Miklos Szeredi To: linux-fsdevel@vger.kernel.org Cc: Al Viro , linux-kernel@vger.kernel.org, Christoph Hellwig , Andreas Gruenbacher Subject: [PATCH v2 08/18] gfs2: convert to miscattr Date: Mon, 22 Mar 2021 15:49:06 +0100 Message-Id: <20210322144916.137245-9-mszeredi@redhat.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210322144916.137245-1-mszeredi@redhat.com> References: <20210322144916.137245-1-mszeredi@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Use the miscattr API to let the VFS handle locking, permission checking and conversion. Signed-off-by: Miklos Szeredi Cc: Andreas Gruenbacher --- fs/gfs2/file.c | 57 ++++++++++++------------------------------------- fs/gfs2/inode.c | 4 ++++ fs/gfs2/inode.h | 3 +++ 3 files changed, 21 insertions(+), 43 deletions(-) diff --git a/fs/gfs2/file.c b/fs/gfs2/file.c index 2d500f90cdac..b77669089f9a 100644 --- a/fs/gfs2/file.c +++ b/fs/gfs2/file.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "gfs2.h" #include "incore.h" @@ -153,9 +154,9 @@ static inline u32 gfs2_gfsflags_to_fsflags(struct inode *inode, u32 gfsflags) return fsflags; } -static int gfs2_get_flags(struct file *filp, u32 __user *ptr) +int gfs2_miscattr_get(struct dentry *dentry, struct miscattr *ma) { - struct inode *inode = file_inode(filp); + struct inode *inode = d_inode(dentry); struct gfs2_inode *ip = GFS2_I(inode); struct gfs2_holder gh; int error; @@ -168,8 +169,7 @@ static int gfs2_get_flags(struct file *filp, u32 __user *ptr) fsflags = gfs2_gfsflags_to_fsflags(inode, ip->i_diskflags); - if (put_user(fsflags, ptr)) - error = -EFAULT; + miscattr_fill_flags(ma, fsflags); gfs2_glock_dq(&gh); out_uninit: @@ -213,33 +213,19 @@ void gfs2_set_inode_flags(struct inode *inode) * @fsflags: The FS_* inode flags passed in * */ -static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask, +static int do_gfs2_set_flags(struct inode *inode, u32 reqflags, u32 mask, const u32 fsflags) { - struct inode *inode = file_inode(filp); struct gfs2_inode *ip = GFS2_I(inode); struct gfs2_sbd *sdp = GFS2_SB(inode); struct buffer_head *bh; struct gfs2_holder gh; int error; - u32 new_flags, flags, oldflags; - - error = mnt_want_write_file(filp); - if (error) - return error; + u32 new_flags, flags; error = gfs2_glock_nq_init(ip->i_gl, LM_ST_EXCLUSIVE, 0, &gh); if (error) - goto out_drop_write; - - oldflags = gfs2_gfsflags_to_fsflags(inode, ip->i_diskflags); - error = vfs_ioc_setflags_prepare(inode, oldflags, fsflags); - if (error) - goto out; - - error = -EACCES; - if (!inode_owner_or_capable(&init_user_ns, inode)) - goto out; + return error; error = 0; flags = ip->i_diskflags; @@ -252,9 +238,6 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask, goto out; if (IS_APPEND(inode) && (new_flags & GFS2_DIF_APPENDONLY)) goto out; - if (((new_flags ^ flags) & GFS2_DIF_IMMUTABLE) && - !capable(CAP_LINUX_IMMUTABLE)) - goto out; if (!IS_IMMUTABLE(inode)) { error = gfs2_permission(&init_user_ns, inode, MAY_WRITE); if (error) @@ -291,20 +274,19 @@ static int do_gfs2_set_flags(struct file *filp, u32 reqflags, u32 mask, gfs2_trans_end(sdp); out: gfs2_glock_dq_uninit(&gh); -out_drop_write: - mnt_drop_write_file(filp); return error; } -static int gfs2_set_flags(struct file *filp, u32 __user *ptr) +int gfs2_miscattr_set(struct user_namespace *mnt_userns, + struct dentry *dentry, struct miscattr *ma) { - struct inode *inode = file_inode(filp); - u32 fsflags, gfsflags = 0; + struct inode *inode = d_inode(dentry); + u32 fsflags = ma->flags, gfsflags = 0; u32 mask; int i; - if (get_user(fsflags, ptr)) - return -EFAULT; + if (miscattr_has_xattr(ma)) + return -EOPNOTSUPP; for (i = 0; i < ARRAY_SIZE(fsflag_gfs2flag); i++) { if (fsflags & fsflag_gfs2flag[i].fsflag) { @@ -325,7 +307,7 @@ static int gfs2_set_flags(struct file *filp, u32 __user *ptr) mask &= ~(GFS2_DIF_TOPDIR | GFS2_DIF_INHERIT_JDATA); } - return do_gfs2_set_flags(filp, gfsflags, mask, fsflags); + return do_gfs2_set_flags(inode, gfsflags, mask, fsflags); } static int gfs2_getlabel(struct file *filp, char __user *label) @@ -342,10 +324,6 @@ static int gfs2_getlabel(struct file *filp, char __user *label) static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { switch(cmd) { - case FS_IOC_GETFLAGS: - return gfs2_get_flags(filp, (u32 __user *)arg); - case FS_IOC_SETFLAGS: - return gfs2_set_flags(filp, (u32 __user *)arg); case FITRIM: return gfs2_fitrim(filp, (void __user *)arg); case FS_IOC_GETFSLABEL: @@ -359,13 +337,6 @@ static long gfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) static long gfs2_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { switch(cmd) { - /* These are just misnamed, they actually get/put from/to user an int */ - case FS_IOC32_GETFLAGS: - cmd = FS_IOC_GETFLAGS; - break; - case FS_IOC32_SETFLAGS: - cmd = FS_IOC_SETFLAGS; - break; /* Keep this list in sync with gfs2_ioctl */ case FITRIM: case FS_IOC_GETFSLABEL: diff --git a/fs/gfs2/inode.c b/fs/gfs2/inode.c index c9775d5c6594..c01d9cfb21e7 100644 --- a/fs/gfs2/inode.c +++ b/fs/gfs2/inode.c @@ -2157,6 +2157,8 @@ static const struct inode_operations gfs2_file_iops = { .get_acl = gfs2_get_acl, .set_acl = gfs2_set_acl, .update_time = gfs2_update_time, + .miscattr_get = gfs2_miscattr_get, + .miscattr_set = gfs2_miscattr_set, }; static const struct inode_operations gfs2_dir_iops = { @@ -2178,6 +2180,8 @@ static const struct inode_operations gfs2_dir_iops = { .set_acl = gfs2_set_acl, .update_time = gfs2_update_time, .atomic_open = gfs2_atomic_open, + .miscattr_get = gfs2_miscattr_get, + .miscattr_set = gfs2_miscattr_set, }; static const struct inode_operations gfs2_symlink_iops = { diff --git a/fs/gfs2/inode.h b/fs/gfs2/inode.h index c447bd5b3017..bd2fbbe58def 100644 --- a/fs/gfs2/inode.h +++ b/fs/gfs2/inode.h @@ -111,6 +111,9 @@ extern loff_t gfs2_seek_hole(struct file *file, loff_t offset); extern const struct file_operations gfs2_file_fops_nolock; extern const struct file_operations gfs2_dir_fops_nolock; +extern int gfs2_miscattr_get(struct dentry *dentry, struct miscattr *ma); +extern int gfs2_miscattr_set(struct user_namespace *mnt_userns, + struct dentry *dentry, struct miscattr *ma); extern void gfs2_set_inode_flags(struct inode *inode); #ifdef CONFIG_GFS2_FS_LOCKING_DLM From patchwork Mon Mar 22 14:49:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miklos Szeredi X-Patchwork-Id: 12155023 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id AD0DBC433E0 for ; Mon, 22 Mar 2021 14:50:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 5F80D6198E for ; Mon, 22 Mar 2021 14:50:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231389AbhCVOuI (ORCPT ); Mon, 22 Mar 2021 10:50:08 -0400 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:41195 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231162AbhCVOtc (ORCPT ); Mon, 22 Mar 2021 10:49:32 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1616424572; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/Cwv/A5Pnk5CT0fyBXdfr9uvoDC2TwyHyBwylJYn+jg=; b=OaWD2fAA2hXZmjtxnTrPIMJW3xe/u25jXJ/Y2s9DFVCUKgUR/iGFQBM7Ia/BErPbUdlzID eIPKMXkdH9RpWfcIBN8hOwMj7i/Ot5RiU9KLy9vELZdNufFi/IpQFbhcS97QkqmlhRzoJ+ dpDKeP+byySNSk1LR0NcErmEerdgCNY= Received: from mail-ej1-f71.google.com (mail-ej1-f71.google.com [209.85.218.71]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-394-sorSDT8kMmuqhFIN5vJo-g-1; Mon, 22 Mar 2021 10:49:30 -0400 X-MC-Unique: sorSDT8kMmuqhFIN5vJo-g-1 Received: by mail-ej1-f71.google.com with SMTP id si4so20098926ejb.23 for ; Mon, 22 Mar 2021 07:49:30 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/Cwv/A5Pnk5CT0fyBXdfr9uvoDC2TwyHyBwylJYn+jg=; b=k58xkB8wLGcOGgbOCU5XXmUt2zWBAv9Vi6dMSKBhHre25Mk8R4rcpLFCFsQafTM7Dc 57zipEZSvNPDhpD2uL0SXcghHNic7dmD5duPt48rRW8p3wum3VTdI4tJUnhCuCl/A1FL YH+aNPoqZFbJ+SahaGpZodl0YgTjIrPFeJQaNVPWB5xM9n+KuZ+kNsMlU+M/lb7VdKtp RZuuoC5moPUmHxyxnedQugXIdHglqEslO95l9mmISVGDOHmMyDBs5I1UkwQ+XClV2HzD BjmZupud2SupbNydkWKsv7v5ae9XFeu6ZbHpXoAOwg9FR18E/dJwV21p5pRx+e+bpCAC lWYw== X-Gm-Message-State: AOAM532jGseLL0xLXsaYm+fMq2sWnB4Atk6+NA21JqnC+dnGhF8Bu1wi pT1o/r4XJuj1jnZD0Fx1MnR+zxsG5xjOGeXVX65Pv3VzhjVLUzdH8OkL5S0nWadEE4PdVQhzEGr zI3BkV/+jpzWGCExPY2enSINx9+5opN1At0Bv7QvMviWy+pH2af95CxrIQp0oOXokxorqGDo4on Kq0Q== X-Received: by 2002:a17:906:1182:: with SMTP id n2mr141744eja.234.1616424569298; Mon, 22 Mar 2021 07:49:29 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxJIYmOlDKByJ9Dk+F+G0oPabnbfghfW6yyl+j7PzALL3UI4Hs/OS2XUo6XBJRDxLON7Oh6bg== X-Received: by 2002:a17:906:1182:: with SMTP id n2mr141722eja.234.1616424569052; Mon, 22 Mar 2021 07:49:29 -0700 (PDT) Received: from miu.piliscsaba.redhat.com (catv-86-101-169-67.catv.broadband.hu. [86.101.169.67]) by smtp.gmail.com with ESMTPSA id r4sm9793117ejd.125.2021.03.22.07.49.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Mar 2021 07:49:28 -0700 (PDT) From: Miklos Szeredi To: linux-fsdevel@vger.kernel.org Cc: Al Viro , linux-kernel@vger.kernel.org, Christoph Hellwig , Mike Marshall Subject: [PATCH v2 09/18] orangefs: convert to miscattr Date: Mon, 22 Mar 2021 15:49:07 +0100 Message-Id: <20210322144916.137245-10-mszeredi@redhat.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210322144916.137245-1-mszeredi@redhat.com> References: <20210322144916.137245-1-mszeredi@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Use the miscattr API to let the VFS handle locking, permission checking and conversion. Signed-off-by: Miklos Szeredi Cc: Mike Marshall --- fs/orangefs/file.c | 79 --------------------------------------------- fs/orangefs/inode.c | 50 ++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 79 deletions(-) diff --git a/fs/orangefs/file.c b/fs/orangefs/file.c index 9b28a7132466..ccef8c9dd516 100644 --- a/fs/orangefs/file.c +++ b/fs/orangefs/file.c @@ -375,84 +375,6 @@ static ssize_t orangefs_file_write_iter(struct kiocb *iocb, return ret; } -static int orangefs_getflags(struct inode *inode, unsigned long *uval) -{ - __u64 val = 0; - int ret; - - ret = orangefs_inode_getxattr(inode, - "user.pvfs2.meta_hint", - &val, sizeof(val)); - if (ret < 0 && ret != -ENODATA) - return ret; - else if (ret == -ENODATA) - val = 0; - *uval = val; - return 0; -} - -/* - * Perform a miscellaneous operation on a file. - */ -static long orangefs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct inode *inode = file_inode(file); - int ret = -ENOTTY; - __u64 val = 0; - unsigned long uval; - - gossip_debug(GOSSIP_FILE_DEBUG, - "orangefs_ioctl: called with cmd %d\n", - cmd); - - /* - * we understand some general ioctls on files, such as the immutable - * and append flags - */ - if (cmd == FS_IOC_GETFLAGS) { - ret = orangefs_getflags(inode, &uval); - if (ret) - return ret; - gossip_debug(GOSSIP_FILE_DEBUG, - "orangefs_ioctl: FS_IOC_GETFLAGS: %llu\n", - (unsigned long long)uval); - return put_user(uval, (int __user *)arg); - } else if (cmd == FS_IOC_SETFLAGS) { - unsigned long old_uval; - - ret = 0; - if (get_user(uval, (int __user *)arg)) - return -EFAULT; - /* - * ORANGEFS_MIRROR_FL is set internally when the mirroring mode - * is turned on for a file. The user is not allowed to turn - * on this bit, but the bit is present if the user first gets - * the flags and then updates the flags with some new - * settings. So, we ignore it in the following edit. bligon. - */ - if ((uval & ~ORANGEFS_MIRROR_FL) & - (~(FS_IMMUTABLE_FL | FS_APPEND_FL | FS_NOATIME_FL))) { - gossip_err("orangefs_ioctl: the FS_IOC_SETFLAGS only supports setting one of FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NOATIME_FL\n"); - return -EINVAL; - } - ret = orangefs_getflags(inode, &old_uval); - if (ret) - return ret; - ret = vfs_ioc_setflags_prepare(inode, old_uval, uval); - if (ret) - return ret; - val = uval; - gossip_debug(GOSSIP_FILE_DEBUG, - "orangefs_ioctl: FS_IOC_SETFLAGS: %llu\n", - (unsigned long long)val); - ret = orangefs_inode_setxattr(inode, - "user.pvfs2.meta_hint", - &val, sizeof(val), 0); - } - - return ret; -} - static vm_fault_t orangefs_fault(struct vm_fault *vmf) { struct file *file = vmf->vma->vm_file; @@ -657,7 +579,6 @@ const struct file_operations orangefs_file_operations = { .read_iter = orangefs_file_read_iter, .write_iter = orangefs_file_write_iter, .lock = orangefs_lock, - .unlocked_ioctl = orangefs_ioctl, .mmap = orangefs_file_mmap, .open = generic_file_open, .splice_read = generic_file_splice_read, diff --git a/fs/orangefs/inode.c b/fs/orangefs/inode.c index 5079cfafa8d7..63d420d091f8 100644 --- a/fs/orangefs/inode.c +++ b/fs/orangefs/inode.c @@ -11,6 +11,7 @@ */ #include +#include #include "protocol.h" #include "orangefs-kernel.h" #include "orangefs-bufmap.h" @@ -954,6 +955,53 @@ int orangefs_update_time(struct inode *inode, struct timespec64 *time, int flags return __orangefs_setattr(inode, &iattr); } +static int orangefs_miscattr_get(struct dentry *dentry, struct miscattr *ma) +{ + u64 val = 0; + int ret; + + gossip_debug(GOSSIP_FILE_DEBUG, "%s: called on %pd\n", __func__, + dentry); + + ret = orangefs_inode_getxattr(d_inode(dentry), + "user.pvfs2.meta_hint", + &val, sizeof(val)); + if (ret < 0 && ret != -ENODATA) + return ret; + + gossip_debug(GOSSIP_FILE_DEBUG, "%s: flags=%u\n", __func__, (u32) val); + + miscattr_fill_flags(ma, val); + return 0; +} + +static int orangefs_miscattr_set(struct user_namespace *mnt_userns, + struct dentry *dentry, struct miscattr *ma) +{ + u64 val = 0; + + gossip_debug(GOSSIP_FILE_DEBUG, "%s: called on %pd\n", __func__, + dentry); + /* + * ORANGEFS_MIRROR_FL is set internally when the mirroring mode is + * turned on for a file. The user is not allowed to turn on this bit, + * but the bit is present if the user first gets the flags and then + * updates the flags with some new settings. So, we ignore it in the + * following edit. bligon. + */ + if (miscattr_has_xattr(ma) || + (ma->flags & ~(FS_IMMUTABLE_FL | FS_APPEND_FL | FS_NOATIME_FL | ORANGEFS_MIRROR_FL))) { + gossip_err("%s: only supports setting one of FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NOATIME_FL\n", + __func__); + return -EOPNOTSUPP; + } + val = ma->flags; + gossip_debug(GOSSIP_FILE_DEBUG, "%s: flags=%u\n", __func__, (u32) val); + return orangefs_inode_setxattr(d_inode(dentry), + "user.pvfs2.meta_hint", + &val, sizeof(val), 0); +} + /* ORANGEFS2 implementation of VFS inode operations for files */ static const struct inode_operations orangefs_file_inode_operations = { .get_acl = orangefs_get_acl, @@ -963,6 +1011,8 @@ static const struct inode_operations orangefs_file_inode_operations = { .listxattr = orangefs_listxattr, .permission = orangefs_permission, .update_time = orangefs_update_time, + .miscattr_get = orangefs_miscattr_get, + .miscattr_set = orangefs_miscattr_set, }; static int orangefs_init_iops(struct inode *inode) From patchwork Mon Mar 22 14:49:08 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miklos Szeredi X-Patchwork-Id: 12155013 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id F1043C433F2 for ; Mon, 22 Mar 2021 14:50:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CE31A6192D for ; Mon, 22 Mar 2021 14:50:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231403AbhCVOuK (ORCPT ); Mon, 22 Mar 2021 10:50:10 -0400 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:23192 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231199AbhCVOtf (ORCPT ); Mon, 22 Mar 2021 10:49:35 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1616424574; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=e98FGcmKFjpFS3LKlPLNjfDTHU79Xr3bXL5xeBp/qmo=; b=HpvQq5HiGYJj0Z6msNszOfe8IlXSAQV1LIrP1iCAgx3OLEp9NzEVuChoe4kGuTR5HHOwf2 XOorDq7GTmNc3efy3oesvOVhFQrLpieYi1HBVI/8wYPF6SWq5B6eANr0M9X8Qmyie12T8n tuwXQfvM5FE0NlJSPAK7DJxybKEXo0s= Received: from mail-ed1-f70.google.com (mail-ed1-f70.google.com [209.85.208.70]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-508-sqWfk7lPO4GpPEutBlGwSw-1; Mon, 22 Mar 2021 10:49:32 -0400 X-MC-Unique: sqWfk7lPO4GpPEutBlGwSw-1 Received: by mail-ed1-f70.google.com with SMTP id k8so27505692edn.19 for ; Mon, 22 Mar 2021 07:49:32 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=e98FGcmKFjpFS3LKlPLNjfDTHU79Xr3bXL5xeBp/qmo=; b=JQJDNXH1kYp96hUExqoXyF/8zW+7WasyaILPo6WRlpUzSXd2KtIcUgkemFonNSCrNv E/TAr58qm2EHlluGwiM+f+mi8HYh8u121BDjbfVRW8qm7xJgInObcV86XwAKWIAg0Osp 0yhhOpGdpEmHdaGEWmDyPbSR8lvzpMalvODKwTpKtObDpuYwflxeFaaYfVO4I2Gnsabt Oye3bbBc4bF0aOVaPCI86F74puP9lNJsLsNF2l8P084TsxOOFFgA54xTjRk2cJylN1g6 gi/mlYKMb4mGcp1fJomqzEwL8WR1vQkUUM6P5p1UCRVxftcMYUOEWJ87cmn9B0Ecs6OY OlYg== X-Gm-Message-State: AOAM532y3wOBBljKAmfeaDSUfNrgu7utAjU1RJM7bbQCqFVB/Bos13SS PcYqu2We0d3CYQEzsl3x8QZqJ0oY1cnktDqaG20QYm8xBQ/hDjwz55sA5j2ve7yuFEkDOMhYJps L2TPTLC80BRyg4U7C8i0Hvdeul7fdHTjhpIRfL0WPsPE66DgaBDhI4/xAQzdFjeeYjRcmwU1ON6 P+yg== X-Received: by 2002:a17:906:1986:: with SMTP id g6mr60919ejd.533.1616424571114; Mon, 22 Mar 2021 07:49:31 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwAXI2VYef2kxQ4lof5soxYVswOdOeBgIuCE2WrYOl3yCTDlpFpigNLdmfeRxNoSwRwCfixRQ== X-Received: by 2002:a17:906:1986:: with SMTP id g6mr60893ejd.533.1616424570846; Mon, 22 Mar 2021 07:49:30 -0700 (PDT) Received: from miu.piliscsaba.redhat.com (catv-86-101-169-67.catv.broadband.hu. [86.101.169.67]) by smtp.gmail.com with ESMTPSA id r4sm9793117ejd.125.2021.03.22.07.49.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Mar 2021 07:49:30 -0700 (PDT) From: Miklos Szeredi To: linux-fsdevel@vger.kernel.org Cc: Al Viro , linux-kernel@vger.kernel.org, Christoph Hellwig , "Darrick J . Wong" Subject: [PATCH v2 10/18] xfs: convert to miscattr Date: Mon, 22 Mar 2021 15:49:08 +0100 Message-Id: <20210322144916.137245-11-mszeredi@redhat.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210322144916.137245-1-mszeredi@redhat.com> References: <20210322144916.137245-1-mszeredi@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Use the miscattr API to let the VFS handle locking, permission checking and conversion. Signed-off-by: Miklos Szeredi Cc: Darrick J. Wong --- 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 #include +#include /* * 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; - 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? */ + 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)); + + 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)); 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? */ + 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); 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 #include @@ -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 = { From patchwork Mon Mar 22 14:49:09 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miklos Szeredi X-Patchwork-Id: 12155017 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B4A64C433ED for ; Mon, 22 Mar 2021 14:50:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8A8996192D for ; Mon, 22 Mar 2021 14:50:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231398AbhCVOuJ (ORCPT ); Mon, 22 Mar 2021 10:50:09 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:32993 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231202AbhCVOtf (ORCPT ); Mon, 22 Mar 2021 10:49:35 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1616424575; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=fZ1kizA+LiFidVAaGzgHTkHThFh4LhWmsbGPiZbctac=; b=DmDXfaVxLyg/VDrDgTNZTuqDGIwn15MV6eqFd/4QMtARrUpwzau4jyW9ADPcbd4wQVQ/dz oFN/RJA4C2mZGhOw0UHArCkHCt3PWgsR1ceQ3lYucf+WPPu97SIuteiUPs0BEAPbVg3OMD jGwNNvBNBnUnRm3NssrwOE2YlPDrb2A= Received: from mail-ed1-f70.google.com (mail-ed1-f70.google.com [209.85.208.70]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-251-Jm3LaqjNMQCTdOsuXpyBFQ-1; Mon, 22 Mar 2021 10:49:33 -0400 X-MC-Unique: Jm3LaqjNMQCTdOsuXpyBFQ-1 Received: by mail-ed1-f70.google.com with SMTP id n20so27700844edr.8 for ; Mon, 22 Mar 2021 07:49:33 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=fZ1kizA+LiFidVAaGzgHTkHThFh4LhWmsbGPiZbctac=; b=jnmFuAZihQLCUjGKz+WoiVldwcytH8U4N42Mgd7pDVJT3GQKf2IVNomGoX+gir+/an YrPvNZWCexnB6XAKcQ88RmvWJSJfc0ECtf6r5SezFa8nHhLmqtpsddk8Sgg+gMPkR427 n8JFue1FSpHVzDXuYaOCqbEwxl3G9qsGewwzkif6OZcMk23v4N4JqmXO7mM680ApfDK2 2KCMJHyUi2udvHFRhqMZjGiUvsbHn29Snsc7sBGDl9APfeq8wI2XO870hdIX9EveGxb4 E3+GobdB9lzInph/x9LXmF3expJXZE8EizOxWCQZRhaKLCtjvLfvzFSBTrKobV0jLfjW UZcw== X-Gm-Message-State: AOAM530eq7jo79YE0w03E/3OgCAaHSPyliho9Tg8Sc95HqGxa7fHY7Oq bF2H9XvjxoeNZ4aTauhYgYGey8YRvYOBZCORhVliugIz9z+uFO0IL7YAEYtRJSh+Wmuqv+h3FrP 05aSarMPQpWyWEgmbyYGEzQEMb3lpypYQlD/HuHuJs0ojUuXR7lBfMioPgquspYyDRQDT/x0Zs3 FVbg== X-Received: by 2002:a17:907:766f:: with SMTP id kk15mr162113ejc.24.1616424571880; Mon, 22 Mar 2021 07:49:31 -0700 (PDT) X-Google-Smtp-Source: ABdhPJySxMs+2+TlVeih//2S1IHzOOCWeOijLxHeyriI4OXE0His8umI3R99StaabYK9VG9Oy1yaiw== X-Received: by 2002:a17:907:766f:: with SMTP id kk15mr162099ejc.24.1616424571664; Mon, 22 Mar 2021 07:49:31 -0700 (PDT) Received: from miu.piliscsaba.redhat.com (catv-86-101-169-67.catv.broadband.hu. [86.101.169.67]) by smtp.gmail.com with ESMTPSA id r4sm9793117ejd.125.2021.03.22.07.49.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Mar 2021 07:49:31 -0700 (PDT) From: Miklos Szeredi To: linux-fsdevel@vger.kernel.org Cc: Al Viro , linux-kernel@vger.kernel.org, Christoph Hellwig , Matthew Garrett Subject: [PATCH v2 11/18] efivars: convert to miscattr Date: Mon, 22 Mar 2021 15:49:09 +0100 Message-Id: <20210322144916.137245-12-mszeredi@redhat.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210322144916.137245-1-mszeredi@redhat.com> References: <20210322144916.137245-1-mszeredi@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Use the miscattr API to let the VFS handle locking, permission checking and conversion. Signed-off-by: Miklos Szeredi Cc: Matthew Garrett --- fs/efivarfs/file.c | 77 --------------------------------------------- fs/efivarfs/inode.c | 44 ++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 77 deletions(-) diff --git a/fs/efivarfs/file.c b/fs/efivarfs/file.c index e6bc0302643b..d57ee15874f9 100644 --- a/fs/efivarfs/file.c +++ b/fs/efivarfs/file.c @@ -106,86 +106,9 @@ static ssize_t efivarfs_file_read(struct file *file, char __user *userbuf, return size; } -static inline unsigned int efivarfs_getflags(struct inode *inode) -{ - unsigned int i_flags; - unsigned int flags = 0; - - i_flags = inode->i_flags; - if (i_flags & S_IMMUTABLE) - flags |= FS_IMMUTABLE_FL; - return flags; -} - -static int -efivarfs_ioc_getxflags(struct file *file, void __user *arg) -{ - struct inode *inode = file->f_mapping->host; - unsigned int flags = efivarfs_getflags(inode); - - if (copy_to_user(arg, &flags, sizeof(flags))) - return -EFAULT; - return 0; -} - -static int -efivarfs_ioc_setxflags(struct file *file, void __user *arg) -{ - struct inode *inode = file->f_mapping->host; - unsigned int flags; - unsigned int i_flags = 0; - unsigned int oldflags = efivarfs_getflags(inode); - int error; - - if (!inode_owner_or_capable(&init_user_ns, inode)) - return -EACCES; - - if (copy_from_user(&flags, arg, sizeof(flags))) - return -EFAULT; - - if (flags & ~FS_IMMUTABLE_FL) - return -EOPNOTSUPP; - - if (flags & FS_IMMUTABLE_FL) - i_flags |= S_IMMUTABLE; - - - error = mnt_want_write_file(file); - if (error) - return error; - - inode_lock(inode); - - error = vfs_ioc_setflags_prepare(inode, oldflags, flags); - if (error) - goto out; - - inode_set_flags(inode, i_flags, S_IMMUTABLE); -out: - inode_unlock(inode); - mnt_drop_write_file(file); - return error; -} - -static long -efivarfs_file_ioctl(struct file *file, unsigned int cmd, unsigned long p) -{ - void __user *arg = (void __user *)p; - - switch (cmd) { - case FS_IOC_GETFLAGS: - return efivarfs_ioc_getxflags(file, arg); - case FS_IOC_SETFLAGS: - return efivarfs_ioc_setxflags(file, arg); - } - - return -ENOTTY; -} - const struct file_operations efivarfs_file_operations = { .open = simple_open, .read = efivarfs_file_read, .write = efivarfs_file_write, .llseek = no_llseek, - .unlocked_ioctl = efivarfs_file_ioctl, }; diff --git a/fs/efivarfs/inode.c b/fs/efivarfs/inode.c index 14e2947975fd..3ff034d86544 100644 --- a/fs/efivarfs/inode.c +++ b/fs/efivarfs/inode.c @@ -10,9 +10,12 @@ #include #include #include +#include #include "internal.h" +static const struct inode_operations efivarfs_file_inode_operations; + struct inode *efivarfs_get_inode(struct super_block *sb, const struct inode *dir, int mode, dev_t dev, bool is_removable) @@ -26,6 +29,7 @@ struct inode *efivarfs_get_inode(struct super_block *sb, inode->i_flags = is_removable ? 0 : S_IMMUTABLE; switch (mode & S_IFMT) { case S_IFREG: + inode->i_op = &efivarfs_file_inode_operations; inode->i_fop = &efivarfs_file_operations; break; case S_IFDIR: @@ -138,3 +142,43 @@ const struct inode_operations efivarfs_dir_inode_operations = { .unlink = efivarfs_unlink, .create = efivarfs_create, }; + +static int +efivarfs_miscattr_get(struct dentry *dentry, struct miscattr *ma) +{ + unsigned int i_flags; + unsigned int flags = 0; + + i_flags = d_inode(dentry)->i_flags; + if (i_flags & S_IMMUTABLE) + flags |= FS_IMMUTABLE_FL; + + miscattr_fill_flags(ma, flags); + + return 0; +} + +static int +efivarfs_miscattr_set(struct user_namespace *mnt_userns, + struct dentry *dentry, struct miscattr *ma) +{ + unsigned int i_flags = 0; + + if (miscattr_has_xattr(ma)) + return -EOPNOTSUPP; + + if (ma->flags & ~FS_IMMUTABLE_FL) + return -EOPNOTSUPP; + + if (ma->flags & FS_IMMUTABLE_FL) + i_flags |= S_IMMUTABLE; + + inode_set_flags(d_inode(dentry), i_flags, S_IMMUTABLE); + + return 0; +} + +static const struct inode_operations efivarfs_file_inode_operations = { + .miscattr_get = efivarfs_miscattr_get, + .miscattr_set = efivarfs_miscattr_set, +}; From patchwork Mon Mar 22 14:49:10 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miklos Szeredi X-Patchwork-Id: 12155019 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 69A8FC433F4 for ; Mon, 22 Mar 2021 14:50:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 226D8619BD for ; Mon, 22 Mar 2021 14:50:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231408AbhCVOuM (ORCPT ); Mon, 22 Mar 2021 10:50:12 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:52796 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231214AbhCVOth (ORCPT ); Mon, 22 Mar 2021 10:49:37 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1616424576; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=9vCEwIUmGd3ShhFCYwPPz97LFr0egAhHKCVaObC8MuI=; b=KchxE+7pz4Opgk5y/zCRlTxx7WD5WzlZ/yW1Rw4ANerq4ooYocQKQkzWMGk5moHnIja6wU TFeFooicEV+Rr3jDL4eIURNibjaclQqCvrYTEXZ8ydxM1h59BrYHnds2+vUVAXpMUcHee5 VI9H1wLrRdCbKSY7EhaNXpjnU/f+Jnw= Received: from mail-ej1-f70.google.com (mail-ej1-f70.google.com [209.85.218.70]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-495-7LrcZvz3OYut41dtNiSJqg-1; Mon, 22 Mar 2021 10:49:35 -0400 X-MC-Unique: 7LrcZvz3OYut41dtNiSJqg-1 Received: by mail-ej1-f70.google.com with SMTP id d6so833565ejd.15 for ; Mon, 22 Mar 2021 07:49:34 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=9vCEwIUmGd3ShhFCYwPPz97LFr0egAhHKCVaObC8MuI=; b=lJrNoO5l2kobFF6zkF5hDbNu+RAXODyUXNZP0RAdjIHzXNhgKejPXskGKcSPF05Tj8 RiMoT/0xS/ApiugV+0asWYusDJ9lfK1/umJibtj8TkHAEPGq4YlzcvVtHqqwxMj4q09L ExUgHiQGFWKTolEZ7UjyaP2T4xxv6/d8P5XouN1oJrbUKTuxvNMW1nJo/gsR+Q4p2FsK NcOAfC40J6EXx8DepM2B0npZjW9PmyDopgG6Ltm2OX/4nSHr699r61Tshxu3ONShfXlZ b55HxdZzgjyOXD6COSFdzHzCZNMyrC+R2xibLmVZ7jds8WiADbxlpsjUIO5y9xteVx8y Ev7A== X-Gm-Message-State: AOAM531NvkYEr7KUuaonMWG5O6XdQV6JsvDAtsNBX5ycAwjU9itiYYOV P7OCtBPIk/t6OT9If+xQpa5wAZhvElEyGs1BZ1+vf9UoSbu4FFhdGLI1JI6i7CzVPpdtfTCzbpa HWFpBRkKrDf3lTqf0fL7xgky/QgC4Yc2+O+i65EoINiTKRNNp1QS/K3Wi3IpGtjbtxKkp7O+WHx Goag== X-Received: by 2002:a17:906:f56:: with SMTP id h22mr119901ejj.494.1616424573522; Mon, 22 Mar 2021 07:49:33 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwPSF3TWmWE6nxg36tU3lsp04zqlZXn4U4XSAFJfh2lE5KtMufLSvf0mLqTtsyxeppYd/93pA== X-Received: by 2002:a17:906:f56:: with SMTP id h22mr119877ejj.494.1616424573314; Mon, 22 Mar 2021 07:49:33 -0700 (PDT) Received: from miu.piliscsaba.redhat.com (catv-86-101-169-67.catv.broadband.hu. [86.101.169.67]) by smtp.gmail.com with ESMTPSA id r4sm9793117ejd.125.2021.03.22.07.49.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Mar 2021 07:49:32 -0700 (PDT) From: Miklos Szeredi To: linux-fsdevel@vger.kernel.org Cc: Al Viro , linux-kernel@vger.kernel.org, Christoph Hellwig Subject: [PATCH v2 12/18] hfsplus: convert to miscattr Date: Mon, 22 Mar 2021 15:49:10 +0100 Message-Id: <20210322144916.137245-13-mszeredi@redhat.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210322144916.137245-1-mszeredi@redhat.com> References: <20210322144916.137245-1-mszeredi@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Use the miscattr API to let the VFS handle locking, permission checking and conversion. Signed-off-by: Miklos Szeredi --- fs/hfsplus/dir.c | 2 + fs/hfsplus/hfsplus_fs.h | 14 ++----- fs/hfsplus/inode.c | 54 ++++++++++++++++++++++++++ fs/hfsplus/ioctl.c | 84 ----------------------------------------- 4 files changed, 59 insertions(+), 95 deletions(-) diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index 03e6c046faf4..34b446a8307e 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c @@ -569,6 +569,8 @@ const struct inode_operations hfsplus_dir_inode_operations = { .rename = hfsplus_rename, .getattr = hfsplus_getattr, .listxattr = hfsplus_listxattr, + .miscattr_get = hfsplus_miscattr_get, + .miscattr_set = hfsplus_miscattr_set, }; const struct file_operations hfsplus_dir_operations = { diff --git a/fs/hfsplus/hfsplus_fs.h b/fs/hfsplus/hfsplus_fs.h index 12b20479ed2b..75d397dcd123 100644 --- a/fs/hfsplus/hfsplus_fs.h +++ b/fs/hfsplus/hfsplus_fs.h @@ -344,17 +344,6 @@ static inline unsigned short hfsplus_min_io_size(struct super_block *sb) #define hfs_brec_goto hfsplus_brec_goto #define hfs_part_find hfsplus_part_find -/* - * definitions for ext2 flag ioctls (linux really needs a generic - * interface for this). - */ - -/* ext2 ioctls (EXT2_IOC_GETFLAGS and EXT2_IOC_SETFLAGS) to support - * chattr/lsattr */ -#define HFSPLUS_IOC_EXT2_GETFLAGS FS_IOC_GETFLAGS -#define HFSPLUS_IOC_EXT2_SETFLAGS FS_IOC_SETFLAGS - - /* * hfs+-specific ioctl for making the filesystem bootable */ @@ -493,6 +482,9 @@ int hfsplus_getattr(struct user_namespace *mnt_userns, const struct path *path, unsigned int query_flags); int hfsplus_file_fsync(struct file *file, loff_t start, loff_t end, int datasync); +int hfsplus_miscattr_get(struct dentry *dentry, struct miscattr *ma); +int hfsplus_miscattr_set(struct user_namespace *mnt_userns, + struct dentry *dentry, struct miscattr *ma); /* ioctl.c */ long hfsplus_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index 078c5c8a5156..808f2b8b5a8f 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c @@ -17,6 +17,7 @@ #include #include #include +#include #include "hfsplus_fs.h" #include "hfsplus_raw.h" @@ -353,6 +354,8 @@ static const struct inode_operations hfsplus_file_inode_operations = { .setattr = hfsplus_setattr, .getattr = hfsplus_getattr, .listxattr = hfsplus_listxattr, + .miscattr_get = hfsplus_miscattr_get, + .miscattr_set = hfsplus_miscattr_set, }; static const struct file_operations hfsplus_file_operations = { @@ -628,3 +631,54 @@ int hfsplus_cat_write_inode(struct inode *inode) hfs_find_exit(&fd); return 0; } + +int hfsplus_miscattr_get(struct dentry *dentry, struct miscattr *ma) +{ + struct inode *inode = d_inode(dentry); + struct hfsplus_inode_info *hip = HFSPLUS_I(inode); + unsigned int flags = 0; + + if (inode->i_flags & S_IMMUTABLE) + flags |= FS_IMMUTABLE_FL; + if (inode->i_flags & S_APPEND) + flags |= FS_APPEND_FL; + if (hip->userflags & HFSPLUS_FLG_NODUMP) + flags |= FS_NODUMP_FL; + + miscattr_fill_flags(ma, flags); + + return 0; +} + +int hfsplus_miscattr_set(struct user_namespace *mnt_userns, + struct dentry *dentry, struct miscattr *ma) +{ + struct inode *inode = d_inode(dentry); + struct hfsplus_inode_info *hip = HFSPLUS_I(inode); + unsigned int new_fl = 0; + + if (miscattr_has_xattr(ma)) + return -EOPNOTSUPP; + + /* don't silently ignore unsupported ext2 flags */ + if (ma->flags & ~(FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NODUMP_FL)) + return -EOPNOTSUPP; + + if (ma->flags & FS_IMMUTABLE_FL) + new_fl |= S_IMMUTABLE; + + if (ma->flags & FS_APPEND_FL) + new_fl |= S_APPEND; + + inode_set_flags(inode, new_fl, S_IMMUTABLE | S_APPEND); + + if (ma->flags & FS_NODUMP_FL) + hip->userflags |= HFSPLUS_FLG_NODUMP; + else + hip->userflags &= ~HFSPLUS_FLG_NODUMP; + + inode->i_ctime = current_time(inode); + mark_inode_dirty(inode); + + return 0; +} diff --git a/fs/hfsplus/ioctl.c b/fs/hfsplus/ioctl.c index 3edb1926d127..5661a2e24d03 100644 --- a/fs/hfsplus/ioctl.c +++ b/fs/hfsplus/ioctl.c @@ -57,95 +57,11 @@ static int hfsplus_ioctl_bless(struct file *file, int __user *user_flags) return 0; } -static inline unsigned int hfsplus_getflags(struct inode *inode) -{ - struct hfsplus_inode_info *hip = HFSPLUS_I(inode); - unsigned int flags = 0; - - if (inode->i_flags & S_IMMUTABLE) - flags |= FS_IMMUTABLE_FL; - if (inode->i_flags & S_APPEND) - flags |= FS_APPEND_FL; - if (hip->userflags & HFSPLUS_FLG_NODUMP) - flags |= FS_NODUMP_FL; - return flags; -} - -static int hfsplus_ioctl_getflags(struct file *file, int __user *user_flags) -{ - struct inode *inode = file_inode(file); - unsigned int flags = hfsplus_getflags(inode); - - return put_user(flags, user_flags); -} - -static int hfsplus_ioctl_setflags(struct file *file, int __user *user_flags) -{ - struct inode *inode = file_inode(file); - struct hfsplus_inode_info *hip = HFSPLUS_I(inode); - unsigned int flags, new_fl = 0; - unsigned int oldflags = hfsplus_getflags(inode); - int err = 0; - - err = mnt_want_write_file(file); - if (err) - goto out; - - if (!inode_owner_or_capable(&init_user_ns, inode)) { - err = -EACCES; - goto out_drop_write; - } - - if (get_user(flags, user_flags)) { - err = -EFAULT; - goto out_drop_write; - } - - inode_lock(inode); - - err = vfs_ioc_setflags_prepare(inode, oldflags, flags); - if (err) - goto out_unlock_inode; - - /* don't silently ignore unsupported ext2 flags */ - if (flags & ~(FS_IMMUTABLE_FL|FS_APPEND_FL|FS_NODUMP_FL)) { - err = -EOPNOTSUPP; - goto out_unlock_inode; - } - - if (flags & FS_IMMUTABLE_FL) - new_fl |= S_IMMUTABLE; - - if (flags & FS_APPEND_FL) - new_fl |= S_APPEND; - - inode_set_flags(inode, new_fl, S_IMMUTABLE | S_APPEND); - - if (flags & FS_NODUMP_FL) - hip->userflags |= HFSPLUS_FLG_NODUMP; - else - hip->userflags &= ~HFSPLUS_FLG_NODUMP; - - inode->i_ctime = current_time(inode); - mark_inode_dirty(inode); - -out_unlock_inode: - inode_unlock(inode); -out_drop_write: - mnt_drop_write_file(file); -out: - return err; -} - long hfsplus_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { void __user *argp = (void __user *)arg; switch (cmd) { - case HFSPLUS_IOC_EXT2_GETFLAGS: - return hfsplus_ioctl_getflags(file, argp); - case HFSPLUS_IOC_EXT2_SETFLAGS: - return hfsplus_ioctl_setflags(file, argp); case HFSPLUS_IOC_BLESS: return hfsplus_ioctl_bless(file, argp); default: From patchwork Mon Mar 22 14:49:11 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miklos Szeredi X-Patchwork-Id: 12155021 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 865FAC433F8 for ; Mon, 22 Mar 2021 14:50:28 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3DA536192D for ; Mon, 22 Mar 2021 14:50:28 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229746AbhCVOuO (ORCPT ); Mon, 22 Mar 2021 10:50:14 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:29452 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231220AbhCVOti (ORCPT ); Mon, 22 Mar 2021 10:49:38 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1616424577; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=bCOf3n4s8BDA0zcLoGv9fPeTWUpDxjyRHJ+1bBL4q8A=; b=GaEyKRxQVYw99FbofABf232fEPNws14C5ofu/C2od15hQazQjLZ177ml6iSAi/6tVGtlAF nVmras3KDXqCFkVG0XvBxxSOOI3uv0zt8cHM9fpFEo4S/2RFWeGxit4Gwo/DOyci9ZnzYR 0FQbm7T67GuLgtuGK7MyQ5kfS8bWdEY= Received: from mail-ed1-f70.google.com (mail-ed1-f70.google.com [209.85.208.70]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-65--oJ78CgMOvKuiCMxNA8Z6Q-1; Mon, 22 Mar 2021 10:49:36 -0400 X-MC-Unique: -oJ78CgMOvKuiCMxNA8Z6Q-1 Received: by mail-ed1-f70.google.com with SMTP id f9so23206505edd.13 for ; Mon, 22 Mar 2021 07:49:35 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=bCOf3n4s8BDA0zcLoGv9fPeTWUpDxjyRHJ+1bBL4q8A=; b=VGd7k5xB51ASEMjTI0/G4NgzhZUrDAbB7fnXpPXhDznT17jNkvhvtDcCMWQ9VfjWgA T/VwOVMYk07m9oJwzZMI4uFN9RiVe5gGd7eizy5sl5WhUeJaHAHdypkek4HoVVwbftSQ 3xOA5I5Y21fGzQpRY/9cWmyULaFDH6dHD8S57qdCC6B9PYiVWGg8pj40rcKc7OAUhikZ FpzGdrShpa+e3TcSKSe5G6u3kyIbelFW5PZSN/dyg3VRhrhUcQReTI4wD5rz+uftdtey Z/Ep/c6mHlCvNyO2ZkYd6IlgM8KTpkeJi/PPRb8YJATf4Jbhy0RdhxBu35KCjFPwE028 7GYA== X-Gm-Message-State: AOAM530UVuwlh7E3AHkLvyjQAhsixzc5lYlf5h5a+vbFAaS5RkfaF35+ vcTRsXUDzKKdxQYp8hnNixJeHwjwnkxBvMIse+ZdlfcMky9o0GwybHiRth+/94c/O1zUPZRyyny SPWmPfqTDT3aYdk/GZ9R+u/9MiN2K00qjB0jSpZ9ZheuQCatHfuzr2VSFes+PkcxtNG/xfjJyV6 GnSg== X-Received: by 2002:a17:907:2062:: with SMTP id qp2mr75750ejb.397.1616424574571; Mon, 22 Mar 2021 07:49:34 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyctFHrbZT7eZX0HCMdd/UUt9AC49kif7LyWYv3I9vyyzoibXOKO/5pAV00exX/LAdLY7kVpA== X-Received: by 2002:a17:907:2062:: with SMTP id qp2mr75726ejb.397.1616424574396; Mon, 22 Mar 2021 07:49:34 -0700 (PDT) Received: from miu.piliscsaba.redhat.com (catv-86-101-169-67.catv.broadband.hu. [86.101.169.67]) by smtp.gmail.com with ESMTPSA id r4sm9793117ejd.125.2021.03.22.07.49.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Mar 2021 07:49:33 -0700 (PDT) From: Miklos Szeredi To: linux-fsdevel@vger.kernel.org Cc: Al Viro , linux-kernel@vger.kernel.org, Christoph Hellwig , Dave Kleikamp Subject: [PATCH v2 13/18] jfs: convert to miscattr Date: Mon, 22 Mar 2021 15:49:11 +0100 Message-Id: <20210322144916.137245-14-mszeredi@redhat.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210322144916.137245-1-mszeredi@redhat.com> References: <20210322144916.137245-1-mszeredi@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Use the miscattr API to let the VFS handle locking, permission checking and conversion. Signed-off-by: Miklos Szeredi Cc: Dave Kleikamp --- fs/jfs/file.c | 6 +-- fs/jfs/ioctl.c | 105 ++++++++++++++------------------------------ fs/jfs/jfs_dinode.h | 7 --- fs/jfs/jfs_inode.h | 4 +- fs/jfs/namei.c | 6 +-- 5 files changed, 43 insertions(+), 85 deletions(-) diff --git a/fs/jfs/file.c b/fs/jfs/file.c index 28b70e7c7dd4..05ecbb1d2193 100644 --- a/fs/jfs/file.c +++ b/fs/jfs/file.c @@ -130,6 +130,8 @@ int jfs_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, const struct inode_operations jfs_file_inode_operations = { .listxattr = jfs_listxattr, .setattr = jfs_setattr, + .miscattr_get = jfs_miscattr_get, + .miscattr_set = jfs_miscattr_set, #ifdef CONFIG_JFS_POSIX_ACL .get_acl = jfs_get_acl, .set_acl = jfs_set_acl, @@ -147,7 +149,5 @@ const struct file_operations jfs_file_operations = { .fsync = jfs_fsync, .release = jfs_release, .unlocked_ioctl = jfs_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = jfs_compat_ioctl, -#endif + .compat_ioctl = compat_ptr_ioctl, }; diff --git a/fs/jfs/ioctl.c b/fs/jfs/ioctl.c index 2581d4db58ff..55de6203d6d9 100644 --- a/fs/jfs/ioctl.c +++ b/fs/jfs/ioctl.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "jfs_filsys.h" #include "jfs_debug.h" @@ -56,69 +57,50 @@ static long jfs_map_ext2(unsigned long flags, int from) return mapped; } +int jfs_miscattr_get(struct dentry *dentry, struct miscattr *ma) +{ + struct jfs_inode_info *jfs_inode = JFS_IP(d_inode(dentry)); + unsigned int flags = jfs_inode->mode2 & JFS_FL_USER_VISIBLE; -long jfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) + miscattr_fill_flags(ma, jfs_map_ext2(flags, 0)); + + return 0; +} + +int jfs_miscattr_set(struct user_namespace *mnt_userns, + struct dentry *dentry, struct miscattr *ma) { - struct inode *inode = file_inode(filp); + struct inode *inode = d_inode(dentry); struct jfs_inode_info *jfs_inode = JFS_IP(inode); unsigned int flags; - switch (cmd) { - case JFS_IOC_GETFLAGS: - flags = jfs_inode->mode2 & JFS_FL_USER_VISIBLE; - flags = jfs_map_ext2(flags, 0); - return put_user(flags, (int __user *) arg); - case JFS_IOC_SETFLAGS: { - unsigned int oldflags; - int err; - - err = mnt_want_write_file(filp); - if (err) - return err; - - if (!inode_owner_or_capable(&init_user_ns, inode)) { - err = -EACCES; - goto setflags_out; - } - if (get_user(flags, (int __user *) arg)) { - err = -EFAULT; - goto setflags_out; - } + if (miscattr_has_xattr(ma)) + return -EOPNOTSUPP; - flags = jfs_map_ext2(flags, 1); - if (!S_ISDIR(inode->i_mode)) - flags &= ~JFS_DIRSYNC_FL; + flags = jfs_map_ext2(ma->flags, 1); + if (!S_ISDIR(inode->i_mode)) + flags &= ~JFS_DIRSYNC_FL; - /* Is it quota file? Do not allow user to mess with it */ - if (IS_NOQUOTA(inode)) { - err = -EPERM; - goto setflags_out; - } + /* Is it quota file? Do not allow user to mess with it */ + if (IS_NOQUOTA(inode)) + return -EPERM; - /* Lock against other parallel changes of flags */ - inode_lock(inode); + flags = flags & JFS_FL_USER_MODIFIABLE; + flags |= jfs_inode->mode2 & ~JFS_FL_USER_MODIFIABLE; + jfs_inode->mode2 = flags; - oldflags = jfs_map_ext2(jfs_inode->mode2 & JFS_FL_USER_VISIBLE, - 0); - err = vfs_ioc_setflags_prepare(inode, oldflags, flags); - if (err) { - inode_unlock(inode); - goto setflags_out; - } + jfs_set_inode_flags(inode); + inode->i_ctime = current_time(inode); + mark_inode_dirty(inode); - flags = flags & JFS_FL_USER_MODIFIABLE; - flags |= jfs_inode->mode2 & ~JFS_FL_USER_MODIFIABLE; - jfs_inode->mode2 = flags; - - jfs_set_inode_flags(inode); - inode_unlock(inode); - inode->i_ctime = current_time(inode); - mark_inode_dirty(inode); -setflags_out: - mnt_drop_write_file(filp); - return err; - } + return 0; +} + +long jfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + struct inode *inode = file_inode(filp); + switch (cmd) { case FITRIM: { struct super_block *sb = inode->i_sb; @@ -156,22 +138,3 @@ long jfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) return -ENOTTY; } } - -#ifdef CONFIG_COMPAT -long jfs_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - /* While these ioctl numbers defined with 'long' and have different - * numbers than the 64bit ABI, - * the actual implementation only deals with ints and is compatible. - */ - switch (cmd) { - case JFS_IOC_GETFLAGS32: - cmd = JFS_IOC_GETFLAGS; - break; - case JFS_IOC_SETFLAGS32: - cmd = JFS_IOC_SETFLAGS; - break; - } - return jfs_ioctl(filp, cmd, arg); -} -#endif diff --git a/fs/jfs/jfs_dinode.h b/fs/jfs/jfs_dinode.h index 5fa9fd594115..d6af79e94263 100644 --- a/fs/jfs/jfs_dinode.h +++ b/fs/jfs/jfs_dinode.h @@ -160,11 +160,4 @@ struct dinode { #define JFS_FL_USER_MODIFIABLE 0x03F80000 #define JFS_FL_INHERIT 0x03C80000 -/* These are identical to EXT[23]_IOC_GETFLAGS/SETFLAGS */ -#define JFS_IOC_GETFLAGS _IOR('f', 1, long) -#define JFS_IOC_SETFLAGS _IOW('f', 2, long) - -#define JFS_IOC_GETFLAGS32 _IOR('f', 1, int) -#define JFS_IOC_SETFLAGS32 _IOW('f', 2, int) - #endif /*_H_JFS_DINODE */ diff --git a/fs/jfs/jfs_inode.h b/fs/jfs/jfs_inode.h index 01daa0cb0ae5..9b0872141a08 100644 --- a/fs/jfs/jfs_inode.h +++ b/fs/jfs/jfs_inode.h @@ -9,8 +9,10 @@ struct fid; extern struct inode *ialloc(struct inode *, umode_t); extern int jfs_fsync(struct file *, loff_t, loff_t, int); +extern int jfs_miscattr_get(struct dentry *dentry, struct miscattr *ma); +extern int jfs_miscattr_set(struct user_namespace *mnt_userns, + struct dentry *dentry, struct miscattr *ma); extern long jfs_ioctl(struct file *, unsigned int, unsigned long); -extern long jfs_compat_ioctl(struct file *, unsigned int, unsigned long); extern struct inode *jfs_iget(struct super_block *, unsigned long); extern int jfs_commit_inode(struct inode *, int); extern int jfs_write_inode(struct inode *, struct writeback_control *); diff --git a/fs/jfs/namei.c b/fs/jfs/namei.c index 9abed0d750e5..7cfb19b5a1cc 100644 --- a/fs/jfs/namei.c +++ b/fs/jfs/namei.c @@ -1522,6 +1522,8 @@ const struct inode_operations jfs_dir_inode_operations = { .rename = jfs_rename, .listxattr = jfs_listxattr, .setattr = jfs_setattr, + .miscattr_get = jfs_miscattr_get, + .miscattr_set = jfs_miscattr_set, #ifdef CONFIG_JFS_POSIX_ACL .get_acl = jfs_get_acl, .set_acl = jfs_set_acl, @@ -1533,9 +1535,7 @@ const struct file_operations jfs_dir_operations = { .iterate = jfs_readdir, .fsync = jfs_fsync, .unlocked_ioctl = jfs_ioctl, -#ifdef CONFIG_COMPAT - .compat_ioctl = jfs_compat_ioctl, -#endif + .compat_ioctl = compat_ptr_ioctl, .llseek = generic_file_llseek, }; From patchwork Mon Mar 22 14:49:12 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miklos Szeredi X-Patchwork-Id: 12155027 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0C711C433DB for ; Mon, 22 Mar 2021 14:50:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B5D1E6192D for ; Mon, 22 Mar 2021 14:50:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231414AbhCVOuU (ORCPT ); Mon, 22 Mar 2021 10:50:20 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:49994 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231233AbhCVOtj (ORCPT ); Mon, 22 Mar 2021 10:49:39 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1616424578; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=gR1g+wrmq8CNGMHC9HF+FPFW3/Mbla9HvLt7skHdCM8=; b=DI1amX7CsIOHlo/uCx0aTR2XKK882d9bw7/n6jrPgQcPrAAYb9JEImj3SuA/fzKorA7xql 7yXgLsR3paaNLmyHB+GEjf8AagjzpRSchbcNIxTBPYT1nLdlcw3UclMzxgkWthWJIbmBU+ SMsf3redvyy2zIRObWcMKdTsB16SG6o= Received: from mail-ed1-f71.google.com (mail-ed1-f71.google.com [209.85.208.71]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-179-x9FNFIeFOH2yCrj8jb-lxQ-1; Mon, 22 Mar 2021 10:49:37 -0400 X-MC-Unique: x9FNFIeFOH2yCrj8jb-lxQ-1 Received: by mail-ed1-f71.google.com with SMTP id o15so27615028edv.7 for ; Mon, 22 Mar 2021 07:49:36 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=gR1g+wrmq8CNGMHC9HF+FPFW3/Mbla9HvLt7skHdCM8=; b=uhRFf9A7cf1i7ySqXaFRrdu1tuDXbPN8Ufh6KQRBvolwJhhJTeJIdZEdobw87gyFzi 86xWIxMzMcNf9D2mVRfCq6N4u1EiEUwCb4cb3Lwh+0nXNb0Btwuv72sM/hssO3ZN+vKu Pas3XZpy2Z/mHDB1fbGvYPldHPMB1nPUGSiBC3pJAeBqjnVgM0aPbMtJLe+CtKs1ynpd IR4lG+67tx83H/FcTxPOyp8Cx9pQSReo3YXp48A/Q/+sgxFkQTzkrvZNW/Tb6itwYTMC pup6dpAFTlhSLxIfd7ALfmWgkpY8tVmzmyBhh6Y+V08yCrOAbWAde5Fe9Ibyvp1SaRPU 1L+A== X-Gm-Message-State: AOAM533ncqjmKEDTKmuuZ6g1GrL0lqgBWqni4GF1RgA+nlS0c9ks5ah6 vLAb7r6V0cbRzfQ+LiymaPCD/KlDWmd3xRCG6u7Cf1NgSTQamLZSmisMg0lkQkWkCg/Z2J2kg3b PQTO93Qy/ApBMRQ6vFKXp30zvbt05qRcc+rNSn92GY9OdzNRp66JJXVU0cU7BM+CmTDojRulMwm a82g== X-Received: by 2002:a17:907:e88:: with SMTP id ho8mr99793ejc.199.1616424575577; Mon, 22 Mar 2021 07:49:35 -0700 (PDT) X-Google-Smtp-Source: ABdhPJztIBTmpouYG8EVNmhdgk36jXeOwcmhhqjfU++DaRsUQo8mOQ4U/Zmdf5dp8EDtGvu++grrMg== X-Received: by 2002:a17:907:e88:: with SMTP id ho8mr99776ejc.199.1616424575417; Mon, 22 Mar 2021 07:49:35 -0700 (PDT) Received: from miu.piliscsaba.redhat.com (catv-86-101-169-67.catv.broadband.hu. [86.101.169.67]) by smtp.gmail.com with ESMTPSA id r4sm9793117ejd.125.2021.03.22.07.49.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Mar 2021 07:49:34 -0700 (PDT) From: Miklos Szeredi To: linux-fsdevel@vger.kernel.org Cc: Al Viro , linux-kernel@vger.kernel.org, Christoph Hellwig , Ryusuke Konishi Subject: [PATCH v2 14/18] nilfs2: convert to miscattr Date: Mon, 22 Mar 2021 15:49:12 +0100 Message-Id: <20210322144916.137245-15-mszeredi@redhat.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210322144916.137245-1-mszeredi@redhat.com> References: <20210322144916.137245-1-mszeredi@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Use the miscattr API to let the VFS handle locking, permission checking and conversion. Signed-off-by: Miklos Szeredi Cc: Ryusuke Konishi --- fs/nilfs2/file.c | 2 ++ fs/nilfs2/ioctl.c | 61 ++++++++++++++--------------------------------- fs/nilfs2/namei.c | 2 ++ fs/nilfs2/nilfs.h | 3 +++ 4 files changed, 25 insertions(+), 43 deletions(-) diff --git a/fs/nilfs2/file.c b/fs/nilfs2/file.c index e1bd592ce700..e2716ce4b95e 100644 --- a/fs/nilfs2/file.c +++ b/fs/nilfs2/file.c @@ -148,6 +148,8 @@ const struct inode_operations nilfs_file_inode_operations = { .setattr = nilfs_setattr, .permission = nilfs_permission, .fiemap = nilfs_fiemap, + .miscattr_get = nilfs_miscattr_get, + .miscattr_set = nilfs_miscattr_set, }; /* end of file */ diff --git a/fs/nilfs2/ioctl.c b/fs/nilfs2/ioctl.c index b053b40315bf..4bb5f09b6efa 100644 --- a/fs/nilfs2/ioctl.c +++ b/fs/nilfs2/ioctl.c @@ -16,6 +16,7 @@ #include /* compat_ptr() */ #include /* mnt_want_write_file(), mnt_drop_write_file() */ #include +#include #include "nilfs.h" #include "segment.h" #include "bmap.h" @@ -113,51 +114,39 @@ static int nilfs_ioctl_wrap_copy(struct the_nilfs *nilfs, } /** - * nilfs_ioctl_getflags - ioctl to support lsattr + * nilfs_miscattr_get - ioctl to support lsattr */ -static int nilfs_ioctl_getflags(struct inode *inode, void __user *argp) +int nilfs_miscattr_get(struct dentry *dentry, struct miscattr *ma) { - unsigned int flags = NILFS_I(inode)->i_flags & FS_FL_USER_VISIBLE; + struct inode *inode = d_inode(dentry); - return put_user(flags, (int __user *)argp); + miscattr_fill_flags(ma, NILFS_I(inode)->i_flags & FS_FL_USER_VISIBLE); + + return 0; } /** - * nilfs_ioctl_setflags - ioctl to support chattr + * nilfs_miscattr_set - ioctl to support chattr */ -static int nilfs_ioctl_setflags(struct inode *inode, struct file *filp, - void __user *argp) +int nilfs_miscattr_set(struct user_namespace *mnt_userns, + struct dentry *dentry, struct miscattr *ma) { + struct inode *inode = d_inode(dentry); struct nilfs_transaction_info ti; unsigned int flags, oldflags; int ret; - if (!inode_owner_or_capable(&init_user_ns, inode)) - return -EACCES; - - if (get_user(flags, (int __user *)argp)) - return -EFAULT; - - ret = mnt_want_write_file(filp); - if (ret) - return ret; - - flags = nilfs_mask_flags(inode->i_mode, flags); - - inode_lock(inode); - - oldflags = NILFS_I(inode)->i_flags; + if (miscattr_has_xattr(ma)) + return -EOPNOTSUPP; - ret = vfs_ioc_setflags_prepare(inode, oldflags, flags); - if (ret) - goto out; + flags = nilfs_mask_flags(inode->i_mode, ma->flags); ret = nilfs_transaction_begin(inode->i_sb, &ti, 0); if (ret) - goto out; + return ret; - NILFS_I(inode)->i_flags = (oldflags & ~FS_FL_USER_MODIFIABLE) | - (flags & FS_FL_USER_MODIFIABLE); + oldflags = NILFS_I(inode)->i_flags & ~FS_FL_USER_MODIFIABLE; + NILFS_I(inode)->i_flags = oldflags | (flags & FS_FL_USER_MODIFIABLE); nilfs_set_inode_flags(inode); inode->i_ctime = current_time(inode); @@ -165,11 +154,7 @@ static int nilfs_ioctl_setflags(struct inode *inode, struct file *filp, nilfs_set_transaction_flag(NILFS_TI_SYNC); nilfs_mark_inode_dirty(inode); - ret = nilfs_transaction_commit(inode->i_sb); -out: - inode_unlock(inode); - mnt_drop_write_file(filp); - return ret; + return nilfs_transaction_commit(inode->i_sb); } /** @@ -1282,10 +1267,6 @@ long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) void __user *argp = (void __user *)arg; switch (cmd) { - case FS_IOC_GETFLAGS: - return nilfs_ioctl_getflags(inode, argp); - case FS_IOC_SETFLAGS: - return nilfs_ioctl_setflags(inode, filp, argp); case FS_IOC_GETVERSION: return nilfs_ioctl_getversion(inode, argp); case NILFS_IOCTL_CHANGE_CPMODE: @@ -1331,12 +1312,6 @@ long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) long nilfs_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { switch (cmd) { - case FS_IOC32_GETFLAGS: - cmd = FS_IOC_GETFLAGS; - break; - case FS_IOC32_SETFLAGS: - cmd = FS_IOC_SETFLAGS; - break; case FS_IOC32_GETVERSION: cmd = FS_IOC_GETVERSION; break; diff --git a/fs/nilfs2/namei.c b/fs/nilfs2/namei.c index ecace5f96a95..5ed4b824a8fa 100644 --- a/fs/nilfs2/namei.c +++ b/fs/nilfs2/namei.c @@ -552,6 +552,8 @@ const struct inode_operations nilfs_dir_inode_operations = { .setattr = nilfs_setattr, .permission = nilfs_permission, .fiemap = nilfs_fiemap, + .miscattr_get = nilfs_miscattr_get, + .miscattr_set = nilfs_miscattr_set, }; const struct inode_operations nilfs_special_inode_operations = { diff --git a/fs/nilfs2/nilfs.h b/fs/nilfs2/nilfs.h index c4a45a081ade..03184ea11287 100644 --- a/fs/nilfs2/nilfs.h +++ b/fs/nilfs2/nilfs.h @@ -243,6 +243,9 @@ extern void nilfs_set_link(struct inode *, struct nilfs_dir_entry *, extern int nilfs_sync_file(struct file *, loff_t, loff_t, int); /* ioctl.c */ +int nilfs_miscattr_get(struct dentry *dentry, struct miscattr *m); +int nilfs_miscattr_set(struct user_namespace *mnt_userns, + struct dentry *dentry, struct miscattr *ma); long nilfs_ioctl(struct file *, unsigned int, unsigned long); long nilfs_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg); int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *, struct nilfs_argv *, From patchwork Mon Mar 22 14:49:13 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miklos Szeredi X-Patchwork-Id: 12155029 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 25E73C433E1 for ; Mon, 22 Mar 2021 14:50:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D5ED16197F for ; Mon, 22 Mar 2021 14:50:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229984AbhCVOuY (ORCPT ); Mon, 22 Mar 2021 10:50:24 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:36471 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231237AbhCVOtl (ORCPT ); Mon, 22 Mar 2021 10:49:41 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1616424579; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=69DYhwT5xB2HAhx/Tr5I8TuWYr5//KxtYgUgHfgI45Y=; b=I8Sv/u52g6Of6Fy6UYSPFxiVeCrrAGNyV21VFyniFV9TPIwro6KrYVOtYdyzCMWGZuVKDb UCCGxQ/NjjNBK64VC10vfDe1RvyQV/3XsKgbFHb9oirKxPCt09UP0j936fcvLEQUoBcYZ4 4RRLn08+1rTMBe4LLQVwgU5BDe4r3qI= Received: from mail-ej1-f72.google.com (mail-ej1-f72.google.com [209.85.218.72]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-197-Mkh0h7xrPjamYl7xz4upuA-1; Mon, 22 Mar 2021 10:49:38 -0400 X-MC-Unique: Mkh0h7xrPjamYl7xz4upuA-1 Received: by mail-ej1-f72.google.com with SMTP id t21so12005646ejf.14 for ; Mon, 22 Mar 2021 07:49:38 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=69DYhwT5xB2HAhx/Tr5I8TuWYr5//KxtYgUgHfgI45Y=; b=PD2wHxD4FSXomwaVFjXBMtVBcFQUb3Nj7+AEZYPKj1XQm4bgmnFkQHOhPjoWRAvtFd hQ2dJQWjByPaiklVZuaNav3IvxXw1HTZ+xLA8POR++1Ist2q9dHNmyIdUY1uy1LzuX66 JgrM7hBX1BedZ3d1qsuU5y4/WNk8X3g2pl+ThWD3ZcanhwdiCIWAHkPNDudSpg+SmpKw 3SchBgGm37QHVrfrLljaiWs32VRSIMzId0LviEMC8II/u2d+hhKu8DwVxny9s6X1bYsg ypGUmpiprf2JWr+QRjQfZKSeOQ8IY5A+lXoGptqVKXXMovLSDLi2//1CcEOZcyR1q25+ Z8Lw== X-Gm-Message-State: AOAM5302/R1ilqo76nyy5xMcVF7Vx6NhJY9nivj33paO4TEd5M/J2J1b Kzl3Vdd2rzXt9pM79xzcq/YZvEpSQ0PHbwr+2/Yg5FWQp3sY9Bqbg3cWM3+gNhj/n5MpKVybSRE 0CrTpS1IjbF1adP21u8BSttraOB9t5XfKHYDAUEdYmQvVl4DokjO1NfWByTkI01vzU4nQMby+3x W4vA== X-Received: by 2002:a17:906:a896:: with SMTP id ha22mr62704ejb.503.1616424576777; Mon, 22 Mar 2021 07:49:36 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxgxjDgf0jKR6n6QloHOiLhHT0Iw1VMJEHAtI03b7e6ceDKVUlWEgSWmP2nFfv9p3fyHPIWlA== X-Received: by 2002:a17:906:a896:: with SMTP id ha22mr62683ejb.503.1616424576527; Mon, 22 Mar 2021 07:49:36 -0700 (PDT) Received: from miu.piliscsaba.redhat.com (catv-86-101-169-67.catv.broadband.hu. [86.101.169.67]) by smtp.gmail.com with ESMTPSA id r4sm9793117ejd.125.2021.03.22.07.49.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Mar 2021 07:49:36 -0700 (PDT) From: Miklos Szeredi To: linux-fsdevel@vger.kernel.org Cc: Al Viro , linux-kernel@vger.kernel.org, Christoph Hellwig , Joel Becker Subject: [PATCH v2 15/18] ocfs2: convert to miscattr Date: Mon, 22 Mar 2021 15:49:13 +0100 Message-Id: <20210322144916.137245-16-mszeredi@redhat.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210322144916.137245-1-mszeredi@redhat.com> References: <20210322144916.137245-1-mszeredi@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Use the miscattr API to let the VFS handle locking, permission checking and conversion. Signed-off-by: Miklos Szeredi Cc: Joel Becker --- fs/ocfs2/file.c | 2 ++ fs/ocfs2/ioctl.c | 59 ++++++++++++++---------------------------- fs/ocfs2/ioctl.h | 3 +++ fs/ocfs2/namei.c | 3 +++ fs/ocfs2/ocfs2_ioctl.h | 8 ------ 5 files changed, 27 insertions(+), 48 deletions(-) diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 6611c64ca0be..fa92629ff285 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c @@ -2645,6 +2645,8 @@ const struct inode_operations ocfs2_file_iops = { .fiemap = ocfs2_fiemap, .get_acl = ocfs2_iop_get_acl, .set_acl = ocfs2_iop_set_acl, + .miscattr_get = ocfs2_miscattr_get, + .miscattr_set = ocfs2_miscattr_set, }; const struct inode_operations ocfs2_special_file_iops = { diff --git a/fs/ocfs2/ioctl.c b/fs/ocfs2/ioctl.c index 50c9b30ee9f6..34ea3cde01bb 100644 --- a/fs/ocfs2/ioctl.c +++ b/fs/ocfs2/ioctl.c @@ -10,6 +10,7 @@ #include #include #include +#include #include @@ -61,8 +62,10 @@ static inline int o2info_coherent(struct ocfs2_info_request *req) return (!(req->ir_flags & OCFS2_INFO_FL_NON_COHERENT)); } -static int ocfs2_get_inode_attr(struct inode *inode, unsigned *flags) +int ocfs2_miscattr_get(struct dentry *dentry, struct miscattr *ma) { + struct inode *inode = d_inode(dentry); + unsigned int flags; int status; status = ocfs2_inode_lock(inode, NULL, 0); @@ -71,15 +74,19 @@ static int ocfs2_get_inode_attr(struct inode *inode, unsigned *flags) return status; } ocfs2_get_inode_flags(OCFS2_I(inode)); - *flags = OCFS2_I(inode)->ip_attr; + flags = OCFS2_I(inode)->ip_attr; ocfs2_inode_unlock(inode, 0); + miscattr_fill_flags(ma, flags & OCFS2_FL_VISIBLE); + return status; } -static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags, - unsigned mask) +int ocfs2_miscattr_set(struct user_namespace *mnt_userns, + struct dentry *dentry, struct miscattr *ma) { + struct inode *inode = d_inode(dentry); + unsigned int flags = ma->flags; struct ocfs2_inode_info *ocfs2_inode = OCFS2_I(inode); struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); handle_t *handle = NULL; @@ -87,7 +94,8 @@ static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags, unsigned oldflags; int status; - inode_lock(inode); + if (miscattr_has_xattr(ma)) + return -EOPNOTSUPP; status = ocfs2_inode_lock(inode, &bh, 1); if (status < 0) { @@ -95,19 +103,17 @@ static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags, goto bail; } - status = -EACCES; - if (!inode_owner_or_capable(&init_user_ns, inode)) - goto bail_unlock; - if (!S_ISDIR(inode->i_mode)) flags &= ~OCFS2_DIRSYNC_FL; oldflags = ocfs2_inode->ip_attr; - flags = flags & mask; - flags |= oldflags & ~mask; + flags = flags & OCFS2_FL_MODIFIABLE; + flags |= oldflags & ~OCFS2_FL_MODIFIABLE; - status = vfs_ioc_setflags_prepare(inode, oldflags, flags); - if (status) + /* Check already done by VFS, but repeat with ocfs lock */ + status = -EPERM; + if ((flags ^ oldflags) & (FS_APPEND_FL | FS_IMMUTABLE_FL) && + !capable(CAP_LINUX_IMMUTABLE)) goto bail_unlock; handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS); @@ -129,8 +135,6 @@ static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags, bail_unlock: ocfs2_inode_unlock(inode, 1); bail: - inode_unlock(inode); - brelse(bh); return status; @@ -836,7 +840,6 @@ static int ocfs2_info_handle(struct inode *inode, struct ocfs2_info *info, long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct inode *inode = file_inode(filp); - unsigned int flags; int new_clusters; int status; struct ocfs2_space_resv sr; @@ -849,24 +852,6 @@ long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) void __user *argp = (void __user *)arg; switch (cmd) { - case OCFS2_IOC_GETFLAGS: - status = ocfs2_get_inode_attr(inode, &flags); - if (status < 0) - return status; - - flags &= OCFS2_FL_VISIBLE; - return put_user(flags, (int __user *) arg); - case OCFS2_IOC_SETFLAGS: - if (get_user(flags, (int __user *) arg)) - return -EFAULT; - - status = mnt_want_write_file(filp); - if (status) - return status; - status = ocfs2_set_inode_attr(inode, flags, - OCFS2_FL_MODIFIABLE); - mnt_drop_write_file(filp); - return status; case OCFS2_IOC_RESVSP: case OCFS2_IOC_RESVSP64: case OCFS2_IOC_UNRESVSP: @@ -959,12 +944,6 @@ long ocfs2_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg) void __user *argp = (void __user *)arg; switch (cmd) { - case OCFS2_IOC32_GETFLAGS: - cmd = OCFS2_IOC_GETFLAGS; - break; - case OCFS2_IOC32_SETFLAGS: - cmd = OCFS2_IOC_SETFLAGS; - break; case OCFS2_IOC_RESVSP: case OCFS2_IOC_RESVSP64: case OCFS2_IOC_UNRESVSP: diff --git a/fs/ocfs2/ioctl.h b/fs/ocfs2/ioctl.h index 9f5e4d95e37f..575e754b7d16 100644 --- a/fs/ocfs2/ioctl.h +++ b/fs/ocfs2/ioctl.h @@ -11,6 +11,9 @@ #ifndef OCFS2_IOCTL_PROTO_H #define OCFS2_IOCTL_PROTO_H +int ocfs2_miscattr_get(struct dentry *dentry, struct miscattr *ma); +int ocfs2_miscattr_set(struct user_namespace *mnt_userns, + struct dentry *dentry, struct miscattr *ma); long ocfs2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); long ocfs2_compat_ioctl(struct file *file, unsigned cmd, unsigned long arg); diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index 3abdd36da2e2..ec8c3b813532 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -50,6 +50,7 @@ #include "xattr.h" #include "acl.h" #include "ocfs2_trace.h" +#include "ioctl.h" #include "buffer_head_io.h" @@ -2918,4 +2919,6 @@ const struct inode_operations ocfs2_dir_iops = { .fiemap = ocfs2_fiemap, .get_acl = ocfs2_iop_get_acl, .set_acl = ocfs2_iop_set_acl, + .miscattr_get = ocfs2_miscattr_get, + .miscattr_set = ocfs2_miscattr_set, }; diff --git a/fs/ocfs2/ocfs2_ioctl.h b/fs/ocfs2/ocfs2_ioctl.h index d7b31734f6be..273616bd4f19 100644 --- a/fs/ocfs2/ocfs2_ioctl.h +++ b/fs/ocfs2/ocfs2_ioctl.h @@ -12,14 +12,6 @@ #ifndef OCFS2_IOCTL_H #define OCFS2_IOCTL_H -/* - * ioctl commands - */ -#define OCFS2_IOC_GETFLAGS FS_IOC_GETFLAGS -#define OCFS2_IOC_SETFLAGS FS_IOC_SETFLAGS -#define OCFS2_IOC32_GETFLAGS FS_IOC32_GETFLAGS -#define OCFS2_IOC32_SETFLAGS FS_IOC32_SETFLAGS - /* * Space reservation / allocation / free ioctls and argument structure * are designed to be compatible with XFS. From patchwork Mon Mar 22 14:49:14 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miklos Szeredi X-Patchwork-Id: 12155031 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 48F4EC433E0 for ; Mon, 22 Mar 2021 14:50:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 02C9A61992 for ; Mon, 22 Mar 2021 14:50:54 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229931AbhCVOuc (ORCPT ); Mon, 22 Mar 2021 10:50:32 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:46226 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231241AbhCVOtm (ORCPT ); Mon, 22 Mar 2021 10:49:42 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1616424581; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=l6EzCQAw/mBMnPIz8KDSZFIEDfo7AHQRBn5q68A5xxs=; b=RCU7fkWGz6CYDEhGxCX2VZhOyjwB24xjuc1liZ6iUBLCk61/n+yPjpWtSulfkQuqt4xs1L xK7pXptT18RHrVten4wbiRB19oIcQ1VznnNF8O5BSuhMlxp0L444vB+LKNEGQoi7G+JuiC u+0G+is2xwKzk1FcwxXx0DX0cJaeIR8= Received: from mail-ej1-f72.google.com (mail-ej1-f72.google.com [209.85.218.72]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-463-WyyXchQDO6Sro8e9SnbyHg-1; Mon, 22 Mar 2021 10:49:39 -0400 X-MC-Unique: WyyXchQDO6Sro8e9SnbyHg-1 Received: by mail-ej1-f72.google.com with SMTP id au15so20099198ejc.8 for ; Mon, 22 Mar 2021 07:49:39 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=l6EzCQAw/mBMnPIz8KDSZFIEDfo7AHQRBn5q68A5xxs=; b=Cbp0iXJWv5D2nHYJjG+NE+4TV/jgxbtw+Pu/Kp/BtnP8fm9qBqvEDXVw0sG0p2OSIz Z1uEO1F+IJlyhRVfX5J8MCp5l0zOP2JjnZ8LMlyip0cp0QFPz4Ea8A/uGhqIqtr5+qyb Mtnw4b+cvVitG7ZkFR24VuP4DyZ7ZT4AoF3G5oITecPlgrtRkcNj9K0lxbdXkoKft/mv G9jHWI+2aD940nvAumPcQcFq1+1ZJCD7bLMevBPoYixsg6W6IcqMZfog5lmsT3KWb547 2L22Oxnler8/97Bqmc9hUJ6WwOghG7MMwA5uiRAKEhaI+SCwUclApkRQ7W9mMo3hr7nI aIQQ== X-Gm-Message-State: AOAM532uZ5JzNHSakvXcM1bHdvENx08CZtnChEmumde1ERAXAgOwWcl4 TLdLBgPc+5VwmHYP2L0P/fLneMQeLY80gaR6rQCpC+pS+f8W8QZ/hUnZe0nyjxD/7itJksEVmUj 4poOIH+YxtUhiS9DYZCL94jfR3mX9ZR+Oo4zDJhFhj6UNT5n2h0EpR7qTwaFdDXBjlf1EFmOASC 2cvg== X-Received: by 2002:a17:907:6289:: with SMTP id nd9mr129367ejc.384.1616424577825; Mon, 22 Mar 2021 07:49:37 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxmoL1xtRBZBvW72vdcqh8NIrWFegxo5+WgvxENXGto+uk06haidHAPFlhoeOzC0kwv6nsTWA== X-Received: by 2002:a17:907:6289:: with SMTP id nd9mr129339ejc.384.1616424577612; Mon, 22 Mar 2021 07:49:37 -0700 (PDT) Received: from miu.piliscsaba.redhat.com (catv-86-101-169-67.catv.broadband.hu. [86.101.169.67]) by smtp.gmail.com with ESMTPSA id r4sm9793117ejd.125.2021.03.22.07.49.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Mar 2021 07:49:37 -0700 (PDT) From: Miklos Szeredi To: linux-fsdevel@vger.kernel.org Cc: Al Viro , linux-kernel@vger.kernel.org, Christoph Hellwig , Jan Kara Subject: [PATCH v2 16/18] reiserfs: convert to miscattr Date: Mon, 22 Mar 2021 15:49:14 +0100 Message-Id: <20210322144916.137245-17-mszeredi@redhat.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210322144916.137245-1-mszeredi@redhat.com> References: <20210322144916.137245-1-mszeredi@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Use the miscattr API to let the VFS handle locking, permission checking and conversion. Signed-off-by: Miklos Szeredi Cc: Jan Kara --- fs/reiserfs/file.c | 2 + fs/reiserfs/ioctl.c | 121 +++++++++++++++++++---------------------- fs/reiserfs/namei.c | 2 + fs/reiserfs/reiserfs.h | 7 ++- fs/reiserfs/super.c | 2 +- 5 files changed, 64 insertions(+), 70 deletions(-) diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c index 1db0254bc38b..bf8f125b41ca 100644 --- a/fs/reiserfs/file.c +++ b/fs/reiserfs/file.c @@ -258,4 +258,6 @@ const struct inode_operations reiserfs_file_inode_operations = { .permission = reiserfs_permission, .get_acl = reiserfs_get_acl, .set_acl = reiserfs_set_acl, + .miscattr_get = reiserfs_miscattr_get, + .miscattr_set = reiserfs_miscattr_set, }; diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c index 4f1cbd930179..913c4dc016e5 100644 --- a/fs/reiserfs/ioctl.c +++ b/fs/reiserfs/ioctl.c @@ -10,6 +10,59 @@ #include #include #include +#include + +int reiserfs_miscattr_get(struct dentry *dentry, struct miscattr *ma) +{ + struct inode *inode = d_inode(dentry); + + if (!reiserfs_attrs(inode->i_sb)) + return -ENOTTY; + + miscattr_fill_flags(ma, REISERFS_I(inode)->i_attrs); + + return 0; +} + +int reiserfs_miscattr_set(struct user_namespace *mnt_userns, + struct dentry *dentry, struct miscattr *ma) +{ + struct inode *inode = d_inode(dentry); + unsigned int flags = ma->flags; + int err; + + reiserfs_write_lock(inode->i_sb); + + err = -ENOTTY; + if (!reiserfs_attrs(inode->i_sb)) + goto unlock; + + err = -EOPNOTSUPP; + if (miscattr_has_xattr(ma)) + goto unlock; + + /* + * Is it quota file? Do not allow user to mess with it + */ + err = -EPERM; + if (IS_NOQUOTA(inode)) + goto unlock; + + if ((flags & REISERFS_NOTAIL_FL) && S_ISREG(inode->i_mode)) { + err = reiserfs_unpack(inode); + if (err) + goto unlock; + } + sd_attrs_to_i_attrs(flags, inode); + REISERFS_I(inode)->i_attrs = flags; + inode->i_ctime = current_time(inode); + mark_inode_dirty(inode); + err = 0; +unlock: + reiserfs_write_unlock(inode->i_sb); + + return err; +} /* * reiserfs_ioctl - handler for ioctl for inode @@ -23,7 +76,6 @@ long reiserfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct inode *inode = file_inode(filp); - unsigned int flags; int err = 0; reiserfs_write_lock(inode->i_sb); @@ -32,7 +84,7 @@ long reiserfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) case REISERFS_IOC_UNPACK: if (S_ISREG(inode->i_mode)) { if (arg) - err = reiserfs_unpack(inode, filp); + err = reiserfs_unpack(inode); } else err = -ENOTTY; break; @@ -40,63 +92,6 @@ long reiserfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) * following two cases are taken from fs/ext2/ioctl.c by Remy * Card (card@masi.ibp.fr) */ - case REISERFS_IOC_GETFLAGS: - if (!reiserfs_attrs(inode->i_sb)) { - err = -ENOTTY; - break; - } - - flags = REISERFS_I(inode)->i_attrs; - err = put_user(flags, (int __user *)arg); - break; - case REISERFS_IOC_SETFLAGS:{ - if (!reiserfs_attrs(inode->i_sb)) { - err = -ENOTTY; - break; - } - - err = mnt_want_write_file(filp); - if (err) - break; - - if (!inode_owner_or_capable(&init_user_ns, inode)) { - err = -EPERM; - goto setflags_out; - } - if (get_user(flags, (int __user *)arg)) { - err = -EFAULT; - goto setflags_out; - } - /* - * Is it quota file? Do not allow user to mess with it - */ - if (IS_NOQUOTA(inode)) { - err = -EPERM; - goto setflags_out; - } - err = vfs_ioc_setflags_prepare(inode, - REISERFS_I(inode)->i_attrs, - flags); - if (err) - goto setflags_out; - if ((flags & REISERFS_NOTAIL_FL) && - S_ISREG(inode->i_mode)) { - int result; - - result = reiserfs_unpack(inode, filp); - if (result) { - err = result; - goto setflags_out; - } - } - sd_attrs_to_i_attrs(flags, inode); - REISERFS_I(inode)->i_attrs = flags; - inode->i_ctime = current_time(inode); - mark_inode_dirty(inode); -setflags_out: - mnt_drop_write_file(filp); - break; - } case REISERFS_IOC_GETVERSION: err = put_user(inode->i_generation, (int __user *)arg); break; @@ -138,12 +133,6 @@ long reiserfs_compat_ioctl(struct file *file, unsigned int cmd, case REISERFS_IOC32_UNPACK: cmd = REISERFS_IOC_UNPACK; break; - case REISERFS_IOC32_GETFLAGS: - cmd = REISERFS_IOC_GETFLAGS; - break; - case REISERFS_IOC32_SETFLAGS: - cmd = REISERFS_IOC_SETFLAGS; - break; case REISERFS_IOC32_GETVERSION: cmd = REISERFS_IOC_GETVERSION; break; @@ -165,7 +154,7 @@ int reiserfs_commit_write(struct file *f, struct page *page, * Function try to convert tail from direct item into indirect. * It set up nopack attribute in the REISERFS_I(inode)->nopack */ -int reiserfs_unpack(struct inode *inode, struct file *filp) +int reiserfs_unpack(struct inode *inode) { int retval = 0; int index; diff --git a/fs/reiserfs/namei.c b/fs/reiserfs/namei.c index e6eb05e2b2f1..7d8a6b38e68a 100644 --- a/fs/reiserfs/namei.c +++ b/fs/reiserfs/namei.c @@ -1660,6 +1660,8 @@ const struct inode_operations reiserfs_dir_inode_operations = { .permission = reiserfs_permission, .get_acl = reiserfs_get_acl, .set_acl = reiserfs_set_acl, + .miscattr_get = reiserfs_miscattr_get, + .miscattr_set = reiserfs_miscattr_set, }; /* diff --git a/fs/reiserfs/reiserfs.h b/fs/reiserfs/reiserfs.h index 0ca2ac62e534..ba1d5b6fba47 100644 --- a/fs/reiserfs/reiserfs.h +++ b/fs/reiserfs/reiserfs.h @@ -18,8 +18,6 @@ /* the 32 bit compat definitions with int argument */ #define REISERFS_IOC32_UNPACK _IOW(0xCD, 1, int) -#define REISERFS_IOC32_GETFLAGS FS_IOC32_GETFLAGS -#define REISERFS_IOC32_SETFLAGS FS_IOC32_SETFLAGS #define REISERFS_IOC32_GETVERSION FS_IOC32_GETVERSION #define REISERFS_IOC32_SETVERSION FS_IOC32_SETVERSION @@ -3408,7 +3406,10 @@ __u32 r5_hash(const signed char *msg, int len); #define SPARE_SPACE 500 /* prototypes from ioctl.c */ +int reiserfs_miscattr_get(struct dentry *dentry, struct miscattr *ma); +int reiserfs_miscattr_set(struct user_namespace *mnt_userns, + struct dentry *dentry, struct miscattr *ma); long reiserfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); long reiserfs_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); -int reiserfs_unpack(struct inode *inode, struct file *filp); +int reiserfs_unpack(struct inode *inode); diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 1b9c7a387dc7..3ffafc73acf0 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c @@ -2408,7 +2408,7 @@ static int reiserfs_quota_on(struct super_block *sb, int type, int format_id, * IO to work */ if (!(REISERFS_I(inode)->i_flags & i_nopack_mask)) { - err = reiserfs_unpack(inode, NULL); + err = reiserfs_unpack(inode); if (err) { reiserfs_warning(sb, "super-6520", "Unpacking tail of quota file failed" From patchwork Mon Mar 22 14:49:15 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miklos Szeredi X-Patchwork-Id: 12155035 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E4D91C433E4 for ; Mon, 22 Mar 2021 14:50:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 573E9619B0 for ; Mon, 22 Mar 2021 14:50:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231437AbhCVOuf (ORCPT ); Mon, 22 Mar 2021 10:50:35 -0400 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:20233 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230288AbhCVOtm (ORCPT ); Mon, 22 Mar 2021 10:49:42 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1616424581; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Zh83JkhktP4ysipqS2U23lr0Hw3W6qLosekTGDxh+tI=; b=CKpsLNWXVWC3oxjrscg7/4Zcs+sO4iXdHOlS3vx08Ho/Ms6/Yr2nmtD5UhtYUEfA1CJxbW GrJuza1GPtxhK8LroviF9flMsoxU8nDUGVmPwjLOFji+D6d/LKAFHZpxN+SblsslkkVdzM TwrH8cXyGWta7xnJFT7+Si2YGqaBfPA= Received: from mail-ej1-f70.google.com (mail-ej1-f70.google.com [209.85.218.70]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-548-5bqYnJfpMl-mL5t5x6Rx9A-1; Mon, 22 Mar 2021 10:49:40 -0400 X-MC-Unique: 5bqYnJfpMl-mL5t5x6Rx9A-1 Received: by mail-ej1-f70.google.com with SMTP id t21so12005688ejf.14 for ; Mon, 22 Mar 2021 07:49:40 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Zh83JkhktP4ysipqS2U23lr0Hw3W6qLosekTGDxh+tI=; b=FSclBvLT3fLkEikN2cFd7UHTQFAzxaa+LHPJiULkNvVXtMmT1BBGKqsuHRX0ly44/V Mq736tMkdeIZvBFnUGcEINXf5wHd5yRB4EUjHH4thdJfbWWc7E1S+aaJ1owar8k2biIV fCUAo15ScSrJn3QhaBM/5Di0oJs1h0kmhfclvAEGYn2rqBTShshQh9RI9rQe2LsPK++h sx3p4kqNmFHujdz/MNog3Q/pvWEsiSJx1zZwhQ5RDjxtzal6v7UP3NRYMOqKaIFgnyBl asSxqAdeJS45r9Nwd7ko4nyaKhoLW0TPU0V25M2q8QJwo7aK9TmcmssIXJrxy8aFLvhC BNdw== X-Gm-Message-State: AOAM530ay/OhRNb+96F3iY73KaMb3noAqj8BPg/6lUzOdlv54vHoKUUm 5FKGtCcjXAGTCYZfPdwjv9dZvFQfAwpTsPnMEVycrkTIMPq+RRDZ+1YGHvMwg9oRixTV6p2IQyp LVhMXHz1z3k/ySO6aIjTZod9WwH6rymYCSVltqc1BdtjcsYGgcv7tvr+0wKHuZxu97cJ0tJDXAM L2iA== X-Received: by 2002:a17:907:7684:: with SMTP id jv4mr93177ejc.231.1616424579108; Mon, 22 Mar 2021 07:49:39 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzG5rnPxNZ5oGaCHvZUXeu7d2TZ2kP8r1pdCR02U9IOBl5+gOATfnUgGmJ2k38s0jwrpYNBpQ== X-Received: by 2002:a17:907:7684:: with SMTP id jv4mr93152ejc.231.1616424578911; Mon, 22 Mar 2021 07:49:38 -0700 (PDT) Received: from miu.piliscsaba.redhat.com (catv-86-101-169-67.catv.broadband.hu. [86.101.169.67]) by smtp.gmail.com with ESMTPSA id r4sm9793117ejd.125.2021.03.22.07.49.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Mar 2021 07:49:38 -0700 (PDT) From: Miklos Szeredi To: linux-fsdevel@vger.kernel.org Cc: Al Viro , linux-kernel@vger.kernel.org, Christoph Hellwig , Richard Weinberger Subject: [PATCH v2 17/18] ubifs: convert to miscattr Date: Mon, 22 Mar 2021 15:49:15 +0100 Message-Id: <20210322144916.137245-18-mszeredi@redhat.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210322144916.137245-1-mszeredi@redhat.com> References: <20210322144916.137245-1-mszeredi@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Use the miscattr API to let the VFS handle locking, permission checking and conversion. Signed-off-by: Miklos Szeredi Cc: Richard Weinberger --- fs/ubifs/dir.c | 2 ++ fs/ubifs/file.c | 2 ++ fs/ubifs/ioctl.c | 74 ++++++++++++++++++++---------------------------- fs/ubifs/ubifs.h | 3 ++ 4 files changed, 38 insertions(+), 43 deletions(-) diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c index d9d8d7794eff..ed9a3127fcd9 100644 --- a/fs/ubifs/dir.c +++ b/fs/ubifs/dir.c @@ -1637,6 +1637,8 @@ const struct inode_operations ubifs_dir_inode_operations = { .listxattr = ubifs_listxattr, .update_time = ubifs_update_time, .tmpfile = ubifs_tmpfile, + .miscattr_get = ubifs_miscattr_get, + .miscattr_set = ubifs_miscattr_set, }; const struct file_operations ubifs_dir_operations = { diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index 0e4b4be3aa26..90bad37ed060 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c @@ -1648,6 +1648,8 @@ const struct inode_operations ubifs_file_inode_operations = { .getattr = ubifs_getattr, .listxattr = ubifs_listxattr, .update_time = ubifs_update_time, + .miscattr_get = ubifs_miscattr_get, + .miscattr_set = ubifs_miscattr_set, }; const struct inode_operations ubifs_symlink_inode_operations = { diff --git a/fs/ubifs/ioctl.c b/fs/ubifs/ioctl.c index 2326d5122beb..87a423ee09bc 100644 --- a/fs/ubifs/ioctl.c +++ b/fs/ubifs/ioctl.c @@ -14,6 +14,7 @@ #include #include +#include #include "ubifs.h" /* Need to be kept consistent with checked flags in ioctl2ubifs() */ @@ -103,7 +104,7 @@ static int ubifs2ioctl(int ubifs_flags) static int setflags(struct inode *inode, int flags) { - int oldflags, err, release; + int err, release; struct ubifs_inode *ui = ubifs_inode(inode); struct ubifs_info *c = inode->i_sb->s_fs_info; struct ubifs_budget_req req = { .dirtied_ino = 1, @@ -114,11 +115,6 @@ static int setflags(struct inode *inode, int flags) return err; mutex_lock(&ui->ui_mutex); - oldflags = ubifs2ioctl(ui->flags); - err = vfs_ioc_setflags_prepare(inode, oldflags, flags); - if (err) - goto out_unlock; - ui->flags &= ~ioctl2ubifs(UBIFS_SETTABLE_IOCTL_FLAGS); ui->flags |= ioctl2ubifs(flags); ubifs_set_inode_flags(inode); @@ -132,54 +128,46 @@ static int setflags(struct inode *inode, int flags) if (IS_SYNC(inode)) err = write_inode_now(inode, 1); return err; - -out_unlock: - mutex_unlock(&ui->ui_mutex); - ubifs_release_budget(c, &req); - return err; } -long ubifs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +int ubifs_miscattr_get(struct dentry *dentry, struct miscattr *ma) { - int flags, err; - struct inode *inode = file_inode(file); + struct inode *inode = d_inode(dentry); + int flags = ubifs2ioctl(ubifs_inode(inode)->flags); - switch (cmd) { - case FS_IOC_GETFLAGS: - flags = ubifs2ioctl(ubifs_inode(inode)->flags); + dbg_gen("get flags: %#x, i_flags %#x", flags, inode->i_flags); + miscattr_fill_flags(ma, flags); - dbg_gen("get flags: %#x, i_flags %#x", flags, inode->i_flags); - return put_user(flags, (int __user *) arg); + return 0; +} - case FS_IOC_SETFLAGS: { - if (IS_RDONLY(inode)) - return -EROFS; +int ubifs_miscattr_set(struct user_namespace *mnt_userns, + struct dentry *dentry, struct miscattr *ma) +{ + struct inode *inode = d_inode(dentry); + int flags = ma->flags; - if (!inode_owner_or_capable(&init_user_ns, inode)) - return -EACCES; + if (miscattr_has_xattr(ma)) + return -EOPNOTSUPP; - if (get_user(flags, (int __user *) arg)) - return -EFAULT; + if (flags & ~UBIFS_GETTABLE_IOCTL_FLAGS) + return -EOPNOTSUPP; - if (flags & ~UBIFS_GETTABLE_IOCTL_FLAGS) - return -EOPNOTSUPP; - flags &= UBIFS_SETTABLE_IOCTL_FLAGS; + flags &= UBIFS_SETTABLE_IOCTL_FLAGS; - if (!S_ISDIR(inode->i_mode)) - flags &= ~FS_DIRSYNC_FL; + if (!S_ISDIR(inode->i_mode)) + flags &= ~FS_DIRSYNC_FL; - /* - * Make sure the file-system is read-write and make sure it - * will not become read-only while we are changing the flags. - */ - err = mnt_want_write_file(file); - if (err) - return err; - dbg_gen("set flags: %#x, i_flags %#x", flags, inode->i_flags); - err = setflags(inode, flags); - mnt_drop_write_file(file); - return err; - } + dbg_gen("set flags: %#x, i_flags %#x", flags, inode->i_flags); + return setflags(inode, flags); +} + +long ubifs_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int err; + struct inode *inode = file_inode(file); + + switch (cmd) { case FS_IOC_SET_ENCRYPTION_POLICY: { struct ubifs_info *c = inode->i_sb->s_fs_info; diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 7fdfdbda4b8a..f577cee6c548 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h @@ -2053,6 +2053,9 @@ int ubifs_recover_size(struct ubifs_info *c, bool in_place); void ubifs_destroy_size_tree(struct ubifs_info *c); /* ioctl.c */ +int ubifs_miscattr_get(struct dentry *dentry, struct miscattr *ma); +int ubifs_miscattr_set(struct user_namespace *mnt_userns, + struct dentry *dentry, struct miscattr *ma); long ubifs_ioctl(struct file *file, unsigned int cmd, unsigned long arg); void ubifs_set_inode_flags(struct inode *inode); #ifdef CONFIG_COMPAT From patchwork Mon Mar 22 14:49:16 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miklos Szeredi X-Patchwork-Id: 12155033 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-19.0 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D0C9AC433E5 for ; Mon, 22 Mar 2021 14:50:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7618E61992 for ; Mon, 22 Mar 2021 14:50:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231445AbhCVOuh (ORCPT ); Mon, 22 Mar 2021 10:50:37 -0400 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:30968 "EHLO us-smtp-delivery-124.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230241AbhCVOto (ORCPT ); Mon, 22 Mar 2021 10:49:44 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1616424583; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=DzzrxrfbZ6Li1+rV206VufAvp4kmrq19gDEYr0Sjiyg=; b=huCnqCoBhGalT+LmtXIU7J6EmxtzCYxCzswKyeIrKP3HxO3wNaDQVaVDwVOnA+6V7Ga9wj +EAXeL0u2xGBo1F+mxzMwiM+PojxrlrXZrazUrIl7sKbcTM1EMe5yEFoT10s9lUhYAFS1I 1bNmqd+4El9ZtJTGQczTe85ao8gQTa4= Received: from mail-ej1-f70.google.com (mail-ej1-f70.google.com [209.85.218.70]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-485-VPqmcdQ2NXKSYWIjMeXvwg-1; Mon, 22 Mar 2021 10:49:41 -0400 X-MC-Unique: VPqmcdQ2NXKSYWIjMeXvwg-1 Received: by mail-ej1-f70.google.com with SMTP id rl7so19905658ejb.16 for ; Mon, 22 Mar 2021 07:49:41 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=DzzrxrfbZ6Li1+rV206VufAvp4kmrq19gDEYr0Sjiyg=; b=jX52yCdAReo2jxsn3wBZFvxNjiNDKf7Z4G9uc+EvgJ7A5oVCgA/WGBg0Gyy1566i54 v7XGpwbutYGulwUYnVI+pWd4w1cLQBosarVznOjM+kIY4CteUSO5ZXVwmlgqmFW+GrLZ Qla6PjkdAX60g94w0lseJwSg0P6+EvnePbESjJ7jt+luLkxcmJo/eGgDnK6SJQmh8qX/ wh/IACxSVtLK1w30DrhwgqJEg4g3Dq4uIqPgVPFqJbCvW/yFTMaZzsCC49Mjbw/UvANv Qjw6ay7/Hpp7uNWt+bHcCpUnpsDBaEV/M5bgUJsaEndb1zCTuJsjarbsbukCwUfDXeey mIXQ== X-Gm-Message-State: AOAM530+R9q3PDvoAYO4+vh0eDzN9sZZLXS8sSKRQJo9nn9DLhMP6md/ 9Cy2fpKZfyVKqWj4+otLLoBStycxrKD/XGNKEAYQC8bwsEBMZOlbsj8qata3novhhHWd7C8tj+j K3KqH8t/wwRT+eSrjS7b47Ph1PGaB4g2L1V5vFwLcrqug+Bk5b+jcKzsiMmd/QKuBnwV98e6sH4 fgXA== X-Received: by 2002:a05:6402:181a:: with SMTP id g26mr26122494edy.225.1616424579975; Mon, 22 Mar 2021 07:49:39 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwmA+7jm77Yf7uBGUKOCjGtM76lqZiG9z471QyGjwDECbN0X/0/eSaIJdwN8mOgSCCGtChCmA== X-Received: by 2002:a05:6402:181a:: with SMTP id g26mr26122467edy.225.1616424579749; Mon, 22 Mar 2021 07:49:39 -0700 (PDT) Received: from miu.piliscsaba.redhat.com (catv-86-101-169-67.catv.broadband.hu. [86.101.169.67]) by smtp.gmail.com with ESMTPSA id r4sm9793117ejd.125.2021.03.22.07.49.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 22 Mar 2021 07:49:39 -0700 (PDT) From: Miklos Szeredi To: linux-fsdevel@vger.kernel.org Cc: Al Viro , linux-kernel@vger.kernel.org, Christoph Hellwig Subject: [PATCH v2 18/18] vfs: remove unused ioctl helpers Date: Mon, 22 Mar 2021 15:49:16 +0100 Message-Id: <20210322144916.137245-19-mszeredi@redhat.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210322144916.137245-1-mszeredi@redhat.com> References: <20210322144916.137245-1-mszeredi@redhat.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org Remove vfs_ioc_setflags_prepare(), vfs_ioc_fssetxattr_check() and simple_fill_fsxattr(), which are no longer used. Signed-off-by: Miklos Szeredi Reviewed-by: Darrick J. Wong --- fs/inode.c | 87 ---------------------------------------------- include/linux/fs.h | 12 ------- 2 files changed, 99 deletions(-) diff --git a/fs/inode.c b/fs/inode.c index a047ab306f9a..ae526fd9c0a4 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #include @@ -2314,89 +2313,3 @@ struct timespec64 current_time(struct inode *inode) return timestamp_truncate(now, inode); } EXPORT_SYMBOL(current_time); - -/* - * Generic function to check FS_IOC_SETFLAGS values and reject any invalid - * configurations. - * - * Note: the caller should be holding i_mutex, or else be sure that they have - * exclusive access to the inode structure. - */ -int vfs_ioc_setflags_prepare(struct inode *inode, unsigned int oldflags, - unsigned int flags) -{ - /* - * The IMMUTABLE and APPEND_ONLY flags can only be changed by - * the relevant capability. - * - * This test looks nicer. Thanks to Pauline Middelink - */ - if ((flags ^ oldflags) & (FS_APPEND_FL | FS_IMMUTABLE_FL) && - !capable(CAP_LINUX_IMMUTABLE)) - return -EPERM; - - return fscrypt_prepare_setflags(inode, oldflags, flags); -} -EXPORT_SYMBOL(vfs_ioc_setflags_prepare); - -/* - * Generic function to check FS_IOC_FSSETXATTR values and reject any invalid - * configurations. - * - * Note: the caller should be holding i_mutex, or else be sure that they have - * exclusive access to the inode structure. - */ -int vfs_ioc_fssetxattr_check(struct inode *inode, const struct fsxattr *old_fa, - struct fsxattr *fa) -{ - /* - * Can't modify an immutable/append-only file unless we have - * appropriate permission. - */ - if ((old_fa->fsx_xflags ^ fa->fsx_xflags) & - (FS_XFLAG_IMMUTABLE | FS_XFLAG_APPEND) && - !capable(CAP_LINUX_IMMUTABLE)) - return -EPERM; - - /* - * Project Quota ID state is only allowed to change from within the init - * namespace. Enforce that restriction only if we are trying to change - * the quota ID state. Everything else is allowed in user namespaces. - */ - if (current_user_ns() != &init_user_ns) { - if (old_fa->fsx_projid != fa->fsx_projid) - return -EINVAL; - if ((old_fa->fsx_xflags ^ fa->fsx_xflags) & - FS_XFLAG_PROJINHERIT) - return -EINVAL; - } - - /* Check extent size hints. */ - if ((fa->fsx_xflags & FS_XFLAG_EXTSIZE) && !S_ISREG(inode->i_mode)) - return -EINVAL; - - if ((fa->fsx_xflags & FS_XFLAG_EXTSZINHERIT) && - !S_ISDIR(inode->i_mode)) - return -EINVAL; - - if ((fa->fsx_xflags & FS_XFLAG_COWEXTSIZE) && - !S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode)) - return -EINVAL; - - /* - * It is only valid to set the DAX flag on regular files and - * directories on filesystems. - */ - if ((fa->fsx_xflags & FS_XFLAG_DAX) && - !(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode))) - return -EINVAL; - - /* Extent size hints of zero turn off the flags. */ - if (fa->fsx_extsize == 0) - fa->fsx_xflags &= ~(FS_XFLAG_EXTSIZE | FS_XFLAG_EXTSZINHERIT); - if (fa->fsx_cowextsize == 0) - fa->fsx_xflags &= ~FS_XFLAG_COWEXTSIZE; - - return 0; -} -EXPORT_SYMBOL(vfs_ioc_fssetxattr_check); diff --git a/include/linux/fs.h b/include/linux/fs.h index 9e7f6a592a70..1e88ace15004 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -3571,18 +3571,6 @@ extern int vfs_fadvise(struct file *file, loff_t offset, loff_t len, extern int generic_fadvise(struct file *file, loff_t offset, loff_t len, int advice); -int vfs_ioc_setflags_prepare(struct inode *inode, unsigned int oldflags, - unsigned int flags); - -int vfs_ioc_fssetxattr_check(struct inode *inode, const struct fsxattr *old_fa, - struct fsxattr *fa); - -static inline void simple_fill_fsxattr(struct fsxattr *fa, __u32 xflags) -{ - memset(fa, 0, sizeof(*fa)); - fa->fsx_xflags = xflags; -} - /* * Flush file data before changing attributes. Caller must hold any locks * required to prevent further writes to this file until we're done setting