Commit 9c6694bd authored by Jens Axboe's avatar Jens Axboe
Browse files

Merge branch 'md-next' of...

Merge branch 'md-next' of https://git.kernel.org/pub/scm/linux/kernel/git/song/md into for-5.5/drivers

Pull MD changes from Song.

* 'md-next' of https://git.kernel.org/pub/scm/linux/kernel/git/song/md:
  md: no longer compare spare disk superblock events in super_load
  md: improve handling of bio with REQ_PREFLUSH in md_flush_request()
  md/bitmap: avoid race window between md_bitmap_resize and bitmap_file_clear_bit
  md/raid0: Fix an error message in raid0_make_request()
parents dd85b492 6a5cb53a
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -2139,6 +2139,7 @@ int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks,
		memcpy(page_address(store.sb_page),
		       page_address(bitmap->storage.sb_page),
		       sizeof(bitmap_super_t));
	spin_lock_irq(&bitmap->counts.lock);
	md_bitmap_file_unmap(&bitmap->storage);
	bitmap->storage = store;

@@ -2154,7 +2155,6 @@ int md_bitmap_resize(struct bitmap *bitmap, sector_t blocks,
	blocks = min(old_counts.chunks << old_counts.chunkshift,
		     chunks << chunkshift);

	spin_lock_irq(&bitmap->counts.lock);
	/* For cluster raid, need to pre-allocate bitmap */
	if (mddev_is_clustered(bitmap->mddev)) {
		unsigned long page;
+2 −3
Original line number Diff line number Diff line
@@ -244,10 +244,9 @@ static bool linear_make_request(struct mddev *mddev, struct bio *bio)
	sector_t start_sector, end_sector, data_offset;
	sector_t bio_sector = bio->bi_iter.bi_sector;

	if (unlikely(bio->bi_opf & REQ_PREFLUSH)) {
		md_flush_request(mddev, bio);
	if (unlikely(bio->bi_opf & REQ_PREFLUSH)
	    && md_flush_request(mddev, bio))
		return true;
	}

	tmp_dev = which_dev(mddev, bio_sector);
	start_sector = tmp_dev->end_sector - tmp_dev->rdev->sectors;
+2 −3
Original line number Diff line number Diff line
@@ -104,10 +104,9 @@ static bool multipath_make_request(struct mddev *mddev, struct bio * bio)
	struct multipath_bh * mp_bh;
	struct multipath_info *multipath;

	if (unlikely(bio->bi_opf & REQ_PREFLUSH)) {
		md_flush_request(mddev, bio);
	if (unlikely(bio->bi_opf & REQ_PREFLUSH)
	    && md_flush_request(mddev, bio))
		return true;
	}

	mp_bh = mempool_alloc(&conf->pool, GFP_NOIO);

+60 −8
Original line number Diff line number Diff line
@@ -550,7 +550,13 @@ static void md_submit_flush_data(struct work_struct *ws)
	}
}

void md_flush_request(struct mddev *mddev, struct bio *bio)
/*
 * Manages consolidation of flushes and submitting any flushes needed for
 * a bio with REQ_PREFLUSH.  Returns true if the bio is finished or is
 * being finished in another context.  Returns false if the flushing is
 * complete but still needs the I/O portion of the bio to be processed.
 */
bool md_flush_request(struct mddev *mddev, struct bio *bio)
{
	ktime_t start = ktime_get_boottime();
	spin_lock_irq(&mddev->lock);
@@ -575,9 +581,10 @@ void md_flush_request(struct mddev *mddev, struct bio *bio)
			bio_endio(bio);
		else {
			bio->bi_opf &= ~REQ_PREFLUSH;
			mddev->pers->make_request(mddev, bio);
			return false;
		}
	}
	return true;
}
EXPORT_SYMBOL(md_flush_request);

@@ -1149,7 +1156,15 @@ static int super_90_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor
		rdev->desc_nr = sb->this_disk.number;

	if (!refdev) {
		/*
		 * Insist on good event counter while assembling, except
		 * for spares (which don't need an event count)
		 */
		if (sb->disks[rdev->desc_nr].state & (
			(1<<MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE)))
			ret = 1;
		else
			ret = 0;
	} else {
		__u64 ev1, ev2;
		mdp_super_t *refsb = page_address(refdev->sb_page);
@@ -1165,7 +1180,14 @@ static int super_90_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor
		}
		ev1 = md_event(sb);
		ev2 = md_event(refsb);
		if (ev1 > ev2)

		/*
		 * Insist on good event counter while assembling, except
		 * for spares (which don't need an event count)
		 */
		if (sb->disks[rdev->desc_nr].state & (
			(1<<MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE)) &&
			(ev1 > ev2))
			ret = 1;
		else
			ret = 0;
@@ -1525,6 +1547,7 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_
	sector_t sectors;
	char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE];
	int bmask;
	__u64 role;

	/*
	 * Calculate the position of the superblock in 512byte sectors.
@@ -1658,8 +1681,20 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_
	    sb->level != 0)
		return -EINVAL;

	role = le16_to_cpu(sb->dev_roles[rdev->desc_nr]);

	if (!refdev) {
		/*
		 * Insist of good event counter while assembling, except for
		 * spares (which don't need an event count)
		 */
		if (rdev->desc_nr >= 0 &&
		    rdev->desc_nr < le32_to_cpu(sb->max_dev) &&
			(role < MD_DISK_ROLE_MAX ||
			 role == MD_DISK_ROLE_JOURNAL))
			ret = 1;
		else
			ret = 0;
	} else {
		__u64 ev1, ev2;
		struct mdp_superblock_1 *refsb = page_address(refdev->sb_page);
@@ -1676,7 +1711,14 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_
		ev1 = le64_to_cpu(sb->events);
		ev2 = le64_to_cpu(refsb->events);

		if (ev1 > ev2)
		/*
		 * Insist of good event counter while assembling, except for
		 * spares (which don't need an event count)
		 */
		if (rdev->desc_nr >= 0 &&
		    rdev->desc_nr < le32_to_cpu(sb->max_dev) &&
			(role < MD_DISK_ROLE_MAX ||
			 role == MD_DISK_ROLE_JOURNAL) && ev1 > ev2)
			ret = 1;
		else
			ret = 0;
@@ -3597,7 +3639,7 @@ abort_free:
 * Check a full RAID array for plausibility
 */

static void analyze_sbs(struct mddev *mddev)
static int analyze_sbs(struct mddev *mddev)
{
	int i;
	struct md_rdev *rdev, *freshest, *tmp;
@@ -3618,6 +3660,12 @@ static void analyze_sbs(struct mddev *mddev)
			md_kick_rdev_from_array(rdev);
		}

	/* Cannot find a valid fresh disk */
	if (!freshest) {
		pr_warn("md: cannot find a valid disk\n");
		return -EINVAL;
	}

	super_types[mddev->major_version].
		validate_super(mddev, freshest);

@@ -3652,6 +3700,8 @@ static void analyze_sbs(struct mddev *mddev)
			clear_bit(In_sync, &rdev->flags);
		}
	}

	return 0;
}

/* Read a fixed-point number.
@@ -5570,7 +5620,9 @@ int md_run(struct mddev *mddev)
	if (!mddev->raid_disks) {
		if (!mddev->persistent)
			return -EINVAL;
		analyze_sbs(mddev);
		err = analyze_sbs(mddev);
		if (err)
			return -EINVAL;
	}

	if (mddev->level != LEVEL_NONE)
+2 −2
Original line number Diff line number Diff line
@@ -550,7 +550,7 @@ struct md_personality
	int level;
	struct list_head list;
	struct module *owner;
	bool (*make_request)(struct mddev *mddev, struct bio *bio);
	bool __must_check (*make_request)(struct mddev *mddev, struct bio *bio);
	/*
	 * start up works that do NOT require md_thread. tasks that
	 * requires md_thread should go into start()
@@ -703,7 +703,7 @@ extern void md_error(struct mddev *mddev, struct md_rdev *rdev);
extern void md_finish_reshape(struct mddev *mddev);

extern int mddev_congested(struct mddev *mddev, int bits);
extern void md_flush_request(struct mddev *mddev, struct bio *bio);
extern bool __must_check md_flush_request(struct mddev *mddev, struct bio *bio);
extern void md_super_write(struct mddev *mddev, struct md_rdev *rdev,
			   sector_t sector, int size, struct page *page);
extern int md_super_wait(struct mddev *mddev);
Loading