From nobody Wed Apr 29 00:43:43 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3277CC433EF for ; Thu, 26 May 2022 13:41:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S245488AbiEZNlj (ORCPT ); Thu, 26 May 2022 09:41:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41436 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S243990AbiEZNlh (ORCPT ); Thu, 26 May 2022 09:41:37 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 25E64C66 for ; Thu, 26 May 2022 06:41:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1653572494; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=cPpYHnXIBZc98vfrpGPPeNO4G+nbrOWi/rqlDfKtk/c=; b=X/laqBFRVhv6WlhxpVRLhAsz0uohm0B6J6bLbFj4M4EZe3uLrghPf56sUxkd3MW+QgS9YL 9wtB7ktGLe9WIa6a6scE0uVJalXX5nsEZzstV0dlfRqkxxQD5Rs1rRdzv8znRAPddDBd5W B3VUBIHBfSy3kuFzDKTM7RicjSm3iz8= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-628-tGYkW9k3MCWUHF6gsBxOEw-1; Thu, 26 May 2022 09:41:33 -0400 X-MC-Unique: tGYkW9k3MCWUHF6gsBxOEw-1 Received: by mail-wr1-f69.google.com with SMTP id s14-20020adfa28e000000b0020ac7532f08so268948wra.15 for ; Thu, 26 May 2022 06:41:33 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=cPpYHnXIBZc98vfrpGPPeNO4G+nbrOWi/rqlDfKtk/c=; b=WQAjkjL+FGsEZ5ByC4c1/oxuNX2ZSRwEKTamgiLadCxWbVJI5zS0OtaGEf3sRgDoOg 0OaCtM6EdcdKvJJOkm78l1d+eKqXV3vgjoRuOKb2pTSetWxuxk7Wkoo0C7aEcIpfeLpX DDsDq1RpVeizl4djLh+43biDnucMRBjdUUgHpUeYNppNS+goGNgKZQW9qJ+1/NnDqAB6 ya1Kx53pw8sMIGMZx0+dvfjWYh6ZTvU/yQAohp/5H9oUQEoWPk8JdR+e43zRLuJsrbGT DLZNGJq18EEZVMDRZAaWJr/HHC5w4Z9mKScwiwnt+b/gurdKU3jbsXwpXHB9F/MZzBEH vXXw== X-Gm-Message-State: AOAM531YjjS10LyNA/lLALKfbfH3O+PIKedQ8eI8cz4WQAyRedzlFX9a WrdUgllgalc8XovoqCG9lZJGQVnpffoL7kcs6sF2hAz1GYTALX5Y5iamWBmZBsP50VnTNxME7w4 7FQzuITPs9Dcixbd70AYdg/DwQtuFxkgd+CtA5oT+M8Civz3qhRO2PHsByFoPu5CefCuuIlti8k 4= X-Received: by 2002:a5d:6daf:0:b0:20f:f1e7:c720 with SMTP id u15-20020a5d6daf000000b0020ff1e7c720mr10535508wrs.584.1653572491881; Thu, 26 May 2022 06:41:31 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwVYTuz6x/5UvuRXjQeFp4kffPnv1D04L8SNOA7VUlENyLLGoULl5N/3tWbwS2OIqt7VfQu5Q== X-Received: by 2002:a5d:6daf:0:b0:20f:f1e7:c720 with SMTP id u15-20020a5d6daf000000b0020ff1e7c720mr10535483wrs.584.1653572491600; Thu, 26 May 2022 06:41:31 -0700 (PDT) Received: from minerva.home (205.pool92-176-231.dynamic.orange.es. [92.176.231.205]) by smtp.gmail.com with ESMTPSA id h6-20020a5d5046000000b0020c547f75easm1765022wrt.101.2022.05.26.06.41.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 26 May 2022 06:41:31 -0700 (PDT) From: Javier Martinez Canillas To: linux-kernel@vger.kernel.org Cc: Christian Kellner , Muhammad Usama Anjum , Alexander Larsson , Alberto Ruiz , Peter Jones , Lennart Poettering , Colin Walters , Chung-Chiang Cheng , Javier Martinez Canillas , OGAWA Hirofumi Subject: [PATCH v3 1/3] fat: add a vfat_rename2() and make existing .rename callback a helper Date: Thu, 26 May 2022 15:41:17 +0200 Message-Id: <20220526134119.242182-2-javierm@redhat.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220526134119.242182-1-javierm@redhat.com> References: <20220526134119.242182-1-javierm@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Currently vfat only supports the RENAME_NOREPLACE flag which is handled by the virtual file system layer but doesn't support the RENAME_EXCHANGE flag. Add a vfat_rename2() function to be used as the .rename callback and move the current vfat_rename() handler to a helper. This is in preparation for implementing the RENAME_NOREPLACE flag using a different helper function. Signed-off-by: Javier Martinez Canillas --- (no changes since v1) fs/fat/namei_vfat.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index c573314806cf..88ccb2ee3537 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c @@ -889,9 +889,8 @@ static int vfat_mkdir(struct user_namespace *mnt_userns= , struct inode *dir, return err; } =20 -static int vfat_rename(struct user_namespace *mnt_userns, struct inode *ol= d_dir, - struct dentry *old_dentry, struct inode *new_dir, - struct dentry *new_dentry, unsigned int flags) +static int vfat_rename(struct inode *old_dir, struct dentry *old_dentry, + struct inode *new_dir, struct dentry *new_dentry) { struct buffer_head *dotdot_bh; struct msdos_dir_entry *dotdot_de; @@ -902,9 +901,6 @@ static int vfat_rename(struct user_namespace *mnt_usern= s, struct inode *old_dir, int err, is_dir, update_dotdot, corrupt =3D 0; struct super_block *sb =3D old_dir->i_sb; =20 - if (flags & ~RENAME_NOREPLACE) - return -EINVAL; - old_sinfo.bh =3D sinfo.bh =3D dotdot_bh =3D NULL; old_inode =3D d_inode(old_dentry); new_inode =3D d_inode(new_dentry); @@ -1021,13 +1017,24 @@ static int vfat_rename(struct user_namespace *mnt_u= serns, struct inode *old_dir, goto out; } =20 +static int vfat_rename2(struct user_namespace *mnt_userns, struct inode *o= ld_dir, + struct dentry *old_dentry, struct inode *new_dir, + struct dentry *new_dentry, unsigned int flags) +{ + if (flags & ~RENAME_NOREPLACE) + return -EINVAL; + + /* VFS already handled RENAME_NOREPLACE, handle it as a normal rename */ + return vfat_rename(old_dir, old_dentry, new_dir, new_dentry); +} + static const struct inode_operations vfat_dir_inode_operations =3D { .create =3D vfat_create, .lookup =3D vfat_lookup, .unlink =3D vfat_unlink, .mkdir =3D vfat_mkdir, .rmdir =3D vfat_rmdir, - .rename =3D vfat_rename, + .rename =3D vfat_rename2, .setattr =3D fat_setattr, .getattr =3D fat_getattr, .update_time =3D fat_update_time, --=20 2.36.1 From nobody Wed Apr 29 00:43:43 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1F242C433EF for ; Thu, 26 May 2022 13:42:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1343909AbiEZNl6 (ORCPT ); Thu, 26 May 2022 09:41:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41646 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344624AbiEZNll (ORCPT ); Thu, 26 May 2022 09:41:41 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 1D7F5D5B for ; Thu, 26 May 2022 06:41:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1653572498; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=xz869cX5K5CXp5x1mskXe6licPQenMVKhOFszIG412s=; b=fsxti0ef8pxm0SzP0UY4Jnz5JqeNzOlnDVsh3ymLQW8rohiLzNZzXjdhIFJIDBDFyYZB2b crldTSEnMb6gBJ254SV67vZkKgLED1pDG4hUibnLSGn02KVQXC6+HWxsu7EIzNoBBLYmK3 mnehGAFUjbQYPxvmMBvP8TR8GH6VBOw= Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-15-9z8noiHDPvCYOYjmAhTrbw-1; Thu, 26 May 2022 09:41:34 -0400 X-MC-Unique: 9z8noiHDPvCYOYjmAhTrbw-1 Received: by mail-wr1-f71.google.com with SMTP id e24-20020a5d5958000000b0020ffd1d62b2so270030wri.17 for ; Thu, 26 May 2022 06:41:34 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=xz869cX5K5CXp5x1mskXe6licPQenMVKhOFszIG412s=; b=7Pia+zHNarmT24wLfdP02wIN4sTjoo/34NCDMVAkS/IOy6gN75cuXvcRyFnS0T7hUI fZvmcX8V8D+hLcnublEQmMt/UZ4Yup9WNzlEMkaqkRyAGLi+UI/z2zyATKcczEkuGaHr VCNlDhtsYnYi7KJXEYPoVXiAWpOuQt4kUQgSm8XZ8vGl+09neNVqZprLvZ/of1oCts0b 9dyQ2fHFaEA7AMGU/Ibzek+MsL0mnHKBd8ALjTypjNjtvlU5+IPNV7LvxTkYZH9DW4hY +oHh1xAbNpklKf2Z9MpYI0X396UJLGC6cT71VnRGqOqNzUe3uLkaPjaW7v4J6RPH1yZ6 OdSg== X-Gm-Message-State: AOAM530n70PYbXAr4UshfW/Hi6tDwkLZGRz6IZjLjXJ8rRCI6WL1qJdV mlPMF/IESDmHykcujhMcNrelzo8pbLHtWOdXIX2KoZ1mKw+GVsga26ptiNtTrfCbQhVAZFiW+kQ qY2OTysBYaeWXOA4iwHCO2BE2BS/l0ByxhS8N6q1XWLtmOwpUhwo9V4fAqsdg35qoqz8bYHDycr s= X-Received: by 2002:a05:600c:350f:b0:397:7204:ce8e with SMTP id h15-20020a05600c350f00b003977204ce8emr2459318wmq.0.1653572493179; Thu, 26 May 2022 06:41:33 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxhvdL5xR1GCFTYP0T/+AyiS182c45K+C1HH8bDLOBnINXuGbuIlcmnepA5uBLi2mV8f41Diw== X-Received: by 2002:a05:600c:350f:b0:397:7204:ce8e with SMTP id h15-20020a05600c350f00b003977204ce8emr2459290wmq.0.1653572492866; Thu, 26 May 2022 06:41:32 -0700 (PDT) Received: from minerva.home (205.pool92-176-231.dynamic.orange.es. [92.176.231.205]) by smtp.gmail.com with ESMTPSA id h6-20020a5d5046000000b0020c547f75easm1765022wrt.101.2022.05.26.06.41.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 26 May 2022 06:41:32 -0700 (PDT) From: Javier Martinez Canillas To: linux-kernel@vger.kernel.org Cc: Christian Kellner , Muhammad Usama Anjum , Alexander Larsson , Alberto Ruiz , Peter Jones , Lennart Poettering , Colin Walters , Chung-Chiang Cheng , Javier Martinez Canillas , OGAWA Hirofumi Subject: [PATCH v3 2/3] fat: add renameat2 RENAME_EXCHANGE flag support Date: Thu, 26 May 2022 15:41:18 +0200 Message-Id: <20220526134119.242182-3-javierm@redhat.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220526134119.242182-1-javierm@redhat.com> References: <20220526134119.242182-1-javierm@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" The renameat2 RENAME_EXCHANGE flag allows to atomically exchange two paths but is currently not supported by the Linux vfat filesystem driver. Add a vfat_rename_exchange() helper function that implements this support. The super block lock is acquired during the operation to ensure atomicity, and in the error path actions made are reversed also with the mutex held. It makes the operation as transactional as possible, within the limitation impossed by vfat due not having a journal with logs to replay. Signed-off-by: Javier Martinez Canillas --- (no changes since v2) Changes in v2: - Only update the new_dir inode version and timestamps if !=3D old_dir (Alex Larsson). - Add some helper functions to avoid duplicating code (OGAWA Hirofumi). - Use braces for multi-lines blocks even if are one statement (OGAWA Hirofu= mi). - Mention in commit message that the operation is as transactional as possi= ble but within the vfat limitations of not having a journal (Colin Walters). fs/fat/namei_vfat.c | 174 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 173 insertions(+), 1 deletion(-) diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index 88ccb2ee3537..97caec8c5207 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c @@ -1017,13 +1017,185 @@ static int vfat_rename(struct inode *old_dir, stru= ct dentry *old_dentry, goto out; } =20 +/* Helpers for vfat_rename_exchange() */ + +static int vfat_get_dotdot_info(struct inode *inode, struct buffer_head **= dotdot_bh, + struct msdos_dir_entry **dotdot_de) +{ + if (!S_ISDIR(inode->i_mode)) + return 0; + + return fat_get_dotdot_entry(inode, dotdot_bh, dotdot_de); +} + +static void vfat_exchange_dentries(struct inode *old_inode, struct inode *= new_inode, + loff_t old_i_pos, loff_t new_i_pos) +{ + fat_detach(old_inode); + fat_detach(new_inode); + + fat_attach(old_inode, new_i_pos); + fat_attach(new_inode, old_i_pos); +} + +static int vfat_sync_after_exchange(struct inode *dir, struct inode *inode) +{ + int err =3D 0; + + if (IS_DIRSYNC(dir)) + err =3D fat_sync_inode(inode); + else + mark_inode_dirty(inode); + + return err; +} + +static int vfat_update_dotdot_info(struct buffer_head *dotdot_bh, struct m= sdos_dir_entry *dotdot_de, + struct inode *dir, struct inode *inode) +{ + int err =3D 0; + + fat_set_start(dotdot_de, MSDOS_I(dir)->i_logstart); + mark_buffer_dirty_inode(dotdot_bh, inode); + + if (IS_DIRSYNC(dir)) + err =3D sync_dirty_buffer(dotdot_bh); + + return err; +} + +static void vfat_update_dir_metadata(struct inode *dir, struct timespec64 = *ts) +{ + inode_inc_iversion(dir); + fat_truncate_time(dir, ts, S_CTIME | S_MTIME); + + if (IS_DIRSYNC(dir)) + (void)fat_sync_inode(dir); + else + mark_inode_dirty(dir); +} + +static int vfat_rename_exchange(struct inode *old_dir, struct dentry *old_= dentry, + struct inode *new_dir, struct dentry *new_dentry) +{ + struct buffer_head *old_dotdot_bh =3D NULL, *new_dotdot_bh =3D NULL; + struct msdos_dir_entry *old_dotdot_de =3D NULL, *new_dotdot_de =3D NULL; + struct inode *old_inode, *new_inode; + struct timespec64 ts =3D current_time(old_dir); + loff_t old_i_pos, new_i_pos; + int err, corrupt =3D 0; + struct super_block *sb =3D old_dir->i_sb; + + old_inode =3D d_inode(old_dentry); + new_inode =3D d_inode(new_dentry); + + /* Acquire super block lock for the operation to be atomic */ + mutex_lock(&MSDOS_SB(sb)->s_lock); + + /* if directories are not the same, get ".." info to update */ + if (old_dir !=3D new_dir) { + err =3D vfat_get_dotdot_info(old_inode, &old_dotdot_bh, &old_dotdot_de); + if (err) + goto out; + + err =3D vfat_get_dotdot_info(new_inode, &new_dotdot_bh, &new_dotdot_de); + if (err) + goto out; + } + + old_i_pos =3D MSDOS_I(old_inode)->i_pos; + new_i_pos =3D MSDOS_I(new_inode)->i_pos; + + /* exchange the two dentries */ + vfat_exchange_dentries(old_inode, new_inode, old_i_pos, new_i_pos); + + err =3D vfat_sync_after_exchange(old_dir, new_inode); + if (err) + goto error_exchange; + + err =3D vfat_sync_after_exchange(new_dir, old_inode); + if (err) + goto error_exchange; + + /* update ".." directory entry info */ + if (old_dotdot_de) { + err =3D vfat_update_dotdot_info(old_dotdot_bh, old_dotdot_de, new_dir, o= ld_inode); + if (err) + goto error_old_dotdot; + + drop_nlink(old_dir); + inc_nlink(new_dir); + } + + if (new_dotdot_de) { + err =3D vfat_update_dotdot_info(new_dotdot_bh, new_dotdot_de, old_dir, n= ew_inode); + if (err) + goto error_new_dotdot; + + drop_nlink(new_dir); + inc_nlink(old_dir); + } + + /* update inode version and timestamps */ + inode_inc_iversion(old_inode); + inode_inc_iversion(new_inode); + + vfat_update_dir_metadata(old_dir, &ts); + + /* if directories are not the same, update new_dir as well */ + if (old_dir !=3D new_dir) + vfat_update_dir_metadata(new_dir, &ts); +out: + brelse(old_dotdot_bh); + brelse(new_dotdot_bh); + mutex_unlock(&MSDOS_SB(sb)->s_lock); + + return err; + +error_new_dotdot: + /* data cluster is shared, serious corruption */ + corrupt =3D 1; + + if (new_dotdot_de) { + corrupt |=3D vfat_update_dotdot_info(new_dotdot_bh, new_dotdot_de, + new_dir, new_inode); + } + +error_old_dotdot: + /* data cluster is shared, serious corruption */ + corrupt =3D 1; + + if (old_dotdot_de) { + corrupt |=3D vfat_update_dotdot_info(old_dotdot_bh, old_dotdot_de, + old_dir, old_inode); + } + +error_exchange: + vfat_exchange_dentries(old_inode, new_inode, new_i_pos, old_i_pos); + + if (corrupt) { + corrupt |=3D fat_sync_inode(old_inode); + corrupt |=3D fat_sync_inode(new_inode); + } + + if (corrupt < 0) { + fat_fs_error(new_dir->i_sb, + "%s: Filesystem corrupted (i_pos %lld, %lld)", + __func__, old_i_pos, new_i_pos); + } + goto out; +} + static int vfat_rename2(struct user_namespace *mnt_userns, struct inode *o= ld_dir, struct dentry *old_dentry, struct inode *new_dir, struct dentry *new_dentry, unsigned int flags) { - if (flags & ~RENAME_NOREPLACE) + if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE)) return -EINVAL; =20 + if (flags & RENAME_EXCHANGE) + return vfat_rename_exchange(old_dir, old_dentry, new_dir, new_dentry); + /* VFS already handled RENAME_NOREPLACE, handle it as a normal rename */ return vfat_rename(old_dir, old_dentry, new_dir, new_dentry); } --=20 2.36.1 From nobody Wed Apr 29 00:43:43 2026 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 vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D5E18C433F5 for ; Thu, 26 May 2022 13:42:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345292AbiEZNmF (ORCPT ); Thu, 26 May 2022 09:42:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41648 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1344645AbiEZNll (ORCPT ); Thu, 26 May 2022 09:41:41 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id C871713F for ; Thu, 26 May 2022 06:41:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1653572498; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=RzJPqz0kjhM05tfVcWUDXOjhqjYpXjYlJDf77Kz4GBo=; b=HHjzBN5jXzKr2pmN142yBX7GhMl9n3/+hR7f1uvOQyAlSrIIzMtJcVye2RbWlya6svkzdc sOGX60j4tUebBbXM8nifjcsybXL9mZbaFmgGIqcPzmpw3WM/DQJpajTUVpMkTWGzahZ7ht s99I9MRrnsNI1uI46wjMGuT9s75FNNE= Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-56-Frp9R4PyO9CxYZH5gtBXaw-1; Thu, 26 May 2022 09:41:37 -0400 X-MC-Unique: Frp9R4PyO9CxYZH5gtBXaw-1 Received: by mail-wr1-f71.google.com with SMTP id q10-20020adfcd8a000000b0020ff96b68c2so267358wrj.19 for ; Thu, 26 May 2022 06:41:36 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=RzJPqz0kjhM05tfVcWUDXOjhqjYpXjYlJDf77Kz4GBo=; b=a6Au/F2gkNLvQosmeaE+MHm5Ov0Q3uO/X9E+mFDBqdYvQ+3GtF/Jrnjttyxl9uoFgL 9YrzobgIqN/s5F7gg6YpFeZbDHgcZXt2xAIzeQ6k1AhRFNfomupZMXIZ9qN7W94/STfy 5aAwltdRpBEsbxBjx5pemN0X8/yt8/HX5LBTGkq7UhYSb6ROr8jdoDdkM2zQKT5kU2iL XCXWKhhl5aDKRM1SyScYuP99ueBAVawQITJCcB/7bOBZYS4PIq0XxXA0OKOOs5uhwABv B0Mr14+D2QvX/xofvK1DrlueBKV2+qDVJ0X/dxceX2RaPs7NRFSb+Jn2Zd6gQSEPoVKR wasw== X-Gm-Message-State: AOAM531erPlnD+1wMK1d6E46/kA+WKQWNFHBs5Vzo82IFbQ6XJ3tffs4 F6fsDohb87H3h78EG1AbLI73GKrsP9KT4IFFUcL4p5GYftU1SwJxF9Xf7C1vV0z6UCxtS13VelK jcsfrZj7/YGUSC4k4Nh746mLYWE4pNvuf0dHwcROIYLRISA54fXcU+5CzvaCLOV3AHZ/mclgfKE k= X-Received: by 2002:adf:d08a:0:b0:20d:1029:4957 with SMTP id y10-20020adfd08a000000b0020d10294957mr30009016wrh.55.1653572494670; Thu, 26 May 2022 06:41:34 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyMQ9r3iwb05ARiit0mMex4XwxgHBvORhJCrt3DWHzbRI7/F8M6gDeuxisuXeST93eJMDcBcQ== X-Received: by 2002:adf:d08a:0:b0:20d:1029:4957 with SMTP id y10-20020adfd08a000000b0020d10294957mr30008986wrh.55.1653572494274; Thu, 26 May 2022 06:41:34 -0700 (PDT) Received: from minerva.home (205.pool92-176-231.dynamic.orange.es. [92.176.231.205]) by smtp.gmail.com with ESMTPSA id h6-20020a5d5046000000b0020c547f75easm1765022wrt.101.2022.05.26.06.41.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 26 May 2022 06:41:33 -0700 (PDT) From: Javier Martinez Canillas To: linux-kernel@vger.kernel.org Cc: Christian Kellner , Muhammad Usama Anjum , Alexander Larsson , Alberto Ruiz , Peter Jones , Lennart Poettering , Colin Walters , Chung-Chiang Cheng , Javier Martinez Canillas , OGAWA Hirofumi , Shuah Khan , linux-kselftest@vger.kernel.org Subject: [PATCH v3 3/3] selftests/filesystems: add a vfat RENAME_EXCHANGE test Date: Thu, 26 May 2022 15:41:19 +0200 Message-Id: <20220526134119.242182-4-javierm@redhat.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220526134119.242182-1-javierm@redhat.com> References: <20220526134119.242182-1-javierm@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add a test for the renameat2 RENAME_EXCHANGE support in vfat, but split it in a tool that just does the rename exchange and a script that is run by the kselftests framework on `make TARGETS=3D"filesystems/fat" kselftest`. That way the script can be easily extended to test other file operations. The script creates a 1 MiB disk image, that is then formated with a vfat filesystem and mounted using a loop device. That way all file operations are done on an ephemeral filesystem. Signed-off-by: Javier Martinez Canillas Acked-by: Muhammad Usama Anjum --- Changes in v3: - Add a .gitignore for the rename_exchange binary (Muhammad Usama Anjum). - Include $(KHDR_INCLUDES) instead of hardcoding a relative path in Makefile (Muhammad Usama Anjum). Changes in v2: - Call sync to flush the page cache before checking the file contents (Alex Larsson). MAINTAINERS | 1 + tools/testing/selftests/Makefile | 1 + .../selftests/filesystems/fat/.gitignore | 2 + .../selftests/filesystems/fat/Makefile | 7 ++ .../testing/selftests/filesystems/fat/config | 2 + .../filesystems/fat/rename_exchange.c | 37 +++++++++ .../filesystems/fat/run_fat_tests.sh | 82 +++++++++++++++++++ 7 files changed, 132 insertions(+) create mode 100644 tools/testing/selftests/filesystems/fat/.gitignore create mode 100644 tools/testing/selftests/filesystems/fat/Makefile create mode 100644 tools/testing/selftests/filesystems/fat/config create mode 100644 tools/testing/selftests/filesystems/fat/rename_exchange= .c create mode 100755 tools/testing/selftests/filesystems/fat/run_fat_tests.sh diff --git a/MAINTAINERS b/MAINTAINERS index 4fdbbd6c1984..158771bb7755 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -20841,6 +20841,7 @@ M: OGAWA Hirofumi S: Maintained F: Documentation/filesystems/vfat.rst F: fs/fat/ +F: tools/testing/selftests/filesystems/fat/ =20 VFIO DRIVER M: Alex Williamson diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Mak= efile index 0aedcd76cf0f..fc59ad849a90 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile @@ -16,6 +16,7 @@ TARGETS +=3D exec TARGETS +=3D filesystems TARGETS +=3D filesystems/binderfs TARGETS +=3D filesystems/epoll +TARGETS +=3D filesystems/fat TARGETS +=3D firmware TARGETS +=3D fpu TARGETS +=3D ftrace diff --git a/tools/testing/selftests/filesystems/fat/.gitignore b/tools/tes= ting/selftests/filesystems/fat/.gitignore new file mode 100644 index 000000000000..b89920ed841c --- /dev/null +++ b/tools/testing/selftests/filesystems/fat/.gitignore @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +rename_exchange diff --git a/tools/testing/selftests/filesystems/fat/Makefile b/tools/testi= ng/selftests/filesystems/fat/Makefile new file mode 100644 index 000000000000..902033f6ef09 --- /dev/null +++ b/tools/testing/selftests/filesystems/fat/Makefile @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0 + +TEST_PROGS :=3D run_fat_tests.sh +TEST_GEN_PROGS_EXTENDED :=3D rename_exchange +CFLAGS +=3D -O2 -g -Wall $(KHDR_INCLUDES) + +include ../../lib.mk diff --git a/tools/testing/selftests/filesystems/fat/config b/tools/testing= /selftests/filesystems/fat/config new file mode 100644 index 000000000000..6cf95e787a17 --- /dev/null +++ b/tools/testing/selftests/filesystems/fat/config @@ -0,0 +1,2 @@ +CONFIG_BLK_DEV_LOOP=3Dy +CONFIG_VFAT_FS=3Dy diff --git a/tools/testing/selftests/filesystems/fat/rename_exchange.c b/to= ols/testing/selftests/filesystems/fat/rename_exchange.c new file mode 100644 index 000000000000..e488ad354fce --- /dev/null +++ b/tools/testing/selftests/filesystems/fat/rename_exchange.c @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Program that atomically exchanges two paths using + * the renameat2() system call RENAME_EXCHANGE flag. + * + * Copyright 2022 Red Hat Inc. + * Author: Javier Martinez Canillas + */ + +#define _GNU_SOURCE +#include +#include +#include + +void print_usage(const char *program) +{ + printf("Usage: %s [oldpath] [newpath]\n", program); + printf("Atomically exchange oldpath and newpath\n"); +} + +int main(int argc, char *argv[]) +{ + int ret; + + if (argc !=3D 3) { + print_usage(argv[0]); + exit(EXIT_FAILURE); + } + + ret =3D renameat2(AT_FDCWD, argv[1], AT_FDCWD, argv[2], RENAME_EXCHANGE); + if (ret) { + perror("rename exchange failed"); + exit(EXIT_FAILURE); + } + + exit(EXIT_SUCCESS); +} diff --git a/tools/testing/selftests/filesystems/fat/run_fat_tests.sh b/too= ls/testing/selftests/filesystems/fat/run_fat_tests.sh new file mode 100755 index 000000000000..7f35dc3d15df --- /dev/null +++ b/tools/testing/selftests/filesystems/fat/run_fat_tests.sh @@ -0,0 +1,82 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0 +# +# Run filesystem operations tests on an 1 MiB disk image that is formatted= with +# a vfat filesystem and mounted in a temporary directory using a loop devi= ce. +# +# Copyright 2022 Red Hat Inc. +# Author: Javier Martinez Canillas + +set -e +set -u +set -o pipefail + +BASE_DIR=3D"$(dirname $0)" +TMP_DIR=3D"$(mktemp -d /tmp/fat_tests_tmp.XXXX)" +IMG_PATH=3D"${TMP_DIR}/fat.img" +MNT_PATH=3D"${TMP_DIR}/mnt" + +cleanup() +{ + mountpoint -q "${MNT_PATH}" && unmount_image + rm -rf "${TMP_DIR}" +} +trap cleanup SIGINT SIGTERM EXIT + +create_loopback() +{ + touch "${IMG_PATH}" + chattr +C "${IMG_PATH}" >/dev/null 2>&1 || true + + truncate -s 1M "${IMG_PATH}" + mkfs.vfat "${IMG_PATH}" >/dev/null 2>&1 +} + +mount_image() +{ + mkdir -p "${MNT_PATH}" + sudo mount -o loop "${IMG_PATH}" "${MNT_PATH}" +} + +rename_exchange_test() +{ + local rename_exchange=3D"${BASE_DIR}/rename_exchange" + local old_path=3D"${MNT_PATH}/old_file" + local new_path=3D"${MNT_PATH}/new_file" + + echo old | sudo tee "${old_path}" >/dev/null 2>&1 + echo new | sudo tee "${new_path}" >/dev/null 2>&1 + sudo "${rename_exchange}" "${old_path}" "${new_path}" >/dev/null 2>&1 + sudo sync -f "${MNT_PATH}" + grep new "${old_path}" >/dev/null 2>&1 + grep old "${new_path}" >/dev/null 2>&1 +} + +rename_exchange_subdir_test() +{ + local rename_exchange=3D"${BASE_DIR}/rename_exchange" + local dir_path=3D"${MNT_PATH}/subdir" + local old_path=3D"${MNT_PATH}/old_file" + local new_path=3D"${dir_path}/new_file" + + sudo mkdir -p "${dir_path}" + echo old | sudo tee "${old_path}" >/dev/null 2>&1 + echo new | sudo tee "${new_path}" >/dev/null 2>&1 + sudo "${rename_exchange}" "${old_path}" "${new_path}" >/dev/null 2>&1 + sudo sync -f "${MNT_PATH}" + grep new "${old_path}" >/dev/null 2>&1 + grep old "${new_path}" >/dev/null 2>&1 +} + +unmount_image() +{ + sudo umount "${MNT_PATH}" &> /dev/null +} + +create_loopback +mount_image +rename_exchange_test +rename_exchange_subdir_test +unmount_image + +exit 0 --=20 2.36.1