Skip to content

Commit c0d067c

Browse files
idryomovgregkh
authored andcommitted
rbd: make get_lock_owner_info() return a single locker or NULL
commit f38cb9d upstream. 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 <[email protected]> Reviewed-by: Dongsheng Yang <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 3d215ad commit c0d067c

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
@@ -3850,10 +3850,17 @@ static void wake_lock_waiters(struct rbd_device *rbd_dev, int result)
38503850
list_splice_tail_init(&rbd_dev->acquiring_list, &rbd_dev->running_list);
38513851
}
38523852

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

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

3869-
if (*num_lockers == 0) {
3878+
if (num_lockers == 0) {
38703879
dout("%s rbd_dev %p no lockers detected\n", __func__, rbd_dev);
3880+
lockers = NULL;
38713881
goto out;
38723882
}
38733883

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

38813890
if (lock_type == CEPH_CLS_LOCK_SHARED) {
38823891
rbd_warn(rbd_dev, "shared lock type detected");
3883-
ret = -EBUSY;
3884-
goto out;
3892+
goto err_busy;
38853893
}
38863894

3887-
if (strncmp((*lockers)[0].id.cookie, RBD_LOCK_COOKIE_PREFIX,
3895+
WARN_ON(num_lockers != 1);
3896+
if (strncmp(lockers[0].id.cookie, RBD_LOCK_COOKIE_PREFIX,
38883897
strlen(RBD_LOCK_COOKIE_PREFIX))) {
38893898
rbd_warn(rbd_dev, "locked by external mechanism, cookie %s",
3890-
(*lockers)[0].id.cookie);
3891-
ret = -EBUSY;
3892-
goto out;
3899+
lockers[0].id.cookie);
3900+
goto err_busy;
38933901
}
38943902

38953903
out:
38963904
kfree(lock_tag);
3897-
return ret;
3905+
return lockers;
3906+
3907+
err_busy:
3908+
kfree(lock_tag);
3909+
ceph_free_lockers(lockers, num_lockers);
3910+
return ERR_PTR(-EBUSY);
38983911
}
38993912

39003913
static int find_watcher(struct rbd_device *rbd_dev,
@@ -3948,51 +3961,56 @@ static int find_watcher(struct rbd_device *rbd_dev,
39483961
static int rbd_try_lock(struct rbd_device *rbd_dev)
39493962
{
39503963
struct ceph_client *client = rbd_dev->rbd_client->client;
3951-
struct ceph_locker *lockers;
3952-
u32 num_lockers;
3964+
struct ceph_locker *locker;
39533965
int ret;
39543966

39553967
for (;;) {
3968+
locker = NULL;
3969+
39563970
ret = rbd_lock(rbd_dev);
39573971
if (ret != -EBUSY)
3958-
return ret;
3972+
goto out;
39593973

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

3968-
ret = find_watcher(rbd_dev, lockers);
3984+
ret = find_watcher(rbd_dev, locker);
39693985
if (ret)
39703986
goto out; /* request lock or error */
39713987

39723988
rbd_warn(rbd_dev, "breaking header lock owned by %s%llu",
3973-
ENTITY_NAME(lockers[0].id.name));
3989+
ENTITY_NAME(locker->id.name));
39743990

39753991
ret = ceph_monc_blocklist_add(&client->monc,
3976-
&lockers[0].info.addr);
3992+
&locker->info.addr);
39773993
if (ret) {
3978-
rbd_warn(rbd_dev, "blocklist of %s%llu failed: %d",
3979-
ENTITY_NAME(lockers[0].id.name), ret);
3994+
rbd_warn(rbd_dev, "failed to blocklist %s%llu: %d",
3995+
ENTITY_NAME(locker->id.name), ret);
39803996
goto out;
39813997
}
39823998

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

39904008
again:
3991-
ceph_free_lockers(lockers, num_lockers);
4009+
free_locker(locker);
39924010
}
39934011

39944012
out:
3995-
ceph_free_lockers(lockers, num_lockers);
4013+
free_locker(locker);
39964014
return ret;
39974015
}
39984016

0 commit comments

Comments
 (0)