Eliminate 'shared_snapshot' from 'struct logical_volume' and just use 'snapshot' for origin lv's reference to the shared snapshot store; also set SNAPSHOT_SHARED in the origin lv's status. Move SNAPSHOT_SHARED flag so it doesn't overlap with legacy hole in flags. Change 'snapshot_flags' to be 64bit. lv_is_visible() was updated to be aware that a -shared cow device is not visible. This enables vg_validate() to succeed. As a result, these changes enable the following test to succeed: lvcreate -n testlv1 -L 4G test lvcreate -L 1G --sharedstore mikulas -s test/testlv1 lvcreate -s -n testlv1_snap test/testlv1 lvremove test/testlv1 Do you really want to remove active logical volume testlv1_snap? [y/n]: y Logical volume "testlv1_snap" successfully removed Logical volume "testlv1-shared" successfully removed Do you really want to remove active logical volume testlv1? [y/n]: y Logical volume "testlv1" successfully removed Without these changes the above test would fail with: Do you really want to remove active logical volume testlv1_snap? [y/n]: y Internal error: #internal LVs (3) != #LVs (2) + #snapshots (1) + #internal LVs 1 in VG test Signed-off-by: Mike Snitzer --- lib/format_text/flags.c | 1 + lib/metadata/lv.h | 3 --- lib/metadata/lv_alloc.h | 2 +- lib/metadata/lv_manip.c | 3 +-- lib/metadata/metadata-exported.h | 4 ++-- lib/metadata/snapshot_manip.c | 16 +++++++++++----- 6 files changed, 16 insertions(+), 13 deletions(-) Index: LVM2.2.02.85/lib/format_text/flags.c =================================================================== --- LVM2.2.02.85.orig/lib/format_text/flags.c 2011-05-20 14:57:08.000000000 +0200 +++ LVM2.2.02.85/lib/format_text/flags.c 2011-05-23 16:08:02.000000000 +0200 @@ -61,6 +61,7 @@ static const struct flag _lv_flags[] = { {MIRRORED, NULL, 0}, {VIRTUAL, NULL, 0}, {SNAPSHOT, NULL, 0}, + {SNAPSHOT_SHARED, NULL, 0}, {MERGING, NULL, 0}, {ACTIVATE_EXCL, NULL, 0}, {CONVERTING, NULL, 0}, Index: LVM2.2.02.85/lib/metadata/lv_alloc.h =================================================================== --- LVM2.2.02.85.orig/lib/metadata/lv_alloc.h 2011-05-23 15:59:19.000000000 +0200 +++ LVM2.2.02.85/lib/metadata/lv_alloc.h 2011-05-23 16:08:02.000000000 +0200 @@ -31,7 +31,7 @@ struct lv_segment *alloc_lv_segment(stru struct lv_segment *alloc_snapshot_seg(struct logical_volume *lv, uint64_t status, uint32_t old_le_count, - uint32_t snapshot_flags); + uint64_t snapshot_flags); int set_lv_segment_area_pv(struct lv_segment *seg, uint32_t area_num, struct physical_volume *pv, uint32_t pe); Index: LVM2.2.02.85/lib/metadata/lv_manip.c =================================================================== --- LVM2.2.02.85.orig/lib/metadata/lv_manip.c 2011-05-23 16:07:54.000000000 +0200 +++ LVM2.2.02.85/lib/metadata/lv_manip.c 2011-05-23 16:08:02.000000000 +0200 @@ -253,7 +253,7 @@ struct lv_segment *alloc_lv_segment(stru struct lv_segment *alloc_snapshot_seg(struct logical_volume *lv, uint64_t status, uint32_t old_le_count, - uint32_t snapshot_flags) + uint64_t snapshot_flags) { struct lv_segment *seg; const struct segment_type *segtype; @@ -2484,7 +2484,6 @@ 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); Index: LVM2.2.02.85/lib/metadata/metadata-exported.h =================================================================== --- LVM2.2.02.85.orig/lib/metadata/metadata-exported.h 2011-05-23 16:07:58.000000000 +0200 +++ LVM2.2.02.85/lib/metadata/metadata-exported.h 2011-05-23 16:08:02.000000000 +0200 @@ -65,7 +65,6 @@ //#define ACTIVATE_EXCL 0x00100000U /* LV - internal use only */ //#define PRECOMMITTED 0x00200000U /* VG - internal use only */ #define CONVERTING 0x00400000U /* LV */ -#define SNAPSHOT_SHARED 0x02000000U /* SEG */ #define MISSING_PV 0x00800000U /* PV */ #define PARTIAL_LV 0x01000000U /* LV - derived flag, not @@ -76,6 +75,7 @@ //#define VIRTUAL_ORIGIN 0x08000000U /* LV - internal use only */ #define MERGING 0x10000000U /* LV SEG */ +#define SNAPSHOT_SHARED 0x20000000U /* LV SEG */ #define REPLICATOR 0x20000000U /* LV -internal use only for replicator */ #define REPLICATOR_LOG 0x40000000U /* LV -internal use only for replicator-dev */ @@ -654,7 +654,7 @@ void clear_snapshot_merge(struct logical int vg_add_snapshot(struct logical_volume *origin, struct logical_volume *cow, union lvid *lvid, uint32_t extent_count, const char *exception_store, uint32_t chunk_size, - unsigned snapshot_flags); + uint64_t snapshot_flags); int vg_remove_snapshot(struct logical_volume *cow); Index: LVM2.2.02.85/lib/metadata/snapshot_manip.c =================================================================== --- LVM2.2.02.85.orig/lib/metadata/snapshot_manip.c 2011-05-23 16:07:58.000000000 +0200 +++ LVM2.2.02.85/lib/metadata/snapshot_manip.c 2011-05-23 16:08:02.000000000 +0200 @@ -43,6 +43,9 @@ int lv_is_visible(const struct logical_v if (lv_is_merging_cow(lv)) return 0; + if (lv_is_shared_cow(lv)) + return 0; + return lv_is_visible(origin_from_cow(lv)); } @@ -75,7 +78,7 @@ int lv_is_merging_cow(const struct logic int lv_is_multisnap_origin(const struct logical_volume *origin) { - return (origin->shared_snapshot) ? 1 : 0; + return (origin->status & SNAPSHOT_SHARED) ? 1 : 0; } struct lv_segment *find_shared_cow(const struct logical_volume *origin) @@ -83,7 +86,7 @@ struct lv_segment *find_shared_cow(const if (!lv_is_multisnap_origin(origin)) return NULL; - return origin->shared_snapshot; + return find_cow(origin); } int lv_is_shared_cow(const struct logical_volume *lv) @@ -140,12 +143,15 @@ void clear_snapshot_merge(struct logical static void init_shared_snapshot(struct lv_segment *cow_seg, struct logical_volume *origin) { - origin->shared_snapshot = cow_seg; + cow_seg->lv->status &= ~VISIBLE_LV; + origin->snapshot = cow_seg; + origin->status |= SNAPSHOT_SHARED; } static void clear_shared_snapshot(struct logical_volume *origin) { - origin->shared_snapshot = NULL; + origin->snapshot = NULL; + origin->status &= ~SNAPSHOT_SHARED; } int init_snapshot_seg(struct lv_segment *seg, struct logical_volume *origin, @@ -196,7 +202,7 @@ int init_snapshot_seg(struct lv_segment int vg_add_snapshot(struct logical_volume *origin, struct logical_volume *cow, union lvid *lvid, uint32_t extent_count, const char *exception_store, - uint32_t chunk_size, unsigned snapshot_flags) + uint32_t chunk_size, uint64_t snapshot_flags) { struct logical_volume *snap; struct lv_segment *seg; Index: LVM2.2.02.85/lib/metadata/lv.h =================================================================== --- LVM2.2.02.85.orig/lib/metadata/lv.h 2011-05-23 15:59:26.000000000 +0200 +++ LVM2.2.02.85/lib/metadata/lv.h 2011-05-23 16:08:02.000000000 +0200 @@ -43,9 +43,6 @@ 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;