|
@@ -2183,19 +2183,29 @@ location_show(struct mddev *mddev, char *page)
|
|
static ssize_t
|
|
static ssize_t
|
|
location_store(struct mddev *mddev, const char *buf, size_t len)
|
|
location_store(struct mddev *mddev, const char *buf, size_t len)
|
|
{
|
|
{
|
|
|
|
+ int rv;
|
|
|
|
|
|
|
|
+ rv = mddev_lock(mddev);
|
|
|
|
+ if (rv)
|
|
|
|
+ return rv;
|
|
if (mddev->pers) {
|
|
if (mddev->pers) {
|
|
- if (!mddev->pers->quiesce)
|
|
|
|
- return -EBUSY;
|
|
|
|
- if (mddev->recovery || mddev->sync_thread)
|
|
|
|
- return -EBUSY;
|
|
|
|
|
|
+ if (!mddev->pers->quiesce) {
|
|
|
|
+ rv = -EBUSY;
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
+ if (mddev->recovery || mddev->sync_thread) {
|
|
|
|
+ rv = -EBUSY;
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
if (mddev->bitmap || mddev->bitmap_info.file ||
|
|
if (mddev->bitmap || mddev->bitmap_info.file ||
|
|
mddev->bitmap_info.offset) {
|
|
mddev->bitmap_info.offset) {
|
|
/* bitmap already configured. Only option is to clear it */
|
|
/* bitmap already configured. Only option is to clear it */
|
|
- if (strncmp(buf, "none", 4) != 0)
|
|
|
|
- return -EBUSY;
|
|
|
|
|
|
+ if (strncmp(buf, "none", 4) != 0) {
|
|
|
|
+ rv = -EBUSY;
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
if (mddev->pers) {
|
|
if (mddev->pers) {
|
|
mddev->pers->quiesce(mddev, 1);
|
|
mddev->pers->quiesce(mddev, 1);
|
|
bitmap_destroy(mddev);
|
|
bitmap_destroy(mddev);
|
|
@@ -2214,21 +2224,25 @@ location_store(struct mddev *mddev, const char *buf, size_t len)
|
|
/* nothing to be done */;
|
|
/* nothing to be done */;
|
|
else if (strncmp(buf, "file:", 5) == 0) {
|
|
else if (strncmp(buf, "file:", 5) == 0) {
|
|
/* Not supported yet */
|
|
/* Not supported yet */
|
|
- return -EINVAL;
|
|
|
|
|
|
+ rv = -EINVAL;
|
|
|
|
+ goto out;
|
|
} else {
|
|
} else {
|
|
- int rv;
|
|
|
|
if (buf[0] == '+')
|
|
if (buf[0] == '+')
|
|
rv = kstrtoll(buf+1, 10, &offset);
|
|
rv = kstrtoll(buf+1, 10, &offset);
|
|
else
|
|
else
|
|
rv = kstrtoll(buf, 10, &offset);
|
|
rv = kstrtoll(buf, 10, &offset);
|
|
if (rv)
|
|
if (rv)
|
|
- return rv;
|
|
|
|
- if (offset == 0)
|
|
|
|
- return -EINVAL;
|
|
|
|
|
|
+ goto out;
|
|
|
|
+ if (offset == 0) {
|
|
|
|
+ rv = -EINVAL;
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
if (mddev->bitmap_info.external == 0 &&
|
|
if (mddev->bitmap_info.external == 0 &&
|
|
mddev->major_version == 0 &&
|
|
mddev->major_version == 0 &&
|
|
- offset != mddev->bitmap_info.default_offset)
|
|
|
|
- return -EINVAL;
|
|
|
|
|
|
+ offset != mddev->bitmap_info.default_offset) {
|
|
|
|
+ rv = -EINVAL;
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
mddev->bitmap_info.offset = offset;
|
|
mddev->bitmap_info.offset = offset;
|
|
if (mddev->pers) {
|
|
if (mddev->pers) {
|
|
struct bitmap *bitmap;
|
|
struct bitmap *bitmap;
|
|
@@ -2245,7 +2259,7 @@ location_store(struct mddev *mddev, const char *buf, size_t len)
|
|
mddev->pers->quiesce(mddev, 0);
|
|
mddev->pers->quiesce(mddev, 0);
|
|
if (rv) {
|
|
if (rv) {
|
|
bitmap_destroy(mddev);
|
|
bitmap_destroy(mddev);
|
|
- return rv;
|
|
|
|
|
|
+ goto out;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -2257,6 +2271,11 @@ location_store(struct mddev *mddev, const char *buf, size_t len)
|
|
set_bit(MD_CHANGE_DEVS, &mddev->flags);
|
|
set_bit(MD_CHANGE_DEVS, &mddev->flags);
|
|
md_wakeup_thread(mddev->thread);
|
|
md_wakeup_thread(mddev->thread);
|
|
}
|
|
}
|
|
|
|
+ rv = 0;
|
|
|
|
+out:
|
|
|
|
+ mddev_unlock(mddev);
|
|
|
|
+ if (rv)
|
|
|
|
+ return rv;
|
|
return len;
|
|
return len;
|
|
}
|
|
}
|
|
|
|
|