aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-snap.c
diff options
context:
space:
mode:
authorAdrian Bunk <bunk@stusta.de>2006-02-03 17:49:49 -0500
committerAdrian Bunk <bunk@r063144.stusta.swh.mhn.de>2006-02-03 17:49:49 -0500
commit01d206a7c1167639f6ca6dac22140fbdca017558 (patch)
treebc3ccf1a8140a7f787c4728cfa4c30e65ad56eb2 /drivers/md/dm-snap.c
parent9c4b562abc9005e4b413de02c85d3d29da707cba (diff)
parentd6c8f6aaa1d7f68c1e6471ab0839d9047cdd159f (diff)
Merge with git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Diffstat (limited to 'drivers/md/dm-snap.c')
-rw-r--r--drivers/md/dm-snap.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index 87727d84dbba..f3759dd7828e 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -373,16 +373,11 @@ static inline ulong round_up(ulong n, ulong size)
373 373
374static void read_snapshot_metadata(struct dm_snapshot *s) 374static void read_snapshot_metadata(struct dm_snapshot *s)
375{ 375{
376 if (s->have_metadata)
377 return;
378
379 if (s->store.read_metadata(&s->store)) { 376 if (s->store.read_metadata(&s->store)) {
380 down_write(&s->lock); 377 down_write(&s->lock);
381 s->valid = 0; 378 s->valid = 0;
382 up_write(&s->lock); 379 up_write(&s->lock);
383 } 380 }
384
385 s->have_metadata = 1;
386} 381}
387 382
388/* 383/*
@@ -471,7 +466,7 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
471 s->chunk_shift = ffs(chunk_size) - 1; 466 s->chunk_shift = ffs(chunk_size) - 1;
472 467
473 s->valid = 1; 468 s->valid = 1;
474 s->have_metadata = 0; 469 s->active = 0;
475 s->last_percent = 0; 470 s->last_percent = 0;
476 init_rwsem(&s->lock); 471 init_rwsem(&s->lock);
477 s->table = ti->table; 472 s->table = ti->table;
@@ -506,7 +501,11 @@ static int snapshot_ctr(struct dm_target *ti, unsigned int argc, char **argv)
506 goto bad5; 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 /* Add snapshot to the list of snapshots for this origin */ 507 /* Add snapshot to the list of snapshots for this origin */
508 /* Exceptions aren't triggered till snapshot_resume() is called */
510 if (register_snapshot(s)) { 509 if (register_snapshot(s)) {
511 r = -EINVAL; 510 r = -EINVAL;
512 ti->error = "Cannot register snapshot origin"; 511 ti->error = "Cannot register snapshot origin";
@@ -793,6 +792,9 @@ static int snapshot_map(struct dm_target *ti, struct bio *bio,
793 if (!s->valid) 792 if (!s->valid)
794 return -EIO; 793 return -EIO;
795 794
795 if (unlikely(bio_barrier(bio)))
796 return -EOPNOTSUPP;
797
796 /* 798 /*
797 * Write to snapshot - higher level takes care of RW/RO 799 * Write to snapshot - higher level takes care of RW/RO
798 * flags so we should only get this if we are 800 * flags so we should only get this if we are
@@ -862,7 +864,9 @@ static void snapshot_resume(struct dm_target *ti)
862{ 864{
863 struct dm_snapshot *s = (struct dm_snapshot *) ti->private; 865 struct dm_snapshot *s = (struct dm_snapshot *) ti->private;
864 866
865 read_snapshot_metadata(s); 867 down_write(&s->lock);
868 s->active = 1;
869 up_write(&s->lock);
866} 870}
867 871
868static int snapshot_status(struct dm_target *ti, status_type_t type, 872static int snapshot_status(struct dm_target *ti, status_type_t type,
@@ -932,8 +936,8 @@ static int __origin_write(struct list_head *snapshots, struct bio *bio)
932 /* Do all the snapshots on this origin */ 936 /* Do all the snapshots on this origin */
933 list_for_each_entry (snap, snapshots, list) { 937 list_for_each_entry (snap, snapshots, list) {
934 938
935 /* Only deal with valid snapshots */ 939 /* Only deal with valid and active snapshots */
936 if (!snap->valid) 940 if (!snap->valid || !snap->active)
937 continue; 941 continue;
938 942
939 /* Nothing to do if writing beyond end of snapshot */ 943 /* Nothing to do if writing beyond end of snapshot */
@@ -1057,6 +1061,9 @@ static int origin_map(struct dm_target *ti, struct bio *bio,
1057 struct dm_dev *dev = (struct dm_dev *) ti->private; 1061 struct dm_dev *dev = (struct dm_dev *) ti->private;
1058 bio->bi_bdev = dev->bdev; 1062 bio->bi_bdev = dev->bdev;
1059 1063
1064 if (unlikely(bio_barrier(bio)))
1065 return -EOPNOTSUPP;
1066
1060 /* Only tell snapshots if this is a write */ 1067 /* Only tell snapshots if this is a write */
1061 return (bio_rw(bio) == WRITE) ? do_origin(dev, bio) : 1; 1068 return (bio_rw(bio) == WRITE) ? do_origin(dev, bio) : 1;
1062} 1069}
@@ -1104,7 +1111,7 @@ static int origin_status(struct dm_target *ti, status_type_t type, char *result,
1104 1111
1105static struct target_type origin_target = { 1112static struct target_type origin_target = {
1106 .name = "snapshot-origin", 1113 .name = "snapshot-origin",
1107 .version = {1, 0, 1}, 1114 .version = {1, 1, 0},
1108 .module = THIS_MODULE, 1115 .module = THIS_MODULE,
1109 .ctr = origin_ctr, 1116 .ctr = origin_ctr,
1110 .dtr = origin_dtr, 1117 .dtr = origin_dtr,
@@ -1115,7 +1122,7 @@ static struct target_type origin_target = {
1115 1122
1116static struct target_type snapshot_target = { 1123static struct target_type snapshot_target = {
1117 .name = "snapshot", 1124 .name = "snapshot",
1118 .version = {1, 0, 1}, 1125 .version = {1, 1, 0},
1119 .module = THIS_MODULE, 1126 .module = THIS_MODULE,
1120 .ctr = snapshot_ctr, 1127 .ctr = snapshot_ctr,
1121 .dtr = snapshot_dtr, 1128 .dtr = snapshot_dtr,