Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/linux-dm
[pandora-kernel.git] / drivers / md / dm-raid.c
index 86df8b2..11fa96d 100644 (file)
@@ -37,7 +37,7 @@ struct raid_dev {
         */
        struct dm_dev *meta_dev;
        struct dm_dev *data_dev;
-       struct mdk_rdev_s rdev;
+       struct md_rdev rdev;
 };
 
 /*
@@ -57,7 +57,7 @@ struct raid_set {
 
        uint64_t print_flags;
 
-       struct mddev_s md;
+       struct mddev md;
        struct raid_type *raid_type;
        struct dm_target_callbacks callbacks;
 
@@ -594,7 +594,7 @@ struct dm_raid_superblock {
                                /* Always set to 0 when writing. */
 } __packed;
 
-static int read_disk_sb(mdk_rdev_t *rdev, int size)
+static int read_disk_sb(struct md_rdev *rdev, int size)
 {
        BUG_ON(!rdev->sb_page);
 
@@ -611,9 +611,9 @@ static int read_disk_sb(mdk_rdev_t *rdev, int size)
        return 0;
 }
 
-static void super_sync(mddev_t *mddev, mdk_rdev_t *rdev)
+static void super_sync(struct mddev *mddev, struct md_rdev *rdev)
 {
-       mdk_rdev_t *r, *t;
+       struct md_rdev *r, *t;
        uint64_t failed_devices;
        struct dm_raid_superblock *sb;
 
@@ -651,7 +651,7 @@ static void super_sync(mddev_t *mddev, mdk_rdev_t *rdev)
  *
  * Return: 1 if use rdev, 0 if use refdev, -Exxx otherwise
  */
-static int super_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev)
+static int super_load(struct md_rdev *rdev, struct md_rdev *refdev)
 {
        int ret;
        struct dm_raid_superblock *sb;
@@ -689,7 +689,7 @@ static int super_load(mdk_rdev_t *rdev, mdk_rdev_t *refdev)
        return (events_sb > events_refsb) ? 1 : 0;
 }
 
-static int super_init_validation(mddev_t *mddev, mdk_rdev_t *rdev)
+static int super_init_validation(struct mddev *mddev, struct md_rdev *rdev)
 {
        int role;
        struct raid_set *rs = container_of(mddev, struct raid_set, md);
@@ -698,7 +698,7 @@ static int super_init_validation(mddev_t *mddev, mdk_rdev_t *rdev)
        struct dm_raid_superblock *sb;
        uint32_t new_devs = 0;
        uint32_t rebuilds = 0;
-       mdk_rdev_t *r, *t;
+       struct md_rdev *r, *t;
        struct dm_raid_superblock *sb2;
 
        sb = page_address(rdev->sb_page);
@@ -809,7 +809,7 @@ static int super_init_validation(mddev_t *mddev, mdk_rdev_t *rdev)
        return 0;
 }
 
-static int super_validate(mddev_t *mddev, mdk_rdev_t *rdev)
+static int super_validate(struct mddev *mddev, struct md_rdev *rdev)
 {
        struct dm_raid_superblock *sb = page_address(rdev->sb_page);
 
@@ -849,8 +849,8 @@ static int super_validate(mddev_t *mddev, mdk_rdev_t *rdev)
 static int analyse_superblocks(struct dm_target *ti, struct raid_set *rs)
 {
        int ret;
-       mdk_rdev_t *rdev, *freshest, *tmp;
-       mddev_t *mddev = &rs->md;
+       struct md_rdev *rdev, *freshest, *tmp;
+       struct mddev *mddev = &rs->md;
 
        freshest = NULL;
        rdev_for_each(rdev, tmp, mddev) {
@@ -1004,7 +1004,7 @@ static void raid_dtr(struct dm_target *ti)
 static int raid_map(struct dm_target *ti, struct bio *bio, union map_info *map_context)
 {
        struct raid_set *rs = ti->private;
-       mddev_t *mddev = &rs->md;
+       struct mddev *mddev = &rs->md;
 
        mddev->pers->make_request(mddev, bio);
 
@@ -1017,30 +1017,56 @@ static int raid_status(struct dm_target *ti, status_type_t type,
        struct raid_set *rs = ti->private;
        unsigned raid_param_cnt = 1; /* at least 1 for chunksize */
        unsigned sz = 0;
-       int i;
+       int i, array_in_sync = 0;
        sector_t sync;
 
        switch (type) {
        case STATUSTYPE_INFO:
                DMEMIT("%s %d ", rs->raid_type->name, rs->md.raid_disks);
 
-               for (i = 0; i < rs->md.raid_disks; i++) {
-                       if (test_bit(Faulty, &rs->dev[i].rdev.flags))
-                               DMEMIT("D");
-                       else if (test_bit(In_sync, &rs->dev[i].rdev.flags))
-                               DMEMIT("A");
-                       else
-                               DMEMIT("a");
-               }
-
                if (test_bit(MD_RECOVERY_RUNNING, &rs->md.recovery))
                        sync = rs->md.curr_resync_completed;
                else
                        sync = rs->md.recovery_cp;
 
-               if (sync > rs->md.resync_max_sectors)
+               if (sync >= rs->md.resync_max_sectors) {
+                       array_in_sync = 1;
                        sync = rs->md.resync_max_sectors;
+               } else {
+                       /*
+                        * The array may be doing an initial sync, or it may
+                        * be rebuilding individual components.  If all the
+                        * devices are In_sync, then it is the array that is
+                        * being initialized.
+                        */
+                       for (i = 0; i < rs->md.raid_disks; i++)
+                               if (!test_bit(In_sync, &rs->dev[i].rdev.flags))
+                                       array_in_sync = 1;
+               }
+               /*
+                * Status characters:
+                *  'D' = Dead/Failed device
+                *  'a' = Alive but not in-sync
+                *  'A' = Alive and in-sync
+                */
+               for (i = 0; i < rs->md.raid_disks; i++) {
+                       if (test_bit(Faulty, &rs->dev[i].rdev.flags))
+                               DMEMIT("D");
+                       else if (!array_in_sync ||
+                                !test_bit(In_sync, &rs->dev[i].rdev.flags))
+                               DMEMIT("a");
+                       else
+                               DMEMIT("A");
+               }
 
+               /*
+                * In-sync ratio:
+                *  The in-sync ratio shows the progress of:
+                *   - Initializing the array
+                *   - Rebuilding a subset of devices of the array
+                *  The user can distinguish between the two by referring
+                *  to the status characters.
+                */
                DMEMIT(" %llu/%llu",
                       (unsigned long long) sync,
                       (unsigned long long) rs->md.resync_max_sectors);
@@ -1097,7 +1123,7 @@ static int raid_status(struct dm_target *ti, status_type_t type,
                               rs->md.bitmap_info.max_write_behind);
 
                if (rs->print_flags & DMPF_STRIPE_CACHE) {
-                       raid5_conf_t *conf = rs->md.private;
+                       struct r5conf *conf = rs->md.private;
 
                        /* convert from kiB to sectors */
                        DMEMIT(" stripe_cache %d",
@@ -1146,7 +1172,7 @@ static void raid_io_hints(struct dm_target *ti, struct queue_limits *limits)
 {
        struct raid_set *rs = ti->private;
        unsigned chunk_size = rs->md.chunk_sectors << 9;
-       raid5_conf_t *conf = rs->md.private;
+       struct r5conf *conf = rs->md.private;
 
        blk_limits_io_min(limits, chunk_size);
        blk_limits_io_opt(limits, chunk_size * (conf->raid_disks - conf->max_degraded));