From patchwork Fri Jul 15 01:59:12 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Theodore Ts'o X-Patchwork-Id: 12918667 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2F58FC433EF for ; Fri, 15 Jul 2022 01:59:21 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 9E88C9401C3; Thu, 14 Jul 2022 21:59:20 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 996EC9401A5; Thu, 14 Jul 2022 21:59:20 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 85E0F9401C3; Thu, 14 Jul 2022 21:59:20 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0016.hostedemail.com [216.40.44.16]) by kanga.kvack.org (Postfix) with ESMTP id 7413E9401A5 for ; Thu, 14 Jul 2022 21:59:20 -0400 (EDT) Received: from smtpin23.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay11.hostedemail.com (Postfix) with ESMTP id 479E6803BE for ; Fri, 15 Jul 2022 01:59:20 +0000 (UTC) X-FDA: 79687676880.23.3D5DAB5 Received: from outgoing.mit.edu (outgoing-auth-1.mit.edu [18.9.28.11]) by imf21.hostedemail.com (Postfix) with ESMTP id 8736C1C0083 for ; Fri, 15 Jul 2022 01:59:19 +0000 (UTC) Received: from cwcc.thunk.org (pool-173-48-118-63.bstnma.fios.verizon.net [173.48.118.63]) (authenticated bits=0) (User authenticated as tytso@ATHENA.MIT.EDU) by outgoing.mit.edu (8.14.7/8.12.4) with ESMTP id 26F1xGOq023262 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 14 Jul 2022 21:59:17 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mit.edu; s=outgoing; t=1657850357; bh=BwKs/HXOIBcvqCDd2CHuTrllAqglGVK7AL6jliIdTqQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=M4Z5PucCIwGozM+HKS+y48GoyeW+UF6RrKV6GbP0uJfH/ZyantK/Cery4LgyWdfi4 TisRbzGUCAMbUwvGi6MMUH0PVUaEg3i0ryk0j0U6Tu7JiVbcxr13kDutGOsmTDttBM hGrAPT6xah5/rHjUvPUIxNdyLNlxvD3yw+3YUrlRnkFMuiJqTlNF+tGrwa5mvb7jT7 HZJJSfgS3Jt1CqLphfhV7/ih0+63PS7H4Ds+SqP7/olET4qq4jzlmg+JP1DNRvQyh2 1TVVJCq234eohtMEAKVO0SgA7g2fApLdHOJTWbbCkEVvyyTAn029A7FcTjFtctsBKT Uj4rvy8O3jlaQ== Received: by cwcc.thunk.org (Postfix, from userid 15806) id 1162515C003C; Thu, 14 Jul 2022 21:59:16 -0400 (EDT) From: "Theodore Ts'o" To: Andrew Morton Cc: Hugh Dickins , linux-mm@kvack.org, "Theodore Ts'o" Subject: [PATCH -v3] mm/shmem: support FS_IOC_[SG]ETFLAGS in tmpfs Date: Thu, 14 Jul 2022 21:59:12 -0400 Message-Id: <20220715015912.2560575-1-tytso@mit.edu> X-Mailer: git-send-email 2.31.0 In-Reply-To: <20220714022448.2430819-1-tytso@mit.edu> References: <20220714022448.2430819-1-tytso@mit.edu> MIME-Version: 1.0 ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1657850359; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=BwKs/HXOIBcvqCDd2CHuTrllAqglGVK7AL6jliIdTqQ=; b=Cikng6nnthytZOgrSxXwUl2d9Jah2aZ1b1sRJtKP2UcGFZH87cIyazOLr7sP7Titw2bSiN 6g6Wan50Ism402v/MI2IwuJWAJhyRGy9Fk6oEhF3InidAyiLzsPPu/rAgDWQeUVIavukXF 1cY66XEbWS97gK6vH80Wdgei/MfPF/w= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1657850359; a=rsa-sha256; cv=none; b=0VGRGOuvs9xQq8JT4NyfjxzmKKIKv/4YeBEPSsQ6K3I7FtpVB2MON2+W9bbmBcc4YMl1SS kV0Jv+AttE3SMzAv+02lqhGB9b+oOoR59Cs/dk1Sq9gIEvPn9D9XCoGHz/PjpfbJ1YhZHy RIzQHRBZSXpOXdHhOmWUWScHIAHOxgE= ARC-Authentication-Results: i=1; imf21.hostedemail.com; dkim=fail ("headers rsa verify failed") header.d=mit.edu header.s=outgoing header.b=M4Z5PucC; dmarc=fail reason="No valid SPF" header.from=mit.edu (policy=none); spf=none (imf21.hostedemail.com: domain of tytso@mit.edu has no SPF policy when checking 18.9.28.11) smtp.mailfrom=tytso@mit.edu X-Rspam-User: X-Rspamd-Server: rspam05 Authentication-Results: imf21.hostedemail.com; dkim=fail ("headers rsa verify failed") header.d=mit.edu header.s=outgoing header.b=M4Z5PucC; dmarc=fail reason="No valid SPF" header.from=mit.edu (policy=none); spf=none (imf21.hostedemail.com: domain of tytso@mit.edu has no SPF policy when checking 18.9.28.11) smtp.mailfrom=tytso@mit.edu X-Stat-Signature: mwpqqdnht75fwodud44y69jgzdjmz6a3 X-Rspamd-Queue-Id: 8736C1C0083 X-HE-Tag: 1657850359-637500 X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: This allows userspace to set flags like FS_APPEND_FL, FS_IMMUTABLE_FL, FS_NODUMP_FL, etc., like all other standard Linux file systems. Signed-off-by: Theodore Ts'o --- v3: - declare shmem_fileattr_get() and shmem_fileattr_set() as static functions v2: - replace use of EXT2_xxx_FL with FS_xxx_FL - fix preservation of non-modifiable flags in shmem_fileattr_set() - update the commit summary description include/linux/shmem_fs.h | 11 +++++++ mm/shmem.c | 63 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h index a68f982f22d1..1b6c4013f691 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h @@ -25,9 +25,20 @@ struct shmem_inode_info { struct simple_xattrs xattrs; /* list of xattrs */ atomic_t stop_eviction; /* hold when working on inode */ struct timespec64 i_crtime; /* file creation time */ + unsigned int fsflags; /* flags for FS_IOC_[SG]ETFLAGS */ struct inode vfs_inode; }; +#define SHMEM_FL_USER_VISIBLE FS_FL_USER_VISIBLE +#define SHMEM_FL_USER_MODIFIABLE FS_FL_USER_MODIFIABLE +#define SHMEM_FL_INHERITED FS_FL_USER_MODIFIABLE + +/* Flags that are appropriate for regular files (all but dir-specific ones). */ +#define SHMEM_REG_FLMASK (~(FS_DIRSYNC_FL | FS_TOPDIR_FL)) + +/* Flags that are appropriate for non-directories/regular files. */ +#define SHMEM_OTHER_FLMASK (FS_NODUMP_FL | FS_NOATIME_FL) + struct shmem_sb_info { unsigned long max_blocks; /* How many blocks are allowed */ struct percpu_counter used_blocks; /* How many are allocated */ diff --git a/mm/shmem.c b/mm/shmem.c index a6f565308133..fc48680b961a 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -1058,6 +1059,15 @@ static int shmem_getattr(struct user_namespace *mnt_userns, shmem_recalc_inode(inode); spin_unlock_irq(&info->lock); } + if (info->fsflags & FS_APPEND_FL) + stat->attributes |= STATX_ATTR_APPEND; + if (info->fsflags & FS_IMMUTABLE_FL) + stat->attributes |= STATX_ATTR_IMMUTABLE; + if (info->fsflags & FS_NODUMP_FL) + stat->attributes |= STATX_ATTR_NODUMP; + stat->attributes_mask |= (STATX_ATTR_APPEND | + STATX_ATTR_IMMUTABLE | + STATX_ATTR_NODUMP); generic_fillattr(&init_user_ns, inode, stat); if (shmem_is_huge(NULL, inode, 0)) @@ -2272,7 +2282,18 @@ static int shmem_mmap(struct file *file, struct vm_area_struct *vma) return 0; } -static struct inode *shmem_get_inode(struct super_block *sb, const struct inode *dir, +/* Mask out flags that are inappropriate for the given type of inode. */ +static unsigned shmem_mask_flags(umode_t mode, __u32 flags) +{ + if (S_ISDIR(mode)) + return flags; + else if (S_ISREG(mode)) + return flags & SHMEM_REG_FLMASK; + else + return flags & SHMEM_OTHER_FLMASK; +} + +static struct inode *shmem_get_inode(struct super_block *sb, struct inode *dir, umode_t mode, dev_t dev, unsigned long flags) { struct inode *inode; @@ -2297,6 +2318,9 @@ static struct inode *shmem_get_inode(struct super_block *sb, const struct inode info->seals = F_SEAL_SEAL; info->flags = flags & VM_NORESERVE; info->i_crtime = inode->i_mtime; + info->fsflags = (dir == NULL) ? 0 : + SHMEM_I(dir)->fsflags & SHMEM_FL_INHERITED; + info->fsflags = shmem_mask_flags(mode, info->fsflags); INIT_LIST_HEAD(&info->shrinklist); INIT_LIST_HEAD(&info->swaplist); simple_xattrs_init(&info->xattrs); @@ -2813,6 +2837,39 @@ static long shmem_fallocate(struct file *file, int mode, loff_t offset, return error; } +static int shmem_fileattr_get(struct dentry *dentry, struct fileattr *fa) +{ + struct shmem_inode_info *info = SHMEM_I(d_inode(dentry)); + + fileattr_fill_flags(fa, info->fsflags & SHMEM_FL_USER_VISIBLE); + + return 0; +} + +static int shmem_fileattr_set(struct user_namespace *mnt_userns, + struct dentry *dentry, struct fileattr *fa) +{ + struct inode *inode = d_inode(dentry); + struct shmem_inode_info *info = SHMEM_I(inode); + + if (fileattr_has_fsx(fa)) + return -EOPNOTSUPP; + + info->fsflags = (info->fsflags & ~SHMEM_FL_USER_MODIFIABLE) | + (fa->flags & SHMEM_FL_USER_MODIFIABLE); + + inode->i_flags &= ~(S_APPEND | S_IMMUTABLE | S_NOATIME); + if (info->fsflags & FS_APPEND_FL) + inode->i_flags |= S_APPEND; + if (info->fsflags & FS_IMMUTABLE_FL) + inode->i_flags |= S_IMMUTABLE; + if (info->fsflags & FS_NOATIME_FL) + inode->i_flags |= S_NOATIME; + + inode->i_ctime = current_time(inode); + return 0; +} + static int shmem_statfs(struct dentry *dentry, struct kstatfs *buf) { struct shmem_sb_info *sbinfo = SHMEM_SB(dentry->d_sb); @@ -3828,6 +3885,8 @@ static const struct inode_operations shmem_inode_operations = { #ifdef CONFIG_TMPFS_XATTR .listxattr = shmem_listxattr, .set_acl = simple_set_acl, + .fileattr_get = shmem_fileattr_get, + .fileattr_set = shmem_fileattr_set, #endif }; @@ -3847,6 +3906,8 @@ static const struct inode_operations shmem_dir_inode_operations = { #endif #ifdef CONFIG_TMPFS_XATTR .listxattr = shmem_listxattr, + .fileattr_get = shmem_fileattr_get, + .fileattr_set = shmem_fileattr_set, #endif #ifdef CONFIG_TMPFS_POSIX_ACL .setattr = shmem_setattr,