@@ -100,6 +100,11 @@ static inline struct device *nbd_to_dev(struct nbd_device *nbd)
100100 return disk_to_dev (nbd -> disk );
101101}
102102
103+ static bool nbd_is_connected (struct nbd_device * nbd )
104+ {
105+ return !!nbd -> task_recv ;
106+ }
107+
103108static const char * nbdcmd_to_ascii (int cmd )
104109{
105110 switch (cmd ) {
@@ -112,6 +117,42 @@ static const char *nbdcmd_to_ascii(int cmd)
112117 return "invalid" ;
113118}
114119
120+ static int nbd_size_clear (struct nbd_device * nbd , struct block_device * bdev )
121+ {
122+ bdev -> bd_inode -> i_size = 0 ;
123+ set_capacity (nbd -> disk , 0 );
124+ kobject_uevent (& nbd_to_dev (nbd )-> kobj , KOBJ_CHANGE );
125+
126+ return 0 ;
127+ }
128+
129+ static void nbd_size_update (struct nbd_device * nbd , struct block_device * bdev )
130+ {
131+ if (!nbd_is_connected (nbd ))
132+ return ;
133+
134+ bdev -> bd_inode -> i_size = nbd -> bytesize ;
135+ set_capacity (nbd -> disk , nbd -> bytesize >> 9 );
136+ kobject_uevent (& nbd_to_dev (nbd )-> kobj , KOBJ_CHANGE );
137+ }
138+
139+ static int nbd_size_set (struct nbd_device * nbd , struct block_device * bdev ,
140+ int blocksize , int nr_blocks )
141+ {
142+ int ret ;
143+
144+ ret = set_blocksize (bdev , blocksize );
145+ if (ret )
146+ return ret ;
147+
148+ nbd -> blksize = blocksize ;
149+ nbd -> bytesize = (loff_t )blocksize * (loff_t )nr_blocks ;
150+
151+ nbd_size_update (nbd , bdev );
152+
153+ return 0 ;
154+ }
155+
115156static void nbd_end_request (struct nbd_device * nbd , struct request * req )
116157{
117158 int error = req -> errors ? - EIO : 0 ;
@@ -401,7 +442,7 @@ static struct device_attribute pid_attr = {
401442 .show = pid_show ,
402443};
403444
404- static int nbd_thread_recv (struct nbd_device * nbd )
445+ static int nbd_thread_recv (struct nbd_device * nbd , struct block_device * bdev )
405446{
406447 struct request * req ;
407448 int ret ;
@@ -421,6 +462,8 @@ static int nbd_thread_recv(struct nbd_device *nbd)
421462 return ret ;
422463 }
423464
465+ nbd_size_update (nbd , bdev );
466+
424467 while (1 ) {
425468 req = nbd_read_stat (nbd );
426469 if (IS_ERR (req )) {
@@ -431,6 +474,8 @@ static int nbd_thread_recv(struct nbd_device *nbd)
431474 nbd_end_request (nbd , req );
432475 }
433476
477+ nbd_size_clear (nbd , bdev );
478+
434479 device_remove_file (disk_to_dev (nbd -> disk ), & pid_attr );
435480
436481 nbd -> task_recv = NULL ;
@@ -707,20 +752,19 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
707752 return err ;
708753 }
709754
710- case NBD_SET_BLKSIZE :
711- nbd -> blksize = arg ;
712- nbd -> bytesize &= ~(nbd -> blksize - 1 );
713- bdev -> bd_inode -> i_size = nbd -> bytesize ;
714- set_blocksize (bdev , nbd -> blksize );
715- set_capacity (nbd -> disk , nbd -> bytesize >> 9 );
716- return 0 ;
755+ case NBD_SET_BLKSIZE : {
756+ loff_t bsize = nbd -> bytesize ;
757+ do_div (bsize , arg );
758+
759+ return nbd_size_set (nbd , bdev , arg , bsize );
760+ }
717761
718762 case NBD_SET_SIZE :
719- nbd -> bytesize = arg & ~( nbd -> blksize - 1 );
720- bdev -> bd_inode -> i_size = nbd -> bytesize ;
721- set_blocksize ( bdev , nbd -> blksize );
722- set_capacity ( nbd -> disk , nbd -> bytesize >> 9 );
723- return 0 ;
763+ return nbd_size_set ( nbd , bdev , nbd -> blksize ,
764+ arg / nbd -> blksize ) ;
765+
766+ case NBD_SET_SIZE_BLOCKS :
767+ return nbd_size_set ( nbd , bdev , nbd -> blksize , arg ) ;
724768
725769 case NBD_SET_TIMEOUT :
726770 nbd -> xmit_timeout = arg * HZ ;
@@ -736,13 +780,6 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
736780 nbd -> flags = arg ;
737781 return 0 ;
738782
739- case NBD_SET_SIZE_BLOCKS :
740- nbd -> bytesize = ((u64 ) arg ) * nbd -> blksize ;
741- bdev -> bd_inode -> i_size = nbd -> bytesize ;
742- set_blocksize (bdev , nbd -> blksize );
743- set_capacity (nbd -> disk , nbd -> bytesize >> 9 );
744- return 0 ;
745-
746783 case NBD_DO_IT : {
747784 struct task_struct * thread ;
748785 int error ;
@@ -764,7 +801,7 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
764801 }
765802
766803 nbd_dev_dbg_init (nbd );
767- error = nbd_thread_recv (nbd );
804+ error = nbd_thread_recv (nbd , bdev );
768805 nbd_dev_dbg_close (nbd );
769806 kthread_stop (thread );
770807
0 commit comments