Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 176575
b: refs/heads/master
c: 9d3b15c
h: refs/heads/master
i:
  176573: 4c178fe
  176571: 8682f7f
  176567: 60baedf
  176559: e8a5e5a
  176543: b941878
  176511: 4bc4b11
v: v3
  • Loading branch information
Mikulas Patocka authored and Alasdair G Kergon committed Dec 10, 2009
1 parent 49af7fb commit e4e361c
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 7 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 10b8106a70433e14153469ebbdd189776500e238
refs/heads/master: 9d3b15c4c776b041f9ee81810cbd375275411829
33 changes: 27 additions & 6 deletions trunk/drivers/md/dm-snap.c
Original file line number Diff line number Diff line change
Expand Up @@ -300,8 +300,10 @@ static void __insert_origin(struct origin *o)
* Returns number of snapshots registered using the supplied cow device, plus:
* snap_src - a snapshot suitable for use as a source of exception handover
* snap_dest - a snapshot capable of receiving exception handover.
* snap_merge - an existing snapshot-merge target linked to the same origin.
* There can be at most one snapshot-merge target. The parameter is optional.
*
* Possible return values and states:
* Possible return values and states of snap_src and snap_dest.
* 0: NULL, NULL - first new snapshot
* 1: snap_src, NULL - normal snapshot
* 2: snap_src, snap_dest - waiting for handover
Expand All @@ -310,7 +312,8 @@ static void __insert_origin(struct origin *o)
*/
static int __find_snapshots_sharing_cow(struct dm_snapshot *snap,
struct dm_snapshot **snap_src,
struct dm_snapshot **snap_dest)
struct dm_snapshot **snap_dest,
struct dm_snapshot **snap_merge)
{
struct dm_snapshot *s;
struct origin *o;
Expand All @@ -322,6 +325,8 @@ static int __find_snapshots_sharing_cow(struct dm_snapshot *snap,
goto out;

list_for_each_entry(s, &o->snapshots, list) {
if (dm_target_is_snapshot_merge(s->ti) && snap_merge)
*snap_merge = s;
if (!bdev_equal(s->cow->bdev, snap->cow->bdev))
continue;

Expand Down Expand Up @@ -349,9 +354,11 @@ static int __find_snapshots_sharing_cow(struct dm_snapshot *snap,
static int __validate_exception_handover(struct dm_snapshot *snap)
{
struct dm_snapshot *snap_src = NULL, *snap_dest = NULL;
struct dm_snapshot *snap_merge = NULL;

/* Does snapshot need exceptions handed over to it? */
if ((__find_snapshots_sharing_cow(snap, &snap_src, &snap_dest) == 2) ||
if ((__find_snapshots_sharing_cow(snap, &snap_src, &snap_dest,
&snap_merge) == 2) ||
snap_dest) {
snap->ti->error = "Snapshot cow pairing for exception "
"table handover failed";
Expand All @@ -365,6 +372,20 @@ static int __validate_exception_handover(struct dm_snapshot *snap)
if (!snap_src)
return 0;

/*
* Non-snapshot-merge handover?
*/
if (!dm_target_is_snapshot_merge(snap->ti))
return 1;

/*
* Do not allow more than one merging snapshot.
*/
if (snap_merge) {
snap->ti->error = "A snapshot is already merging.";
return -EINVAL;
}

return 1;
}

Expand Down Expand Up @@ -933,7 +954,7 @@ static void snapshot_dtr(struct dm_target *ti)

down_read(&_origins_lock);
/* Check whether exception handover must be cancelled */
(void) __find_snapshots_sharing_cow(s, &snap_src, &snap_dest);
(void) __find_snapshots_sharing_cow(s, &snap_src, &snap_dest, NULL);
if (snap_src && snap_dest && (s == snap_src)) {
down_write(&snap_dest->lock);
snap_dest->valid = 0;
Expand Down Expand Up @@ -1399,7 +1420,7 @@ static int snapshot_preresume(struct dm_target *ti)
struct dm_snapshot *snap_src = NULL, *snap_dest = NULL;

down_read(&_origins_lock);
(void) __find_snapshots_sharing_cow(s, &snap_src, &snap_dest);
(void) __find_snapshots_sharing_cow(s, &snap_src, &snap_dest, NULL);
if (snap_src && snap_dest) {
down_read(&snap_src->lock);
if (s == snap_src) {
Expand All @@ -1424,7 +1445,7 @@ static void snapshot_resume(struct dm_target *ti)
struct dm_snapshot *snap_src = NULL, *snap_dest = NULL;

down_read(&_origins_lock);
(void) __find_snapshots_sharing_cow(s, &snap_src, &snap_dest);
(void) __find_snapshots_sharing_cow(s, &snap_src, &snap_dest, NULL);
if (snap_src && snap_dest) {
down_write(&snap_src->lock);
down_write_nested(&snap_dest->lock, SINGLE_DEPTH_NESTING);
Expand Down

0 comments on commit e4e361c

Please sign in to comment.