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.53/lib/metadata/lv_manip.c =================================================================== --- LVM2.2.02.53.orig/lib/metadata/lv_manip.c 2009-10-13 01:52:59.000000000 +0200 +++ LVM2.2.02.53/lib/metadata/lv_manip.c 2009-10-13 02:04:47.000000000 +0200 @@ -1872,6 +1872,7 @@ int vg_max_lv_reached(struct volume_grou void lv_init(struct logical_volume *lv) { lv->snapshot = NULL; + lv->shared_snapshot = NULL; dm_list_init(&lv->snapshot_segs); dm_list_init(&lv->segments); dm_list_init(&lv->tags); @@ -2930,6 +2931,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.53/lib/metadata/metadata-exported.h =================================================================== --- LVM2.2.02.53.orig/lib/metadata/metadata-exported.h 2009-10-13 01:53:18.000000000 +0200 +++ LVM2.2.02.53/lib/metadata/metadata-exported.h 2009-10-13 02:04:47.000000000 +0200 @@ -322,6 +322,9 @@ struct logical_volume { struct dm_list snapshot_segs; struct lv_segment *snapshot; + /* 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; @@ -605,6 +608,7 @@ struct lv_segment *first_seg(const struc int lv_is_origin(const struct logical_volume *lv); int lv_is_virtual_origin(const struct logical_volume *lv); int lv_is_cow(const struct logical_volume *lv); +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.53/lib/metadata/snapshot_manip.c =================================================================== --- LVM2.2.02.53.orig/lib/metadata/snapshot_manip.c 2009-10-13 01:54:33.000000000 +0200 +++ LVM2.2.02.53/lib/metadata/snapshot_manip.c 2009-10-13 02:06:03.000000000 +0200 @@ -28,6 +28,11 @@ int lv_is_cow(const struct logical_volum return 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) @@ -90,6 +95,15 @@ int init_snapshot_seg(struct lv_segment } } + 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; @@ -116,6 +130,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))) @@ -136,6 +155,9 @@ int vg_remove_snapshot(struct logical_vo dm_list_del(&cow->snapshot->origin_list); cow->snapshot->origin->origin_count--; + 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);