Make pointer from the origin volume to the shared store. There may be only one shared store, so we do not need to build a list. Signed-off-by: Mikulas Patocka --- lib/metadata/lv_manip.c | 12 ++++++++++++ lib/metadata/metadata-exported.h | 4 ++++ lib/metadata/snapshot_manip.c | 22 ++++++++++++++++++++++ 3 files changed, 38 insertions(+) Index: LVM2.2.02.73/lib/metadata/lv_manip.c =================================================================== --- LVM2.2.02.73.orig/lib/metadata/lv_manip.c 2010-09-10 17:44:56.000000000 +0200 +++ LVM2.2.02.73/lib/metadata/lv_manip.c 2010-09-10 17:45:05.000000000 +0200 @@ -2008,6 +2008,7 @@ struct logical_volume *alloc_lv(struct d } lv->snapshot = NULL; + lv->shared_snapshot = NULL; dm_list_init(&lv->snapshot_segs); dm_list_init(&lv->segments); dm_list_init(&lv->tags); @@ -3095,6 +3096,17 @@ int lv_create_single(struct volume_group "supported yet."); return 0; } + if (lv_is_multisnap_origin(org)) { + log_error("It is not allowed to create more " + "shared snapshot stores."); + return 0; + } + if (lv_is_origin(org) && !lv_is_multisnap_origin(org) && + lp->shared_store) { + log_error("It is not allowed to mix shared " + "and unshared snapshots."); + return 0; + } if (org->status & LOCKED) { log_error("Snapshots of locked devices are not " "supported yet"); Index: LVM2.2.02.73/lib/metadata/metadata-exported.h =================================================================== --- LVM2.2.02.73.orig/lib/metadata/metadata-exported.h 2010-09-10 17:44:56.000000000 +0200 +++ LVM2.2.02.73/lib/metadata/metadata-exported.h 2010-09-10 17:45:05.000000000 +0200 @@ -419,6 +419,9 @@ struct logical_volume { struct replicator_device *rdevice;/* For replicator-devs, rimages, slogs - reference to rdevice */ struct dm_list rsites; /* For replicators - all sites */ + /* A shared-snapshot segment for this origin */ + struct lv_segment *shared_snapshot; + struct dm_list segments; struct dm_list tags; struct dm_list segs_using_this_lv; @@ -721,6 +724,7 @@ int lv_is_virtual_origin(const struct lo int lv_is_cow(const struct logical_volume *lv); int lv_is_merging_origin(const struct logical_volume *origin); int lv_is_merging_cow(const struct logical_volume *snapshot); +int lv_is_multisnap_origin(const struct logical_volume *lv); /* Test if given LV is visible from user's perspective */ int lv_is_visible(const struct logical_volume *lv); Index: LVM2.2.02.73/lib/metadata/snapshot_manip.c =================================================================== --- LVM2.2.02.73.orig/lib/metadata/snapshot_manip.c 2010-09-10 17:44:56.000000000 +0200 +++ LVM2.2.02.73/lib/metadata/snapshot_manip.c 2010-09-10 17:45:05.000000000 +0200 @@ -30,6 +30,11 @@ int lv_is_cow(const struct logical_volum return (!lv_is_origin(lv) && lv->snapshot) ? 1 : 0; } +int lv_is_multisnap_origin(const struct logical_volume *lv) +{ + return lv_is_origin(lv) && lv->shared_snapshot; +} + int lv_is_visible(const struct logical_volume *lv) { if (lv->status & SNAPSHOT) @@ -116,6 +121,15 @@ int init_snapshot_seg(struct lv_segment if (merge) init_snapshot_merge(seg, origin); + if (seg->status & SNAPSHOT_SHARED) { + if (!origin->shared_snapshot) { + origin->shared_snapshot = seg; + } else { + log_err("Origin '%s' has already a shared snapshot.", origin->name); + return_0; + } + } + dm_list_add(&origin->snapshot_segs, &seg->origin_list); return 1; @@ -169,6 +183,11 @@ int vg_add_snapshot(struct logical_volum return 0; } + if (snapshot_flags & SNAPSHOT_SHARED && origin->shared_snapshot) { + log_error("Origin has already a shared snapshot."); + return 0; + } + if (!(snap = lv_create_empty("snapshot%d", lvid, LVM_READ | LVM_WRITE | VISIBLE_LV, ALLOC_INHERIT, origin->vg))) @@ -211,6 +230,9 @@ int vg_remove_snapshot(struct logical_vo } } + if (cow->snapshot->origin->shared_snapshot == cow->snapshot) + cow->snapshot->origin->shared_snapshot = NULL; + if (!lv_remove(cow->snapshot->lv)) { log_error("Failed to remove internal snapshot LV %s", cow->snapshot->lv->name);