diff options
Diffstat (limited to 'fs/btrfs/bio.c')
| -rw-r--r-- | fs/btrfs/bio.c | 26 | 
1 files changed, 18 insertions, 8 deletions
diff --git a/fs/btrfs/bio.c b/fs/btrfs/bio.c index f04d93109960..b4e31ae17cd9 100644 --- a/fs/btrfs/bio.c +++ b/fs/btrfs/bio.c @@ -668,7 +668,6 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num)  {  	struct btrfs_inode *inode = bbio->inode;  	struct btrfs_fs_info *fs_info = bbio->fs_info; -	struct btrfs_bio *orig_bbio = bbio;  	struct bio *bio = &bbio->bio;  	u64 logical = bio->bi_iter.bi_sector << SECTOR_SHIFT;  	u64 length = bio->bi_iter.bi_size; @@ -706,7 +705,7 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num)  		bbio->saved_iter = bio->bi_iter;  		ret = btrfs_lookup_bio_sums(bbio);  		if (ret) -			goto fail_put_bio; +			goto fail;  	}  	if (btrfs_op(bio) == BTRFS_MAP_WRITE) { @@ -740,13 +739,13 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num)  			ret = btrfs_bio_csum(bbio);  			if (ret) -				goto fail_put_bio; +				goto fail;  		} else if (use_append ||  			   (btrfs_is_zoned(fs_info) && inode &&  			    inode->flags & BTRFS_INODE_NODATASUM)) {  			ret = btrfs_alloc_dummy_sum(bbio);  			if (ret) -				goto fail_put_bio; +				goto fail;  		}  	} @@ -754,12 +753,23 @@ static bool btrfs_submit_chunk(struct btrfs_bio *bbio, int mirror_num)  done:  	return map_length == length; -fail_put_bio: -	if (map_length < length) -		btrfs_cleanup_bio(bbio);  fail:  	btrfs_bio_counter_dec(fs_info); -	btrfs_bio_end_io(orig_bbio, ret); +	/* +	 * We have split the original bbio, now we have to end both the current +	 * @bbio and remaining one, as the remaining one will never be submitted. +	 */ +	if (map_length < length) { +		struct btrfs_bio *remaining = bbio->private; + +		ASSERT(bbio->bio.bi_pool == &btrfs_clone_bioset); +		ASSERT(remaining); + +		remaining->bio.bi_status = ret; +		btrfs_orig_bbio_end_io(remaining); +	} +	bbio->bio.bi_status = ret; +	btrfs_orig_bbio_end_io(bbio);  	/* Do not submit another chunk */  	return true;  }  | 
