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. 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/metadata.c | 5 ++++- lib/metadata/snapshot_manip.c | 12 +++++++----- 6 files changed, 16 insertions(+), 14 deletions(-) Index: lvm2/lib/format_text/flags.c =================================================================== --- lvm2.orig/lib/format_text/flags.c +++ lvm2/lib/format_text/flags.c @@ -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/lib/metadata/lv_alloc.h =================================================================== --- lvm2.orig/lib/metadata/lv_alloc.h +++ lvm2/lib/metadata/lv_alloc.h @@ -30,7 +30,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/lib/metadata/lv_manip.c =================================================================== --- lvm2.orig/lib/metadata/lv_manip.c +++ lvm2/lib/metadata/lv_manip.c @@ -216,7 +216,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; @@ -1880,7 +1880,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/lib/metadata/metadata-exported.h =================================================================== --- lvm2.orig/lib/metadata/metadata-exported.h +++ lvm2/lib/metadata/metadata-exported.h @@ -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 LVM_READ 0x00000100U /* LV VG */ #define LVM_WRITE 0x00000200U /* LV VG */ @@ -335,9 +335,6 @@ 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; @@ -661,7 +658,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/lib/metadata/snapshot_manip.c =================================================================== --- lvm2.orig/lib/metadata/snapshot_manip.c +++ lvm2/lib/metadata/snapshot_manip.c @@ -32,7 +32,7 @@ int lv_is_cow(const struct logical_volum int lv_is_multisnap_origin(const struct logical_volume *lv) { - return lv_is_origin(lv) && lv->shared_snapshot; + return lv_is_origin(lv) && (lv->status & SNAPSHOT_SHARED); } int lv_is_multisnap_cow(const struct logical_volume *lv) @@ -99,7 +99,7 @@ struct lv_segment *find_shared_cow(const if (!lv_is_multisnap_origin(origin)) return NULL; - return origin->shared_snapshot; + return find_cow(origin); } /* Given a cow LV, return its origin */ @@ -111,12 +111,14 @@ struct logical_volume *origin_from_cow(c static void init_shared_snapshot(struct lv_segment *cow_seg, struct logical_volume *origin) { - origin->shared_snapshot = cow_seg; + 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, @@ -194,7 +196,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) + uint32_t chunk_size, uint64_t snapshot_flags) { struct logical_volume *snap; struct lv_segment *seg; Index: lvm2/lib/metadata/metadata.c =================================================================== --- lvm2.orig/lib/metadata/metadata.c +++ lvm2/lib/metadata/metadata.c @@ -1848,9 +1848,12 @@ unsigned snapshot_count(const struct vol struct lv_list *lvl; unsigned num_snapshots = 0; - dm_list_iterate_items(lvl, &vg->lvs) + dm_list_iterate_items(lvl, &vg->lvs) { + if (lv_is_shared_cow(lvl->lv)) + continue; if (lv_is_cow(lvl->lv)) num_snapshots++; + } return num_snapshots; }