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

Commit e6036c0b authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

Pull md bugfixes from Neil Brown:
 "Assorted md bug-fixes for 3.12.

  All tagged for -stable releases too"

* tag 'md/3.12-fixes' of git://neil.brown.name/md:
  raid5: avoid finding "discard" stripe
  raid5: set bio bi_vcnt 0 for discard request
  md: avoid deadlock when md_set_badblocks.
  md: Fix skipping recovery for read-only arrays.
parents be6e8c76 d47648fc
Loading
Loading
Loading
Loading
+3 −2
Original line number Original line Diff line number Diff line
@@ -8111,6 +8111,7 @@ static int md_set_badblocks(struct badblocks *bb, sector_t s, int sectors,
	u64 *p;
	u64 *p;
	int lo, hi;
	int lo, hi;
	int rv = 1;
	int rv = 1;
	unsigned long flags;


	if (bb->shift < 0)
	if (bb->shift < 0)
		/* badblocks are disabled */
		/* badblocks are disabled */
@@ -8125,7 +8126,7 @@ static int md_set_badblocks(struct badblocks *bb, sector_t s, int sectors,
		sectors = next - s;
		sectors = next - s;
	}
	}


	write_seqlock_irq(&bb->lock);
	write_seqlock_irqsave(&bb->lock, flags);


	p = bb->page;
	p = bb->page;
	lo = 0;
	lo = 0;
@@ -8241,7 +8242,7 @@ static int md_set_badblocks(struct badblocks *bb, sector_t s, int sectors,
	bb->changed = 1;
	bb->changed = 1;
	if (!acknowledged)
	if (!acknowledged)
		bb->unacked_exist = 1;
		bb->unacked_exist = 1;
	write_sequnlock_irq(&bb->lock);
	write_sequnlock_irqrestore(&bb->lock, flags);


	return rv;
	return rv;
}
}
+1 −0
Original line number Original line Diff line number Diff line
@@ -1479,6 +1479,7 @@ static int raid1_spare_active(struct mddev *mddev)
			}
			}
		}
		}
		if (rdev
		if (rdev
		    && rdev->recovery_offset == MaxSector
		    && !test_bit(Faulty, &rdev->flags)
		    && !test_bit(Faulty, &rdev->flags)
		    && !test_and_set_bit(In_sync, &rdev->flags)) {
		    && !test_and_set_bit(In_sync, &rdev->flags)) {
			count++;
			count++;
+1 −0
Original line number Original line Diff line number Diff line
@@ -1782,6 +1782,7 @@ static int raid10_spare_active(struct mddev *mddev)
			}
			}
			sysfs_notify_dirent_safe(tmp->replacement->sysfs_state);
			sysfs_notify_dirent_safe(tmp->replacement->sysfs_state);
		} else if (tmp->rdev
		} else if (tmp->rdev
			   && tmp->rdev->recovery_offset == MaxSector
			   && !test_bit(Faulty, &tmp->rdev->flags)
			   && !test_bit(Faulty, &tmp->rdev->flags)
			   && !test_and_set_bit(In_sync, &tmp->rdev->flags)) {
			   && !test_and_set_bit(In_sync, &tmp->rdev->flags)) {
			count++;
			count++;
+20 −0
Original line number Original line Diff line number Diff line
@@ -778,6 +778,12 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s)
			bi->bi_io_vec[0].bv_len = STRIPE_SIZE;
			bi->bi_io_vec[0].bv_len = STRIPE_SIZE;
			bi->bi_io_vec[0].bv_offset = 0;
			bi->bi_io_vec[0].bv_offset = 0;
			bi->bi_size = STRIPE_SIZE;
			bi->bi_size = STRIPE_SIZE;
			/*
			 * If this is discard request, set bi_vcnt 0. We don't
			 * want to confuse SCSI because SCSI will replace payload
			 */
			if (rw & REQ_DISCARD)
				bi->bi_vcnt = 0;
			if (rrdev)
			if (rrdev)
				set_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags);
				set_bit(R5_DOUBLE_LOCKED, &sh->dev[i].flags);


@@ -816,6 +822,12 @@ static void ops_run_io(struct stripe_head *sh, struct stripe_head_state *s)
			rbi->bi_io_vec[0].bv_len = STRIPE_SIZE;
			rbi->bi_io_vec[0].bv_len = STRIPE_SIZE;
			rbi->bi_io_vec[0].bv_offset = 0;
			rbi->bi_io_vec[0].bv_offset = 0;
			rbi->bi_size = STRIPE_SIZE;
			rbi->bi_size = STRIPE_SIZE;
			/*
			 * If this is discard request, set bi_vcnt 0. We don't
			 * want to confuse SCSI because SCSI will replace payload
			 */
			if (rw & REQ_DISCARD)
				rbi->bi_vcnt = 0;
			if (conf->mddev->gendisk)
			if (conf->mddev->gendisk)
				trace_block_bio_remap(bdev_get_queue(rbi->bi_bdev),
				trace_block_bio_remap(bdev_get_queue(rbi->bi_bdev),
						      rbi, disk_devt(conf->mddev->gendisk),
						      rbi, disk_devt(conf->mddev->gendisk),
@@ -2910,6 +2922,14 @@ static void handle_stripe_clean_event(struct r5conf *conf,
		}
		}
		/* now that discard is done we can proceed with any sync */
		/* now that discard is done we can proceed with any sync */
		clear_bit(STRIPE_DISCARD, &sh->state);
		clear_bit(STRIPE_DISCARD, &sh->state);
		/*
		 * SCSI discard will change some bio fields and the stripe has
		 * no updated data, so remove it from hash list and the stripe
		 * will be reinitialized
		 */
		spin_lock_irq(&conf->device_lock);
		remove_hash(sh);
		spin_unlock_irq(&conf->device_lock);
		if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state))
		if (test_bit(STRIPE_SYNC_REQUESTED, &sh->state))
			set_bit(STRIPE_HANDLE, &sh->state);
			set_bit(STRIPE_HANDLE, &sh->state);