Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 054bdf64 authored by Kent Overstreet's avatar Kent Overstreet
Browse files

block: Add bio_advance()



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: default avatarKent Overstreet <koverstreet@google.com>
CC: Jens Axboe <axboe@kernel.dk>
parent 9f060e22
Loading
Loading
Loading
Loading
+41 −0
Original line number Original line Diff line number Diff line
@@ -752,6 +752,47 @@ int bio_add_page(struct bio *bio, struct page *page, unsigned int len,
}
}
EXPORT_SYMBOL(bio_add_page);
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_map_data {
	struct bio_vec *iovecs;
	struct bio_vec *iovecs;
	struct sg_iovec *sgvecs;
	struct sg_iovec *sgvecs;
+2 −0
Original line number Original line Diff line number Diff line
@@ -248,6 +248,8 @@ extern void bio_endio(struct bio *, int);
struct request_queue;
struct request_queue;
extern int bio_phys_segments(struct request_queue *, struct bio *);
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_init(struct bio *);
extern void bio_reset(struct bio *);
extern void bio_reset(struct bio *);


+2 −0
Original line number Original line Diff line number Diff line
@@ -197,6 +197,8 @@ enum rq_flag_bits {
	 REQ_SECURE)
	 REQ_SECURE)
#define REQ_CLONE_MASK		REQ_COMMON_MASK
#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 */
/* This mask is used for both bio and request merge checking */
#define REQ_NOMERGE_FLAGS \
#define REQ_NOMERGE_FLAGS \
	(REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA)
	(REQ_NOMERGE | REQ_STARTED | REQ_SOFTBARRIER | REQ_FLUSH | REQ_FUA)