diff -urN generic-map-ref/drivers/block/ll_rw_blk.c generic-map/drivers/block/ll_rw_blk.c --- generic-map-ref/drivers/block/ll_rw_blk.c Wed Nov 29 18:42:58 2000 +++ generic-map/drivers/block/ll_rw_blk.c Wed Nov 29 18:44:23 2000 @@ -26,13 +26,6 @@ #include -#if defined CONFIG_BLK_DEV_LVM || defined CONFIG_BLK_DEV_LVM_MODULE -#include - /* function pointer to the LVM driver remapping function - which will be setup during driver/module init; neccessary - to be able to load LVM as a module */ -int (*lvm_map_ptr) (struct buffer_head *, int) = NULL; -#endif /* * The request-struct contains all necessary data @@ -804,7 +797,7 @@ { unsigned int major; int correct_size; - struct blk_dev_struct * dev; + struct blk_dev_struct * dev, * tdev = NULL; int i; /* Make sure that the first block contains something reasonable */ @@ -817,7 +810,7 @@ dev = NULL; if ((major = MAJOR(bh[0]->b_dev)) < MAX_BLKDEV) dev = blk_dev + major; - if (!dev || !dev->request_fn) { + if (!dev || (!dev->request_fn && !dev->makerq_fn && !dev->map_fn)) { printk(KERN_ERR "ll_rw_block: Trying to read nonexistent block-device %s (%ld)\n", kdevname(bh[0]->b_dev), bh[0]->b_blocknr); @@ -833,47 +826,38 @@ /* Verify requested block sizes. */ for (i = 0; i < nr; i++) { - if (bh[i] && bh[i]->b_size != correct_size) { + if (bh[i]->b_size != correct_size) { printk(KERN_NOTICE "ll_rw_block: device %s: " "only %d-char blocks implemented (%lu)\n", kdevname(bh[0]->b_dev), correct_size, bh[i]->b_size); goto sorry; } + /* LVM and MD remap blocks now */ -#if defined CONFIG_BLK_DEV_LVM || defined CONFIG_BLK_DEV_LVM_MODULE - major = MAJOR(bh[i]->b_dev); - if (major == LVM_BLK_MAJOR) { - if (lvm_map_ptr == NULL) { - printk(KERN_ERR - "Bad lvm_map_ptr in ll_rw_block\n"); - goto sorry; - } - if ((lvm_map_ptr) (bh[i], rw) != 0) { - printk(KERN_ERR - "Bad lvm_map in ll_rw_block\n"); - goto sorry; - } - /* remap major too ... */ - major = MAJOR(bh[i]->b_rdev); - } else { - bh[i]->b_rdev = bh[i]->b_dev; - bh[i]->b_rsector = bh[i]->b_blocknr * (bh[i]->b_size >> 9); - } -#else bh[i]->b_rdev = bh[i]->b_dev; bh[i]->b_rsector=bh[i]->b_blocknr*(bh[i]->b_size >> 9); -#endif -#ifdef CONFIG_BLK_DEV_MD - if (major==MD_MAJOR && - /* changed v to allow LVM to remap */ - md_map (MINOR(bh[i]->b_rdev), &bh[i]->b_rdev, - &bh[i]->b_rsector, bh[i]->b_size >> 9)) { - printk (KERN_ERR - "Bad md_map in ll_rw_block\n"); - goto sorry; + + tdev = dev; + while (tdev->map_fn) { + kdev_t __rdev = bh[i]->b_rdev; + unsigned long __rsector = bh[i]->b_rsector; + + if (tdev->map_fn (bh[i]->b_rdev, &bh[i]->b_rdev, + &bh[i]->b_rsector, + bh[i]->b_size >> 9, rw)) { + printk (KERN_ERR "Bad map in ll_rw_block\n"); + goto sorry; + } + if (__rdev == bh[i]->b_rdev && + __rsector == bh[i]->b_rsector) + /* + * Break the loop if map_fn is a noop + * as it happens with raid1. + */ + break; + tdev = blk_dev + MAJOR(bh[i]->b_rdev); } -#endif } if ((rw == WRITE || rw == WRITEA) && is_read_only(bh[0]->b_dev)) { @@ -883,18 +867,12 @@ } for (i = 0; i < nr; i++) { - if (bh[i]) { - set_bit(BH_Req, &bh[i]->b_state); -#ifdef CONFIG_BLK_DEV_MD - /* changed v to allow LVM to remap */ - if (MAJOR(bh[i]->b_rdev) == MD_MAJOR) { - /* remap device for MD too v */ - md_make_request(MINOR (bh[i]->b_rdev), rw, bh[i]); - continue; - } -#endif - make_request(MAJOR(bh[i]->b_rdev), rw, bh[i]); + set_bit(BH_Req, &bh[i]->b_state); + if (tdev->makerq_fn) { + tdev->makerq_fn(bh[i], rw); + continue; } + make_request(MAJOR(bh[i]->b_rdev), rw, bh[i]); } return; @@ -975,6 +953,8 @@ dev->request_fn = NULL; dev->queue = NULL; dev->current_request = NULL; + dev->map_fn = NULL; + dev->makerq_fn = NULL; dev->plug.rq_status = RQ_INACTIVE; dev->plug.cmd = -1; dev->plug.next = NULL; diff -urN generic-map-ref/drivers/block/lvm.c generic-map/drivers/block/lvm.c --- generic-map-ref/drivers/block/lvm.c Wed Nov 29 18:42:58 2000 +++ generic-map/drivers/block/lvm.c Wed Nov 29 18:44:23 2000 @@ -241,13 +241,12 @@ * Internal function prototypes */ static void lvm_init_vars ( void); -extern int (*lvm_map_ptr) ( struct buffer_head*, int); #ifdef LVM_HD_NAME extern void (*lvm_hd_name_ptr) ( char*, int); #endif -static int lvm_map ( struct buffer_head*, int); +static int lvm_map (kdev_t, kdev_t *, unsigned long *, unsigned long, int); static int do_vg_create ( int, void *); static int do_vg_remove ( int); static int do_lv_create ( int, char *, lv_t *); @@ -405,9 +404,6 @@ lvm_gendisk.next = NULL; } - /* reference from drivers/block/ll_rw_blk.c */ - lvm_map_ptr = lvm_map; - #ifdef LVM_HD_NAME /* reference from drivers/block/genhd.c */ lvm_hd_name_ptr = lvm_hd_name; @@ -418,6 +414,8 @@ #else blk_dev[MAJOR_NR].request_fn = lvm_dummy_device_request; blk_dev[MAJOR_NR].current_request = NULL; + blk_dev[MAJOR_NR].makerq_fn = NULL; + blk_dev[MAJOR_NR].map_fn = lvm_map; #endif /* optional read root VGDA */ @@ -480,6 +478,8 @@ #else blk_dev[MAJOR_NR].request_fn = NULL; blk_dev[MAJOR_NR].current_request = NULL; + blk_dev[MAJOR_NR].makerq_fn = NULL; + blk_dev[MAJOR_NR].map_fn = NULL; #endif gendisk_ptr = gendisk_ptr_prev = gendisk_head; @@ -502,9 +502,6 @@ # endif #endif - /* reference from linux/drivers/block/ll_rw_blk.c */ - lvm_map_ptr = NULL; - #ifdef LVM_HD_NAME /* reference from linux/drivers/block/genhd.c */ lvm_hd_name_ptr = NULL; @@ -1573,14 +1570,13 @@ * block device support function for /usr/src/linux/drivers/block/ll_rw_blk.c * (see init_module/lvm_init) */ -static int lvm_map ( struct buffer_head *bh, int rw) { - int minor = MINOR ( bh->b_dev); +static int lvm_map (kdev_t rdev_tmp, kdev_t * rdev_out, + unsigned long * rsector_out, unsigned long size, int rw) { + int minor = MINOR (rdev_tmp); int ret = 0; ulong index; - ulong size = bh->b_size >> 9; - ulong rsector_tmp = bh->b_blocknr * size; + ulong rsector_tmp = *rsector_out; ulong rsector_sav; - kdev_t rdev_tmp = bh->b_dev; kdev_t rdev_sav; lv_t *lv = vg[VG_BLK(minor)]->lv[LV_BLK(minor)]; unsigned long pe_start; @@ -1598,19 +1594,6 @@ printk ( "%s -- %02d:%02d block: %lu rw: %d\n", lvm_name, MAJOR ( bh->b_dev), MINOR ( bh->b_dev), bh->b_blocknr, rw); */ - /* take care of snapshot chunk writes before - check for writable logical volume */ - if ( ( lv->lv_access & LV_SNAPSHOT) && - MAJOR ( bh->b_dev) != 0 && - MAJOR ( bh->b_dev) != MAJOR_NR && - ( rw == WRITEA || rw == WRITE)) - { -/* -printk ( "%s -- doing snapshot write for %02d:%02d[%02d:%02d] b_blocknr: %lu b_rsector: %lu\n", lvm_name, MAJOR ( bh->b_dev), MINOR ( bh->b_dev), MAJOR ( bh->b_dev), MINOR ( bh->b_dev), bh->b_blocknr, bh->b_rsector); -*/ - return 0; - } - if ( ( rw == WRITE || rw == WRITEA) && ! ( lv->lv_access & LV_WRITE)) { printk ( KERN_CRIT @@ -1752,8 +1735,8 @@ } } - bh->b_rdev = rdev_tmp; - bh->b_rsector = rsector_tmp; + *rdev_out = rdev_tmp; + *rsector_out = rsector_tmp; return ret; } /* lvm_map () */ diff -urN generic-map-ref/drivers/block/md.c generic-map/drivers/block/md.c --- generic-map-ref/drivers/block/md.c Wed Nov 29 18:42:58 2000 +++ generic-map/drivers/block/md.c Wed Nov 29 18:43:06 2000 @@ -758,8 +758,10 @@ block_fsync }; -int md_map (int minor, kdev_t *rdev, unsigned long *rsector, unsigned long size) +int md_map (kdev_t dev, kdev_t *rdev, unsigned long *rsector, unsigned long size, int rw) { + int minor = MINOR(dev); + if ((unsigned int) minor >= MAX_MD_DEV) { printk ("Bad md device %d\n", minor); @@ -775,8 +777,10 @@ return (md_dev[minor].pers->map(md_dev+minor, rdev, rsector, size)); } -int md_make_request (int minor, int rw, struct buffer_head * bh) +int md_make_request (struct buffer_head * bh, int rw) { + int minor = MINOR(bh->b_rdev); + if (md_dev [minor].pers->make_request) { if (buffer_locked(bh)) return 0; @@ -1321,6 +1325,8 @@ blk_dev[MD_MAJOR].request_fn=DEVICE_REQUEST; blk_dev[MD_MAJOR].current_request=NULL; + blk_dev[MD_MAJOR].makerq_fn=md_make_request; + blk_dev[MD_MAJOR].map_fn=md_map; read_ahead[MD_MAJOR]=INT_MAX; memset(md_dev, 0, MAX_MD_DEV * sizeof (struct md_dev)); md_gendisk.next=gendisk_head; diff -urN generic-map-ref/drivers/block/raid1.c generic-map/drivers/block/raid1.c --- generic-map-ref/drivers/block/raid1.c Wed Nov 29 18:42:58 2000 +++ generic-map/drivers/block/raid1.c Wed Nov 29 18:43:06 2000 @@ -191,7 +191,7 @@ map_and_make_request (int rw, struct buffer_head *bh) { if (MAJOR (bh->b_rdev) == MD_MAJOR) - md_map (MINOR (bh->b_rdev), &bh->b_rdev, &bh->b_rsector, bh->b_size >> 9); + md_map (bh->b_rdev, &bh->b_rdev, &bh->b_rsector, bh->b_size >> 9, rw); clear_bit(BH_Lock, &bh->b_state); make_request (MAJOR (bh->b_rdev), rw, bh); } diff -urN generic-map-ref/include/linux/blkdev.h generic-map/include/linux/blkdev.h --- generic-map-ref/include/linux/blkdev.h Wed Nov 29 18:42:58 2000 +++ generic-map/include/linux/blkdev.h Wed Nov 29 18:43:06 2000 @@ -36,6 +36,8 @@ }; typedef void (request_fn_proc) (void); +typedef int (makerq_fn_proc) (struct buffer_head *, int rw); +typedef int (map_fn_proc) (kdev_t, kdev_t *, unsigned long *, unsigned long, int); typedef struct request ** (queue_proc) (kdev_t dev); typedef struct elevator_s @@ -66,6 +68,8 @@ struct blk_dev_struct { request_fn_proc *request_fn; + makerq_fn_proc *makerq_fn; + map_fn_proc *map_fn; /* * queue_proc has to be atomic */ @@ -90,9 +94,6 @@ extern void unplug_device(void * data); extern void make_request(int major,int rw, struct buffer_head * bh); -/* md needs this function to remap requests */ -extern int md_map (int minor, kdev_t *rdev, unsigned long *rsector, unsigned long size); -extern int md_make_request (int minor, int rw, struct buffer_head * bh); extern int md_error (kdev_t mddev, kdev_t rdev); extern int * blk_size[MAX_BLKDEV]; diff -urN generic-map-ref/include/linux/md.h generic-map/include/linux/md.h --- generic-map-ref/include/linux/md.h Wed Nov 29 18:42:58 2000 +++ generic-map/include/linux/md.h Wed Nov 29 18:43:06 2000 @@ -295,6 +295,7 @@ extern void md_wakeup_thread(struct md_thread *thread); extern int md_update_sb (int minor); extern int md_do_sync(struct md_dev *mddev); +extern int md_map (kdev_t dev, kdev_t *rdev, unsigned long *rsector, unsigned long size, int rw); #endif __KERNEL__ #endif _MD_H diff -urN generic-map-ref/kernel/ksyms.c generic-map/kernel/ksyms.c --- generic-map-ref/kernel/ksyms.c Wed Nov 29 18:42:58 2000 +++ generic-map/kernel/ksyms.c Wed Nov 29 18:43:06 2000 @@ -86,10 +86,7 @@ EXPORT_SYMBOL(get_options); #ifdef CONFIG_BLK_DEV_LVM_MODULE - extern int (*lvm_map_ptr) ( int, kdev_t *, unsigned long *, - unsigned long, int); extern void (*lvm_hd_name_ptr) ( char*, int); - EXPORT_SYMBOL(lvm_map_ptr); EXPORT_SYMBOL(lvm_hd_name_ptr); #endif