Skip to content

Commit f38cb9d

Browse files
committed
rbd: make get_lock_owner_info() return a single locker or NULL
Make the "num_lockers can be only 0 or 1" assumption explicit and simplify the API by getting rid of output parameters in preparation for calling get_lock_owner_info() twice before blocklisting. Signed-off-by: Ilya Dryomov <idryomov@gmail.com> Reviewed-by: Dongsheng Yang <dongsheng.yang@easystack.cn>
1 parent 5016450 commit f38cb9d

File tree

1 file changed

+51
-33
lines changed

1 file changed

+51
-33
lines changed

drivers/block/rbd.c

Lines changed: 51 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -3849,10 +3849,17 @@ static void wake_lock_waiters(struct rbd_device *rbd_dev, int result)
38493849
list_splice_tail_init(&rbd_dev->acquiring_list, &rbd_dev->running_list);
38503850
}
38513851

3852-
static int get_lock_owner_info(struct rbd_device *rbd_dev,
3853-
struct ceph_locker **lockers, u32 *num_lockers)
3852+
static void free_locker(struct ceph_locker *locker)
3853+
{
3854+
if (locker)
3855+
ceph_free_lockers(locker, 1);
3856+
}
3857+
3858+
static struct ceph_locker *get_lock_owner_info(struct rbd_device *rbd_dev)
38543859
{
38553860
struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc;
3861+
struct ceph_locker *lockers;
3862+
u32 num_lockers;
38563863
u8 lock_type;
38573864
char *lock_tag;
38583865
int ret;
@@ -3861,39 +3868,45 @@ static int get_lock_owner_info(struct rbd_device *rbd_dev,
38613868

38623869
ret = ceph_cls_lock_info(osdc, &rbd_dev->header_oid,
38633870
&rbd_dev->header_oloc, RBD_LOCK_NAME,
3864-
&lock_type, &lock_tag, lockers, num_lockers);
3865-
if (ret)
3866-
return ret;
3871+
&lock_type, &lock_tag, &lockers, &num_lockers);
3872+
if (ret) {
3873+
rbd_warn(rbd_dev, "failed to retrieve lockers: %d", ret);
3874+
return ERR_PTR(ret);
3875+
}
38673876

3868-
if (*num_lockers == 0) {
3877+
if (num_lockers == 0) {
38693878
dout("%s rbd_dev %p no lockers detected\n", __func__, rbd_dev);
3879+
lockers = NULL;
38703880
goto out;
38713881
}
38723882

38733883
if (strcmp(lock_tag, RBD_LOCK_TAG)) {
38743884
rbd_warn(rbd_dev, "locked by external mechanism, tag %s",
38753885
lock_tag);
3876-
ret = -EBUSY;
3877-
goto out;
3886+
goto err_busy;
38783887
}
38793888

38803889
if (lock_type == CEPH_CLS_LOCK_SHARED) {
38813890
rbd_warn(rbd_dev, "shared lock type detected");
3882-
ret = -EBUSY;
3883-
goto out;
3891+
goto err_busy;
38843892
}
38853893

3886-
if (strncmp((*lockers)[0].id.cookie, RBD_LOCK_COOKIE_PREFIX,
3894+
WARN_ON(num_lockers != 1);
3895+
if (strncmp(lockers[0].id.cookie, RBD_LOCK_COOKIE_PREFIX,
38873896
strlen(RBD_LOCK_COOKIE_PREFIX))) {
38883897
rbd_warn(rbd_dev, "locked by external mechanism, cookie %s",
3889-
(*lockers)[0].id.cookie);
3890-
ret = -EBUSY;
3891-
goto out;
3898+
lockers[0].id.cookie);
3899+
goto err_busy;
38923900
}
38933901

38943902
out:
38953903
kfree(lock_tag);
3896-
return ret;
3904+
return lockers;
3905+
3906+
err_busy:
3907+
kfree(lock_tag);
3908+
ceph_free_lockers(lockers, num_lockers);
3909+
return ERR_PTR(-EBUSY);
38973910
}
38983911

38993912
static int find_watcher(struct rbd_device *rbd_dev,
@@ -3947,51 +3960,56 @@ static int find_watcher(struct rbd_device *rbd_dev,
39473960
static int rbd_try_lock(struct rbd_device *rbd_dev)
39483961
{
39493962
struct ceph_client *client = rbd_dev->rbd_client->client;
3950-
struct ceph_locker *lockers;
3951-
u32 num_lockers;
3963+
struct ceph_locker *locker;
39523964
int ret;
39533965

39543966
for (;;) {
3967+
locker = NULL;
3968+
39553969
ret = rbd_lock(rbd_dev);
39563970
if (ret != -EBUSY)
3957-
return ret;
3971+
goto out;
39583972

39593973
/* determine if the current lock holder is still alive */
3960-
ret = get_lock_owner_info(rbd_dev, &lockers, &num_lockers);
3961-
if (ret)
3962-
return ret;
3963-
3964-
if (num_lockers == 0)
3974+
locker = get_lock_owner_info(rbd_dev);
3975+
if (IS_ERR(locker)) {
3976+
ret = PTR_ERR(locker);
3977+
locker = NULL;
3978+
goto out;
3979+
}
3980+
if (!locker)
39653981
goto again;
39663982

3967-
ret = find_watcher(rbd_dev, lockers);
3983+
ret = find_watcher(rbd_dev, locker);
39683984
if (ret)
39693985
goto out; /* request lock or error */
39703986

39713987
rbd_warn(rbd_dev, "breaking header lock owned by %s%llu",
3972-
ENTITY_NAME(lockers[0].id.name));
3988+
ENTITY_NAME(locker->id.name));
39733989

39743990
ret = ceph_monc_blocklist_add(&client->monc,
3975-
&lockers[0].info.addr);
3991+
&locker->info.addr);
39763992
if (ret) {
3977-
rbd_warn(rbd_dev, "blocklist of %s%llu failed: %d",
3978-
ENTITY_NAME(lockers[0].id.name), ret);
3993+
rbd_warn(rbd_dev, "failed to blocklist %s%llu: %d",
3994+
ENTITY_NAME(locker->id.name), ret);
39793995
goto out;
39803996
}
39813997

39823998
ret = ceph_cls_break_lock(&client->osdc, &rbd_dev->header_oid,
39833999
&rbd_dev->header_oloc, RBD_LOCK_NAME,
3984-
lockers[0].id.cookie,
3985-
&lockers[0].id.name);
3986-
if (ret && ret != -ENOENT)
4000+
locker->id.cookie, &locker->id.name);
4001+
if (ret && ret != -ENOENT) {
4002+
rbd_warn(rbd_dev, "failed to break header lock: %d",
4003+
ret);
39874004
goto out;
4005+
}
39884006

39894007
again:
3990-
ceph_free_lockers(lockers, num_lockers);
4008+
free_locker(locker);
39914009
}
39924010

39934011
out:
3994-
ceph_free_lockers(lockers, num_lockers);
4012+
free_locker(locker);
39954013
return ret;
39964014
}
39974015

0 commit comments

Comments
 (0)