dm thin: fix discard corruption
[pandora-kernel.git] / drivers / md / dm-raid.c
index c2907d8..86862ea 100644 (file)
@@ -667,7 +667,14 @@ static int super_load(struct md_rdev *rdev, struct md_rdev *refdev)
                return ret;
 
        sb = page_address(rdev->sb_page);
-       if (sb->magic != cpu_to_le32(DM_RAID_MAGIC)) {
+
+       /*
+        * Two cases that we want to write new superblocks and rebuild:
+        * 1) New device (no matching magic number)
+        * 2) Device specified for rebuild (!In_sync w/ offset == 0)
+        */
+       if ((sb->magic != cpu_to_le32(DM_RAID_MAGIC)) ||
+           (!test_bit(In_sync, &rdev->flags) && !rdev->recovery_offset)) {
                super_sync(rdev->mddev, rdev);
 
                set_bit(FirstUse, &rdev->flags);
@@ -744,11 +751,8 @@ static int super_init_validation(struct mddev *mddev, struct md_rdev *rdev)
         */
        rdev_for_each(r, t, mddev) {
                if (!test_bit(In_sync, &r->flags)) {
-                       if (!test_bit(FirstUse, &r->flags))
-                               DMERR("Superblock area of "
-                                     "rebuild device %d should have been "
-                                     "cleared.", r->raid_disk);
-                       set_bit(FirstUse, &r->flags);
+                       DMINFO("Device %d specified for rebuild: "
+                              "Clearing superblock", r->raid_disk);
                        rebuilds++;
                } else if (test_bit(FirstUse, &r->flags))
                        new_devs++;
@@ -970,6 +974,7 @@ static int raid_ctr(struct dm_target *ti, unsigned argc, char **argv)
 
        INIT_WORK(&rs->md.event_work, do_table_event);
        ti->private = rs;
+       ti->num_flush_requests = 1;
 
        mutex_lock(&rs->md.reconfig_mutex);
        ret = md_run(&rs->md);
@@ -1012,8 +1017,8 @@ static int raid_map(struct dm_target *ti, struct bio *bio, union map_info *map_c
        return DM_MAPIO_SUBMITTED;
 }
 
-static int raid_status(struct dm_target *ti, status_type_t type,
-                      char *result, unsigned maxlen)
+static void raid_status(struct dm_target *ti, status_type_t type,
+                       char *result, unsigned maxlen)
 {
        struct raid_set *rs = ti->private;
        unsigned raid_param_cnt = 1; /* at least 1 for chunksize */
@@ -1148,8 +1153,6 @@ static int raid_status(struct dm_target *ti, status_type_t type,
                                DMEMIT(" -");
                }
        }
-
-       return 0;
 }
 
 static int raid_iterate_devices(struct dm_target *ti, iterate_devices_callout_fn fn, void *data)
@@ -1203,7 +1206,7 @@ static void raid_resume(struct dm_target *ti)
 
 static struct target_type raid_target = {
        .name = "raid",
-       .version = {1, 1, 0},
+       .version = {1, 1, 1},
        .module = THIS_MODULE,
        .ctr = raid_ctr,
        .dtr = raid_dtr,