1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-01-03 05:18:29 +03:00

Allow deactivation of final snapshot.

This commit is contained in:
Alasdair Kergon 2002-04-16 14:42:20 +00:00
parent 0e06dd31fd
commit 69e8a53ee4

View File

@ -544,11 +544,11 @@ static int _emit_target(struct dm_task *dmt, struct stripe_segment *seg)
s == (stripes - 1) ? "" : " "); s == (stripes - 1) ? "" : " ");
else else
tw = lvm_snprintf(params + w, sizeof(params) - w, tw = lvm_snprintf(params + w, sizeof(params) - w,
"%s %" PRIu64 "%s", "%s %" PRIu64 "%s",
dev_name(seg->area[s].pv->dev), dev_name(seg->area[s].pv->dev),
(seg->area[s].pv->pe_start + (seg->area[s].pv->pe_start +
(esize * seg->area[s].pe)), (esize * seg->area[s].pe)),
s == (stripes - 1) ? "" : " "); s == (stripes - 1) ? "" : " ");
if (tw < 0) if (tw < 0)
goto error; goto error;
@ -729,7 +729,6 @@ int dev_manager_info(struct dev_manager *dm, struct logical_volume *lv,
return 1; return 1;
} }
static struct dev_layer *_create_dev(struct dev_manager *dm, char *name, static struct dev_layer *_create_dev(struct dev_manager *dm, char *name,
char *dlid) char *dlid)
{ {
@ -1061,8 +1060,7 @@ int _create_rec(struct dev_manager *dm, struct dev_layer *dl,
/* FIXME Create and use a _suspend_parents() function instead */ /* FIXME Create and use a _suspend_parents() function instead */
/* Suspend? */ /* Suspend? */
if (_get_flag(dl, SUSPENDED) && if (_get_flag(dl, SUSPENDED) && (!_suspend_parent || !_suspend(dl))) {
(!_suspend_parent || !_suspend(dl))) {
stack; stack;
return 0; return 0;
} }
@ -1098,9 +1096,8 @@ int _create_rec(struct dev_manager *dm, struct dev_layer *dl,
newname = _build_name(dm->mem, dm->vg_name, dl->lv->name, newname = _build_name(dm->mem, dm->vg_name, dl->lv->name,
suffix); suffix);
if (strcmp(newname, dl->name)) { if (strcmp(newname, dl->name)) {
if (!_suspend_parent(parent) || if (!_suspend_parent(parent) ||
!_suspend(dl) || !_suspend(dl) || !_rename(dm, dl, newname)) {
!_rename(dm, dl, newname)) {
stack; stack;
return 0; return 0;
} }
@ -1109,7 +1106,7 @@ int _create_rec(struct dev_manager *dm, struct dev_layer *dl,
/* Create? */ /* Create? */
if (!dl->info.exists) { if (!dl->info.exists) {
if (!_suspend_parent(parent) || if (!_suspend_parent(parent) ||
!_load(dm, dl, DM_DEVICE_CREATE)) { !_load(dm, dl, DM_DEVICE_CREATE)) {
stack; stack;
return 0; return 0;
@ -1119,15 +1116,14 @@ int _create_rec(struct dev_manager *dm, struct dev_layer *dl,
/* Reload? */ /* Reload? */
if (_get_flag(dl, RELOAD) && if (_get_flag(dl, RELOAD) &&
(!_suspend_parent(parent) || !_suspend(dl) || (!_suspend_parent(parent) || !_suspend(dl) ||
!_load(dm, dl, DM_DEVICE_RELOAD))) { !_load(dm, dl, DM_DEVICE_RELOAD))) {
stack; stack;
return 0; return 0;
} }
/* Resume? */ /* Resume? */
if (!_get_flag(dl, SUSPENDED) && if (!_get_flag(dl, SUSPENDED) && (!_suspend_parent || !_resume(dl))) {
(!_suspend_parent || !_resume(dl))) {
stack; stack;
return 0; return 0;
} }
@ -1406,20 +1402,36 @@ static void _remove_lv(struct list *head, struct logical_volume *lv)
} }
} }
/* Remove any snapshots with given origin */ static int _remove_lvs(struct dev_manager *dm, struct logical_volume *lv)
static void _remove_lvs(struct list *head, struct logical_volume *origin)
{ {
struct logical_volume *active; struct logical_volume *active, *old_origin;
struct snapshot *s; struct snapshot *s;
struct list *sh; struct list *sh, *active_head;
list_iterate(sh, head) { active_head = &dm->active_list;
/* Remove any snapshots with given origin */
list_iterate(sh, active_head) {
active = list_item(sh, struct lv_list)->lv; active = list_item(sh, struct lv_list)->lv;
if ((s = find_cow(active)) && s->origin == origin) if ((s = find_cow(active)) && s->origin == lv)
_remove_lv(head, active); _remove_lv(active_head, active);
} }
_remove_lv(head, origin); _remove_lv(active_head, lv);
if (!(s = find_cow(lv)))
return 1;
old_origin = s->origin;
/* Was this the last active snapshot with this origin? */
list_iterate(sh, active_head) {
active = list_item(sh, struct lv_list)->lv;
if ((s = find_cow(active)) && s->origin == old_origin)
return 1;
}
return _add_lvs(dm->mem, &dm->reload_list, old_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)
@ -1468,7 +1480,10 @@ static int _action(struct dev_manager *dm, struct logical_volume *lv,
if (action == ACTIVATE || action == DEACTIVATE) if (action == ACTIVATE || action == DEACTIVATE)
/* Get into known state - remove from active list if present */ /* Get into known state - remove from active list if present */
_remove_lvs(&dm->active_list, lv); if (!_remove_lvs(dm, lv)) {
stack;
return 0;
}
if (action == ACTIVATE) { if (action == ACTIVATE) {
/* Add to active & reload lists */ /* Add to active & reload lists */
@ -1508,4 +1523,3 @@ int dev_manager_suspend(struct dev_manager *dm, struct logical_volume *lv)
{ {
return _action(dm, lv, SUSPEND); return _action(dm, lv, SUSPEND);
} }