Received: by 2002:a05:6a10:9848:0:0:0:0 with SMTP id x8csp4534974pxf; Tue, 23 Mar 2021 13:02:49 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxzFFdoDze/PxEdaIkY4tcPKWknNAlO0StQvTa027WWRMVSvFU3z1j/bSkTrXRXMszb38Vm X-Received: by 2002:a17:906:4f02:: with SMTP id t2mr6441457eju.121.1616529769466; Tue, 23 Mar 2021 13:02:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1616529769; cv=none; d=google.com; s=arc-20160816; b=tDFJlIiFtJHsZ/iRuzoManGpFva2/kRUKD2BMLh7xya9hjk7wnjJV60PXn2p5JBYLd 6XTQfnKnLolzgkJJKYGFLhpIK+7QyOngjRVwXCyqsYO34Btf3t0KSCOuPNkMLAaeg02C pvHMpPGNJplS1jVj8zN0SSMLfeY1OJZU0VTXGiekmyFeN8oMmkCsZxyjICHRzC6DSNND Lc3hOlQRBRxCakrbPk5Z4T5llB94bVqxepJsGeGtjVzuapaHcQXKWk6vG1MIHnt5Gx4D K4p1p2cOV6zqvjQYkJWkH1JOcrPdUmWezJjR16i94ehdVXQpaJnVg6Sgk0P3UCGOnpNS t+IA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=ZL1oQ7rbMiyQ352X8jHPXy7bFUM8kECllbK/W1eBcRM=; b=SDaTgGVgSfDoE/RIbcQMwioNGALv3gwwuWNBae63+1ifE5KMQ4/SQpIXdzJbLfagJp 43m3JpBs5xbMjcEe3G1nrr7FcnYAbehV4Ns8nyKDbkTDWs1h2lFT4tkhsyW59mriG0am 2vq5v/TY73SLWDcnTnX7oC0W7fDTeRnfMzFFHk2U5nU1bN5onnL+zEt3ZQHmviEWnM46 eCFf5nyGAyr7J046zlTOZ76A45pKrD1LeXj5iPxpZXjT9IqSRDv/yA2b6BAmNMD1ZuOI 8Xelj+iZJTeRFu5YB9qBjXOht8sPWAdD4ah/iLWbQf53eNX2VNlB3+SDthv8kQaM+LKz hTQQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=collabora.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id hc43si30832ejc.387.2021.03.23.13.02.26; Tue, 23 Mar 2021 13:02:49 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=collabora.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233332AbhCWUAs (ORCPT + 99 others); Tue, 23 Mar 2021 16:00:48 -0400 Received: from bhuna.collabora.co.uk ([46.235.227.227]:54078 "EHLO bhuna.collabora.co.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232978AbhCWUAO (ORCPT ); Tue, 23 Mar 2021 16:00:14 -0400 Received: from [127.0.0.1] (localhost [127.0.0.1]) (Authenticated sender: tonyk) with ESMTPSA id C6F111F44DBA From: =?UTF-8?q?Andr=C3=A9=20Almeida?= To: Hugh Dickins , Andrew Morton , Alexander Viro Cc: krisman@collabora.com, smcv@collabora.com, kernel@collabora.com, linux-mm@kvack.org, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org, Daniel Rosenberg , =?UTF-8?q?Andr=C3=A9=20Almeida?= Subject: [RFC PATCH 3/4] mm: shmem: Add IOCTL support for tmpfs Date: Tue, 23 Mar 2021 16:59:40 -0300 Message-Id: <20210323195941.69720-4-andrealmeid@collabora.com> X-Mailer: git-send-email 2.31.0 In-Reply-To: <20210323195941.69720-1-andrealmeid@collabora.com> References: <20210323195941.69720-1-andrealmeid@collabora.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Implement IOCTL operations for files to set/get file flags. Implement the only supported flag by now, that is S_CASEFOLD. Signed-off-by: André Almeida --- include/linux/shmem_fs.h | 4 ++ mm/shmem.c | 84 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 87 insertions(+), 1 deletion(-) diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h index 29ee64352807..2c89c5a66508 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h @@ -140,4 +140,8 @@ extern int shmem_mfill_zeropage_pte(struct mm_struct *dst_mm, dst_addr) ({ BUG(); 0; }) #endif +#define TMPFS_CASEFOLD_FL 0x40000000 /* Casefolded file */ +#define TMPFS_USER_FLS TMPFS_CASEFOLD_FL /* Userspace supported flags */ +#define TMPFS_FLS S_CASEFOLD /* Kernel supported flags */ + #endif diff --git a/mm/shmem.c b/mm/shmem.c index 20df81763995..2f2c996d215b 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -258,6 +258,7 @@ static inline void shmem_inode_unacct_blocks(struct inode *inode, long pages) static const struct super_operations shmem_ops; const struct address_space_operations shmem_aops; static const struct file_operations shmem_file_operations; +static const struct file_operations shmem_dir_operations; static const struct inode_operations shmem_inode_operations; static const struct inode_operations shmem_dir_inode_operations; static const struct inode_operations shmem_special_inode_operations; @@ -2347,7 +2348,7 @@ static struct inode *shmem_get_inode(struct super_block *sb, const struct inode /* Some things misbehave if size == 0 on a directory */ inode->i_size = 2 * BOGO_DIRENT_SIZE; inode->i_op = &shmem_dir_inode_operations; - inode->i_fop = &simple_dir_operations; + inode->i_fop = &shmem_dir_operations; break; case S_IFLNK: /* @@ -2838,6 +2839,76 @@ static long shmem_fallocate(struct file *file, int mode, loff_t offset, return error; } +static long shmem_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +{ + int ret; + u32 fsflags = 0, old, new = 0; + struct inode *inode = file_inode(file); + struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb); + + switch (cmd) { + case FS_IOC_GETFLAGS: + if ((inode->i_flags & S_CASEFOLD) && S_ISDIR(inode->i_mode)) + fsflags |= TMPFS_CASEFOLD_FL; + + if (put_user(fsflags, (int __user *)arg)) + return -EFAULT; + + return 0; + + case FS_IOC_SETFLAGS: + if (get_user(fsflags, (int __user *)arg)) + return -EFAULT; + + old = inode->i_flags; + + if (fsflags & ~TMPFS_USER_FLS) + return -EINVAL; + + if (fsflags & TMPFS_CASEFOLD_FL) { + if (!sbinfo->casefold) { + pr_err("tmpfs: casefold disabled at this mount point\n"); + return -EOPNOTSUPP; + } + + if (!S_ISDIR(inode->i_mode)) + return -ENOTDIR; + + if (!simple_empty(file_dentry(file))) + return -ENOTEMPTY; + + new |= S_CASEFOLD; + } else if (old & S_CASEFOLD) { + if (!simple_empty(file_dentry(file))) + return -ENOTEMPTY; + } + + ret = mnt_want_write_file(file); + if (ret) + return ret; + + inode_lock(inode); + + ret = vfs_ioc_setflags_prepare(inode, old, new); + if (ret) { + inode_unlock(inode); + mnt_drop_write_file(file); + return ret; + } + + inode_set_flags(inode, new, TMPFS_FLS); + + inode_unlock(inode); + mnt_drop_write_file(file); + return 0; + + default: + return -ENOTTY; + } + + return 0; +} + static int shmem_statfs(struct dentry *dentry, struct kstatfs *buf) { struct shmem_sb_info *sbinfo = SHMEM_SB(dentry->d_sb); @@ -3916,6 +3987,7 @@ static const struct file_operations shmem_file_operations = { .splice_read = generic_file_splice_read, .splice_write = iter_file_splice_write, .fallocate = shmem_fallocate, + .unlocked_ioctl = shmem_ioctl, #endif }; @@ -3928,6 +4000,16 @@ static const struct inode_operations shmem_inode_operations = { #endif }; +static const struct file_operations shmem_dir_operations = { + .open = dcache_dir_open, + .release = dcache_dir_close, + .llseek = dcache_dir_lseek, + .read = generic_read_dir, + .iterate_shared = dcache_readdir, + .fsync = noop_fsync, + .unlocked_ioctl = shmem_ioctl, +}; + static const struct inode_operations shmem_dir_inode_operations = { #ifdef CONFIG_TMPFS .create = shmem_create, -- 2.31.0