From: Mike Snitzer <snitzer@redhat.com>
To: dm-devel@redhat.com
Cc: Mikulas Patocka <mpatocka@redhat.com>
Subject: Re: [PATCH 3/4] dm-snapshot-exception-handover
Date: Tue, 6 Oct 2009 10:38:05 -0400 [thread overview]
Message-ID: <20091006143805.GB19024@redhat.com> (raw)
In-Reply-To: <1254769231-12053-4-git-send-email-snitzer@redhat.com>
On Mon, Oct 05 2009 at 3:00pm -0400,
Mike Snitzer <snitzer@redhat.com> wrote:
> From: Mikulas Patocka <mpatocka@redhat.com>
>
> Handover of the exception store. This is needed for merging (to allow reload of
> the table) and it also enables origin or snapshot resize.
>
> The supported call sequences are:
>
> new_snapshot->ctr
> old_snapshot->suspend
> old_snapshot->dtr
> new_snapshot->resume
>
> and
>
> new_snapshot->ctr
> old_snapshot->suspend
> new_snapshot->resume
> old_snapshot->dtr
>
> There may not be more than two instances of a given snapshot. LVM always creates
> at most two; if there are more, the user misuses dmsetup.
>
> Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
...
> +/* _origins_lock must be held */
> +static struct dm_snapshot *find_duplicate(struct dm_snapshot *snap)
> +{
...
I just noticed that find_duplicate should be renamed to __find_duplicate
to use the convention of a '__' prefix on all dm-snap.c functions that
require the _origins_lock.
Here is an updated patch (doesn't change any snapshot-merge patches that
follow):
Handover of the exception store. This is needed for merging (to allow reload of
the table) and it also enables origin or snapshot resize.
The supported call sequences are:
new_snapshot->ctr
old_snapshot->suspend
old_snapshot->dtr
new_snapshot->resume
and
new_snapshot->ctr
old_snapshot->suspend
new_snapshot->resume
old_snapshot->dtr
There may not be more than two instances of a given snapshot. LVM always creates
at most two; if there are more, the user misuses dmsetup.
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>
---
drivers/md/dm-snap.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 85 insertions(+)
Index: linux-2.6/drivers/md/dm-snap.c
===================================================================
--- linux-2.6.orig/drivers/md/dm-snap.c
+++ linux-2.6/drivers/md/dm-snap.c
@@ -72,6 +72,9 @@ struct dm_snapshot {
/* Origin writes don't trigger exceptions until this is set */
int active;
+ /* Exception store will be handed over from another snapshot */
+ int handover;
+
mempool_t *pending_pool;
atomic_t pending_exceptions_count;
@@ -505,6 +508,33 @@ static int dm_add_exception(void *contex
return 0;
}
+/* _origins_lock must be held */
+static struct dm_snapshot *__find_duplicate(struct dm_snapshot *snap)
+{
+ struct dm_snapshot *dup;
+ struct dm_snapshot *l;
+ struct origin *o;
+
+ o = __lookup_origin(snap->origin->bdev);
+ if (!o)
+ return NULL;
+
+ dup = NULL;
+ list_for_each_entry(l, &o->snapshots, list)
+ if (l != snap && bdev_equal(l->cow->bdev,
+ snap->cow->bdev)) {
+ if (!dup) {
+ dup = l;
+ } else {
+ DMERR("Multiple active duplicates, "
+ "user misuses dmsetup.");
+ return NULL;
+ }
+ }
+
+ return dup;
+}
+
#define min_not_zero(l, r) (((l) == 0) ? (r) : (((r) == 0) ? (l) : min(l, r)))
/*
@@ -635,6 +665,7 @@ static int snapshot_ctr(struct dm_target
s->valid = 1;
s->active = 0;
atomic_set(&s->pending_exceptions_count, 0);
+ s->handover = 0;
init_rwsem(&s->lock);
spin_lock_init(&s->pe_lock);
@@ -670,6 +701,11 @@ static int snapshot_ctr(struct dm_target
spin_lock_init(&s->tracked_chunk_lock);
+ down_read(&_origins_lock);
+ if (__find_duplicate(s))
+ s->handover = 1;
+ up_read(&_origins_lock);
+
/* Metadata must only be loaded into one table at once */
r = s->store->type->read_metadata(s->store, dm_add_exception,
(void *)s);
@@ -741,15 +777,49 @@ static void __free_exceptions(struct dm_
exit_exception_table(&s->complete, exception_cache);
}
+static void handover_exceptions(struct dm_snapshot *old,
+ struct dm_snapshot *new)
+{
+ union {
+ struct exception_table table_swap;
+ struct dm_exception_store *store_swap;
+ } u;
+
+ u.table_swap = new->complete;
+ new->complete = old->complete;
+ old->complete = u.table_swap;
+ u.store_swap = new->store;
+ new->store = old->store;
+ old->store = u.store_swap;
+
+ new->store->snap = new;
+ old->store->snap = old;
+
+ old->active = 0;
+ new->handover = 0;
+}
+
static void snapshot_dtr(struct dm_target *ti)
{
#ifdef CONFIG_DM_DEBUG
int i;
#endif
struct dm_snapshot *s = ti->private;
+ struct dm_snapshot *dup;
flush_workqueue(ksnapd);
+ down_write(&_origins_lock);
+ down_write(&s->lock);
+ dup = __find_duplicate(s);
+ if (dup && dup->handover) {
+ down_write_nested(&dup->lock, SINGLE_DEPTH_NESTING);
+ handover_exceptions(s, dup);
+ up_write(&dup->lock);
+ }
+ up_write(&s->lock);
+ up_write(&_origins_lock);
+
/* Prevent further origin writes from using this snapshot. */
/* After this returns there can be no new kcopyd jobs. */
unregister_snapshot(s);
@@ -1144,9 +1214,24 @@ static void snapshot_resume(struct dm_ta
{
struct dm_snapshot *s = ti->private;
+ down_write(&_origins_lock);
down_write(&s->lock);
+ if (s->handover) {
+ struct dm_snapshot *dup;
+ dup = __find_duplicate(s);
+ if (!dup) {
+ DMERR("duplicate not found");
+ s->valid = 0;
+ goto ret;
+ }
+ down_write_nested(&dup->lock, SINGLE_DEPTH_NESTING);
+ handover_exceptions(dup, s);
+ up_write(&dup->lock);
+ }
s->active = 1;
+ ret:
up_write(&s->lock);
+ up_write(&_origins_lock);
}
static int snapshot_status(struct dm_target *ti, status_type_t type,
next prev parent reply other threads:[~2009-10-06 14:38 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-10-05 19:00 [PATCH 0/4] snapshot-merge preparation Mike Snitzer
2009-10-05 19:00 ` [PATCH 1/4] dm-snapshot-rework-origin-write Mike Snitzer
2009-10-06 14:17 ` Mike Snitzer
2009-10-07 17:39 ` Jonathan Brassow
2009-10-05 19:00 ` [PATCH 2/4] dm-snapshot-refactor-associations Mike Snitzer
2009-10-07 17:38 ` Jonathan Brassow
2009-10-07 18:24 ` Mike Snitzer
2009-10-08 17:32 ` Mike Snitzer
2009-10-08 21:14 ` Jonathan Brassow
2009-10-05 19:00 ` [PATCH 3/4] dm-snapshot-exception-handover Mike Snitzer
2009-10-06 14:38 ` Mike Snitzer [this message]
2009-10-07 17:42 ` Jonathan Brassow
2009-10-05 19:00 ` [PATCH 4/4] dm-exception-store-dont-read-metadata-if-going-to-handover Mike Snitzer
2009-10-07 17:48 ` Jonathan Brassow
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20091006143805.GB19024@redhat.com \
--to=snitzer@redhat.com \
--cc=dm-devel@redhat.com \
--cc=mpatocka@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.