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_alloc.h | 2 +- lib/metadata/lv_manip.c | 3 +-- lib/metadata/metadata-exported.h | 7 ++----- lib/metadata/snapshot_manip.c | 16 +++++++++++----- 5 files changed, 16 insertions(+), 13 deletions(-) Index: LVM2.2.02.73/lib/format_text/flags.c =================================================================== --- LVM2.2.02.73.orig/lib/format_text/flags.c 2010-05-21 14:36:31.000000000 +0200 +++ LVM2.2.02.73/lib/format_text/flags.c 2010-09-10 19:15:17.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.73/lib/metadata/lv_alloc.h =================================================================== --- LVM2.2.02.73.orig/lib/metadata/lv_alloc.h 2010-09-10 17:44:56.000000000 +0200 +++ LVM2.2.02.73/lib/metadata/lv_alloc.h 2010-09-10 19:15:17.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.73/lib/metadata/lv_manip.c =================================================================== --- LVM2.2.02.73.orig/lib/metadata/lv_manip.c 2010-09-10 19:15:10.000000000 +0200 +++ LVM2.2.02.73/lib/metadata/lv_manip.c 2010-09-10 19:15:17.000000000 +0200 @@ -218,7 +218,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; @@ -2017,7 +2017,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.73/lib/metadata/metadata-exported.h =================================================================== --- LVM2.2.02.73.orig/lib/metadata/metadata-exported.h 2010-09-10 19:15:15.000000000 +0200 +++ LVM2.2.02.73/lib/metadata/metadata-exported.h 2010-09-10 19:15:17.000000000 +0200 @@ -61,7 +61,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 @@ -72,6 +71,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 */ @@ -421,9 +421,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; @@ -757,7 +754,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.73/lib/metadata/snapshot_manip.c =================================================================== --- LVM2.2.02.73.orig/lib/metadata/snapshot_manip.c 2010-09-10 19:15:15.000000000 +0200 +++ LVM2.2.02.73/lib/metadata/snapshot_manip.c 2010-09-10 19:15:17.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;