支持"制造请求",“请求队列”,
static void setup_device(struct vmem_disk_dev *dev,int which)
{
memset(dev,0,sizeof(struct vmem_disk_dev));
dev->size = NSECTORS*HARDSECT_SIZE;
dev->data = vmalloc(dev->size);
if(dev->data = NULL)
{
printk(KERN_NOTICE"vmalloc failure.\n");
return;
}
spin_lock_init(&dev->lock);
swicth(request_mode)
{
case VMEMD_NOQUEUE:
dev->queue = blk_alloc_queue(GFP_KERNEL);
if(dev->queue ==NULL)
{
goto out_vfree;
}
blk_queue_make_request(dev->queue,vmem_disk_make_rquest);
break;
default:
printk(KERN_NOTICE"Bad request mode %d,using simple\n",request_mode);
case VMEMD_QUEUE:
dev->queue = blk_init_queue(vmeme_disk_request,&dev->lock);
if(dev->queue == NULL)
{
goto out_vfree;
}
break;
}
blk_queue_logical_block_size(dev->queue,HARDSECT_SIZE);
dev->queue->queuedata = dev;
dev->gd = alloc_disk(VMEM_DISK_MINORS);
if(!dev->gd)
{
printk(KERNEL_NOTICE"alloc_disk failure\n");
goto out_vfree;
}
dev->gd->major = vmem_disk_major;
dev->gd->first_minor = which * VMEM_DISK_MINORS;
dev->gd->fops = &vmem_disk_ops;
dev->gd->queue = dev->queue;
dev->gd_private_data = dev;
snprintf(dev->gd->disk_name,32,"vmem_disk%c,which + "a");
set_capacuty(dev->gd,NSECTORS*(HARDSECT_SIZE/KERNEL_SECTOR_SIZE));
add_disk(dev->gd);
return;
out_vfree:
if(dev->data)
{
vfree(dev->data);
}
}
static int __init vmem_disk_init(void)
{
int i;
vmem_disk_major = register_blkdev(vmem_disk_major,"vmem_disk");//块设备注册函数
if(vmem_disk_major <= 0)
{
printk(KERN_WARNING"vmem_disk:unable to get major number\n");
return -EBUSY;
}
devices = kmalloc(NDEVICES *sizeof(struct vmem_disk_dev),GFP_KERNEL);
if(!devices)
{
goto out_unregister;
}
for(i = 0; i< NDEVICES; i++)
{
setup_device(devices + i, i);
}
return 0;
out_unregister:
unregister_blkdev(vmem_disk_major,"sbd");
return -ENOMEM;
}
module_init(vmem_disk_init);
我们实际上支持两种I/O请求模式,一种是make_rqueust
,另一种是request_queue
。make_request
的版本直接使用vmem_disk_make_request()
来处理bio,而request_queue
的版本则使用vmem_disk_request
来处理请求队列。