aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorLinus Torvalds <[email protected]>2025-09-11 15:01:18 +0000
committerLinus Torvalds <[email protected]>2025-09-11 15:01:18 +0000
commitb10c31b70bf00ba4688c4b364691640a92b7f4bf (patch)
tree38b4cd8bc0c24f5df8f51fb7c2c2d6551b850c05 /fs/btrfs/inode.c
parentMerge tag 'bpf-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf (diff)
parentbtrfs: don't allow adding block device of less than 1 MB (diff)
downloadkernel-b10c31b70bf00ba4688c4b364691640a92b7f4bf.tar.gz
kernel-b10c31b70bf00ba4688c4b364691640a92b7f4bf.zip
Merge tag 'for-6.17-rc5-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: - fix delayed inode tracking in xarray, eviction can race with insertion and leave behind a disconnected inode - on systems with large page (64K) and small block size (4K) fix compression read that can return partially filled folio - slightly relax compression option format for backward compatibility, allow to specify level for LZO although there's only one - fix simple quota accounting of compressed extents - validate minimum device size in 'device add' - update maintainers' entry * tag 'for-6.17-rc5-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: don't allow adding block device of less than 1 MB MAINTAINERS: update btrfs entry btrfs: fix subvolume deletion lockup caused by inodes xarray race btrfs: fix corruption reading compressed range when block size is smaller than page size btrfs: accept and ignore compression level for lzo btrfs: fix squota compressed stats leak
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index dd82dcc7b2b7..e7218e78bff4 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -5696,7 +5696,17 @@ static void btrfs_del_inode_from_root(struct btrfs_inode *inode)
bool empty = false;
xa_lock(&root->inodes);
- entry = __xa_erase(&root->inodes, btrfs_ino(inode));
+ /*
+ * This btrfs_inode is being freed and has already been unhashed at this
+ * point. It's possible that another btrfs_inode has already been
+ * allocated for the same inode and inserted itself into the root, so
+ * don't delete it in that case.
+ *
+ * Note that this shouldn't need to allocate memory, so the gfp flags
+ * don't really matter.
+ */
+ entry = __xa_cmpxchg(&root->inodes, btrfs_ino(inode), inode, NULL,
+ GFP_ATOMIC);
if (entry == inode)
empty = xa_empty(&root->inodes);
xa_unlock(&root->inodes);