Hi,

On Saturday 16 July 2016 16:06:36 Pranay Kr Srivastava wrote:
>       When a timeout occurs or a recv fails, then
>       instead of abruptly killing nbd block device
>       wait for its users to finish.
> 
>       This is more required when filesystem(s) like
>       ext2 or ext3 don't expect their buffer heads to
>       disappear while the filesystem is mounted.
> 
>       Each open is now refcounted with the device being released
>       for re-use only when there are no "other users".
> 
>       A timedout or a disconnected device, if in use, can't
>       be used until it has been resetted. The reset happens
>       when all tasks having this bdev open closes this bdev.
> 
> Behavioral Change:
> 
> 1)    NBD_DO_IT will not wait for the device to be reset. Hence
>       the nbd-client "may exit" while some other process is using
>       this device without actually doing the reset on this device
>       , hence thus making it unusable until all such user space
>       processes have stopped using this device.
> 
> 2)    There's a window where the nbd-client will not be able to
>       change / issue ioctls to the nbd device. This is when there's
>       been a disconnect issued or a timeout has occured, however
>       there are "other" user processes which currently have this
>       nbd device opened.

Thanks for the updated patches. I applied all of your patches with some
smaller changes. I will test them later and push them to the git repo
then.

Best Regards,

Markus

> 
> Signed-off-by: Pranay Kr Srivastava <pran...@gmail.com>
> ---
>  drivers/block/nbd.c | 37 ++++++++++++++++++++++++++++++++-----
>  1 file changed, 32 insertions(+), 5 deletions(-)
> 
> diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
> index 4919760..fe36280 100644
> --- a/drivers/block/nbd.c
> +++ b/drivers/block/nbd.c
> @@ -74,6 +74,7 @@ struct nbd_device {
>        *This is specifically for calling sock_shutdown, for now.
>        */
>       struct work_struct ws_shutdown;
> +     atomic_t users; /* Users that opened the block device */
>  };
>  
>  #if IS_ENABLED(CONFIG_DEBUG_FS)
> @@ -699,6 +700,9 @@ static void nbd_dev_dbg_close(struct nbd_device *nbd);
>  static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
>                      unsigned int cmd, unsigned long arg)
>  {
> +     if (nbd->disconnect || nbd->timedout)
> +             return -EBUSY;
> +
>       switch (cmd) {
>       case NBD_DISCONNECT: {
>               struct request sreq;
> @@ -728,7 +732,6 @@ static int __nbd_ioctl(struct block_device *bdev, struct 
> nbd_device *nbd,
>               nbd_clear_que(nbd);
>               BUG_ON(!list_empty(&nbd->queue_head));
>               BUG_ON(!list_empty(&nbd->waiting_queue));
> -             kill_bdev(bdev);
>               return 0;
>  
>       case NBD_SET_SOCK: {
> @@ -804,16 +807,12 @@ static int __nbd_ioctl(struct block_device *bdev, 
> struct nbd_device *nbd,
>               mutex_lock(&nbd->tx_lock);
>               nbd->task_recv = NULL;
>               nbd_clear_que(nbd);
> -             kill_bdev(bdev);
> -             nbd_bdev_reset(bdev);
>  
>               if (nbd->disconnect) /* user requested, ignore socket errors */
>                       error = 0;
>               if (nbd->timedout)
>                       error = -ETIMEDOUT;
>  
> -             nbd_reset(nbd);
> -
>               return error;
>       }
>  
> @@ -852,10 +851,38 @@ static int nbd_ioctl(struct block_device *bdev, fmode_t 
> mode,
>       return error;
>  }
>  
> +static int nbd_open(struct block_device *bdev, fmode_t mode)
> +{
> +     struct nbd_device *nbd = bdev->bd_disk->private_data;
> +
> +     atomic_inc(&nbd->users);
> +
> +     return 0;
> +}
> +
> +static void nbd_release(struct gendisk *disk, fmode_t mode)
> +{
> +     struct nbd_device *nbd = disk->private_data;
> +     struct block_device *bdev = bdget (part_devt(
> +                                             dev_to_part(nbd_to_dev(nbd))));
> +
> +     WARN_ON(!bdev);
> +     if (atomic_dec_and_test(&nbd->users)) {
> +             if (bdev) {
> +                     nbd_bdev_reset(bdev);
> +                     kill_bdev(bdev);
> +                     bdput(bdev);
> +             }
> +             nbd_reset(nbd);
> +     }
> +}
> +
>  static const struct block_device_operations nbd_fops = {
>       .owner =        THIS_MODULE,
>       .ioctl =        nbd_ioctl,
>       .compat_ioctl = nbd_ioctl,
> +     .open =         nbd_open,
> +     .release =      nbd_release,
>  };
>  
>  static void nbd_ws_func_shutdown(struct work_struct *ws_nbd)
> 

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

Attachment: signature.asc
Description: This is a digitally signed message part.

Reply via email to