Commit 6c88d735 authored by Jens Axboe's avatar Jens Axboe
Browse files

Merge branch 'md-next' of https://github.com/liu-song-6/linux into for-5.2/block

Pull MD fixes from Song.

* 'md-next' of https://github.com/liu-song-6/linux:
  md/raid: raid5 preserve the writeback action after the parity check
  Revert "Don't jump to compute_result state from check_result state"
  md: return -ENODEV if rdev has no mddev assigned
  block: fix use-after-free on gendisk
parents 4d25339e b2176a1d
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -3380,10 +3380,10 @@ rdev_attr_store(struct kobject *kobj, struct attribute *attr,
		return -EIO;
	if (!capable(CAP_SYS_ADMIN))
		return -EACCES;
	rv = mddev ? mddev_lock(mddev): -EBUSY;
	rv = mddev ? mddev_lock(mddev) : -ENODEV;
	if (!rv) {
		if (rdev->mddev == NULL)
			rv = -EBUSY;
			rv = -ENODEV;
		else
			rv = entry->store(rdev, page, length);
		mddev_unlock(mddev);
+24 −5
Original line number Diff line number Diff line
@@ -4191,7 +4191,7 @@ static void handle_parity_checks6(struct r5conf *conf, struct stripe_head *sh,
		/* now write out any block on a failed drive,
		 * or P or Q if they were recomputed
		 */
		BUG_ON(s->uptodate < disks - 1); /* We don't need Q to recover */
		dev = NULL;
		if (s->failed == 2) {
			dev = &sh->dev[s->failed_num[1]];
			s->locked++;
@@ -4216,6 +4216,14 @@ static void handle_parity_checks6(struct r5conf *conf, struct stripe_head *sh,
			set_bit(R5_LOCKED, &dev->flags);
			set_bit(R5_Wantwrite, &dev->flags);
		}
		if (WARN_ONCE(dev && !test_bit(R5_UPTODATE, &dev->flags),
			      "%s: disk%td not up to date\n",
			      mdname(conf->mddev),
			      dev - (struct r5dev *) &sh->dev)) {
			clear_bit(R5_LOCKED, &dev->flags);
			clear_bit(R5_Wantwrite, &dev->flags);
			s->locked--;
		}
		clear_bit(STRIPE_DEGRADED, &sh->state);

		set_bit(STRIPE_INSYNC, &sh->state);
@@ -4227,15 +4235,26 @@ static void handle_parity_checks6(struct r5conf *conf, struct stripe_head *sh,
	case check_state_check_result:
		sh->check_state = check_state_idle;

		if (s->failed > 1)
			break;
		/* handle a successful check operation, if parity is correct
		 * we are done.  Otherwise update the mismatch count and repair
		 * parity if !MD_RECOVERY_CHECK
		 */
		if (sh->ops.zero_sum_result == 0) {
			/* Any parity checked was correct */
			/* both parities are correct */
			if (!s->failed)
				set_bit(STRIPE_INSYNC, &sh->state);
			else {
				/* in contrast to the raid5 case we can validate
				 * parity, but still have a failure to write
				 * back
				 */
				sh->check_state = check_state_compute_result;
				/* Returning at this point means that we may go
				 * off and bring p and/or q uptodate again so
				 * we make sure to check zero_sum_result again
				 * to verify if p or q need writeback
				 */
			}
		} else {
			atomic64_add(STRIPE_SECTORS, &conf->mddev->resync_mismatches);
			if (test_bit(MD_RECOVERY_CHECK, &conf->mddev->recovery)) {