From 94704ea51d3b522f7de88080837e4c1acc820816 Mon Sep 17 00:00:00 2001 From: Johann Latocha Date: Wed, 25 Jan 2012 21:30:58 +0100 Subject: [KERNEL] Multi device support --- src/kernel/blk.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 62 insertions(+), 9 deletions(-) (limited to 'src/kernel/blk.c') diff --git a/src/kernel/blk.c b/src/kernel/blk.c index 8a31841..213ae23 100644 --- a/src/kernel/blk.c +++ b/src/kernel/blk.c @@ -21,26 +21,79 @@ #include "blk.h" #include "net.h" +int dnbd3_blk_add_device(struct dnbd3_device *dev, int minor) +{ + struct gendisk *disk; + struct request_queue *blk_queue; + + init_waitqueue_head(&dev->process_queue_send); + init_waitqueue_head(&dev->process_queue_receive); + INIT_LIST_HEAD(&dev->request_queue_send); + INIT_LIST_HEAD(&dev->request_queue_receive); + + if (!(disk = alloc_disk(1))) + { + printk("ERROR: dnbd3 alloc_disk failed.\n"); + return -EIO; + } + + disk->major = major; + disk->first_minor = minor; + sprintf(disk->disk_name, "dnbd%d", minor); + set_capacity(disk, 0); + set_disk_ro(disk, 1); + disk->fops = &dnbd3_blk_ops; + + spin_lock_init(&dev->blk_lock); + if ((blk_queue = blk_init_queue(&dnbd3_blk_request, &dev->blk_lock)) == NULL) + { + printk("ERROR: dnbd3 blk_init_queue failed.\n"); + return -EIO; + } + + blk_queue_logical_block_size(blk_queue, DNBD3_BLOCK_SIZE); + disk->queue = blk_queue; + disk->private_data = dev; + queue_flag_set_unlocked(QUEUE_FLAG_NONROT, disk->queue); + dev->disk = disk; + + add_disk(disk); // must be last + return 0; +} + +int dnbd3_blk_del_device(struct dnbd3_device *dev) +{ + if (dev->sock) + sock_release(dev->sock); + + del_gendisk(dev->disk); + put_disk(dev->disk); + blk_cleanup_queue(dev->disk->queue); + return 0; +} + struct block_device_operations dnbd3_blk_ops = { .owner = THIS_MODULE, .ioctl = dnbd3_blk_ioctl, }; int dnbd3_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) { + struct dnbd3_device *lo = bdev->bd_disk->private_data; + switch (cmd) { case IOCTL_SET_HOST: - _host = (char *) arg; + lo->host = (char *) arg; break; case IOCTL_SET_PORT: - _port = (char *) arg; + lo->port = (char *) arg; break; case IOCTL_SET_IMAGE: - _image_id = (char *) arg; + lo->image_id = (char *) arg; break; case IOCTL_CONNECT: - dnbd3_net_connect(); + dnbd3_net_connect(lo); break; case BLKFLSBUF: break; @@ -55,12 +108,12 @@ int dnbd3_blk_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, void dnbd3_blk_request(struct request_queue *q) { struct request *req; - - if (!_sock) - return; + struct dnbd3_device *lo; while ((req = blk_fetch_request(q)) != NULL) { + lo = req->rq_disk->private_data; + if (req->cmd_type != REQ_TYPE_FS) { __blk_end_request_all(req, 0); @@ -69,9 +122,9 @@ void dnbd3_blk_request(struct request_queue *q) if (rq_data_dir(req) == READ) { - list_add_tail(&req->queuelist, &_request_queue_send); + list_add_tail(&req->queuelist, &lo->request_queue_send); spin_unlock_irq(q->queue_lock); - wake_up(&_process_queue_send); + wake_up(&lo->process_queue_send); spin_lock_irq(q->queue_lock); } } -- cgit v1.2.3-55-g7522