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

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

Pull MD fixes from Song.

* 'for-5.1/md-post' of https://github.com/liu-song-6/linux:
  md: Fix failed allocation of md_register_thread
  It's wrong to add len to sector_nr in raid10 reshape twice
  raid5: set write hint for PPL
parents 9205e449 e406f12d
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -756,3 +756,6 @@ These currently include:
      The cache mode for raid5. raid5 could include an extra disk for
      caching. The mode can be "write-throuth" and "write-back". The
      default is "write-through".

  ppl_write_hint
      NVMe stream ID to be set for each PPL write request.
+2 −1
Original line number Diff line number Diff line
@@ -3939,6 +3939,8 @@ static int raid10_run(struct mddev *mddev)
		set_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
		mddev->sync_thread = md_register_thread(md_do_sync, mddev,
							"reshape");
		if (!mddev->sync_thread)
			goto out_free_conf;
	}

	return 0;
@@ -4670,7 +4672,6 @@ read_more:
	atomic_inc(&r10_bio->remaining);
	read_bio->bi_next = NULL;
	generic_make_request(read_bio);
	sector_nr += nr_sectors;
	sectors_done += nr_sectors;
	if (sector_nr <= last)
		goto read_more;
+1 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ extern void ppl_stripe_write_finished(struct stripe_head *sh);
extern int ppl_modify_log(struct r5conf *conf, struct md_rdev *rdev, bool add);
extern void ppl_quiesce(struct r5conf *conf, int quiesce);
extern int ppl_handle_flush_request(struct r5l_log *log, struct bio *bio);
extern struct md_sysfs_entry ppl_write_hint;

static inline bool raid5_has_log(struct r5conf *conf)
{
+63 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <linux/raid/md_p.h>
#include "md.h"
#include "raid5.h"
#include "raid5-log.h"

/*
 * PPL consists of a 4KB header (struct ppl_header) and at least 128KB for
@@ -116,6 +117,8 @@ struct ppl_conf {
	/* stripes to retry if failed to allocate io_unit */
	struct list_head no_mem_stripes;
	spinlock_t no_mem_stripes_lock;

	unsigned short write_hint;
};

struct ppl_log {
@@ -476,6 +479,7 @@ static void ppl_submit_iounit(struct ppl_io_unit *io)
	bio_set_dev(bio, log->rdev->bdev);
	bio->bi_iter.bi_sector = log->next_io_sector;
	bio_add_page(bio, io->header_page, PAGE_SIZE, 0);
	bio->bi_write_hint = ppl_conf->write_hint;

	pr_debug("%s: log->current_io_sector: %llu\n", __func__,
	    (unsigned long long)log->next_io_sector);
@@ -505,6 +509,7 @@ static void ppl_submit_iounit(struct ppl_io_unit *io)
			bio = bio_alloc_bioset(GFP_NOIO, BIO_MAX_PAGES,
					       &ppl_conf->bs);
			bio->bi_opf = prev->bi_opf;
			bio->bi_write_hint = prev->bi_write_hint;
			bio_copy_dev(bio, prev);
			bio->bi_iter.bi_sector = bio_end_sector(prev);
			bio_add_page(bio, sh->ppl_page, PAGE_SIZE, 0);
@@ -1409,6 +1414,7 @@ int ppl_init_log(struct r5conf *conf)
	atomic64_set(&ppl_conf->seq, 0);
	INIT_LIST_HEAD(&ppl_conf->no_mem_stripes);
	spin_lock_init(&ppl_conf->no_mem_stripes_lock);
	ppl_conf->write_hint = RWF_WRITE_LIFE_NOT_SET;

	if (!mddev->external) {
		ppl_conf->signature = ~crc32c_le(~0, mddev->uuid, sizeof(mddev->uuid));
@@ -1503,3 +1509,60 @@ int ppl_modify_log(struct r5conf *conf, struct md_rdev *rdev, bool add)

	return ret;
}

static ssize_t
ppl_write_hint_show(struct mddev *mddev, char *buf)
{
	size_t ret = 0;
	struct r5conf *conf;
	struct ppl_conf *ppl_conf = NULL;

	spin_lock(&mddev->lock);
	conf = mddev->private;
	if (conf && raid5_has_ppl(conf))
		ppl_conf = conf->log_private;
	ret = sprintf(buf, "%d\n", ppl_conf ? ppl_conf->write_hint : 0);
	spin_unlock(&mddev->lock);

	return ret;
}

static ssize_t
ppl_write_hint_store(struct mddev *mddev, const char *page, size_t len)
{
	struct r5conf *conf;
	struct ppl_conf *ppl_conf;
	int err = 0;
	unsigned short new;

	if (len >= PAGE_SIZE)
		return -EINVAL;
	if (kstrtou16(page, 10, &new))
		return -EINVAL;

	err = mddev_lock(mddev);
	if (err)
		return err;

	conf = mddev->private;
	if (!conf) {
		err = -ENODEV;
	} else if (raid5_has_ppl(conf)) {
		ppl_conf = conf->log_private;
		if (!ppl_conf)
			err = -EINVAL;
		else
			ppl_conf->write_hint = new;
	} else {
		err = -EINVAL;
	}

	mddev_unlock(mddev);

	return err ?: len;
}

struct md_sysfs_entry
ppl_write_hint = __ATTR(ppl_write_hint, S_IRUGO | S_IWUSR,
			ppl_write_hint_show,
			ppl_write_hint_store);
+3 −0
Original line number Diff line number Diff line
@@ -6660,6 +6660,7 @@ static struct attribute *raid5_attrs[] = {
	&raid5_skip_copy.attr,
	&raid5_rmw_level.attr,
	&r5c_journal_mode.attr,
	&ppl_write_hint.attr,
	NULL,
};
static struct attribute_group raid5_attrs_group = {
@@ -7402,6 +7403,8 @@ static int raid5_run(struct mddev *mddev)
		set_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
		mddev->sync_thread = md_register_thread(md_do_sync, mddev,
							"reshape");
		if (!mddev->sync_thread)
			goto abort;
	}

	/* Ok, everything is just fine now */