From: Joe Thornber Make sure that we maintain ordering when deferring bios. --- 25-akpm/drivers/md/dm-bio-list.h | 68 +++++++++++++++++++++++++++++++++++++++ 25-akpm/drivers/md/dm.c | 9 ++--- 2 files changed, 72 insertions(+), 5 deletions(-) diff -puN /dev/null drivers/md/dm-bio-list.h --- /dev/null Thu Apr 11 07:25:15 2002 +++ 25-akpm/drivers/md/dm-bio-list.h Tue Feb 10 13:01:40 2004 @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2004 Red Hat UK Ltd. + * + * This file is released under the GPL. + */ + +#ifndef DM_BIO_LIST_H +#define DM_BIO_LIST_H + +#include + +struct bio_list { + struct bio *head; + struct bio *tail; +}; + +static inline void bio_list_init(struct bio_list *bl) +{ + bl->head = bl->tail = NULL; +} + +static inline void bio_list_add(struct bio_list *bl, struct bio *bio) +{ + bio->bi_next = NULL; + + if (bl->tail) + bl->tail->bi_next = bio; + else + bl->head = bio; + + bl->tail = bio; +} + +static inline void bio_list_merge(struct bio_list *bl, struct bio_list *bl2) +{ + if (bl->tail) + bl->tail->bi_next = bl2->head; + else + bl->head = bl2->head; + + bl->tail = bl2->tail; +} + +static inline struct bio *bio_list_pop(struct bio_list *bl) +{ + struct bio *bio = bl->head; + + if (bio) { + bl->head = bl->head->bi_next; + if (!bl->head) + bl->tail = NULL; + + bio->bi_next = NULL; + } + + return bio; +} + +static inline struct bio *bio_list_get(struct bio_list *bl) +{ + struct bio *bio = bl->head; + + bl->head = bl->tail = NULL; + + return bio; +} + +#endif diff -puN drivers/md/dm.c~dm-04-maintain-bio-ordering drivers/md/dm.c --- 25/drivers/md/dm.c~dm-04-maintain-bio-ordering Tue Feb 10 13:01:40 2004 +++ 25-akpm/drivers/md/dm.c Tue Feb 10 13:01:40 2004 @@ -5,6 +5,7 @@ */ #include "dm.h" +#include "dm-bio-list.h" #include #include @@ -47,7 +48,7 @@ struct mapped_device { */ atomic_t pending; wait_queue_head_t wait; - struct bio *deferred; + struct bio_list deferred; /* * The current mapping. @@ -195,8 +196,7 @@ static int queue_io(struct mapped_device return 1; } - bio->bi_next = md->deferred; - md->deferred = bio; + bio_list_add(&md->deferred, bio); up_write(&md->lock); return 0; /* deferred successfully */ @@ -822,8 +822,7 @@ int dm_resume(struct mapped_device *md) dm_table_resume_targets(md->map); clear_bit(DMF_SUSPENDED, &md->flags); clear_bit(DMF_BLOCK_IO, &md->flags); - def = md->deferred; - md->deferred = NULL; + def = bio_list_get(&md->deferred); up_write(&md->lock); flush_deferred_io(def); _