@@ -568,27 +568,17 @@ static void do_nbd_request(struct request_queue * q)
568568 }
569569}
570570
571- static int nbd_ioctl (struct block_device * bdev , fmode_t mode ,
572- unsigned int cmd , unsigned long arg )
573- {
574- struct nbd_device * lo = bdev -> bd_disk -> private_data ;
575- struct file * file ;
576- int error ;
577- struct request sreq ;
578- struct task_struct * thread ;
579-
580- if (!capable (CAP_SYS_ADMIN ))
581- return - EPERM ;
582-
583- BUG_ON (lo -> magic != LO_MAGIC );
584-
585- /* Anyone capable of this syscall can do *real bad* things */
586- dprintk (DBG_IOCTL , "%s: nbd_ioctl cmd=%s(0x%x) arg=%lu\n" ,
587- lo -> disk -> disk_name , ioctl_cmd_to_ascii (cmd ), cmd , arg );
571+ /* Must be called with tx_lock held */
588572
573+ static int __nbd_ioctl (struct block_device * bdev , struct nbd_device * lo ,
574+ unsigned int cmd , unsigned long arg )
575+ {
589576 switch (cmd ) {
590- case NBD_DISCONNECT :
577+ case NBD_DISCONNECT : {
578+ struct request sreq ;
579+
591580 printk (KERN_INFO "%s: NBD_DISCONNECT\n" , lo -> disk -> disk_name );
581+
592582 blk_rq_init (NULL , & sreq );
593583 sreq .cmd_type = REQ_TYPE_SPECIAL ;
594584 nbd_cmd (& sreq ) = NBD_CMD_DISC ;
@@ -599,29 +589,29 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
599589 */
600590 sreq .sector = 0 ;
601591 sreq .nr_sectors = 0 ;
602- if (!lo -> sock )
592+ if (!lo -> sock )
603593 return - EINVAL ;
604- mutex_lock (& lo -> tx_lock );
605- nbd_send_req (lo , & sreq );
606- mutex_unlock (& lo -> tx_lock );
594+ nbd_send_req (lo , & sreq );
607595 return 0 ;
596+ }
608597
609- case NBD_CLEAR_SOCK :
610- error = 0 ;
611- mutex_lock ( & lo -> tx_lock );
598+ case NBD_CLEAR_SOCK : {
599+ struct file * file ;
600+
612601 lo -> sock = NULL ;
613- mutex_unlock (& lo -> tx_lock );
614602 file = lo -> file ;
615603 lo -> file = NULL ;
616604 nbd_clear_que (lo );
617605 BUG_ON (!list_empty (& lo -> queue_head ));
618606 if (file )
619607 fput (file );
620- return error ;
621- case NBD_SET_SOCK :
608+ return 0 ;
609+ }
610+
611+ case NBD_SET_SOCK : {
612+ struct file * file ;
622613 if (lo -> file )
623614 return - EBUSY ;
624- error = - EINVAL ;
625615 file = fget (arg );
626616 if (file ) {
627617 struct inode * inode = file -> f_path .dentry -> d_inode ;
@@ -630,48 +620,65 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
630620 lo -> sock = SOCKET_I (inode );
631621 if (max_part > 0 )
632622 bdev -> bd_invalidated = 1 ;
633- error = 0 ;
623+ return 0 ;
634624 } else {
635625 fput (file );
636626 }
637627 }
638- return error ;
628+ return - EINVAL ;
629+ }
630+
639631 case NBD_SET_BLKSIZE :
640632 lo -> blksize = arg ;
641633 lo -> bytesize &= ~(lo -> blksize - 1 );
642634 bdev -> bd_inode -> i_size = lo -> bytesize ;
643635 set_blocksize (bdev , lo -> blksize );
644636 set_capacity (lo -> disk , lo -> bytesize >> 9 );
645637 return 0 ;
638+
646639 case NBD_SET_SIZE :
647640 lo -> bytesize = arg & ~(lo -> blksize - 1 );
648641 bdev -> bd_inode -> i_size = lo -> bytesize ;
649642 set_blocksize (bdev , lo -> blksize );
650643 set_capacity (lo -> disk , lo -> bytesize >> 9 );
651644 return 0 ;
645+
652646 case NBD_SET_TIMEOUT :
653647 lo -> xmit_timeout = arg * HZ ;
654648 return 0 ;
649+
655650 case NBD_SET_SIZE_BLOCKS :
656651 lo -> bytesize = ((u64 ) arg ) * lo -> blksize ;
657652 bdev -> bd_inode -> i_size = lo -> bytesize ;
658653 set_blocksize (bdev , lo -> blksize );
659654 set_capacity (lo -> disk , lo -> bytesize >> 9 );
660655 return 0 ;
661- case NBD_DO_IT :
656+
657+ case NBD_DO_IT : {
658+ struct task_struct * thread ;
659+ struct file * file ;
660+ int error ;
661+
662662 if (lo -> pid )
663663 return - EBUSY ;
664664 if (!lo -> file )
665665 return - EINVAL ;
666+
667+ mutex_unlock (& lo -> tx_lock );
668+
666669 thread = kthread_create (nbd_thread , lo , lo -> disk -> disk_name );
667- if (IS_ERR (thread ))
670+ if (IS_ERR (thread )) {
671+ mutex_lock (& lo -> tx_lock );
668672 return PTR_ERR (thread );
673+ }
669674 wake_up_process (thread );
670675 error = nbd_do_it (lo );
671676 kthread_stop (thread );
677+
678+ mutex_lock (& lo -> tx_lock );
672679 if (error )
673680 return error ;
674- sock_shutdown (lo , 1 );
681+ sock_shutdown (lo , 0 );
675682 file = lo -> file ;
676683 lo -> file = NULL ;
677684 nbd_clear_que (lo );
@@ -684,21 +691,46 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
684691 if (max_part > 0 )
685692 ioctl_by_bdev (bdev , BLKRRPART , 0 );
686693 return lo -> harderror ;
694+ }
695+
687696 case NBD_CLEAR_QUE :
688697 /*
689698 * This is for compatibility only. The queue is always cleared
690699 * by NBD_DO_IT or NBD_CLEAR_SOCK.
691700 */
692701 BUG_ON (!lo -> sock && !list_empty (& lo -> queue_head ));
693702 return 0 ;
703+
694704 case NBD_PRINT_DEBUG :
695705 printk (KERN_INFO "%s: next = %p, prev = %p, head = %p\n" ,
696706 bdev -> bd_disk -> disk_name ,
697707 lo -> queue_head .next , lo -> queue_head .prev ,
698708 & lo -> queue_head );
699709 return 0 ;
700710 }
701- return - EINVAL ;
711+ return - ENOTTY ;
712+ }
713+
714+ static int nbd_ioctl (struct block_device * bdev , fmode_t mode ,
715+ unsigned int cmd , unsigned long arg )
716+ {
717+ struct nbd_device * lo = bdev -> bd_disk -> private_data ;
718+ int error ;
719+
720+ if (!capable (CAP_SYS_ADMIN ))
721+ return - EPERM ;
722+
723+ BUG_ON (lo -> magic != LO_MAGIC );
724+
725+ /* Anyone capable of this syscall can do *real bad* things */
726+ dprintk (DBG_IOCTL , "%s: nbd_ioctl cmd=%s(0x%x) arg=%lu\n" ,
727+ lo -> disk -> disk_name , ioctl_cmd_to_ascii (cmd ), cmd , arg );
728+
729+ mutex_lock (& lo -> tx_lock );
730+ error = __nbd_ioctl (bdev , lo , cmd , arg );
731+ mutex_unlock (& lo -> tx_lock );
732+
733+ return error ;
702734}
703735
704736static struct block_device_operations nbd_fops =
0 commit comments