From nobody Mon Apr 27 23:53:12 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 6A94EC43334 for ; Thu, 9 Jun 2022 09:37:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242764AbiFIJhI (ORCPT ); Thu, 9 Jun 2022 05:37:08 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53228 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242516AbiFIJg4 (ORCPT ); Thu, 9 Jun 2022 05:36:56 -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 7CA6928E30 for ; Thu, 9 Jun 2022 02:36:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1654767413; 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=CSGLSnmFMRJ2m8g4U9LiTMcoVjjO2Y4SeFRNjTO2/yze+jw+Xm03scjykEHa2V+OIMXgSD BmNh78qZoMQnUakWf1KiAIzdUlm9QyJ3k+yQPADw64Qsf+txYRa/hXE2aHqSTkhUI9aR/W mvO5ZQ5UQYBFxYWG2w/waSk4Hh6K21s= Received: from mail-wm1-f71.google.com (mail-wm1-f71.google.com [209.85.128.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-155-uhaPHohYM3Ot5m0oL10eAw-1; Thu, 09 Jun 2022 05:36:52 -0400 X-MC-Unique: uhaPHohYM3Ot5m0oL10eAw-1 Received: by mail-wm1-f71.google.com with SMTP id j31-20020a05600c1c1f00b0039c481c4664so3953198wms.7 for ; Thu, 09 Jun 2022 02:36:52 -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=HtaQKE8A4zNm30udXXuZI61C9z+I9OHF3SEqHlL7cMgw1pXGCvoOvyd/S7Bj85DEJV HxFWXblQDw1J4V/cImDjg63J21MkrmyKluJPXm7WJfBDhlztgaIcwbiw4jmf+Pb7A/Eq luGVASBLbMcDw5XomVPHHx5Zg5UmyxD+LL1zlm6LuqmR0oQJskrOPmCR9tzcbxB5eZEn Lou3Rlmls+9SplET8wpw9XDBUrjRSOKk/tMLCmwK4qiTNPp3dWgeCB2KbkOLRu7XMPUI 765CR5xE0woXu9e5DzQG//If/LpSXvl46PUr7JzGnrHzBCj4dWORJS4EMuT5PUm3gpUZ HXcg== X-Gm-Message-State: AOAM533t2NEzs8mViK8yc/WMkzLk3DDMdZRtOJs+igaZUrm5a9HPuco7 eGt5SbZJOvdlUrzIJlqSnNDiLeweqSF2+XeoVKjwUY+A90Yrt7iXvA+RXOPAiFQ4k8CbMao/X8X OXBJBiy5ENED/lAY6/ACq+II6YtVYVX/l/DrqJk+jyeY06NM7xFkjTCnIv1Br6g6he8y/OqdnvM w= X-Received: by 2002:adf:d1ca:0:b0:218:47e1:ab0b with SMTP id b10-20020adfd1ca000000b0021847e1ab0bmr16907164wrd.90.1654767411231; Thu, 09 Jun 2022 02:36:51 -0700 (PDT) X-Google-Smtp-Source: ABdhPJymFw6eUMkR7CNYmHzwLfgqtmOzRz6ug7p6629lFPTqTuSd5slid+3U6WpmMw011viGhpAfeQ== X-Received: by 2002:adf:d1ca:0:b0:218:47e1:ab0b with SMTP id b10-20020adfd1ca000000b0021847e1ab0bmr16907129wrd.90.1654767410957; Thu, 09 Jun 2022 02:36:50 -0700 (PDT) Received: from minerva.home (205.pool92-176-231.dynamic.orange.es. [92.176.231.205]) by smtp.gmail.com with ESMTPSA id m18-20020a05600c3b1200b00397122e63b6sm27385580wms.29.2022.06.09.02.36.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Jun 2022 02:36:50 -0700 (PDT) From: Javier Martinez Canillas To: linux-kernel@vger.kernel.org Cc: Peter Jones , Alexander Larsson , Colin Walters , Alberto Ruiz , Muhammad Usama Anjum , Lennart Poettering , Chung-Chiang Cheng , Christian Kellner , OGAWA Hirofumi , Carlos Maiolino , Javier Martinez Canillas Subject: [PATCH v5 1/4] fat: add a vfat_rename2() and make existing .rename callback a helper Date: Thu, 9 Jun 2022 11:36:34 +0200 Message-Id: <20220609093638.664034-2-javierm@redhat.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220609093638.664034-1-javierm@redhat.com> References: <20220609093638.664034-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 Mon Apr 27 23:53:12 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 1CA92C43334 for ; Thu, 9 Jun 2022 09:37:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242710AbiFIJhE (ORCPT ); Thu, 9 Jun 2022 05:37:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53230 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242524AbiFIJg4 (ORCPT ); Thu, 9 Jun 2022 05:36:56 -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 74A022AE1E for ; Thu, 9 Jun 2022 02:36:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1654767414; 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=3UvTYFnM/Xxan4k4LuRTmFLCKv7+5+mh7KcxWLzDn8Q=; b=QGsSuitqFZGU75WBo8c3QUjYVw5J1DzV31oRgPwEWnhASPKdfwPxxBZRkEqePa2cfOxbyb p7/J0XFm0LXl+uKjmqMctGo9w88LGaw7BXVkkqKZu0V8QC652ZOaLIaHqgz6zq9Mo/Pa7Q vhRAgAKvcie2hz7RURm6MRx5d5yV/6A= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-104-3md41eXgMB-ztbZ8jCz5Bg-1; Thu, 09 Jun 2022 05:36:53 -0400 X-MC-Unique: 3md41eXgMB-ztbZ8jCz5Bg-1 Received: by mail-wm1-f69.google.com with SMTP id k5-20020a05600c1c8500b003974c5d636dso11128374wms.1 for ; Thu, 09 Jun 2022 02:36:53 -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=3UvTYFnM/Xxan4k4LuRTmFLCKv7+5+mh7KcxWLzDn8Q=; b=W0gF48nKoSO6T9KjGp8mGQ9fbVhsHxiLL/uQxwT/kJVJFVsWOunw76GXZkybB9ElsG NL5jAP00NP4IGlCu9P2cyYyDnb4/VXoZvoomX0Tp5p58pARk7ZcdD6hVqu/r9HZIRacO PmCB3OHlwT8VRYqxgVabaqI7YFmXrHbXmzSJ3vbh63x6oXswdJoSs70Iq3XM9QlEBtV2 yeMiJx7oeUScQk5BlXWIdAKhrJKWgtfz7VbiegYgJDQX2/gdxL5LZrA3AuB3EOGx+XuW CuplXbkqM67azpOMAQWzScM9YEyqsdOjoDaqvWLuHi2eF9OSRKV8njC2oMIbkjC01tDy 1eYg== X-Gm-Message-State: AOAM533TesrPmBykZjh+KPRJkfXPT+0ntgEKrxxxji09J7VkhQ3T68Fw HsmwlthndiEsEA1sNaTfLQ1j7q5us2kB/Iy8w6/p99X21xDaMYKVVK4qoAx7W36UgdK76RijJ7Z gLL/RhNoerXANCWDymnSH0S0pJfYQzLSH1JMJI38jNcAm7tYBrZCe3T7w+mcXM3k5n6jD7yK6FP 8= X-Received: by 2002:a5d:47c1:0:b0:217:1959:3bf5 with SMTP id o1-20020a5d47c1000000b0021719593bf5mr24815402wrc.319.1654767412360; Thu, 09 Jun 2022 02:36:52 -0700 (PDT) X-Google-Smtp-Source: ABdhPJz/vk0jTmvLixTNTZ4cEfwH6NOZxQ1acz3ugi2ZEReCLpUZFSF42fv907hzDvm0X2jMXV0Cgw== X-Received: by 2002:a5d:47c1:0:b0:217:1959:3bf5 with SMTP id o1-20020a5d47c1000000b0021719593bf5mr24815364wrc.319.1654767412065; Thu, 09 Jun 2022 02:36:52 -0700 (PDT) Received: from minerva.home (205.pool92-176-231.dynamic.orange.es. [92.176.231.205]) by smtp.gmail.com with ESMTPSA id m18-20020a05600c3b1200b00397122e63b6sm27385580wms.29.2022.06.09.02.36.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Jun 2022 02:36:51 -0700 (PDT) From: Javier Martinez Canillas To: linux-kernel@vger.kernel.org Cc: Peter Jones , Alexander Larsson , Colin Walters , Alberto Ruiz , Muhammad Usama Anjum , Lennart Poettering , Chung-Chiang Cheng , Christian Kellner , OGAWA Hirofumi , Carlos Maiolino , Javier Martinez Canillas Subject: [PATCH v5 2/4] fat: factor out reusable code in vfat_rename() as helper functions Date: Thu, 9 Jun 2022 11:36:35 +0200 Message-Id: <20220609093638.664034-3-javierm@redhat.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220609093638.664034-1-javierm@redhat.com> References: <20220609093638.664034-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" From: OGAWA Hirofumi The vfat_rename() function is quite big and there are code blocks that can be moved into helper functions. This not only simplify the implementation of that function but also allows these helpers to be reused. For example, the helpers can be used by the handler of the RENAME_EXCHANGE flag once this is implemented in a subsequent patch. Signed-off-by: OGAWA Hirofumi Signed-off-by: Javier Martinez Canillas --- (no changes since v4) Changes in v4: - Add new patch from OGAWA Hirofumi to use the helpers in vfat_rename(). fs/fat/namei_vfat.c | 89 +++++++++++++++++++++++++++++---------------- 1 file changed, 57 insertions(+), 32 deletions(-) diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index 88ccb2ee3537..9c04053a8f1c 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c @@ -889,16 +889,55 @@ static int vfat_mkdir(struct user_namespace *mnt_user= ns, struct inode *dir, return err; } =20 +static int vfat_get_dotdot_de(struct inode *inode, struct buffer_head **bh, + struct msdos_dir_entry **de) +{ + if (S_ISDIR(inode->i_mode)) { + if (fat_get_dotdot_entry(inode, bh, de)) + return -EIO; + } + return 0; +} + +static int vfat_sync_ipos(struct inode *dir, struct inode *inode) +{ + if (IS_DIRSYNC(dir)) + return fat_sync_inode(inode); + mark_inode_dirty(inode); + return 0; +} + +static int vfat_update_dotdot_de(struct inode *dir, struct inode *inode, + struct buffer_head *dotdot_bh, + struct msdos_dir_entry *dotdot_de) +{ + fat_set_start(dotdot_de, MSDOS_I(dir)->i_logstart); + mark_buffer_dirty_inode(dotdot_bh, inode); + if (IS_DIRSYNC(dir)) + return sync_dirty_buffer(dotdot_bh); + return 0; +} + +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(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; + struct msdos_dir_entry *dotdot_de =3D NULL; struct inode *old_inode, *new_inode; struct fat_slot_info old_sinfo, sinfo; struct timespec64 ts; loff_t new_i_pos; - int err, is_dir, update_dotdot, corrupt =3D 0; + int err, is_dir, corrupt =3D 0; struct super_block *sb =3D old_dir->i_sb; =20 old_sinfo.bh =3D sinfo.bh =3D dotdot_bh =3D NULL; @@ -909,15 +948,13 @@ static int vfat_rename(struct inode *old_dir, struct = dentry *old_dentry, if (err) goto out; =20 - is_dir =3D S_ISDIR(old_inode->i_mode); - update_dotdot =3D (is_dir && old_dir !=3D new_dir); - if (update_dotdot) { - if (fat_get_dotdot_entry(old_inode, &dotdot_bh, &dotdot_de)) { - err =3D -EIO; + if (old_dir !=3D new_dir) { + err =3D vfat_get_dotdot_de(old_inode, &dotdot_bh, &dotdot_de); + if (err) goto out; - } } =20 + is_dir =3D S_ISDIR(old_inode->i_mode); ts =3D current_time(old_dir); if (new_inode) { if (is_dir) { @@ -938,21 +975,15 @@ static int vfat_rename(struct inode *old_dir, struct = dentry *old_dentry, =20 fat_detach(old_inode); fat_attach(old_inode, new_i_pos); - if (IS_DIRSYNC(new_dir)) { - err =3D fat_sync_inode(old_inode); - if (err) - goto error_inode; - } else - mark_inode_dirty(old_inode); + err =3D vfat_sync_ipos(new_dir, old_inode); + if (err) + goto error_inode; =20 - if (update_dotdot) { - fat_set_start(dotdot_de, MSDOS_I(new_dir)->i_logstart); - mark_buffer_dirty_inode(dotdot_bh, old_inode); - if (IS_DIRSYNC(new_dir)) { - err =3D sync_dirty_buffer(dotdot_bh); - if (err) - goto error_dotdot; - } + if (dotdot_de) { + err =3D vfat_update_dotdot_de(new_dir, old_inode, dotdot_bh, + dotdot_de); + if (err) + goto error_dotdot; drop_nlink(old_dir); if (!new_inode) inc_nlink(new_dir); @@ -962,12 +993,7 @@ static int vfat_rename(struct inode *old_dir, struct d= entry *old_dentry, old_sinfo.bh =3D NULL; if (err) goto error_dotdot; - inode_inc_iversion(old_dir); - fat_truncate_time(old_dir, &ts, S_CTIME|S_MTIME); - if (IS_DIRSYNC(old_dir)) - (void)fat_sync_inode(old_dir); - else - mark_inode_dirty(old_dir); + vfat_update_dir_metadata(old_dir, &ts); =20 if (new_inode) { drop_nlink(new_inode); @@ -987,10 +1013,9 @@ static int vfat_rename(struct inode *old_dir, struct = dentry *old_dentry, /* data cluster is shared, serious corruption */ corrupt =3D 1; =20 - if (update_dotdot) { - fat_set_start(dotdot_de, MSDOS_I(old_dir)->i_logstart); - mark_buffer_dirty_inode(dotdot_bh, old_inode); - corrupt |=3D sync_dirty_buffer(dotdot_bh); + if (dotdot_de) { + corrupt |=3D vfat_update_dotdot_de(old_dir, old_inode, dotdot_bh, + dotdot_de); } error_inode: fat_detach(old_inode); --=20 2.36.1 From nobody Mon Apr 27 23:53:12 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 1A36FC43334 for ; Thu, 9 Jun 2022 09:37:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242802AbiFIJhP (ORCPT ); Thu, 9 Jun 2022 05:37:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:54014 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242741AbiFIJhG (ORCPT ); Thu, 9 Jun 2022 05:37:06 -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 0B1642CE36 for ; Thu, 9 Jun 2022 02:37:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1654767424; 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=OgRi0PKD0VO5dANyO2dDI6iaCmLjQgKbnL82bbRFxuc=; b=GG0lgiANkRjyfy4FcB5A1bf/TgcxdpOBtj1BrYjYkkpYi4JvENPfu4+xqBPPVNGlVQqOdg GFcl89zwVkMFnI/UnMT8kvUR+KHbVCQIi9x4SousmQsOZmMmT6tZva+8b4TltpjwAn6pXs bbpGo5JH026Yj+Lp8l8sHkcXxew1Lfo= 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-345-veaLGNnUPRilc3Auy9AxNA-1; Thu, 09 Jun 2022 05:36:55 -0400 X-MC-Unique: veaLGNnUPRilc3Auy9AxNA-1 Received: by mail-wr1-f69.google.com with SMTP id y2-20020adff142000000b0021581245fa1so4229903wro.7 for ; Thu, 09 Jun 2022 02:36:54 -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=OgRi0PKD0VO5dANyO2dDI6iaCmLjQgKbnL82bbRFxuc=; b=arwT+acxcyupFhw2epTLyT9OyREcOZUs9VNkJPkRaXqG+/l20Wv0adL+AbyGdMqcPt vtKPv3losgy2GkWrc7VMiCtfj69dT3/MxVGsfwm+P3d/2URDjHBoIhUJtq58wH2UGlVV g8FZWMbat51IO9ch3B9AFncmhJYSge0Ap9eCu3++D2quhlf1S3aOV4WBTiI6zoNNw1QV JfMkZn+FmPzg/emZDSG6Or4kklTlOPEhotXSmL1+z7UU3QQpna4vFVFbOXGowzscE96l xdUf2Abpjinx5DPq105xL7sDjRUvp0FrtYuXasAk+vjxTjdK4OWqmG6BcCzCDvoPP4om Yn5w== X-Gm-Message-State: AOAM530uK5Qc6wqyiag8oGGbz5nSciZ/MzXkCAt/cX/g/QjkE2FdNkKM 9UgiroG8Pxt9oEBJ93ivtkLNGs8xm1RMOBGG2s4jXUwOtq1co7weI3IpcsnSc+kc0UCbIoXHkwN vpdZd1Bb8EO7kZa9/7m2E3tadN7c1r14i++RbmfaCbzT+fk3ZU1/eo2Rt5+3zAr+ZCDVcFFgbII 8= X-Received: by 2002:a05:6000:188b:b0:218:5d79:dc6e with SMTP id a11-20020a056000188b00b002185d79dc6emr8071911wri.183.1654767413821; Thu, 09 Jun 2022 02:36:53 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxvw/z8WVJ+iV9KsL3eBAQMwTrCO7rkZ9WddMOPuseWcJhnVi9NOQjMtd16CYXi2hVkDcC08A== X-Received: by 2002:a05:6000:188b:b0:218:5d79:dc6e with SMTP id a11-20020a056000188b00b002185d79dc6emr8071880wri.183.1654767413559; Thu, 09 Jun 2022 02:36:53 -0700 (PDT) Received: from minerva.home (205.pool92-176-231.dynamic.orange.es. [92.176.231.205]) by smtp.gmail.com with ESMTPSA id m18-20020a05600c3b1200b00397122e63b6sm27385580wms.29.2022.06.09.02.36.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Jun 2022 02:36:53 -0700 (PDT) From: Javier Martinez Canillas To: linux-kernel@vger.kernel.org Cc: Peter Jones , Alexander Larsson , Colin Walters , Alberto Ruiz , Muhammad Usama Anjum , Lennart Poettering , Chung-Chiang Cheng , Christian Kellner , OGAWA Hirofumi , Carlos Maiolino , Javier Martinez Canillas Subject: [PATCH v5 3/4] fat: add renameat2 RENAME_EXCHANGE flag support Date: Thu, 9 Jun 2022 11:36:36 +0200 Message-Id: <20220609093638.664034-4-javierm@redhat.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220609093638.664034-1-javierm@redhat.com> References: <20220609093638.664034-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 --- Changes in v5: - Only update nlink for different parent dirs and file types (OGAWA Hirofum= i). Changes in v4: - Rebase the patch on top of OGAWA Hirofumi proposed changes. - Drop iversion increment for old and new file inodes (OGAWA Hirofumi). 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 | 124 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 123 insertions(+), 1 deletion(-) diff --git a/fs/fat/namei_vfat.c b/fs/fat/namei_vfat.c index 9c04053a8f1c..4aa096a15e59 100644 --- a/fs/fat/namei_vfat.c +++ b/fs/fat/namei_vfat.c @@ -1042,13 +1042,135 @@ static int vfat_rename(struct inode *old_dir, stru= ct dentry *old_dentry, goto out; } =20 +static void vfat_exchange_ipos(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 void vfat_update_nlink(struct inode *dir, struct inode *inode) +{ + if (S_ISDIR(inode->i_mode)) + drop_nlink(dir); + else + inc_nlink(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_de(old_inode, &old_dotdot_bh, + &old_dotdot_de); + if (err) + goto out; + + err =3D vfat_get_dotdot_de(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; + + vfat_exchange_ipos(old_inode, new_inode, old_i_pos, new_i_pos); + + err =3D vfat_sync_ipos(old_dir, new_inode); + if (err) + goto error_exchange; + err =3D vfat_sync_ipos(new_dir, old_inode); + if (err) + goto error_exchange; + + /* update ".." directory entry info */ + if (old_dotdot_de) { + err =3D vfat_update_dotdot_de(new_dir, old_inode, old_dotdot_bh, + old_dotdot_de); + if (err) + goto error_old_dotdot; + } + + if (new_dotdot_de) { + err =3D vfat_update_dotdot_de(old_dir, new_inode, new_dotdot_bh, + new_dotdot_de); + if (err) + goto error_new_dotdot; + } + + 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); + /* nlink only needs to be updated if the file types differ */ + if (old_inode->i_mode !=3D new_inode->i_mode) { + vfat_update_nlink(old_dir, old_inode); + vfat_update_nlink(new_dir, new_inode); + } + } + +out: + brelse(old_dotdot_bh); + brelse(new_dotdot_bh); + mutex_unlock(&MSDOS_SB(sb)->s_lock); + + return err; + +error_new_dotdot: + if (new_dotdot_de) { + corrupt |=3D vfat_update_dotdot_de(new_dir, new_inode, + new_dotdot_bh, new_dotdot_de); + } + +error_old_dotdot: + if (old_dotdot_de) { + corrupt |=3D vfat_update_dotdot_de(old_dir, old_inode, + old_dotdot_bh, old_dotdot_de); + } + +error_exchange: + vfat_exchange_ipos(old_inode, new_inode, new_i_pos, old_i_pos); + corrupt |=3D vfat_sync_ipos(new_dir, new_inode); + corrupt |=3D vfat_sync_ipos(old_dir, old_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 Mon Apr 27 23:53:12 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 99EDAC433EF for ; Thu, 9 Jun 2022 09:37:12 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S242757AbiFIJhK (ORCPT ); Thu, 9 Jun 2022 05:37:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:53740 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242697AbiFIJhD (ORCPT ); Thu, 9 Jun 2022 05:37:03 -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 5059E2494C for ; Thu, 9 Jun 2022 02:37:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1654767419; 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=MR1Gg3APqC3KScgCLB1W8gelo918jbhbexHlcrWCcj0=; b=iWdhNDdWDlK6wjhQgbkiWT7KnEC4xCrtHHpP3kQJ80PY9O7BQyfDayGjJceTUObePy7qRX Ue/y64vG1+B6OUbY2J9cuV0sYDemZRNBV+lN0xyag8AVWaySAxlHZFkp1aeNts8arlKSFp g+UOsfaxMOYJ/HR3NujKhj+uLXqMBxQ= Received: from mail-wm1-f71.google.com (mail-wm1-f71.google.com [209.85.128.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-266-sJ11ohVHO_6jpOW-YaXuEA-1; Thu, 09 Jun 2022 05:36:57 -0400 X-MC-Unique: sJ11ohVHO_6jpOW-YaXuEA-1 Received: by mail-wm1-f71.google.com with SMTP id c125-20020a1c3583000000b003978decffedso15743781wma.5 for ; Thu, 09 Jun 2022 02:36:57 -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=MR1Gg3APqC3KScgCLB1W8gelo918jbhbexHlcrWCcj0=; b=AGp2gD958kxdrxUBvqXx/j16ynRvblZWS51uZ1Jps2jZU2TDZvVIaooDCwbA9/13e+ 5YcfDiCMT4LNjduIy3KbH5jA+ZHu/6UqidMZKKuLGpM4rO2Ttq3LhAkGrNGkDltirZ5S x6AlyNdoRhrecorbs5KJCeKRg1WmcwfXOmUpk8My1xjwM0whovlq6pXO6hXPD1msMU1F i30u/cWS7e6IQeUu7Qd7A+FJ1T56QvJwjt75qaVvQXj2VBMbi7R5FlT2WGhQm+VO1h49 kpXxsPG4C1cXhoUDLz4CsrSgaL2UN6NkcvpIn551VCGJvOKirNq0ETP9bX2D3R0VnhLf ihlA== X-Gm-Message-State: AOAM5313pK4CCRXECleAU0LQ/uoIBAW9/gCZYQI0cQKecFL+gqsuBJ6V 9OFsoHBHh3c07/otVVQqgYNB9zudwvqw3fikqIMkTWnZI86+HK/T9TUKJ5JDcFjEq1+MHYyzxDH YmI/lE+Vxa+cZuH2wRaShMNL94A+0J1BQmfIw05dts/+iMLl3X3GxpeKBQPU2j1olgHF2WBCPeQ k= X-Received: by 2002:a5d:5452:0:b0:216:f80e:f7c6 with SMTP id w18-20020a5d5452000000b00216f80ef7c6mr24899337wrv.472.1654767415182; Thu, 09 Jun 2022 02:36:55 -0700 (PDT) X-Google-Smtp-Source: ABdhPJyxEj2OrQ9eQ+YDGgXFgVqRTz/a3B1WWgKCdV/5GXwifXUVC/IjJoHQVQ6y6SNEa/SE5vTFCw== X-Received: by 2002:a5d:5452:0:b0:216:f80e:f7c6 with SMTP id w18-20020a5d5452000000b00216f80ef7c6mr24899302wrv.472.1654767414837; Thu, 09 Jun 2022 02:36:54 -0700 (PDT) Received: from minerva.home (205.pool92-176-231.dynamic.orange.es. [92.176.231.205]) by smtp.gmail.com with ESMTPSA id m18-20020a05600c3b1200b00397122e63b6sm27385580wms.29.2022.06.09.02.36.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 09 Jun 2022 02:36:54 -0700 (PDT) From: Javier Martinez Canillas To: linux-kernel@vger.kernel.org Cc: Peter Jones , Alexander Larsson , Colin Walters , Alberto Ruiz , Muhammad Usama Anjum , Lennart Poettering , Chung-Chiang Cheng , Christian Kellner , OGAWA Hirofumi , Carlos Maiolino , Javier Martinez Canillas , Shuah Khan , linux-kselftest@vger.kernel.org Subject: [PATCH v5 4/4] selftests/filesystems: add a vfat RENAME_EXCHANGE test Date: Thu, 9 Jun 2022 11:36:37 +0200 Message-Id: <20220609093638.664034-5-javierm@redhat.com> X-Mailer: git-send-email 2.36.1 In-Reply-To: <20220609093638.664034-1-javierm@redhat.com> References: <20220609093638.664034-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 --- (no changes since v4) Changes in v4: - Add Muhammad Usama Anjum Acked-by tag. 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