aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--block/blk-lib.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/block/blk-lib.c b/block/blk-lib.c
index e16185b0d8e1..5d793e143f3c 100644
--- a/block/blk-lib.c
+++ b/block/blk-lib.c
@@ -41,6 +41,7 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
41 struct request_queue *q = bdev_get_queue(bdev); 41 struct request_queue *q = bdev_get_queue(bdev);
42 int type = flags & BLKDEV_IFL_BARRIER ? 42 int type = flags & BLKDEV_IFL_BARRIER ?
43 DISCARD_BARRIER : DISCARD_NOBARRIER; 43 DISCARD_BARRIER : DISCARD_NOBARRIER;
44 unsigned int max_discard_sectors;
44 struct bio *bio; 45 struct bio *bio;
45 int ret = 0; 46 int ret = 0;
46 47
@@ -50,10 +51,18 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
50 if (!blk_queue_discard(q)) 51 if (!blk_queue_discard(q))
51 return -EOPNOTSUPP; 52 return -EOPNOTSUPP;
52 53
53 while (nr_sects && !ret) { 54 /*
54 unsigned int max_discard_sectors = 55 * Ensure that max_discard_sectors is of the proper
55 min(q->limits.max_discard_sectors, UINT_MAX >> 9); 56 * granularity
57 */
58 max_discard_sectors = min(q->limits.max_discard_sectors, UINT_MAX >> 9);
59 if (q->limits.discard_granularity) {
60 unsigned int disc_sects = q->limits.discard_granularity >> 9;
56 61
62 max_discard_sectors &= ~(disc_sects - 1);
63 }
64
65 while (nr_sects && !ret) {
57 bio = bio_alloc(gfp_mask, 1); 66 bio = bio_alloc(gfp_mask, 1);
58 if (!bio) { 67 if (!bio) {
59 ret = -ENOMEM; 68 ret = -ENOMEM;