return bio;
 }
 
+/**
+ * Attempt to add a page to bio
+ *
+ * @bio:       destination bio
+ * @page:      page to add to the bio
+ * @disk_bytenr:  offset of the new bio or to check whether we are adding
+ *                a contiguous page to the previous one
+ * @pg_offset: starting offset in the page
+ * @size:      portion of page that we want to write
+ * @prev_bio_flags:  flags of previous bio to see if we can merge the current one
+ * @bio_flags: flags of the current bio to see if we can merge them
+ * @return:    true if page was added, false otherwise
+ *
+ * Attempt to add a page to bio considering stripe alignment etc.
+ *
+ * Return true if successfully page added. Otherwise, return false.
+ */
+static bool btrfs_bio_add_page(struct bio *bio, struct page *page,
+                              u64 disk_bytenr, unsigned int size,
+                              unsigned int pg_offset,
+                              unsigned long prev_bio_flags,
+                              unsigned long bio_flags)
+{
+       const sector_t sector = disk_bytenr >> SECTOR_SHIFT;
+       bool contig;
+
+       if (prev_bio_flags != bio_flags)
+               return false;
+
+       if (prev_bio_flags & EXTENT_BIO_COMPRESSED)
+               contig = bio->bi_iter.bi_sector == sector;
+       else
+               contig = bio_end_sector(bio) == sector;
+       if (!contig)
+               return false;
+
+       if (btrfs_bio_fits_in_stripe(page, size, bio, bio_flags))
+               return false;
+
+       return bio_add_page(bio, page, size, pg_offset) == size;
+}
+
 /*
  * @opf:       bio REQ_OP_* and REQ_* flags as one value
  * @wbc:       optional writeback control for io accounting
        int ret = 0;
        struct bio *bio;
        size_t io_size = min_t(size_t, size, PAGE_SIZE);
-       sector_t sector = disk_bytenr >> 9;
        struct extent_io_tree *tree = &BTRFS_I(page->mapping->host)->io_tree;
 
        ASSERT(bio_ret);
 
        if (*bio_ret) {
-               bool contig;
-               bool can_merge = true;
-
                bio = *bio_ret;
-               if (prev_bio_flags & EXTENT_BIO_COMPRESSED)
-                       contig = bio->bi_iter.bi_sector == sector;
-               else
-                       contig = bio_end_sector(bio) == sector;
-
-               if (btrfs_bio_fits_in_stripe(page, io_size, bio, bio_flags))
-                       can_merge = false;
-
-               if (prev_bio_flags != bio_flags || !contig || !can_merge ||
-                   force_bio_submit ||
-                   bio_add_page(bio, page, io_size, pg_offset) < io_size) {
+               if (force_bio_submit ||
+                   !btrfs_bio_add_page(bio, page, disk_bytenr, io_size,
+                                       pg_offset, prev_bio_flags, bio_flags)) {
                        ret = submit_one_bio(bio, mirror_num, prev_bio_flags);
                        if (ret < 0) {
                                *bio_ret = NULL;