13bd94003SHeinz Mauelshagen // SPDX-License-Identifier: GPL-2.0-only
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds * Copyright (C) 2003 Sistina Software Limited.
41f965b19SHeinz Mauelshagen * Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
51da177e4SLinus Torvalds *
61da177e4SLinus Torvalds * This file is released under the GPL.
71da177e4SLinus Torvalds */
81da177e4SLinus Torvalds
906386bbfSJonathan Brassow #include "dm-bio-record.h"
101da177e4SLinus Torvalds
111da177e4SLinus Torvalds #include <linux/init.h>
121da177e4SLinus Torvalds #include <linux/mempool.h>
131da177e4SLinus Torvalds #include <linux/module.h>
141da177e4SLinus Torvalds #include <linux/pagemap.h>
151da177e4SLinus Torvalds #include <linux/slab.h>
161da177e4SLinus Torvalds #include <linux/workqueue.h>
171f965b19SHeinz Mauelshagen #include <linux/device-mapper.h>
18a765e20eSAlasdair G Kergon #include <linux/dm-io.h>
19a765e20eSAlasdair G Kergon #include <linux/dm-dirty-log.h>
20a765e20eSAlasdair G Kergon #include <linux/dm-kcopyd.h>
211f965b19SHeinz Mauelshagen #include <linux/dm-region-hash.h>
221da177e4SLinus Torvalds
23a7e8f7fbSTetsuo Handa static struct workqueue_struct *dm_raid1_wq;
24a7e8f7fbSTetsuo Handa
2572d94861SAlasdair G Kergon #define DM_MSG_PREFIX "raid1"
261f965b19SHeinz Mauelshagen
271f965b19SHeinz Mauelshagen #define MAX_RECOVERY 1 /* Maximum number of regions recovered in parallel. */
2872d94861SAlasdair G Kergon
2965972a6fSKees Cook #define MAX_NR_MIRRORS (DM_KCOPYD_MAX_REGIONS + 1)
3065972a6fSKees Cook
31a8e6afa2SJonathan E Brassow #define DM_RAID1_HANDLE_ERRORS 0x01
32ed63287dSLidong Zhong #define DM_RAID1_KEEP_LOG 0x02
33f44db678SJonathan Brassow #define errors_handled(p) ((p)->features & DM_RAID1_HANDLE_ERRORS)
34ed63287dSLidong Zhong #define keep_log(p) ((p)->features & DM_RAID1_KEEP_LOG)
35a8e6afa2SJonathan E Brassow
3633184048SJonathan E Brassow static DECLARE_WAIT_QUEUE_HEAD(_kmirrord_recovery_stopped);
371da177e4SLinus Torvalds
38a4a82ce3SHeinz Mauelshagen /*
39a4a82ce3SHeinz Mauelshagen *---------------------------------------------------------------
40e4c8b3baSNeil Brown * Mirror set structures.
41a4a82ce3SHeinz Mauelshagen *---------------------------------------------------------------
42a4a82ce3SHeinz Mauelshagen */
4372f4b314SJonathan Brassow enum dm_raid1_error {
4472f4b314SJonathan Brassow DM_RAID1_WRITE_ERROR,
4564b30c46SMikulas Patocka DM_RAID1_FLUSH_ERROR,
4672f4b314SJonathan Brassow DM_RAID1_SYNC_ERROR,
4772f4b314SJonathan Brassow DM_RAID1_READ_ERROR
4872f4b314SJonathan Brassow };
4972f4b314SJonathan Brassow
50e4c8b3baSNeil Brown struct mirror {
51aa5617c5SJonathan Brassow struct mirror_set *ms;
52e4c8b3baSNeil Brown atomic_t error_count;
5339ed7adbSAl Viro unsigned long error_type;
54e4c8b3baSNeil Brown struct dm_dev *dev;
55e4c8b3baSNeil Brown sector_t offset;
56e4c8b3baSNeil Brown };
57e4c8b3baSNeil Brown
58e4c8b3baSNeil Brown struct mirror_set {
59e4c8b3baSNeil Brown struct dm_target *ti;
60e4c8b3baSNeil Brown struct list_head list;
611f965b19SHeinz Mauelshagen
62a8e6afa2SJonathan E Brassow uint64_t features;
63e4c8b3baSNeil Brown
6472f4b314SJonathan Brassow spinlock_t lock; /* protects the lists */
65e4c8b3baSNeil Brown struct bio_list reads;
66e4c8b3baSNeil Brown struct bio_list writes;
6772f4b314SJonathan Brassow struct bio_list failures;
6804788507SMikulas Patocka struct bio_list holds; /* bios are waiting until suspend */
69e4c8b3baSNeil Brown
701f965b19SHeinz Mauelshagen struct dm_region_hash *rh;
711f965b19SHeinz Mauelshagen struct dm_kcopyd_client *kcopyd_client;
7288be163aSMilan Broz struct dm_io_client *io_client;
7388be163aSMilan Broz
74e4c8b3baSNeil Brown /* recovery */
75e4c8b3baSNeil Brown region_t nr_regions;
76e4c8b3baSNeil Brown int in_sync;
77fc1ff958SJonathan Brassow int log_failure;
78929be8fcSMikulas Patocka int leg_failure;
79b80aa7a0SJonathan Brassow atomic_t suspend;
80e4c8b3baSNeil Brown
8172f4b314SJonathan Brassow atomic_t default_mirror; /* Default mirror */
82e4c8b3baSNeil Brown
836ad36fe2SHolger Smolinski struct workqueue_struct *kmirrord_wq;
846ad36fe2SHolger Smolinski struct work_struct kmirrord_work;
85a2aebe03SMikulas Patocka struct timer_list timer;
86a2aebe03SMikulas Patocka unsigned long timer_pending;
87a2aebe03SMikulas Patocka
8872f4b314SJonathan Brassow struct work_struct trigger_event;
896ad36fe2SHolger Smolinski
9086a3238cSHeinz Mauelshagen unsigned int nr_mirrors;
91b18ae8ddSGustavo A. R. Silva struct mirror mirror[];
92e4c8b3baSNeil Brown };
93e4c8b3baSNeil Brown
94df5d2e90SMikulas Patocka DECLARE_DM_KCOPYD_THROTTLE_WITH_MODULE_PARM(raid1_resync_throttle,
95df5d2e90SMikulas Patocka "A percentage of time allocated for raid resynchronization");
96df5d2e90SMikulas Patocka
wakeup_mirrord(void * context)971f965b19SHeinz Mauelshagen static void wakeup_mirrord(void *context)
981da177e4SLinus Torvalds {
991f965b19SHeinz Mauelshagen struct mirror_set *ms = context;
1001da177e4SLinus Torvalds
1016ad36fe2SHolger Smolinski queue_work(ms->kmirrord_wq, &ms->kmirrord_work);
1026ad36fe2SHolger Smolinski }
1036ad36fe2SHolger Smolinski
delayed_wake_fn(struct timer_list * t)1048376d3c1SKees Cook static void delayed_wake_fn(struct timer_list *t)
105a2aebe03SMikulas Patocka {
1068376d3c1SKees Cook struct mirror_set *ms = from_timer(ms, t, timer);
107a2aebe03SMikulas Patocka
108a2aebe03SMikulas Patocka clear_bit(0, &ms->timer_pending);
1091f965b19SHeinz Mauelshagen wakeup_mirrord(ms);
110a2aebe03SMikulas Patocka }
111a2aebe03SMikulas Patocka
delayed_wake(struct mirror_set * ms)112a2aebe03SMikulas Patocka static void delayed_wake(struct mirror_set *ms)
113a2aebe03SMikulas Patocka {
114a2aebe03SMikulas Patocka if (test_and_set_bit(0, &ms->timer_pending))
115a2aebe03SMikulas Patocka return;
116a2aebe03SMikulas Patocka
117a2aebe03SMikulas Patocka ms->timer.expires = jiffies + HZ / 5;
118a2aebe03SMikulas Patocka add_timer(&ms->timer);
119a2aebe03SMikulas Patocka }
120a2aebe03SMikulas Patocka
wakeup_all_recovery_waiters(void * context)1211f965b19SHeinz Mauelshagen static void wakeup_all_recovery_waiters(void *context)
1221da177e4SLinus Torvalds {
123f3ee6b2fSJonathan E Brassow wake_up_all(&_kmirrord_recovery_stopped);
124f3ee6b2fSJonathan E Brassow }
125f3ee6b2fSJonathan E Brassow
queue_bio(struct mirror_set * ms,struct bio * bio,int rw)1261f965b19SHeinz Mauelshagen static void queue_bio(struct mirror_set *ms, struct bio *bio, int rw)
1271da177e4SLinus Torvalds {
1281da177e4SLinus Torvalds unsigned long flags;
1291da177e4SLinus Torvalds int should_wake = 0;
1301f965b19SHeinz Mauelshagen struct bio_list *bl;
1311da177e4SLinus Torvalds
1321f965b19SHeinz Mauelshagen bl = (rw == WRITE) ? &ms->writes : &ms->reads;
1331f965b19SHeinz Mauelshagen spin_lock_irqsave(&ms->lock, flags);
1341f965b19SHeinz Mauelshagen should_wake = !(bl->head);
1351f965b19SHeinz Mauelshagen bio_list_add(bl, bio);
1361f965b19SHeinz Mauelshagen spin_unlock_irqrestore(&ms->lock, flags);
1371da177e4SLinus Torvalds
1381da177e4SLinus Torvalds if (should_wake)
1391f965b19SHeinz Mauelshagen wakeup_mirrord(ms);
1401da177e4SLinus Torvalds }
1411da177e4SLinus Torvalds
dispatch_bios(void * context,struct bio_list * bio_list)1421f965b19SHeinz Mauelshagen static void dispatch_bios(void *context, struct bio_list *bio_list)
1431da177e4SLinus Torvalds {
1441f965b19SHeinz Mauelshagen struct mirror_set *ms = context;
1451f965b19SHeinz Mauelshagen struct bio *bio;
1461da177e4SLinus Torvalds
1471f965b19SHeinz Mauelshagen while ((bio = bio_list_pop(bio_list)))
1481f965b19SHeinz Mauelshagen queue_bio(ms, bio, WRITE);
1491da177e4SLinus Torvalds }
1501da177e4SLinus Torvalds
15189c7cd89SMikulas Patocka struct dm_raid1_bio_record {
15206386bbfSJonathan Brassow struct mirror *m;
153309dca30SChristoph Hellwig /* if details->bi_bdev == NULL, details were not saved */
15406386bbfSJonathan Brassow struct dm_bio_details details;
1550045d61bSMikulas Patocka region_t write_region;
15606386bbfSJonathan Brassow };
15706386bbfSJonathan Brassow
1581da177e4SLinus Torvalds /*
1591da177e4SLinus Torvalds * Every mirror should look like this one.
1601da177e4SLinus Torvalds */
1611da177e4SLinus Torvalds #define DEFAULT_MIRROR 0
1621da177e4SLinus Torvalds
1631da177e4SLinus Torvalds /*
16406386bbfSJonathan Brassow * This is yucky. We squirrel the mirror struct away inside
16506386bbfSJonathan Brassow * bi_next for read/write buffers. This is safe since the bh
1661da177e4SLinus Torvalds * doesn't get submitted to the lower levels of block layer.
1671da177e4SLinus Torvalds */
bio_get_m(struct bio * bio)16806386bbfSJonathan Brassow static struct mirror *bio_get_m(struct bio *bio)
1691da177e4SLinus Torvalds {
17006386bbfSJonathan Brassow return (struct mirror *) bio->bi_next;
1711da177e4SLinus Torvalds }
1721da177e4SLinus Torvalds
bio_set_m(struct bio * bio,struct mirror * m)17306386bbfSJonathan Brassow static void bio_set_m(struct bio *bio, struct mirror *m)
1741da177e4SLinus Torvalds {
17506386bbfSJonathan Brassow bio->bi_next = (struct bio *) m;
1761da177e4SLinus Torvalds }
1771da177e4SLinus Torvalds
get_default_mirror(struct mirror_set * ms)17872f4b314SJonathan Brassow static struct mirror *get_default_mirror(struct mirror_set *ms)
17972f4b314SJonathan Brassow {
18072f4b314SJonathan Brassow return &ms->mirror[atomic_read(&ms->default_mirror)];
18172f4b314SJonathan Brassow }
18272f4b314SJonathan Brassow
set_default_mirror(struct mirror * m)18372f4b314SJonathan Brassow static void set_default_mirror(struct mirror *m)
18472f4b314SJonathan Brassow {
18572f4b314SJonathan Brassow struct mirror_set *ms = m->ms;
18672f4b314SJonathan Brassow struct mirror *m0 = &(ms->mirror[0]);
18772f4b314SJonathan Brassow
18872f4b314SJonathan Brassow atomic_set(&ms->default_mirror, m - m0);
18972f4b314SJonathan Brassow }
19072f4b314SJonathan Brassow
get_valid_mirror(struct mirror_set * ms)19187968dddSMikulas Patocka static struct mirror *get_valid_mirror(struct mirror_set *ms)
19287968dddSMikulas Patocka {
19387968dddSMikulas Patocka struct mirror *m;
19487968dddSMikulas Patocka
19587968dddSMikulas Patocka for (m = ms->mirror; m < ms->mirror + ms->nr_mirrors; m++)
19687968dddSMikulas Patocka if (!atomic_read(&m->error_count))
19787968dddSMikulas Patocka return m;
19887968dddSMikulas Patocka
19987968dddSMikulas Patocka return NULL;
20087968dddSMikulas Patocka }
20187968dddSMikulas Patocka
20272f4b314SJonathan Brassow /* fail_mirror
20372f4b314SJonathan Brassow * @m: mirror device to fail
20472f4b314SJonathan Brassow * @error_type: one of the enum's, DM_RAID1_*_ERROR
20572f4b314SJonathan Brassow *
20672f4b314SJonathan Brassow * If errors are being handled, record the type of
20772f4b314SJonathan Brassow * error encountered for this device. If this type
20872f4b314SJonathan Brassow * of error has already been recorded, we can return;
20972f4b314SJonathan Brassow * otherwise, we must signal userspace by triggering
21072f4b314SJonathan Brassow * an event. Additionally, if the device is the
21172f4b314SJonathan Brassow * primary device, we must choose a new primary, but
21272f4b314SJonathan Brassow * only if the mirror is in-sync.
21372f4b314SJonathan Brassow *
21472f4b314SJonathan Brassow * This function must not block.
21572f4b314SJonathan Brassow */
fail_mirror(struct mirror * m,enum dm_raid1_error error_type)21672f4b314SJonathan Brassow static void fail_mirror(struct mirror *m, enum dm_raid1_error error_type)
21772f4b314SJonathan Brassow {
21872f4b314SJonathan Brassow struct mirror_set *ms = m->ms;
21972f4b314SJonathan Brassow struct mirror *new;
22072f4b314SJonathan Brassow
221929be8fcSMikulas Patocka ms->leg_failure = 1;
222929be8fcSMikulas Patocka
22372f4b314SJonathan Brassow /*
22472f4b314SJonathan Brassow * error_count is used for nothing more than a
22572f4b314SJonathan Brassow * simple way to tell if a device has encountered
22672f4b314SJonathan Brassow * errors.
22772f4b314SJonathan Brassow */
22872f4b314SJonathan Brassow atomic_inc(&m->error_count);
22972f4b314SJonathan Brassow
23072f4b314SJonathan Brassow if (test_and_set_bit(error_type, &m->error_type))
23172f4b314SJonathan Brassow return;
23272f4b314SJonathan Brassow
233d460c65aSJonathan Brassow if (!errors_handled(ms))
234d460c65aSJonathan Brassow return;
235d460c65aSJonathan Brassow
23672f4b314SJonathan Brassow if (m != get_default_mirror(ms))
23772f4b314SJonathan Brassow goto out;
23872f4b314SJonathan Brassow
239ed63287dSLidong Zhong if (!ms->in_sync && !keep_log(ms)) {
24072f4b314SJonathan Brassow /*
24172f4b314SJonathan Brassow * Better to issue requests to same failing device
24272f4b314SJonathan Brassow * than to risk returning corrupt data.
24372f4b314SJonathan Brassow */
2442e84fecfSHeinz Mauelshagen DMERR("Primary mirror (%s) failed while out-of-sync: Reads may fail.",
2452e84fecfSHeinz Mauelshagen m->dev->name);
24672f4b314SJonathan Brassow goto out;
24772f4b314SJonathan Brassow }
24872f4b314SJonathan Brassow
24987968dddSMikulas Patocka new = get_valid_mirror(ms);
25087968dddSMikulas Patocka if (new)
25172f4b314SJonathan Brassow set_default_mirror(new);
25287968dddSMikulas Patocka else
25372f4b314SJonathan Brassow DMWARN("All sides of mirror have failed.");
25472f4b314SJonathan Brassow
25572f4b314SJonathan Brassow out:
256a7e8f7fbSTetsuo Handa queue_work(dm_raid1_wq, &ms->trigger_event);
25772f4b314SJonathan Brassow }
25872f4b314SJonathan Brassow
mirror_flush(struct dm_target * ti)259c0da3748SMikulas Patocka static int mirror_flush(struct dm_target *ti)
260c0da3748SMikulas Patocka {
261c0da3748SMikulas Patocka struct mirror_set *ms = ti->private;
262c0da3748SMikulas Patocka unsigned long error_bits;
263c0da3748SMikulas Patocka
264c0da3748SMikulas Patocka unsigned int i;
26565972a6fSKees Cook struct dm_io_region io[MAX_NR_MIRRORS];
266c0da3748SMikulas Patocka struct mirror *m;
267c0da3748SMikulas Patocka struct dm_io_request io_req = {
268581075e4SBart Van Assche .bi_opf = REQ_OP_WRITE | REQ_PREFLUSH | REQ_SYNC,
269c0da3748SMikulas Patocka .mem.type = DM_IO_KMEM,
2705fc2ffeaSMike Snitzer .mem.ptr.addr = NULL,
271c0da3748SMikulas Patocka .client = ms->io_client,
272c0da3748SMikulas Patocka };
273c0da3748SMikulas Patocka
274c0da3748SMikulas Patocka for (i = 0, m = ms->mirror; i < ms->nr_mirrors; i++, m++) {
275c0da3748SMikulas Patocka io[i].bdev = m->dev->bdev;
276c0da3748SMikulas Patocka io[i].sector = 0;
277c0da3748SMikulas Patocka io[i].count = 0;
278c0da3748SMikulas Patocka }
279c0da3748SMikulas Patocka
280c0da3748SMikulas Patocka error_bits = -1;
281*5cfcea64SHongyu Jin dm_io(&io_req, ms->nr_mirrors, io, &error_bits, IOPRIO_DEFAULT);
282c0da3748SMikulas Patocka if (unlikely(error_bits != 0)) {
283c0da3748SMikulas Patocka for (i = 0; i < ms->nr_mirrors; i++)
284c0da3748SMikulas Patocka if (test_bit(i, &error_bits))
285c0da3748SMikulas Patocka fail_mirror(ms->mirror + i,
28664b30c46SMikulas Patocka DM_RAID1_FLUSH_ERROR);
287c0da3748SMikulas Patocka return -EIO;
288c0da3748SMikulas Patocka }
289c0da3748SMikulas Patocka
290c0da3748SMikulas Patocka return 0;
291c0da3748SMikulas Patocka }
292c0da3748SMikulas Patocka
293a4a82ce3SHeinz Mauelshagen /*
294a4a82ce3SHeinz Mauelshagen *---------------------------------------------------------------
2951da177e4SLinus Torvalds * Recovery.
2961da177e4SLinus Torvalds *
2971da177e4SLinus Torvalds * When a mirror is first activated we may find that some regions
2981da177e4SLinus Torvalds * are in the no-sync state. We have to recover these by
2991da177e4SLinus Torvalds * recopying from the default mirror to all the others.
300a4a82ce3SHeinz Mauelshagen *---------------------------------------------------------------
301a4a82ce3SHeinz Mauelshagen */
recovery_complete(int read_err,unsigned long write_err,void * context)3024cdc1d1fSAlasdair G Kergon static void recovery_complete(int read_err, unsigned long write_err,
3031da177e4SLinus Torvalds void *context)
3041da177e4SLinus Torvalds {
3051f965b19SHeinz Mauelshagen struct dm_region *reg = context;
3061f965b19SHeinz Mauelshagen struct mirror_set *ms = dm_rh_region_context(reg);
3078f0205b7SJonathan Brassow int m, bit = 0;
3081da177e4SLinus Torvalds
3098f0205b7SJonathan Brassow if (read_err) {
310f44db678SJonathan Brassow /* Read error means the failure of default mirror. */
311f44db678SJonathan Brassow DMERR_LIMIT("Unable to read primary mirror during recovery");
3128f0205b7SJonathan Brassow fail_mirror(get_default_mirror(ms), DM_RAID1_SYNC_ERROR);
3138f0205b7SJonathan Brassow }
314f44db678SJonathan Brassow
3158f0205b7SJonathan Brassow if (write_err) {
3164cdc1d1fSAlasdair G Kergon DMERR_LIMIT("Write error during recovery (error = 0x%lx)",
317f44db678SJonathan Brassow write_err);
3188f0205b7SJonathan Brassow /*
3198f0205b7SJonathan Brassow * Bits correspond to devices (excluding default mirror).
3208f0205b7SJonathan Brassow * The default mirror cannot change during recovery.
3218f0205b7SJonathan Brassow */
3228f0205b7SJonathan Brassow for (m = 0; m < ms->nr_mirrors; m++) {
3238f0205b7SJonathan Brassow if (&ms->mirror[m] == get_default_mirror(ms))
3248f0205b7SJonathan Brassow continue;
3258f0205b7SJonathan Brassow if (test_bit(bit, &write_err))
3268f0205b7SJonathan Brassow fail_mirror(ms->mirror + m,
3278f0205b7SJonathan Brassow DM_RAID1_SYNC_ERROR);
3288f0205b7SJonathan Brassow bit++;
3298f0205b7SJonathan Brassow }
3308f0205b7SJonathan Brassow }
331f44db678SJonathan Brassow
3321f965b19SHeinz Mauelshagen dm_rh_recovery_end(reg, !(read_err || write_err));
3331da177e4SLinus Torvalds }
3341da177e4SLinus Torvalds
recover(struct mirror_set * ms,struct dm_region * reg)3357209049dSMike Snitzer static void recover(struct mirror_set *ms, struct dm_region *reg)
3361da177e4SLinus Torvalds {
33786a3238cSHeinz Mauelshagen unsigned int i;
338eb69aca5SHeinz Mauelshagen struct dm_io_region from, to[DM_KCOPYD_MAX_REGIONS], *dest;
3391da177e4SLinus Torvalds struct mirror *m;
3401da177e4SLinus Torvalds unsigned long flags = 0;
3411f965b19SHeinz Mauelshagen region_t key = dm_rh_get_region_key(reg);
3421f965b19SHeinz Mauelshagen sector_t region_size = dm_rh_get_region_size(ms->rh);
3431da177e4SLinus Torvalds
3441da177e4SLinus Torvalds /* fill in the source */
34572f4b314SJonathan Brassow m = get_default_mirror(ms);
3461da177e4SLinus Torvalds from.bdev = m->dev->bdev;
3471f965b19SHeinz Mauelshagen from.sector = m->offset + dm_rh_region_to_sector(ms->rh, key);
3481f965b19SHeinz Mauelshagen if (key == (ms->nr_regions - 1)) {
3491da177e4SLinus Torvalds /*
3501da177e4SLinus Torvalds * The final region may be smaller than
3511da177e4SLinus Torvalds * region_size.
3521da177e4SLinus Torvalds */
3531f965b19SHeinz Mauelshagen from.count = ms->ti->len & (region_size - 1);
3541da177e4SLinus Torvalds if (!from.count)
3551f965b19SHeinz Mauelshagen from.count = region_size;
3561da177e4SLinus Torvalds } else
3571f965b19SHeinz Mauelshagen from.count = region_size;
3581da177e4SLinus Torvalds
3591da177e4SLinus Torvalds /* fill in the destinations */
3601da177e4SLinus Torvalds for (i = 0, dest = to; i < ms->nr_mirrors; i++) {
36172f4b314SJonathan Brassow if (&ms->mirror[i] == get_default_mirror(ms))
3621da177e4SLinus Torvalds continue;
3631da177e4SLinus Torvalds
3641da177e4SLinus Torvalds m = ms->mirror + i;
3651da177e4SLinus Torvalds dest->bdev = m->dev->bdev;
3661f965b19SHeinz Mauelshagen dest->sector = m->offset + dm_rh_region_to_sector(ms->rh, key);
3671da177e4SLinus Torvalds dest->count = from.count;
3681da177e4SLinus Torvalds dest++;
3691da177e4SLinus Torvalds }
3701da177e4SLinus Torvalds
3711da177e4SLinus Torvalds /* hand to kcopyd */
372f7c83e2eSJonathan Brassow if (!errors_handled(ms))
373db2351ebSMikulas Patocka flags |= BIT(DM_KCOPYD_IGNORE_ERROR);
374f7c83e2eSJonathan Brassow
3757209049dSMike Snitzer dm_kcopyd_copy(ms->kcopyd_client, &from, ms->nr_mirrors - 1, to,
376eb69aca5SHeinz Mauelshagen flags, recovery_complete, reg);
3771da177e4SLinus Torvalds }
3781da177e4SLinus Torvalds
reset_ms_flags(struct mirror_set * ms)379ed63287dSLidong Zhong static void reset_ms_flags(struct mirror_set *ms)
380ed63287dSLidong Zhong {
381ed63287dSLidong Zhong unsigned int m;
382ed63287dSLidong Zhong
383ed63287dSLidong Zhong ms->leg_failure = 0;
384ed63287dSLidong Zhong for (m = 0; m < ms->nr_mirrors; m++) {
385ed63287dSLidong Zhong atomic_set(&(ms->mirror[m].error_count), 0);
386ed63287dSLidong Zhong ms->mirror[m].error_type = 0;
387ed63287dSLidong Zhong }
388ed63287dSLidong Zhong }
389ed63287dSLidong Zhong
do_recovery(struct mirror_set * ms)3901da177e4SLinus Torvalds static void do_recovery(struct mirror_set *ms)
3911da177e4SLinus Torvalds {
3921f965b19SHeinz Mauelshagen struct dm_region *reg;
3931f965b19SHeinz Mauelshagen struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh);
3941da177e4SLinus Torvalds
3951da177e4SLinus Torvalds /*
3961da177e4SLinus Torvalds * Start quiescing some regions.
3971da177e4SLinus Torvalds */
3981f965b19SHeinz Mauelshagen dm_rh_recovery_prepare(ms->rh);
3991da177e4SLinus Torvalds
4001da177e4SLinus Torvalds /*
4011da177e4SLinus Torvalds * Copy any already quiesced regions.
4021da177e4SLinus Torvalds */
4037209049dSMike Snitzer while ((reg = dm_rh_recovery_start(ms->rh)))
4047209049dSMike Snitzer recover(ms, reg);
4051da177e4SLinus Torvalds
4061da177e4SLinus Torvalds /*
4071da177e4SLinus Torvalds * Update the in sync flag.
4081da177e4SLinus Torvalds */
4091da177e4SLinus Torvalds if (!ms->in_sync &&
4101da177e4SLinus Torvalds (log->type->get_sync_count(log) == ms->nr_regions)) {
4111da177e4SLinus Torvalds /* the sync is complete */
4121da177e4SLinus Torvalds dm_table_event(ms->ti->table);
4131da177e4SLinus Torvalds ms->in_sync = 1;
414ed63287dSLidong Zhong reset_ms_flags(ms);
4151da177e4SLinus Torvalds }
4161da177e4SLinus Torvalds }
4171da177e4SLinus Torvalds
418a4a82ce3SHeinz Mauelshagen /*
419a4a82ce3SHeinz Mauelshagen *---------------------------------------------------------------
4201da177e4SLinus Torvalds * Reads
421a4a82ce3SHeinz Mauelshagen *---------------------------------------------------------------
422a4a82ce3SHeinz Mauelshagen */
choose_mirror(struct mirror_set * ms,sector_t sector)4231da177e4SLinus Torvalds static struct mirror *choose_mirror(struct mirror_set *ms, sector_t sector)
4241da177e4SLinus Torvalds {
42506386bbfSJonathan Brassow struct mirror *m = get_default_mirror(ms);
42606386bbfSJonathan Brassow
42706386bbfSJonathan Brassow do {
42806386bbfSJonathan Brassow if (likely(!atomic_read(&m->error_count)))
42906386bbfSJonathan Brassow return m;
43006386bbfSJonathan Brassow
43106386bbfSJonathan Brassow if (m-- == ms->mirror)
43206386bbfSJonathan Brassow m += ms->nr_mirrors;
43306386bbfSJonathan Brassow } while (m != get_default_mirror(ms));
43406386bbfSJonathan Brassow
43506386bbfSJonathan Brassow return NULL;
43606386bbfSJonathan Brassow }
43706386bbfSJonathan Brassow
default_ok(struct mirror * m)43806386bbfSJonathan Brassow static int default_ok(struct mirror *m)
43906386bbfSJonathan Brassow {
44006386bbfSJonathan Brassow struct mirror *default_mirror = get_default_mirror(m->ms);
44106386bbfSJonathan Brassow
44206386bbfSJonathan Brassow return !atomic_read(&default_mirror->error_count);
44306386bbfSJonathan Brassow }
44406386bbfSJonathan Brassow
mirror_available(struct mirror_set * ms,struct bio * bio)44506386bbfSJonathan Brassow static int mirror_available(struct mirror_set *ms, struct bio *bio)
44606386bbfSJonathan Brassow {
4471f965b19SHeinz Mauelshagen struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh);
4481f965b19SHeinz Mauelshagen region_t region = dm_rh_bio_to_region(ms->rh, bio);
44906386bbfSJonathan Brassow
4501f965b19SHeinz Mauelshagen if (log->type->in_sync(log, region, 0))
4514f024f37SKent Overstreet return choose_mirror(ms, bio->bi_iter.bi_sector) ? 1 : 0;
45206386bbfSJonathan Brassow
45306386bbfSJonathan Brassow return 0;
4541da177e4SLinus Torvalds }
4551da177e4SLinus Torvalds
4561da177e4SLinus Torvalds /*
4571da177e4SLinus Torvalds * remap a buffer to a particular mirror.
4581da177e4SLinus Torvalds */
map_sector(struct mirror * m,struct bio * bio)45906386bbfSJonathan Brassow static sector_t map_sector(struct mirror *m, struct bio *bio)
46006386bbfSJonathan Brassow {
4614f024f37SKent Overstreet if (unlikely(!bio->bi_iter.bi_size))
4624184153fSMikulas Patocka return 0;
4634f024f37SKent Overstreet return m->offset + dm_target_offset(m->ms->ti, bio->bi_iter.bi_sector);
46406386bbfSJonathan Brassow }
46506386bbfSJonathan Brassow
map_bio(struct mirror * m,struct bio * bio)46606386bbfSJonathan Brassow static void map_bio(struct mirror *m, struct bio *bio)
4671da177e4SLinus Torvalds {
46874d46992SChristoph Hellwig bio_set_dev(bio, m->dev->bdev);
4694f024f37SKent Overstreet bio->bi_iter.bi_sector = map_sector(m, bio);
47006386bbfSJonathan Brassow }
47106386bbfSJonathan Brassow
map_region(struct dm_io_region * io,struct mirror * m,struct bio * bio)47222a1ceb1SHeinz Mauelshagen static void map_region(struct dm_io_region *io, struct mirror *m,
47306386bbfSJonathan Brassow struct bio *bio)
47406386bbfSJonathan Brassow {
47506386bbfSJonathan Brassow io->bdev = m->dev->bdev;
47606386bbfSJonathan Brassow io->sector = map_sector(m, bio);
477aa8b57aaSKent Overstreet io->count = bio_sectors(bio);
47806386bbfSJonathan Brassow }
47906386bbfSJonathan Brassow
hold_bio(struct mirror_set * ms,struct bio * bio)48004788507SMikulas Patocka static void hold_bio(struct mirror_set *ms, struct bio *bio)
48104788507SMikulas Patocka {
48204788507SMikulas Patocka /*
483f0703040STakahiro Yasui * Lock is required to avoid race condition during suspend
484f0703040STakahiro Yasui * process.
485f0703040STakahiro Yasui */
486f0703040STakahiro Yasui spin_lock_irq(&ms->lock);
487f0703040STakahiro Yasui
488f0703040STakahiro Yasui if (atomic_read(&ms->suspend)) {
489f0703040STakahiro Yasui spin_unlock_irq(&ms->lock);
490f0703040STakahiro Yasui
491f0703040STakahiro Yasui /*
49204788507SMikulas Patocka * If device is suspended, complete the bio.
49304788507SMikulas Patocka */
49404788507SMikulas Patocka if (dm_noflush_suspending(ms->ti))
4954e4cbee9SChristoph Hellwig bio->bi_status = BLK_STS_DM_REQUEUE;
49604788507SMikulas Patocka else
4974e4cbee9SChristoph Hellwig bio->bi_status = BLK_STS_IOERR;
4984246a0b6SChristoph Hellwig
4994246a0b6SChristoph Hellwig bio_endio(bio);
50004788507SMikulas Patocka return;
50104788507SMikulas Patocka }
50204788507SMikulas Patocka
50304788507SMikulas Patocka /*
50404788507SMikulas Patocka * Hold bio until the suspend is complete.
50504788507SMikulas Patocka */
50604788507SMikulas Patocka bio_list_add(&ms->holds, bio);
50704788507SMikulas Patocka spin_unlock_irq(&ms->lock);
50804788507SMikulas Patocka }
50904788507SMikulas Patocka
510a4a82ce3SHeinz Mauelshagen /*
511a4a82ce3SHeinz Mauelshagen *---------------------------------------------------------------
51206386bbfSJonathan Brassow * Reads
513a4a82ce3SHeinz Mauelshagen *---------------------------------------------------------------
514a4a82ce3SHeinz Mauelshagen */
read_callback(unsigned long error,void * context)51506386bbfSJonathan Brassow static void read_callback(unsigned long error, void *context)
51606386bbfSJonathan Brassow {
51706386bbfSJonathan Brassow struct bio *bio = context;
51806386bbfSJonathan Brassow struct mirror *m;
51906386bbfSJonathan Brassow
52006386bbfSJonathan Brassow m = bio_get_m(bio);
52106386bbfSJonathan Brassow bio_set_m(bio, NULL);
52206386bbfSJonathan Brassow
52306386bbfSJonathan Brassow if (likely(!error)) {
5244246a0b6SChristoph Hellwig bio_endio(bio);
52506386bbfSJonathan Brassow return;
52606386bbfSJonathan Brassow }
52706386bbfSJonathan Brassow
52806386bbfSJonathan Brassow fail_mirror(m, DM_RAID1_READ_ERROR);
52906386bbfSJonathan Brassow
53006386bbfSJonathan Brassow if (likely(default_ok(m)) || mirror_available(m->ms, bio)) {
5312e84fecfSHeinz Mauelshagen DMWARN_LIMIT("Read failure on mirror device %s. Trying alternative device.",
53206386bbfSJonathan Brassow m->dev->name);
53370246286SChristoph Hellwig queue_bio(m->ms, bio, bio_data_dir(bio));
53406386bbfSJonathan Brassow return;
53506386bbfSJonathan Brassow }
53606386bbfSJonathan Brassow
53706386bbfSJonathan Brassow DMERR_LIMIT("Read failure on mirror device %s. Failing I/O.",
53806386bbfSJonathan Brassow m->dev->name);
5394246a0b6SChristoph Hellwig bio_io_error(bio);
54006386bbfSJonathan Brassow }
54106386bbfSJonathan Brassow
54206386bbfSJonathan Brassow /* Asynchronous read. */
read_async_bio(struct mirror * m,struct bio * bio)54306386bbfSJonathan Brassow static void read_async_bio(struct mirror *m, struct bio *bio)
54406386bbfSJonathan Brassow {
54522a1ceb1SHeinz Mauelshagen struct dm_io_region io;
54606386bbfSJonathan Brassow struct dm_io_request io_req = {
547581075e4SBart Van Assche .bi_opf = REQ_OP_READ,
548003b5c57SKent Overstreet .mem.type = DM_IO_BIO,
549003b5c57SKent Overstreet .mem.ptr.bio = bio,
55006386bbfSJonathan Brassow .notify.fn = read_callback,
55106386bbfSJonathan Brassow .notify.context = bio,
55206386bbfSJonathan Brassow .client = m->ms->io_client,
55306386bbfSJonathan Brassow };
55406386bbfSJonathan Brassow
55506386bbfSJonathan Brassow map_region(&io, m, bio);
55606386bbfSJonathan Brassow bio_set_m(bio, m);
557*5cfcea64SHongyu Jin BUG_ON(dm_io(&io_req, 1, &io, NULL, IOPRIO_DEFAULT));
5581f965b19SHeinz Mauelshagen }
5591f965b19SHeinz Mauelshagen
region_in_sync(struct mirror_set * ms,region_t region,int may_block)5601f965b19SHeinz Mauelshagen static inline int region_in_sync(struct mirror_set *ms, region_t region,
5611f965b19SHeinz Mauelshagen int may_block)
5621f965b19SHeinz Mauelshagen {
5631f965b19SHeinz Mauelshagen int state = dm_rh_get_state(ms->rh, region, may_block);
5641f965b19SHeinz Mauelshagen return state == DM_RH_CLEAN || state == DM_RH_DIRTY;
5651da177e4SLinus Torvalds }
5661da177e4SLinus Torvalds
do_reads(struct mirror_set * ms,struct bio_list * reads)5671da177e4SLinus Torvalds static void do_reads(struct mirror_set *ms, struct bio_list *reads)
5681da177e4SLinus Torvalds {
5691da177e4SLinus Torvalds region_t region;
5701da177e4SLinus Torvalds struct bio *bio;
5711da177e4SLinus Torvalds struct mirror *m;
5721da177e4SLinus Torvalds
5731da177e4SLinus Torvalds while ((bio = bio_list_pop(reads))) {
5741f965b19SHeinz Mauelshagen region = dm_rh_bio_to_region(ms->rh, bio);
57506386bbfSJonathan Brassow m = get_default_mirror(ms);
5761da177e4SLinus Torvalds
5771da177e4SLinus Torvalds /*
5781da177e4SLinus Torvalds * We can only read balance if the region is in sync.
5791da177e4SLinus Torvalds */
5801f965b19SHeinz Mauelshagen if (likely(region_in_sync(ms, region, 1)))
5814f024f37SKent Overstreet m = choose_mirror(ms, bio->bi_iter.bi_sector);
58206386bbfSJonathan Brassow else if (m && atomic_read(&m->error_count))
58306386bbfSJonathan Brassow m = NULL;
5841da177e4SLinus Torvalds
58506386bbfSJonathan Brassow if (likely(m))
58606386bbfSJonathan Brassow read_async_bio(m, bio);
58706386bbfSJonathan Brassow else
5884246a0b6SChristoph Hellwig bio_io_error(bio);
5891da177e4SLinus Torvalds }
5901da177e4SLinus Torvalds }
5911da177e4SLinus Torvalds
592a4a82ce3SHeinz Mauelshagen /*
593a4a82ce3SHeinz Mauelshagen *---------------------------------------------------------------------
5941da177e4SLinus Torvalds * Writes.
5951da177e4SLinus Torvalds *
5961da177e4SLinus Torvalds * We do different things with the write io depending on the
5971da177e4SLinus Torvalds * state of the region that it's in:
5981da177e4SLinus Torvalds *
5991da177e4SLinus Torvalds * SYNC: increment pending, use kcopyd to write to *all* mirrors
6001da177e4SLinus Torvalds * RECOVERING: delay the io until recovery completes
6011da177e4SLinus Torvalds * NOSYNC: increment pending, just write to the default mirror
602a4a82ce3SHeinz Mauelshagen *---------------------------------------------------------------------
603a4a82ce3SHeinz Mauelshagen */
write_callback(unsigned long error,void * context)6041da177e4SLinus Torvalds static void write_callback(unsigned long error, void *context)
6051da177e4SLinus Torvalds {
60686a3238cSHeinz Mauelshagen unsigned int i;
60726cb62a2SYu Zhe struct bio *bio = context;
6081da177e4SLinus Torvalds struct mirror_set *ms;
60972f4b314SJonathan Brassow int should_wake = 0;
61072f4b314SJonathan Brassow unsigned long flags;
6111da177e4SLinus Torvalds
61206386bbfSJonathan Brassow ms = bio_get_m(bio)->ms;
61306386bbfSJonathan Brassow bio_set_m(bio, NULL);
6141da177e4SLinus Torvalds
6151da177e4SLinus Torvalds /*
6161da177e4SLinus Torvalds * NOTE: We don't decrement the pending count here,
6171da177e4SLinus Torvalds * instead it is done by the targets endio function.
6181da177e4SLinus Torvalds * This way we handle both writes to SYNC and NOSYNC
6191da177e4SLinus Torvalds * regions with the same code.
6201da177e4SLinus Torvalds */
62160f355eaSMikulas Patocka if (likely(!error)) {
6224246a0b6SChristoph Hellwig bio_endio(bio);
62360f355eaSMikulas Patocka return;
62460f355eaSMikulas Patocka }
6251da177e4SLinus Torvalds
626f2ed51acSMikulas Patocka /*
627f2ed51acSMikulas Patocka * If the bio is discard, return an error, but do not
628f2ed51acSMikulas Patocka * degrade the array.
629f2ed51acSMikulas Patocka */
630e6047149SMike Christie if (bio_op(bio) == REQ_OP_DISCARD) {
6314e4cbee9SChristoph Hellwig bio->bi_status = BLK_STS_NOTSUPP;
6324246a0b6SChristoph Hellwig bio_endio(bio);
633f2ed51acSMikulas Patocka return;
634f2ed51acSMikulas Patocka }
635f2ed51acSMikulas Patocka
6361da177e4SLinus Torvalds for (i = 0; i < ms->nr_mirrors; i++)
63772f4b314SJonathan Brassow if (test_bit(i, &error))
63872f4b314SJonathan Brassow fail_mirror(ms->mirror + i, DM_RAID1_WRITE_ERROR);
63972f4b314SJonathan Brassow
64072f4b314SJonathan Brassow /*
64172f4b314SJonathan Brassow * Need to raise event. Since raising
64272f4b314SJonathan Brassow * events can block, we need to do it in
64372f4b314SJonathan Brassow * the main thread.
64472f4b314SJonathan Brassow */
64572f4b314SJonathan Brassow spin_lock_irqsave(&ms->lock, flags);
64672f4b314SJonathan Brassow if (!ms->failures.head)
64772f4b314SJonathan Brassow should_wake = 1;
64872f4b314SJonathan Brassow bio_list_add(&ms->failures, bio);
64972f4b314SJonathan Brassow spin_unlock_irqrestore(&ms->lock, flags);
65072f4b314SJonathan Brassow if (should_wake)
6511f965b19SHeinz Mauelshagen wakeup_mirrord(ms);
6521da177e4SLinus Torvalds }
6531da177e4SLinus Torvalds
do_write(struct mirror_set * ms,struct bio * bio)6541da177e4SLinus Torvalds static void do_write(struct mirror_set *ms, struct bio *bio)
6551da177e4SLinus Torvalds {
6561da177e4SLinus Torvalds unsigned int i;
65765972a6fSKees Cook struct dm_io_region io[MAX_NR_MIRRORS], *dest = io;
6581da177e4SLinus Torvalds struct mirror *m;
659581075e4SBart Van Assche blk_opf_t op_flags = bio->bi_opf & (REQ_FUA | REQ_PREFLUSH);
66088be163aSMilan Broz struct dm_io_request io_req = {
661581075e4SBart Van Assche .bi_opf = REQ_OP_WRITE | op_flags,
662003b5c57SKent Overstreet .mem.type = DM_IO_BIO,
663003b5c57SKent Overstreet .mem.ptr.bio = bio,
66488be163aSMilan Broz .notify.fn = write_callback,
66588be163aSMilan Broz .notify.context = bio,
66688be163aSMilan Broz .client = ms->io_client,
66788be163aSMilan Broz };
6681da177e4SLinus Torvalds
669e6047149SMike Christie if (bio_op(bio) == REQ_OP_DISCARD) {
670581075e4SBart Van Assche io_req.bi_opf = REQ_OP_DISCARD | op_flags;
6715fc2ffeaSMike Snitzer io_req.mem.type = DM_IO_KMEM;
6725fc2ffeaSMike Snitzer io_req.mem.ptr.addr = NULL;
6735fc2ffeaSMike Snitzer }
6745fc2ffeaSMike Snitzer
67506386bbfSJonathan Brassow for (i = 0, m = ms->mirror; i < ms->nr_mirrors; i++, m++)
67606386bbfSJonathan Brassow map_region(dest++, m, bio);
6771da177e4SLinus Torvalds
67806386bbfSJonathan Brassow /*
67906386bbfSJonathan Brassow * Use default mirror because we only need it to retrieve the reference
68006386bbfSJonathan Brassow * to the mirror set in write_callback().
68106386bbfSJonathan Brassow */
68206386bbfSJonathan Brassow bio_set_m(bio, get_default_mirror(ms));
68388be163aSMilan Broz
684*5cfcea64SHongyu Jin BUG_ON(dm_io(&io_req, ms->nr_mirrors, io, NULL, IOPRIO_DEFAULT));
6851da177e4SLinus Torvalds }
6861da177e4SLinus Torvalds
do_writes(struct mirror_set * ms,struct bio_list * writes)6871da177e4SLinus Torvalds static void do_writes(struct mirror_set *ms, struct bio_list *writes)
6881da177e4SLinus Torvalds {
6891da177e4SLinus Torvalds int state;
6901da177e4SLinus Torvalds struct bio *bio;
6911da177e4SLinus Torvalds struct bio_list sync, nosync, recover, *this_list = NULL;
6927513c2a7SJonathan Brassow struct bio_list requeue;
6937513c2a7SJonathan Brassow struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh);
6947513c2a7SJonathan Brassow region_t region;
6951da177e4SLinus Torvalds
6961da177e4SLinus Torvalds if (!writes->head)
6971da177e4SLinus Torvalds return;
6981da177e4SLinus Torvalds
6991da177e4SLinus Torvalds /*
7001da177e4SLinus Torvalds * Classify each write.
7011da177e4SLinus Torvalds */
7021da177e4SLinus Torvalds bio_list_init(&sync);
7031da177e4SLinus Torvalds bio_list_init(&nosync);
7041da177e4SLinus Torvalds bio_list_init(&recover);
7057513c2a7SJonathan Brassow bio_list_init(&requeue);
7061da177e4SLinus Torvalds
7071da177e4SLinus Torvalds while ((bio = bio_list_pop(writes))) {
7081eff9d32SJens Axboe if ((bio->bi_opf & REQ_PREFLUSH) ||
709e6047149SMike Christie (bio_op(bio) == REQ_OP_DISCARD)) {
7104184153fSMikulas Patocka bio_list_add(&sync, bio);
7114184153fSMikulas Patocka continue;
7124184153fSMikulas Patocka }
7134184153fSMikulas Patocka
7147513c2a7SJonathan Brassow region = dm_rh_bio_to_region(ms->rh, bio);
7157513c2a7SJonathan Brassow
7167513c2a7SJonathan Brassow if (log->type->is_remote_recovering &&
7177513c2a7SJonathan Brassow log->type->is_remote_recovering(log, region)) {
7187513c2a7SJonathan Brassow bio_list_add(&requeue, bio);
7197513c2a7SJonathan Brassow continue;
7207513c2a7SJonathan Brassow }
7217513c2a7SJonathan Brassow
7227513c2a7SJonathan Brassow state = dm_rh_get_state(ms->rh, region, 1);
7231da177e4SLinus Torvalds switch (state) {
7241f965b19SHeinz Mauelshagen case DM_RH_CLEAN:
7251f965b19SHeinz Mauelshagen case DM_RH_DIRTY:
7261da177e4SLinus Torvalds this_list = &sync;
7271da177e4SLinus Torvalds break;
7281da177e4SLinus Torvalds
7291f965b19SHeinz Mauelshagen case DM_RH_NOSYNC:
7301da177e4SLinus Torvalds this_list = &nosync;
7311da177e4SLinus Torvalds break;
7321da177e4SLinus Torvalds
7331f965b19SHeinz Mauelshagen case DM_RH_RECOVERING:
7341da177e4SLinus Torvalds this_list = &recover;
7351da177e4SLinus Torvalds break;
7361da177e4SLinus Torvalds }
7371da177e4SLinus Torvalds
7381da177e4SLinus Torvalds bio_list_add(this_list, bio);
7391da177e4SLinus Torvalds }
7401da177e4SLinus Torvalds
7411da177e4SLinus Torvalds /*
7427513c2a7SJonathan Brassow * Add bios that are delayed due to remote recovery
7437513c2a7SJonathan Brassow * back on to the write queue
7447513c2a7SJonathan Brassow */
7457513c2a7SJonathan Brassow if (unlikely(requeue.head)) {
7467513c2a7SJonathan Brassow spin_lock_irq(&ms->lock);
7477513c2a7SJonathan Brassow bio_list_merge(&ms->writes, &requeue);
7487513c2a7SJonathan Brassow spin_unlock_irq(&ms->lock);
74969885683SMikulas Patocka delayed_wake(ms);
7507513c2a7SJonathan Brassow }
7517513c2a7SJonathan Brassow
7527513c2a7SJonathan Brassow /*
7531da177e4SLinus Torvalds * Increment the pending counts for any regions that will
7541da177e4SLinus Torvalds * be written to (writes to recover regions are going to
7551da177e4SLinus Torvalds * be delayed).
7561da177e4SLinus Torvalds */
7571f965b19SHeinz Mauelshagen dm_rh_inc_pending(ms->rh, &sync);
7581f965b19SHeinz Mauelshagen dm_rh_inc_pending(ms->rh, &nosync);
759d2b69864SJonathan Brassow
760d2b69864SJonathan Brassow /*
761d2b69864SJonathan Brassow * If the flush fails on a previous call and succeeds here,
762d2b69864SJonathan Brassow * we must not reset the log_failure variable. We need
763d2b69864SJonathan Brassow * userspace interaction to do that.
764d2b69864SJonathan Brassow */
765d2b69864SJonathan Brassow ms->log_failure = dm_rh_flush(ms->rh) ? 1 : ms->log_failure;
7661da177e4SLinus Torvalds
7671da177e4SLinus Torvalds /*
7681da177e4SLinus Torvalds * Dispatch io.
7691da177e4SLinus Torvalds */
7705528d17dSMikulas Patocka if (unlikely(ms->log_failure) && errors_handled(ms)) {
771b80aa7a0SJonathan Brassow spin_lock_irq(&ms->lock);
772b80aa7a0SJonathan Brassow bio_list_merge(&ms->failures, &sync);
773b80aa7a0SJonathan Brassow spin_unlock_irq(&ms->lock);
7741f965b19SHeinz Mauelshagen wakeup_mirrord(ms);
775b80aa7a0SJonathan Brassow } else
7761da177e4SLinus Torvalds while ((bio = bio_list_pop(&sync)))
7771da177e4SLinus Torvalds do_write(ms, bio);
7781da177e4SLinus Torvalds
7791da177e4SLinus Torvalds while ((bio = bio_list_pop(&recover)))
7801f965b19SHeinz Mauelshagen dm_rh_delay(ms->rh, bio);
7811da177e4SLinus Torvalds
7821da177e4SLinus Torvalds while ((bio = bio_list_pop(&nosync))) {
783ed63287dSLidong Zhong if (unlikely(ms->leg_failure) && errors_handled(ms) && !keep_log(ms)) {
784ede5ea0bSMikulas Patocka spin_lock_irq(&ms->lock);
785ede5ea0bSMikulas Patocka bio_list_add(&ms->failures, bio);
786ede5ea0bSMikulas Patocka spin_unlock_irq(&ms->lock);
787ede5ea0bSMikulas Patocka wakeup_mirrord(ms);
788ede5ea0bSMikulas Patocka } else {
78906386bbfSJonathan Brassow map_bio(get_default_mirror(ms), bio);
790ed00aabdSChristoph Hellwig submit_bio_noacct(bio);
7911da177e4SLinus Torvalds }
7921da177e4SLinus Torvalds }
793929be8fcSMikulas Patocka }
7941da177e4SLinus Torvalds
do_failures(struct mirror_set * ms,struct bio_list * failures)79572f4b314SJonathan Brassow static void do_failures(struct mirror_set *ms, struct bio_list *failures)
79672f4b314SJonathan Brassow {
79772f4b314SJonathan Brassow struct bio *bio;
79872f4b314SJonathan Brassow
7990f398a84SMikulas Patocka if (likely(!failures->head))
80072f4b314SJonathan Brassow return;
80172f4b314SJonathan Brassow
802b80aa7a0SJonathan Brassow /*
803b80aa7a0SJonathan Brassow * If the log has failed, unattempted writes are being
8040f398a84SMikulas Patocka * put on the holds list. We can't issue those writes
805b80aa7a0SJonathan Brassow * until a log has been marked, so we must store them.
806b80aa7a0SJonathan Brassow *
807b80aa7a0SJonathan Brassow * If a 'noflush' suspend is in progress, we can requeue
808b80aa7a0SJonathan Brassow * the I/O's to the core. This give userspace a chance
809b80aa7a0SJonathan Brassow * to reconfigure the mirror, at which point the core
810b80aa7a0SJonathan Brassow * will reissue the writes. If the 'noflush' flag is
811b80aa7a0SJonathan Brassow * not set, we have no choice but to return errors.
812b80aa7a0SJonathan Brassow *
813b80aa7a0SJonathan Brassow * Some writes on the failures list may have been
814b80aa7a0SJonathan Brassow * submitted before the log failure and represent a
815b80aa7a0SJonathan Brassow * failure to write to one of the devices. It is ok
816b80aa7a0SJonathan Brassow * for us to treat them the same and requeue them
817b80aa7a0SJonathan Brassow * as well.
818b80aa7a0SJonathan Brassow */
8190f398a84SMikulas Patocka while ((bio = bio_list_pop(failures))) {
82060f355eaSMikulas Patocka if (!ms->log_failure) {
8210f398a84SMikulas Patocka ms->in_sync = 0;
822c58098beSMikulas Patocka dm_rh_mark_nosync(ms->rh, bio);
823b80aa7a0SJonathan Brassow }
82460f355eaSMikulas Patocka
82560f355eaSMikulas Patocka /*
82660f355eaSMikulas Patocka * If all the legs are dead, fail the I/O.
827ed63287dSLidong Zhong * If the device has failed and keep_log is enabled,
828ed63287dSLidong Zhong * fail the I/O.
829ed63287dSLidong Zhong *
830ed63287dSLidong Zhong * If we have been told to handle errors, and keep_log
831ed63287dSLidong Zhong * isn't enabled, hold the bio and wait for userspace to
832ed63287dSLidong Zhong * deal with the problem.
833ed63287dSLidong Zhong *
83460f355eaSMikulas Patocka * Otherwise pretend that the I/O succeeded. (This would
83560f355eaSMikulas Patocka * be wrong if the failed leg returned after reboot and
83660f355eaSMikulas Patocka * got replicated back to the good legs.)
83760f355eaSMikulas Patocka */
838ed63287dSLidong Zhong if (unlikely(!get_valid_mirror(ms) || (keep_log(ms) && ms->log_failure)))
8394246a0b6SChristoph Hellwig bio_io_error(bio);
840ed63287dSLidong Zhong else if (errors_handled(ms) && !keep_log(ms))
84160f355eaSMikulas Patocka hold_bio(ms, bio);
84260f355eaSMikulas Patocka else
8434246a0b6SChristoph Hellwig bio_endio(bio);
844b80aa7a0SJonathan Brassow }
84572f4b314SJonathan Brassow }
84672f4b314SJonathan Brassow
trigger_event(struct work_struct * work)84772f4b314SJonathan Brassow static void trigger_event(struct work_struct *work)
84872f4b314SJonathan Brassow {
84972f4b314SJonathan Brassow struct mirror_set *ms =
85072f4b314SJonathan Brassow container_of(work, struct mirror_set, trigger_event);
85172f4b314SJonathan Brassow
85272f4b314SJonathan Brassow dm_table_event(ms->ti->table);
85372f4b314SJonathan Brassow }
85472f4b314SJonathan Brassow
855a4a82ce3SHeinz Mauelshagen /*
856a4a82ce3SHeinz Mauelshagen *---------------------------------------------------------------
8571da177e4SLinus Torvalds * kmirrord
858a4a82ce3SHeinz Mauelshagen *---------------------------------------------------------------
859a4a82ce3SHeinz Mauelshagen */
do_mirror(struct work_struct * work)860a2aebe03SMikulas Patocka static void do_mirror(struct work_struct *work)
8611da177e4SLinus Torvalds {
8626ad36fe2SHolger Smolinski struct mirror_set *ms = container_of(work, struct mirror_set,
8636ad36fe2SHolger Smolinski kmirrord_work);
86472f4b314SJonathan Brassow struct bio_list reads, writes, failures;
86572f4b314SJonathan Brassow unsigned long flags;
8661da177e4SLinus Torvalds
86772f4b314SJonathan Brassow spin_lock_irqsave(&ms->lock, flags);
8681da177e4SLinus Torvalds reads = ms->reads;
8691da177e4SLinus Torvalds writes = ms->writes;
87072f4b314SJonathan Brassow failures = ms->failures;
8711da177e4SLinus Torvalds bio_list_init(&ms->reads);
8721da177e4SLinus Torvalds bio_list_init(&ms->writes);
87372f4b314SJonathan Brassow bio_list_init(&ms->failures);
87472f4b314SJonathan Brassow spin_unlock_irqrestore(&ms->lock, flags);
8751da177e4SLinus Torvalds
8761f965b19SHeinz Mauelshagen dm_rh_update_states(ms->rh, errors_handled(ms));
8771da177e4SLinus Torvalds do_recovery(ms);
8781da177e4SLinus Torvalds do_reads(ms, &reads);
8791da177e4SLinus Torvalds do_writes(ms, &writes);
88072f4b314SJonathan Brassow do_failures(ms, &failures);
88172f4b314SJonathan Brassow }
88272f4b314SJonathan Brassow
883a4a82ce3SHeinz Mauelshagen /*
884a4a82ce3SHeinz Mauelshagen *---------------------------------------------------------------
8851da177e4SLinus Torvalds * Target functions
886a4a82ce3SHeinz Mauelshagen *---------------------------------------------------------------
887a4a82ce3SHeinz Mauelshagen */
alloc_context(unsigned int nr_mirrors,uint32_t region_size,struct dm_target * ti,struct dm_dirty_log * dl)8881da177e4SLinus Torvalds static struct mirror_set *alloc_context(unsigned int nr_mirrors,
8891da177e4SLinus Torvalds uint32_t region_size,
8901da177e4SLinus Torvalds struct dm_target *ti,
891416cd17bSHeinz Mauelshagen struct dm_dirty_log *dl)
8921da177e4SLinus Torvalds {
893bcd67654SGustavo A. R. Silva struct mirror_set *ms =
894bcd67654SGustavo A. R. Silva kzalloc(struct_size(ms, mirror, nr_mirrors), GFP_KERNEL);
8951da177e4SLinus Torvalds
8961da177e4SLinus Torvalds if (!ms) {
89772d94861SAlasdair G Kergon ti->error = "Cannot allocate mirror context";
8981da177e4SLinus Torvalds return NULL;
8991da177e4SLinus Torvalds }
9001da177e4SLinus Torvalds
9011da177e4SLinus Torvalds spin_lock_init(&ms->lock);
9025339fc2dSMikulas Patocka bio_list_init(&ms->reads);
9035339fc2dSMikulas Patocka bio_list_init(&ms->writes);
9045339fc2dSMikulas Patocka bio_list_init(&ms->failures);
9055339fc2dSMikulas Patocka bio_list_init(&ms->holds);
9061da177e4SLinus Torvalds
9071da177e4SLinus Torvalds ms->ti = ti;
9081da177e4SLinus Torvalds ms->nr_mirrors = nr_mirrors;
9091da177e4SLinus Torvalds ms->nr_regions = dm_sector_div_up(ti->len, region_size);
9101da177e4SLinus Torvalds ms->in_sync = 0;
911b80aa7a0SJonathan Brassow ms->log_failure = 0;
912929be8fcSMikulas Patocka ms->leg_failure = 0;
913b80aa7a0SJonathan Brassow atomic_set(&ms->suspend, 0);
91472f4b314SJonathan Brassow atomic_set(&ms->default_mirror, DEFAULT_MIRROR);
9151da177e4SLinus Torvalds
916bda8efecSMikulas Patocka ms->io_client = dm_io_client_create();
91788be163aSMilan Broz if (IS_ERR(ms->io_client)) {
91888be163aSMilan Broz ti->error = "Error creating dm_io client";
91988be163aSMilan Broz kfree(ms);
92088be163aSMilan Broz return NULL;
92188be163aSMilan Broz }
92288be163aSMilan Broz
9231f965b19SHeinz Mauelshagen ms->rh = dm_region_hash_create(ms, dispatch_bios, wakeup_mirrord,
9241f965b19SHeinz Mauelshagen wakeup_all_recovery_waiters,
9251f965b19SHeinz Mauelshagen ms->ti->begin, MAX_RECOVERY,
9261f965b19SHeinz Mauelshagen dl, region_size, ms->nr_regions);
9271f965b19SHeinz Mauelshagen if (IS_ERR(ms->rh)) {
92872d94861SAlasdair G Kergon ti->error = "Error creating dirty region hash";
929a72cf737SDmitry Monakhov dm_io_client_destroy(ms->io_client);
9301da177e4SLinus Torvalds kfree(ms);
9311da177e4SLinus Torvalds return NULL;
9321da177e4SLinus Torvalds }
9331da177e4SLinus Torvalds
9341da177e4SLinus Torvalds return ms;
9351da177e4SLinus Torvalds }
9361da177e4SLinus Torvalds
free_context(struct mirror_set * ms,struct dm_target * ti,unsigned int m)9371da177e4SLinus Torvalds static void free_context(struct mirror_set *ms, struct dm_target *ti,
9381da177e4SLinus Torvalds unsigned int m)
9391da177e4SLinus Torvalds {
9401da177e4SLinus Torvalds while (m--)
9411da177e4SLinus Torvalds dm_put_device(ti, ms->mirror[m].dev);
9421da177e4SLinus Torvalds
94388be163aSMilan Broz dm_io_client_destroy(ms->io_client);
9441f965b19SHeinz Mauelshagen dm_region_hash_destroy(ms->rh);
9451da177e4SLinus Torvalds kfree(ms);
9461da177e4SLinus Torvalds }
9471da177e4SLinus Torvalds
get_mirror(struct mirror_set * ms,struct dm_target * ti,unsigned int mirror,char ** argv)9481da177e4SLinus Torvalds static int get_mirror(struct mirror_set *ms, struct dm_target *ti,
9491da177e4SLinus Torvalds unsigned int mirror, char **argv)
9501da177e4SLinus Torvalds {
9514ee218cdSAndrew Morton unsigned long long offset;
95231998ef1SMikulas Patocka char dummy;
953e80d1c80SVivek Goyal int ret;
9541da177e4SLinus Torvalds
955ef87bfc2SMilan Broz if (sscanf(argv[1], "%llu%c", &offset, &dummy) != 1 ||
956ef87bfc2SMilan Broz offset != (sector_t)offset) {
95772d94861SAlasdair G Kergon ti->error = "Invalid offset";
9581da177e4SLinus Torvalds return -EINVAL;
9591da177e4SLinus Torvalds }
9601da177e4SLinus Torvalds
961e80d1c80SVivek Goyal ret = dm_get_device(ti, argv[0], dm_table_get_mode(ti->table),
962e80d1c80SVivek Goyal &ms->mirror[mirror].dev);
963e80d1c80SVivek Goyal if (ret) {
96472d94861SAlasdair G Kergon ti->error = "Device lookup failure";
965e80d1c80SVivek Goyal return ret;
9661da177e4SLinus Torvalds }
9671da177e4SLinus Torvalds
968aa5617c5SJonathan Brassow ms->mirror[mirror].ms = ms;
96972f4b314SJonathan Brassow atomic_set(&(ms->mirror[mirror].error_count), 0);
97072f4b314SJonathan Brassow ms->mirror[mirror].error_type = 0;
9711da177e4SLinus Torvalds ms->mirror[mirror].offset = offset;
9721da177e4SLinus Torvalds
9731da177e4SLinus Torvalds return 0;
9741da177e4SLinus Torvalds }
9751da177e4SLinus Torvalds
9761da177e4SLinus Torvalds /*
9771da177e4SLinus Torvalds * Create dirty log: log_type #log_params <log_params>
9781da177e4SLinus Torvalds */
create_dirty_log(struct dm_target * ti,unsigned int argc,char ** argv,unsigned int * args_used)979416cd17bSHeinz Mauelshagen static struct dm_dirty_log *create_dirty_log(struct dm_target *ti,
98086a3238cSHeinz Mauelshagen unsigned int argc, char **argv,
98186a3238cSHeinz Mauelshagen unsigned int *args_used)
9821da177e4SLinus Torvalds {
98386a3238cSHeinz Mauelshagen unsigned int param_count;
984416cd17bSHeinz Mauelshagen struct dm_dirty_log *dl;
98531998ef1SMikulas Patocka char dummy;
9861da177e4SLinus Torvalds
9871da177e4SLinus Torvalds if (argc < 2) {
98872d94861SAlasdair G Kergon ti->error = "Insufficient mirror log arguments";
9891da177e4SLinus Torvalds return NULL;
9901da177e4SLinus Torvalds }
9911da177e4SLinus Torvalds
99231998ef1SMikulas Patocka if (sscanf(argv[1], "%u%c", ¶m_count, &dummy) != 1) {
99372d94861SAlasdair G Kergon ti->error = "Invalid mirror log argument count";
9941da177e4SLinus Torvalds return NULL;
9951da177e4SLinus Torvalds }
9961da177e4SLinus Torvalds
9971da177e4SLinus Torvalds *args_used = 2 + param_count;
9981da177e4SLinus Torvalds
9991da177e4SLinus Torvalds if (argc < *args_used) {
100072d94861SAlasdair G Kergon ti->error = "Insufficient mirror log arguments";
10011da177e4SLinus Torvalds return NULL;
10021da177e4SLinus Torvalds }
10031da177e4SLinus Torvalds
1004c0da3748SMikulas Patocka dl = dm_dirty_log_create(argv[0], ti, mirror_flush, param_count,
1005c0da3748SMikulas Patocka argv + 2);
10061da177e4SLinus Torvalds if (!dl) {
100772d94861SAlasdair G Kergon ti->error = "Error creating mirror dirty log";
10081da177e4SLinus Torvalds return NULL;
10091da177e4SLinus Torvalds }
10101da177e4SLinus Torvalds
10111da177e4SLinus Torvalds return dl;
10121da177e4SLinus Torvalds }
10131da177e4SLinus Torvalds
parse_features(struct mirror_set * ms,unsigned int argc,char ** argv,unsigned int * args_used)101486a3238cSHeinz Mauelshagen static int parse_features(struct mirror_set *ms, unsigned int argc, char **argv,
101586a3238cSHeinz Mauelshagen unsigned int *args_used)
1016a8e6afa2SJonathan E Brassow {
101786a3238cSHeinz Mauelshagen unsigned int num_features;
1018a8e6afa2SJonathan E Brassow struct dm_target *ti = ms->ti;
101931998ef1SMikulas Patocka char dummy;
1020ed63287dSLidong Zhong int i;
1021a8e6afa2SJonathan E Brassow
1022a8e6afa2SJonathan E Brassow *args_used = 0;
1023a8e6afa2SJonathan E Brassow
1024a8e6afa2SJonathan E Brassow if (!argc)
1025a8e6afa2SJonathan E Brassow return 0;
1026a8e6afa2SJonathan E Brassow
102731998ef1SMikulas Patocka if (sscanf(argv[0], "%u%c", &num_features, &dummy) != 1) {
1028a8e6afa2SJonathan E Brassow ti->error = "Invalid number of features";
1029a8e6afa2SJonathan E Brassow return -EINVAL;
1030a8e6afa2SJonathan E Brassow }
1031a8e6afa2SJonathan E Brassow
1032a8e6afa2SJonathan E Brassow argc--;
1033a8e6afa2SJonathan E Brassow argv++;
1034a8e6afa2SJonathan E Brassow (*args_used)++;
1035a8e6afa2SJonathan E Brassow
1036a8e6afa2SJonathan E Brassow if (num_features > argc) {
1037a8e6afa2SJonathan E Brassow ti->error = "Not enough arguments to support feature count";
1038a8e6afa2SJonathan E Brassow return -EINVAL;
1039a8e6afa2SJonathan E Brassow }
1040a8e6afa2SJonathan E Brassow
1041ed63287dSLidong Zhong for (i = 0; i < num_features; i++) {
1042a8e6afa2SJonathan E Brassow if (!strcmp("handle_errors", argv[0]))
1043a8e6afa2SJonathan E Brassow ms->features |= DM_RAID1_HANDLE_ERRORS;
1044ed63287dSLidong Zhong else if (!strcmp("keep_log", argv[0]))
1045ed63287dSLidong Zhong ms->features |= DM_RAID1_KEEP_LOG;
1046a8e6afa2SJonathan E Brassow else {
1047a8e6afa2SJonathan E Brassow ti->error = "Unrecognised feature requested";
1048a8e6afa2SJonathan E Brassow return -EINVAL;
1049a8e6afa2SJonathan E Brassow }
1050a8e6afa2SJonathan E Brassow
1051ed63287dSLidong Zhong argc--;
1052ed63287dSLidong Zhong argv++;
1053a8e6afa2SJonathan E Brassow (*args_used)++;
1054ed63287dSLidong Zhong }
1055ed63287dSLidong Zhong if (!errors_handled(ms) && keep_log(ms)) {
1056ed63287dSLidong Zhong ti->error = "keep_log feature requires the handle_errors feature";
1057ed63287dSLidong Zhong return -EINVAL;
1058ed63287dSLidong Zhong }
1059a8e6afa2SJonathan E Brassow
1060a8e6afa2SJonathan E Brassow return 0;
1061a8e6afa2SJonathan E Brassow }
1062a8e6afa2SJonathan E Brassow
10631da177e4SLinus Torvalds /*
10641da177e4SLinus Torvalds * Construct a mirror mapping:
10651da177e4SLinus Torvalds *
10661da177e4SLinus Torvalds * log_type #log_params <log_params>
10671da177e4SLinus Torvalds * #mirrors [mirror_path offset]{2,}
1068a8e6afa2SJonathan E Brassow * [#features <features>]
10691da177e4SLinus Torvalds *
10701da177e4SLinus Torvalds * log_type is "core" or "disk"
10711da177e4SLinus Torvalds * #log_params is between 1 and 3
1072a8e6afa2SJonathan E Brassow *
1073ed63287dSLidong Zhong * If present, supported features are "handle_errors" and "keep_log".
10741da177e4SLinus Torvalds */
mirror_ctr(struct dm_target * ti,unsigned int argc,char ** argv)10751da177e4SLinus Torvalds static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv)
10761da177e4SLinus Torvalds {
10771da177e4SLinus Torvalds int r;
10781da177e4SLinus Torvalds unsigned int nr_mirrors, m, args_used;
10791da177e4SLinus Torvalds struct mirror_set *ms;
1080416cd17bSHeinz Mauelshagen struct dm_dirty_log *dl;
108131998ef1SMikulas Patocka char dummy;
10821da177e4SLinus Torvalds
10831da177e4SLinus Torvalds dl = create_dirty_log(ti, argc, argv, &args_used);
10841da177e4SLinus Torvalds if (!dl)
10851da177e4SLinus Torvalds return -EINVAL;
10861da177e4SLinus Torvalds
10871da177e4SLinus Torvalds argv += args_used;
10881da177e4SLinus Torvalds argc -= args_used;
10891da177e4SLinus Torvalds
109031998ef1SMikulas Patocka if (!argc || sscanf(argv[0], "%u%c", &nr_mirrors, &dummy) != 1 ||
109165972a6fSKees Cook nr_mirrors < 2 || nr_mirrors > MAX_NR_MIRRORS) {
109272d94861SAlasdair G Kergon ti->error = "Invalid number of mirrors";
1093416cd17bSHeinz Mauelshagen dm_dirty_log_destroy(dl);
10941da177e4SLinus Torvalds return -EINVAL;
10951da177e4SLinus Torvalds }
10961da177e4SLinus Torvalds
10971da177e4SLinus Torvalds argv++, argc--;
10981da177e4SLinus Torvalds
1099a8e6afa2SJonathan E Brassow if (argc < nr_mirrors * 2) {
1100a8e6afa2SJonathan E Brassow ti->error = "Too few mirror arguments";
1101416cd17bSHeinz Mauelshagen dm_dirty_log_destroy(dl);
11021da177e4SLinus Torvalds return -EINVAL;
11031da177e4SLinus Torvalds }
11041da177e4SLinus Torvalds
11051da177e4SLinus Torvalds ms = alloc_context(nr_mirrors, dl->type->get_region_size(dl), ti, dl);
11061da177e4SLinus Torvalds if (!ms) {
1107416cd17bSHeinz Mauelshagen dm_dirty_log_destroy(dl);
11081da177e4SLinus Torvalds return -ENOMEM;
11091da177e4SLinus Torvalds }
11101da177e4SLinus Torvalds
11111da177e4SLinus Torvalds /* Get the mirror parameter sets */
11121da177e4SLinus Torvalds for (m = 0; m < nr_mirrors; m++) {
11131da177e4SLinus Torvalds r = get_mirror(ms, ti, m, argv);
11141da177e4SLinus Torvalds if (r) {
11151da177e4SLinus Torvalds free_context(ms, ti, m);
11161da177e4SLinus Torvalds return r;
11171da177e4SLinus Torvalds }
11181da177e4SLinus Torvalds argv += 2;
11191da177e4SLinus Torvalds argc -= 2;
11201da177e4SLinus Torvalds }
11211da177e4SLinus Torvalds
11221da177e4SLinus Torvalds ti->private = ms;
1123542f9038SMike Snitzer
1124542f9038SMike Snitzer r = dm_set_target_max_io_len(ti, dm_rh_get_region_size(ms->rh));
1125542f9038SMike Snitzer if (r)
1126542f9038SMike Snitzer goto err_free_context;
1127542f9038SMike Snitzer
112855a62eefSAlasdair G Kergon ti->num_flush_bios = 1;
112955a62eefSAlasdair G Kergon ti->num_discard_bios = 1;
113030187e1dSMike Snitzer ti->per_io_data_size = sizeof(struct dm_raid1_bio_record);
11311da177e4SLinus Torvalds
1132670368a8STejun Heo ms->kmirrord_wq = alloc_workqueue("kmirrord", WQ_MEM_RECLAIM, 0);
11336ad36fe2SHolger Smolinski if (!ms->kmirrord_wq) {
11346ad36fe2SHolger Smolinski DMERR("couldn't start kmirrord");
1135a72cf737SDmitry Monakhov r = -ENOMEM;
1136a72cf737SDmitry Monakhov goto err_free_context;
11376ad36fe2SHolger Smolinski }
11386ad36fe2SHolger Smolinski INIT_WORK(&ms->kmirrord_work, do_mirror);
11398376d3c1SKees Cook timer_setup(&ms->timer, delayed_wake_fn, 0);
1140a2aebe03SMikulas Patocka ms->timer_pending = 0;
114172f4b314SJonathan Brassow INIT_WORK(&ms->trigger_event, trigger_event);
11426ad36fe2SHolger Smolinski
1143a8e6afa2SJonathan E Brassow r = parse_features(ms, argc, argv, &args_used);
1144a72cf737SDmitry Monakhov if (r)
1145a72cf737SDmitry Monakhov goto err_destroy_wq;
1146a8e6afa2SJonathan E Brassow
1147a8e6afa2SJonathan E Brassow argv += args_used;
1148a8e6afa2SJonathan E Brassow argc -= args_used;
1149a8e6afa2SJonathan E Brassow
1150f44db678SJonathan Brassow /*
1151f44db678SJonathan Brassow * Any read-balancing addition depends on the
1152f44db678SJonathan Brassow * DM_RAID1_HANDLE_ERRORS flag being present.
1153f44db678SJonathan Brassow * This is because the decision to balance depends
1154f44db678SJonathan Brassow * on the sync state of a region. If the above
1155f44db678SJonathan Brassow * flag is not present, we ignore errors; and
1156f44db678SJonathan Brassow * the sync state may be inaccurate.
1157f44db678SJonathan Brassow */
1158f44db678SJonathan Brassow
1159a8e6afa2SJonathan E Brassow if (argc) {
1160a8e6afa2SJonathan E Brassow ti->error = "Too many mirror arguments";
1161a72cf737SDmitry Monakhov r = -EINVAL;
1162a72cf737SDmitry Monakhov goto err_destroy_wq;
1163a8e6afa2SJonathan E Brassow }
1164a8e6afa2SJonathan E Brassow
1165df5d2e90SMikulas Patocka ms->kcopyd_client = dm_kcopyd_client_create(&dm_kcopyd_throttle);
1166fa34ce73SMikulas Patocka if (IS_ERR(ms->kcopyd_client)) {
1167fa34ce73SMikulas Patocka r = PTR_ERR(ms->kcopyd_client);
1168a72cf737SDmitry Monakhov goto err_destroy_wq;
1169fa34ce73SMikulas Patocka }
11701da177e4SLinus Torvalds
11711f965b19SHeinz Mauelshagen wakeup_mirrord(ms);
11721da177e4SLinus Torvalds return 0;
1173a72cf737SDmitry Monakhov
1174a72cf737SDmitry Monakhov err_destroy_wq:
1175a72cf737SDmitry Monakhov destroy_workqueue(ms->kmirrord_wq);
1176a72cf737SDmitry Monakhov err_free_context:
1177a72cf737SDmitry Monakhov free_context(ms, ti, ms->nr_mirrors);
1178a72cf737SDmitry Monakhov return r;
11791da177e4SLinus Torvalds }
11801da177e4SLinus Torvalds
mirror_dtr(struct dm_target * ti)11811da177e4SLinus Torvalds static void mirror_dtr(struct dm_target *ti)
11821da177e4SLinus Torvalds {
118326cb62a2SYu Zhe struct mirror_set *ms = ti->private;
11841da177e4SLinus Torvalds
1185a2aebe03SMikulas Patocka del_timer_sync(&ms->timer);
11866ad36fe2SHolger Smolinski flush_workqueue(ms->kmirrord_wq);
118743829731STejun Heo flush_work(&ms->trigger_event);
1188eb69aca5SHeinz Mauelshagen dm_kcopyd_client_destroy(ms->kcopyd_client);
11896ad36fe2SHolger Smolinski destroy_workqueue(ms->kmirrord_wq);
11901da177e4SLinus Torvalds free_context(ms, ti, ms->nr_mirrors);
11911da177e4SLinus Torvalds }
11921da177e4SLinus Torvalds
11931da177e4SLinus Torvalds /*
11941da177e4SLinus Torvalds * Mirror mapping function
11951da177e4SLinus Torvalds */
mirror_map(struct dm_target * ti,struct bio * bio)11967de3ee57SMikulas Patocka static int mirror_map(struct dm_target *ti, struct bio *bio)
11971da177e4SLinus Torvalds {
119870246286SChristoph Hellwig int r, rw = bio_data_dir(bio);
11991da177e4SLinus Torvalds struct mirror *m;
12001da177e4SLinus Torvalds struct mirror_set *ms = ti->private;
12011f965b19SHeinz Mauelshagen struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh);
12020045d61bSMikulas Patocka struct dm_raid1_bio_record *bio_record =
12030045d61bSMikulas Patocka dm_per_bio_data(bio, sizeof(struct dm_raid1_bio_record));
12040045d61bSMikulas Patocka
1205309dca30SChristoph Hellwig bio_record->details.bi_bdev = NULL;
1206cd15fb64SMike Snitzer
12071da177e4SLinus Torvalds if (rw == WRITE) {
120806386bbfSJonathan Brassow /* Save region for mirror_end_io() handler */
12090045d61bSMikulas Patocka bio_record->write_region = dm_rh_bio_to_region(ms->rh, bio);
12101da177e4SLinus Torvalds queue_bio(ms, bio, rw);
1211d2a7ad29SKiyoshi Ueda return DM_MAPIO_SUBMITTED;
12121da177e4SLinus Torvalds }
12131da177e4SLinus Torvalds
12141f965b19SHeinz Mauelshagen r = log->type->in_sync(log, dm_rh_bio_to_region(ms->rh, bio), 0);
12151da177e4SLinus Torvalds if (r < 0 && r != -EWOULDBLOCK)
1216846785e6SChristoph Hellwig return DM_MAPIO_KILL;
12171da177e4SLinus Torvalds
12181da177e4SLinus Torvalds /*
121906386bbfSJonathan Brassow * If region is not in-sync queue the bio.
12201da177e4SLinus Torvalds */
122106386bbfSJonathan Brassow if (!r || (r == -EWOULDBLOCK)) {
12221eff9d32SJens Axboe if (bio->bi_opf & REQ_RAHEAD)
1223846785e6SChristoph Hellwig return DM_MAPIO_KILL;
12241da177e4SLinus Torvalds
12251da177e4SLinus Torvalds queue_bio(ms, bio, rw);
1226d2a7ad29SKiyoshi Ueda return DM_MAPIO_SUBMITTED;
12271da177e4SLinus Torvalds }
12281da177e4SLinus Torvalds
122906386bbfSJonathan Brassow /*
123006386bbfSJonathan Brassow * The region is in-sync and we can perform reads directly.
123106386bbfSJonathan Brassow * Store enough information so we can retry if it fails.
123206386bbfSJonathan Brassow */
12334f024f37SKent Overstreet m = choose_mirror(ms, bio->bi_iter.bi_sector);
123406386bbfSJonathan Brassow if (unlikely(!m))
1235846785e6SChristoph Hellwig return DM_MAPIO_KILL;
12361da177e4SLinus Torvalds
123789c7cd89SMikulas Patocka dm_bio_record(&bio_record->details, bio);
123889c7cd89SMikulas Patocka bio_record->m = m;
123906386bbfSJonathan Brassow
124006386bbfSJonathan Brassow map_bio(m, bio);
124106386bbfSJonathan Brassow
1242d2a7ad29SKiyoshi Ueda return DM_MAPIO_REMAPPED;
12431da177e4SLinus Torvalds }
12441da177e4SLinus Torvalds
mirror_end_io(struct dm_target * ti,struct bio * bio,blk_status_t * error)12454e4cbee9SChristoph Hellwig static int mirror_end_io(struct dm_target *ti, struct bio *bio,
12464e4cbee9SChristoph Hellwig blk_status_t *error)
12471da177e4SLinus Torvalds {
124870246286SChristoph Hellwig int rw = bio_data_dir(bio);
124926cb62a2SYu Zhe struct mirror_set *ms = ti->private;
125006386bbfSJonathan Brassow struct mirror *m = NULL;
125106386bbfSJonathan Brassow struct dm_bio_details *bd = NULL;
12520045d61bSMikulas Patocka struct dm_raid1_bio_record *bio_record =
12530045d61bSMikulas Patocka dm_per_bio_data(bio, sizeof(struct dm_raid1_bio_record));
12541da177e4SLinus Torvalds
12551da177e4SLinus Torvalds /*
12561da177e4SLinus Torvalds * We need to dec pending if this was a write.
12571da177e4SLinus Torvalds */
125806386bbfSJonathan Brassow if (rw == WRITE) {
12591eff9d32SJens Axboe if (!(bio->bi_opf & REQ_PREFLUSH) &&
126028a8f0d3SMike Christie bio_op(bio) != REQ_OP_DISCARD)
12610045d61bSMikulas Patocka dm_rh_dec(ms->rh, bio_record->write_region);
12621be56909SChristoph Hellwig return DM_ENDIO_DONE;
126306386bbfSJonathan Brassow }
12641da177e4SLinus Torvalds
12654e4cbee9SChristoph Hellwig if (*error == BLK_STS_NOTSUPP)
1266cd15fb64SMike Snitzer goto out;
126706386bbfSJonathan Brassow
12689966afafSChristoph Hellwig if (bio->bi_opf & REQ_RAHEAD)
1269cd15fb64SMike Snitzer goto out;
127006386bbfSJonathan Brassow
12711be56909SChristoph Hellwig if (unlikely(*error)) {
1272309dca30SChristoph Hellwig if (!bio_record->details.bi_bdev) {
1273cd15fb64SMike Snitzer /*
1274cd15fb64SMike Snitzer * There wasn't enough memory to record necessary
1275cd15fb64SMike Snitzer * information for a retry or there was no other
1276cd15fb64SMike Snitzer * mirror in-sync.
1277cd15fb64SMike Snitzer */
1278cd15fb64SMike Snitzer DMERR_LIMIT("Mirror read failed.");
1279c6b1e36cSLinus Torvalds return DM_ENDIO_DONE;
1280cd15fb64SMike Snitzer }
1281cd15fb64SMike Snitzer
128289c7cd89SMikulas Patocka m = bio_record->m;
1283e03f1a84SAdrian Bunk
128406386bbfSJonathan Brassow DMERR("Mirror read failed from %s. Trying alternative device.",
128506386bbfSJonathan Brassow m->dev->name);
128606386bbfSJonathan Brassow
128706386bbfSJonathan Brassow fail_mirror(m, DM_RAID1_READ_ERROR);
128806386bbfSJonathan Brassow
128906386bbfSJonathan Brassow /*
129006386bbfSJonathan Brassow * A failed read is requeued for another attempt using an intact
129106386bbfSJonathan Brassow * mirror.
129206386bbfSJonathan Brassow */
129306386bbfSJonathan Brassow if (default_ok(m) || mirror_available(ms, bio)) {
129489c7cd89SMikulas Patocka bd = &bio_record->details;
129506386bbfSJonathan Brassow
129606386bbfSJonathan Brassow dm_bio_restore(bd, bio);
1297309dca30SChristoph Hellwig bio_record->details.bi_bdev = NULL;
12984e4cbee9SChristoph Hellwig bio->bi_status = 0;
1299f3a44fe0SMikulas Patocka
130006386bbfSJonathan Brassow queue_bio(ms, bio, rw);
130119cbbc60SMikulas Patocka return DM_ENDIO_INCOMPLETE;
130206386bbfSJonathan Brassow }
130306386bbfSJonathan Brassow DMERR("All replicated volumes dead, failing I/O");
130406386bbfSJonathan Brassow }
130506386bbfSJonathan Brassow
1306cd15fb64SMike Snitzer out:
1307309dca30SChristoph Hellwig bio_record->details.bi_bdev = NULL;
1308cd15fb64SMike Snitzer
13091be56909SChristoph Hellwig return DM_ENDIO_DONE;
13101da177e4SLinus Torvalds }
13111da177e4SLinus Torvalds
mirror_presuspend(struct dm_target * ti)1312b80aa7a0SJonathan Brassow static void mirror_presuspend(struct dm_target *ti)
13131da177e4SLinus Torvalds {
131426cb62a2SYu Zhe struct mirror_set *ms = ti->private;
13151f965b19SHeinz Mauelshagen struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh);
13161da177e4SLinus Torvalds
131704788507SMikulas Patocka struct bio_list holds;
131804788507SMikulas Patocka struct bio *bio;
131904788507SMikulas Patocka
1320b80aa7a0SJonathan Brassow atomic_set(&ms->suspend, 1);
1321b80aa7a0SJonathan Brassow
1322b80aa7a0SJonathan Brassow /*
1323f0703040STakahiro Yasui * Process bios in the hold list to start recovery waiting
1324f0703040STakahiro Yasui * for bios in the hold list. After the process, no bio has
1325f0703040STakahiro Yasui * a chance to be added in the hold list because ms->suspend
1326f0703040STakahiro Yasui * is set.
1327f0703040STakahiro Yasui */
1328f0703040STakahiro Yasui spin_lock_irq(&ms->lock);
1329f0703040STakahiro Yasui holds = ms->holds;
1330f0703040STakahiro Yasui bio_list_init(&ms->holds);
1331f0703040STakahiro Yasui spin_unlock_irq(&ms->lock);
1332f0703040STakahiro Yasui
1333f0703040STakahiro Yasui while ((bio = bio_list_pop(&holds)))
1334f0703040STakahiro Yasui hold_bio(ms, bio);
1335f0703040STakahiro Yasui
1336f0703040STakahiro Yasui /*
1337b80aa7a0SJonathan Brassow * We must finish up all the work that we've
1338b80aa7a0SJonathan Brassow * generated (i.e. recovery work).
1339b80aa7a0SJonathan Brassow */
13401f965b19SHeinz Mauelshagen dm_rh_stop_recovery(ms->rh);
134133184048SJonathan E Brassow
134233184048SJonathan E Brassow wait_event(_kmirrord_recovery_stopped,
13431f965b19SHeinz Mauelshagen !dm_rh_recovery_in_flight(ms->rh));
134433184048SJonathan E Brassow
1345b80aa7a0SJonathan Brassow if (log->type->presuspend && log->type->presuspend(log))
1346b80aa7a0SJonathan Brassow /* FIXME: need better error handling */
1347b80aa7a0SJonathan Brassow DMWARN("log presuspend failed");
1348b80aa7a0SJonathan Brassow
1349b80aa7a0SJonathan Brassow /*
1350b80aa7a0SJonathan Brassow * Now that recovery is complete/stopped and the
1351b80aa7a0SJonathan Brassow * delayed bios are queued, we need to wait for
1352b80aa7a0SJonathan Brassow * the worker thread to complete. This way,
1353b80aa7a0SJonathan Brassow * we know that all of our I/O has been pushed.
1354b80aa7a0SJonathan Brassow */
1355b80aa7a0SJonathan Brassow flush_workqueue(ms->kmirrord_wq);
1356b80aa7a0SJonathan Brassow }
1357b80aa7a0SJonathan Brassow
mirror_postsuspend(struct dm_target * ti)1358b80aa7a0SJonathan Brassow static void mirror_postsuspend(struct dm_target *ti)
1359b80aa7a0SJonathan Brassow {
1360b80aa7a0SJonathan Brassow struct mirror_set *ms = ti->private;
13611f965b19SHeinz Mauelshagen struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh);
1362b80aa7a0SJonathan Brassow
13636b3df0d7SJonathan Brassow if (log->type->postsuspend && log->type->postsuspend(log))
13641da177e4SLinus Torvalds /* FIXME: need better error handling */
1365b80aa7a0SJonathan Brassow DMWARN("log postsuspend failed");
13661da177e4SLinus Torvalds }
13671da177e4SLinus Torvalds
mirror_resume(struct dm_target * ti)13681da177e4SLinus Torvalds static void mirror_resume(struct dm_target *ti)
13691da177e4SLinus Torvalds {
1370b80aa7a0SJonathan Brassow struct mirror_set *ms = ti->private;
13711f965b19SHeinz Mauelshagen struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh);
1372b80aa7a0SJonathan Brassow
1373b80aa7a0SJonathan Brassow atomic_set(&ms->suspend, 0);
13741da177e4SLinus Torvalds if (log->type->resume && log->type->resume(log))
13751da177e4SLinus Torvalds /* FIXME: need better error handling */
13761da177e4SLinus Torvalds DMWARN("log resume failed");
13771f965b19SHeinz Mauelshagen dm_rh_start_recovery(ms->rh);
13781da177e4SLinus Torvalds }
13791da177e4SLinus Torvalds
1380af195ac8SJonathan Brassow /*
1381af195ac8SJonathan Brassow * device_status_char
1382af195ac8SJonathan Brassow * @m: mirror device/leg we want the status of
1383af195ac8SJonathan Brassow *
1384af195ac8SJonathan Brassow * We return one character representing the most severe error
1385af195ac8SJonathan Brassow * we have encountered.
1386af195ac8SJonathan Brassow * A => Alive - No failures
1387af195ac8SJonathan Brassow * D => Dead - A write failure occurred leaving mirror out-of-sync
1388af195ac8SJonathan Brassow * S => Sync - A sychronization failure occurred, mirror out-of-sync
1389af195ac8SJonathan Brassow * R => Read - A read failure occurred, mirror data unaffected
1390af195ac8SJonathan Brassow *
1391af195ac8SJonathan Brassow * Returns: <char>
1392af195ac8SJonathan Brassow */
device_status_char(struct mirror * m)1393af195ac8SJonathan Brassow static char device_status_char(struct mirror *m)
1394af195ac8SJonathan Brassow {
1395af195ac8SJonathan Brassow if (!atomic_read(&(m->error_count)))
1396af195ac8SJonathan Brassow return 'A';
1397af195ac8SJonathan Brassow
139864b30c46SMikulas Patocka return (test_bit(DM_RAID1_FLUSH_ERROR, &(m->error_type))) ? 'F' :
139964b30c46SMikulas Patocka (test_bit(DM_RAID1_WRITE_ERROR, &(m->error_type))) ? 'D' :
1400af195ac8SJonathan Brassow (test_bit(DM_RAID1_SYNC_ERROR, &(m->error_type))) ? 'S' :
1401af195ac8SJonathan Brassow (test_bit(DM_RAID1_READ_ERROR, &(m->error_type))) ? 'R' : 'U';
1402af195ac8SJonathan Brassow }
1403af195ac8SJonathan Brassow
1404af195ac8SJonathan Brassow
mirror_status(struct dm_target * ti,status_type_t type,unsigned int status_flags,char * result,unsigned int maxlen)1405fd7c092eSMikulas Patocka static void mirror_status(struct dm_target *ti, status_type_t type,
140686a3238cSHeinz Mauelshagen unsigned int status_flags, char *result, unsigned int maxlen)
14071da177e4SLinus Torvalds {
1408315dcc22SJonathan E Brassow unsigned int m, sz = 0;
1409ed63287dSLidong Zhong int num_feature_args = 0;
141026cb62a2SYu Zhe struct mirror_set *ms = ti->private;
14111f965b19SHeinz Mauelshagen struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh);
141265972a6fSKees Cook char buffer[MAX_NR_MIRRORS + 1];
14131da177e4SLinus Torvalds
14141da177e4SLinus Torvalds switch (type) {
14151da177e4SLinus Torvalds case STATUSTYPE_INFO:
14161da177e4SLinus Torvalds DMEMIT("%d ", ms->nr_mirrors);
1417af195ac8SJonathan Brassow for (m = 0; m < ms->nr_mirrors; m++) {
14181da177e4SLinus Torvalds DMEMIT("%s ", ms->mirror[m].dev->name);
1419af195ac8SJonathan Brassow buffer[m] = device_status_char(&(ms->mirror[m]));
1420af195ac8SJonathan Brassow }
1421af195ac8SJonathan Brassow buffer[m] = '\0';
14221da177e4SLinus Torvalds
1423af195ac8SJonathan Brassow DMEMIT("%llu/%llu 1 %s ",
14241f965b19SHeinz Mauelshagen (unsigned long long)log->type->get_sync_count(log),
1425af195ac8SJonathan Brassow (unsigned long long)ms->nr_regions, buffer);
1426315dcc22SJonathan E Brassow
14271f965b19SHeinz Mauelshagen sz += log->type->status(log, type, result+sz, maxlen-sz);
1428315dcc22SJonathan E Brassow
14291da177e4SLinus Torvalds break;
14301da177e4SLinus Torvalds
14311da177e4SLinus Torvalds case STATUSTYPE_TABLE:
14321f965b19SHeinz Mauelshagen sz = log->type->status(log, type, result, maxlen);
1433315dcc22SJonathan E Brassow
14341da177e4SLinus Torvalds DMEMIT("%d", ms->nr_mirrors);
14351da177e4SLinus Torvalds for (m = 0; m < ms->nr_mirrors; m++)
14364ee218cdSAndrew Morton DMEMIT(" %s %llu", ms->mirror[m].dev->name,
14374ee218cdSAndrew Morton (unsigned long long)ms->mirror[m].offset);
1438a8e6afa2SJonathan E Brassow
1439ed63287dSLidong Zhong num_feature_args += !!errors_handled(ms);
1440ed63287dSLidong Zhong num_feature_args += !!keep_log(ms);
1441ed63287dSLidong Zhong if (num_feature_args) {
1442ed63287dSLidong Zhong DMEMIT(" %d", num_feature_args);
1443ed63287dSLidong Zhong if (errors_handled(ms))
1444ed63287dSLidong Zhong DMEMIT(" handle_errors");
1445ed63287dSLidong Zhong if (keep_log(ms))
1446ed63287dSLidong Zhong DMEMIT(" keep_log");
1447ed63287dSLidong Zhong }
1448ed63287dSLidong Zhong
1449ed63287dSLidong Zhong break;
14508ec45662STushar Sugandhi
14518ec45662STushar Sugandhi case STATUSTYPE_IMA:
14528ec45662STushar Sugandhi DMEMIT_TARGET_NAME_VERSION(ti->type);
14538ec45662STushar Sugandhi DMEMIT(",nr_mirrors=%d", ms->nr_mirrors);
14548ec45662STushar Sugandhi for (m = 0; m < ms->nr_mirrors; m++) {
14558ec45662STushar Sugandhi DMEMIT(",mirror_device_%d=%s", m, ms->mirror[m].dev->name);
14568ec45662STushar Sugandhi DMEMIT(",mirror_device_%d_status=%c",
14578ec45662STushar Sugandhi m, device_status_char(&(ms->mirror[m])));
14588ec45662STushar Sugandhi }
14598ec45662STushar Sugandhi
14608ec45662STushar Sugandhi DMEMIT(",handle_errors=%c", errors_handled(ms) ? 'y' : 'n');
14618ec45662STushar Sugandhi DMEMIT(",keep_log=%c", keep_log(ms) ? 'y' : 'n');
14628ec45662STushar Sugandhi
14638ec45662STushar Sugandhi DMEMIT(",log_type_status=");
14648ec45662STushar Sugandhi sz += log->type->status(log, type, result+sz, maxlen-sz);
14658ec45662STushar Sugandhi DMEMIT(";");
14668ec45662STushar Sugandhi break;
14671da177e4SLinus Torvalds }
14681da177e4SLinus Torvalds }
14691da177e4SLinus Torvalds
mirror_iterate_devices(struct dm_target * ti,iterate_devices_callout_fn fn,void * data)1470af4874e0SMike Snitzer static int mirror_iterate_devices(struct dm_target *ti,
1471af4874e0SMike Snitzer iterate_devices_callout_fn fn, void *data)
1472af4874e0SMike Snitzer {
1473af4874e0SMike Snitzer struct mirror_set *ms = ti->private;
1474af4874e0SMike Snitzer int ret = 0;
147586a3238cSHeinz Mauelshagen unsigned int i;
1476af4874e0SMike Snitzer
1477af4874e0SMike Snitzer for (i = 0; !ret && i < ms->nr_mirrors; i++)
1478af4874e0SMike Snitzer ret = fn(ti, ms->mirror[i].dev,
14795dea271bSMike Snitzer ms->mirror[i].offset, ti->len, data);
1480af4874e0SMike Snitzer
1481af4874e0SMike Snitzer return ret;
1482af4874e0SMike Snitzer }
1483af4874e0SMike Snitzer
14841da177e4SLinus Torvalds static struct target_type mirror_target = {
14851da177e4SLinus Torvalds .name = "mirror",
1486ed63287dSLidong Zhong .version = {1, 14, 0},
14871da177e4SLinus Torvalds .module = THIS_MODULE,
14881da177e4SLinus Torvalds .ctr = mirror_ctr,
14891da177e4SLinus Torvalds .dtr = mirror_dtr,
14901da177e4SLinus Torvalds .map = mirror_map,
14911da177e4SLinus Torvalds .end_io = mirror_end_io,
1492b80aa7a0SJonathan Brassow .presuspend = mirror_presuspend,
14931da177e4SLinus Torvalds .postsuspend = mirror_postsuspend,
14941da177e4SLinus Torvalds .resume = mirror_resume,
14951da177e4SLinus Torvalds .status = mirror_status,
1496af4874e0SMike Snitzer .iterate_devices = mirror_iterate_devices,
14971da177e4SLinus Torvalds };
14981da177e4SLinus Torvalds
dm_mirror_init(void)14991da177e4SLinus Torvalds static int __init dm_mirror_init(void)
15001da177e4SLinus Torvalds {
1501b362c733SYangtao Li int r;
1502a7e8f7fbSTetsuo Handa
1503a7e8f7fbSTetsuo Handa dm_raid1_wq = alloc_workqueue("dm_raid1_wq", 0, 0);
1504990f61e4SYangtao Li if (!dm_raid1_wq) {
1505990f61e4SYangtao Li DMERR("Failed to alloc workqueue");
1506b362c733SYangtao Li return -ENOMEM;
1507990f61e4SYangtao Li }
15081da177e4SLinus Torvalds
150995f8fac8SMikulas Patocka r = dm_register_target(&mirror_target);
151095f8fac8SMikulas Patocka if (r < 0) {
1511a7e8f7fbSTetsuo Handa destroy_workqueue(dm_raid1_wq);
1512b362c733SYangtao Li return r;
151395f8fac8SMikulas Patocka }
151495f8fac8SMikulas Patocka
151595f8fac8SMikulas Patocka return 0;
15161da177e4SLinus Torvalds }
15171da177e4SLinus Torvalds
dm_mirror_exit(void)15181da177e4SLinus Torvalds static void __exit dm_mirror_exit(void)
15191da177e4SLinus Torvalds {
1520a7e8f7fbSTetsuo Handa destroy_workqueue(dm_raid1_wq);
152110d3bd09SMikulas Patocka dm_unregister_target(&mirror_target);
15221da177e4SLinus Torvalds }
15231da177e4SLinus Torvalds
15241da177e4SLinus Torvalds /* Module hooks */
15251da177e4SLinus Torvalds module_init(dm_mirror_init);
15261da177e4SLinus Torvalds module_exit(dm_mirror_exit);
15271da177e4SLinus Torvalds
15281da177e4SLinus Torvalds MODULE_DESCRIPTION(DM_NAME " mirror target");
15291da177e4SLinus Torvalds MODULE_AUTHOR("Joe Thornber");
15301da177e4SLinus Torvalds MODULE_LICENSE("GPL");
1531