block: fix problem with sending down discard that isn't of correct granularity
If the queue doesn't have a limit set, or it just set UINT_MAX like we default to, we coud be sending down a discard request that isn't of the correct granularity if the block size is > 512b. Fix this by adjusting max_discard_sectors down to the proper alignment. Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
This commit is contained in:
parent
f10d9f617a
commit
10d1f9e2cc
|
@ -41,6 +41,7 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
|
|||
struct request_queue *q = bdev_get_queue(bdev);
|
||||
int type = flags & BLKDEV_IFL_BARRIER ?
|
||||
DISCARD_BARRIER : DISCARD_NOBARRIER;
|
||||
unsigned int max_discard_sectors;
|
||||
struct bio *bio;
|
||||
int ret = 0;
|
||||
|
||||
|
@ -50,10 +51,18 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
|
|||
if (!blk_queue_discard(q))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
while (nr_sects && !ret) {
|
||||
unsigned int max_discard_sectors =
|
||||
min(q->limits.max_discard_sectors, UINT_MAX >> 9);
|
||||
/*
|
||||
* Ensure that max_discard_sectors is of the proper
|
||||
* granularity
|
||||
*/
|
||||
max_discard_sectors = min(q->limits.max_discard_sectors, UINT_MAX >> 9);
|
||||
if (q->limits.discard_granularity) {
|
||||
unsigned int disc_sects = q->limits.discard_granularity >> 9;
|
||||
|
||||
max_discard_sectors &= ~(disc_sects - 1);
|
||||
}
|
||||
|
||||
while (nr_sects && !ret) {
|
||||
bio = bio_alloc(gfp_mask, 1);
|
||||
if (!bio) {
|
||||
ret = -ENOMEM;
|
||||
|
|
Loading…
Reference in New Issue