]> asedeno.scripts.mit.edu Git - linux.git/blobdiff - fs/btrfs/extent_map.c
Merge tag 'ras-urgent-2020-02-22' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux.git] / fs / btrfs / extent_map.c
index 6f417ff68980f68f26eb89b6689a732d15a5b2bf..bd6229fb2b6f0cae346f72afc4324463ccfac578 100644 (file)
@@ -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)