Browse Source

Revert "bio: modify __bio_add_page() to accept pages that don't start a new segment"

This reverts commit 254c4407cb84a6dec90336054615b0f0e996bb7c.

It causes crashes with cryptsetup, even after a few iterations and
updates. Drop it for now.
Jens Axboe 11 years ago
parent
commit
26a337944e
1 changed files with 23 additions and 29 deletions
  1. 23 29
      block/bio.c

+ 23 - 29
block/bio.c

@@ -744,7 +744,6 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page
 				}
 			}
 
-			bio->bi_iter.bi_size += len;
 			goto done;
 		}
 
@@ -761,31 +760,28 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page
 		return 0;
 
 	/*
-	 * setup the new entry, we might clear it again later if we
-	 * cannot add the page
-	 */
-	bvec = &bio->bi_io_vec[bio->bi_vcnt];
-	bvec->bv_page = page;
-	bvec->bv_len = len;
-	bvec->bv_offset = offset;
-	bio->bi_vcnt++;
-	bio->bi_phys_segments++;
-	bio->bi_iter.bi_size += len;
-
-	/*
-	 * Perform a recount if the number of segments is greater
-	 * than queue_max_segments(q).
+	 * we might lose a segment or two here, but rather that than
+	 * make this too complex.
 	 */
 
-	while (bio->bi_phys_segments > queue_max_segments(q)) {
+	while (bio->bi_phys_segments >= queue_max_segments(q)) {
 
 		if (retried_segments)
-			goto failed;
+			return 0;
 
 		retried_segments = 1;
 		blk_recount_segments(q, bio);
 	}
 
+	/*
+	 * setup the new entry, we might clear it again later if we
+	 * cannot add the page
+	 */
+	bvec = &bio->bi_io_vec[bio->bi_vcnt];
+	bvec->bv_page = page;
+	bvec->bv_len = len;
+	bvec->bv_offset = offset;
+
 	/*
 	 * if queue has other restrictions (eg varying max sector size
 	 * depending on offset), it can specify a merge_bvec_fn in the
@@ -803,25 +799,23 @@ static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page
 		 * merge_bvec_fn() returns number of bytes it can accept
 		 * at this offset
 		 */
-		if (q->merge_bvec_fn(q, &bvm, bvec) < bvec->bv_len)
-			goto failed;
+		if (q->merge_bvec_fn(q, &bvm, bvec) < bvec->bv_len) {
+			bvec->bv_page = NULL;
+			bvec->bv_len = 0;
+			bvec->bv_offset = 0;
+			return 0;
+		}
 	}
 
 	/* If we may be able to merge these biovecs, force a recount */
-	if (bio->bi_vcnt > 1 && (BIOVEC_PHYS_MERGEABLE(bvec-1, bvec)))
+	if (bio->bi_vcnt && (BIOVEC_PHYS_MERGEABLE(bvec-1, bvec)))
 		bio->bi_flags &= ~(1 << BIO_SEG_VALID);
 
+	bio->bi_vcnt++;
+	bio->bi_phys_segments++;
  done:
+	bio->bi_iter.bi_size += len;
 	return len;
-
- failed:
-	bvec->bv_page = NULL;
-	bvec->bv_len = 0;
-	bvec->bv_offset = 0;
-	bio->bi_vcnt--;
-	bio->bi_iter.bi_size -= len;
-	blk_recount_segments(q, bio);
-	return 0;
 }
 
 /**