Skip to content

Commit

Permalink
Merge tag 'md/4.2' of git://neil.brown.name/md
Browse files Browse the repository at this point in the history
Pull md updates from Neil Brown:
 "A mixed bag

   - a few bug fixes
   - some performance improvement that decrease lock contention
   - some clean-up

  Nothing major"

* tag 'md/4.2' of git://neil.brown.name/md:
  md: clear Blocked flag on failed devices when array is read-only.
  md: unlock mddev_lock on an error path.
  md: clear mddev->private when it has been freed.
  md: fix a build warning
  md/raid5: ignore released_stripes check
  md/raid5: per hash value and exclusive wait_for_stripe
  md/raid5: split wait_for_stripe and introduce wait_for_quiescent
  wait: introduce wait_event_exclusive_cmd
  md: convert to kstrto*()
  md/raid10: make sync_request_write() call bio_copy_data()
  • Loading branch information
Linus Torvalds committed Jun 29, 2015
2 parents a9730fc + ab16bfc commit 6aaf0da
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 101 deletions.
167 changes: 97 additions & 70 deletions drivers/md/md.c
Original file line number Diff line number Diff line change
Expand Up @@ -2628,13 +2628,14 @@ errors_show(struct md_rdev *rdev, char *page)
static ssize_t
errors_store(struct md_rdev *rdev, const char *buf, size_t len)
{
char *e;
unsigned long n = simple_strtoul(buf, &e, 10);
if (*buf && (*e == 0 || *e == '\n')) {
atomic_set(&rdev->corrected_errors, n);
return len;
}
return -EINVAL;
unsigned int n;
int rv;

rv = kstrtouint(buf, 10, &n);
if (rv < 0)
return rv;
atomic_set(&rdev->corrected_errors, n);
return len;
}
static struct rdev_sysfs_entry rdev_errors =
__ATTR(errors, S_IRUGO|S_IWUSR, errors_show, errors_store);
Expand All @@ -2651,13 +2652,16 @@ slot_show(struct md_rdev *rdev, char *page)
static ssize_t
slot_store(struct md_rdev *rdev, const char *buf, size_t len)
{
char *e;
int slot;
int err;
int slot = simple_strtoul(buf, &e, 10);

if (strncmp(buf, "none", 4)==0)
slot = -1;
else if (e==buf || (*e && *e!= '\n'))
return -EINVAL;
else {
err = kstrtouint(buf, 10, (unsigned int *)&slot);
if (err < 0)
return err;
}
if (rdev->mddev->pers && slot == -1) {
/* Setting 'slot' on an active array requires also
* updating the 'rd%d' link, and communicating
Expand Down Expand Up @@ -3542,12 +3546,12 @@ layout_show(struct mddev *mddev, char *page)
static ssize_t
layout_store(struct mddev *mddev, const char *buf, size_t len)
{
char *e;
unsigned long n = simple_strtoul(buf, &e, 10);
unsigned int n;
int err;

if (!*buf || (*e && *e != '\n'))
return -EINVAL;
err = kstrtouint(buf, 10, &n);
if (err < 0)
return err;
err = mddev_lock(mddev);
if (err)
return err;
Expand Down Expand Up @@ -3591,12 +3595,12 @@ static int update_raid_disks(struct mddev *mddev, int raid_disks);
static ssize_t
raid_disks_store(struct mddev *mddev, const char *buf, size_t len)
{
char *e;
unsigned int n;
int err;
unsigned long n = simple_strtoul(buf, &e, 10);

if (!*buf || (*e && *e != '\n'))
return -EINVAL;
err = kstrtouint(buf, 10, &n);
if (err < 0)
return err;

err = mddev_lock(mddev);
if (err)
Expand Down Expand Up @@ -3643,12 +3647,12 @@ chunk_size_show(struct mddev *mddev, char *page)
static ssize_t
chunk_size_store(struct mddev *mddev, const char *buf, size_t len)
{
unsigned long n;
int err;
char *e;
unsigned long n = simple_strtoul(buf, &e, 10);

if (!*buf || (*e && *e != '\n'))
return -EINVAL;
err = kstrtoul(buf, 10, &n);
if (err < 0)
return err;

err = mddev_lock(mddev);
if (err)
Expand Down Expand Up @@ -3686,19 +3690,24 @@ resync_start_show(struct mddev *mddev, char *page)
static ssize_t
resync_start_store(struct mddev *mddev, const char *buf, size_t len)
{
unsigned long long n;
int err;
char *e;
unsigned long long n = simple_strtoull(buf, &e, 10);

if (cmd_match(buf, "none"))
n = MaxSector;
else {
err = kstrtoull(buf, 10, &n);
if (err < 0)
return err;
if (n != (sector_t)n)
return -EINVAL;
}

err = mddev_lock(mddev);
if (err)
return err;
if (mddev->pers && !test_bit(MD_RECOVERY_FROZEN, &mddev->recovery))
err = -EBUSY;
else if (cmd_match(buf, "none"))
n = MaxSector;
else if (!*buf || (*e && *e != '\n'))
err = -EINVAL;

if (!err) {
mddev->recovery_cp = n;
Expand Down Expand Up @@ -3934,14 +3943,14 @@ max_corrected_read_errors_show(struct mddev *mddev, char *page) {
static ssize_t
max_corrected_read_errors_store(struct mddev *mddev, const char *buf, size_t len)
{
char *e;
unsigned long n = simple_strtoul(buf, &e, 10);
unsigned int n;
int rv;

if (*buf && (*e == 0 || *e == '\n')) {
atomic_set(&mddev->max_corr_read_errors, n);
return len;
}
return -EINVAL;
rv = kstrtouint(buf, 10, &n);
if (rv < 0)
return rv;
atomic_set(&mddev->max_corr_read_errors, n);
return len;
}

static struct md_sysfs_entry max_corr_read_errors =
Expand Down Expand Up @@ -4003,8 +4012,10 @@ new_dev_store(struct mddev *mddev, const char *buf, size_t len)
else
rdev = md_import_device(dev, -1, -1);

if (IS_ERR(rdev))
if (IS_ERR(rdev)) {
mddev_unlock(mddev);
return PTR_ERR(rdev);
}
err = bind_rdev_to_array(rdev, mddev);
out:
if (err)
Expand Down Expand Up @@ -4298,15 +4309,18 @@ sync_min_show(struct mddev *mddev, char *page)
static ssize_t
sync_min_store(struct mddev *mddev, const char *buf, size_t len)
{
int min;
char *e;
unsigned int min;
int rv;

if (strncmp(buf, "system", 6)==0) {
mddev->sync_speed_min = 0;
return len;
min = 0;
} else {
rv = kstrtouint(buf, 10, &min);
if (rv < 0)
return rv;
if (min == 0)
return -EINVAL;
}
min = simple_strtoul(buf, &e, 10);
if (buf == e || (*e && *e != '\n') || min <= 0)
return -EINVAL;
mddev->sync_speed_min = min;
return len;
}
Expand All @@ -4324,15 +4338,18 @@ sync_max_show(struct mddev *mddev, char *page)
static ssize_t
sync_max_store(struct mddev *mddev, const char *buf, size_t len)
{
int max;
char *e;
unsigned int max;
int rv;

if (strncmp(buf, "system", 6)==0) {
mddev->sync_speed_max = 0;
return len;
max = 0;
} else {
rv = kstrtouint(buf, 10, &max);
if (rv < 0)
return rv;
if (max == 0)
return -EINVAL;
}
max = simple_strtoul(buf, &e, 10);
if (buf == e || (*e && *e != '\n') || max <= 0)
return -EINVAL;
mddev->sync_speed_max = max;
return len;
}
Expand Down Expand Up @@ -4515,12 +4532,13 @@ suspend_lo_show(struct mddev *mddev, char *page)
static ssize_t
suspend_lo_store(struct mddev *mddev, const char *buf, size_t len)
{
char *e;
unsigned long long new = simple_strtoull(buf, &e, 10);
unsigned long long old;
unsigned long long old, new;
int err;

if (buf == e || (*e && *e != '\n'))
err = kstrtoull(buf, 10, &new);
if (err < 0)
return err;
if (new != (sector_t)new)
return -EINVAL;

err = mddev_lock(mddev);
Expand Down Expand Up @@ -4557,12 +4575,13 @@ suspend_hi_show(struct mddev *mddev, char *page)
static ssize_t
suspend_hi_store(struct mddev *mddev, const char *buf, size_t len)
{
char *e;
unsigned long long new = simple_strtoull(buf, &e, 10);
unsigned long long old;
unsigned long long old, new;
int err;

if (buf == e || (*e && *e != '\n'))
err = kstrtoull(buf, 10, &new);
if (err < 0)
return err;
if (new != (sector_t)new)
return -EINVAL;

err = mddev_lock(mddev);
Expand Down Expand Up @@ -4604,11 +4623,13 @@ static ssize_t
reshape_position_store(struct mddev *mddev, const char *buf, size_t len)
{
struct md_rdev *rdev;
char *e;
unsigned long long new;
int err;
unsigned long long new = simple_strtoull(buf, &e, 10);

if (buf == e || (*e && *e != '\n'))
err = kstrtoull(buf, 10, &new);
if (err < 0)
return err;
if (new != (sector_t)new)
return -EINVAL;
err = mddev_lock(mddev);
if (err)
Expand Down Expand Up @@ -5157,6 +5178,7 @@ int md_run(struct mddev *mddev)
mddev_detach(mddev);
if (mddev->private)
pers->free(mddev, mddev->private);
mddev->private = NULL;
module_put(pers->owner);
bitmap_destroy(mddev);
return err;
Expand Down Expand Up @@ -5292,6 +5314,7 @@ static void md_clean(struct mddev *mddev)
mddev->changed = 0;
mddev->degraded = 0;
mddev->safemode = 0;
mddev->private = NULL;
mddev->merge_check_needed = 0;
mddev->bitmap_info.offset = 0;
mddev->bitmap_info.default_offset = 0;
Expand Down Expand Up @@ -5364,6 +5387,7 @@ static void __md_stop(struct mddev *mddev)
mddev->pers = NULL;
spin_unlock(&mddev->lock);
pers->free(mddev, mddev->private);
mddev->private = NULL;
if (pers->sync_request && mddev->to_remove == NULL)
mddev->to_remove = &md_redundancy_group;
module_put(pers->owner);
Expand Down Expand Up @@ -6373,7 +6397,7 @@ static int update_array_info(struct mddev *mddev, mdu_array_info_t *info)
mddev->ctime != info->ctime ||
mddev->level != info->level ||
/* mddev->layout != info->layout || */
!mddev->persistent != info->not_persistent||
mddev->persistent != !info->not_persistent ||
mddev->chunk_sectors != info->chunk_size >> 9 ||
/* ignore bottom 8 bits of state, and allow SB_BITMAP_PRESENT to change */
((state^info->state) & 0xfffffe00)
Expand Down Expand Up @@ -8104,6 +8128,15 @@ void md_check_recovery(struct mddev *mddev)
int spares = 0;

if (mddev->ro) {
struct md_rdev *rdev;
if (!mddev->external && mddev->in_sync)
/* 'Blocked' flag not needed as failed devices
* will be recorded if array switched to read/write.
* Leaving it set will prevent the device
* from being removed.
*/
rdev_for_each(rdev, mddev)
clear_bit(Blocked, &rdev->flags);
/* On a read-only array we can:
* - remove failed devices
* - add already-in_sync devices if the array itself
Expand Down Expand Up @@ -9011,13 +9044,7 @@ static int get_ro(char *buffer, struct kernel_param *kp)
}
static int set_ro(const char *val, struct kernel_param *kp)
{
char *e;
int num = simple_strtoul(val, &e, 10);
if (*val && (*e == '\0' || *e == '\n')) {
start_readonly = num;
return 0;
}
return -EINVAL;
return kstrtouint(val, 10, (unsigned int *)&start_readonly);
}

module_param_call(start_ro, set_ro, get_ro, NULL, S_IRUSR|S_IWUSR);
Expand Down
18 changes: 4 additions & 14 deletions drivers/md/raid10.c
Original file line number Diff line number Diff line change
Expand Up @@ -2099,17 +2099,10 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
tbio->bi_rw = WRITE;
tbio->bi_private = r10_bio;
tbio->bi_iter.bi_sector = r10_bio->devs[i].addr;

for (j=0; j < vcnt ; j++) {
tbio->bi_io_vec[j].bv_offset = 0;
tbio->bi_io_vec[j].bv_len = PAGE_SIZE;

memcpy(page_address(tbio->bi_io_vec[j].bv_page),
page_address(fbio->bi_io_vec[j].bv_page),
PAGE_SIZE);
}
tbio->bi_end_io = end_sync_write;

bio_copy_data(tbio, fbio);

d = r10_bio->devs[i].devnum;
atomic_inc(&conf->mirrors[d].rdev->nr_pending);
atomic_inc(&r10_bio->remaining);
Expand All @@ -2124,17 +2117,14 @@ static void sync_request_write(struct mddev *mddev, struct r10bio *r10_bio)
* that are active
*/
for (i = 0; i < conf->copies; i++) {
int j, d;
int d;

tbio = r10_bio->devs[i].repl_bio;
if (!tbio || !tbio->bi_end_io)
continue;
if (r10_bio->devs[i].bio->bi_end_io != end_sync_write
&& r10_bio->devs[i].bio != fbio)
for (j = 0; j < vcnt; j++)
memcpy(page_address(tbio->bi_io_vec[j].bv_page),
page_address(fbio->bi_io_vec[j].bv_page),
PAGE_SIZE);
bio_copy_data(tbio, fbio);
d = r10_bio->devs[i].devnum;
atomic_inc(&r10_bio->remaining);
md_sync_acct(conf->mirrors[d].replacement->bdev,
Expand Down
Loading

0 comments on commit 6aaf0da

Please sign in to comment.