Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1ce41cd8 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'md-3.6-fixes' of git://neil.brown.name/md

Pull md fixes from NeilBrown:
 "2 fixes for md, tagged for -stable"

* tag 'md-3.6-fixes' of git://neil.brown.name/md:
  md/raid10: fix problem with on-stack allocation of r10bio structure.
  md: Don't truncate size at 4TB for RAID0 and Linear
parents 846b9996 e0ee7785
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -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);
+19 −11
Original line number Diff line number Diff line
@@ -659,7 +659,11 @@ static int raid10_mergeable_bvec(struct request_queue *q,
		max = biovec->bv_len;

	if (mddev->merge_check_needed) {
		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,
+1 −1
Original line number Diff line number Diff line
@@ -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