This patch rearranges the snapshot_map code so that the functional changes in the next patch are clearer. The only functional change is to replace the existing read lock with a write lock which the next patch needs. Index: linux-2.6.14-rc2/drivers/md/dm-snap.c =================================================================== --- linux-2.6.14-rc2.orig/drivers/md/dm-snap.c 2006-01-06 16:58:20.000000000 +0000 +++ linux-2.6.14-rc2/drivers/md/dm-snap.c 2006-01-06 17:23:44.000000000 +0000 @@ -807,42 +807,39 @@ static int snapshot_map(struct dm_target * flags so we should only get this if we are * writeable. */ - if (bio_rw(bio) == WRITE) { - - /* FIXME: should only take write lock if we need - * to copy an exception */ - down_write(&s->lock); - - /* If the block is already remapped - use that, else remap it */ - e = lookup_exception(&s->complete, chunk); - if (e) { - remap_exception(s, e, bio); - up_write(&s->lock); - } else { - pe = __find_pending_exception(s, bio); + /* FIXME: should only take write lock if we need + * to copy an exception */ + down_write(&s->lock); - if (!pe) { - if (s->store.drop_snapshot) - s->store.drop_snapshot(&s->store); - s->valid = 0; - r = -EIO; - up_write(&s->lock); - } else { - remap_exception(s, &pe->e, bio); - bio_list_add(&pe->snapshot_bios, bio); + /* If the block is already remapped - use that, else remap it */ + e = lookup_exception(&s->complete, chunk); + if (e) { + remap_exception(s, e, bio); + goto out_unlock; + } - if (!pe->started) { - /* this is protected by snap->lock */ - pe->started = 1; - up_write(&s->lock); - start_copy(pe); - } else - up_write(&s->lock); - r = 0; - } + if (bio_rw(bio) == WRITE) { + pe = __find_pending_exception(s, bio); + if (!pe) { + if (s->store.drop_snapshot) + s->store.drop_snapshot(&s->store); + s->valid = 0; + r = -EIO; + goto out_unlock; } + remap_exception(s, &pe->e, bio); + bio_list_add(&pe->snapshot_bios, bio); + + r = 0; + if (!pe->started) { + /* this is protected by snap->lock */ + pe->started = 1; + up_write(&s->lock); + start_copy(pe); + goto out; + } } else { /* * FIXME: this read path scares me because we @@ -851,19 +848,12 @@ static int snapshot_map(struct dm_target * situation where this is wrong - ejt. */ - /* Do reads */ - down_read(&s->lock); - - /* See if it it has been remapped */ - e = lookup_exception(&s->complete, chunk); - if (e) - remap_exception(s, e, bio); - else - bio->bi_bdev = s->origin->bdev; - - up_read(&s->lock); + bio->bi_bdev = s->origin->bdev; } + out_unlock: + up_write(&s->lock); + out: return r; }