Index: sn/drbd/drbd_receiver.c =================================================================== --- sn/drbd/drbd_receiver.c (revision 11983) +++ sn/drbd/drbd_receiver.c (revision 11984) @@ -1065,7 +1065,7 @@ return ok; } -STATIC int recv_resync_read(drbd_dev *mdev,sector_t sector, int data_size) +STATIC int recv_resync_read(drbd_dev *mdev,sector_t sector,int data_size) { struct Tl_epoch_entry *e; @@ -1089,7 +1089,7 @@ INFO("submit EE (RS)WRITE sec=%llus size=%u ee=%p\n", (unsigned long long)e->sector,e->size,e); ); - drbd_generic_make_request(WRITE,DRBD_FAULT_RS_WR,e->private_bio); + drbd_generic_make_request(mdev,WRITE,DRBD_FAULT_RS_WR,e->private_bio); /* accounting done in endio */ maybe_kick_lo(mdev); @@ -1587,7 +1587,7 @@ (unsigned long long)e->sector,e->size,e); ); /* FIXME drbd_al_begin_io in case we have two primaries... */ - drbd_generic_make_request(WRITE,DRBD_FAULT_DT_WR,e->private_bio); + drbd_generic_make_request(mdev,WRITE,DRBD_FAULT_DT_WR,e->private_bio); /* accounting done in endio */ maybe_kick_lo(mdev); @@ -1683,7 +1683,7 @@ (unsigned long long)e->sector,e->size,e); ); /* FIXME actually, it could be a READA originating from the peer ... */ - drbd_generic_make_request(READ,fault_type,e->private_bio); + drbd_generic_make_request(mdev,READ,fault_type,e->private_bio); maybe_kick_lo(mdev); return TRUE; Index: sn/drbd/drbd_actlog.c =================================================================== --- sn/drbd/drbd_actlog.c (revision 11983) +++ sn/drbd/drbd_actlog.c (revision 11984) @@ -34,7 +34,8 @@ * ;) * this is mostly from drivers/md/md.c */ -STATIC int _drbd_md_sync_page_io(struct drbd_backing_dev *bdev, +STATIC int _drbd_md_sync_page_io(drbd_dev *mdev, + struct drbd_backing_dev *bdev, struct page *page, sector_t sector, int rw, int size) { @@ -50,7 +51,7 @@ bio->bi_private = &event; bio->bi_end_io = drbd_md_io_complete; - if (FAULT_ACTIVE((rw & WRITE)? DRBD_FAULT_MD_WR:DRBD_FAULT_MD_RD)) { + if (FAULT_ACTIVE(mdev, (rw & WRITE)? DRBD_FAULT_MD_WR:DRBD_FAULT_MD_RD)) { bio->bi_rw |= rw; bio_endio(bio,bio->bi_size,-EIO); } @@ -112,7 +113,7 @@ void *p = page_address(mdev->md_io_page); void *hp = page_address(mdev->md_io_tmpp); - ok = _drbd_md_sync_page_io(bdev,iop, + ok = _drbd_md_sync_page_io(mdev, bdev,iop, sector,READ,hardsect); if (unlikely(!ok)) { @@ -137,7 +138,7 @@ (unsigned long long)sector, rw ? "WRITE" : "READ"); } - ok = _drbd_md_sync_page_io(bdev,iop,sector,rw,hardsect); + ok = _drbd_md_sync_page_io(mdev, bdev,iop,sector,rw,hardsect); if (unlikely(!ok)) { ERR("drbd_md_sync_page_io(,%llus,%s) failed!\n", (unsigned long long)sector,rw ? "WRITE" : "READ"); @@ -683,7 +684,7 @@ /* all prepared, submit them */ for(i=0; bios[i]; i++) { - if (FAULT_ACTIVE( DRBD_FAULT_MD_WR )) { + if (FAULT_ACTIVE( mdev, DRBD_FAULT_MD_WR )) { bios[i]->bi_rw = WRITE; bio_endio(bios[i],bios[i]->bi_size,-EIO); } else { Index: sn/drbd/drbd_compat_wrappers.h =================================================================== --- sn/drbd/drbd_compat_wrappers.h (revision 11983) +++ sn/drbd/drbd_compat_wrappers.h (revision 11984) @@ -120,18 +120,19 @@ /* * used to submit our private bio */ -static inline void drbd_generic_make_request(int rw, int fault_type, struct bio *bio) +static inline void drbd_generic_make_request(drbd_dev *mdev, int rw, int fault_type, struct bio *bio) { bio->bi_rw = rw; // on the receiver side, e->..rw was not yet defined. if (!bio->bi_bdev) { - printk(KERN_ERR "drbd_generic_make_request: bio->bi_bdev == NULL\n"); + printk(KERN_ERR DEVICE_NAME "%d: drbd_generic_make_request: bio->bi_bdev == NULL\n", + mdev_to_minor(mdev)); dump_stack(); bio_endio(bio, bio->bi_size, -ENODEV); return; } - if (FAULT_ACTIVE(fault_type)) + if (FAULT_ACTIVE(mdev, fault_type)) bio_endio(bio,bio->bi_size,-EIO); else generic_make_request(bio); Index: sn/drbd/drbd_bitmap.c =================================================================== --- sn/drbd/drbd_bitmap.c (revision 11983) +++ sn/drbd/drbd_bitmap.c (revision 11984) @@ -654,7 +654,7 @@ bio->bi_private = b; bio->bi_end_io = drbd_bm_async_io_complete; - if (FAULT_ACTIVE((rw&WRITE)?DRBD_FAULT_MD_WR:DRBD_FAULT_MD_RD)) { + if (FAULT_ACTIVE(mdev, (rw&WRITE)?DRBD_FAULT_MD_WR:DRBD_FAULT_MD_RD)) { bio->bi_rw |= rw; bio_endio(bio,bio->bi_size,-EIO); } Index: sn/drbd/drbd_main.c =================================================================== --- sn/drbd/drbd_main.c (revision 11983) +++ sn/drbd/drbd_main.c (revision 11984) @@ -96,9 +96,11 @@ int enable_faults = 0; int fault_rate; int fault_count; +int fault_devs; module_param(enable_faults,int,0664); // bitmap of enabled faults module_param(fault_rate,int,0664); // fault rate % value - applies to all enabled faults module_param(fault_count,int,0664); // count of faults inserted +module_param(fault_devs,int,0644); // bitmap of devices to insert faults on #endif // module parameter, defined @@ -2880,18 +2882,19 @@ } unsigned int -_drbd_insert_fault(unsigned int type) +_drbd_insert_fault(drbd_dev *mdev, unsigned int type) { static struct fault_random_state rrs = {0,0}; - unsigned int rnd = ((_drbd_fault_random(&rrs) % 100) + 1); - unsigned int ret = (rnd <= fault_rate); + unsigned int ret = ( + (fault_devs == 0 || ((1 << mdev_to_minor(mdev)) & fault_devs) != 0) && + (((_drbd_fault_random(&rrs) % 100) + 1) <= fault_rate)); if (ret) { fault_count++; if (printk_ratelimit()) - printk(KERN_ALERT "Simulating %s failure\n", _drbd_fault_str(type)); + WARN("***Simulating %s failure\n", _drbd_fault_str(type)); } return ret; Index: sn/drbd/drbd_req.c =================================================================== --- sn/drbd/drbd_req.c (revision 11983) +++ sn/drbd/drbd_req.c (revision 11984) @@ -1011,9 +1011,9 @@ * was not detached below us? */ req->private_bio->bi_bdev = mdev->bc->backing_bdev; - if (FAULT_ACTIVE(rw==WRITE ? DRBD_FAULT_DT_WR : - ( rw==READ ? DRBD_FAULT_DT_RD : - DRBD_FAULT_DT_RA ) )) + if (FAULT_ACTIVE(mdev, rw==WRITE ? DRBD_FAULT_DT_WR : + ( rw==READ ? DRBD_FAULT_DT_RD : + DRBD_FAULT_DT_RA ) )) bio_endio(req->private_bio, req->private_bio->bi_size, -EIO); else generic_make_request(req->private_bio); Index: sn/drbd/drbd_int.h =================================================================== --- sn/drbd/drbd_int.h (revision 11983) +++ sn/drbd/drbd_int.h (revision 11984) @@ -48,6 +48,7 @@ #ifdef DRBD_ENABLE_FAULTS extern int enable_faults; extern int fault_rate; +extern int fault_devs; #endif #include @@ -208,12 +209,17 @@ }; #ifdef DRBD_ENABLE_FAULTS -#define FAULT_ACTIVE(_t) \ - (fault_rate && (enable_faults & (1<<(_t))) && _drbd_insert_fault(_t)) +extern unsigned int _drbd_insert_fault(drbd_dev *mdev, unsigned int type); +static inline int +drbd_insert_fault(drbd_dev *mdev, unsigned int type) { + return (fault_rate && + (enable_faults & (1<