]> git.openfabrics.org - ~emulex/infiniband.git/commitdiff
MD: Remember the last sync operation that was performed
authorJonathan Brassow <jbrassow@redhat.com>
Tue, 25 Jun 2013 06:23:59 +0000 (01:23 -0500)
committerNeilBrown <neilb@suse.de>
Wed, 26 Jun 2013 02:38:24 +0000 (12:38 +1000)
MD:  Remember the last sync operation that was performed

This patch adds a field to the mddev structure to track the last
sync operation that was performed.  This is especially useful when
it comes to what is recorded in mismatch_cnt in sysfs.  If the
last operation was "data-check", then it reports the number of
descrepancies found by the user-initiated check.  If it was a
"repair" operation, then it is reporting the number of
descrepancies repaired.  etc.

Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Documentation/device-mapper/dm-raid.txt
drivers/md/dm-raid.c
drivers/md/md.c
drivers/md/md.h

index 2bb3a6823dc7643931a0765a384d21aa02014c2d..ef8ba9fa58c4490cf20c166c1c0ac1b733d85ddd 100644 (file)
@@ -223,3 +223,4 @@ Version History
 1.5.0   Add message interface to allow manipulation of the sync_action.
        New status (STATUSTYPE_INFO) fields: sync_action and mismatch_cnt.
 1.5.1   Add ability to restore transiently failed devices on resume.
+1.5.2   'mismatch_cnt' is zero unless [last_]sync_action is "check".
index 21e8e4660c597642b7f2346e4b8b58d6a446cd68..4880b69e2e9ecb3ea873d514580345a05edcea8a 100644 (file)
@@ -1388,6 +1388,7 @@ static void raid_status(struct dm_target *ti, status_type_t type,
                 *   performing a "check" of the array.
                 */
                DMEMIT(" %llu",
+                      (strcmp(rs->md.last_sync_action, "check")) ? 0 :
                       (unsigned long long)
                       atomic64_read(&rs->md.resync_mismatches));
                break;
@@ -1651,7 +1652,7 @@ static void raid_resume(struct dm_target *ti)
 
 static struct target_type raid_target = {
        .name = "raid",
-       .version = {1, 5, 1},
+       .version = {1, 5, 2},
        .module = THIS_MODULE,
        .ctr = raid_ctr,
        .dtr = raid_dtr,
index 26f9452ea61c02f065eee86f4da91c6889f2c46f..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;
@@ -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
@@ -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,
@@ -7329,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... */
@@ -7339,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
index 653f992b687ac25bbb6e22a8398215bc46156408..20f02c0b5f2d6d99ac69a36067135f0b8196d9a7 100644 (file)
@@ -268,6 +268,14 @@ struct mddev {
 
        struct md_thread                *thread;        /* management thread */
        struct md_thread                *sync_thread;   /* doing resync or reconstruct */
+
+       /* 'last_sync_action' is initialized to "none".  It is set when a
+        * sync operation (i.e "data-check", "requested-resync", "resync",
+        * "recovery", or "reshape") is started.  It holds this value even
+        * when the sync thread is "frozen" (interrupted) or "idle" (stopped
+        * or finished).  It is overwritten when a new sync operation is begun.
+        */
+       char                            *last_sync_action;
        sector_t                        curr_resync;    /* last block scheduled */
        /* As resync requests can complete out of order, we cannot easily track
         * how much resync has been completed.  So we occasionally pause until