aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/md.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r--drivers/md/md.c35
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
2079static ssize_t 2092static 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;