diff options
author | Kent Overstreet <koverstreet@google.com> | 2012-09-28 16:17:55 -0400 |
---|---|---|
committer | Kent Overstreet <koverstreet@google.com> | 2013-03-23 17:15:27 -0400 |
commit | 054bdf646e36c2f7dc1bf6bc6209dbbb5909164b (patch) | |
tree | acd9989fd9e6f5c6d3c985e34e984081a33cbdc3 /fs/bio.c | |
parent | 9f060e2231ca96ca94f2ffcff730acd72606b280 (diff) |
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: Kent Overstreet <koverstreet@google.com>
CC: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'fs/bio.c')
-rw-r--r-- | fs/bio.c | 41 |
1 files changed, 41 insertions, 0 deletions
@@ -752,6 +752,47 @@ int bio_add_page(struct bio *bio, struct page *page, unsigned int len, | |||
752 | } | 752 | } |
753 | EXPORT_SYMBOL(bio_add_page); | 753 | EXPORT_SYMBOL(bio_add_page); |
754 | 754 | ||
755 | /** | ||
756 | * bio_advance - increment/complete a bio by some number of bytes | ||
757 | * @bio: bio to advance | ||
758 | * @bytes: number of bytes to complete | ||
759 | * | ||
760 | * This updates bi_sector, bi_size and bi_idx; if the number of bytes to | ||
761 | * complete doesn't align with a bvec boundary, then bv_len and bv_offset will | ||
762 | * be updated on the last bvec as well. | ||
763 | * | ||
764 | * @bio will then represent the remaining, uncompleted portion of the io. | ||
765 | */ | ||
766 | void bio_advance(struct bio *bio, unsigned bytes) | ||
767 | { | ||
768 | if (bio_integrity(bio)) | ||
769 | bio_integrity_advance(bio, bytes); | ||
770 | |||
771 | bio->bi_sector += bytes >> 9; | ||
772 | bio->bi_size -= bytes; | ||
773 | |||
774 | if (bio->bi_rw & BIO_NO_ADVANCE_ITER_MASK) | ||
775 | return; | ||
776 | |||
777 | while (bytes) { | ||
778 | if (unlikely(bio->bi_idx >= bio->bi_vcnt)) { | ||
779 | WARN_ONCE(1, "bio idx %d >= vcnt %d\n", | ||
780 | bio->bi_idx, bio->bi_vcnt); | ||
781 | break; | ||
782 | } | ||
783 | |||
784 | if (bytes >= bio_iovec(bio)->bv_len) { | ||
785 | bytes -= bio_iovec(bio)->bv_len; | ||
786 | bio->bi_idx++; | ||
787 | } else { | ||
788 | bio_iovec(bio)->bv_len -= bytes; | ||
789 | bio_iovec(bio)->bv_offset += bytes; | ||
790 | bytes = 0; | ||
791 | } | ||
792 | } | ||
793 | } | ||
794 | EXPORT_SYMBOL(bio_advance); | ||
795 | |||
755 | struct bio_map_data { | 796 | struct bio_map_data { |
756 | struct bio_vec *iovecs; | 797 | struct bio_vec *iovecs; |
757 | struct sg_iovec *sgvecs; | 798 | struct sg_iovec *sgvecs; |