Skip to content

Commit

Permalink
block: Add bio_advance()
Browse files Browse the repository at this point in the history
This is prep work for immutable bio vecs; we first want to centralize
where bvecs are modified.

Next two patches convert some existing code to use this function.

Signed-off-by: Kent Overstreet <koverstreet@google.com>
CC: Jens Axboe <axboe@kernel.dk>
  • Loading branch information
Kent Overstreet committed Mar 23, 2013
1 parent 9f060e2 commit 054bdf6
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 0 deletions.
41 changes: 41 additions & 0 deletions fs/bio.c
Original file line number Diff line number Diff line change
Expand Up @@ -752,6 +752,47 @@ int bio_add_page(struct bio *bio, struct page *page, unsigned int len,
}
EXPORT_SYMBOL(bio_add_page);

/**
* bio_advance - increment/complete a bio by some number of bytes
* @bio: bio to advance
* @bytes: number of bytes to complete
*
* This updates bi_sector, bi_size and bi_idx; if the number of bytes to
* complete doesn't align with a bvec boundary, then bv_len and bv_offset will
* be updated on the last bvec as well.
*
* @bio will then represent the remaining, uncompleted portion of the io.
*/
void bio_advance(struct bio *bio, unsigned bytes)
{
if (bio_integrity(bio))
bio_integrity_advance(bio, bytes);

bio->bi_sector += bytes >> 9;
bio->bi_size -= bytes;

if (bio->bi_rw & BIO_NO_ADVANCE_ITER_MASK)
return;

while (bytes) {
if (unlikely(bio->bi_idx >= bio->bi_vcnt)) {
WARN_ONCE(1, "bio idx %d >= vcnt %d\n",
bio->bi_idx, bio->bi_vcnt);
break;
}

if (bytes >= bio_iovec(bio)->bv_len) {
bytes -= bio_iovec(bio)->bv_len;
bio->bi_idx++;
} else {
bio_iovec(bio)->bv_len -= bytes;
bio_iovec(bio)->bv_offset += bytes;
bytes = 0;
}
}
}
EXPORT_SYMBOL(bio_advance);

struct bio_map_data {
struct bio_vec *iovecs;
struct sg_iovec *sgvecs;
Expand Down
2 changes: 2 additions & 0 deletions include/linux/bio.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,8 @@ extern void bio_endio(struct bio *, int);
struct request_queue;
extern int bio_phys_segments(struct request_queue *, struct bio *);

extern void bio_advance(struct bio *, unsigned);

extern void bio_init(struct bio *);
extern void bio_reset(struct bio *);

Expand Down
2 changes: 2 additions & 0 deletions include/linux/blk_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ enum rq_flag_bits {
REQ_SECURE)
#define REQ_CLONE_MASK REQ_COMMON_MASK

#define BIO_NO_ADVANCE_ITER_MASK (REQ_DISCARD|REQ_WRITE_SAME)

/* This mask is used for both bio and request merge checking */
#define REQ_NOMERGE_FLAGS \
(REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA)
Expand Down

0 comments on commit 054bdf6

Please sign in to comment.