From: Alasdair G Kergon Date: Tue, 3 Oct 2006 08:15:29 +0000 (-0700) Subject: [PATCH] dm snapshot: tidy pending_complete X-Git-Tag: v2.6.19-rc1~271 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9d493fa8c943ed4ec6e42b7ebfd8f0b7657d54f8;p=linux-2.6 [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 Signed-off-by: Mark McLoughlin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c index c5449f2504..d92980177b 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,41 +652,39 @@ 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)