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

Commit 63d871cb authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pull md bugfixes from Neil Brown:
 "Here are the bug-fixes I promised :-)

  Funny how you start looking for one and other start appearing.

   - raid6 data corruption during recovery
   - raid6 livelock
   - raid10 memory leaks"

* tag 'md/3.17-fixes' of git://neil.brown.name/md:
  md/raid10: always initialise ->state on newly allocated r10_bio
  md/raid10: avoid memory leak on error path during reshape.
  md/raid10: Fix memory leak when raid10 reshape completes.
  md/raid10: fix memory leak when reshaping a RAID10.
  md/raid6: avoid data corruption during recovery of double-degraded RAID6
  md/raid5: avoid livelock caused by non-aligned writes.
parents f17a6f78 cb8b12b5
Loading
Loading
Loading
Loading
+6 −1
Original line number Diff line number Diff line
@@ -2953,6 +2953,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr,
		 */
		if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery)) {
			end_reshape(conf);
			close_sync(conf);
			return 0;
		}

@@ -3081,6 +3082,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr,
			}

			r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO);
			r10_bio->state = 0;
			raise_barrier(conf, rb2 != NULL);
			atomic_set(&r10_bio->remaining, 0);

@@ -3269,6 +3271,7 @@ static sector_t sync_request(struct mddev *mddev, sector_t sector_nr,
		if (sync_blocks < max_sync)
			max_sync = sync_blocks;
		r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO);
		r10_bio->state = 0;

		r10_bio->mddev = mddev;
		atomic_set(&r10_bio->remaining, 0);
@@ -4384,6 +4387,7 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr,
read_more:
	/* Now schedule reads for blocks from sector_nr to last */
	r10_bio = mempool_alloc(conf->r10buf_pool, GFP_NOIO);
	r10_bio->state = 0;
	raise_barrier(conf, sectors_done != 0);
	atomic_set(&r10_bio->remaining, 0);
	r10_bio->mddev = mddev;
@@ -4398,6 +4402,7 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr,
		 * on all the target devices.
		 */
		// FIXME
		mempool_free(r10_bio, conf->r10buf_pool);
		set_bit(MD_RECOVERY_INTR, &mddev->recovery);
		return sectors_done;
	}
@@ -4410,7 +4415,7 @@ static sector_t reshape_request(struct mddev *mddev, sector_t sector_nr,
	read_bio->bi_private = r10_bio;
	read_bio->bi_end_io = end_sync_read;
	read_bio->bi_rw = READ;
	read_bio->bi_flags &= ~(BIO_POOL_MASK - 1);
	read_bio->bi_flags &= (~0UL << BIO_RESET_BITS);
	read_bio->bi_flags |= 1 << BIO_UPTODATE;
	read_bio->bi_vcnt = 0;
	read_bio->bi_iter.bi_size = 0;
+3 −1
Original line number Diff line number Diff line
@@ -2922,7 +2922,7 @@ static int fetch_block(struct stripe_head *sh, struct stripe_head_state *s,
	      (!test_bit(R5_Insync, &dev->flags) || test_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) &&
	      !test_bit(R5_OVERWRITE, &fdev[0]->flags)) ||
	     (sh->raid_conf->level == 6 && s->failed && s->to_write &&
	      s->to_write < sh->raid_conf->raid_disks - 2 &&
	      s->to_write - s->non_overwrite < sh->raid_conf->raid_disks - 2 &&
	      (!test_bit(R5_Insync, &dev->flags) || test_bit(STRIPE_PREREAD_ACTIVE, &sh->state))))) {
		/* we would like to get this block, possibly by computing it,
		 * otherwise read it if the backing disk is insync
@@ -3817,6 +3817,8 @@ static void handle_stripe(struct stripe_head *sh)
				set_bit(R5_Wantwrite, &dev->flags);
				if (prexor)
					continue;
				if (s.failed > 1)
					continue;
				if (!test_bit(R5_Insync, &dev->flags) ||
				    ((i == sh->pd_idx || i == sh->qd_idx)  &&
				     s.failed == 0))