From patchwork Thu Jul 14 02:24:48 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: 12917250 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 49989C433EF for ; Thu, 14 Jul 2022 02:25:00 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 71460940169; Wed, 13 Jul 2022 22:24:59 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 6C373940134; Wed, 13 Jul 2022 22:24:59 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 5B22F940169; Wed, 13 Jul 2022 22:24:59 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0014.hostedemail.com [216.40.44.14]) by kanga.kvack.org (Postfix) with ESMTP id 4BA15940134 for ; Wed, 13 Jul 2022 22:24:59 -0400 (EDT) Received: from smtpin08.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay13.hostedemail.com (Postfix) with ESMTP id 1EF026030B for ; Thu, 14 Jul 2022 02:24:59 +0000 (UTC) X-FDA: 79684112718.08.94DD835 Received: from outgoing.mit.edu (outgoing-auth-1.mit.edu [18.9.28.11]) by imf23.hostedemail.com (Postfix) with ESMTP id A49DD140080 for ; Thu, 14 Jul 2022 02:24:58 +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 26E2Otl7029916 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 13 Jul 2022 22:24:56 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mit.edu; s=outgoing; t=1657765496; bh=jknfUNY6Fiy4JcwsJFQzvCDzd9tWFv6DW4RA0ADCARA=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=X7f/by3NKAJcwa3RrUVYgbctU+1hoq+KR4dXGer/fBfnELfC0qB+ckt5Tfqh0zVS2 nhcqecZ4uy68K8y+I7E8nglg+0qSQp8ZtFHSv7zG/B5BFo0IugMHg0l2sISu9WW8v1 Da2TqC3JWn/BmFBxQDV98QD8iBg8wQ7e04+xedSuCUJhhzfK9v2GOXFt6S6+5UZSwQ dH7FQCdG7U/Ls7EVRAk6vnQd5eJlKgStypA3UP5nlpRyTT6WPH7udOaUkCIUBfD4RL pYtsO4Iy+Tes3mia5AVRIiUlnuBjZOe5CG+T7wNp0hIP35ZMeWeB3hwxxVDf21+Yvk HjM1e4VxAQwZA== Received: by cwcc.thunk.org (Postfix, from userid 15806) id 5547615C3AE2; Wed, 13 Jul 2022 22:24:55 -0400 (EDT) From: "Theodore Ts'o" To: Andrew Morton Cc: Hugh Dickins , linux-mm@kvack.org, "Theodore Ts'o" Subject: [PATCH -v2] mm/shmem: support FS_IOC_[SG]ETFLAGS in tmpfs Date: Wed, 13 Jul 2022 22:24:48 -0400 Message-Id: <20220714022448.2430819-1-tytso@mit.edu> X-Mailer: git-send-email 2.31.0 In-Reply-To: References: MIME-Version: 1.0 ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1657765498; 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=jknfUNY6Fiy4JcwsJFQzvCDzd9tWFv6DW4RA0ADCARA=; b=tceVYUTLIq28kSl9bsLw+jNRm3bQoimDOdv3rU2lD57un0SIsVKhBey/wgRECtkxNCEGWG yeakWfLyvXS1N6kt+xUwbNRM8tcM94aR5EPp3alYKeEP/dL6xggJJaAwpdFWOeSaUcog4G 1FLFYtuZn0I8HSxOiKEm85hrBXDkow4= ARC-Authentication-Results: i=1; imf23.hostedemail.com; dkim=fail ("headers rsa verify failed") header.d=mit.edu header.s=outgoing header.b="X7f/by3N"; dmarc=fail reason="No valid SPF" header.from=mit.edu (policy=none); spf=none (imf23.hostedemail.com: domain of tytso@mit.edu has no SPF policy when checking 18.9.28.11) smtp.mailfrom=tytso@mit.edu ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1657765498; a=rsa-sha256; cv=none; b=4s8wkxJMQe8zjoczt9bajQLEg2GXBfi/8RMaQjvq05Hn9RbdNl8hOAFYfDiGCX+XkmEoFm LQ26MoBigfxh7NRrs62qhdVj2ojadfdj6yav4TRdDbeaEEd8PKv6EQVyPNA9UuC3JJTGcZ 1cS///Up/sGQygK/kac01zmMXn98/hs= X-Stat-Signature: 533pd7oz6i3oow1p5yagndaopc5kt9gj X-Rspamd-Server: rspam12 X-Rspamd-Queue-Id: A49DD140080 Authentication-Results: imf23.hostedemail.com; dkim=fail ("headers rsa verify failed") header.d=mit.edu header.s=outgoing header.b="X7f/by3N"; dmarc=fail reason="No valid SPF" header.from=mit.edu (policy=none); spf=none (imf23.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-HE-Tag: 1657765498-317528 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 --- 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..7540e16f6afa 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; } +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; +} + +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,