Merge branch 'for-4.13-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/wq
[sfrench/cifs-2.6.git] / block / blk-lib.c
index e8caecd71688e00a4974b5d45b95bc53e4eaeac5..3fe0aec90597294a15e04b1f89144631b976ab94 100644 (file)
@@ -261,6 +261,19 @@ static int __blkdev_issue_write_zeroes(struct block_device *bdev,
        return 0;
 }
 
+/*
+ * Convert a number of 512B sectors to a number of pages.
+ * The result is limited to a number of pages that can fit into a BIO.
+ * Also make sure that the result is always at least 1 (page) for the cases
+ * where nr_sects is lower than the number of sectors in a page.
+ */
+static unsigned int __blkdev_sectors_to_bio_pages(sector_t nr_sects)
+{
+       sector_t bytes = (nr_sects << 9) + PAGE_SIZE - 1;
+
+       return min(bytes >> PAGE_SHIFT, (sector_t)BIO_MAX_PAGES);
+}
+
 /**
  * __blkdev_issue_zeroout - generate number of zero filed write bios
  * @bdev:      blockdev to issue
@@ -307,18 +320,18 @@ int __blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
 
        ret = 0;
        while (nr_sects != 0) {
-               bio = next_bio(bio, min(nr_sects, (sector_t)BIO_MAX_PAGES),
-                               gfp_mask);
+               bio = next_bio(bio, __blkdev_sectors_to_bio_pages(nr_sects),
+                              gfp_mask);
                bio->bi_iter.bi_sector = sector;
                bio->bi_bdev   = bdev;
                bio_set_op_attrs(bio, REQ_OP_WRITE, 0);
 
                while (nr_sects != 0) {
-                       sz = min((sector_t) PAGE_SIZE >> 9 , nr_sects);
-                       bi_size = bio_add_page(bio, ZERO_PAGE(0), sz << 9, 0);
+                       sz = min((sector_t) PAGE_SIZE, nr_sects << 9);
+                       bi_size = bio_add_page(bio, ZERO_PAGE(0), sz, 0);
                        nr_sects -= bi_size >> 9;
                        sector += bi_size >> 9;
-                       if (bi_size < (sz << 9))
+                       if (bi_size < sz)
                                break;
                }
                cond_resched();