From: Neil Brown With the current code in bio_add_page, if fail_segments is ever set, it stays set, so bio_add_page will eventually fail having recounted the segmentation once. I don't think this is intended. This patch changes the code to allow success if the recounting the segments helps. fs/bio.c | 11 ++++------- 1 files changed, 4 insertions(+), 7 deletions(-) diff -puN fs/bio.c~fix-strange-code-in-bio_add_page fs/bio.c --- 25/fs/bio.c~fix-strange-code-in-bio_add_page 2003-08-25 20:01:53.000000000 -0700 +++ 25-akpm/fs/bio.c 2003-08-25 20:01:53.000000000 -0700 @@ -296,7 +296,7 @@ int bio_add_page(struct bio *bio, struct unsigned int offset) { request_queue_t *q = bdev_get_queue(bio->bi_bdev); - int fail_segments = 0, retried_segments = 0; + int retried_segments = 0; struct bio_vec *bvec; /* @@ -315,18 +315,15 @@ int bio_add_page(struct bio *bio, struct * we might lose a segment or two here, but rather that than * make this too complex. */ -retry_segments: - if (bio_phys_segments(q, bio) >= q->max_phys_segments - || bio_hw_segments(q, bio) >= q->max_hw_segments) - fail_segments = 1; - if (fail_segments) { + while (bio_phys_segments(q, bio) >= q->max_phys_segments + || bio_hw_segments(q, bio) >= q->max_hw_segments) { + if (retried_segments) return 0; bio->bi_flags &= ~(1 << BIO_SEG_VALID); retried_segments = 1; - goto retry_segments; } /* _