aboutsummaryrefslogtreecommitdiffstats
path: root/fs/bio.c
diff options
context:
space:
mode:
authorKent Overstreet <kmo@daterainc.com>2013-08-07 17:26:21 -0400
committerKent Overstreet <kmo@daterainc.com>2013-11-24 01:33:49 -0500
commit4550dd6c6b062fc5e5b647296d55da22616123c3 (patch)
tree9ca83cc0283151980b7c2f18c0e928aa34a2a0d9 /fs/bio.c
parent7988613b0e5b2638caf6cd493cc78e9595eba19c (diff)
block: Immutable bio vecs
This adds a mechanism by which we can advance a bio by an arbitrary number of bytes without modifying the biovec: bio->bi_iter.bi_bvec_done indicates the number of bytes completed in the current bvec. Various driver code still needs to be updated to not refer to the bvec directly before we can use this for interesting things, like efficient bio splitting. Signed-off-by: Kent Overstreet <kmo@daterainc.com> Cc: Jens Axboe <axboe@kernel.dk> Cc: Lars Ellenberg <drbd-dev@lists.linbit.com> Cc: Paul Clements <Paul.Clements@steeleye.com> Cc: drbd-user@lists.linbit.com Cc: nbd-general@lists.sourceforge.net
Diffstat (limited to 'fs/bio.c')
-rw-r--r--fs/bio.c27
1 files changed, 2 insertions, 25 deletions
diff --git a/fs/bio.c b/fs/bio.c
index 8b7f14a95503..07b4b7afa695 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -532,13 +532,11 @@ void __bio_clone(struct bio *bio, struct bio *bio_src)
532 * most users will be overriding ->bi_bdev with a new target, 532 * most users will be overriding ->bi_bdev with a new target,
533 * so we don't set nor calculate new physical/hw segment counts here 533 * so we don't set nor calculate new physical/hw segment counts here
534 */ 534 */
535 bio->bi_iter.bi_sector = bio_src->bi_iter.bi_sector;
536 bio->bi_bdev = bio_src->bi_bdev; 535 bio->bi_bdev = bio_src->bi_bdev;
537 bio->bi_flags |= 1 << BIO_CLONED; 536 bio->bi_flags |= 1 << BIO_CLONED;
538 bio->bi_rw = bio_src->bi_rw; 537 bio->bi_rw = bio_src->bi_rw;
539 bio->bi_vcnt = bio_src->bi_vcnt; 538 bio->bi_vcnt = bio_src->bi_vcnt;
540 bio->bi_iter.bi_size = bio_src->bi_iter.bi_size; 539 bio->bi_iter = bio_src->bi_iter;
541 bio->bi_iter.bi_idx = bio_src->bi_iter.bi_idx;
542} 540}
543EXPORT_SYMBOL(__bio_clone); 541EXPORT_SYMBOL(__bio_clone);
544 542
@@ -808,28 +806,7 @@ void bio_advance(struct bio *bio, unsigned bytes)
808 if (bio_integrity(bio)) 806 if (bio_integrity(bio))
809 bio_integrity_advance(bio, bytes); 807 bio_integrity_advance(bio, bytes);
810 808
811 bio->bi_iter.bi_sector += bytes >> 9; 809 bio_advance_iter(bio, &bio->bi_iter, bytes);
812 bio->bi_iter.bi_size -= bytes;
813
814 if (bio->bi_rw & BIO_NO_ADVANCE_ITER_MASK)
815 return;
816
817 while (bytes) {
818 if (unlikely(bio->bi_iter.bi_idx >= bio->bi_vcnt)) {
819 WARN_ONCE(1, "bio idx %d >= vcnt %d\n",
820 bio->bi_iter.bi_idx, bio->bi_vcnt);
821 break;
822 }
823
824 if (bytes >= bio_iovec(bio).bv_len) {
825 bytes -= bio_iovec(bio).bv_len;
826 bio->bi_iter.bi_idx++;
827 } else {
828 bio_iovec(bio).bv_len -= bytes;
829 bio_iovec(bio).bv_offset += bytes;
830 bytes = 0;
831 }
832 }
833} 810}
834EXPORT_SYMBOL(bio_advance); 811EXPORT_SYMBOL(bio_advance);
835 812