/* * Copyright (C) 2003 Sistina Software Limited. * Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved. * * This file is released under the GPL. */#include"dm-bio-list.h"#include"dm-bio-record.h"#include<linux/init.h>#include<linux/mempool.h>#include<linux/module.h>#include<linux/pagemap.h>#include<linux/slab.h>#include<linux/workqueue.h>#include<linux/device-mapper.h>#include<linux/dm-io.h>#include<linux/dm-dirty-log.h>#include<linux/dm-kcopyd.h>#include<linux/dm-region-hash.h>#define DM_MSG_PREFIX "raid1"#define MAX_RECOVERY 1 /* Maximum number of regions recovered in parallel. */#define DM_IO_PAGES 64#define DM_KCOPYD_PAGES 64#define DM_RAID1_HANDLE_ERRORS 0x01#define errors_handled(p) ((p)->features & DM_RAID1_HANDLE_ERRORS)staticDECLARE_WAIT_QUEUE_HEAD(_kmirrord_recovery_stopped);/*----------------------------------------------------------------- * Mirror set structures. *---------------------------------------------------------------*/enumdm_raid1_error{DM_RAID1_WRITE_ERROR,DM_RAID1_SYNC_ERROR,DM_RAID1_READ_ERROR};structmirror{structmirror_set*ms;atomic_terror_count;unsignedlongerror_type;structdm_dev*dev;sector_toffset;};structmirror_set{structdm_target*ti;structlist_headlist;uint64_tfeatures;spinlock_tlock;/* protects the lists */structbio_listreads;structbio_listwrites;structbio_listfailures;structdm_region_hash*rh;structdm_kcopyd_client*kcopyd_client;structdm_io_client*io_client;mempool_t*read_record_pool;/* recovery */region_tnr_regions;intin_sync;intlog_failure;atomic_tsuspend;atomic_tdefault_mirror;/* Default mirror */structworkqueue_struct*kmirrord_wq;structwork_structkmirrord_work;structtimer_listtimer;unsignedlongtimer_pending;structwork_structtrigger_event;unsignednr_mirrors;structmirrormirror[0];};staticvoidwakeup_mirrord(void*context){structmirror_set*ms=context;queue_work(ms->kmirrord_wq,&ms->kmirrord_work);}staticvoiddelayed_wake_fn(unsignedlongdata){structmirror_set*ms=(structmirror_set*)data;clear_bit(0,&ms->timer_pending);wakeup_mirrord(ms);}staticvoiddelayed_wake(structmirror_set*ms){if(test_and_set_bit(0