Commit 7d251bec authored by Jens Axboe's avatar Jens Axboe
Browse files

Merge tag 'md-6.11-20240704' of...

Merge tag 'md-6.11-20240704' of git://git.kernel.org/pub/scm/linux/kernel/git/song/md into for-6.11/block

Merge MD fixes from Song:

"This PR contains various small fixes by Yu Kuai,
 Benjamin Marzinski, Christophe JAILLET, and Yang Li."

* tag 'md-6.11-20240704' of git://git.kernel.org/pub/scm/linux/kernel/git/song/md:
  md/raid5: recheck if reshape has finished with device_lock held
  md: Don't wait for MD_RECOVERY_NEEDED for HOT_REMOVE_DISK ioctl
  md-cluster: Constify struct md_cluster_operations
  md: Remove unneeded semicolon
  md/raid5: fix spares errors about rcu usage
parents 162e0687 25b3a823
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -1570,7 +1570,7 @@ static int gather_bitmaps(struct md_rdev *rdev)
	return err;
}

static struct md_cluster_operations cluster_ops = {
static const struct md_cluster_operations cluster_ops = {
	.join   = join,
	.leave  = leave,
	.slot_number = slot_number,
+3 −9
Original line number Diff line number Diff line
@@ -85,7 +85,7 @@ static DEFINE_SPINLOCK(pers_lock);

static const struct kobj_type md_ktype;

struct md_cluster_operations *md_cluster_ops;
const struct md_cluster_operations *md_cluster_ops;
EXPORT_SYMBOL(md_cluster_ops);
static struct module *md_cluster_mod;

@@ -627,7 +627,7 @@ static void md_submit_flush_data(struct work_struct *ws)
		 * always is 0, make_request() will not be called here.
		 */
		if (WARN_ON_ONCE(!mddev->pers->make_request(mddev, bio)))
			bio_io_error(bio);;
			bio_io_error(bio);
	}

	/* The pair is percpu_ref_get() from md_flush_request() */
@@ -7765,12 +7765,6 @@ static int md_ioctl(struct block_device *bdev, blk_mode_t mode,
		return get_bitmap_file(mddev, argp);
	}

	if (cmd == HOT_REMOVE_DISK)
		/* need to ensure recovery thread has run */
		wait_event_interruptible_timeout(mddev->sb_wait,
						 !test_bit(MD_RECOVERY_NEEDED,
							   &mddev->recovery),
						 msecs_to_jiffies(5000));
	if (cmd == STOP_ARRAY || cmd == STOP_ARRAY_RO) {
		/* Need to flush page cache, and ensure no-one else opens
		 * and writes
@@ -8543,7 +8537,7 @@ int unregister_md_personality(struct md_personality *p)
}
EXPORT_SYMBOL(unregister_md_personality);

int register_md_cluster_operations(struct md_cluster_operations *ops,
int register_md_cluster_operations(const struct md_cluster_operations *ops,
				   struct module *module)
{
	int ret = 0;
+2 −2
Original line number Diff line number Diff line
@@ -849,7 +849,7 @@ static inline void safe_put_page(struct page *p)

extern int register_md_personality(struct md_personality *p);
extern int unregister_md_personality(struct md_personality *p);
extern int register_md_cluster_operations(struct md_cluster_operations *ops,
extern int register_md_cluster_operations(const struct md_cluster_operations *ops,
		struct module *module);
extern int unregister_md_cluster_operations(void);
extern int md_setup_cluster(struct mddev *mddev, int nodes);
@@ -932,7 +932,7 @@ static inline void rdev_dec_pending(struct md_rdev *rdev, struct mddev *mddev)
	}
}

extern struct md_cluster_operations *md_cluster_ops;
extern const struct md_cluster_operations *md_cluster_ops;
static inline int mddev_is_clustered(struct mddev *mddev)
{
	return mddev->cluster_info && mddev->bitmap_info.nodes > 1;
+46 −30
Original line number Diff line number Diff line
@@ -5899,6 +5899,39 @@ static int add_all_stripe_bios(struct r5conf *conf,
	return ret;
}

enum reshape_loc {
	LOC_NO_RESHAPE,
	LOC_AHEAD_OF_RESHAPE,
	LOC_INSIDE_RESHAPE,
	LOC_BEHIND_RESHAPE,
};

static enum reshape_loc get_reshape_loc(struct mddev *mddev,
		struct r5conf *conf, sector_t logical_sector)
{
	sector_t reshape_progress, reshape_safe;
	/*
	 * Spinlock is needed as reshape_progress may be
	 * 64bit on a 32bit platform, and so it might be
	 * possible to see a half-updated value
	 * Of course reshape_progress could change after
	 * the lock is dropped, so once we get a reference
	 * to the stripe that we think it is, we will have
	 * to check again.
	 */
	spin_lock_irq(&conf->device_lock);
	reshape_progress = conf->reshape_progress;
	reshape_safe = conf->reshape_safe;
	spin_unlock_irq(&conf->device_lock);
	if (reshape_progress == MaxSector)
		return LOC_NO_RESHAPE;
	if (ahead_of_reshape(mddev, logical_sector, reshape_progress))
		return LOC_AHEAD_OF_RESHAPE;
	if (ahead_of_reshape(mddev, logical_sector, reshape_safe))
		return LOC_INSIDE_RESHAPE;
	return LOC_BEHIND_RESHAPE;
}

static enum stripe_result make_stripe_request(struct mddev *mddev,
		struct r5conf *conf, struct stripe_request_ctx *ctx,
		sector_t logical_sector, struct bio *bi)
@@ -5913,28 +5946,14 @@ static enum stripe_result make_stripe_request(struct mddev *mddev,
	seq = read_seqcount_begin(&conf->gen_lock);

	if (unlikely(conf->reshape_progress != MaxSector)) {
		/*
		 * Spinlock is needed as reshape_progress may be
		 * 64bit on a 32bit platform, and so it might be
		 * possible to see a half-updated value
		 * Of course reshape_progress could change after
		 * the lock is dropped, so once we get a reference
		 * to the stripe that we think it is, we will have
		 * to check again.
		 */
		spin_lock_irq(&conf->device_lock);
		if (ahead_of_reshape(mddev, logical_sector,
				     conf->reshape_progress)) {
			previous = 1;
		} else {
			if (ahead_of_reshape(mddev, logical_sector,
					     conf->reshape_safe)) {
				spin_unlock_irq(&conf->device_lock);
		enum reshape_loc loc = get_reshape_loc(mddev, conf,
						       logical_sector);
		if (loc == LOC_INSIDE_RESHAPE) {
			ret = STRIPE_SCHEDULE_AND_RETRY;
			goto out;
		}
		}
		spin_unlock_irq(&conf->device_lock);
		if (loc == LOC_AHEAD_OF_RESHAPE)
			previous = 1;
	}

	new_sector = raid5_compute_sector(conf, logical_sector, previous,
@@ -6112,8 +6131,7 @@ static bool raid5_make_request(struct mddev *mddev, struct bio * bi)
	/* Bail out if conflicts with reshape and REQ_NOWAIT is set */
	if ((bi->bi_opf & REQ_NOWAIT) &&
	    (conf->reshape_progress != MaxSector) &&
	    !ahead_of_reshape(mddev, logical_sector, conf->reshape_progress) &&
	    ahead_of_reshape(mddev, logical_sector, conf->reshape_safe)) {
	    get_reshape_loc(mddev, conf, logical_sector) == LOC_INSIDE_RESHAPE) {
		bio_wouldblock_error(bi);
		if (rw == WRITE)
			md_write_end(mddev);
@@ -7568,11 +7586,11 @@ static struct r5conf *setup_conf(struct mddev *mddev)
		if (test_bit(Replacement, &rdev->flags)) {
			if (disk->replacement)
				goto abort;
			RCU_INIT_POINTER(disk->replacement, rdev);
			disk->replacement = rdev;
		} else {
			if (disk->rdev)
				goto abort;
			RCU_INIT_POINTER(disk->rdev, rdev);
			disk->rdev = rdev;
		}

		if (test_bit(In_sync, &rdev->flags)) {
@@ -8068,15 +8086,13 @@ static void print_raid5_conf (struct r5conf *conf)
	       conf->raid_disks,
	       conf->raid_disks - conf->mddev->degraded);

	rcu_read_lock();
	for (i = 0; i < conf->raid_disks; i++) {
		rdev = rcu_dereference(conf->disks[i].rdev);
		rdev = conf->disks[i].rdev;
		if (rdev)
			pr_debug(" disk %d, o:%d, dev:%pg\n",
			       i, !test_bit(Faulty, &rdev->flags),
			       rdev->bdev);
	}
	rcu_read_unlock();
}

static int raid5_spare_active(struct mddev *mddev)