dm raid1: implement mirror_flush
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)
Implement flush callee. It uses dm_io to send zero-size barrier synchronously
and concurrently to all the mirror legs.

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

index d44bc497dad9ec00b4888813e0a195edb64d66d0..751660b0c5741547dae116d81a167a73bbb4fd4c 100644 (file)
@@ -237,6 +237,40 @@ out:
        schedule_work(&ms->trigger_event);
 }
 
+static int mirror_flush(struct dm_target *ti)
+{
+       struct mirror_set *ms = ti->private;
+       unsigned long error_bits;
+
+       unsigned int i;
+       struct dm_io_region io[ms->nr_mirrors];
+       struct mirror *m;
+       struct dm_io_request io_req = {
+               .bi_rw = WRITE_BARRIER,
+               .mem.type = DM_IO_KMEM,
+               .mem.ptr.bvec = NULL,
+               .client = ms->io_client,
+       };
+
+       for (i = 0, m = ms->mirror; i < ms->nr_mirrors; i++, m++) {
+               io[i].bdev = m->dev->bdev;
+               io[i].sector = 0;
+               io[i].count = 0;
+       }
+
+       error_bits = -1;
+       dm_io(&io_req, ms->nr_mirrors, io, &error_bits);
+       if (unlikely(error_bits != 0)) {
+               for (i = 0; i < ms->nr_mirrors; i++)
+                       if (test_bit(i, &error_bits))
+                               fail_mirror(ms->mirror + i,
+                                           DM_RAID1_WRITE_ERROR);
+               return -EIO;
+       }
+
+       return 0;
+}
+
 /*-----------------------------------------------------------------
  * Recovery.
  *
@@ -896,7 +930,8 @@ static struct dm_dirty_log *create_dirty_log(struct dm_target *ti,
                return NULL;
        }
 
-       dl = dm_dirty_log_create(argv[0], ti, NULL, param_count, argv + 2);
+       dl = dm_dirty_log_create(argv[0], ti, mirror_flush, param_count,
+                                argv + 2);
        if (!dl) {
                ti->error = "Error creating mirror dirty log";
                return NULL;