diff options
Diffstat (limited to 'drivers/md')
| -rw-r--r-- | drivers/md/bcache/super.c | 14 | ||||
| -rw-r--r-- | drivers/md/dm-flakey.c | 27 | ||||
| -rw-r--r-- | drivers/md/dm-log.c | 11 | 
3 files changed, 32 insertions, 20 deletions
| diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c index 95a4ca6ce6ff..849ad441cd76 100644 --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c @@ -760,7 +760,8 @@ static int bcache_device_init(struct bcache_device *d, unsigned block_size,  	if (!d->nr_stripes ||  	    d->nr_stripes > INT_MAX ||  	    d->nr_stripes > SIZE_MAX / sizeof(atomic_t)) { -		pr_err("nr_stripes too large"); +		pr_err("nr_stripes too large or invalid: %u (start sector beyond end of disk?)", +			(unsigned)d->nr_stripes);  		return -ENOMEM;  	} @@ -1820,7 +1821,7 @@ static int cache_alloc(struct cache *ca)  	free = roundup_pow_of_two(ca->sb.nbuckets) >> 10;  	if (!init_fifo(&ca->free[RESERVE_BTREE], 8, GFP_KERNEL) || -	    !init_fifo(&ca->free[RESERVE_PRIO], prio_buckets(ca), GFP_KERNEL) || +	    !init_fifo_exact(&ca->free[RESERVE_PRIO], prio_buckets(ca), GFP_KERNEL) ||  	    !init_fifo(&ca->free[RESERVE_MOVINGGC], free, GFP_KERNEL) ||  	    !init_fifo(&ca->free[RESERVE_NONE], free, GFP_KERNEL) ||  	    !init_fifo(&ca->free_inc,	free << 2, GFP_KERNEL) || @@ -1844,7 +1845,7 @@ static int register_cache(struct cache_sb *sb, struct page *sb_page,  				struct block_device *bdev, struct cache *ca)  {  	char name[BDEVNAME_SIZE]; -	const char *err = NULL; +	const char *err = NULL; /* must be set for any error case */  	int ret = 0;  	memcpy(&ca->sb, sb, sizeof(struct cache_sb)); @@ -1861,8 +1862,13 @@ static int register_cache(struct cache_sb *sb, struct page *sb_page,  		ca->discard = CACHE_DISCARD(&ca->sb);  	ret = cache_alloc(ca); -	if (ret != 0) +	if (ret != 0) { +		if (ret == -ENOMEM) +			err = "cache_alloc(): -ENOMEM"; +		else +			err = "cache_alloc(): unknown error";  		goto err; +	}  	if (kobject_add(&ca->kobj, &part_to_dev(bdev->bd_part)->kobj, "bcache")) {  		err = "error calling kobject_add"; diff --git a/drivers/md/dm-flakey.c b/drivers/md/dm-flakey.c index 97e446d54a15..6a2e8dd44a1b 100644 --- a/drivers/md/dm-flakey.c +++ b/drivers/md/dm-flakey.c @@ -289,15 +289,13 @@ static int flakey_map(struct dm_target *ti, struct bio *bio)  		pb->bio_submitted = true;  		/* -		 * Map reads as normal only if corrupt_bio_byte set. +		 * Error reads if neither corrupt_bio_byte or drop_writes are set. +		 * Otherwise, flakey_end_io() will decide if the reads should be modified.  		 */  		if (bio_data_dir(bio) == READ) { -			/* If flags were specified, only corrupt those that match. */ -			if (fc->corrupt_bio_byte && (fc->corrupt_bio_rw == READ) && -			    all_corrupt_bio_flags_match(bio, fc)) -				goto map_bio; -			else +			if (!fc->corrupt_bio_byte && !test_bit(DROP_WRITES, &fc->flags))  				return -EIO; +			goto map_bio;  		}  		/* @@ -334,14 +332,21 @@ static int flakey_end_io(struct dm_target *ti, struct bio *bio, int error)  	struct flakey_c *fc = ti->private;  	struct per_bio_data *pb = dm_per_bio_data(bio, sizeof(struct per_bio_data)); -	/* -	 * Corrupt successful READs while in down state. -	 */  	if (!error && pb->bio_submitted && (bio_data_dir(bio) == READ)) { -		if (fc->corrupt_bio_byte) +		if (fc->corrupt_bio_byte && (fc->corrupt_bio_rw == READ) && +		    all_corrupt_bio_flags_match(bio, fc)) { +			/* +			 * Corrupt successful matching READs while in down state. +			 */  			corrupt_bio_data(bio, fc); -		else + +		} else if (!test_bit(DROP_WRITES, &fc->flags)) { +			/* +			 * Error read during the down_interval if drop_writes +			 * wasn't configured. +			 */  			return -EIO; +		}  	}  	return error; diff --git a/drivers/md/dm-log.c b/drivers/md/dm-log.c index 4ca2d1df5b44..07fc1ad42ec5 100644 --- a/drivers/md/dm-log.c +++ b/drivers/md/dm-log.c @@ -291,9 +291,10 @@ static void header_from_disk(struct log_header_core *core, struct log_header_dis  	core->nr_regions = le64_to_cpu(disk->nr_regions);  } -static int rw_header(struct log_c *lc, int rw) +static int rw_header(struct log_c *lc, int op)  { -	lc->io_req.bi_op = rw; +	lc->io_req.bi_op = op; +	lc->io_req.bi_op_flags = 0;  	return dm_io(&lc->io_req, 1, &lc->header_location, NULL);  } @@ -316,7 +317,7 @@ static int read_header(struct log_c *log)  {  	int r; -	r = rw_header(log, READ); +	r = rw_header(log, REQ_OP_READ);  	if (r)  		return r; @@ -630,7 +631,7 @@ static int disk_resume(struct dm_dirty_log *log)  	header_to_disk(&lc->header, lc->disk_header);  	/* write the new header */ -	r = rw_header(lc, WRITE); +	r = rw_header(lc, REQ_OP_WRITE);  	if (!r) {  		r = flush_header(lc);  		if (r) @@ -698,7 +699,7 @@ static int disk_flush(struct dm_dirty_log *log)  			log_clear_bit(lc, lc->clean_bits, i);  	} -	r = rw_header(lc, WRITE); +	r = rw_header(lc, REQ_OP_WRITE);  	if (r)  		fail_log_device(lc);  	else { |