dm raid1: report flush errors separately in status
authorMikulas Patocka <mpatocka@redhat.com>
Thu, 10 Dec 2009 23:52:02 +0000 (23:52 +0000)
committerAlasdair G Kergon <agk@redhat.com>
Thu, 10 Dec 2009 23:52:02 +0000 (23:52 +0000)
Report flush errors as 'F' instead of 'D' for log and mirror devices.

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
drivers/md/dm-log.c
drivers/md/dm-raid1.c

index 315e36a..7035582 100644 (file)
@@ -237,6 +237,7 @@ struct log_c {
         * Disk log fields
         */
        int log_dev_failed;
+       int log_dev_flush_failed;
        struct dm_dev *log_dev;
        struct log_header header;
 
@@ -425,6 +426,7 @@ static int create_log_context(struct dm_dirty_log *log, struct dm_target *ti,
        } else {
                lc->log_dev = dev;
                lc->log_dev_failed = 0;
+               lc->log_dev_flush_failed = 0;
                lc->header_location.bdev = lc->log_dev->bdev;
                lc->header_location.sector = 0;
 
@@ -633,8 +635,11 @@ static int disk_resume(struct dm_dirty_log *log)
 
        /* write the new header */
        r = rw_header(lc, WRITE);
-       if (!r)
+       if (!r) {
                r = flush_header(lc);
+               if (r)
+                       lc->log_dev_flush_failed = 1;
+       }
        if (r) {
                DMWARN("%s: Failed to write header on dirty region log device",
                       lc->log_dev->name);
@@ -703,9 +708,10 @@ static int disk_flush(struct dm_dirty_log *log)
        else {
                if (lc->touched_dirtied) {
                        r = flush_header(lc);
-                       if (r)
+                       if (r) {
+                               lc->log_dev_flush_failed = 1;
                                fail_log_device(lc);
-                       else
+                       else
                                lc->touched_dirtied = 0;
                }
                lc->touched_cleaned = 0;
@@ -805,7 +811,9 @@ static int disk_status(struct dm_dirty_log *log, status_type_t status,
        switch(status) {
        case STATUSTYPE_INFO:
                DMEMIT("3 %s %s %c", log->type->name, lc->log_dev->name,
-                      lc->log_dev_failed ? 'D' : 'A');
+                      lc->log_dev_flush_failed ? 'F' :
+                      lc->log_dev_failed ? 'D' :
+                      'A');
                break;
 
        case STATUSTYPE_TABLE:
index 751660b..85c8704 100644 (file)
@@ -35,6 +35,7 @@ static DECLARE_WAIT_QUEUE_HEAD(_kmirrord_recovery_stopped);
  *---------------------------------------------------------------*/
 enum dm_raid1_error {
        DM_RAID1_WRITE_ERROR,
+       DM_RAID1_FLUSH_ERROR,
        DM_RAID1_SYNC_ERROR,
        DM_RAID1_READ_ERROR
 };
@@ -264,7 +265,7 @@ static int mirror_flush(struct dm_target *ti)
                for (i = 0; i < ms->nr_mirrors; i++)
                        if (test_bit(i, &error_bits))
                                fail_mirror(ms->mirror + i,
-                                           DM_RAID1_WRITE_ERROR);
+                                           DM_RAID1_FLUSH_ERROR);
                return -EIO;
        }
 
@@ -1288,7 +1289,8 @@ static char device_status_char(struct mirror *m)
        if (!atomic_read(&(m->error_count)))
                return 'A';
 
-       return (test_bit(DM_RAID1_WRITE_ERROR, &(m->error_type))) ? 'D' :
+       return (test_bit(DM_RAID1_FLUSH_ERROR, &(m->error_type))) ? 'F' :
+               (test_bit(DM_RAID1_WRITE_ERROR, &(m->error_type))) ? 'D' :
                (test_bit(DM_RAID1_SYNC_ERROR, &(m->error_type))) ? 'S' :
                (test_bit(DM_RAID1_READ_ERROR, &(m->error_type))) ? 'R' : 'U';
 }