md: remove the 'super' sysfs attribute from devices in an 'md' array
[sfrench/cifs-2.6.git] / drivers / md / md.c
index 5fc326d3970e511faf3e6f1a0b4fde30ac0f8f67..61ccbd2683fa215aeddb0363bd6ddcb621bc85ac 100644 (file)
@@ -1105,7 +1105,11 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
        rdev->sb_size = le32_to_cpu(sb->max_dev) * 2 + 256;
        bmask = queue_hardsect_size(rdev->bdev->bd_disk->queue)-1;
        if (rdev->sb_size & bmask)
-               rdev-> sb_size = (rdev->sb_size | bmask)+1;
+               rdev->sb_size = (rdev->sb_size | bmask) + 1;
+
+       if (minor_version
+           && rdev->data_offset < sb_offset + (rdev->sb_size/512))
+               return -EINVAL;
 
        if (sb->level == cpu_to_le32(LEVEL_MULTIPATH))
                rdev->desc_nr = -1;
@@ -1137,7 +1141,7 @@ static int super_1_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev, int minor_version)
                else
                        ret = 0;
        }
-       if (minor_version) 
+       if (minor_version)
                rdev->size = ((rdev->bdev->bd_inode->i_size>>9) - le64_to_cpu(sb->data_offset)) / 2;
        else
                rdev->size = rdev->sb_offset;
@@ -1499,7 +1503,8 @@ static void export_rdev(mdk_rdev_t * rdev)
        free_disk_sb(rdev);
        list_del_init(&rdev->same_set);
 #ifndef MODULE
-       md_autodetect_dev(rdev->bdev->bd_dev);
+       if (test_bit(AutoDetected, &rdev->flags))
+               md_autodetect_dev(rdev->bdev->bd_dev);
 #endif
        unlock_rdev(rdev);
        kobject_put(&rdev->kobj);
@@ -1858,17 +1863,6 @@ state_store(mdk_rdev_t *rdev, const char *buf, size_t len)
 static struct rdev_sysfs_entry rdev_state =
 __ATTR(state, S_IRUGO|S_IWUSR, state_show, state_store);
 
-static ssize_t
-super_show(mdk_rdev_t *rdev, char *page)
-{
-       if (rdev->sb_loaded && rdev->sb_size) {
-               memcpy(page, page_address(rdev->sb_page), rdev->sb_size);
-               return rdev->sb_size;
-       } else
-               return 0;
-}
-static struct rdev_sysfs_entry rdev_super = __ATTR_RO(super);
-
 static ssize_t
 errors_show(mdk_rdev_t *rdev, char *page)
 {
@@ -1996,9 +1990,11 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
        char *e;
        unsigned long long size = simple_strtoull(buf, &e, 10);
        unsigned long long oldsize = rdev->size;
+       mddev_t *my_mddev = rdev->mddev;
+
        if (e==buf || (*e && *e != '\n'))
                return -EINVAL;
-       if (rdev->mddev->pers)
+       if (my_mddev->pers)
                return -EBUSY;
        rdev->size = size;
        if (size > oldsize && rdev->mddev->external) {
@@ -2011,7 +2007,7 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
                int overlap = 0;
                struct list_head *tmp, *tmp2;
 
-               mddev_unlock(rdev->mddev);
+               mddev_unlock(my_mddev);
                for_each_mddev(mddev, tmp) {
                        mdk_rdev_t *rdev2;
 
@@ -2031,7 +2027,7 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
                                break;
                        }
                }
-               mddev_lock(rdev->mddev);
+               mddev_lock(my_mddev);
                if (overlap) {
                        /* Someone else could have slipped in a size
                         * change here, but doing so is just silly.
@@ -2043,8 +2039,8 @@ rdev_size_store(mdk_rdev_t *rdev, const char *buf, size_t len)
                        return -EBUSY;
                }
        }
-       if (size < rdev->mddev->size || rdev->mddev->size == 0)
-               rdev->mddev->size = size;
+       if (size < my_mddev->size || my_mddev->size == 0)
+               my_mddev->size = size;
        return len;
 }
 
@@ -2053,7 +2049,6 @@ __ATTR(size, S_IRUGO|S_IWUSR, rdev_size_show, rdev_size_store);
 
 static struct attribute *rdev_default_attrs[] = {
        &rdev_state.attr,
-       &rdev_super.attr,
        &rdev_errors.attr,
        &rdev_slot.attr,
        &rdev_offset.attr,
@@ -2065,10 +2060,21 @@ rdev_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
 {
        struct rdev_sysfs_entry *entry = container_of(attr, struct rdev_sysfs_entry, attr);
        mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj);
+       mddev_t *mddev = rdev->mddev;
+       ssize_t rv;
 
        if (!entry->show)
                return -EIO;
-       return entry->show(rdev, page);
+
+       rv = mddev ? mddev_lock(mddev) : -EBUSY;
+       if (!rv) {
+               if (rdev->mddev == NULL)
+                       rv = -EBUSY;
+               else
+                       rv = entry->show(rdev, page);
+               mddev_unlock(mddev);
+       }
+       return rv;
 }
 
 static ssize_t
@@ -2077,15 +2083,19 @@ rdev_attr_store(struct kobject *kobj, struct attribute *attr,
 {
        struct rdev_sysfs_entry *entry = container_of(attr, struct rdev_sysfs_entry, attr);
        mdk_rdev_t *rdev = container_of(kobj, mdk_rdev_t, kobj);
-       int rv;
+       ssize_t rv;
+       mddev_t *mddev = rdev->mddev;
 
        if (!entry->store)
                return -EIO;
        if (!capable(CAP_SYS_ADMIN))
                return -EACCES;
-       rv = mddev_lock(rdev->mddev);
+       rv = mddev ? mddev_lock(mddev): -EBUSY;
        if (!rv) {
-               rv = entry->store(rdev, page, length);
+               if (rdev->mddev == NULL)
+                       rv = -EBUSY;
+               else
+                       rv = entry->store(rdev, page, length);
                mddev_unlock(rdev->mddev);
        }
        return rv;
@@ -5127,7 +5137,7 @@ static int md_seq_show(struct seq_file *seq, void *v)
                        if (mddev->ro==1)
                                seq_printf(seq, " (read-only)");
                        if (mddev->ro==2)
-                               seq_printf(seq, "(auto-read-only)");
+                               seq_printf(seq, " (auto-read-only)");
                        seq_printf(seq, " %s", mddev->pers->name);
                }
 
@@ -5197,8 +5207,7 @@ static int md_seq_show(struct seq_file *seq, void *v)
                                chunk_kb ? "KB" : "B");
                        if (bitmap->file) {
                                seq_printf(seq, ", file: ");
-                               seq_path(seq, bitmap->file->f_path.mnt,
-                                        bitmap->file->f_path.dentry," \t\n");
+                               seq_path(seq, &bitmap->file->f_path, " \t\n");
                        }
 
                        seq_printf(seq, "\n");
@@ -5352,6 +5361,7 @@ void md_write_start(mddev_t *mddev, struct bio *bi)
                mddev->ro = 0;
                set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
                md_wakeup_thread(mddev->thread);
+               md_wakeup_thread(mddev->sync_thread);
        }
        atomic_inc(&mddev->writes_pending);
        if (mddev->in_sync) {
@@ -6022,6 +6032,7 @@ static void autostart_arrays(int part)
                        MD_BUG();
                        continue;
                }
+               set_bit(AutoDetected, &rdev->flags);
                list_add(&rdev->same_set, &pending_raid_disks);
                i_passed++;
        }