mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
lvmlockd: fix cachevol locking
When a cachevol LV is attached, have the LV keep it's lock allocated. The lock on the cachevol won't be used while it's attached. When the cachevol is split a new lock does not need to be allocated. (Applies to cachevol usage by both dm-cache and dm-writecache.)
This commit is contained in:
parent
221edf4030
commit
6a8bd0c509
@ -2367,6 +2367,14 @@ int lockd_lv(struct cmd_context *cmd, struct logical_volume *lv,
|
||||
if (!lv->lock_args)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* A cachevol LV is one exception, where the LV keeps lock_args (so
|
||||
* they do not need to be reallocated on split) but the lvmlockd lock
|
||||
* is not used.
|
||||
*/
|
||||
if (lv_is_cache_vol(lv))
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* LV type cannot be active concurrently on multiple hosts,
|
||||
* so shared mode activation is not allowed.
|
||||
|
@ -2670,7 +2670,9 @@ int vg_validate(struct volume_group *vg)
|
||||
|
||||
}
|
||||
} else {
|
||||
if (lvl->lv->lock_args) {
|
||||
if (lv_is_cache_vol(lvl->lv)) {
|
||||
log_debug("lock_args will be ignored on cache vol");
|
||||
} else if (lvl->lv->lock_args) {
|
||||
log_error(INTERNAL_ERROR "LV %s/%s shouldn't have lock_args",
|
||||
vg->name, lvl->lv->name);
|
||||
r = 0;
|
||||
|
@ -3474,6 +3474,18 @@ static int _cache_vol_attach(struct cmd_context *cmd,
|
||||
if (!archive(vg))
|
||||
goto_out;
|
||||
|
||||
/*
|
||||
* lv/cache_lv keeps the same lockd lock it had before, the lock for
|
||||
* lv_fast is kept but is not used while it's attached, and
|
||||
* lv_corig has no lock. (When the cachevol is split a new lvmlockd
|
||||
* lock does not need to be created for it again.)
|
||||
*/
|
||||
if (vg_is_shared(vg) && lv_fast->lock_args) {
|
||||
lockd_fast_args = dm_pool_strdup(cmd->mem, lv_fast->lock_args);
|
||||
lockd_fast_name = dm_pool_strdup(cmd->mem, lv_fast->name);
|
||||
memcpy(&lockd_fast_id, &lv_fast->lvid.id[1], sizeof(struct id));
|
||||
}
|
||||
|
||||
/*
|
||||
* The lvm tradition is to rename an LV with a special role-specific
|
||||
* suffix when it becomes hidden. Here the _cvol suffix is added to
|
||||
@ -3517,18 +3529,6 @@ static int _cache_vol_attach(struct cmd_context *cmd,
|
||||
goto_out;
|
||||
}
|
||||
|
||||
/*
|
||||
* lv/cache_lv keeps the same lockd lock it had before, the lock for
|
||||
* lv_fast is freed, and lv_corig has no lock.
|
||||
*/
|
||||
|
||||
if (vg_is_shared(vg) && lv_fast->lock_args) {
|
||||
lockd_fast_args = dm_pool_strdup(cmd->mem, lv_fast->lock_args);
|
||||
lockd_fast_name = dm_pool_strdup(cmd->mem, lv_fast->name);
|
||||
memcpy(&lockd_fast_id, &lv_fast->lvid.id[1], sizeof(struct id));
|
||||
lv_fast->lock_args = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* vg_write(), suspend_lv(), vg_commit(), resume_lv(),
|
||||
* where the old LV is suspended and the new LV is resumed.
|
||||
@ -3538,10 +3538,9 @@ static int _cache_vol_attach(struct cmd_context *cmd,
|
||||
goto_out;
|
||||
|
||||
if (lockd_fast_name) {
|
||||
/* unlock and free lockd lock for lv_fast */
|
||||
/* lockd unlock for lv_fast */
|
||||
if (!lockd_lv_name(cmd, vg, lockd_fast_name, &lockd_fast_id, lockd_fast_args, "un", LDLV_PERSISTENT))
|
||||
log_error("Failed to unlock fast LV %s/%s", vg->name, lockd_fast_name);
|
||||
lockd_free_lv(cmd, vg, lockd_fast_name, &lockd_fast_id, lockd_fast_args);
|
||||
}
|
||||
|
||||
r = 1;
|
||||
@ -5607,6 +5606,17 @@ static int _lvconvert_writecache_attach_single(struct cmd_context *cmd,
|
||||
if (!archive(vg))
|
||||
goto_bad;
|
||||
|
||||
/*
|
||||
* lv keeps the same lockd lock it had before, the lock for
|
||||
* lv_fast is kept but is not used while it's attached, and
|
||||
* lv_wcorig gets no lock.
|
||||
*/
|
||||
if (vg_is_shared(vg) && lv_fast->lock_args) {
|
||||
lockd_fast_args = dm_pool_strdup(cmd->mem, lv_fast->lock_args);
|
||||
lockd_fast_name = dm_pool_strdup(cmd->mem, lv_fast->name);
|
||||
memcpy(&lockd_fast_id, &lv_fast->lvid.id[1], sizeof(struct id));
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: use libblkid to get the sector size of lv. If it doesn't
|
||||
* match the block_size we are using for the writecache, then warn that
|
||||
@ -5650,17 +5660,6 @@ static int _lvconvert_writecache_attach_single(struct cmd_context *cmd,
|
||||
if (!(lv_wcorig = _lv_writecache_create(cmd, lv, lv_fast, block_size_sectors, &settings)))
|
||||
goto_bad;
|
||||
|
||||
/*
|
||||
* lv keeps the same lockd lock it had before, the lock for
|
||||
* lv_fast is freed, and lv_wcorig gets no lock.
|
||||
*/
|
||||
if (vg_is_shared(vg) && lv_fast->lock_args) {
|
||||
lockd_fast_args = dm_pool_strdup(cmd->mem, lv_fast->lock_args);
|
||||
lockd_fast_name = dm_pool_strdup(cmd->mem, lv_fast->name);
|
||||
memcpy(&lockd_fast_id, &lv_fast->lvid.id[1], sizeof(struct id));
|
||||
lv_fast->lock_args = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* vg_write(), suspend_lv(), vg_commit(), resume_lv(),
|
||||
* where the old LV is suspended and the new LV is resumed.
|
||||
@ -5672,10 +5671,9 @@ static int _lvconvert_writecache_attach_single(struct cmd_context *cmd,
|
||||
lockd_lv(cmd, lv, "un", 0);
|
||||
|
||||
if (lockd_fast_name) {
|
||||
/* unlock and free lockd lock for lv_fast */
|
||||
/* lockd unlock for lv_fast */
|
||||
if (!lockd_lv_name(cmd, vg, lockd_fast_name, &lockd_fast_id, lockd_fast_args, "un", 0))
|
||||
log_error("Failed to unlock fast LV %s/%s", vg->name, lockd_fast_name);
|
||||
lockd_free_lv(cmd, vg, lockd_fast_name, &lockd_fast_id, lockd_fast_args);
|
||||
}
|
||||
|
||||
log_print_unless_silent("Logical volume %s now has write cache.",
|
||||
|
Loading…
Reference in New Issue
Block a user