mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-22 17:35:59 +03:00
Tie all snapshot (de)activation requests to (de)activation of origin device.
This commit is contained in:
parent
6821379586
commit
20f990b6ce
@ -283,7 +283,7 @@ static int _load(struct dev_manager *dm, struct dev_layer *dl, int task)
|
||||
|
||||
dm_task_destroy(dmt);
|
||||
|
||||
if (_get_flag(dl, VISIBLE))
|
||||
if (r && _get_flag(dl, VISIBLE))
|
||||
fs_add_lv(dl->lv, dl->name);
|
||||
|
||||
_clear_flag(dl, DIRTY);
|
||||
@ -297,9 +297,9 @@ static int _remove(struct dev_layer *dl)
|
||||
struct dm_task *dmt;
|
||||
|
||||
if (_get_flag(dl, VISIBLE))
|
||||
log_verbose("Unloading %s", dl->name);
|
||||
log_verbose("Removing %s", dl->name);
|
||||
else
|
||||
log_very_verbose("Unloading %s", dl->name);
|
||||
log_very_verbose("Removing %s", dl->name);
|
||||
|
||||
if (!(dmt = _setup_task(dl->name, DM_DEVICE_REMOVE))) {
|
||||
stack;
|
||||
@ -316,7 +316,7 @@ static int _remove(struct dev_layer *dl)
|
||||
|
||||
dm_task_destroy(dmt);
|
||||
|
||||
if (_get_flag(dl, VISIBLE))
|
||||
if (r && _get_flag(dl, VISIBLE))
|
||||
fs_del_lv(dl->lv);
|
||||
|
||||
_clear_flag(dl, ACTIVE);
|
||||
@ -1220,6 +1220,23 @@ static int _add_lv(struct pool *mem,
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
int found;
|
||||
@ -1266,7 +1299,7 @@ static int _fill_in_active_list(struct dev_manager *dm, struct volume_group *vg)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _activate(struct dev_manager *dm, struct logical_volume *lv,
|
||||
static int _activate(struct dev_manager *dm, struct logical_volume *lv,
|
||||
activate_t activate)
|
||||
{
|
||||
if (!_scan_existing_devices(dm)) {
|
||||
@ -1280,12 +1313,12 @@ static int _activate(struct dev_manager *dm, struct logical_volume *lv,
|
||||
}
|
||||
|
||||
/* Remove from active list if present */
|
||||
_remove_lv(&dm->active_list, lv);
|
||||
_remove_lvs(&dm->active_list, lv);
|
||||
|
||||
if (activate == ACTIVATE) {
|
||||
/* Add to active and dirty lists */
|
||||
if (!_add_lv(dm->mem, &dm->dirty_list, lv) ||
|
||||
!_add_lv(dm->mem, &dm->active_list, lv)) {
|
||||
if (!_add_lvs(dm->mem, &dm->dirty_list, lv) ||
|
||||
!_add_lvs(dm->mem, &dm->active_list, lv)) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
@ -67,7 +67,9 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv)
|
||||
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",
|
||||
lv->name);
|
||||
return ECMD_FAILED;
|
||||
@ -187,6 +189,7 @@ static int lvchange_availability(struct cmd_context *cmd,
|
||||
}
|
||||
|
||||
if (activate) {
|
||||
/* FIXME Tighter locking if lv_is_origin() */
|
||||
log_verbose("Activating logical volume \"%s\"", lv->name);
|
||||
if (!lock_vol(cmd, lv->lvid.s, LCK_LV_ACTIVATE))
|
||||
return 0;
|
||||
|
@ -35,6 +35,10 @@ static int _activate_lvs_in_vg(struct cmd_context *cmd,
|
||||
list_iterate(lvh, &vg->lvs) {
|
||||
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))
|
||||
continue;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user