From 7f4078ff3ae0baf0a6df52f14c0a0680366931f8 Mon Sep 17 00:00:00 2001 From: Mikulas Patocka Date: Mon, 21 Jul 2008 12:00:34 +0100 Subject: [PATCH] --- yaml --- r: 104294 b: refs/heads/master c: a8d41b59f3f5a7ac19452ef442a7fc1b5fa17366 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/md/dm-snap.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index c61f1428b95a..b2301be2244a 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: cd45daffd1f7b53aac0835b23e97f814ec3f10dc +refs/heads/master: a8d41b59f3f5a7ac19452ef442a7fc1b5fa17366 diff --git a/trunk/drivers/md/dm-snap.c b/trunk/drivers/md/dm-snap.c index de302702ab3e..f4fd0cee9c3d 100644 --- a/trunk/drivers/md/dm-snap.c +++ b/trunk/drivers/md/dm-snap.c @@ -134,6 +134,27 @@ static void stop_tracking_chunk(struct dm_snapshot *s, mempool_free(c, s->tracked_chunk_pool); } +static int __chunk_is_tracked(struct dm_snapshot *s, chunk_t chunk) +{ + struct dm_snap_tracked_chunk *c; + struct hlist_node *hn; + int found = 0; + + spin_lock_irq(&s->tracked_chunk_lock); + + hlist_for_each_entry(c, hn, + &s->tracked_chunk_hash[DM_TRACKED_CHUNK_HASH(chunk)], node) { + if (c->chunk == chunk) { + found = 1; + break; + } + } + + spin_unlock_irq(&s->tracked_chunk_lock); + + return found; +} + /* * One of these per registered origin, held in the snapshot_origins hash */ @@ -839,6 +860,13 @@ static void pending_complete(struct dm_snap_pending_exception *pe, int success) goto out; } + /* + * Check for conflicting reads. This is extremely improbable, + * so yield() is sufficient and there is no need for a wait queue. + */ + while (__chunk_is_tracked(s, pe->e.old_chunk)) + yield(); + /* * Add a proper exception, and remove the * in-flight exception from the list.