@@ -568,27 +568,17 @@ static void do_nbd_request(struct request_queue * q)
568
568
}
569
569
}
570
570
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 */
588
572
573
+ static int __nbd_ioctl (struct block_device * bdev , struct nbd_device * lo ,
574
+ unsigned int cmd , unsigned long arg )
575
+ {
589
576
switch (cmd ) {
590
- case NBD_DISCONNECT :
577
+ case NBD_DISCONNECT : {
578
+ struct request sreq ;
579
+
591
580
printk (KERN_INFO "%s: NBD_DISCONNECT\n" , lo -> disk -> disk_name );
581
+
592
582
blk_rq_init (NULL , & sreq );
593
583
sreq .cmd_type = REQ_TYPE_SPECIAL ;
594
584
nbd_cmd (& sreq ) = NBD_CMD_DISC ;
@@ -599,29 +589,29 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
599
589
*/
600
590
sreq .sector = 0 ;
601
591
sreq .nr_sectors = 0 ;
602
- if (!lo -> sock )
592
+ if (!lo -> sock )
603
593
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 );
607
595
return 0 ;
596
+ }
608
597
609
- case NBD_CLEAR_SOCK :
610
- error = 0 ;
611
- mutex_lock ( & lo -> tx_lock );
598
+ case NBD_CLEAR_SOCK : {
599
+ struct file * file ;
600
+
612
601
lo -> sock = NULL ;
613
- mutex_unlock (& lo -> tx_lock );
614
602
file = lo -> file ;
615
603
lo -> file = NULL ;
616
604
nbd_clear_que (lo );
617
605
BUG_ON (!list_empty (& lo -> queue_head ));
618
606
if (file )
619
607
fput (file );
620
- return error ;
621
- case NBD_SET_SOCK :
608
+ return 0 ;
609
+ }
610
+
611
+ case NBD_SET_SOCK : {
612
+ struct file * file ;
622
613
if (lo -> file )
623
614
return - EBUSY ;
624
- error = - EINVAL ;
625
615
file = fget (arg );
626
616
if (file ) {
627
617
struct inode * inode = file -> f_path .dentry -> d_inode ;
@@ -630,48 +620,65 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
630
620
lo -> sock = SOCKET_I (inode );
631
621
if (max_part > 0 )
632
622
bdev -> bd_invalidated = 1 ;
633
- error = 0 ;
623
+ return 0 ;
634
624
} else {
635
625
fput (file );
636
626
}
637
627
}
638
- return error ;
628
+ return - EINVAL ;
629
+ }
630
+
639
631
case NBD_SET_BLKSIZE :
640
632
lo -> blksize = arg ;
641
633
lo -> bytesize &= ~(lo -> blksize - 1 );
642
634
bdev -> bd_inode -> i_size = lo -> bytesize ;
643
635
set_blocksize (bdev , lo -> blksize );
644
636
set_capacity (lo -> disk , lo -> bytesize >> 9 );
645
637
return 0 ;
638
+
646
639
case NBD_SET_SIZE :
647
640
lo -> bytesize = arg & ~(lo -> blksize - 1 );
648
641
bdev -> bd_inode -> i_size = lo -> bytesize ;
649
642
set_blocksize (bdev , lo -> blksize );
650
643
set_capacity (lo -> disk , lo -> bytesize >> 9 );
651
644
return 0 ;
645
+
652
646
case NBD_SET_TIMEOUT :
653
647
lo -> xmit_timeout = arg * HZ ;
654
648
return 0 ;
649
+
655
650
case NBD_SET_SIZE_BLOCKS :
656
651
lo -> bytesize = ((u64 ) arg ) * lo -> blksize ;
657
652
bdev -> bd_inode -> i_size = lo -> bytesize ;
658
653
set_blocksize (bdev , lo -> blksize );
659
654
set_capacity (lo -> disk , lo -> bytesize >> 9 );
660
655
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
+
662
662
if (lo -> pid )
663
663
return - EBUSY ;
664
664
if (!lo -> file )
665
665
return - EINVAL ;
666
+
667
+ mutex_unlock (& lo -> tx_lock );
668
+
666
669
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 );
668
672
return PTR_ERR (thread );
673
+ }
669
674
wake_up_process (thread );
670
675
error = nbd_do_it (lo );
671
676
kthread_stop (thread );
677
+
678
+ mutex_lock (& lo -> tx_lock );
672
679
if (error )
673
680
return error ;
674
- sock_shutdown (lo , 1 );
681
+ sock_shutdown (lo , 0 );
675
682
file = lo -> file ;
676
683
lo -> file = NULL ;
677
684
nbd_clear_que (lo );
@@ -684,21 +691,46 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t mode,
684
691
if (max_part > 0 )
685
692
ioctl_by_bdev (bdev , BLKRRPART , 0 );
686
693
return lo -> harderror ;
694
+ }
695
+
687
696
case NBD_CLEAR_QUE :
688
697
/*
689
698
* This is for compatibility only. The queue is always cleared
690
699
* by NBD_DO_IT or NBD_CLEAR_SOCK.
691
700
*/
692
701
BUG_ON (!lo -> sock && !list_empty (& lo -> queue_head ));
693
702
return 0 ;
703
+
694
704
case NBD_PRINT_DEBUG :
695
705
printk (KERN_INFO "%s: next = %p, prev = %p, head = %p\n" ,
696
706
bdev -> bd_disk -> disk_name ,
697
707
lo -> queue_head .next , lo -> queue_head .prev ,
698
708
& lo -> queue_head );
699
709
return 0 ;
700
710
}
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 ;
702
734
}
703
735
704
736
static struct block_device_operations nbd_fops =
0 commit comments