diff options
Diffstat (limited to 'drivers/md')
-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; |