From patchwork Thu Aug 3 02:31:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: zhanchengbin X-Patchwork-Id: 1816276 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=ozlabs.org (client-ip=2404:9400:2221:ea00::3; helo=gandalf.ozlabs.org; envelope-from=srs0=4ara=du=vger.kernel.org=linux-ext4-owner@ozlabs.org; receiver=) Received: from gandalf.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RGY023SyCz1ybS for ; Thu, 3 Aug 2023 12:37:06 +1000 (AEST) Received: from gandalf.ozlabs.org (mail.ozlabs.org [IPv6:2404:9400:2221:ea00::3]) by gandalf.ozlabs.org (Postfix) with ESMTP id 4RGXzs4q3kz4wqW for ; Thu, 3 Aug 2023 12:36:57 +1000 (AEST) Received: by gandalf.ozlabs.org (Postfix) id 4RGXzs4mRfz4wqX; Thu, 3 Aug 2023 12:36:57 +1000 (AEST) Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: gandalf.ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=huawei.com Authentication-Results: gandalf.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2620:137:e000::1:20; helo=out1.vger.email; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=ozlabs.org) Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by gandalf.ozlabs.org (Postfix) with ESMTP id 4RGXzs4hCnz4wqW for ; Thu, 3 Aug 2023 12:36:57 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231490AbjHCCg4 (ORCPT ); Wed, 2 Aug 2023 22:36:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54232 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232802AbjHCCgg (ORCPT ); Wed, 2 Aug 2023 22:36:36 -0400 Received: from szxga02-in.huawei.com (szxga02-in.huawei.com [45.249.212.188]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E67E75592 for ; Wed, 2 Aug 2023 19:34:50 -0700 (PDT) Received: from dggpeml500016.china.huawei.com (unknown [172.30.72.53]) by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4RGXsJ3TrwzNmfN; Thu, 3 Aug 2023 10:31:16 +0800 (CST) Received: from huawei.com (10.175.127.227) by dggpeml500016.china.huawei.com (7.185.36.70) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Thu, 3 Aug 2023 10:34:42 +0800 From: zhanchengbin To: CC: , , , , , , zhanchengbin , kernel test robot Subject: [RFC PATCH v2 1/2] ext4: ioctl adds a framework for modifying superblock parameters Date: Thu, 3 Aug 2023 10:31:27 +0800 Message-ID: <20230803023128.35170-2-zhanchengbin1@huawei.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20230803023128.35170-1-zhanchengbin1@huawei.com> References: <20230803023128.35170-1-zhanchengbin1@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.127.227] X-ClientProxiedBy: dggems704-chm.china.huawei.com (10.3.19.181) To dggpeml500016.china.huawei.com (7.185.36.70) X-CFilter-Loop: Reflected X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_MED, RCVD_IN_MSPIKE_H5,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org A framework for modifying attrs in the super block is added here, including the check and set of attrs in the super block, and it will be very convenient to add new parameter modifications later. When in use, pass in ext4_sbattrs to the kernel mode, and ext4_sbattrs->sba_attrs contains attrs that need to be modified one by one. It is guaranteed that all variables in one call are modified atomically. Link: https://lore.kernel.org/linux-ext4/29f6134f-ba0a-d601-0a5a-ad2b5e9bbf1d@huawei.com/ Signed-off-by: zhanchengbin Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202308030412.jMcaYq0E-lkp@intel.com/ --- fs/ext4/ext4.h | 12 ++++ fs/ext4/ioctl.c | 127 ++++++++++++++++++++++++++++++++++++++ include/uapi/linux/ext4.h | 26 ++++++++ 3 files changed, 165 insertions(+) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 0a2d55faa095..461d8bbe1e70 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -3823,6 +3823,18 @@ static inline int ext4_buffer_uptodate(struct buffer_head *bh) return buffer_uptodate(bh); } +struct ext4_ksbattrs { + __u32 sba_count; + struct ext4_sbattr *sba_attrs[]; +}; + +struct ext4_sbattr_operation { + int sb_attr_key; + int (*sb_attr_check)(struct ext4_sbattr *p_sbattr); + void (*sb_attr_set)(struct ext4_super_block *es, const void *arg); +}; + + #endif /* __KERNEL__ */ #define EFSBADCRC EBADMSG /* Bad CRC detected */ diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index 331859511f80..76653d855073 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c @@ -30,6 +30,13 @@ typedef void ext4_update_sb_callback(struct ext4_super_block *es, const void *arg); +/* + * Check and modify functions for each superblock variable + */ +struct ext4_sbattr_operation ext4_sbattr_ops[] = { + {EXT4_IOC_SUPERBLOCK_KEY_MAX, NULL, NULL}, +}; + /* * Superblock modification callback function for changing file system * label @@ -51,6 +58,18 @@ static void ext4_sb_setuuid(struct ext4_super_block *es, const void *arg) memcpy(es->s_uuid, (__u8 *)arg, UUID_SIZE); } +static void ext4_sb_set_superblock_attr(struct ext4_super_block *es, const void *arg) +{ + struct ext4_ksbattrs *p_sbattrs = (struct ext4_ksbattrs *)arg; + struct ext4_sbattr *p_sbattr; + int count; + + for (count = 0; count < p_sbattrs->sba_count; count++) { + p_sbattr = p_sbattrs->sba_attrs[count]; + ext4_sbattr_ops[p_sbattr->sba_key].sb_attr_set(es, p_sbattr); + } +} + static int ext4_update_primary_sb(struct super_block *sb, handle_t *handle, ext4_update_sb_callback func, @@ -1220,6 +1239,112 @@ static int ext4_ioctl_setuuid(struct file *filp, return ret; } +/* + * Check the key-value pairs passed in from the user mode and assign it + * to the super block + */ +static int ext4_ioctl_set_superblock_attr(struct file *filp, + const struct ext4_sbattrs __user *usbattrs) +{ + int ret = 0; + struct super_block *sb = file_inode(filp)->i_sb; + struct ext4_sbattrs sbattrs, *p_sbattrs = NULL; + struct ext4_ksbattrs *p_ksbattrs = NULL; + struct ext4_sbattr sbattr, *p_sbattr = NULL; + size_t size; + int count = 0; + + if (!capable(CAP_SYS_ADMIN)) { + ret = -EPERM; + goto failed; + } + + if (copy_from_user(&sbattrs, usbattrs, sizeof(sbattrs))) { + ret = -EFAULT; + goto failed; + } + + if (sbattrs.sba_count > EXT4_SBATTR_MAX_COUNT) { + ret = -EINVAL; + goto failed; + } + size = sizeof(sbattrs) + sbattrs.sba_count * sizeof(struct ext4_sbarrt *); + + p_sbattrs = kmalloc(size, GFP_KERNEL); + if (p_sbattrs == NULL) { + ret = -ENOMEM; + goto failed; + } + + if (copy_from_user(p_sbattrs, usbattrs, size)) { + ret = -EFAULT; + goto failed; + } + + p_ksbattrs = kzalloc(size, GFP_KERNEL); + if (p_ksbattrs == NULL) { + ret = -ENOMEM; + goto failed; + } + p_ksbattrs->sba_count = p_sbattrs->sba_count; + + while (count < p_sbattrs->sba_count) { + if (copy_from_user(&sbattr, p_sbattrs->sba_attrs[count], sizeof(sbattr))) { + ret = -EFAULT; + goto failed; + } + + size = sizeof(sbattr) + sbattr.sba_len * sizeof(char); + if (size > PAGE_SIZE) { + ret = -EINVAL; + goto failed; + } + + if (sbattr.sba_key >= EXT4_IOC_SUPERBLOCK_KEY_MAX) { + ret = -EINVAL; + goto failed; + } + + p_sbattr = kmalloc(size, GFP_KERNEL); + if (p_sbattr == NULL) { + ret = -ENOMEM; + goto failed; + } + + p_ksbattrs->sba_attrs[count] = p_sbattr; + + if (copy_from_user(p_sbattr, p_sbattrs->sba_attrs[count], size)) { + ret = -EFAULT; + goto failed; + } + + /* Check the validity of key-value pairs */ + ret = ext4_sbattr_ops[sbattr.sba_key].sb_attr_check(p_sbattr); + if (ret) + goto failed; + + count++; + } + + ret = mnt_want_write_file(filp); + if (ret) + goto failed; + + ret = ext4_update_superblocks_fn(sb, ext4_sb_set_superblock_attr, p_ksbattrs); + mnt_drop_write_file(filp); + +failed: + kfree(p_sbattrs); + + if (p_ksbattrs) { + for (count = 0; count < p_ksbattrs->sba_count; count++) + kfree(p_ksbattrs->sba_attrs[count]); + kfree(p_ksbattrs); + } + + return ret; +} + static long __ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { struct inode *inode = file_inode(filp); @@ -1607,6 +1732,8 @@ static long __ext4_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) return ext4_ioctl_getuuid(EXT4_SB(sb), (void __user *)arg); case EXT4_IOC_SETFSUUID: return ext4_ioctl_setuuid(filp, (const void __user *)arg); + case EXT4_IOC_SET_SUPERBLOCK_ATTR: + return ext4_ioctl_set_superblock_attr(filp, (const void __user *)arg); default: return -ENOTTY; } diff --git a/include/uapi/linux/ext4.h b/include/uapi/linux/ext4.h index 1c4c2dd29112..79b5a751b83e 100644 --- a/include/uapi/linux/ext4.h +++ b/include/uapi/linux/ext4.h @@ -33,6 +33,7 @@ #define EXT4_IOC_CHECKPOINT _IOW('f', 43, __u32) #define EXT4_IOC_GETFSUUID _IOR('f', 44, struct fsuuid) #define EXT4_IOC_SETFSUUID _IOW('f', 44, struct fsuuid) +#define EXT4_IOC_SET_SUPERBLOCK_ATTR _IOW('f', 45, struct ext4_sbattrs) #define EXT4_IOC_SHUTDOWN _IOR('X', 125, __u32) @@ -69,6 +70,31 @@ EXT4_IOC_CHECKPOINT_FLAG_ZEROOUT | \ EXT4_IOC_CHECKPOINT_FLAG_DRY_RUN) +/* + * Structure for EXT4_IOC_SET_SUPERBLOCK_ATTR + */ +struct ext4_sbattrs { + __u32 sba_count; /* attrs number */ + struct ext4_sbattr __user *sba_attrs[]; +}; + +/* + * key for attr's magic in superblock + * len for attr's size in superblock + * value for attr's value in superblock + */ +struct ext4_sbattr { + __u32 sba_key; + __u32 sba_len; + char sba_value[]; +}; + +enum ext4_ioc_superblock_key { + EXT4_IOC_SUPERBLOCK_KEY_MAX = 0, +}; + +#define EXT4_SBATTR_MAX_COUNT 20 + /* * Structure for EXT4_IOC_GETFSUUID/EXT4_IOC_SETFSUUID */ From patchwork Thu Aug 3 02:31:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: zhanchengbin X-Patchwork-Id: 1816273 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=ozlabs.org (client-ip=150.107.74.76; helo=gandalf.ozlabs.org; envelope-from=srs0=4ara=du=vger.kernel.org=linux-ext4-owner@ozlabs.org; receiver=) Received: from gandalf.ozlabs.org (gandalf.ozlabs.org [150.107.74.76]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RGXzx4Fwtz1ybS for ; Thu, 3 Aug 2023 12:37:01 +1000 (AEST) Received: from gandalf.ozlabs.org (gandalf.ozlabs.org [150.107.74.76]) by gandalf.ozlabs.org (Postfix) with ESMTP id 4RGXzx0jcmz4wxW for ; Thu, 3 Aug 2023 12:37:01 +1000 (AEST) Received: by gandalf.ozlabs.org (Postfix) id 4RGXzx0g53z4wxm; Thu, 3 Aug 2023 12:37:01 +1000 (AEST) Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: gandalf.ozlabs.org; dmarc=fail (p=quarantine dis=none) header.from=huawei.com Authentication-Results: gandalf.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=2620:137:e000::1:20; helo=out1.vger.email; envelope-from=linux-ext4-owner@vger.kernel.org; receiver=ozlabs.org) Received: from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20]) by gandalf.ozlabs.org (Postfix) with ESMTP id 4RGXzx0ZvFz4wxW for ; Thu, 3 Aug 2023 12:37:01 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233740AbjHCChA (ORCPT ); Wed, 2 Aug 2023 22:37:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53816 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231851AbjHCCgh (ORCPT ); Wed, 2 Aug 2023 22:36:37 -0400 Received: from szxga01-in.huawei.com (szxga01-in.huawei.com [45.249.212.187]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1DB534215 for ; Wed, 2 Aug 2023 19:34:52 -0700 (PDT) Received: from dggpeml500016.china.huawei.com (unknown [172.30.72.56]) by szxga01-in.huawei.com (SkyGuard) with ESMTP id 4RGXsN42QWztRjG; Thu, 3 Aug 2023 10:31:20 +0800 (CST) Received: from huawei.com (10.175.127.227) by dggpeml500016.china.huawei.com (7.185.36.70) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Thu, 3 Aug 2023 10:34:42 +0800 From: zhanchengbin To: CC: , , , , , , zhanchengbin , kernel test robot Subject: [RFC PATCH v2 2/2] ext4: ioctl add EXT4_IOC_SUPERBLOCK_KEY_S_ERRORS Date: Thu, 3 Aug 2023 10:31:28 +0800 Message-ID: <20230803023128.35170-3-zhanchengbin1@huawei.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20230803023128.35170-1-zhanchengbin1@huawei.com> References: <20230803023128.35170-1-zhanchengbin1@huawei.com> MIME-Version: 1.0 X-Originating-IP: [10.175.127.227] X-ClientProxiedBy: dggems704-chm.china.huawei.com (10.3.19.181) To dggpeml500016.china.huawei.com (7.185.36.70) X-CFilter-Loop: Reflected X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_MED, RCVD_IN_MSPIKE_H5,RCVD_IN_MSPIKE_WL,SPF_HELO_NONE,SPF_PASS, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org Added modifications to s_errors in the modification framework of superblock's attrs. There is no lock protection when the user mode operates on the same block, so I modify the s_errors by the modification framework of superblock's attrs. The parameters passed in from the user mode will be checked by sb_attr_errors_check first, if the check is passed, It will call buffer_lock in ext4_update_superblocks_fn and use sb_attr_errors_set, so it can ensure the atomicity of a modification. Signed-off-by: zhanchengbin Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202308021801.ieUVR2xl-lkp@intel.com/ --- fs/ext4/ioctl.c | 22 ++++++++++++++++++++++ include/uapi/linux/ext4.h | 4 +++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index 76653d855073..4053a038da0a 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c @@ -30,10 +30,32 @@ typedef void ext4_update_sb_callback(struct ext4_super_block *es, const void *arg); +static int sb_attr_errors_check(struct ext4_sbattr *p_sbattr) +{ + __u16 error_behavior = *(__u16 *)(p_sbattr->sba_value); + + if (p_sbattr->sba_len != EXT4_IOC_SUPERBLOCK_LEN_S_ERRORS) + return -EINVAL; + + if (error_behavior < EXT4_ERRORS_CONTINUE || + error_behavior > EXT4_ERRORS_PANIC) + return -EINVAL; + + return 0; +} + +static void sb_attr_errors_set(struct ext4_super_block *es, const void *arg) +{ + struct ext4_sbattr *p_sbattr = (struct ext4_sbattr *)arg; + + es->s_errors = cpu_to_le16(*(__u16 *)p_sbattr->sba_value); +} + /* * Check and modify functions for each superblock variable */ struct ext4_sbattr_operation ext4_sbattr_ops[] = { + {EXT4_IOC_SUPERBLOCK_KEY_S_ERRORS, sb_attr_errors_check, sb_attr_errors_set}, {EXT4_IOC_SUPERBLOCK_KEY_MAX, NULL, NULL}, }; diff --git a/include/uapi/linux/ext4.h b/include/uapi/linux/ext4.h index 79b5a751b83e..f5429630343e 100644 --- a/include/uapi/linux/ext4.h +++ b/include/uapi/linux/ext4.h @@ -90,8 +90,10 @@ struct ext4_sbattr { }; enum ext4_ioc_superblock_key { - EXT4_IOC_SUPERBLOCK_KEY_MAX = 0, + EXT4_IOC_SUPERBLOCK_KEY_S_ERRORS = 0, + EXT4_IOC_SUPERBLOCK_KEY_MAX, }; +#define EXT4_IOC_SUPERBLOCK_LEN_S_ERRORS 2 #define EXT4_SBATTR_MAX_COUNT 20