问一个关于bio中bi_io_vec个数(bi_vcnt)的问题

发布于 2022-09-23 14:19:20 字数 1038 浏览 7 评论 0

最近在看块设备这块,第一次write/read最后都会调到submit_bh

在submit_bh()中,生成bio的过程如下。
    bio = bio_alloc(GFP_NOIO, 1);

    bio->bi_sector = bh->b_blocknr * (bh->b_size >> 9);
    bio->bi_bdev = bh->b_bdev;
    bio->bi_io_vec[0].bv_page = bh->b_page;
    bio->bi_io_vec[0].bv_len = bh->b_size;
    bio->bi_io_vec[0].bv_offset = bh_offset(bh);

    bio->bi_vcnt = 1;
    bio->bi_idx = 0;
    bio->bi_size = bh->b_size;

    bio->bi_end_io = end_bio_bh_io_sync;
    bio->bi_private = bh;

    bio_get(bio);
    submit_bio(rw, bio);
照这样,每个submit的bio最后bi_io_vec数组中 的bio_vec都只有一项。

    想问问bio中bi_io_vec数组是不是就在预读成功的时候会出现多项,其他情况下(所有的一般的读写)都只会有一项。
    请高人指点哈子。

[ 本帖最后由 taylergreen 于 2009-1-12 15:50 编辑 ]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

苦妄 2022-09-30 14:19:20

本帖最后由 chishanmingshen 于 2013-06-12 08:38 编辑

回复 1# taylergreen

from 3.9.4
static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page
                          *page, unsigned int len, unsigned int offset,
                          unsigned short max_secto
{
        /*
         * 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) {
                        unsigned int prev_bv_len = prev->bv_len;
                        prev->bv_len += len;

                        if (q->merge_bvec_fn) {
                                struct bvec_merge_data bvm = {
                                        /* prev_bvec is already charged in
                                           bi_size, discharge it in order to
                                           simulate merging updated prev_bvec
                                           as new bvec. */
                                        .bi_bdev = bio->bi_bdev,
                                        .bi_sector = bio->bi_sector,
                                        .bi_size = bio->bi_size - prev_bv_len,
                                        .bi_rw = bio->bi_rw,
                                };

                                if (q->merge_bvec_fn(q, &bvm, prev) < prev->bv_len) {
                                        prev->bv_len -= len;
                                        return 0;
                                }
                        }

                        goto done;
                }
        }
}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文