dm-raid1.c revision 1f965b19437017cea6d3f3f46acdc5acae5fd011
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2003 Sistina Software Limited. 31f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen * Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved. 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This file is released under the GPL. 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "dm-bio-list.h" 906386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow#include "dm-bio-record.h" 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/mempool.h> 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/pagemap.h> 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/slab.h> 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/workqueue.h> 171f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen#include <linux/device-mapper.h> 18a765e20eeb423d0fa6a02ffab51141e53bbd93cbAlasdair G Kergon#include <linux/dm-io.h> 19a765e20eeb423d0fa6a02ffab51141e53bbd93cbAlasdair G Kergon#include <linux/dm-dirty-log.h> 20a765e20eeb423d0fa6a02ffab51141e53bbd93cbAlasdair G Kergon#include <linux/dm-kcopyd.h> 211f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen#include <linux/dm-region-hash.h> 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2372d9486169a2a8353e022813185ba2f32d7dde69Alasdair G Kergon#define DM_MSG_PREFIX "raid1" 241f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen 251f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen#define MAX_RECOVERY 1 /* Maximum number of regions recovered in parallel. */ 2688be163abb5324bab09f5eff9646590eec5314ebMilan Broz#define DM_IO_PAGES 64 271f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen#define DM_KCOPYD_PAGES 64 2872d9486169a2a8353e022813185ba2f32d7dde69Alasdair G Kergon 29a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow#define DM_RAID1_HANDLE_ERRORS 0x01 30f44db678edcc6f4c2779ac43f63f0b9dfa28b724Jonathan Brassow#define errors_handled(p) ((p)->features & DM_RAID1_HANDLE_ERRORS) 31a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow 3233184048dc4f9d5550d3b6a88c8e0ff92033eb6eJonathan E Brassowstatic DECLARE_WAIT_QUEUE_HEAD(_kmirrord_recovery_stopped); 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*----------------------------------------------------------------- 35e4c8b3ba34cc1aeab451c7a5cc843c5fd62cbe3dNeil Brown * Mirror set structures. 36e4c8b3ba34cc1aeab451c7a5cc843c5fd62cbe3dNeil Brown *---------------------------------------------------------------*/ 3772f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassowenum dm_raid1_error { 3872f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow DM_RAID1_WRITE_ERROR, 3972f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow DM_RAID1_SYNC_ERROR, 4072f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow DM_RAID1_READ_ERROR 4172f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow}; 4272f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow 43e4c8b3ba34cc1aeab451c7a5cc843c5fd62cbe3dNeil Brownstruct mirror { 44aa5617c55357d86c9082ba1d66fa9795370c9954Jonathan Brassow struct mirror_set *ms; 45e4c8b3ba34cc1aeab451c7a5cc843c5fd62cbe3dNeil Brown atomic_t error_count; 4639ed7adb17bdec8224bd3fae551bb7222e05f35bAl Viro unsigned long error_type; 47e4c8b3ba34cc1aeab451c7a5cc843c5fd62cbe3dNeil Brown struct dm_dev *dev; 48e4c8b3ba34cc1aeab451c7a5cc843c5fd62cbe3dNeil Brown sector_t offset; 49e4c8b3ba34cc1aeab451c7a5cc843c5fd62cbe3dNeil Brown}; 50e4c8b3ba34cc1aeab451c7a5cc843c5fd62cbe3dNeil Brown 51e4c8b3ba34cc1aeab451c7a5cc843c5fd62cbe3dNeil Brownstruct mirror_set { 52e4c8b3ba34cc1aeab451c7a5cc843c5fd62cbe3dNeil Brown struct dm_target *ti; 53e4c8b3ba34cc1aeab451c7a5cc843c5fd62cbe3dNeil Brown struct list_head list; 541f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen 55a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow uint64_t features; 56e4c8b3ba34cc1aeab451c7a5cc843c5fd62cbe3dNeil Brown 5772f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow spinlock_t lock; /* protects the lists */ 58e4c8b3ba34cc1aeab451c7a5cc843c5fd62cbe3dNeil Brown struct bio_list reads; 59e4c8b3ba34cc1aeab451c7a5cc843c5fd62cbe3dNeil Brown struct bio_list writes; 6072f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow struct bio_list failures; 61e4c8b3ba34cc1aeab451c7a5cc843c5fd62cbe3dNeil Brown 621f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen struct dm_region_hash *rh; 631f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen struct dm_kcopyd_client *kcopyd_client; 6488be163abb5324bab09f5eff9646590eec5314ebMilan Broz struct dm_io_client *io_client; 6506386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow mempool_t *read_record_pool; 6688be163abb5324bab09f5eff9646590eec5314ebMilan Broz 67e4c8b3ba34cc1aeab451c7a5cc843c5fd62cbe3dNeil Brown /* recovery */ 68e4c8b3ba34cc1aeab451c7a5cc843c5fd62cbe3dNeil Brown region_t nr_regions; 69e4c8b3ba34cc1aeab451c7a5cc843c5fd62cbe3dNeil Brown int in_sync; 70fc1ff9588a6d56258ff9576a31aa34f17757c666Jonathan Brassow int log_failure; 71b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow atomic_t suspend; 72e4c8b3ba34cc1aeab451c7a5cc843c5fd62cbe3dNeil Brown 7372f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow atomic_t default_mirror; /* Default mirror */ 74e4c8b3ba34cc1aeab451c7a5cc843c5fd62cbe3dNeil Brown 756ad36fe2b451cc85cc7b14f4128286759e217124Holger Smolinski struct workqueue_struct *kmirrord_wq; 766ad36fe2b451cc85cc7b14f4128286759e217124Holger Smolinski struct work_struct kmirrord_work; 77a2aebe03be60ae4da03507a00d60211d5e0327c3Mikulas Patocka struct timer_list timer; 78a2aebe03be60ae4da03507a00d60211d5e0327c3Mikulas Patocka unsigned long timer_pending; 79a2aebe03be60ae4da03507a00d60211d5e0327c3Mikulas Patocka 8072f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow struct work_struct trigger_event; 816ad36fe2b451cc85cc7b14f4128286759e217124Holger Smolinski 821f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen unsigned nr_mirrors; 83e4c8b3ba34cc1aeab451c7a5cc843c5fd62cbe3dNeil Brown struct mirror mirror[0]; 84e4c8b3ba34cc1aeab451c7a5cc843c5fd62cbe3dNeil Brown}; 85e4c8b3ba34cc1aeab451c7a5cc843c5fd62cbe3dNeil Brown 861f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagenstatic void wakeup_mirrord(void *context) 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 881f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen struct mirror_set *ms = context; 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 906ad36fe2b451cc85cc7b14f4128286759e217124Holger Smolinski queue_work(ms->kmirrord_wq, &ms->kmirrord_work); 916ad36fe2b451cc85cc7b14f4128286759e217124Holger Smolinski} 926ad36fe2b451cc85cc7b14f4128286759e217124Holger Smolinski 93a2aebe03be60ae4da03507a00d60211d5e0327c3Mikulas Patockastatic void delayed_wake_fn(unsigned long data) 94a2aebe03be60ae4da03507a00d60211d5e0327c3Mikulas Patocka{ 95a2aebe03be60ae4da03507a00d60211d5e0327c3Mikulas Patocka struct mirror_set *ms = (struct mirror_set *) data; 96a2aebe03be60ae4da03507a00d60211d5e0327c3Mikulas Patocka 97a2aebe03be60ae4da03507a00d60211d5e0327c3Mikulas Patocka clear_bit(0, &ms->timer_pending); 981f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen wakeup_mirrord(ms); 99a2aebe03be60ae4da03507a00d60211d5e0327c3Mikulas Patocka} 100a2aebe03be60ae4da03507a00d60211d5e0327c3Mikulas Patocka 101a2aebe03be60ae4da03507a00d60211d5e0327c3Mikulas Patockastatic void delayed_wake(struct mirror_set *ms) 102a2aebe03be60ae4da03507a00d60211d5e0327c3Mikulas Patocka{ 103a2aebe03be60ae4da03507a00d60211d5e0327c3Mikulas Patocka if (test_and_set_bit(0, &ms->timer_pending)) 104a2aebe03be60ae4da03507a00d60211d5e0327c3Mikulas Patocka return; 105a2aebe03be60ae4da03507a00d60211d5e0327c3Mikulas Patocka 106a2aebe03be60ae4da03507a00d60211d5e0327c3Mikulas Patocka ms->timer.expires = jiffies + HZ / 5; 107a2aebe03be60ae4da03507a00d60211d5e0327c3Mikulas Patocka ms->timer.data = (unsigned long) ms; 108a2aebe03be60ae4da03507a00d60211d5e0327c3Mikulas Patocka ms->timer.function = delayed_wake_fn; 109a2aebe03be60ae4da03507a00d60211d5e0327c3Mikulas Patocka add_timer(&ms->timer); 110a2aebe03be60ae4da03507a00d60211d5e0327c3Mikulas Patocka} 111a2aebe03be60ae4da03507a00d60211d5e0327c3Mikulas Patocka 1121f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagenstatic void wakeup_all_recovery_waiters(void *context) 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1141f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen wake_up_all(&_kmirrord_recovery_stopped); 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1171f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagenstatic void queue_bio(struct mirror_set *ms, struct bio *bio, int rw) 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int should_wake = 0; 1211f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen struct bio_list *bl; 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1231f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen bl = (rw == WRITE) ? &ms->writes : &ms->reads; 1241f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen spin_lock_irqsave(&ms->lock, flags); 1251f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen should_wake = !(bl->head); 1261f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen bio_list_add(bl, bio); 1271f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen spin_unlock_irqrestore(&ms->lock, flags); 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (should_wake) 1301f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen wakeup_mirrord(ms); 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1331f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagenstatic void dispatch_bios(void *context, struct bio_list *bio_list) 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1351f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen struct mirror_set *ms = context; 1361f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen struct bio *bio; 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1381f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen while ((bio = bio_list_pop(bio_list))) 1391f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen queue_bio(ms, bio, WRITE); 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 14206386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow#define MIN_READ_RECORDS 20 14306386bbfd2441416875d0403d405c56822f6ebacJonathan Brassowstruct dm_raid1_read_record { 14406386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow struct mirror *m; 14506386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow struct dm_bio_details details; 14606386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow}; 14706386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow 1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Every mirror should look like this one. 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DEFAULT_MIRROR 0 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 15406386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow * This is yucky. We squirrel the mirror struct away inside 15506386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow * bi_next for read/write buffers. This is safe since the bh 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * doesn't get submitted to the lower levels of block layer. 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 15806386bbfd2441416875d0403d405c56822f6ebacJonathan Brassowstatic struct mirror *bio_get_m(struct bio *bio) 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 16006386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow return (struct mirror *) bio->bi_next; 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16306386bbfd2441416875d0403d405c56822f6ebacJonathan Brassowstatic void bio_set_m(struct bio *bio, struct mirror *m) 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 16506386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow bio->bi_next = (struct bio *) m; 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 16872f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassowstatic struct mirror *get_default_mirror(struct mirror_set *ms) 16972f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow{ 17072f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow return &ms->mirror[atomic_read(&ms->default_mirror)]; 17172f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow} 17272f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow 17372f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassowstatic void set_default_mirror(struct mirror *m) 17472f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow{ 17572f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow struct mirror_set *ms = m->ms; 17672f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow struct mirror *m0 = &(ms->mirror[0]); 17772f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow 17872f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow atomic_set(&ms->default_mirror, m - m0); 17972f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow} 18072f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow 18172f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow/* fail_mirror 18272f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow * @m: mirror device to fail 18372f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow * @error_type: one of the enum's, DM_RAID1_*_ERROR 18472f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow * 18572f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow * If errors are being handled, record the type of 18672f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow * error encountered for this device. If this type 18772f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow * of error has already been recorded, we can return; 18872f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow * otherwise, we must signal userspace by triggering 18972f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow * an event. Additionally, if the device is the 19072f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow * primary device, we must choose a new primary, but 19172f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow * only if the mirror is in-sync. 19272f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow * 19372f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow * This function must not block. 19472f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow */ 19572f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassowstatic void fail_mirror(struct mirror *m, enum dm_raid1_error error_type) 19672f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow{ 19772f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow struct mirror_set *ms = m->ms; 19872f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow struct mirror *new; 19972f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow 20072f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow if (!errors_handled(ms)) 20172f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow return; 20272f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow 20372f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow /* 20472f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow * error_count is used for nothing more than a 20572f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow * simple way to tell if a device has encountered 20672f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow * errors. 20772f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow */ 20872f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow atomic_inc(&m->error_count); 20972f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow 21072f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow if (test_and_set_bit(error_type, &m->error_type)) 21172f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow return; 21272f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow 21372f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow if (m != get_default_mirror(ms)) 21472f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow goto out; 21572f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow 21672f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow if (!ms->in_sync) { 21772f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow /* 21872f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow * Better to issue requests to same failing device 21972f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow * than to risk returning corrupt data. 22072f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow */ 22172f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow DMERR("Primary mirror (%s) failed while out-of-sync: " 22272f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow "Reads may fail.", m->dev->name); 22372f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow goto out; 22472f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow } 22572f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow 22672f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow for (new = ms->mirror; new < ms->mirror + ms->nr_mirrors; new++) 22772f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow if (!atomic_read(&new->error_count)) { 22872f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow set_default_mirror(new); 22972f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow break; 23072f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow } 23172f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow 23272f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow if (unlikely(new == ms->mirror + ms->nr_mirrors)) 23372f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow DMWARN("All sides of mirror have failed."); 23472f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow 23572f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassowout: 23672f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow schedule_work(&ms->trigger_event); 23772f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow} 23872f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*----------------------------------------------------------------- 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Recovery. 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * When a mirror is first activated we may find that some regions 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * are in the no-sync state. We have to recover these by 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * recopying from the default mirror to all the others. 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *---------------------------------------------------------------*/ 2464cdc1d1fa5c5ac14dc21be19832f02fd0b83867eAlasdair G Kergonstatic void recovery_complete(int read_err, unsigned long write_err, 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds void *context) 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2491f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen struct dm_region *reg = context; 2501f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen struct mirror_set *ms = dm_rh_region_context(reg); 2518f0205b798f926e2745de5fdebf0a8605c621de6Jonathan Brassow int m, bit = 0; 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2538f0205b798f926e2745de5fdebf0a8605c621de6Jonathan Brassow if (read_err) { 254f44db678edcc6f4c2779ac43f63f0b9dfa28b724Jonathan Brassow /* Read error means the failure of default mirror. */ 255f44db678edcc6f4c2779ac43f63f0b9dfa28b724Jonathan Brassow DMERR_LIMIT("Unable to read primary mirror during recovery"); 2568f0205b798f926e2745de5fdebf0a8605c621de6Jonathan Brassow fail_mirror(get_default_mirror(ms), DM_RAID1_SYNC_ERROR); 2578f0205b798f926e2745de5fdebf0a8605c621de6Jonathan Brassow } 258f44db678edcc6f4c2779ac43f63f0b9dfa28b724Jonathan Brassow 2598f0205b798f926e2745de5fdebf0a8605c621de6Jonathan Brassow if (write_err) { 2604cdc1d1fa5c5ac14dc21be19832f02fd0b83867eAlasdair G Kergon DMERR_LIMIT("Write error during recovery (error = 0x%lx)", 261f44db678edcc6f4c2779ac43f63f0b9dfa28b724Jonathan Brassow write_err); 2628f0205b798f926e2745de5fdebf0a8605c621de6Jonathan Brassow /* 2638f0205b798f926e2745de5fdebf0a8605c621de6Jonathan Brassow * Bits correspond to devices (excluding default mirror). 2648f0205b798f926e2745de5fdebf0a8605c621de6Jonathan Brassow * The default mirror cannot change during recovery. 2658f0205b798f926e2745de5fdebf0a8605c621de6Jonathan Brassow */ 2668f0205b798f926e2745de5fdebf0a8605c621de6Jonathan Brassow for (m = 0; m < ms->nr_mirrors; m++) { 2678f0205b798f926e2745de5fdebf0a8605c621de6Jonathan Brassow if (&ms->mirror[m] == get_default_mirror(ms)) 2688f0205b798f926e2745de5fdebf0a8605c621de6Jonathan Brassow continue; 2698f0205b798f926e2745de5fdebf0a8605c621de6Jonathan Brassow if (test_bit(bit, &write_err)) 2708f0205b798f926e2745de5fdebf0a8605c621de6Jonathan Brassow fail_mirror(ms->mirror + m, 2718f0205b798f926e2745de5fdebf0a8605c621de6Jonathan Brassow DM_RAID1_SYNC_ERROR); 2728f0205b798f926e2745de5fdebf0a8605c621de6Jonathan Brassow bit++; 2738f0205b798f926e2745de5fdebf0a8605c621de6Jonathan Brassow } 2748f0205b798f926e2745de5fdebf0a8605c621de6Jonathan Brassow } 275f44db678edcc6f4c2779ac43f63f0b9dfa28b724Jonathan Brassow 2761f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen dm_rh_recovery_end(reg, !(read_err || write_err)); 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2791f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagenstatic int recover(struct mirror_set *ms, struct dm_region *reg) 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int r; 2821f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen unsigned i; 283eb69aca5d3370b81450d68edeebc2bb9a3eb9689Heinz Mauelshagen struct dm_io_region from, to[DM_KCOPYD_MAX_REGIONS], *dest; 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct mirror *m; 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags = 0; 2861f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen region_t key = dm_rh_get_region_key(reg); 2871f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen sector_t region_size = dm_rh_get_region_size(ms->rh); 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* fill in the source */ 29072f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow m = get_default_mirror(ms); 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds from.bdev = m->dev->bdev; 2921f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen from.sector = m->offset + dm_rh_region_to_sector(ms->rh, key); 2931f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen if (key == (ms->nr_regions - 1)) { 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The final region may be smaller than 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * region_size. 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 2981f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen from.count = ms->ti->len & (region_size - 1); 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!from.count) 3001f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen from.count = region_size; 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else 3021f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen from.count = region_size; 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* fill in the destinations */ 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0, dest = to; i < ms->nr_mirrors; i++) { 30672f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow if (&ms->mirror[i] == get_default_mirror(ms)) 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds m = ms->mirror + i; 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dest->bdev = m->dev->bdev; 3111f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen dest->sector = m->offset + dm_rh_region_to_sector(ms->rh, key); 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dest->count = from.count; 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dest++; 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* hand to kcopyd */ 317f7c83e2e4783c4f7abe6f3a85a8c5e210f98bc7bJonathan Brassow if (!errors_handled(ms)) 318f7c83e2e4783c4f7abe6f3a85a8c5e210f98bc7bJonathan Brassow set_bit(DM_KCOPYD_IGNORE_ERROR, &flags); 319f7c83e2e4783c4f7abe6f3a85a8c5e210f98bc7bJonathan Brassow 320eb69aca5d3370b81450d68edeebc2bb9a3eb9689Heinz Mauelshagen r = dm_kcopyd_copy(ms->kcopyd_client, &from, ms->nr_mirrors - 1, to, 321eb69aca5d3370b81450d68edeebc2bb9a3eb9689Heinz Mauelshagen flags, recovery_complete, reg); 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return r; 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void do_recovery(struct mirror_set *ms) 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3281f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen struct dm_region *reg; 3291f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh); 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int r; 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Start quiescing some regions. 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3351f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen dm_rh_recovery_prepare(ms->rh); 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copy any already quiesced regions. 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3401f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen while ((reg = dm_rh_recovery_start(ms->rh))) { 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r = recover(ms, reg); 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (r) 3431f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen dm_rh_recovery_end(reg, 0); 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Update the in sync flag. 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!ms->in_sync && 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (log->type->get_sync_count(log) == ms->nr_regions)) { 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* the sync is complete */ 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dm_table_event(ms->ti->table); 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ms->in_sync = 1; 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*----------------------------------------------------------------- 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Reads 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *---------------------------------------------------------------*/ 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct mirror *choose_mirror(struct mirror_set *ms, sector_t sector) 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 36206386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow struct mirror *m = get_default_mirror(ms); 36306386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow 36406386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow do { 36506386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow if (likely(!atomic_read(&m->error_count))) 36606386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow return m; 36706386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow 36806386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow if (m-- == ms->mirror) 36906386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow m += ms->nr_mirrors; 37006386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow } while (m != get_default_mirror(ms)); 37106386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow 37206386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow return NULL; 37306386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow} 37406386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow 37506386bbfd2441416875d0403d405c56822f6ebacJonathan Brassowstatic int default_ok(struct mirror *m) 37606386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow{ 37706386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow struct mirror *default_mirror = get_default_mirror(m->ms); 37806386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow 37906386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow return !atomic_read(&default_mirror->error_count); 38006386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow} 38106386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow 38206386bbfd2441416875d0403d405c56822f6ebacJonathan Brassowstatic int mirror_available(struct mirror_set *ms, struct bio *bio) 38306386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow{ 3841f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh); 3851f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen region_t region = dm_rh_bio_to_region(ms->rh, bio); 38606386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow 3871f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen if (log->type->in_sync(log, region, 0)) 38806386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow return choose_mirror(ms, bio->bi_sector) ? 1 : 0; 38906386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow 39006386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow return 0; 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * remap a buffer to a particular mirror. 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 39606386bbfd2441416875d0403d405c56822f6ebacJonathan Brassowstatic sector_t map_sector(struct mirror *m, struct bio *bio) 39706386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow{ 39806386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow return m->offset + (bio->bi_sector - m->ms->ti->begin); 39906386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow} 40006386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow 40106386bbfd2441416875d0403d405c56822f6ebacJonathan Brassowstatic void map_bio(struct mirror *m, struct bio *bio) 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bio->bi_bdev = m->dev->bdev; 40406386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow bio->bi_sector = map_sector(m, bio); 40506386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow} 40606386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow 40722a1ceb1e6a7fbce95a1531ff10bb4fb036d4a37Heinz Mauelshagenstatic void map_region(struct dm_io_region *io, struct mirror *m, 40806386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow struct bio *bio) 40906386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow{ 41006386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow io->bdev = m->dev->bdev; 41106386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow io->sector = map_sector(m, bio); 41206386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow io->count = bio->bi_size >> 9; 41306386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow} 41406386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow 41506386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow/*----------------------------------------------------------------- 41606386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow * Reads 41706386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow *---------------------------------------------------------------*/ 41806386bbfd2441416875d0403d405c56822f6ebacJonathan Brassowstatic void read_callback(unsigned long error, void *context) 41906386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow{ 42006386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow struct bio *bio = context; 42106386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow struct mirror *m; 42206386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow 42306386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow m = bio_get_m(bio); 42406386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow bio_set_m(bio, NULL); 42506386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow 42606386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow if (likely(!error)) { 42706386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow bio_endio(bio, 0); 42806386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow return; 42906386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow } 43006386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow 43106386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow fail_mirror(m, DM_RAID1_READ_ERROR); 43206386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow 43306386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow if (likely(default_ok(m)) || mirror_available(m->ms, bio)) { 43406386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow DMWARN_LIMIT("Read failure on mirror device %s. " 43506386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow "Trying alternative device.", 43606386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow m->dev->name); 43706386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow queue_bio(m->ms, bio, bio_rw(bio)); 43806386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow return; 43906386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow } 44006386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow 44106386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow DMERR_LIMIT("Read failure on mirror device %s. Failing I/O.", 44206386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow m->dev->name); 44306386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow bio_endio(bio, -EIO); 44406386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow} 44506386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow 44606386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow/* Asynchronous read. */ 44706386bbfd2441416875d0403d405c56822f6ebacJonathan Brassowstatic void read_async_bio(struct mirror *m, struct bio *bio) 44806386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow{ 44922a1ceb1e6a7fbce95a1531ff10bb4fb036d4a37Heinz Mauelshagen struct dm_io_region io; 45006386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow struct dm_io_request io_req = { 45106386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow .bi_rw = READ, 45206386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow .mem.type = DM_IO_BVEC, 45306386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow .mem.ptr.bvec = bio->bi_io_vec + bio->bi_idx, 45406386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow .notify.fn = read_callback, 45506386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow .notify.context = bio, 45606386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow .client = m->ms->io_client, 45706386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow }; 45806386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow 45906386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow map_region(&io, m, bio); 46006386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow bio_set_m(bio, m); 4611f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen BUG_ON(dm_io(&io_req, 1, &io, NULL)); 4621f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen} 4631f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen 4641f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagenstatic inline int region_in_sync(struct mirror_set *ms, region_t region, 4651f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen int may_block) 4661f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen{ 4671f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen int state = dm_rh_get_state(ms->rh, region, may_block); 4681f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen return state == DM_RH_CLEAN || state == DM_RH_DIRTY; 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void do_reads(struct mirror_set *ms, struct bio_list *reads) 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds region_t region; 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct bio *bio; 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct mirror *m; 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while ((bio = bio_list_pop(reads))) { 4781f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen region = dm_rh_bio_to_region(ms->rh, bio); 47906386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow m = get_default_mirror(ms); 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We can only read balance if the region is in sync. 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4841f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen if (likely(region_in_sync(ms, region, 1))) 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds m = choose_mirror(ms, bio->bi_sector); 48606386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow else if (m && atomic_read(&m->error_count)) 48706386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow m = NULL; 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 48906386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow if (likely(m)) 49006386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow read_async_bio(m, bio); 49106386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow else 49206386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow bio_endio(bio, -EIO); 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*----------------------------------------------------------------- 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Writes. 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We do different things with the write io depending on the 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * state of the region that it's in: 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * SYNC: increment pending, use kcopyd to write to *all* mirrors 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * RECOVERING: delay the io until recovery completes 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NOSYNC: increment pending, just write to the default mirror 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *---------------------------------------------------------------*/ 50672f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow 50772f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void write_callback(unsigned long error, void *context) 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 51072f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow unsigned i, ret = 0; 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct bio *bio = (struct bio *) context; 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct mirror_set *ms; 51372f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow int uptodate = 0; 51472f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow int should_wake = 0; 51572f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow unsigned long flags; 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 51706386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow ms = bio_get_m(bio)->ms; 51806386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow bio_set_m(bio, NULL); 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NOTE: We don't decrement the pending count here, 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * instead it is done by the targets endio function. 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This way we handle both writes to SYNC and NOSYNC 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * regions with the same code. 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 52672f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow if (likely(!error)) 52772f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow goto out; 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 52972f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow for (i = 0; i < ms->nr_mirrors; i++) 53072f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow if (test_bit(i, &error)) 53172f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow fail_mirror(ms->mirror + i, DM_RAID1_WRITE_ERROR); 53272f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow else 53372f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow uptodate = 1; 53472f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow 53572f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow if (unlikely(!uptodate)) { 53672f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow DMERR("All replicated volumes dead, failing I/O"); 53772f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow /* None of the writes succeeded, fail the I/O. */ 53872f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow ret = -EIO; 53972f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow } else if (errors_handled(ms)) { 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 54172f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow * Need to raise event. Since raising 54272f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow * events can block, we need to do it in 54372f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow * the main thread. 5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 54572f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow spin_lock_irqsave(&ms->lock, flags); 54672f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow if (!ms->failures.head) 54772f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow should_wake = 1; 54872f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow bio_list_add(&ms->failures, bio); 54972f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow spin_unlock_irqrestore(&ms->lock, flags); 55072f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow if (should_wake) 5511f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen wakeup_mirrord(ms); 55272f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow return; 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 55472f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassowout: 55572f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow bio_endio(bio, ret); 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void do_write(struct mirror_set *ms, struct bio *bio) 5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int i; 56122a1ceb1e6a7fbce95a1531ff10bb4fb036d4a37Heinz Mauelshagen struct dm_io_region io[ms->nr_mirrors], *dest = io; 5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct mirror *m; 56388be163abb5324bab09f5eff9646590eec5314ebMilan Broz struct dm_io_request io_req = { 56488be163abb5324bab09f5eff9646590eec5314ebMilan Broz .bi_rw = WRITE, 56588be163abb5324bab09f5eff9646590eec5314ebMilan Broz .mem.type = DM_IO_BVEC, 56688be163abb5324bab09f5eff9646590eec5314ebMilan Broz .mem.ptr.bvec = bio->bi_io_vec + bio->bi_idx, 56788be163abb5324bab09f5eff9646590eec5314ebMilan Broz .notify.fn = write_callback, 56888be163abb5324bab09f5eff9646590eec5314ebMilan Broz .notify.context = bio, 56988be163abb5324bab09f5eff9646590eec5314ebMilan Broz .client = ms->io_client, 57088be163abb5324bab09f5eff9646590eec5314ebMilan Broz }; 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 57206386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow for (i = 0, m = ms->mirror; i < ms->nr_mirrors; i++, m++) 57306386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow map_region(dest++, m, bio); 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 57506386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow /* 57606386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow * Use default mirror because we only need it to retrieve the reference 57706386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow * to the mirror set in write_callback(). 57806386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow */ 57906386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow bio_set_m(bio, get_default_mirror(ms)); 58088be163abb5324bab09f5eff9646590eec5314ebMilan Broz 5811f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen BUG_ON(dm_io(&io_req, ms->nr_mirrors, io, NULL)); 5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void do_writes(struct mirror_set *ms, struct bio_list *writes) 5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int state; 5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct bio *bio; 5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct bio_list sync, nosync, recover, *this_list = NULL; 5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!writes->head) 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Classify each write. 5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bio_list_init(&sync); 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bio_list_init(&nosync); 5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bio_list_init(&recover); 5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while ((bio = bio_list_pop(writes))) { 6011f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen state = dm_rh_get_state(ms->rh, 6021f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen dm_rh_bio_to_region(ms->rh, bio), 1); 6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (state) { 6041f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen case DM_RH_CLEAN: 6051f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen case DM_RH_DIRTY: 6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds this_list = &sync; 6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6091f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen case DM_RH_NOSYNC: 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds this_list = &nosync; 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6131f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen case DM_RH_RECOVERING: 6141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds this_list = &recover; 6151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bio_list_add(this_list, bio); 6191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Increment the pending counts for any regions that will 6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * be written to (writes to recover regions are going to 6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * be delayed). 6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 6261f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen dm_rh_inc_pending(ms->rh, &sync); 6271f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen dm_rh_inc_pending(ms->rh, &nosync); 6281f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen ms->log_failure = dm_rh_flush(ms->rh) ? 1 : 0; 6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Dispatch io. 6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 633b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow if (unlikely(ms->log_failure)) { 634b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow spin_lock_irq(&ms->lock); 635b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow bio_list_merge(&ms->failures, &sync); 636b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow spin_unlock_irq(&ms->lock); 6371f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen wakeup_mirrord(ms); 638b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow } else 639fc1ff9588a6d56258ff9576a31aa34f17757c666Jonathan Brassow while ((bio = bio_list_pop(&sync))) 640b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow do_write(ms, bio); 6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while ((bio = bio_list_pop(&recover))) 6431f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen dm_rh_delay(ms->rh, bio); 6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while ((bio = bio_list_pop(&nosync))) { 64606386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow map_bio(get_default_mirror(ms), bio); 6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds generic_make_request(bio); 6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 6501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 65172f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassowstatic void do_failures(struct mirror_set *ms, struct bio_list *failures) 65272f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow{ 65372f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow struct bio *bio; 65472f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow 65572f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow if (!failures->head) 65672f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow return; 65772f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow 658b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow if (!ms->log_failure) { 659b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow while ((bio = bio_list_pop(failures))) 6601f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen ms->in_sync = 0; 6611f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen dm_rh_mark_nosync(ms->rh, bio, bio->bi_size, 0); 662b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow return; 663b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow } 664b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow 665b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow /* 666b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow * If the log has failed, unattempted writes are being 667b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow * put on the failures list. We can't issue those writes 668b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow * until a log has been marked, so we must store them. 669b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow * 670b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow * If a 'noflush' suspend is in progress, we can requeue 671b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow * the I/O's to the core. This give userspace a chance 672b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow * to reconfigure the mirror, at which point the core 673b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow * will reissue the writes. If the 'noflush' flag is 674b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow * not set, we have no choice but to return errors. 675b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow * 676b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow * Some writes on the failures list may have been 677b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow * submitted before the log failure and represent a 678b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow * failure to write to one of the devices. It is ok 679b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow * for us to treat them the same and requeue them 680b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow * as well. 681b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow */ 682b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow if (dm_noflush_suspending(ms->ti)) { 683b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow while ((bio = bio_list_pop(failures))) 684b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow bio_endio(bio, DM_ENDIO_REQUEUE); 685b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow return; 686b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow } 687b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow 688b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow if (atomic_read(&ms->suspend)) { 689b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow while ((bio = bio_list_pop(failures))) 690b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow bio_endio(bio, -EIO); 691b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow return; 692b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow } 693b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow 694b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow spin_lock_irq(&ms->lock); 695b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow bio_list_merge(&ms->failures, failures); 696b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow spin_unlock_irq(&ms->lock); 697b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow 698a2aebe03be60ae4da03507a00d60211d5e0327c3Mikulas Patocka delayed_wake(ms); 69972f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow} 70072f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow 70172f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassowstatic void trigger_event(struct work_struct *work) 70272f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow{ 70372f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow struct mirror_set *ms = 70472f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow container_of(work, struct mirror_set, trigger_event); 70572f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow 70672f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow dm_table_event(ms->ti->table); 70772f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow} 70872f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow 7091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*----------------------------------------------------------------- 7101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * kmirrord 7111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *---------------------------------------------------------------*/ 712a2aebe03be60ae4da03507a00d60211d5e0327c3Mikulas Patockastatic void do_mirror(struct work_struct *work) 7131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7141f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen struct mirror_set *ms = container_of(work, struct mirror_set, 7151f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen kmirrord_work); 71672f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow struct bio_list reads, writes, failures; 71772f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow unsigned long flags; 7181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 71972f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow spin_lock_irqsave(&ms->lock, flags); 7201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds reads = ms->reads; 7211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds writes = ms->writes; 72272f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow failures = ms->failures; 7231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bio_list_init(&ms->reads); 7241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bio_list_init(&ms->writes); 72572f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow bio_list_init(&ms->failures); 72672f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow spin_unlock_irqrestore(&ms->lock, flags); 7271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7281f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen dm_rh_update_states(ms->rh, errors_handled(ms)); 7291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds do_recovery(ms); 7301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds do_reads(ms, &reads); 7311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds do_writes(ms, &writes); 73272f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow do_failures(ms, &failures); 7337ff14a36159d947872870e7a3e9dcaebc46b23ebMikulas Patocka 7347ff14a36159d947872870e7a3e9dcaebc46b23ebMikulas Patocka dm_table_unplug_all(ms->ti->table); 7351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*----------------------------------------------------------------- 7381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Target functions 7391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *---------------------------------------------------------------*/ 7401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct mirror_set *alloc_context(unsigned int nr_mirrors, 7411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds uint32_t region_size, 7421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct dm_target *ti, 743416cd17b1982217bca3dc41b9f00b0b38fdaadadHeinz Mauelshagen struct dm_dirty_log *dl) 7441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 7451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size_t len; 7461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct mirror_set *ms = NULL; 7471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds len = sizeof(*ms) + (sizeof(ms->mirror[0]) * nr_mirrors); 7491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 750dd00cc486ab1c17049a535413d1751ef3482141cYoann Padioleau ms = kzalloc(len, GFP_KERNEL); 7511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!ms) { 75272d9486169a2a8353e022813185ba2f32d7dde69Alasdair G Kergon ti->error = "Cannot allocate mirror context"; 7531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 7541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds spin_lock_init(&ms->lock); 7571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ms->ti = ti; 7591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ms->nr_mirrors = nr_mirrors; 7601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ms->nr_regions = dm_sector_div_up(ti->len, region_size); 7611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ms->in_sync = 0; 762b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow ms->log_failure = 0; 763b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow atomic_set(&ms->suspend, 0); 76472f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow atomic_set(&ms->default_mirror, DEFAULT_MIRROR); 7651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 76606386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow len = sizeof(struct dm_raid1_read_record); 76706386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow ms->read_record_pool = mempool_create_kmalloc_pool(MIN_READ_RECORDS, 76806386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow len); 76906386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow if (!ms->read_record_pool) { 77006386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow ti->error = "Error creating mirror read_record_pool"; 77106386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow kfree(ms); 77206386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow return NULL; 77306386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow } 77406386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow 77588be163abb5324bab09f5eff9646590eec5314ebMilan Broz ms->io_client = dm_io_client_create(DM_IO_PAGES); 77688be163abb5324bab09f5eff9646590eec5314ebMilan Broz if (IS_ERR(ms->io_client)) { 77788be163abb5324bab09f5eff9646590eec5314ebMilan Broz ti->error = "Error creating dm_io client"; 77806386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow mempool_destroy(ms->read_record_pool); 77988be163abb5324bab09f5eff9646590eec5314ebMilan Broz kfree(ms); 78088be163abb5324bab09f5eff9646590eec5314ebMilan Broz return NULL; 78188be163abb5324bab09f5eff9646590eec5314ebMilan Broz } 78288be163abb5324bab09f5eff9646590eec5314ebMilan Broz 7831f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen ms->rh = dm_region_hash_create(ms, dispatch_bios, wakeup_mirrord, 7841f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen wakeup_all_recovery_waiters, 7851f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen ms->ti->begin, MAX_RECOVERY, 7861f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen dl, region_size, ms->nr_regions); 7871f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen if (IS_ERR(ms->rh)) { 78872d9486169a2a8353e022813185ba2f32d7dde69Alasdair G Kergon ti->error = "Error creating dirty region hash"; 789a72cf737e09da409e047863e38410930dae5fe05Dmitry Monakhov dm_io_client_destroy(ms->io_client); 79006386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow mempool_destroy(ms->read_record_pool); 7911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(ms); 7921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 7931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 7941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ms; 7961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 7971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 7981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void free_context(struct mirror_set *ms, struct dm_target *ti, 7991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int m) 8001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds while (m--) 8021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dm_put_device(ti, ms->mirror[m].dev); 8031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 80488be163abb5324bab09f5eff9646590eec5314ebMilan Broz dm_io_client_destroy(ms->io_client); 8051f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen dm_region_hash_destroy(ms->rh); 80606386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow mempool_destroy(ms->read_record_pool); 8071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds kfree(ms); 8081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline int _check_region_size(struct dm_target *ti, uint32_t size) 8111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8126f3c3f0afa50782dc1742c968646c491657d255avignesh babu return !(size % (PAGE_SIZE >> 9) || !is_power_of_2(size) || 8131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size > ti->len); 8141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int get_mirror(struct mirror_set *ms, struct dm_target *ti, 8171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int mirror, char **argv) 8181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8194ee218cd67b385759993a6c840ea45f0ee0a8b30Andrew Morton unsigned long long offset; 8201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8214ee218cd67b385759993a6c840ea45f0ee0a8b30Andrew Morton if (sscanf(argv[1], "%llu", &offset) != 1) { 82272d9486169a2a8353e022813185ba2f32d7dde69Alasdair G Kergon ti->error = "Invalid offset"; 8231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 8241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (dm_get_device(ti, argv[0], offset, ti->len, 8271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dm_table_get_mode(ti->table), 8281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds &ms->mirror[mirror].dev)) { 82972d9486169a2a8353e022813185ba2f32d7dde69Alasdair G Kergon ti->error = "Device lookup failure"; 8301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENXIO; 8311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 833aa5617c55357d86c9082ba1d66fa9795370c9954Jonathan Brassow ms->mirror[mirror].ms = ms; 83472f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow atomic_set(&(ms->mirror[mirror].error_count), 0); 83572f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow ms->mirror[mirror].error_type = 0; 8361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ms->mirror[mirror].offset = offset; 8371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 8391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 8421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Create dirty log: log_type #log_params <log_params> 8431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 844416cd17b1982217bca3dc41b9f00b0b38fdaadadHeinz Mauelshagenstatic struct dm_dirty_log *create_dirty_log(struct dm_target *ti, 8451f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen unsigned argc, char **argv, 8461f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen unsigned *args_used) 8471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 8481f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen unsigned param_count; 849416cd17b1982217bca3dc41b9f00b0b38fdaadadHeinz Mauelshagen struct dm_dirty_log *dl; 8501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (argc < 2) { 85272d9486169a2a8353e022813185ba2f32d7dde69Alasdair G Kergon ti->error = "Insufficient mirror log arguments"; 8531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 8541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (sscanf(argv[1], "%u", ¶m_count) != 1) { 85772d9486169a2a8353e022813185ba2f32d7dde69Alasdair G Kergon ti->error = "Invalid mirror log argument count"; 8581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 8591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *args_used = 2 + param_count; 8621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (argc < *args_used) { 86472d9486169a2a8353e022813185ba2f32d7dde69Alasdair G Kergon ti->error = "Insufficient mirror log arguments"; 8651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 8661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 868416cd17b1982217bca3dc41b9f00b0b38fdaadadHeinz Mauelshagen dl = dm_dirty_log_create(argv[0], ti, param_count, argv + 2); 8691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!dl) { 87072d9486169a2a8353e022813185ba2f32d7dde69Alasdair G Kergon ti->error = "Error creating mirror dirty log"; 8711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 8721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!_check_region_size(ti, dl->type->get_region_size(dl))) { 87572d9486169a2a8353e022813185ba2f32d7dde69Alasdair G Kergon ti->error = "Invalid region size"; 876416cd17b1982217bca3dc41b9f00b0b38fdaadadHeinz Mauelshagen dm_dirty_log_destroy(dl); 8771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return NULL; 8781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 8791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return dl; 8811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 8821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 883a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassowstatic int parse_features(struct mirror_set *ms, unsigned argc, char **argv, 884a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow unsigned *args_used) 885a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow{ 886a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow unsigned num_features; 887a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow struct dm_target *ti = ms->ti; 888a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow 889a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow *args_used = 0; 890a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow 891a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow if (!argc) 892a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow return 0; 893a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow 894a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow if (sscanf(argv[0], "%u", &num_features) != 1) { 895a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow ti->error = "Invalid number of features"; 896a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow return -EINVAL; 897a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow } 898a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow 899a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow argc--; 900a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow argv++; 901a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow (*args_used)++; 902a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow 903a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow if (num_features > argc) { 904a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow ti->error = "Not enough arguments to support feature count"; 905a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow return -EINVAL; 906a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow } 907a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow 908a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow if (!strcmp("handle_errors", argv[0])) 909a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow ms->features |= DM_RAID1_HANDLE_ERRORS; 910a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow else { 911a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow ti->error = "Unrecognised feature requested"; 912a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow return -EINVAL; 913a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow } 914a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow 915a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow (*args_used)++; 916a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow 917a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow return 0; 918a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow} 919a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow 9201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 9211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Construct a mirror mapping: 9221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 9231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * log_type #log_params <log_params> 9241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * #mirrors [mirror_path offset]{2,} 925a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow * [#features <features>] 9261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 9271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * log_type is "core" or "disk" 9281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * #log_params is between 1 and 3 929a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow * 930a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow * If present, features must be "handle_errors". 9311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 9321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv) 9331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 9341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int r; 9351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int nr_mirrors, m, args_used; 9361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct mirror_set *ms; 937416cd17b1982217bca3dc41b9f00b0b38fdaadadHeinz Mauelshagen struct dm_dirty_log *dl; 9381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds dl = create_dirty_log(ti, argc, argv, &args_used); 9401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!dl) 9411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 9421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds argv += args_used; 9441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds argc -= args_used; 9451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!argc || sscanf(argv[0], "%u", &nr_mirrors) != 1 || 947eb69aca5d3370b81450d68edeebc2bb9a3eb9689Heinz Mauelshagen nr_mirrors < 2 || nr_mirrors > DM_KCOPYD_MAX_REGIONS + 1) { 94872d9486169a2a8353e022813185ba2f32d7dde69Alasdair G Kergon ti->error = "Invalid number of mirrors"; 949416cd17b1982217bca3dc41b9f00b0b38fdaadadHeinz Mauelshagen dm_dirty_log_destroy(dl); 9501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 9511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds argv++, argc--; 9541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 955a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow if (argc < nr_mirrors * 2) { 956a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow ti->error = "Too few mirror arguments"; 957416cd17b1982217bca3dc41b9f00b0b38fdaadadHeinz Mauelshagen dm_dirty_log_destroy(dl); 9581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EINVAL; 9591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ms = alloc_context(nr_mirrors, dl->type->get_region_size(dl), ti, dl); 9621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!ms) { 963416cd17b1982217bca3dc41b9f00b0b38fdaadadHeinz Mauelshagen dm_dirty_log_destroy(dl); 9641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -ENOMEM; 9651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Get the mirror parameter sets */ 9681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (m = 0; m < nr_mirrors; m++) { 9691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r = get_mirror(ms, ti, m, argv); 9701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (r) { 9711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free_context(ms, ti, m); 9721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return r; 9731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds argv += 2; 9751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds argc -= 2; 9761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 9771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ti->private = ms; 9791f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen ti->split_io = dm_rh_get_region_size(ms->rh); 9801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 9816ad36fe2b451cc85cc7b14f4128286759e217124Holger Smolinski ms->kmirrord_wq = create_singlethread_workqueue("kmirrord"); 9826ad36fe2b451cc85cc7b14f4128286759e217124Holger Smolinski if (!ms->kmirrord_wq) { 9836ad36fe2b451cc85cc7b14f4128286759e217124Holger Smolinski DMERR("couldn't start kmirrord"); 984a72cf737e09da409e047863e38410930dae5fe05Dmitry Monakhov r = -ENOMEM; 985a72cf737e09da409e047863e38410930dae5fe05Dmitry Monakhov goto err_free_context; 9866ad36fe2b451cc85cc7b14f4128286759e217124Holger Smolinski } 9876ad36fe2b451cc85cc7b14f4128286759e217124Holger Smolinski INIT_WORK(&ms->kmirrord_work, do_mirror); 988a2aebe03be60ae4da03507a00d60211d5e0327c3Mikulas Patocka init_timer(&ms->timer); 989a2aebe03be60ae4da03507a00d60211d5e0327c3Mikulas Patocka ms->timer_pending = 0; 99072f4b314100bae85c75d8e4c6fec621ab44e777dJonathan Brassow INIT_WORK(&ms->trigger_event, trigger_event); 9916ad36fe2b451cc85cc7b14f4128286759e217124Holger Smolinski 992a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow r = parse_features(ms, argc, argv, &args_used); 993a72cf737e09da409e047863e38410930dae5fe05Dmitry Monakhov if (r) 994a72cf737e09da409e047863e38410930dae5fe05Dmitry Monakhov goto err_destroy_wq; 995a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow 996a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow argv += args_used; 997a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow argc -= args_used; 998a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow 999f44db678edcc6f4c2779ac43f63f0b9dfa28b724Jonathan Brassow /* 1000f44db678edcc6f4c2779ac43f63f0b9dfa28b724Jonathan Brassow * Any read-balancing addition depends on the 1001f44db678edcc6f4c2779ac43f63f0b9dfa28b724Jonathan Brassow * DM_RAID1_HANDLE_ERRORS flag being present. 1002f44db678edcc6f4c2779ac43f63f0b9dfa28b724Jonathan Brassow * This is because the decision to balance depends 1003f44db678edcc6f4c2779ac43f63f0b9dfa28b724Jonathan Brassow * on the sync state of a region. If the above 1004f44db678edcc6f4c2779ac43f63f0b9dfa28b724Jonathan Brassow * flag is not present, we ignore errors; and 1005f44db678edcc6f4c2779ac43f63f0b9dfa28b724Jonathan Brassow * the sync state may be inaccurate. 1006f44db678edcc6f4c2779ac43f63f0b9dfa28b724Jonathan Brassow */ 1007f44db678edcc6f4c2779ac43f63f0b9dfa28b724Jonathan Brassow 1008a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow if (argc) { 1009a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow ti->error = "Too many mirror arguments"; 1010a72cf737e09da409e047863e38410930dae5fe05Dmitry Monakhov r = -EINVAL; 1011a72cf737e09da409e047863e38410930dae5fe05Dmitry Monakhov goto err_destroy_wq; 1012a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow } 1013a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow 10141f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen r = dm_kcopyd_client_create(DM_KCOPYD_PAGES, &ms->kcopyd_client); 1015a72cf737e09da409e047863e38410930dae5fe05Dmitry Monakhov if (r) 1016a72cf737e09da409e047863e38410930dae5fe05Dmitry Monakhov goto err_destroy_wq; 10171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10181f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen wakeup_mirrord(ms); 10191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1020a72cf737e09da409e047863e38410930dae5fe05Dmitry Monakhov 1021a72cf737e09da409e047863e38410930dae5fe05Dmitry Monakhoverr_destroy_wq: 1022a72cf737e09da409e047863e38410930dae5fe05Dmitry Monakhov destroy_workqueue(ms->kmirrord_wq); 1023a72cf737e09da409e047863e38410930dae5fe05Dmitry Monakhoverr_free_context: 1024a72cf737e09da409e047863e38410930dae5fe05Dmitry Monakhov free_context(ms, ti, ms->nr_mirrors); 1025a72cf737e09da409e047863e38410930dae5fe05Dmitry Monakhov return r; 10261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void mirror_dtr(struct dm_target *ti) 10291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct mirror_set *ms = (struct mirror_set *) ti->private; 10311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1032a2aebe03be60ae4da03507a00d60211d5e0327c3Mikulas Patocka del_timer_sync(&ms->timer); 10336ad36fe2b451cc85cc7b14f4128286759e217124Holger Smolinski flush_workqueue(ms->kmirrord_wq); 1034eb69aca5d3370b81450d68edeebc2bb9a3eb9689Heinz Mauelshagen dm_kcopyd_client_destroy(ms->kcopyd_client); 10356ad36fe2b451cc85cc7b14f4128286759e217124Holger Smolinski destroy_workqueue(ms->kmirrord_wq); 10361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds free_context(ms, ti, ms->nr_mirrors); 10371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 10401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Mirror mapping function 10411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 10421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int mirror_map(struct dm_target *ti, struct bio *bio, 10431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds union map_info *map_context) 10441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int r, rw = bio_rw(bio); 10461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct mirror *m; 10471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct mirror_set *ms = ti->private; 104806386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow struct dm_raid1_read_record *read_record = NULL; 10491f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh); 10501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (rw == WRITE) { 105206386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow /* Save region for mirror_end_io() handler */ 10531f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen map_context->ll = dm_rh_bio_to_region(ms->rh, bio); 10541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds queue_bio(ms, bio, rw); 1055d2a7ad29a810441e9dacbaddcc2f0c6045390008Kiyoshi Ueda return DM_MAPIO_SUBMITTED; 10561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10581f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen r = log->type->in_sync(log, dm_rh_bio_to_region(ms->rh, bio), 0); 10591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (r < 0 && r != -EWOULDBLOCK) 10601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return r; 10611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 106306386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow * If region is not in-sync queue the bio. 10641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 106506386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow if (!r || (r == -EWOULDBLOCK)) { 106606386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow if (rw == READA) 106706386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow return -EWOULDBLOCK; 10681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds queue_bio(ms, bio, rw); 1070d2a7ad29a810441e9dacbaddcc2f0c6045390008Kiyoshi Ueda return DM_MAPIO_SUBMITTED; 10711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 10721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 107306386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow /* 107406386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow * The region is in-sync and we can perform reads directly. 107506386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow * Store enough information so we can retry if it fails. 107606386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow */ 10771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds m = choose_mirror(ms, bio->bi_sector); 107806386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow if (unlikely(!m)) 10791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -EIO; 10801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 108106386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow read_record = mempool_alloc(ms->read_record_pool, GFP_NOIO); 108206386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow if (likely(read_record)) { 108306386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow dm_bio_record(&read_record->details, bio); 108406386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow map_context->ptr = read_record; 108506386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow read_record->m = m; 108606386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow } 108706386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow 108806386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow map_bio(m, bio); 108906386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow 1090d2a7ad29a810441e9dacbaddcc2f0c6045390008Kiyoshi Ueda return DM_MAPIO_REMAPPED; 10911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 10921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 10931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int mirror_end_io(struct dm_target *ti, struct bio *bio, 10941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int error, union map_info *map_context) 10951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 10961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int rw = bio_rw(bio); 10971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct mirror_set *ms = (struct mirror_set *) ti->private; 109806386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow struct mirror *m = NULL; 109906386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow struct dm_bio_details *bd = NULL; 110006386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow struct dm_raid1_read_record *read_record = map_context->ptr; 11011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 11031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We need to dec pending if this was a write. 11041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 110506386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow if (rw == WRITE) { 11061f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen dm_rh_dec(ms->rh, map_context->ll); 110706386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow return error; 110806386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow } 11091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 111006386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow if (error == -EOPNOTSUPP) 111106386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow goto out; 111206386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow 111306386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow if ((error == -EWOULDBLOCK) && bio_rw_ahead(bio)) 111406386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow goto out; 111506386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow 111606386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow if (unlikely(error)) { 111706386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow if (!read_record) { 111806386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow /* 111906386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow * There wasn't enough memory to record necessary 112006386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow * information for a retry or there was no other 112106386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow * mirror in-sync. 112206386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow */ 1123e03f1a842287480aa03732612148c0d333baca61Adrian Bunk DMERR_LIMIT("Mirror read failed."); 112406386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow return -EIO; 112506386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow } 1126e03f1a842287480aa03732612148c0d333baca61Adrian Bunk 1127e03f1a842287480aa03732612148c0d333baca61Adrian Bunk m = read_record->m; 1128e03f1a842287480aa03732612148c0d333baca61Adrian Bunk 112906386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow DMERR("Mirror read failed from %s. Trying alternative device.", 113006386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow m->dev->name); 113106386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow 113206386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow fail_mirror(m, DM_RAID1_READ_ERROR); 113306386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow 113406386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow /* 113506386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow * A failed read is requeued for another attempt using an intact 113606386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow * mirror. 113706386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow */ 113806386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow if (default_ok(m) || mirror_available(ms, bio)) { 113906386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow bd = &read_record->details; 114006386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow 114106386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow dm_bio_restore(bd, bio); 114206386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow mempool_free(read_record, ms->read_record_pool); 114306386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow map_context->ptr = NULL; 114406386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow queue_bio(ms, bio, rw); 114506386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow return 1; 114606386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow } 114706386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow DMERR("All replicated volumes dead, failing I/O"); 114806386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow } 114906386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow 115006386bbfd2441416875d0403d405c56822f6ebacJonathan Brassowout: 115106386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow if (read_record) { 115206386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow mempool_free(read_record, ms->read_record_pool); 115306386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow map_context->ptr = NULL; 115406386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow } 115506386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow 115606386bbfd2441416875d0403d405c56822f6ebacJonathan Brassow return error; 11571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1159b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassowstatic void mirror_presuspend(struct dm_target *ti) 11601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 11611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct mirror_set *ms = (struct mirror_set *) ti->private; 11621f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh); 11631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1164b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow atomic_set(&ms->suspend, 1); 1165b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow 1166b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow /* 1167b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow * We must finish up all the work that we've 1168b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow * generated (i.e. recovery work). 1169b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow */ 11701f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen dm_rh_stop_recovery(ms->rh); 117133184048dc4f9d5550d3b6a88c8e0ff92033eb6eJonathan E Brassow 117233184048dc4f9d5550d3b6a88c8e0ff92033eb6eJonathan E Brassow wait_event(_kmirrord_recovery_stopped, 11731f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen !dm_rh_recovery_in_flight(ms->rh)); 117433184048dc4f9d5550d3b6a88c8e0ff92033eb6eJonathan E Brassow 1175b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow if (log->type->presuspend && log->type->presuspend(log)) 1176b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow /* FIXME: need better error handling */ 1177b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow DMWARN("log presuspend failed"); 1178b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow 1179b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow /* 1180b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow * Now that recovery is complete/stopped and the 1181b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow * delayed bios are queued, we need to wait for 1182b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow * the worker thread to complete. This way, 1183b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow * we know that all of our I/O has been pushed. 1184b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow */ 1185b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow flush_workqueue(ms->kmirrord_wq); 1186b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow} 1187b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow 1188b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassowstatic void mirror_postsuspend(struct dm_target *ti) 1189b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow{ 1190b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow struct mirror_set *ms = ti->private; 11911f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh); 1192b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow 11936b3df0d7a5e85ad2afd3eecc50e2dee59e876ae8Jonathan Brassow if (log->type->postsuspend && log->type->postsuspend(log)) 11941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* FIXME: need better error handling */ 1195b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow DMWARN("log postsuspend failed"); 11961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 11971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 11981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void mirror_resume(struct dm_target *ti) 11991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1200b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow struct mirror_set *ms = ti->private; 12011f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh); 1202b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow 1203b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow atomic_set(&ms->suspend, 0); 12041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (log->type->resume && log->type->resume(log)) 12051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* FIXME: need better error handling */ 12061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DMWARN("log resume failed"); 12071f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen dm_rh_start_recovery(ms->rh); 12081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1210af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassow/* 1211af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassow * device_status_char 1212af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassow * @m: mirror device/leg we want the status of 1213af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassow * 1214af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassow * We return one character representing the most severe error 1215af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassow * we have encountered. 1216af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassow * A => Alive - No failures 1217af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassow * D => Dead - A write failure occurred leaving mirror out-of-sync 1218af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassow * S => Sync - A sychronization failure occurred, mirror out-of-sync 1219af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassow * R => Read - A read failure occurred, mirror data unaffected 1220af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassow * 1221af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassow * Returns: <char> 1222af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassow */ 1223af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassowstatic char device_status_char(struct mirror *m) 1224af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassow{ 1225af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassow if (!atomic_read(&(m->error_count))) 1226af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassow return 'A'; 1227af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassow 1228af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassow return (test_bit(DM_RAID1_WRITE_ERROR, &(m->error_type))) ? 'D' : 1229af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassow (test_bit(DM_RAID1_SYNC_ERROR, &(m->error_type))) ? 'S' : 1230af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassow (test_bit(DM_RAID1_READ_ERROR, &(m->error_type))) ? 'R' : 'U'; 1231af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassow} 1232af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassow 1233af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassow 12341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int mirror_status(struct dm_target *ti, status_type_t type, 12351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char *result, unsigned int maxlen) 12361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1237315dcc226f066c1d3cef79283dcde807fe0e32d1Jonathan E Brassow unsigned int m, sz = 0; 12381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct mirror_set *ms = (struct mirror_set *) ti->private; 12391f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen struct dm_dirty_log *log = dm_rh_dirty_log(ms->rh); 1240af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassow char buffer[ms->nr_mirrors + 1]; 12411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (type) { 12431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case STATUSTYPE_INFO: 12441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DMEMIT("%d ", ms->nr_mirrors); 1245af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassow for (m = 0; m < ms->nr_mirrors; m++) { 12461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DMEMIT("%s ", ms->mirror[m].dev->name); 1247af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassow buffer[m] = device_status_char(&(ms->mirror[m])); 1248af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassow } 1249af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassow buffer[m] = '\0'; 12501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1251af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassow DMEMIT("%llu/%llu 1 %s ", 12521f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen (unsigned long long)log->type->get_sync_count(log), 1253af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassow (unsigned long long)ms->nr_regions, buffer); 1254315dcc226f066c1d3cef79283dcde807fe0e32d1Jonathan E Brassow 12551f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen sz += log->type->status(log, type, result+sz, maxlen-sz); 1256315dcc226f066c1d3cef79283dcde807fe0e32d1Jonathan E Brassow 12571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 12581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case STATUSTYPE_TABLE: 12601f965b19437017cea6d3f3f46acdc5acae5fd011Heinz Mauelshagen sz = log->type->status(log, type, result, maxlen); 1261315dcc226f066c1d3cef79283dcde807fe0e32d1Jonathan E Brassow 1262e52b8f6dbe18c879ad2b5013f991ec9e46813043Jonathan Brassow DMEMIT("%d", ms->nr_mirrors); 12631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (m = 0; m < ms->nr_mirrors; m++) 1264e52b8f6dbe18c879ad2b5013f991ec9e46813043Jonathan Brassow DMEMIT(" %s %llu", ms->mirror[m].dev->name, 1265b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow (unsigned long long)ms->mirror[m].offset); 1266a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow 1267a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow if (ms->features & DM_RAID1_HANDLE_ERRORS) 1268a8e6afa2363de7ee0dea1a3297f6236f421c2dd4Jonathan E Brassow DMEMIT(" 1 handle_errors"); 12691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 12701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 12721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct target_type mirror_target = { 12751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .name = "mirror", 1276af195ac82e38ba802fd86b5a014ed05ef6dd88bbJonathan Brassow .version = {1, 0, 20}, 12771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .module = THIS_MODULE, 12781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .ctr = mirror_ctr, 12791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .dtr = mirror_dtr, 12801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .map = mirror_map, 12811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .end_io = mirror_end_io, 1282b80aa7a0c268d3ae0c472f648af1e3e4a359765cJonathan Brassow .presuspend = mirror_presuspend, 12831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .postsuspend = mirror_postsuspend, 12841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .resume = mirror_resume, 12851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .status = mirror_status, 12861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 12871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init dm_mirror_init(void) 12891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 12901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int r; 12911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r = dm_register_target(&mirror_target); 1293769aef30f0f505c44bbe9fcd2c911a052a386139Heinz Mauelshagen if (r < 0) 12940cd3312434cd1f29bee6bff53bf2790d733ad2a2Alasdair G Kergon DMERR("Failed to register mirror target"); 12951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return r; 12971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 12981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __exit dm_mirror_exit(void) 13001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 13011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int r; 13021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds r = dm_unregister_target(&mirror_target); 13041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (r < 0) 13050cd3312434cd1f29bee6bff53bf2790d733ad2a2Alasdair G Kergon DMERR("unregister failed %d", r); 13061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 13071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Module hooks */ 13091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_init(dm_mirror_init); 13101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmodule_exit(dm_mirror_exit); 13111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 13121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_DESCRIPTION(DM_NAME " mirror target"); 13131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_AUTHOR("Joe Thornber"); 13141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 1315