lkml.org 
[lkml]   [2018]   [Nov]   [15]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH V10 02/19] block: introduce bio_for_each_bvec()
    Date
    This helper is used for iterating over multi-page bvec for bio
    split & merge code.

    Cc: Dave Chinner <dchinner@redhat.com>
    Cc: Kent Overstreet <kent.overstreet@gmail.com>
    Cc: Mike Snitzer <snitzer@redhat.com>
    Cc: dm-devel@redhat.com
    Cc: Alexander Viro <viro@zeniv.linux.org.uk>
    Cc: linux-fsdevel@vger.kernel.org
    Cc: Shaohua Li <shli@kernel.org>
    Cc: linux-raid@vger.kernel.org
    Cc: linux-erofs@lists.ozlabs.org
    Cc: David Sterba <dsterba@suse.com>
    Cc: linux-btrfs@vger.kernel.org
    Cc: Darrick J. Wong <darrick.wong@oracle.com>
    Cc: linux-xfs@vger.kernel.org
    Cc: Gao Xiang <gaoxiang25@huawei.com>
    Cc: Christoph Hellwig <hch@lst.de>
    Cc: Theodore Ts'o <tytso@mit.edu>
    Cc: linux-ext4@vger.kernel.org
    Cc: Coly Li <colyli@suse.de>
    Cc: linux-bcache@vger.kernel.org
    Cc: Boaz Harrosh <ooo@electrozaur.com>
    Cc: Bob Peterson <rpeterso@redhat.com>
    Cc: cluster-devel@redhat.com
    Signed-off-by: Ming Lei <ming.lei@redhat.com>
    ---
    include/linux/bio.h | 34 +++++++++++++++++++++++++++++++---
    include/linux/bvec.h | 36 ++++++++++++++++++++++++++++++++----
    2 files changed, 63 insertions(+), 7 deletions(-)

    diff --git a/include/linux/bio.h b/include/linux/bio.h
    index 056fb627edb3..1f0dcf109841 100644
    --- a/include/linux/bio.h
    +++ b/include/linux/bio.h
    @@ -76,6 +76,9 @@
    #define bio_data_dir(bio) \
    (op_is_write(bio_op(bio)) ? WRITE : READ)

    +#define bio_iter_mp_iovec(bio, iter) \
    + mp_bvec_iter_bvec((bio)->bi_io_vec, (iter))
    +
    /*
    * Check whether this bio carries any data or not. A NULL bio is allowed.
    */
    @@ -135,18 +138,33 @@ static inline bool bio_full(struct bio *bio)
    #define bio_for_each_segment_all(bvl, bio, i) \
    for (i = 0, bvl = (bio)->bi_io_vec; i < (bio)->bi_vcnt; i++, bvl++)

    -static inline void bio_advance_iter(struct bio *bio, struct bvec_iter *iter,
    - unsigned bytes)
    +static inline void __bio_advance_iter(struct bio *bio, struct bvec_iter *iter,
    + unsigned bytes, bool mp)
    {
    iter->bi_sector += bytes >> 9;

    if (bio_no_advance_iter(bio))
    iter->bi_size -= bytes;
    else
    - bvec_iter_advance(bio->bi_io_vec, iter, bytes);
    + if (!mp)
    + bvec_iter_advance(bio->bi_io_vec, iter, bytes);
    + else
    + mp_bvec_iter_advance(bio->bi_io_vec, iter, bytes);
    /* TODO: It is reasonable to complete bio with error here. */
    }

    +static inline void bio_advance_iter(struct bio *bio, struct bvec_iter *iter,
    + unsigned bytes)
    +{
    + __bio_advance_iter(bio, iter, bytes, false);
    +}
    +
    +static inline void bio_advance_mp_iter(struct bio *bio, struct bvec_iter *iter,
    + unsigned bytes)
    +{
    + __bio_advance_iter(bio, iter, bytes, true);
    +}
    +
    #define __bio_for_each_segment(bvl, bio, iter, start) \
    for (iter = (start); \
    (iter).bi_size && \
    @@ -156,6 +174,16 @@ static inline void bio_advance_iter(struct bio *bio, struct bvec_iter *iter,
    #define bio_for_each_segment(bvl, bio, iter) \
    __bio_for_each_segment(bvl, bio, iter, (bio)->bi_iter)

    +#define __bio_for_each_bvec(bvl, bio, iter, start) \
    + for (iter = (start); \
    + (iter).bi_size && \
    + ((bvl = bio_iter_mp_iovec((bio), (iter))), 1); \
    + bio_advance_mp_iter((bio), &(iter), (bvl).bv_len))
    +
    +/* returns one real segment(multipage bvec) each time */
    +#define bio_for_each_bvec(bvl, bio, iter) \
    + __bio_for_each_bvec(bvl, bio, iter, (bio)->bi_iter)
    +
    #define bio_iter_last(bvec, iter) ((iter).bi_size == (bvec).bv_len)

    static inline unsigned bio_segments(struct bio *bio)
    diff --git a/include/linux/bvec.h b/include/linux/bvec.h
    index 8ef904a50577..3d61352cd8cf 100644
    --- a/include/linux/bvec.h
    +++ b/include/linux/bvec.h
    @@ -124,8 +124,16 @@ struct bvec_iter {
    .bv_offset = bvec_iter_offset((bvec), (iter)), \
    })

    -static inline bool bvec_iter_advance(const struct bio_vec *bv,
    - struct bvec_iter *iter, unsigned bytes)
    +#define mp_bvec_iter_bvec(bvec, iter) \
    +((struct bio_vec) { \
    + .bv_page = mp_bvec_iter_page((bvec), (iter)), \
    + .bv_len = mp_bvec_iter_len((bvec), (iter)), \
    + .bv_offset = mp_bvec_iter_offset((bvec), (iter)), \
    +})
    +
    +static inline bool __bvec_iter_advance(const struct bio_vec *bv,
    + struct bvec_iter *iter,
    + unsigned bytes, bool mp)
    {
    if (WARN_ONCE(bytes > iter->bi_size,
    "Attempted to advance past end of bvec iter\n")) {
    @@ -134,8 +142,14 @@ static inline bool bvec_iter_advance(const struct bio_vec *bv,
    }

    while (bytes) {
    - unsigned iter_len = bvec_iter_len(bv, *iter);
    - unsigned len = min(bytes, iter_len);
    + unsigned len;
    +
    + if (mp)
    + len = mp_bvec_iter_len(bv, *iter);
    + else
    + len = bvec_iter_len(bv, *iter);
    +
    + len = min(bytes, len);

    bytes -= len;
    iter->bi_size -= len;
    @@ -173,6 +187,20 @@ static inline bool bvec_iter_rewind(const struct bio_vec *bv,
    return true;
    }

    +static inline bool bvec_iter_advance(const struct bio_vec *bv,
    + struct bvec_iter *iter,
    + unsigned bytes)
    +{
    + return __bvec_iter_advance(bv, iter, bytes, false);
    +}
    +
    +static inline bool mp_bvec_iter_advance(const struct bio_vec *bv,
    + struct bvec_iter *iter,
    + unsigned bytes)
    +{
    + return __bvec_iter_advance(bv, iter, bytes, true);
    +}
    +
    #define for_each_bvec(bvl, bio_vec, iter, start) \
    for (iter = (start); \
    (iter).bi_size && \
    --
    2.9.5
    \
     
     \ /
      Last update: 2018-11-15 09:54    [W:3.277 / U:0.152 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site