diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2012-08-02 03:48:49 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2012-08-02 03:48:49 -0400 |
commit | f6ff53d3611b564661896be23369b54d84941a0e (patch) | |
tree | 9a6128ce4f3f86e327d088c42e4ddd7002bb410b /block/blk-lib.c | |
parent | 1a9b4993b70fb1884716902774dc9025b457760d (diff) |
block: reorganize rounding of max_discard_sectors
Mostly a preparation for the next patch.
In principle this fixes an infinite loop if max_discard_sectors < granularity,
but that really shouldn't happen.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Acked-by: Vivek Goyal <vgoyal@redhat.com>
Tested-by: Mike Snitzer <snitzer@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block/blk-lib.c')
-rw-r--r-- | block/blk-lib.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/block/blk-lib.c b/block/blk-lib.c index 2b461b496a78..16b06f62e68c 100644 --- a/block/blk-lib.c +++ b/block/blk-lib.c | |||
@@ -44,6 +44,7 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector, | |||
44 | struct request_queue *q = bdev_get_queue(bdev); | 44 | struct request_queue *q = bdev_get_queue(bdev); |
45 | int type = REQ_WRITE | REQ_DISCARD; | 45 | int type = REQ_WRITE | REQ_DISCARD; |
46 | unsigned int max_discard_sectors; | 46 | unsigned int max_discard_sectors; |
47 | unsigned int granularity; | ||
47 | struct bio_batch bb; | 48 | struct bio_batch bb; |
48 | struct bio *bio; | 49 | struct bio *bio; |
49 | int ret = 0; | 50 | int ret = 0; |
@@ -54,18 +55,18 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector, | |||
54 | if (!blk_queue_discard(q)) | 55 | if (!blk_queue_discard(q)) |
55 | return -EOPNOTSUPP; | 56 | return -EOPNOTSUPP; |
56 | 57 | ||
58 | /* Zero-sector (unknown) and one-sector granularities are the same. */ | ||
59 | granularity = max(q->limits.discard_granularity >> 9, 1U); | ||
60 | |||
57 | /* | 61 | /* |
58 | * Ensure that max_discard_sectors is of the proper | 62 | * Ensure that max_discard_sectors is of the proper |
59 | * granularity | 63 | * granularity |
60 | */ | 64 | */ |
61 | max_discard_sectors = min(q->limits.max_discard_sectors, UINT_MAX >> 9); | 65 | max_discard_sectors = min(q->limits.max_discard_sectors, UINT_MAX >> 9); |
66 | max_discard_sectors = round_down(max_discard_sectors, granularity); | ||
62 | if (unlikely(!max_discard_sectors)) { | 67 | if (unlikely(!max_discard_sectors)) { |
63 | /* Avoid infinite loop below. Being cautious never hurts. */ | 68 | /* Avoid infinite loop below. Being cautious never hurts. */ |
64 | return -EOPNOTSUPP; | 69 | return -EOPNOTSUPP; |
65 | } else if (q->limits.discard_granularity) { | ||
66 | unsigned int disc_sects = q->limits.discard_granularity >> 9; | ||
67 | |||
68 | max_discard_sectors &= ~(disc_sects - 1); | ||
69 | } | 70 | } |
70 | 71 | ||
71 | if (flags & BLKDEV_DISCARD_SECURE) { | 72 | if (flags & BLKDEV_DISCARD_SECURE) { |