From: Kent Overstreet <kmo@daterainc.com>
To: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org,
hch@infradead.org
Cc: Kent Overstreet <kmo@daterainc.com>, Jens Axboe <axboe@kernel.dk>
Subject: [PATCH 16/25] block: Refactor bio_clone_bioset() for immutable biovecs
Date: Tue, 26 Nov 2013 16:45:19 -0800 [thread overview]
Message-ID: <1385513128-5035-16-git-send-email-kmo@daterainc.com> (raw)
In-Reply-To: <1385513128-5035-1-git-send-email-kmo@daterainc.com>
bio_clone() needs to produce a bio that's suitable for the caller to
munge with the biovec. Part of the immutable biovec patch series is
fixing stuff up so that submitting partially completed bios is safe and
works: thus, we now need bio_clone() on a partially completed bio to
produce a bio for which bi_idx and bi_bvec done are 0 - like they would
be if the caller had just allocated a new bio.
Signed-off-by: Kent Overstreet <kmo@daterainc.com>
Cc: Jens Axboe <axboe@kernel.dk>
---
fs/bio.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 47 insertions(+), 13 deletions(-)
diff --git a/fs/bio.c b/fs/bio.c
index a082ce2..1628917 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -549,36 +549,70 @@ void __bio_clone(struct bio *bio, struct bio *bio_src)
EXPORT_SYMBOL(__bio_clone);
/**
- * bio_clone_bioset - clone a bio
- * @bio: bio to clone
+ * bio_clone_bioset - clone a bio
+ * @bio_src: bio to clone
* @gfp_mask: allocation priority
* @bs: bio_set to allocate from
*
- * Like __bio_clone, only also allocates the returned bio
+ * Clone bio. Caller will own the returned bio, but not the actual data it
+ * points to. Reference count of returned bio will be one.
*/
-struct bio *bio_clone_bioset(struct bio *bio, gfp_t gfp_mask,
+struct bio *bio_clone_bioset(struct bio *bio_src, gfp_t gfp_mask,
struct bio_set *bs)
{
- struct bio *b;
+ unsigned nr_iovecs = 0;
+ struct bvec_iter iter;
+ struct bio_vec bv;
+ struct bio *bio;
+
+ /*
+ * Pre immutable biovecs, __bio_clone() used to just do a memcpy from
+ * bio_src->bi_io_vec to bio->bi_io_vec.
+ *
+ * We can't do that anymore, because:
+ *
+ * - The point of cloning the biovec is to produce a bio with a biovec
+ * the caller can modify: bi_idx and bi_bvec_done should be 0.
+ *
+ * - The original bio could've had more than BIO_MAX_PAGES biovecs; if
+ * we tried to clone the whole thing bio_alloc_bioset() would fail.
+ * But the clone should succeed as long as the number of biovecs we
+ * actually need to allocate is fewer than BIO_MAX_PAGES.
+ *
+ * - Lastly, bi_vcnt should not be looked at or relied upon by code
+ * that does not own the bio - reason being drivers don't use it for
+ * iterating over the biovec anymore, so expecting it to be kept up
+ * to date (i.e. for clones that share the parent biovec) is just
+ * asking for trouble and would force extra work on
+ * __bio_clone_fast() anyways.
+ */
+
+ bio_for_each_segment(bv, bio_src, iter)
+ nr_iovecs++;
- b = bio_alloc_bioset(gfp_mask, bio->bi_max_vecs, bs);
- if (!b)
+ bio = bio_alloc_bioset(gfp_mask, nr_iovecs, bs);
+ if (!bio)
return NULL;
- __bio_clone(b, bio);
+ bio->bi_bdev = bio_src->bi_bdev;
+ bio->bi_rw = bio_src->bi_rw;
+ bio->bi_iter.bi_sector = bio_src->bi_iter.bi_sector;
+ bio->bi_iter.bi_size = bio_src->bi_iter.bi_size;
- if (bio_integrity(bio)) {
- int ret;
+ bio_for_each_segment(bv, bio_src, iter)
+ bio->bi_io_vec[bio->bi_vcnt++] = bv;
- ret = bio_integrity_clone(b, bio, gfp_mask);
+ if (bio_integrity(bio_src)) {
+ int ret;
+ ret = bio_integrity_clone(bio, bio_src, gfp_mask);
if (ret < 0) {
- bio_put(b);
+ bio_put(bio);
return NULL;
}
}
- return b;
+ return bio;
}
EXPORT_SYMBOL(bio_clone_bioset);
--
1.8.4.4
next prev parent reply other threads:[~2013-11-27 0:49 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-11-25 21:52 [GIT PULL] Immutable biovecs Kent Overstreet
2013-11-26 6:05 ` Christoph Hellwig
2013-11-27 0:44 ` Kent Overstreet
2013-11-27 0:45 ` [PATCH 01/25] block: submit_bio_wait() conversions Kent Overstreet
2013-11-27 0:45 ` [PATCH 02/25] block: Convert various code to bio_for_each_segment() Kent Overstreet
2013-11-27 0:45 ` [PATCH 03/25] bcache: Kill unaligned bvec hack Kent Overstreet
2013-11-27 0:45 ` [PATCH 05/25] dm: Use bvec_iter for dm_bio_record() Kent Overstreet
2013-11-27 0:45 ` [PATCH 06/25] block: Convert bio_iovec() to bvec_iter Kent Overstreet
2013-11-27 0:45 ` [PATCH 08/25] block: Immutable bio vecs Kent Overstreet
2013-11-27 0:45 ` [PATCH 09/25] block: Convert bio_copy_data() to bvec_iter Kent Overstreet
2013-11-27 0:45 ` [PATCH 10/25] bio-integrity: Convert " Kent Overstreet
2013-11-27 0:45 ` [PATCH 11/25] block: Kill bio_segments()/bi_vcnt usage Kent Overstreet
2013-11-27 0:45 ` [PATCH 12/25] block: Convert drivers to immutable biovecs Kent Overstreet
2013-11-27 0:45 ` [PATCH 13/25] aoe: Convert " Kent Overstreet
2013-11-27 0:45 ` [PATCH 14/25] ceph: " Kent Overstreet
2013-11-27 0:45 ` [PATCH 15/25] block: Kill bio_iovec_idx(), __bio_iovec() Kent Overstreet
2013-11-27 0:45 ` Kent Overstreet [this message]
2013-11-27 0:45 ` [PATCH 17/25] block: Add bio_clone_fast() Kent Overstreet
2013-11-27 0:45 ` [PATCH 18/25] rbd: Refactor bio cloning Kent Overstreet
2013-11-27 0:45 ` [PATCH 19/25] dm: Refactor for new bio cloning/splitting Kent Overstreet
2013-11-27 0:45 ` [PATCH 20/25] block: Don't save/copy bvec array anymore Kent Overstreet
2013-11-27 0:45 ` [PATCH 21/25] block: Remove bi_idx hacks Kent Overstreet
2013-11-27 0:45 ` [PATCH 22/25] block: Generic bio chaining Kent Overstreet
2013-11-27 0:45 ` [PATCH 23/25] block: Rename bio_split() -> bio_pair_split() Kent Overstreet
2013-11-27 0:45 ` [PATCH 24/25] block: Introduce new bio_split() Kent Overstreet
2013-11-27 0:45 ` [PATCH 25/25] block: Kill bio_pair_split() Kent Overstreet
[not found] ` <1385513128-5035-4-git-send-email-kmo@daterainc.com>
2013-11-27 18:51 ` [PATCH 04/25] block: Abstract out bvec iterator Geoff Levand
2013-11-27 0:59 ` [GIT PULL] Immutable biovecs Jens Axboe
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1385513128-5035-16-git-send-email-kmo@daterainc.com \
--to=kmo@daterainc.com \
--cc=axboe@kernel.dk \
--cc=hch@infradead.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®