}
 EXPORT_SYMBOL(bio_put);
 
-/**
- *     __bio_clone_fast - clone a bio that shares the original bio's biovec
- *     @bio: destination bio
- *     @bio_src: bio to clone
- *     @gfp: allocation flags
- *
- *     Clone a &bio. Caller will own the returned bio, but not
- *     the actual data it points to. Reference count of returned
- *     bio will be one.
- *
- *     Caller must ensure that @bio_src is not freed before @bio.
- */
-int __bio_clone_fast(struct bio *bio, struct bio *bio_src, gfp_t gfp)
+static int __bio_clone(struct bio *bio, struct bio *bio_src, gfp_t gfp)
 {
-       WARN_ON_ONCE(bio->bi_pool && bio->bi_max_vecs);
-
-       /*
-        * most users will be overriding ->bi_bdev with a new target,
-        * so we don't set nor calculate new physical/hw segment counts here
-        */
-       bio->bi_bdev = bio_src->bi_bdev;
        bio_set_flag(bio, BIO_CLONED);
        if (bio_flagged(bio_src, BIO_THROTTLED))
                bio_set_flag(bio, BIO_THROTTLED);
        if (bio_flagged(bio_src, BIO_REMAPPED))
                bio_set_flag(bio, BIO_REMAPPED);
-       bio->bi_opf = bio_src->bi_opf;
        bio->bi_ioprio = bio_src->bi_ioprio;
        bio->bi_write_hint = bio_src->bi_write_hint;
        bio->bi_iter = bio_src->bi_iter;
-       bio->bi_io_vec = bio_src->bi_io_vec;
 
        bio_clone_blkg_association(bio, bio_src);
        blkcg_bio_issue_init(bio);
                return -ENOMEM;
        return 0;
 }
-EXPORT_SYMBOL(__bio_clone_fast);
 
 /**
- *     bio_clone_fast - clone a bio that shares the original bio's biovec
- *     @bio: bio to clone
- *     @gfp_mask: allocation priority
- *     @bs: bio_set to allocate from
+ * bio_clone_fast - clone a bio that shares the original bio's biovec
+ * @bio_src: bio to clone from
+ * @gfp: allocation priority
+ * @bs: bio_set to allocate from
+ *
+ * Allocate a new bio that is a clone of @bio_src. The caller owns the returned
+ * bio, but not the actual data it points to.
  *
- *     Like __bio_clone_fast, only also allocates the returned bio
+ * The caller must ensure that the return bio is not freed before @bio_src.
  */
-struct bio *bio_clone_fast(struct bio *bio, gfp_t gfp_mask, struct bio_set *bs)
+struct bio *bio_clone_fast(struct bio *bio_src, gfp_t gfp, struct bio_set *bs)
 {
-       struct bio *b;
+       struct bio *bio;
 
-       b = bio_alloc_bioset(NULL, 0, 0, gfp_mask, bs);
-       if (!b)
+       bio = bio_alloc_bioset(bio_src->bi_bdev, 0, bio_src->bi_opf, gfp, bs);
+       if (!bio)
                return NULL;
 
-       if (__bio_clone_fast(b, bio, gfp_mask < 0)) {
-               bio_put(b);
+       if (__bio_clone(bio, bio_src, gfp) < 0) {
+               bio_put(bio);
                return NULL;
        }
+       bio->bi_io_vec = bio_src->bi_io_vec;
 
-       return b;
+       return bio;
 }
 EXPORT_SYMBOL(bio_clone_fast);
 
+/**
+ * __bio_clone_fast - clone a bio that shares the original bio's biovec
+ * @bio: bio to clone into
+ * @bio_src: bio to clone from
+ * @gfp: allocation priority
+ *
+ * Initialize a new bio in caller provided memory that is a clone of @bio_src.
+ * The caller owns the returned bio, but not the actual data it points to.
+ *
+ * The caller must ensure that @bio_src is not freed before @bio.
+ */
+int __bio_clone_fast(struct bio *bio, struct bio *bio_src, gfp_t gfp)
+{
+       int ret;
+
+       bio_init(bio, bio_src->bi_bdev, bio_src->bi_io_vec, 0, bio_src->bi_opf);
+       ret = __bio_clone(bio, bio_src, gfp);
+       if (ret)
+               bio_uninit(bio);
+       return ret;
+}
+EXPORT_SYMBOL(__bio_clone_fast);
+
 const char *bio_devname(struct bio *bio, char *buf)
 {
        return bdevname(bio->bi_bdev, buf);