Re: bio_chain: proposed solution for bio_alloc failure and large IO simplification

From: Andrew Morton (
Date: Sat Jun 15 2002 - 14:50:12 EST

"Adam J. Richter" wrote:
> ...
> newbio = q->one_more_bvec(q, bio, page, offset, len);

That's a comfortable interface. Or maybe just:

        struct bio *bio_add_bvec(bio, page, offset, len);

Couple of points:

- It's tricky to determine how many bvecs are available in
  a bio. There is no straightforward "how big is it" field
  in struct bio.

- AFAIK, there are no established conventions for BIO assembly.
  We have conventions which state what the various fields do
  while the BIO is being processed by the block layer, but not
  for when the client is assembling the BIO.

What I did, and what I'd suggest as a convention is:

During BIO assembly, bi_vcnt indicates the maximum number of
bvecs which the BIO can hold. And bi_idx indexes the next-free
bvec within the BIO.

If you do this, *now* you have enough information to write

struct bio *bio_add_bvec(bio, page, offset, len)
        if (block layer says bio is maximum size) ||
                        (bio->bi_idx == bio->bi_vcnt) {
                bio->bi_vcnt = bio->bi_idx;
                bio->bi_idx = 0;
                submit_bio(bio); /* Caller has set up bi_end_io() */
                bio = NULL;
        } else {
                bio->bi_io_vec[bio->bi_idx].page = page;
        return bio;

It returns NULL if the bio was sent so that the caller gets
to allocate the new BIO. If you want to allocate the new BIO
here you'll need to pass in gfp_flags and the new bio's
desired size as well. And copy that size into bi_vcnt.

ll_rw_kio() can be adapted to the above convention too, which will
simplify it a little.

To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to
More majordomo info at
Please read the FAQ at

This archive was generated by hypermail 2b29 : Sat Jun 15 2002 - 22:00:33 EST