#include #include #include #define SIZE_IN_KBYTES 256 static int major; static struct gendisk *disk; static struct request_queue *bdqueue; static char *mempool; DEFINE_SPINLOCK(bdlock); static void bd_request(struct request_queue *q) { unsigned long start, to_copy; struct request *req = blk_fetch_request(q); while (req) { printk("req: %d - ", req->cmd_type); if (!blk_fs_request(req)) { if (!__blk_end_request_cur(req, 0)) req = blk_fetch_request(q); continue; } start = blk_rq_pos(req) << 9; // * 512 to_copy = blk_rq_cur_bytes(req); spin_unlock_irq(q->queue_lock); if ((start + to_copy) <= (SIZE_IN_KBYTES * 1024)) if (rq_data_dir(req) == READ) { printk("read %p %ld %lu\n", req->buffer, start, to_copy); memcpy(req->buffer, mempool + start, to_copy); } else { printk("write %ld %p %lu\n", start, req->buffer, to_copy); memcpy(mempool + start, req->buffer, to_copy); } else printk("%ld not in range ...\n", start + to_copy); spin_lock_irq(q->queue_lock); if (!__blk_end_request_cur(req, 0)) req = blk_fetch_request(q); else printk("followup: "); } } static struct block_device_operations bdops = { .owner = THIS_MODULE, }; static int __init mod_init(void) { if (!(major = register_blkdev(0,"bds"))) { printk("bd: can't get majornumber\n"); return -EIO; } printk("major: %d\n", major); if (!(mempool = vmalloc(SIZE_IN_KBYTES * 1024))) { printk("vmalloc failed ...\n"); goto out_no_mem; } if (!(disk = alloc_disk(1))) { printk("alloc_disk failed ...\n"); goto out; } disk->major = major; disk->first_minor = 0; sprintf(disk->disk_name, "bds0"); set_capacity(disk, (SIZE_IN_KBYTES * 1024) >> 9); // 512 Byte blocks disk->fops = &bdops; if (!(bdqueue = blk_init_queue(&bd_request, &bdlock))) goto out; blk_queue_logical_block_size(bdqueue, 512); disk->queue = bdqueue; add_disk(disk); return 0; out: vfree(mempool); out_no_mem: unregister_blkdev(major, "bds"); return -EIO; } static void __exit mod_exit(void) { unregister_blkdev(major, "bds"); del_gendisk(disk); put_disk(disk); blk_cleanup_queue(bdqueue); vfree(mempool); } module_init(mod_init); module_exit(mod_exit); MODULE_LICENSE("GPL");