Re: [PATCH 1/3] rbd: support timeout in rbd_wait_state_locked

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Mar 20, 2018 at 11:32 AM, Dongsheng Yang
<dongsheng.yang@xxxxxxxxxxxx> wrote:
> currently, the rbd_wait_state_locked() will wait forever if we
> can't get our state locked. Example:
>
> rbd map --exclusive test1  --> /dev/rbd0
> rbd map test1  --> /dev/rbd1
> dd if=/dev/zero of=/dev/rbd1 bs=1M count=1 --> IO blocked
>
> To avoid this problem, this patch introduce a timeout design
> in rbd_wait_state_locked(). Then rbd_wait_state_locked() will
> return error when we reach a timeout.
>
> Signed-off-by: Dongsheng Yang <dongsheng.yang@xxxxxxxxxxxx>
> ---
>  drivers/block/rbd.c | 23 +++++++++++++++++++----
>  1 file changed, 19 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c
> index 96657ad..199819d 100644
> --- a/drivers/block/rbd.c
> +++ b/drivers/block/rbd.c
> @@ -761,6 +761,7 @@ struct rbd_options {
>  #define RBD_READ_ONLY_DEFAULT  false
>  #define RBD_LOCK_ON_READ_DEFAULT false
>  #define RBD_EXCLUSIVE_DEFAULT  false
> +#define RBD_WAIT_LOCK_TIMEOUT_DEFAULT  MAX_SCHEDULE_TIMEOUT

#define RBD_LOCK_TIMEOUT_DEFAULT  0  /* no timeout */

Passing lock_timeout=0 on the command line for "no timeout" must be
supported.  0 -> MAX_SCHEDULE_TIMEOUT will be handled by
ceph_timeout_jiffies() in rbd_wait_state_locked().

>
>  static int parse_rbd_opts_token(char *c, void *private)
>  {
> @@ -3494,8 +3495,9 @@ static int rbd_obj_method_sync(struct rbd_device *rbd_dev,
>  /*
>   * lock_rwsem must be held for read
>   */
> -static void rbd_wait_state_locked(struct rbd_device *rbd_dev)
> +static int rbd_wait_state_locked(struct rbd_device *rbd_dev)
>  {
> +       long timeo = RBD_WAIT_LOCK_TIMEOUT_DEFAULT;
>         DEFINE_WAIT(wait);
>
>         do {
> @@ -3508,12 +3510,18 @@ static void rbd_wait_state_locked(struct rbd_device *rbd_dev)
>                 prepare_to_wait_exclusive(&rbd_dev->lock_waitq, &wait,
>                                           TASK_UNINTERRUPTIBLE);
>                 up_read(&rbd_dev->lock_rwsem);
> -               schedule();
> +               timeo = schedule_timeout(timeo);
>                 down_read(&rbd_dev->lock_rwsem);
> +               if (!timeo) {
> +                       finish_wait(&rbd_dev->lock_waitq, &wait);
> +                       rbd_warn(rbd_dev, "timed out in waiting state locked");

"timed out waiting for lock"

> +                       return -ETIMEDOUT;
> +               }
>         } while (rbd_dev->lock_state != RBD_LOCK_STATE_LOCKED &&
>                  !test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags));
>
>         finish_wait(&rbd_dev->lock_waitq, &wait);
> +       return 0;
>  }
>
>  static void rbd_queue_workfn(struct work_struct *work)
> @@ -3606,7 +3614,9 @@ static void rbd_queue_workfn(struct work_struct *work)
>                                 result = -EROFS;
>                                 goto err_unlock;
>                         }
> -                       rbd_wait_state_locked(rbd_dev);
> +                       result = rbd_wait_state_locked(rbd_dev);
> +                       if (result)
> +                               goto err_unlock;
>                 }
>                 if (test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags)) {
>                         result = -EBLACKLISTED;
> @@ -5261,6 +5271,8 @@ static void rbd_dev_image_unlock(struct rbd_device *rbd_dev)
>
>  static int rbd_add_acquire_lock(struct rbd_device *rbd_dev)
>  {
> +       int ret = 0;
> +
>         if (!(rbd_dev->header.features & RBD_FEATURE_EXCLUSIVE_LOCK)) {
>                 rbd_warn(rbd_dev, "exclusive-lock feature is not enabled");
>                 return -EINVAL;
> @@ -5268,8 +5280,11 @@ static int rbd_add_acquire_lock(struct rbd_device *rbd_dev)
>
>         /* FIXME: "rbd map --exclusive" should be in interruptible */
>         down_read(&rbd_dev->lock_rwsem);
> -       rbd_wait_state_locked(rbd_dev);
> +       ret = rbd_wait_state_locked(rbd_dev);
>         up_read(&rbd_dev->lock_rwsem);
> +       if (ret) {
> +               return ret;
> +       }

Unneeded braces.

Thanks,

                Ilya
--
To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [CEPH Users]     [Ceph Large]     [Information on CEPH]     [Linux BTRFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux