Re-read exceptions after acquiring the cluster lock. Signed-off-by: Mikulas Patocka --- drivers/md/dm-exception-store.h | 8 ++++++++ drivers/md/dm-snap-persistent.c | 11 +++++++++++ drivers/md/dm-snap.c | 16 ++++++++++++++++ 3 files changed, 35 insertions(+) Index: linux-2.6.31-fast/drivers/md/dm-exception-store.h =================================================================== --- linux-2.6.31-fast.orig/drivers/md/dm-exception-store.h 2009-10-19 12:05:53.000000000 +0200 +++ linux-2.6.31-fast/drivers/md/dm-exception-store.h 2009-10-19 12:50:57.000000000 +0200 @@ -69,6 +69,14 @@ struct dm_exception_store_type { void *callback_context, int will_handover); /* + * Reread new exceptions after some other node added them. + */ + int (*reread_exceptions) (struct dm_exception_store *store, + int (*callback)(void *callback_context, + chunk_t old, chunk_t new), + void *callback_context); + + /* * Find somewhere to store the next exception. */ int (*prepare_exception) (struct dm_exception_store *store, Index: linux-2.6.31-fast/drivers/md/dm-snap-persistent.c =================================================================== --- linux-2.6.31-fast.orig/drivers/md/dm-snap-persistent.c 2009-10-19 12:50:46.000000000 +0200 +++ linux-2.6.31-fast/drivers/md/dm-snap-persistent.c 2009-10-19 12:50:57.000000000 +0200 @@ -616,6 +616,15 @@ static int persistent_read_metadata(stru return r; } +static int persistent_reread_exceptions(struct dm_exception_store *store, + int (*callback)(void *callback_context, + chunk_t old, chunk_t new), + void *callback_context) +{ + struct pstore *ps = get_info(store); + return read_exceptions(ps, callback, callback_context, 1); +} + static int persistent_prepare_exception(struct dm_exception_store *store, struct dm_exception *e) { @@ -833,6 +842,7 @@ static struct dm_exception_store_type _p .ctr = persistent_ctr, .dtr = persistent_dtr, .read_metadata = persistent_read_metadata, + .reread_exceptions = persistent_reread_exceptions, .prepare_exception = persistent_prepare_exception, .commit_exception = persistent_commit_exception, .prepare_merge = persistent_prepare_merge, @@ -848,6 +858,7 @@ static struct dm_exception_store_type _p .ctr = persistent_ctr, .dtr = persistent_dtr, .read_metadata = persistent_read_metadata, + .reread_exceptions = persistent_reread_exceptions, .prepare_exception = persistent_prepare_exception, .commit_exception = persistent_commit_exception, .prepare_merge = persistent_prepare_merge, Index: linux-2.6.31-fast/drivers/md/dm-snap.c =================================================================== --- linux-2.6.31-fast.orig/drivers/md/dm-snap.c 2009-10-19 12:50:42.000000000 +0200 +++ linux-2.6.31-fast/drivers/md/dm-snap.c 2009-10-19 12:53:25.000000000 +0200 @@ -178,6 +178,9 @@ static int bdev_equal(struct block_devic return lhs == rhs; } +static void __invalidate_snapshot(struct dm_snapshot *s, int err); +static int dm_add_exception(void *context, chunk_t old, chunk_t new); + static int snapshot_merge_map(struct dm_target *ti, struct bio *bio, union map_info *map_context); @@ -352,6 +355,12 @@ static void lock_snapshot(struct dm_snap int r = dm_cluster_lock_by_str(lockspace_handle, s->lockid, DM_CLUSTER_LOCK_EXCLUSIVE, NULL, NULL); BUG_ON(r < 0); + if (s->valid && r) { + r = s->store->type->reread_exceptions(s->store, + dm_add_exception, (void *)s); + if (unlikely(r)) + __invalidate_snapshot(s, r); + } } #endif } @@ -977,6 +986,12 @@ static int snapshot_ctr(struct dm_target argv += args_used; argc -= args_used; + if (is_clustered(s) && !s->store->type->reread_exceptions) { + ti->error = "This exception store doesn't support clustering"; + r = -EINVAL; + goto bad_clustered_store; + } + r = dm_get_device(ti, origin_path, 0, ti->len, FMODE_READ, &s->origin); if (r) { ti->error = "Cannot get origin device"; @@ -1111,6 +1126,7 @@ bad_hash_tables: dm_put_device(ti, s->origin); bad_origin: +bad_clustered_store: dm_exception_store_destroy(s->store); bad_clustering: