📄 vdisk-full.c
字号:
/* * vdisk.c - virtual disk driver * * Copyright 2008 (C) weiqin (qinwei1998@hotmail.com) * * This code is based in part on ramdisk driver , only for teching * * This software is distributed under the terms of the GNU General * Public License ("GPL") as published by the Free Software Foundation, * either version 2 of that License or (at your option) any later version. * */#include <linux/string.h>#include <linux/slab.h>#include <asm/atomic.h>#include <linux/bio.h>#include <linux/module.h>#include <linux/moduleparam.h>#include <linux/init.h>#include <linux/pagemap.h>#include <linux/blkdev.h>#include <linux/genhd.h>#include <linux/buffer_head.h> #include <linux/backing-dev.h>#include <linux/blkpg.h>#include <linux/writeback.h>#include <linux/vmalloc.h>#include <asm/uaccess.h>#ifdef VDISK_DEBUG#define dprintk(fmt, args...) printk(fmt, ## args)#else#define dprintk(fmt, args...) /* not debugging: nothing */#endif#define VDISK_MAJOR 254#define VDISK_SIZE (2*1024*1024)#define SECTOR_SIZE (512)/* Various static variables go here. Most are used only in the vdisk code. */struct vdisk_dev{ struct gendisk *vdisks; struct request_queue *vdisk_queue; struct block_device *vdisk_bdev; unsigned char * vdisk_mem; spinlock_t vdisk_lock; };static struct vdisk_dev my_vdisk;/* * Handle an I/O request. */static void vdisk_transfer(struct vdisk_dev *dev, unsigned long sector, unsigned long nsect, char *buffer, int write){ unsigned long offset = sector*SECTOR_SIZE; unsigned long nbytes = nsect*SECTOR_SIZE; if (write) memcpy(dev->vdisk_mem + offset, buffer, nbytes); else memcpy(buffer, dev->vdisk_mem + offset, nbytes);}static void vdisk_request(struct request_queue *q){ struct request *req; while ((req = elv_next_request(q)) != NULL) { struct vdisk_dev *dev = req->rq_disk->private_data; if (! blk_fs_request(req)) { printk (KERN_NOTICE "Skip non-fs request\n"); end_request(req, 0); continue; } vdisk_transfer(dev, req->sector, req->current_nr_sectors, req->buffer, rq_data_dir(req)); end_request(req, 1); }}static int vdisk_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){ return 0;}static int vdisk_open(struct inode *inode, struct file *filp){ struct block_device *bdev = inode->i_bdev; unsigned bsize; my_vdisk.vdisk_bdev = bdev; bsize = bdev_hardsect_size(bdev); bdev->bd_block_size = bsize; return 0;}static struct block_device_operations vdisk_bd_op = { .owner = THIS_MODULE, .open = vdisk_open, .ioctl = vdisk_ioctl,};/* * This is the registration and initialization section of the vdisk driver */static int vdisk_major = 0;static int __init vdisk_init(void){ int err = -ENOMEM; struct gendisk *disk; my_vdisk.vdisks = alloc_disk(1); if (!my_vdisk.vdisks) goto out; my_vdisk.vdisk_queue = blk_alloc_queue(GFP_KERNEL); if (!my_vdisk.vdisk_queue) { put_disk(my_vdisk.vdisks); goto out; } vdisk_major = register_blkdev(VDISK_MAJOR, "vdisk"); if ( vdisk_major<0 ) { put_disk(my_vdisk.vdisks); blk_cleanup_queue(my_vdisk.vdisk_queue); err = -EIO; goto out; } spin_lock_init(&my_vdisk.vdisk_lock); my_vdisk.vdisk_queue = blk_init_queue(vdisk_request, &my_vdisk.vdisk_lock); blk_queue_hardsect_size(my_vdisk.vdisk_queue, 512); my_vdisk.vdisk_queue->queuedata = &my_vdisk; my_vdisk.vdisk_mem = vmalloc(VDISK_SIZE); memset(my_vdisk.vdisk_mem, 0, VDISK_SIZE); disk = my_vdisk.vdisks; disk->major = VDISK_MAJOR; disk->first_minor = 0; disk->fops = &vdisk_bd_op; disk->queue = my_vdisk.vdisk_queue; disk->private_data = &my_vdisk;; disk->flags |= GENHD_FL_SUPPRESS_PARTITION_INFO; sprintf(disk->disk_name, "vdisk"); set_capacity(disk, VDISK_SIZE/SECTOR_SIZE); add_disk(my_vdisk.vdisks); printk("VDISK driver initialized, vdisk_major= %d\n", vdisk_major); return 0;out: put_disk(my_vdisk.vdisks); blk_cleanup_queue(my_vdisk.vdisk_queue); return err;}static void __exit vdisk_cleanup(void){ struct block_device *bdev = my_vdisk.vdisk_bdev; my_vdisk.vdisk_bdev = NULL; if (bdev) { invalidate_bdev(bdev); blkdev_put(bdev); } del_gendisk(my_vdisk.vdisks); put_disk(my_vdisk.vdisks); blk_cleanup_queue(my_vdisk.vdisk_queue); unregister_blkdev(VDISK_MAJOR, "vdisk");}module_init(vdisk_init);module_exit(vdisk_cleanup);MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -