btrfs: allocate path earlier at btrfs_log_new_name()
authorFilipe Manana <fdmanana@suse.com>
Sat, 31 May 2025 15:33:14 +0000 (16:33 +0100)
committerDavid Sterba <dsterba@suse.com>
Mon, 21 Jul 2025 21:53:29 +0000 (23:53 +0200)
Instead of allocating the path after joining the log transaction, allocate
it before so that we're not delaying log commits for the rare cases where
the allocation takes a significant time (under memory pressure and all
slabs are full, there's the need to allocate a new page, etc).

Reviewed-by: Boris Burkov <boris@bur.io>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/tree-log.c

index c3d7238ba2cbd911fc618c8311aa34189fa47ade..bacee096dd72ffecfa64fdc770898c76933f4efc 100644 (file)
@@ -7545,6 +7545,14 @@ void btrfs_log_new_name(struct btrfs_trans_handle *trans,
                                             &old_dentry->d_name, 0, &fname);
                if (ret)
                        goto out;
+
+               path = btrfs_alloc_path();
+               if (!path) {
+                       ret = -ENOMEM;
+                       fscrypt_free_filename(&fname);
+                       goto out;
+               }
+
                /*
                 * We have two inodes to update in the log, the old directory and
                 * the inode that got renamed, so we must pin the log to prevent
@@ -7558,19 +7566,13 @@ void btrfs_log_new_name(struct btrfs_trans_handle *trans,
                 * mark the log for a full commit.
                 */
                if (WARN_ON_ONCE(ret < 0)) {
+                       btrfs_free_path(path);
                        fscrypt_free_filename(&fname);
                        goto out;
                }
 
                log_pinned = true;
 
-               path = btrfs_alloc_path();
-               if (!path) {
-                       ret = -ENOMEM;
-                       fscrypt_free_filename(&fname);
-                       goto out;
-               }
-
                /*
                 * Other concurrent task might be logging the old directory,
                 * as it can be triggered when logging other inode that had or