--- lib/metadata/lv_manip.c | 1 + lib/metadata/metadata-exported.h | 3 +++ lib/metadata/snapshot_manip.c | 10 ++++++++-- tools/lvcreate.c | 5 +++++ 4 files changed, 17 insertions(+), 2 deletions(-) Index: LVM2.2.02.45/lib/metadata/lv_manip.c =================================================================== --- LVM2.2.02.45.orig/lib/metadata/lv_manip.c 2009-05-19 21:13:23.000000000 +0200 +++ LVM2.2.02.45/lib/metadata/lv_manip.c 2009-05-19 21:13:31.000000000 +0200 @@ -1825,6 +1825,7 @@ void lv_init(struct logical_volume *lv) { lv->snapshot = NULL; lv->merging_snapshot = NULL; + lv->shared_snapshot = NULL; dm_list_init(&lv->snapshot_segs); dm_list_init(&lv->segments); dm_list_init(&lv->tags); Index: LVM2.2.02.45/lib/metadata/metadata-exported.h =================================================================== --- LVM2.2.02.45.orig/lib/metadata/metadata-exported.h 2009-05-19 21:13:23.000000000 +0200 +++ LVM2.2.02.45/lib/metadata/metadata-exported.h 2009-05-19 21:13:31.000000000 +0200 @@ -339,6 +339,9 @@ struct logical_volume { /* A snapshot that is merging into this origin */ struct lv_segment *merging_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; Index: LVM2.2.02.45/lib/metadata/snapshot_manip.c =================================================================== --- LVM2.2.02.45.orig/lib/metadata/snapshot_manip.c 2009-05-19 21:13:23.000000000 +0200 +++ LVM2.2.02.45/lib/metadata/snapshot_manip.c 2009-05-19 21:13:31.000000000 +0200 @@ -77,8 +77,9 @@ int vg_add_snapshot(const char *name, st return 0; } - if (cow->status & SNAPSHOT_MERGE && origin->merging_snapshot) { - log_error("Origin has already merging snapshot."); + if (cow->status & (SNAPSHOT_MERGE | SNAPSHOT_SHARED) && + (origin->merging_snapshot || origin->shared_snapshot)) { + log_error("Origin has already merging or shared snapshot."); return 0; } @@ -98,6 +99,8 @@ int vg_add_snapshot(const char *name, st seg->lv->status |= SNAPSHOT; if (snapshot_flags & SNAPSHOT_MERGE) origin->merging_snapshot = seg; + if (snapshot_flags & SNAPSHOT_SHARED) + origin->shared_snapshot = seg; seg->status |= snapshot_flags & (SNAPSHOT_MERGE | SNAPSHOT_MERGE_ON_ACT | SNAPSHOT_SHARED); @@ -120,6 +123,9 @@ int vg_remove_snapshot(struct logical_vo if (cow->snapshot->origin->merging_snapshot == cow->snapshot) cow->snapshot->origin->merging_snapshot = NULL; + 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); Index: LVM2.2.02.45/tools/lvcreate.c =================================================================== --- LVM2.2.02.45.orig/tools/lvcreate.c 2009-05-19 21:13:23.000000000 +0200 +++ LVM2.2.02.45/tools/lvcreate.c 2009-05-19 21:13:31.000000000 +0200 @@ -676,6 +676,11 @@ static int _lvcreate(struct cmd_context "another snapshot is merging"); return 0; } + if (org->shared_snapshot) { + log_error("It is not allowed to create more shared " + "snapshot stores"); + return 0; + } if (org->status & MIRROR_IMAGE || org->status & MIRROR_LOG || org->status & MIRRORED) {