]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
btrfs: add mount option for ref_tracker
authorLeo Martins <loemra.dev@gmail.com>
Tue, 12 Aug 2025 23:04:41 +0000 (16:04 -0700)
committerDavid Sterba <dsterba@suse.com>
Mon, 22 Sep 2025 08:54:32 +0000 (10:54 +0200)
The ref_tracker infrastructure aids debugging but is not enabled by
default as it has a performance impact. Add mount option 'ref_tracker'
so it can be selectively enabled on a filesystem. Currently it track
references of 'delayed inodes'.

Signed-off-by: Leo Martins <loemra.dev@gmail.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/delayed-inode.h
fs/btrfs/fs.h
fs/btrfs/super.c

index 7f2db9905aeaee83a0c8b1a4f529a25e4b3f7b81..0d949edc0caf16eb48e31f1ff3984074dbdf05d5 100644 (file)
@@ -198,6 +198,9 @@ void btrfs_assert_delayed_root_empty(struct btrfs_fs_info *fs_info);
 #ifdef CONFIG_BTRFS_DEBUG
 static inline void btrfs_delayed_node_ref_tracker_dir_init(struct btrfs_delayed_node *node)
 {
+       if (!btrfs_test_opt(node->root->fs_info, REF_TRACKER))
+               return;
+
        ref_tracker_dir_init(&node->ref_dir.dir,
                             BTRFS_DELAYED_NODE_REF_TRACKER_QUARANTINE_COUNT,
                             "delayed_node");
@@ -205,11 +208,17 @@ static inline void btrfs_delayed_node_ref_tracker_dir_init(struct btrfs_delayed_
 
 static inline void btrfs_delayed_node_ref_tracker_dir_exit(struct btrfs_delayed_node *node)
 {
+       if (!btrfs_test_opt(node->root->fs_info, REF_TRACKER))
+               return;
+
        ref_tracker_dir_exit(&node->ref_dir.dir);
 }
 
 static inline void btrfs_delayed_node_ref_tracker_dir_print(struct btrfs_delayed_node *node)
 {
+       if (!btrfs_test_opt(node->root->fs_info, REF_TRACKER))
+               return;
+
        ref_tracker_dir_print(&node->ref_dir.dir,
                              BTRFS_DELAYED_NODE_REF_TRACKER_DISPLAY_LIMIT);
 }
@@ -218,12 +227,18 @@ static inline int btrfs_delayed_node_ref_tracker_alloc(struct btrfs_delayed_node
                                                       struct btrfs_ref_tracker *tracker,
                                                       gfp_t gfp)
 {
+       if (!btrfs_test_opt(node->root->fs_info, REF_TRACKER))
+               return 0;
+
        return ref_tracker_alloc(&node->ref_dir.dir, &tracker->tracker, gfp);
 }
 
 static inline int btrfs_delayed_node_ref_tracker_free(struct btrfs_delayed_node *node,
                                                      struct btrfs_ref_tracker *tracker)
 {
+       if (!btrfs_test_opt(node->root->fs_info, REF_TRACKER))
+               return 0;
+
        return ref_tracker_free(&node->ref_dir.dir, &tracker->tracker);
 }
 #else
index 66e08e20ff5acc8c1c90f12ea110e97d2327f2e9..a84128e991a9d43a77c29c3b504891758a9356d9 100644 (file)
@@ -245,6 +245,7 @@ enum {
        BTRFS_MOUNT_NOSPACECACHE                = (1ULL << 30),
        BTRFS_MOUNT_IGNOREMETACSUMS             = (1ULL << 31),
        BTRFS_MOUNT_IGNORESUPERFLAGS            = (1ULL << 32),
+       BTRFS_MOUNT_REF_TRACKER                 = (1ULL << 33),
 };
 
 /*
index 3bc19989e7fbf3607411257dbafd5ac639c4bd58..4951f50e9823e7c843d24cc4e868d867a449a9d1 100644 (file)
@@ -134,6 +134,7 @@ enum {
 #ifdef CONFIG_BTRFS_DEBUG
        Opt_fragment, Opt_fragment_data, Opt_fragment_metadata, Opt_fragment_all,
        Opt_ref_verify,
+       Opt_ref_tracker,
 #endif
        Opt_err,
 };
@@ -255,6 +256,7 @@ static const struct fs_parameter_spec btrfs_fs_parameters[] = {
        fsparam_flag_no("enospc_debug", Opt_enospc_debug),
 #ifdef CONFIG_BTRFS_DEBUG
        fsparam_enum("fragment", Opt_fragment, btrfs_parameter_fragment),
+       fsparam_flag("ref_tracker", Opt_ref_tracker),
        fsparam_flag("ref_verify", Opt_ref_verify),
 #endif
        {}
@@ -645,6 +647,9 @@ static int btrfs_parse_param(struct fs_context *fc, struct fs_parameter *param)
        case Opt_ref_verify:
                btrfs_set_opt(ctx->mount_opt, REF_VERIFY);
                break;
+       case Opt_ref_tracker:
+               btrfs_set_opt(ctx->mount_opt, REF_TRACKER);
+               break;
 #endif
        default:
                btrfs_err(NULL, "unrecognized mount option '%s'", param->key);
@@ -1150,6 +1155,8 @@ static int btrfs_show_options(struct seq_file *seq, struct dentry *dentry)
 #endif
        if (btrfs_test_opt(info, REF_VERIFY))
                seq_puts(seq, ",ref_verify");
+       if (btrfs_test_opt(info, REF_TRACKER))
+               seq_puts(seq, ",ref_tracker");
        seq_printf(seq, ",subvolid=%llu", btrfs_root_id(BTRFS_I(d_inode(dentry))->root));
        subvol_name = btrfs_get_subvol_name_from_objectid(info,
                        btrfs_root_id(BTRFS_I(d_inode(dentry))->root));