diff options
author | Adrian Bunk <bunk@stusta.de> | 2006-02-03 17:49:49 -0500 |
---|---|---|
committer | Adrian Bunk <bunk@r063144.stusta.swh.mhn.de> | 2006-02-03 17:49:49 -0500 |
commit | 01d206a7c1167639f6ca6dac22140fbdca017558 (patch) | |
tree | bc3ccf1a8140a7f787c4728cfa4c30e65ad56eb2 /drivers/md/dm-snap.c | |
parent | 9c4b562abc9005e4b413de02c85d3d29da707cba (diff) | |
parent | d6c8f6aaa1d7f68c1e6471ab0839d9047cdd159f (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.c | 29 |
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 | ||
374 | static void read_snapshot_metadata(struct dm_snapshot *s) | 374 | static 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 | ||
868 | static int snapshot_status(struct dm_target *ti, status_type_t type, | 872 | static 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 | ||
1105 | static struct target_type origin_target = { | 1112 | static 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 | ||
1116 | static struct target_type snapshot_target = { | 1123 | static 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, |