Merge tag 'sysctl-6.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof...
[linux-2.6-microblaze.git] / drivers / md / md.c
index 0dc01f8..8e344b4 100644 (file)
@@ -78,7 +78,7 @@
 static LIST_HEAD(pers_list);
 static DEFINE_SPINLOCK(pers_lock);
 
-static struct kobj_type md_ktype;
+static const struct kobj_type md_ktype;
 
 struct md_cluster_operations *md_cluster_ops;
 EXPORT_SYMBOL(md_cluster_ops);
@@ -3580,7 +3580,7 @@ static const struct sysfs_ops rdev_sysfs_ops = {
        .show           = rdev_attr_show,
        .store          = rdev_attr_store,
 };
-static struct kobj_type rdev_ktype = {
+static const struct kobj_type rdev_ktype = {
        .release        = rdev_free,
        .sysfs_ops      = &rdev_sysfs_ops,
        .default_groups = rdev_default_groups,
@@ -5538,7 +5538,7 @@ static const struct sysfs_ops md_sysfs_ops = {
        .show   = md_attr_show,
        .store  = md_attr_store,
 };
-static struct kobj_type md_ktype = {
+static const struct kobj_type md_ktype = {
        .release        = md_kobj_release,
        .sysfs_ops      = &md_sysfs_ops,
        .default_groups = md_attr_groups,
@@ -6240,7 +6240,6 @@ static void __md_stop(struct mddev *mddev)
        module_put(pers->owner);
        clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
 
-       percpu_ref_exit(&mddev->writes_pending);
        percpu_ref_exit(&mddev->active_io);
        bioset_exit(&mddev->bio_set);
        bioset_exit(&mddev->sync_set);
@@ -6253,6 +6252,7 @@ void md_stop(struct mddev *mddev)
         */
        __md_stop_writes(mddev);
        __md_stop(mddev);
+       percpu_ref_exit(&mddev->writes_pending);
 }
 
 EXPORT_SYMBOL_GPL(md_stop);
@@ -7823,6 +7823,7 @@ static void md_free_disk(struct gendisk *disk)
 {
        struct mddev *mddev = disk->private_data;
 
+       percpu_ref_exit(&mddev->writes_pending);
        mddev_free(mddev);
 }
 
@@ -7953,6 +7954,9 @@ void md_error(struct mddev *mddev, struct md_rdev *rdev)
                return;
        mddev->pers->error_handler(mddev, rdev);
 
+       if (mddev->pers->level == 0 || mddev->pers->level == LEVEL_LINEAR)
+               return;
+
        if (mddev->degraded && !test_bit(MD_BROKEN, &mddev->flags))
                set_bit(MD_RECOVERY_RECOVER, &mddev->recovery);
        sysfs_notify_dirent_safe(rdev->sysfs_state);
@@ -8008,16 +8012,16 @@ static int status_resync(struct seq_file *seq, struct mddev *mddev)
        } else if (resync > max_sectors) {
                resync = max_sectors;
        } else {
-               resync -= atomic_read(&mddev->recovery_active);
-               if (resync < MD_RESYNC_ACTIVE) {
-                       /*
-                        * Resync has started, but the subtraction has
-                        * yielded one of the special values. Force it
-                        * to active to ensure the status reports an
-                        * active resync.
-                        */
+               res = atomic_read(&mddev->recovery_active);
+               /*
+                * Resync has started, but the subtraction has overflowed or
+                * yielded one of the special values. Force it to active to
+                * ensure the status reports an active resync.
+                */
+               if (resync < res || resync - res < MD_RESYNC_ACTIVE)
                        resync = MD_RESYNC_ACTIVE;
-               }
+               else
+                       resync -= res;
        }
 
        if (resync == MD_RESYNC_NONE) {