]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/block/nbd.c
nbd: do not allow two clients at the same time
[linux-2.6-omap-h63xx.git] / drivers / block / nbd.c
index 9034ca585afd710d6425d53f7b6357c13357a6af..34f80fa6fed16d379733e3db018f765831e09778 100644 (file)
@@ -406,6 +406,7 @@ static int nbd_do_it(struct nbd_device *lo)
        ret = sysfs_create_file(&disk_to_dev(lo->disk)->kobj, &pid_attr.attr);
        if (ret) {
                printk(KERN_ERR "nbd: sysfs_create_file failed!");
+               lo->pid = 0;
                return ret;
        }
 
@@ -413,6 +414,7 @@ static int nbd_do_it(struct nbd_device *lo)
                nbd_end_request(req);
 
        sysfs_remove_file(&disk_to_dev(lo->disk)->kobj, &pid_attr.attr);
+       lo->pid = 0;
        return 0;
 }
 
@@ -557,10 +559,11 @@ static void do_nbd_request(struct request_queue * q)
        }
 }
 
-static int nbd_ioctl(struct inode *inode, struct file *file,
+static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
                     unsigned int cmd, unsigned long arg)
 {
-       struct nbd_device *lo = inode->i_bdev->bd_disk->private_data;
+       struct nbd_device *lo = bdev->bd_disk->private_data;
+       struct file *file;
        int error;
        struct request sreq ;
        struct task_struct *thread;
@@ -612,8 +615,7 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
                error = -EINVAL;
                file = fget(arg);
                if (file) {
-                       struct block_device *bdev = inode->i_bdev;
-                       inode = file->f_path.dentry->d_inode;
+                       struct inode *inode = file->f_path.dentry->d_inode;
                        if (S_ISSOCK(inode->i_mode)) {
                                lo->file = file;
                                lo->sock = SOCKET_I(inode);
@@ -628,14 +630,14 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
        case NBD_SET_BLKSIZE:
                lo->blksize = arg;
                lo->bytesize &= ~(lo->blksize-1);
-               inode->i_bdev->bd_inode->i_size = lo->bytesize;
-               set_blocksize(inode->i_bdev, lo->blksize);
+               bdev->bd_inode->i_size = lo->bytesize;
+               set_blocksize(bdev, lo->blksize);
                set_capacity(lo->disk, lo->bytesize >> 9);
                return 0;
        case NBD_SET_SIZE:
                lo->bytesize = arg & ~(lo->blksize-1);
-               inode->i_bdev->bd_inode->i_size = lo->bytesize;
-               set_blocksize(inode->i_bdev, lo->blksize);
+               bdev->bd_inode->i_size = lo->bytesize;
+               set_blocksize(bdev, lo->blksize);
                set_capacity(lo->disk, lo->bytesize >> 9);
                return 0;
        case NBD_SET_TIMEOUT:
@@ -643,11 +645,13 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
                return 0;
        case NBD_SET_SIZE_BLOCKS:
                lo->bytesize = ((u64) arg) * lo->blksize;
-               inode->i_bdev->bd_inode->i_size = lo->bytesize;
-               set_blocksize(inode->i_bdev, lo->blksize);
+               bdev->bd_inode->i_size = lo->bytesize;
+               set_blocksize(bdev, lo->blksize);
                set_capacity(lo->disk, lo->bytesize >> 9);
                return 0;
        case NBD_DO_IT:
+               if (lo->pid)
+                       return -EBUSY;
                if (!lo->file)
                        return -EINVAL;
                thread = kthread_create(nbd_thread, lo, lo->disk->disk_name);
@@ -666,10 +670,10 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
                if (file)
                        fput(file);
                lo->bytesize = 0;
-               inode->i_bdev->bd_inode->i_size = 0;
+               bdev->bd_inode->i_size = 0;
                set_capacity(lo->disk, 0);
                if (max_part > 0)
-                       ioctl_by_bdev(inode->i_bdev, BLKRRPART, 0);
+                       ioctl_by_bdev(bdev, BLKRRPART, 0);
                return lo->harderror;
        case NBD_CLEAR_QUE:
                /*
@@ -680,7 +684,7 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
                return 0;
        case NBD_PRINT_DEBUG:
                printk(KERN_INFO "%s: next = %p, prev = %p, head = %p\n",
-                       inode->i_bdev->bd_disk->disk_name,
+                       bdev->bd_disk->disk_name,
                        lo->queue_head.next, lo->queue_head.prev,
                        &lo->queue_head);
                return 0;
@@ -691,7 +695,7 @@ static int nbd_ioctl(struct inode *inode, struct file *file,
 static struct block_device_operations nbd_fops =
 {
        .owner =        THIS_MODULE,
-       .ioctl =        nbd_ioctl,
+       .locked_ioctl = nbd_ioctl,
 };
 
 /*
@@ -722,7 +726,6 @@ static int __init nbd_init(void)
 
        for (i = 0; i < nbds_max; i++) {
                struct gendisk *disk = alloc_disk(1 << part_shift);
-               elevator_t *old_e;
                if (!disk)
                        goto out;
                nbd_dev[i].disk = disk;
@@ -736,11 +739,10 @@ static int __init nbd_init(void)
                        put_disk(disk);
                        goto out;
                }
-               old_e = disk->queue->elevator;
-               if (elevator_init(disk->queue, "deadline") == 0 ||
-                       elevator_init(disk->queue, "noop") == 0) {
-                               elevator_exit(old_e);
-               }
+               /*
+                * Tell the block layer that we are not a rotational device
+                */
+               queue_flag_set_unlocked(QUEUE_FLAG_NONROT, disk->queue);
        }
 
        if (register_blkdev(NBD_MAJOR, "nbd")) {