Commit aa14edeb994f8f7e223d02ad14780bf2fa719f6d

Authored by Alasdair G Kergon
Committed by Linus Torvalds
1 parent cb82a6cdf9

[PATCH] device-mapper snapshot: load metadata on creation

Move snapshot metadata loading to happen when the table is created instead of
when the device is resumed.  Writes to the origin device don't trigger
exceptions until each snapshot table becomes active when resume() is called on
each snapshot.

If you're using lvm2, for this patch to work properly you should update to
lvm2 version 2.02.01 or later and device-mapper version 1.02.02 or later.

Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>

Showing 2 changed files with 15 additions and 12 deletions Side-by-side Diff

drivers/md/dm-snap.c
... ... @@ -373,16 +373,11 @@
373 373  
374 374 static void read_snapshot_metadata(struct dm_snapshot *s)
375 375 {
376   - if (s->have_metadata)
377   - return;
378   -
379 376 if (s->store.read_metadata(&s->store)) {
380 377 down_write(&s->lock);
381 378 s->valid = 0;
382 379 up_write(&s->lock);
383 380 }
384   -
385   - s->have_metadata = 1;
386 381 }
387 382  
388 383 /*
... ... @@ -471,7 +466,7 @@
471 466 s->chunk_shift = ffs(chunk_size) - 1;
472 467  
473 468 s->valid = 1;
474   - s->have_metadata = 0;
  469 + s->active = 0;
475 470 s->last_percent = 0;
476 471 init_rwsem(&s->lock);
477 472 s->table = ti->table;
478 473  
... ... @@ -506,7 +501,11 @@
506 501 goto bad5;
507 502 }
508 503  
  504 + /* Metadata must only be loaded into one table at once */
  505 + read_snapshot_metadata(s);
  506 +
509 507 /* Add snapshot to the list of snapshots for this origin */
  508 + /* Exceptions aren't triggered till snapshot_resume() is called */
510 509 if (register_snapshot(s)) {
511 510 r = -EINVAL;
512 511 ti->error = "Cannot register snapshot origin";
... ... @@ -862,7 +861,9 @@
862 861 {
863 862 struct dm_snapshot *s = (struct dm_snapshot *) ti->private;
864 863  
865   - read_snapshot_metadata(s);
  864 + down_write(&s->lock);
  865 + s->active = 1;
  866 + up_write(&s->lock);
866 867 }
867 868  
868 869 static int snapshot_status(struct dm_target *ti, status_type_t type,
... ... @@ -932,8 +933,8 @@
932 933 /* Do all the snapshots on this origin */
933 934 list_for_each_entry (snap, snapshots, list) {
934 935  
935   - /* Only deal with valid snapshots */
936   - if (!snap->valid)
  936 + /* Only deal with valid and active snapshots */
  937 + if (!snap->valid || !snap->active)
937 938 continue;
938 939  
939 940 /* Nothing to do if writing beyond end of snapshot */
... ... @@ -1104,7 +1105,7 @@
1104 1105  
1105 1106 static struct target_type origin_target = {
1106 1107 .name = "snapshot-origin",
1107   - .version = {1, 0, 1},
  1108 + .version = {1, 1, 0},
1108 1109 .module = THIS_MODULE,
1109 1110 .ctr = origin_ctr,
1110 1111 .dtr = origin_dtr,
... ... @@ -1115,7 +1116,7 @@
1115 1116  
1116 1117 static struct target_type snapshot_target = {
1117 1118 .name = "snapshot",
1118   - .version = {1, 0, 1},
  1119 + .version = {1, 1, 0},
1119 1120 .module = THIS_MODULE,
1120 1121 .ctr = snapshot_ctr,
1121 1122 .dtr = snapshot_dtr,
drivers/md/dm-snap.h
... ... @@ -99,7 +99,9 @@
99 99  
100 100 /* You can't use a snapshot if this is 0 (e.g. if full) */
101 101 int valid;
102   - int have_metadata;
  102 +
  103 + /* Origin writes don't trigger exceptions until this is set */
  104 + int active;
103 105  
104 106 /* Used for display of table */
105 107 char type;