diff options
Diffstat (limited to 'fs/btrfs/scrub.c')
| -rw-r--r-- | fs/btrfs/scrub.c | 25 | 
1 files changed, 18 insertions, 7 deletions
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index fab420db5121..9770cc5bfb76 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c @@ -25,6 +25,7 @@  #include "transaction.h"  #include "backref.h"  #include "extent_io.h" +#include "check-integrity.h"  /*   * This is only the first step towards a full-features scrub. It reads all @@ -256,6 +257,11 @@ static int scrub_print_warning_inode(u64 inum, u64 offset, u64 root, void *ctx)  	btrfs_release_path(swarn->path);  	ipath = init_ipath(4096, local_root, swarn->path); +	if (IS_ERR(ipath)) { +		ret = PTR_ERR(ipath); +		ipath = NULL; +		goto err; +	}  	ret = paths_from_inode(inum, ipath);  	if (ret < 0) @@ -304,7 +310,7 @@ static void scrub_print_warning(const char *errstr, struct scrub_bio *sbio,  	u8 ref_level;  	unsigned long ptr = 0;  	const int bufsize = 4096; -	u64 extent_offset; +	u64 extent_item_pos;  	path = btrfs_alloc_path(); @@ -324,12 +330,13 @@ static void scrub_print_warning(const char *errstr, struct scrub_bio *sbio,  	if (ret < 0)  		goto out; -	extent_offset = swarn.logical - found_key.objectid; +	extent_item_pos = swarn.logical - found_key.objectid;  	swarn.extent_item_size = found_key.offset;  	eb = path->nodes[0];  	ei = btrfs_item_ptr(eb, path->slots[0], struct btrfs_extent_item);  	item_size = btrfs_item_size_nr(eb, path->slots[0]); +	btrfs_release_path(path);  	if (ret & BTRFS_EXTENT_FLAG_TREE_BLOCK) {  		do { @@ -346,7 +353,7 @@ static void scrub_print_warning(const char *errstr, struct scrub_bio *sbio,  	} else {  		swarn.path = path;  		iterate_extent_inodes(fs_info, path, found_key.objectid, -					extent_offset, +					extent_item_pos,  					scrub_print_warning_inode, &swarn);  	} @@ -727,7 +734,7 @@ static int scrub_fixup_io(int rw, struct block_device *bdev, sector_t sector,  	bio_add_page(bio, page, PAGE_SIZE, 0);  	bio->bi_end_io = scrub_fixup_end_io;  	bio->bi_private = &complete; -	submit_bio(rw, bio); +	btrfsic_submit_bio(rw, bio);  	/* this will also unplug the queue */  	wait_for_completion(&complete); @@ -953,7 +960,7 @@ static int scrub_submit(struct scrub_dev *sdev)  	sdev->curr = -1;  	atomic_inc(&sdev->in_flight); -	submit_bio(READ, sbio->bio); +	btrfsic_submit_bio(READ, sbio->bio);  	return 0;  } @@ -1530,18 +1537,22 @@ static noinline_for_stack int scrub_supers(struct scrub_dev *sdev)  static noinline_for_stack int scrub_workers_get(struct btrfs_root *root)  {  	struct btrfs_fs_info *fs_info = root->fs_info; +	int ret = 0;  	mutex_lock(&fs_info->scrub_lock);  	if (fs_info->scrub_workers_refcnt == 0) {  		btrfs_init_workers(&fs_info->scrub_workers, "scrub",  			   fs_info->thread_pool_size, &fs_info->generic_worker);  		fs_info->scrub_workers.idle_thresh = 4; -		btrfs_start_workers(&fs_info->scrub_workers, 1); +		ret = btrfs_start_workers(&fs_info->scrub_workers); +		if (ret) +			goto out;  	}  	++fs_info->scrub_workers_refcnt; +out:  	mutex_unlock(&fs_info->scrub_lock); -	return 0; +	return ret;  }  static noinline_for_stack void scrub_workers_put(struct btrfs_root *root)  |