]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blobdiff - fs/bio.c
block: Introduce new bio_split()
[mirror_ubuntu-zesty-kernel.git] / fs / bio.c
index a3e753f4d5a6b951cd62d2a95c29d86edda8175d..7b062befac8280b47a7fb90b6cd7e0f1e3bf8191 100644 (file)
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -1793,6 +1793,42 @@ void bio_endio_nodec(struct bio *bio, int error)
 }
 EXPORT_SYMBOL(bio_endio_nodec);
 
+/**
+ * bio_split - split a bio
+ * @bio:       bio to split
+ * @sectors:   number of sectors to split from the front of @bio
+ * @gfp:       gfp mask
+ * @bs:                bio set to allocate from
+ *
+ * Allocates and returns a new bio which represents @sectors from the start of
+ * @bio, and updates @bio to represent the remaining sectors.
+ *
+ * The newly allocated bio will point to @bio's bi_io_vec; it is the caller's
+ * responsibility to ensure that @bio is not freed before the split.
+ */
+struct bio *bio_split(struct bio *bio, int sectors,
+                     gfp_t gfp, struct bio_set *bs)
+{
+       struct bio *split = NULL;
+
+       BUG_ON(sectors <= 0);
+       BUG_ON(sectors >= bio_sectors(bio));
+
+       split = bio_clone_fast(bio, gfp, bs);
+       if (!split)
+               return NULL;
+
+       split->bi_iter.bi_size = sectors << 9;
+
+       if (bio_integrity(split))
+               bio_integrity_trim(split, 0, sectors);
+
+       bio_advance(bio, split->bi_iter.bi_size);
+
+       return split;
+}
+EXPORT_SYMBOL(bio_split);
+
 void bio_pair_release(struct bio_pair *bp)
 {
        if (atomic_dec_and_test(&bp->cnt)) {