Skip to content

Commit 34f55d0

Browse files
yangdongshengidryomov
authored andcommitted
rbd: support timeout in rbd_wait_state_locked()
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. This patch allow user to set the lock_timeout in rbd mapping. Signed-off-by: Dongsheng Yang <[email protected]> Reviewed-by: Ilya Dryomov <[email protected]> Signed-off-by: Ilya Dryomov <[email protected]>
1 parent 2f18d46 commit 34f55d0

File tree

1 file changed

+21
-1
lines changed

1 file changed

+21
-1
lines changed

drivers/block/rbd.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -732,6 +732,7 @@ static struct rbd_client *rbd_client_find(struct ceph_options *ceph_opts)
732732
*/
733733
enum {
734734
Opt_queue_depth,
735+
Opt_lock_timeout,
735736
Opt_last_int,
736737
/* int args above */
737738
Opt_last_string,
@@ -745,6 +746,7 @@ enum {
745746

746747
static match_table_t rbd_opts_tokens = {
747748
{Opt_queue_depth, "queue_depth=%d"},
749+
{Opt_lock_timeout, "lock_timeout=%d"},
748750
/* int args above */
749751
/* string args above */
750752
{Opt_read_only, "read_only"},
@@ -758,12 +760,14 @@ static match_table_t rbd_opts_tokens = {
758760

759761
struct rbd_options {
760762
int queue_depth;
763+
unsigned long lock_timeout;
761764
bool read_only;
762765
bool lock_on_read;
763766
bool exclusive;
764767
};
765768

766769
#define RBD_QUEUE_DEPTH_DEFAULT BLKDEV_MAX_RQ
770+
#define RBD_LOCK_TIMEOUT_DEFAULT 0 /* no timeout */
767771
#define RBD_READ_ONLY_DEFAULT false
768772
#define RBD_LOCK_ON_READ_DEFAULT false
769773
#define RBD_EXCLUSIVE_DEFAULT false
@@ -796,6 +800,14 @@ static int parse_rbd_opts_token(char *c, void *private)
796800
}
797801
rbd_opts->queue_depth = intval;
798802
break;
803+
case Opt_lock_timeout:
804+
/* 0 is "wait forever" (i.e. infinite timeout) */
805+
if (intval < 0 || intval > INT_MAX / 1000) {
806+
pr_err("lock_timeout out of range\n");
807+
return -EINVAL;
808+
}
809+
rbd_opts->lock_timeout = msecs_to_jiffies(intval * 1000);
810+
break;
799811
case Opt_read_only:
800812
rbd_opts->read_only = true;
801813
break;
@@ -3536,6 +3548,7 @@ static int rbd_obj_method_sync(struct rbd_device *rbd_dev,
35363548
static int rbd_wait_state_locked(struct rbd_device *rbd_dev, bool may_acquire)
35373549
{
35383550
DEFINE_WAIT(wait);
3551+
unsigned long timeout;
35393552
int ret = 0;
35403553

35413554
if (test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags))
@@ -3559,12 +3572,18 @@ static int rbd_wait_state_locked(struct rbd_device *rbd_dev, bool may_acquire)
35593572
prepare_to_wait_exclusive(&rbd_dev->lock_waitq, &wait,
35603573
TASK_UNINTERRUPTIBLE);
35613574
up_read(&rbd_dev->lock_rwsem);
3562-
schedule();
3575+
timeout = schedule_timeout(ceph_timeout_jiffies(
3576+
rbd_dev->opts->lock_timeout));
35633577
down_read(&rbd_dev->lock_rwsem);
35643578
if (test_bit(RBD_DEV_FLAG_BLACKLISTED, &rbd_dev->flags)) {
35653579
ret = -EBLACKLISTED;
35663580
break;
35673581
}
3582+
if (!timeout) {
3583+
rbd_warn(rbd_dev, "timed out waiting for lock");
3584+
ret = -ETIMEDOUT;
3585+
break;
3586+
}
35683587
} while (rbd_dev->lock_state != RBD_LOCK_STATE_LOCKED);
35693588

35703589
finish_wait(&rbd_dev->lock_waitq, &wait);
@@ -5186,6 +5205,7 @@ static int rbd_add_parse_args(const char *buf,
51865205

51875206
rbd_opts->read_only = RBD_READ_ONLY_DEFAULT;
51885207
rbd_opts->queue_depth = RBD_QUEUE_DEPTH_DEFAULT;
5208+
rbd_opts->lock_timeout = RBD_LOCK_TIMEOUT_DEFAULT;
51895209
rbd_opts->lock_on_read = RBD_LOCK_ON_READ_DEFAULT;
51905210
rbd_opts->exclusive = RBD_EXCLUSIVE_DEFAULT;
51915211

0 commit comments

Comments
 (0)