Hello, I wrote a module to change the underlying block_device of a bio structure. It works, but the first processed page is always filled with junk. All the remaining pages are processed correctly. I tried it under a 2.6.8 and a 2.6.19 kernel. Does anybody has an idea what could be wrong? Thanks and regards, Jochen --- /** * * Test module to play around with the bio structure in order to * redirect a READ from one block device to another. * * **/ #define MAJOR_NR 241 #define KERNEL_SECTOR_SIZE 512 #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/init.h> #include <linux/syscalls.h> #include <linux/blkdev.h> #include <linux/bio.h> #include <linux/slab.h> /* kmalloc */ #include <linux/kernel.h> /* printk() */ #include <linux/fs.h> /* everything */ #include <linux/errno.h> /* error codes */ #include <linux/types.h> /* size_t */ #include <linux/vmalloc.h> #include <linux/genhd.h> #include <linux/hdreg.h> #include <linux/interrupt.h> #include <linux/delay.h> /* udelay(int); */ #include <linux/spinlock.h> #include <linux/ioctl.h> MODULE_LICENSE("GPL"); /* The sector size of the block device. */ static int sect_size = 512; struct pseudo_device { char * name; spinlock_t lock; struct request_queue *queue; struct gendisk *gendisk; struct block_device *bdev; }; // the test device struct pseudo_device *pd; int register_device(struct pseudo_device *); static int pd_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { return 0; } static int pd_open(struct inode *inode, struct file *file) { return 0; } static struct block_device_operations pd_ops = { .owner = THIS_MODULE, .ioctl = pd_ioctl, .open = pd_open }; static int pd_transfer_request(struct pseudo_device *pd, struct request *req) { struct bio *bio; struct bio *cloned_bio; int nsect = 0; printk(KERN_WARNING "pd: pd_transfer_request\n"); rq_for_each_bio(bio, req) { // Extend the bio. //extended = extend_bio(bio, pd_device); //bio -> bi_bdev = pd_device -> bdev; cloned_bio = bio_clone(bio, GFP_NOIO); cloned_bio -> bi_private = bio; cloned_bio -> bi_bdev = pd -> bdev; if(bio_data_dir(cloned_bio) == WRITE) { submit_bio(WRITE, cloned_bio); } else { submit_bio(READ, cloned_bio); } nsect += cloned_bio->bi_size/KERNEL_SECTOR_SIZE; } return nsect; } static void pd_full_request(request_queue_t *q) { struct request *req; int sectors_xferred; struct pseudo_device *pd = q->queuedata; printk(KERN_WARNING "pd: pd_full_request\n"); while ((req = elv_next_request(q)) != NULL) { if (! blk_fs_request(req)) { printk (KERN_NOTICE "Skip non-fs request\n"); end_request(req, 0); continue; } sectors_xferred = pd_transfer_request(pd, req); if (! end_that_request_first(req, 1, sectors_xferred)) { blkdev_dequeue_request(req); end_that_request_last(req, 0); } } } static int pd_init(void) { printk(KERN_INFO "pd: Initialize pseudo module\n"); pd = kmalloc(sizeof(struct pseudo_device), GFP_KERNEL); memset(pd, 0, sizeof(*pd)); pd -> name = "pd1"; spin_lock_init(&pd->lock); //pd->queue = blk_init_queue(pd_full_request, &pd->lock); pd -> bdev = open_bdev_excl("/dev/sdb", 00000002, NULL); pd -> gendisk = alloc_disk(1); if(!pd -> gendisk) { printk(KERN_WARNING "pd: alloc_disk failure for control device.\n"); goto abort; } pd -> gendisk -> major = MAJOR_NR; pd -> gendisk -> first_minor = 0; pd -> gendisk -> fops = &pd_ops; pd -> gendisk -> private_data = &pd; strcpy(pd->gendisk -> disk_name, pd -> name); set_capacity(pd -> gendisk, (pd->bdev->bd_disk->capacity)); spin_lock_init(&pd -> lock); if( (pd -> queue = blk_init_queue(pd_full_request, &pd -> lock)) == NULL) { printk(KERN_WARNING "pd: register: no queue\n"); goto abort; } blk_queue_hardsect_size(pd -> queue, sect_size); pd -> queue -> queuedata = pd; pd -> gendisk -> queue = pd -> queue; add_disk(pd -> gendisk); /* Create device node in /dev/ */ /** * mknod seems not to work in kernel land. * "mknod /dev/pd1 b 241 0" does the job in the console. */ return 0; abort: return -1; } static void pd_exit(void) { printk(KERN_INFO "pd: Removing pseudo module from kernel\n"); if(pd -> gendisk) { del_gendisk(pd->gendisk); put_disk(pd->gendisk); } } module_init(pd_init); module_exit(pd_exit); My Makefile looks like this: obj-m += biomod.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean And after creating the device node with "mknod /dev/pd1 b 241 0", I try to read with: "dd if=/dev/pd1 of=./output count=2000" The error occurs, regardless of the values for count (and skip). - To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html