diff options
author | Alasdair G Kergon <agk@redhat.com> | 2006-10-03 01:15:29 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-03 08:04:14 -0700 |
commit | 9d493fa8c943ed4ec6e42b7ebfd8f0b7657d54f8 (patch) | |
tree | 8d7cac80b09a73058fd491563737a77db47df7de /drivers | |
parent | ba40a2aa6e6f3d084cf35c8b872fc9f18f91231f (diff) | |
download | op-kernel-dev-9d493fa8c943ed4ec6e42b7ebfd8f0b7657d54f8.zip op-kernel-dev-9d493fa8c943ed4ec6e42b7ebfd8f0b7657d54f8.tar.gz |
[PATCH] dm snapshot: tidy pending_complete
This patch rearranges the pending_complete() code so that the functional
changes in subsequent patches are clearer.
By consolidating the error and the non-error paths, we can move
error_snapshot_bios() and __flush_bios() in line.
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/md/dm-snap.c | 76 |
1 files changed, 30 insertions, 46 deletions
diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index c5449f2..d929801 100644 --- a/drivers/md/dm-snap.c +++ b/drivers/md/dm-snap.c @@ -609,26 +609,6 @@ static void error_bios(struct bio *bio) } } -static inline void error_snapshot_bios(struct pending_exception *pe) -{ - error_bios(bio_list_get(&pe->snapshot_bios)); -} - -static struct bio *__flush_bios(struct pending_exception *pe) -{ - /* - * If this pe is involved in a write to the origin and - * it is the last sibling to complete then release - * the bios for the original write to the origin. - */ - - if (pe->primary_pe && - atomic_dec_and_test(&pe->primary_pe->sibling_count)) - return bio_list_get(&pe->primary_pe->origin_bios); - - return NULL; -} - static void __invalidate_snapshot(struct dm_snapshot *s, struct pending_exception *pe, int err) { @@ -656,16 +636,15 @@ static void pending_complete(struct pending_exception *pe, int success) struct exception *e; struct pending_exception *primary_pe; struct dm_snapshot *s = pe->snap; - struct bio *flush = NULL; + struct bio *origin_bios = NULL; + struct bio *snapshot_bios = NULL; + int error = 0; if (!success) { /* Read/write error - snapshot is unusable */ down_write(&s->lock); __invalidate_snapshot(s, pe, -EIO); - flush = __flush_bios(pe); - up_write(&s->lock); - - error_snapshot_bios(pe); + error = 1; goto out; } @@ -673,42 +652,40 @@ static void pending_complete(struct pending_exception *pe, int success) if (!e) { down_write(&s->lock); __invalidate_snapshot(s, pe, -ENOMEM); - flush = __flush_bios(pe); - up_write(&s->lock); - - error_snapshot_bios(pe); + error = 1; goto out; } *e = pe->e; - /* - * Add a proper exception, and remove the - * in-flight exception from the list. - */ down_write(&s->lock); if (!s->valid) { - flush = __flush_bios(pe); - up_write(&s->lock); - free_exception(e); - - error_snapshot_bios(pe); + error = 1; goto out; } + /* + * Add a proper exception, and remove the + * in-flight exception from the list. + */ insert_exception(&s->complete, e); remove_exception(&pe->e); - flush = __flush_bios(pe); - - up_write(&s->lock); - - /* Submit any pending write bios */ - flush_bios(bio_list_get(&pe->snapshot_bios)); out: + snapshot_bios = bio_list_get(&pe->snapshot_bios); + primary_pe = pe->primary_pe; /* + * If this pe is involved in a write to the origin and + * it is the last sibling to complete then release + * the bios for the original write to the origin. + */ + if (primary_pe && + atomic_dec_and_test(&primary_pe->sibling_count)) + origin_bios = bio_list_get(&primary_pe->origin_bios); + + /* * Free the pe if it's not linked to an origin write or if * it's not itself a primary pe. */ @@ -721,8 +698,15 @@ static void pending_complete(struct pending_exception *pe, int success) if (primary_pe && !atomic_read(&primary_pe->sibling_count)) free_pending_exception(primary_pe); - if (flush) - flush_bios(flush); + up_write(&s->lock); + + /* Submit any pending write bios */ + if (error) + error_bios(snapshot_bios); + else + flush_bios(snapshot_bios); + + flush_bios(origin_bios); } static void commit_callback(void *context, int success) |