mirror of
git://sourceware.org/git/lvm2.git
synced 2025-12-14 04:23:50 +03:00
Tie all snapshot (de)activation requests to (de)activation of origin device.
This commit is contained in:
@@ -283,7 +283,7 @@ static int _load(struct dev_manager *dm, struct dev_layer *dl, int task)
|
|||||||
|
|
||||||
dm_task_destroy(dmt);
|
dm_task_destroy(dmt);
|
||||||
|
|
||||||
if (_get_flag(dl, VISIBLE))
|
if (r && _get_flag(dl, VISIBLE))
|
||||||
fs_add_lv(dl->lv, dl->name);
|
fs_add_lv(dl->lv, dl->name);
|
||||||
|
|
||||||
_clear_flag(dl, DIRTY);
|
_clear_flag(dl, DIRTY);
|
||||||
@@ -297,9 +297,9 @@ static int _remove(struct dev_layer *dl)
|
|||||||
struct dm_task *dmt;
|
struct dm_task *dmt;
|
||||||
|
|
||||||
if (_get_flag(dl, VISIBLE))
|
if (_get_flag(dl, VISIBLE))
|
||||||
log_verbose("Unloading %s", dl->name);
|
log_verbose("Removing %s", dl->name);
|
||||||
else
|
else
|
||||||
log_very_verbose("Unloading %s", dl->name);
|
log_very_verbose("Removing %s", dl->name);
|
||||||
|
|
||||||
if (!(dmt = _setup_task(dl->name, DM_DEVICE_REMOVE))) {
|
if (!(dmt = _setup_task(dl->name, DM_DEVICE_REMOVE))) {
|
||||||
stack;
|
stack;
|
||||||
@@ -316,7 +316,7 @@ static int _remove(struct dev_layer *dl)
|
|||||||
|
|
||||||
dm_task_destroy(dmt);
|
dm_task_destroy(dmt);
|
||||||
|
|
||||||
if (_get_flag(dl, VISIBLE))
|
if (r && _get_flag(dl, VISIBLE))
|
||||||
fs_del_lv(dl->lv);
|
fs_del_lv(dl->lv);
|
||||||
|
|
||||||
_clear_flag(dl, ACTIVE);
|
_clear_flag(dl, ACTIVE);
|
||||||
@@ -1220,6 +1220,23 @@ static int _add_lv(struct pool *mem,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _add_lvs(struct pool *mem,
|
||||||
|
struct list *head, struct logical_volume *origin)
|
||||||
|
{
|
||||||
|
struct logical_volume *lv;
|
||||||
|
struct snapshot *s;
|
||||||
|
struct list *lvh;
|
||||||
|
|
||||||
|
list_iterate(lvh, &origin->vg->lvs) {
|
||||||
|
lv = list_item(lvh, struct lv_list)->lv;
|
||||||
|
if ((s = find_cow(lv)) && s->origin == origin)
|
||||||
|
if (!_add_lv(mem, head, lv))
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _add_lv(mem, head, origin);
|
||||||
|
}
|
||||||
|
|
||||||
static void _remove_lv(struct list *head, struct logical_volume *lv)
|
static void _remove_lv(struct list *head, struct logical_volume *lv)
|
||||||
{
|
{
|
||||||
struct list *lvh;
|
struct list *lvh;
|
||||||
@@ -1234,6 +1251,22 @@ static void _remove_lv(struct list *head, struct logical_volume *lv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Remove any snapshots with given origin */
|
||||||
|
static void _remove_lvs(struct list *head, struct logical_volume *origin)
|
||||||
|
{
|
||||||
|
struct logical_volume *active;
|
||||||
|
struct snapshot *s;
|
||||||
|
struct list *sh;
|
||||||
|
|
||||||
|
list_iterate(sh, head) {
|
||||||
|
active = list_item(sh, struct lv_list)->lv;
|
||||||
|
if ((s = find_cow(active)) && s->origin == origin)
|
||||||
|
_remove_lv(head, active);
|
||||||
|
}
|
||||||
|
|
||||||
|
_remove_lv(head, origin);
|
||||||
|
}
|
||||||
|
|
||||||
static int _fill_in_active_list(struct dev_manager *dm, struct volume_group *vg)
|
static int _fill_in_active_list(struct dev_manager *dm, struct volume_group *vg)
|
||||||
{
|
{
|
||||||
int found;
|
int found;
|
||||||
@@ -1280,12 +1313,12 @@ static int _activate(struct dev_manager *dm, struct logical_volume *lv,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Remove from active list if present */
|
/* Remove from active list if present */
|
||||||
_remove_lv(&dm->active_list, lv);
|
_remove_lvs(&dm->active_list, lv);
|
||||||
|
|
||||||
if (activate == ACTIVATE) {
|
if (activate == ACTIVATE) {
|
||||||
/* Add to active and dirty lists */
|
/* Add to active and dirty lists */
|
||||||
if (!_add_lv(dm->mem, &dm->dirty_list, lv) ||
|
if (!_add_lvs(dm->mem, &dm->dirty_list, lv) ||
|
||||||
!_add_lv(dm->mem, &dm->active_list, lv)) {
|
!_add_lvs(dm->mem, &dm->active_list, lv)) {
|
||||||
stack;
|
stack;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,7 +67,9 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv)
|
|||||||
return EINVALID_CMD_LINE;
|
return EINVALID_CMD_LINE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lv_is_origin(lv)) {
|
if (lv_is_origin(lv) &&
|
||||||
|
(arg_count(cmd, contiguous_ARG) || arg_count(cmd, permission_ARG) ||
|
||||||
|
arg_count(cmd, readahead_ARG) || arg_count(cmd, persistent_ARG))) {
|
||||||
log_error("Can't change logical volume \"%s\" under snapshot",
|
log_error("Can't change logical volume \"%s\" under snapshot",
|
||||||
lv->name);
|
lv->name);
|
||||||
return ECMD_FAILED;
|
return ECMD_FAILED;
|
||||||
@@ -187,6 +189,7 @@ static int lvchange_availability(struct cmd_context *cmd,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (activate) {
|
if (activate) {
|
||||||
|
/* FIXME Tighter locking if lv_is_origin() */
|
||||||
log_verbose("Activating logical volume \"%s\"", lv->name);
|
log_verbose("Activating logical volume \"%s\"", lv->name);
|
||||||
if (!lock_vol(cmd, lv->lvid.s, LCK_LV_ACTIVATE))
|
if (!lock_vol(cmd, lv->lvid.s, LCK_LV_ACTIVATE))
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -35,6 +35,10 @@ static int _activate_lvs_in_vg(struct cmd_context *cmd,
|
|||||||
list_iterate(lvh, &vg->lvs) {
|
list_iterate(lvh, &vg->lvs) {
|
||||||
lv = list_item(lvh, struct lv_list)->lv;
|
lv = list_item(lvh, struct lv_list)->lv;
|
||||||
|
|
||||||
|
/* Only request activatation of snapshot origin devices */
|
||||||
|
if (lv_is_cow(lv))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!lock_vol(cmd, lv->lvid.s, lock | LCK_NONBLOCK))
|
if (!lock_vol(cmd, lv->lvid.s, lock | LCK_NONBLOCK))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user