diff options
Diffstat (limited to 'drivers/md')
| -rw-r--r-- | drivers/md/md.c | 9 | ||||
| -rw-r--r-- | drivers/md/raid10.c | 30 | ||||
| -rw-r--r-- | drivers/md/raid10.h | 2 | 
3 files changed, 26 insertions, 15 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index fcd098794d3..3f6203a4c7e 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -1108,8 +1108,11 @@ static int super_90_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor  			ret = 0;  	}  	rdev->sectors = rdev->sb_start; -	/* Limit to 4TB as metadata cannot record more than that */ -	if (rdev->sectors >= (2ULL << 32)) +	/* Limit to 4TB as metadata cannot record more than that. +	 * (not needed for Linear and RAID0 as metadata doesn't +	 * record this size) +	 */ +	if (rdev->sectors >= (2ULL << 32) && sb->level >= 1)  		rdev->sectors = (2ULL << 32) - 2;  	if (rdev->sectors < ((sector_t)sb->size) * 2 && sb->level >= 1) @@ -1400,7 +1403,7 @@ super_90_rdev_size_change(struct md_rdev *rdev, sector_t num_sectors)  	/* Limit to 4TB as metadata cannot record more than that.  	 * 4TB == 2^32 KB, or 2*2^32 sectors.  	 */ -	if (num_sectors >= (2ULL << 32)) +	if (num_sectors >= (2ULL << 32) && rdev->mddev->level >= 1)  		num_sectors = (2ULL << 32) - 2;  	md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size,  		       rdev->sb_page); diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index de5ed6fd880..1c2eb38f3c5 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c @@ -659,7 +659,11 @@ static int raid10_mergeable_bvec(struct request_queue *q,  		max = biovec->bv_len;  	if (mddev->merge_check_needed) { -		struct r10bio r10_bio; +		struct { +			struct r10bio r10_bio; +			struct r10dev devs[conf->copies]; +		} on_stack; +		struct r10bio *r10_bio = &on_stack.r10_bio;  		int s;  		if (conf->reshape_progress != MaxSector) {  			/* Cannot give any guidance during reshape */ @@ -667,18 +671,18 @@ static int raid10_mergeable_bvec(struct request_queue *q,  				return biovec->bv_len;  			return 0;  		} -		r10_bio.sector = sector; -		raid10_find_phys(conf, &r10_bio); +		r10_bio->sector = sector; +		raid10_find_phys(conf, r10_bio);  		rcu_read_lock();  		for (s = 0; s < conf->copies; s++) { -			int disk = r10_bio.devs[s].devnum; +			int disk = r10_bio->devs[s].devnum;  			struct md_rdev *rdev = rcu_dereference(  				conf->mirrors[disk].rdev);  			if (rdev && !test_bit(Faulty, &rdev->flags)) {  				struct request_queue *q =  					bdev_get_queue(rdev->bdev);  				if (q->merge_bvec_fn) { -					bvm->bi_sector = r10_bio.devs[s].addr +					bvm->bi_sector = r10_bio->devs[s].addr  						+ rdev->data_offset;  					bvm->bi_bdev = rdev->bdev;  					max = min(max, q->merge_bvec_fn( @@ -690,7 +694,7 @@ static int raid10_mergeable_bvec(struct request_queue *q,  				struct request_queue *q =  					bdev_get_queue(rdev->bdev);  				if (q->merge_bvec_fn) { -					bvm->bi_sector = r10_bio.devs[s].addr +					bvm->bi_sector = r10_bio->devs[s].addr  						+ rdev->data_offset;  					bvm->bi_bdev = rdev->bdev;  					max = min(max, q->merge_bvec_fn( @@ -4414,14 +4418,18 @@ static int handle_reshape_read_error(struct mddev *mddev,  {  	/* Use sync reads to get the blocks from somewhere else */  	int sectors = r10_bio->sectors; -	struct r10bio r10b;  	struct r10conf *conf = mddev->private; +	struct { +		struct r10bio r10_bio; +		struct r10dev devs[conf->copies]; +	} on_stack; +	struct r10bio *r10b = &on_stack.r10_bio;  	int slot = 0;  	int idx = 0;  	struct bio_vec *bvec = r10_bio->master_bio->bi_io_vec; -	r10b.sector = r10_bio->sector; -	__raid10_find_phys(&conf->prev, &r10b); +	r10b->sector = r10_bio->sector; +	__raid10_find_phys(&conf->prev, r10b);  	while (sectors) {  		int s = sectors; @@ -4432,7 +4440,7 @@ static int handle_reshape_read_error(struct mddev *mddev,  			s = PAGE_SIZE >> 9;  		while (!success) { -			int d = r10b.devs[slot].devnum; +			int d = r10b->devs[slot].devnum;  			struct md_rdev *rdev = conf->mirrors[d].rdev;  			sector_t addr;  			if (rdev == NULL || @@ -4440,7 +4448,7 @@ static int handle_reshape_read_error(struct mddev *mddev,  			    !test_bit(In_sync, &rdev->flags))  				goto failed; -			addr = r10b.devs[slot].addr + idx * PAGE_SIZE; +			addr = r10b->devs[slot].addr + idx * PAGE_SIZE;  			success = sync_page_io(rdev,  					       addr,  					       s << 9, diff --git a/drivers/md/raid10.h b/drivers/md/raid10.h index 007c2c68dd8..1054cf60234 100644 --- a/drivers/md/raid10.h +++ b/drivers/md/raid10.h @@ -110,7 +110,7 @@ struct r10bio {  	 * We choose the number when they are allocated.  	 * We sometimes need an extra bio to write to the replacement.  	 */ -	struct { +	struct r10dev {  		struct bio	*bio;  		union {  			struct bio	*repl_bio; /* used for resync and  |