[PATCH 12/15] btrfs: remove the free space inode ordered extent special cases

From: Tal Zussman

Date: Mon Sep 07 2026 - 21:22:02 EST


Free space inodes never have ordered extents any more. Drop the lockdep
exceptions for them and btrfs_join_transaction_spacecache(), which was
only used to finish their ordered extents during a commit, along with
TRANS_JOIN_NOLOCK.

Assisted-by: Claude:claude-fable-5-1
Signed-off-by: Tal Zussman <tz2294@xxxxxxxxxxxx>
---
fs/btrfs/inode.c | 20 +++-----------------
fs/btrfs/ordered-data.c | 20 ++------------------
fs/btrfs/transaction.c | 23 +----------------------
fs/btrfs/transaction.h | 3 ---
4 files changed, 6 insertions(+), 60 deletions(-)

diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 699a321fc43b..5e4ecd1fe194 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -3203,7 +3203,6 @@ int btrfs_finish_one_ordered(struct btrfs_ordered_extent *ordered_extent)
int compress_type = 0;
int ret = 0;
u64 logical_len = ordered_extent->num_bytes;
- bool freespace_inode;
bool truncated = false;
bool clear_reserved_extent = true;
unsigned int clear_bits = 0;
@@ -3220,9 +3219,7 @@ int btrfs_finish_one_ordered(struct btrfs_ordered_extent *ordered_extent)
if (!test_bit(BTRFS_ORDERED_NOCOW, &ordered_extent->flags))
clear_bits |= EXTENT_DEFRAG;

- freespace_inode = btrfs_is_free_space_inode(inode);
- if (!freespace_inode)
- btrfs_lockdep_acquire(fs_info, btrfs_ordered_extent);
+ btrfs_lockdep_acquire(fs_info, btrfs_ordered_extent);

if (unlikely(test_bit(BTRFS_ORDERED_IOERR, &ordered_extent->flags))) {
ret = -EIO;
@@ -3257,10 +3254,7 @@ int btrfs_finish_one_ordered(struct btrfs_ordered_extent *ordered_extent)
&cached_state);
}

- if (freespace_inode)
- trans = btrfs_join_transaction_spacecache(root);
- else
- trans = btrfs_join_transaction(root);
+ trans = btrfs_join_transaction(root);
if (IS_ERR(trans)) {
ret = PTR_ERR(trans);
trans = NULL;
@@ -8116,7 +8110,6 @@ void btrfs_destroy_inode(struct inode *vfs_inode)
struct btrfs_ordered_extent *ordered;
struct btrfs_inode *inode = BTRFS_I(vfs_inode);
struct btrfs_root *root = inode->root;
- bool freespace_inode;

WARN_ON(!hlist_empty(&vfs_inode->i_dentry));
WARN_ON(vfs_inode->i_data.nrpages);
@@ -8139,12 +8132,6 @@ void btrfs_destroy_inode(struct inode *vfs_inode)
if (!root)
return;

- /*
- * If this is a free space inode do not take the ordered extents lockdep
- * map.
- */
- freespace_inode = btrfs_is_free_space_inode(inode);
-
while (1) {
ordered = btrfs_lookup_first_ordered_extent(inode, (u64)-1);
if (!ordered)
@@ -8154,8 +8141,7 @@ void btrfs_destroy_inode(struct inode *vfs_inode)
"found ordered extent %llu %llu on inode cleanup",
ordered->file_offset, ordered->num_bytes);

- if (!freespace_inode)
- btrfs_lockdep_acquire(root->fs_info, btrfs_ordered_extent);
+ btrfs_lockdep_acquire(root->fs_info, btrfs_ordered_extent);

btrfs_remove_ordered_extent(ordered);
btrfs_put_ordered_extent(ordered);
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c
index e9f1cbeb555a..df74c75d6c29 100644
--- a/fs/btrfs/ordered-data.c
+++ b/fs/btrfs/ordered-data.c
@@ -654,13 +654,6 @@ void btrfs_remove_ordered_extent(struct btrfs_ordered_extent *entry)
struct btrfs_fs_info *fs_info = root->fs_info;
struct rb_node *node;
bool pending;
- bool freespace_inode;
-
- /*
- * If this is a free space inode the thread has not acquired the ordered
- * extents lockdep map.
- */
- freespace_inode = btrfs_is_free_space_inode(btrfs_inode);

btrfs_lockdep_acquire(fs_info, btrfs_trans_pending_ordered);
/* This is paired with alloc_ordered_extent(). */
@@ -735,8 +728,7 @@ void btrfs_remove_ordered_extent(struct btrfs_ordered_extent *entry)
}
spin_unlock(&root->ordered_extent_lock);
wake_up(&entry->wait);
- if (!freespace_inode)
- btrfs_lockdep_release(fs_info, btrfs_ordered_extent);
+ btrfs_lockdep_release(fs_info, btrfs_ordered_extent);
}

static void btrfs_run_ordered_extent_work(struct btrfs_work *work)
@@ -867,16 +859,9 @@ void btrfs_start_ordered_extent_nowriteback(struct btrfs_ordered_extent *entry,
u64 start = entry->file_offset;
u64 end = start + entry->num_bytes - 1;
struct btrfs_inode *inode = entry->inode;
- bool freespace_inode;

trace_btrfs_ordered_extent_start(inode, entry);

- /*
- * If this is a free space inode do not take the ordered extents lockdep
- * map.
- */
- freespace_inode = btrfs_is_free_space_inode(inode);
-
/*
* pages in the range can be dirty, clean or writeback. We
* start IO on any dirty ones so the wait doesn't stall waiting
@@ -896,8 +881,7 @@ void btrfs_start_ordered_extent_nowriteback(struct btrfs_ordered_extent *entry,
}
}

- if (!freespace_inode)
- btrfs_might_wait_for_event(inode->root->fs_info, btrfs_ordered_extent);
+ btrfs_might_wait_for_event(inode->root->fs_info, btrfs_ordered_extent);
wait_event(entry->wait, test_bit(BTRFS_ORDERED_COMPLETE, &entry->flags));
}

diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index d2ff3b568eed..232cfa37d2d8 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -125,17 +125,14 @@ static const unsigned int btrfs_blocked_trans_types[TRANS_STATE_MAX] = {
[TRANS_STATE_UNBLOCKED] = (__TRANS_START |
__TRANS_ATTACH |
__TRANS_JOIN |
- __TRANS_JOIN_NOLOCK |
__TRANS_JOIN_NOSTART),
[TRANS_STATE_SUPER_COMMITTED] = (__TRANS_START |
__TRANS_ATTACH |
__TRANS_JOIN |
- __TRANS_JOIN_NOLOCK |
__TRANS_JOIN_NOSTART),
[TRANS_STATE_COMPLETED] = (__TRANS_START |
__TRANS_ATTACH |
__TRANS_JOIN |
- __TRANS_JOIN_NOLOCK |
__TRANS_JOIN_NOSTART),
};

@@ -310,12 +307,6 @@ static noinline int join_transaction(struct btrfs_fs_info *fs_info,
if (type == TRANS_ATTACH || type == TRANS_JOIN_NOSTART)
return -ENOENT;

- /*
- * JOIN_NOLOCK only happens during the transaction commit, so
- * it is impossible that ->running_transaction is NULL
- */
- BUG_ON(type == TRANS_JOIN_NOLOCK);
-
cur_trans = kmalloc_obj(*cur_trans, GFP_NOFS);
if (!cur_trans)
return -ENOMEM;
@@ -708,14 +699,8 @@ start_transaction(struct btrfs_root *root, unsigned int num_items,
}

/*
- * If we are JOIN_NOLOCK we're already committing a transaction and
- * waiting on this guy, so we don't need to do the sb_start_intwrite
- * because we're already holding a ref. We need this because we could
- * have raced in and did an fsync() on a file which can kick a commit
- * and then we deadlock with somebody doing a freeze.
- *
* If we are ATTACH, it means we just want to catch the current
- * transaction and commit it, so we needn't do sb_start_intwrite().
+ * transaction and commit it, so we needn't do sb_start_intwrite().
*/
if (type & __TRANS_FREEZABLE)
sb_start_intwrite(fs_info->sb);
@@ -853,12 +838,6 @@ struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root)
true);
}

-struct btrfs_trans_handle *btrfs_join_transaction_spacecache(struct btrfs_root *root)
-{
- return start_transaction(root, 0, TRANS_JOIN_NOLOCK,
- BTRFS_RESERVE_NO_FLUSH, true);
-}
-
/*
* Similar to regular join but it never starts a transaction when none is
* running or when there's a running one at a state >= TRANS_STATE_UNBLOCKED.
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h
index 889babc76b68..51633af27894 100644
--- a/fs/btrfs/transaction.h
+++ b/fs/btrfs/transaction.h
@@ -100,7 +100,6 @@ enum {
ENUM_BIT(__TRANS_START),
ENUM_BIT(__TRANS_ATTACH),
ENUM_BIT(__TRANS_JOIN),
- ENUM_BIT(__TRANS_JOIN_NOLOCK),
ENUM_BIT(__TRANS_DUMMY),
ENUM_BIT(__TRANS_JOIN_NOSTART),
};
@@ -108,7 +107,6 @@ enum {
#define TRANS_START (__TRANS_START | __TRANS_FREEZABLE)
#define TRANS_ATTACH (__TRANS_ATTACH)
#define TRANS_JOIN (__TRANS_JOIN | __TRANS_FREEZABLE)
-#define TRANS_JOIN_NOLOCK (__TRANS_JOIN_NOLOCK)
#define TRANS_JOIN_NOSTART (__TRANS_JOIN_NOSTART)

#define TRANS_EXTWRITERS (__TRANS_START | __TRANS_ATTACH)
@@ -288,7 +286,6 @@ struct btrfs_trans_handle *btrfs_start_transaction_fallback_global_rsv(
struct btrfs_root *root,
unsigned int num_items);
struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root);
-struct btrfs_trans_handle *btrfs_join_transaction_spacecache(struct btrfs_root *root);
struct btrfs_trans_handle *btrfs_join_transaction_nostart(struct btrfs_root *root);
struct btrfs_trans_handle *btrfs_attach_transaction(struct btrfs_root *root);
struct btrfs_trans_handle *btrfs_attach_transaction_barrier(

--
2.39.5