summaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent_map.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2020-02-16 20:43:45 +0100
committerLinus Torvalds <torvalds@linux-foundation.org>2020-02-16 20:43:45 +0100
commit713db356041071d16360e82247de3107ec9ed57f (patch)
treeef2d0a469f4da52c39b8d3e296689362e97a9c17 /fs/btrfs/extent_map.c
parentMerge tag '5.6-rc1-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6 (diff)
parentbtrfs: sysfs, move device id directories to UUID/devinfo (diff)
downloadlinux-713db356041071d16360e82247de3107ec9ed57f.tar.xz
linux-713db356041071d16360e82247de3107ec9ed57f.zip
Merge tag 'for-5.6-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: "Two races fixed, memory leak fix, sysfs directory fixup and two new log messages: - two fixed race conditions: extent map merging and truncate vs fiemap - create the right sysfs directory with device information and move the individual device dirs under it - print messages when the tree-log is replayed at mount time or cannot be replayed on remount" * tag 'for-5.6-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: btrfs: sysfs, move device id directories to UUID/devinfo btrfs: sysfs, add UUID/devinfo kobject Btrfs: fix race between shrinking truncate and fiemap btrfs: log message when rw remount is attempted with unclean tree-log btrfs: print message when tree-log replay starts Btrfs: fix race between using extent maps and merging them btrfs: ref-verify: fix memory leaks
Diffstat (limited to 'fs/btrfs/extent_map.c')
-rw-r--r--fs/btrfs/extent_map.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c
index 6f417ff68980..bd6229fb2b6f 100644
--- a/fs/btrfs/extent_map.c
+++ b/fs/btrfs/extent_map.c
@@ -237,6 +237,17 @@ static void try_merge_map(struct extent_map_tree *tree, struct extent_map *em)
struct extent_map *merge = NULL;
struct rb_node *rb;
+ /*
+ * We can't modify an extent map that is in the tree and that is being
+ * used by another task, as it can cause that other task to see it in
+ * inconsistent state during the merging. We always have 1 reference for
+ * the tree and 1 for this task (which is unpinning the extent map or
+ * clearing the logging flag), so anything > 2 means it's being used by
+ * other tasks too.
+ */
+ if (refcount_read(&em->refs) > 2)
+ return;
+
if (em->start != 0) {
rb = rb_prev(&em->rb_node);
if (rb)