lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Tue, 31 Jul 2007 12:17:53 +1000 From: NeilBrown <neilb@...e.de> To: linux-kernel@...r.kernel.org Subject: [PATCH 024 of 35] Allow request bio list not to end with NULL If we are going to share a bio between requests, then the last bio in a list may not point to NULL, but may point to the next bio in a different list. So instead of testing if ->bi_next is NULL, test if the bio matches rq->biotail. Signed-off-by: Neil Brown <neilb@...e.de> ### Diffstat output ./block/ll_rw_blk.c | 8 ++++---- ./drivers/block/cciss.c | 16 +++++++++------- ./drivers/block/cpqarray.c | 18 ++++++++---------- ./include/linux/blkdev.h | 5 +++-- 4 files changed, 24 insertions(+), 23 deletions(-) diff .prev/block/ll_rw_blk.c ./block/ll_rw_blk.c --- .prev/block/ll_rw_blk.c 2007-07-31 11:21:07.000000000 +1000 +++ ./block/ll_rw_blk.c 2007-07-31 11:21:14.000000000 +1000 @@ -1196,13 +1196,10 @@ EXPORT_SYMBOL(blk_dump_rq_flags); void blk_recount_segments(struct request_queue *q, struct bio *bio) { struct request rq; - struct bio *nxt = bio->bi_next; rq.q = q; rq.bio = rq.biotail = bio; rq.first_offset = 0; - bio->bi_next = NULL; blk_recalc_rq_segments(&rq); - bio->bi_next = nxt; bio->bi_phys_segments = rq.nr_phys_segments; bio->bi_hw_segments = rq.nr_hw_segments; bio->bi_flags |= (1 << BIO_SEG_VALID); @@ -3416,7 +3413,10 @@ static int __end_that_request_first(stru int nbytes; if (nr_bytes >= bio->bi_size) { - req->bio = bio->bi_next; + if (req->bio == req->biotail) + req->bio = NULL; + else + req->bio = bio->bi_next; nbytes = bio->bi_size; if (!ordered_bio_endio(req, bio, error)) bio_endio(bio, error); diff .prev/drivers/block/cciss.c ./drivers/block/cciss.c --- .prev/drivers/block/cciss.c 2007-07-31 11:20:51.000000000 +1000 +++ ./drivers/block/cciss.c 2007-07-31 11:21:14.000000000 +1000 @@ -1187,15 +1187,17 @@ static int cciss_ioctl(struct inode *ino } } -static inline void complete_buffers(struct bio *bio, int status) +static inline void complete_buffers(struct request *req, int status) { - while (bio) { - struct bio *xbh = bio->bi_next; - int nr_sectors = bio_sectors(bio); + while (req->bio) { + struct bio *bio = req->bio; + + if (bio == req->biotail) + req->bio = NULL; + else + req->bio = bio->bi_next; - bio->bi_next = NULL; bio_endio(bio, status ? 0 : -EIO); - bio = xbh; } } @@ -1264,7 +1266,7 @@ static void cciss_softirq_done(struct re pci_unmap_page(h->pdev, temp64.val, cmd->SG[i].Len, ddir); } - complete_buffers(rq->bio, (rq->errors == 0)); + complete_buffers(rq, (rq->errors == 0)); if (blk_fs_request(rq)) { const int rw = rq_data_dir(rq); diff .prev/drivers/block/cpqarray.c ./drivers/block/cpqarray.c --- .prev/drivers/block/cpqarray.c 2007-07-31 11:20:51.000000000 +1000 +++ ./drivers/block/cpqarray.c 2007-07-31 11:21:14.000000000 +1000 @@ -166,7 +166,6 @@ static void start_io(ctlr_info_t *h); static inline void addQ(cmdlist_t **Qptr, cmdlist_t *c); static inline cmdlist_t *removeQ(cmdlist_t **Qptr, cmdlist_t *c); -static inline void complete_buffers(struct bio *bio, int ok); static inline void complete_command(cmdlist_t *cmd, int timeout); static irqreturn_t do_ida_intr(int irq, void *dev_id); @@ -979,18 +978,17 @@ static void start_io(ctlr_info_t *h) } } -static inline void complete_buffers(struct bio *bio, int ok) +static inline void complete_buffers(struct request *req, int ok) { - struct bio *xbh; - while(bio) { - int nr_sectors = bio_sectors(bio); + while (req->bio) { + struct bio *bio = req->bio; - xbh = bio->bi_next; - bio->bi_next = NULL; + if (bio == req->biotail) + req->bio = NULL; + else + req->bio = bio->bi_next; bio_endio(bio, ok ? 0 : -EIO); - - bio = xbh; } } /* @@ -1030,7 +1028,7 @@ static inline void complete_command(cmdl pci_unmap_page(hba[cmd->ctlr]->pci_dev, cmd->req.sg[i].addr, cmd->req.sg[i].size, ddir); - complete_buffers(rq->bio, ok); + complete_buffers(rq, ok); if (blk_fs_request(rq)) { const int rw = rq_data_dir(rq); diff .prev/include/linux/blkdev.h ./include/linux/blkdev.h --- .prev/include/linux/blkdev.h 2007-07-31 11:21:07.000000000 +1000 +++ ./include/linux/blkdev.h 2007-07-31 11:21:14.000000000 +1000 @@ -660,12 +660,13 @@ struct req_iterator { }; #define rq_for_each_segment(rq, _iter, bvec) \ for (_iter.bio = (rq)->bio, _iter.offset = (rq)->first_offset; \ - _iter.bio; \ + _iter.bio && _iter.bio != rq->biotail->bi_next; \ _iter.bio = _iter.bio->bi_next, _iter.offset = 0) \ bio_for_each_segment_offset(bvec, _iter.bio, _iter.i, \ _iter.offset) -#define rq_iter_last(rq, _iter) (_iter.bio->bi_next == NULL && \ +#define rq_iter_last(rq, _iter) ((_iter.bio->bi_next == NULL || \ + _iter.bio == rq->biotail) && \ _iter.i.i == _iter.bio->bi_vcnt - 1) extern int blk_register_queue(struct gendisk *disk); - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists