diff options
| -rw-r--r-- | drivers/md/md.c | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index a986845ea0c3..827824a9f3e9 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
| @@ -2001,9 +2001,11 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
| 2001 | char *e; | 2001 | char *e; |
| 2002 | unsigned long long size = simple_strtoull(buf, &e, 10); | 2002 | unsigned long long size = simple_strtoull(buf, &e, 10); |
| 2003 | unsigned long long oldsize = rdev->size; | 2003 | unsigned long long oldsize = rdev->size; |
| 2004 | mddev_t *my_mddev = rdev->mddev; | ||
| 2005 | |||
| 2004 | if (e==buf || (*e && *e != '\n')) | 2006 | if (e==buf || (*e && *e != '\n')) |
| 2005 | return -EINVAL; | 2007 | return -EINVAL; |
| 2006 | if (rdev->mddev->pers) | 2008 | if (my_mddev->pers) |
| 2007 | return -EBUSY; | 2009 | return -EBUSY; |
| 2008 | rdev->size = size; | 2010 | rdev->size = size; |
| 2009 | if (size > oldsize && rdev->mddev->external) { | 2011 | if (size > oldsize && rdev->mddev->external) { |
| @@ -2016,7 +2018,7 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
| 2016 | int overlap = 0; | 2018 | int overlap = 0; |
| 2017 | struct list_head *tmp, *tmp2; | 2019 | struct list_head *tmp, *tmp2; |
| 2018 | 2020 | ||
| 2019 | mddev_unlock(rdev->mddev); | 2021 | mddev_unlock(my_mddev); |
| 2020 | for_each_mddev(mddev, tmp) { | 2022 | for_each_mddev(mddev, tmp) { |
| 2021 | mdk_rdev_t *rdev2; | 2023 | mdk_rdev_t *rdev2; |
| 2022 | 2024 | ||
| @@ -2036,7 +2038,7 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
| 2036 | break; | 2038 | break; |
| 2037 | } | 2039 | } |
| 2038 | } | 2040 | } |
| 2039 | mddev_lock(rdev->mddev); | 2041 | mddev_lock(my_mddev); |
| 2040 | if (overlap) { | 2042 | if (overlap) { |
| 2041 | /* Someone else could have slipped in a size | 2043 | /* Someone else could have slipped in a size |
| 2042 | * change here, but doing so is just silly. | 2044 | * change here, but doing so is just silly. |
| @@ -2048,8 +2050,8 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len) | |||
| 2048 | return -EBUSY; | 2050 | return -EBUSY; |
| 2049 | } | 2051 | } |
| 2050 | } | 2052 | } |
| 2051 | if (size < rdev->mddev->size || rdev->mddev->size == 0) | 2053 | if (size < my_mddev->size || my_mddev->size == 0) |
| 2052 | rdev->mddev->size = size; | 2054 | my_mddev->size = size; |
| 2053 | return len; | 2055 | return len; |
| 2054 | } | 2056 | } |
| 2055 | 2057 | ||
| @@ -2070,10 +2072,21 @@ rdev_attr_show(struct kobject *kobj, struct attribute *attr, char *page) | |||
| 2070 | { | 2072 | { |
| 2071 | struct rdev_sysfs_entry *entry = container_of(attr, struct rdev_sysfs_entry, attr); | 2073 | struct rdev_sysfs_entry *entry = container_of(attr, struct rdev_sysfs_entry, attr); |
| 2072 | mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj); | 2074 | mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj); |
| 2075 | mddev_t *mddev = rdev->mddev; | ||
| 2076 | ssize_t rv; | ||
| 2073 | 2077 | ||
| 2074 | if (!entry->show) | 2078 | if (!entry->show) |
| 2075 | return -EIO; | 2079 | return -EIO; |
| 2076 | return entry->show(rdev, page); | 2080 | |
| 2081 | rv = mddev ? mddev_lock(mddev) : -EBUSY; | ||
| 2082 | if (!rv) { | ||
| 2083 | if (rdev->mddev == NULL) | ||
| 2084 | rv = -EBUSY; | ||
| 2085 | else | ||
| 2086 | rv = entry->show(rdev, page); | ||
| 2087 | mddev_unlock(mddev); | ||
| 2088 | } | ||
| 2089 | return rv; | ||
| 2077 | } | 2090 | } |
| 2078 | 2091 | ||
| 2079 | static ssize_t | 2092 | static ssize_t |
| @@ -2082,15 +2095,19 @@ rdev_attr_store(struct kobject *kobj, struct attribute *attr, | |||
| 2082 | { | 2095 | { |
| 2083 | struct rdev_sysfs_entry *entry = container_of(attr, struct rdev_sysfs_entry, attr); | 2096 | struct rdev_sysfs_entry *entry = container_of(attr, struct rdev_sysfs_entry, attr); |
| 2084 | mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj); | 2097 | mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj); |
| 2085 | int rv; | 2098 | ssize_t rv; |
| 2099 | mddev_t *mddev = rdev->mddev; | ||
| 2086 | 2100 | ||
| 2087 | if (!entry->store) | 2101 | if (!entry->store) |
| 2088 | return -EIO; | 2102 | return -EIO; |
| 2089 | if (!capable(CAP_SYS_ADMIN)) | 2103 | if (!capable(CAP_SYS_ADMIN)) |
| 2090 | return -EACCES; | 2104 | return -EACCES; |
| 2091 | rv = mddev_lock(rdev->mddev); | 2105 | rv = mddev ? mddev_lock(mddev): -EBUSY; |
| 2092 | if (!rv) { | 2106 | if (!rv) { |
| 2093 | rv = entry->store(rdev, page, length); | 2107 | if (rdev->mddev == NULL) |
| 2108 | rv = -EBUSY; | ||
| 2109 | else | ||
| 2110 | rv = entry->store(rdev, page, length); | ||
| 2094 | mddev_unlock(rdev->mddev); | 2111 | mddev_unlock(rdev->mddev); |
| 2095 | } | 2112 | } |
| 2096 | return rv; | 2113 | return rv; |
