]> Pileus Git - ~andy/linux/blobdiff - drivers/md/md.c
mwifiex: rename mef macros
[~andy/linux] / drivers / md / md.c
index 9b82377a833bd6572b628c79426ca153781fd712..dddc87bcf64aa3ef24ba9bda56d3347a457ed544 100644 (file)
@@ -521,6 +521,7 @@ void mddev_init(struct mddev *mddev)
        init_waitqueue_head(&mddev->recovery_wait);
        mddev->reshape_position = MaxSector;
        mddev->reshape_backwards = 0;
+       mddev->last_sync_action = "none";
        mddev->resync_min = 0;
        mddev->resync_max = MaxSector;
        mddev->level = LEVEL_NONE;
@@ -2867,7 +2868,7 @@ static ssize_t
 offset_store(struct md_rdev *rdev, const char *buf, size_t len)
 {
        unsigned long long offset;
-       if (strict_strtoull(buf, 10, &offset) < 0)
+       if (kstrtoull(buf, 10, &offset) < 0)
                return -EINVAL;
        if (rdev->mddev->pers && rdev->raid_disk >= 0)
                return -EBUSY;
@@ -2895,7 +2896,7 @@ static ssize_t new_offset_store(struct md_rdev *rdev,
        unsigned long long new_offset;
        struct mddev *mddev = rdev->mddev;
 
-       if (strict_strtoull(buf, 10, &new_offset) < 0)
+       if (kstrtoull(buf, 10, &new_offset) < 0)
                return -EINVAL;
 
        if (mddev->sync_thread)
@@ -2961,7 +2962,7 @@ static int strict_blocks_to_sectors(const char *buf, sector_t *sectors)
        unsigned long long blocks;
        sector_t new;
 
-       if (strict_strtoull(buf, 10, &blocks) < 0)
+       if (kstrtoull(buf, 10, &blocks) < 0)
                return -EINVAL;
 
        if (blocks & 1ULL << (8 * sizeof(blocks) - 1))
@@ -3069,7 +3070,7 @@ static ssize_t recovery_start_store(struct md_rdev *rdev, const char *buf, size_
 
        if (cmd_match(buf, "none"))
                recovery_start = MaxSector;
-       else if (strict_strtoull(buf, 10, &recovery_start))
+       else if (kstrtoull(buf, 10, &recovery_start))
                return -EINVAL;
 
        if (rdev->mddev->pers &&
@@ -3497,7 +3498,7 @@ level_store(struct mddev *mddev, const char *buf, size_t len)
        if (clevel[len-1] == '\n')
                len--;
        clevel[len] = 0;
-       if (strict_strtol(clevel, 10, &level))
+       if (kstrtol(clevel, 10, &level))
                level = LEVEL_NONE;
 
        if (request_module("md-%s", clevel) != 0)
@@ -4272,6 +4273,17 @@ action_store(struct mddev *mddev, const char *page, size_t len)
        return len;
 }
 
+static struct md_sysfs_entry md_scan_mode =
+__ATTR(sync_action, S_IRUGO|S_IWUSR, action_show, action_store);
+
+static ssize_t
+last_sync_action_show(struct mddev *mddev, char *page)
+{
+       return sprintf(page, "%s\n", mddev->last_sync_action);
+}
+
+static struct md_sysfs_entry md_last_scan_mode = __ATTR_RO(last_sync_action);
+
 static ssize_t
 mismatch_cnt_show(struct mddev *mddev, char *page)
 {
@@ -4280,10 +4292,6 @@ mismatch_cnt_show(struct mddev *mddev, char *page)
                       atomic64_read(&mddev->resync_mismatches));
 }
 
-static struct md_sysfs_entry md_scan_mode =
-__ATTR(sync_action, S_IRUGO|S_IWUSR, action_show, action_store);
-
-
 static struct md_sysfs_entry md_mismatches = __ATTR_RO(mismatch_cnt);
 
 static ssize_t
@@ -4356,7 +4364,7 @@ sync_force_parallel_store(struct mddev *mddev, const char *buf, size_t len)
 {
        long n;
 
-       if (strict_strtol(buf, 10, &n))
+       if (kstrtol(buf, 10, &n))
                return -EINVAL;
 
        if (n != 0 && n != 1)
@@ -4424,7 +4432,7 @@ static ssize_t
 min_sync_store(struct mddev *mddev, const char *buf, size_t len)
 {
        unsigned long long min;
-       if (strict_strtoull(buf, 10, &min))
+       if (kstrtoull(buf, 10, &min))
                return -EINVAL;
        if (min > mddev->resync_max)
                return -EINVAL;
@@ -4461,7 +4469,7 @@ max_sync_store(struct mddev *mddev, const char *buf, size_t len)
                mddev->resync_max = MaxSector;
        else {
                unsigned long long max;
-               if (strict_strtoull(buf, 10, &max))
+               if (kstrtoull(buf, 10, &max))
                        return -EINVAL;
                if (max < mddev->resync_min)
                        return -EINVAL;
@@ -4686,6 +4694,7 @@ static struct attribute *md_default_attrs[] = {
 
 static struct attribute *md_redundancy_attrs[] = {
        &md_scan_mode.attr,
+       &md_last_scan_mode.attr,
        &md_mismatches.attr,
        &md_sync_min.attr,
        &md_sync_max.attr,
@@ -6405,6 +6414,12 @@ static int md_ioctl(struct block_device *bdev, fmode_t mode,
                /* need to ensure md_delayed_delete() has completed */
                flush_workqueue(md_misc_wq);
 
+       if (cmd == HOT_REMOVE_DISK)
+               /* need to ensure recovery thread has run */
+               wait_event_interruptible_timeout(mddev->sb_wait,
+                                                !test_bit(MD_RECOVERY_NEEDED,
+                                                          &mddev->flags),
+                                                msecs_to_jiffies(5000));
        err = mddev_lock(mddev);
        if (err) {
                printk(KERN_INFO 
@@ -7323,7 +7338,7 @@ void md_do_sync(struct md_thread *thread)
        sector_t last_check;
        int skipped = 0;
        struct md_rdev *rdev;
-       char *desc;
+       char *desc, *action = NULL;
        struct blk_plug plug;
 
        /* just incase thread restarts... */
@@ -7333,17 +7348,21 @@ void md_do_sync(struct md_thread *thread)
                return;
 
        if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
-               if (test_bit(MD_RECOVERY_CHECK, &mddev->recovery))
+               if (test_bit(MD_RECOVERY_CHECK, &mddev->recovery)) {
                        desc = "data-check";
-               else if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery))
+                       action = "check";
+               } else if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
                        desc = "requested-resync";
-               else
+                       action = "repair";
+               } else
                        desc = "resync";
        } else if (test_bit(MD_RECOVERY_RESHAPE, &mddev->recovery))
                desc = "reshape";
        else
                desc = "recovery";
 
+       mddev->last_sync_action = action ?: desc;
+
        /* we overload curr_resync somewhat here.
         * 0 == not engaged in resync at all
         * 2 == checking that there is no conflict with another sync
@@ -7892,6 +7911,8 @@ void md_check_recovery(struct mddev *mddev)
                        md_new_event(mddev);
                }
        unlock:
+               wake_up(&mddev->sb_wait);
+
                if (!mddev->sync_thread) {
                        clear_bit(MD_RECOVERY_RUNNING, &mddev->recovery);
                        if (test_and_clear_bit(MD_RECOVERY_RECOVER,