btrfs: Skip scrubbing removed chunks to avoid -ENOENT.
[cascardo/linux.git] / fs / btrfs / scrub.c
index 0be7799..b6d198f 100644 (file)
@@ -588,8 +588,9 @@ static void scrub_print_warning(const char *errstr, struct scrub_block *sblock)
 
        if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) {
                do {
-                       ret = tree_backref_for_extent(&ptr, eb, ei, item_size,
-                                                       &ref_root, &ref_level);
+                       ret = tree_backref_for_extent(&ptr, eb, &found_key, ei,
+                                                     item_size, &ref_root,
+                                                     &ref_level);
                        printk_in_rcu(KERN_WARNING
                                "BTRFS: %s at logical %llu on dev %s, "
                                "sector %llu: metadata %s (level %d) in tree "
@@ -717,8 +718,8 @@ static int scrub_fixup_readpage(u64 inum, u64 offset, u64 root, void *fixup_ctx)
 out:
        if (page)
                put_page(page);
-       if (inode)
-               iput(inode);
+
+       iput(inode);
 
        if (ret < 0)
                return ret;
@@ -2724,11 +2725,8 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,
                dev_extent = btrfs_item_ptr(l, slot, struct btrfs_dev_extent);
                length = btrfs_dev_extent_length(l, dev_extent);
 
-               if (found_key.offset + length <= start) {
-                       key.offset = found_key.offset + length;
-                       btrfs_release_path(path);
-                       continue;
-               }
+               if (found_key.offset + length <= start)
+                       goto skip;
 
                chunk_tree = btrfs_dev_extent_chunk_tree(l, dev_extent);
                chunk_objectid = btrfs_dev_extent_chunk_objectid(l, dev_extent);
@@ -2739,10 +2737,12 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,
                 * the chunk from going away while we scrub it
                 */
                cache = btrfs_lookup_block_group(fs_info, chunk_offset);
-               if (!cache) {
-                       ret = -ENOENT;
-                       break;
-               }
+
+               /* some chunks are removed but not committed to disk yet,
+                * continue scrubbing */
+               if (!cache)
+                       goto skip;
+
                dev_replace->cursor_right = found_key.offset + length;
                dev_replace->cursor_left = found_key.offset;
                dev_replace->item_needs_writeback = 1;
@@ -2801,7 +2801,7 @@ int scrub_enumerate_chunks(struct scrub_ctx *sctx,
 
                dev_replace->cursor_left = dev_replace->cursor_right;
                dev_replace->item_needs_writeback = 1;
-
+skip:
                key.offset = found_key.offset + length;
                btrfs_release_path(path);
        }