diff options
author | Mikulas Patocka <mpatocka@redhat.com> | 2009-12-10 23:52:02 +0000 |
---|---|---|
committer | Alasdair G Kergon <agk@redhat.com> | 2009-12-10 23:52:02 +0000 |
commit | c0da3748b9a894b9f9b561ecc2d090a913988a0f (patch) | |
tree | 85213c004d3b39dae3d64ab8e4a641958421b231 /drivers/md/dm-raid1.c | |
parent | 076010e2e6ea5b66dfd1f81a6133fb014c9b291d (diff) | |
download | lwn-c0da3748b9a894b9f9b561ecc2d090a913988a0f.tar.gz lwn-c0da3748b9a894b9f9b561ecc2d090a913988a0f.zip |
dm raid1: implement mirror_flush
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>
Diffstat (limited to 'drivers/md/dm-raid1.c')
-rw-r--r-- | drivers/md/dm-raid1.c | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/drivers/md/dm-raid1.c b/drivers/md/dm-raid1.c index d44bc497dad9..751660b0c574 100644 --- a/drivers/md/dm-raid1.c +++ b/drivers/md/dm-raid1.c @@ -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; |