bio_free(bio, fs_bio_set);
}
-inline void bio_init(struct bio *bio)
+void bio_init(struct bio *bio)
{
bio->bi_next = NULL;
+ bio->bi_bdev = NULL;
bio->bi_flags = 1 << BIO_UPTODATE;
bio->bi_rw = 0;
bio->bi_vcnt = 0;
* the actual data it points to. Reference count of returned
* bio will be one.
*/
-inline void __bio_clone(struct bio *bio, struct bio *bio_src)
+void __bio_clone(struct bio *bio, struct bio *bio_src)
{
request_queue_t *q = bdev_get_queue(bio_src->bi_bdev);
if (unlikely(bio_flagged(bio, BIO_CLONED)))
return 0;
- if (bio->bi_vcnt >= bio->bi_max_vecs)
+ if (((bio->bi_size + len) >> 9) > max_sectors)
return 0;
- if (((bio->bi_size + len) >> 9) > max_sectors)
+ /*
+ * For filesystems with a blocksize smaller than the pagesize
+ * we will often be called with the same page as last time and
+ * a consecutive offset. Optimize this special case.
+ */
+ if (bio->bi_vcnt > 0) {
+ struct bio_vec *prev = &bio->bi_io_vec[bio->bi_vcnt - 1];
+
+ if (page == prev->bv_page &&
+ offset == prev->bv_offset + prev->bv_len) {
+ prev->bv_len += len;
+ if (q->merge_bvec_fn &&
+ q->merge_bvec_fn(q, bio, prev) < len) {
+ prev->bv_len -= len;
+ return 0;
+ }
+
+ goto done;
+ }
+ }
+
+ if (bio->bi_vcnt >= bio->bi_max_vecs)
return 0;
/*
bio->bi_vcnt++;
bio->bi_phys_segments++;
bio->bi_hw_segments++;
+ done:
bio->bi_size += len;
return len;
}
/**
* bio_add_pc_page - attempt to add page to bio
+ * @q: the target queue
* @bio: destination bio
* @page: page to add
* @len: vec entry length