mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
lvmlockd vdo: add support
lvmlockd handling for vdo lv and vdo pool is like thin lv and thin pool.
This commit is contained in:
parent
82e270c18a
commit
2272a32e6f
@ -2311,6 +2311,49 @@ static int _lockd_lv_thin(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
pool_lv->lock_args, def_mode, flags);
|
||||
}
|
||||
|
||||
static int _lockd_lv_vdo(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
const char *def_mode, uint32_t flags)
|
||||
{
|
||||
struct logical_volume *pool_lv = NULL;
|
||||
|
||||
if (lv_is_vdo(lv)) {
|
||||
if (first_seg(lv))
|
||||
pool_lv = seg_lv(first_seg(lv), 0);
|
||||
|
||||
} else if (lv_is_vdo_pool(lv)) {
|
||||
pool_lv = lv;
|
||||
|
||||
} else if (lv_is_vdo_pool_data(lv)) {
|
||||
return 1;
|
||||
|
||||
} else {
|
||||
/* This should not happen AFAIK. */
|
||||
log_error("Lock on incorrect vdo lv type %s/%s",
|
||||
lv->vg->name, lv->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!pool_lv) {
|
||||
/* This happens in lvremove where it's harmless. */
|
||||
log_debug("No vdo pool for %s/%s", lv->vg->name, lv->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Locking a locked lv (pool in this case) is a no-op.
|
||||
* Unlock when the pool is no longer active.
|
||||
*/
|
||||
|
||||
if (def_mode && !strcmp(def_mode, "un") &&
|
||||
lv_is_vdo_pool(pool_lv) && lv_is_active(lv_lock_holder(pool_lv)))
|
||||
return 1;
|
||||
|
||||
flags |= LDLV_MODE_NO_SH;
|
||||
|
||||
return lockd_lv_name(cmd, pool_lv->vg, pool_lv->name, &pool_lv->lvid.id[1],
|
||||
pool_lv->lock_args, def_mode, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the VG has no lock_type, then this function can return immediately.
|
||||
* The LV itself may have no lock (NULL lv->lock_args), but the lock request
|
||||
@ -2352,6 +2395,9 @@ int lockd_lv(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
if (lv_is_thin_type(lv))
|
||||
return _lockd_lv_thin(cmd, lv, def_mode, flags);
|
||||
|
||||
if (lv_is_vdo_type(lv))
|
||||
return _lockd_lv_vdo(cmd, lv, def_mode, flags);
|
||||
|
||||
/*
|
||||
* An LV with NULL lock_args does not have a lock of its own.
|
||||
*/
|
||||
@ -2724,6 +2770,27 @@ int lockd_init_lv(struct cmd_context *cmd, struct volume_group *vg, struct logic
|
||||
return 0;
|
||||
}
|
||||
|
||||
} else if (seg_is_vdo(lp)) {
|
||||
struct lv_list *lvl;
|
||||
|
||||
/*
|
||||
* A vdo lv is being created in a vdo pool. The vdo lv does
|
||||
* not have its own lock, the lock of the vdo pool is used, and
|
||||
* the vdo pool needs to be locked to create a vdo lv in it.
|
||||
*/
|
||||
|
||||
if (!(lvl = find_lv_in_vg(vg, lp->pool_name))) {
|
||||
log_error("Failed to find vdo pool %s/%s", vg->name, lp->pool_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!lockd_lv(cmd, lvl->lv, "ex", LDLV_PERSISTENT)) {
|
||||
log_error("Failed to lock vdo pool %s/%s", vg->name, lp->pool_name);
|
||||
return 0;
|
||||
}
|
||||
lv->lock_args = NULL;
|
||||
return 1;
|
||||
|
||||
} else {
|
||||
/* Creating a normal lv. */
|
||||
/* lv_name_lock = lv_name; */
|
||||
@ -2963,6 +3030,12 @@ int lockd_lv_uses_lock(struct logical_volume *lv)
|
||||
if (lv_is_pool_metadata_spare(lv))
|
||||
return 0;
|
||||
|
||||
if (lv_is_vdo(lv))
|
||||
return 0;
|
||||
|
||||
if (lv_is_vdo_pool_data(lv))
|
||||
return 0;
|
||||
|
||||
if (lv_is_cache_vol(lv))
|
||||
return 0;
|
||||
|
||||
|
@ -1222,8 +1222,19 @@ static int _release_and_discard_lv_segment_area(struct lv_segment *seg, uint32_t
|
||||
}
|
||||
|
||||
/* When removed last VDO user automatically removes VDO pool */
|
||||
if (lv_is_vdo_pool(lv) && dm_list_empty(&(lv->segs_using_this_lv)))
|
||||
return lv_remove(lv); /* FIXME: any upper level reporting */
|
||||
if (lv_is_vdo_pool(lv) && dm_list_empty(&(lv->segs_using_this_lv))) {
|
||||
struct volume_group *vg = lv->vg;
|
||||
|
||||
if (!lv_remove(lv)) /* FIXME: any upper level reporting */
|
||||
return_0;
|
||||
|
||||
if (vg_is_shared(vg)) {
|
||||
if (!lockd_lv_name(vg->cmd, vg, lv->name, &lv->lvid.id[1], lv->lock_args, "un", LDLV_PERSISTENT))
|
||||
log_error("Failed to unlock vdo pool in lvmlockd.");
|
||||
lockd_free_lv(vg->cmd, vg, lv->name, &lv->lvid.id[1], lv->lock_args);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -8730,9 +8741,15 @@ struct logical_volume *lv_create_single(struct volume_group *vg,
|
||||
/* The VDO segment needs VDO pool which is layer above created striped data LV */
|
||||
if (!(lp->segtype = get_segtype_from_string(vg->cmd, SEG_TYPE_NAME_VDO_POOL)))
|
||||
return_NULL;
|
||||
|
||||
/* We want a lockd lock for the new vdo pool, but not the vdo lv. */
|
||||
lp->needs_lockd_init = 1;
|
||||
|
||||
/* Use vpool names for vdo-pool */
|
||||
if (!(lv = _lv_create_an_lv(vg, lp, lp->pool_name ? : "vpool%d")))
|
||||
return_NULL;
|
||||
|
||||
lp->needs_lockd_init = 0;
|
||||
} else {
|
||||
log_error(INTERNAL_ERROR "Creation of pool for unsupported segment type %s.",
|
||||
lp->segtype->name);
|
||||
|
Loading…
Reference in New Issue
Block a user