From patchwork Wed Jul 13 14:52:34 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: 12916852 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 CED2AC43334 for ; Wed, 13 Jul 2022 14:52:44 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 012D294013D; Wed, 13 Jul 2022 10:52:44 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id F03E9940134; Wed, 13 Jul 2022 10:52:43 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id DCB7B94013D; Wed, 13 Jul 2022 10:52:43 -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 CB28A940134 for ; Wed, 13 Jul 2022 10:52:43 -0400 (EDT) Received: from smtpin29.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay02.hostedemail.com (Postfix) with ESMTP id A2B33343B2 for ; Wed, 13 Jul 2022 14:52:43 +0000 (UTC) X-FDA: 79682368206.29.142E02B Received: from outgoing.mit.edu (outgoing-auth-1.mit.edu [18.9.28.11]) by imf16.hostedemail.com (Postfix) with ESMTP id 385A8180068 for ; Wed, 13 Jul 2022 14:52:43 +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 26DEqd68004489 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 13 Jul 2022 10:52:40 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mit.edu; s=outgoing; t=1657723961; bh=4IntBCgW9bQI8V7wMWWb5V8Y2dmIVkKrZgJSdehTo2s=; h=From:To:Cc:Subject:Date; b=gb/IuVobc1i3yb379INLk/C38pTTTltdQ0IUYu4urtUT0Tl+MC2Ee+8vVrVj5hwuZ Kg7M5y6b8HCsNuyka8DC+vBXzd1nm6Q1F+d5VfOsuOFnGAJTayelEmcwBwoOyfJgQf eNuRf4HXTSrLwH/k8xa26my31z1VLfXOBuChnyp9wwiYOYMI8Sog6ERAAzxly9l0ZJ CrEWwH0MwR8416ksfSNYP922Kl4kZs4HoS/s+q8VJ95Wfntd0npylJaTNuHgOHFDiH gZHQYTJBh5yvgL9BFH4Y2NPX/BBg7JK1IgLdFL4tPOrkBL3yCmOVp3KU7vPjCvlfDe zfiCDvX7jsiGQ== Received: by cwcc.thunk.org (Postfix, from userid 15806) id 54AC915C3AE2; Wed, 13 Jul 2022 10:52:39 -0400 (EDT) From: "Theodore Ts'o" To: Hugh Dickins Cc: Andrew Morton , linux-mm@kvack.org, "Theodore Ts'o" Subject: [PATCH] mm/shmem: add support for FS_IOC_[SG]ETFLAGS for tmpfs Date: Wed, 13 Jul 2022 10:52:34 -0400 Message-Id: <20220713145234.2356641-1-tytso@mit.edu> X-Mailer: git-send-email 2.31.0 MIME-Version: 1.0 ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1657723963; a=rsa-sha256; cv=none; b=DffBMihE+wsmPDf09nEDVKeAEfSYJ/eJcCHpQg9gjhB5I5LRg1uAtBUbS6JW1RTr7o64um p+wviI7FPH/tu/AT5oY9/lJjI6rLcg5qqoJPVfcoJqdkR/Z44Sc6VKpx2zMQGvw6j+nMmc qwwyOQKex6mkXovZbT2rJXseQFAKXIs= ARC-Authentication-Results: i=1; imf16.hostedemail.com; dkim=fail ("headers rsa verify failed") header.d=mit.edu header.s=outgoing header.b="gb/IuVob"; dmarc=fail reason="No valid SPF" header.from=mit.edu (policy=none); spf=none (imf16.hostedemail.com: domain of tytso@mit.edu has no SPF policy when checking 18.9.28.11) smtp.mailfrom=tytso@mit.edu ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1657723963; 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:references:dkim-signature; bh=4IntBCgW9bQI8V7wMWWb5V8Y2dmIVkKrZgJSdehTo2s=; b=uRjSezPePrGtISlEtnJxITwQspIsQRGJfpVtpTd7n7BnEnlWSdj1DEIaCO72XJrvOr9kwu J92eDrGNoHZL1SKhEgH2yUogquQUcuumo+bA8sSjyos6Mfan+3QOOhuuGDSyheHhmQh37r cZjqTyQQLgJ1xxv0grLayl+frRwPNhE= X-Rspam-User: X-Stat-Signature: chi7txoud1b4qd4xgg3igb817poqwitf X-Rspamd-Queue-Id: 385A8180068 Authentication-Results: imf16.hostedemail.com; dkim=fail ("headers rsa verify failed") header.d=mit.edu header.s=outgoing header.b="gb/IuVob"; dmarc=fail reason="No valid SPF" header.from=mit.edu (policy=none); spf=none (imf16.hostedemail.com: domain of tytso@mit.edu has no SPF policy when checking 18.9.28.11) smtp.mailfrom=tytso@mit.edu X-Rspamd-Server: rspam03 X-HE-Tag: 1657723963-53938 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 Reported-by: kernel test robot Reported-by: kernel test robot --- include/linux/shmem_fs.h | 11 +++++++ mm/shmem.c | 65 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 75 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..515a2708d658 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 & EXT2_APPEND_FL) + stat->attributes |= STATX_ATTR_APPEND; + if (info->fsflags & EXT2_IMMUTABLE_FL) + stat->attributes |= STATX_ATTR_IMMUTABLE; + if (info->fsflags & EXT2_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,41 @@ 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 = (fa->flags & ~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 +3887,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 +3908,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,