diff options
author | Mikulas Patocka <mpatocka@redhat.com> | 2018-07-03 13:34:22 -0400 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2018-07-09 11:07:54 -0400 |
commit | b88aef36b87c9787a4db724923ec4f57dfd513f3 (patch) | |
tree | 9d493ac5c131c41f719877fb632493d99b6614e7 /block/blk-lib.c | |
parent | c137969bd4c5b2a67803d10518e3d60d3b13d0cb (diff) |
block: fix infinite loop if the device loses discard capability
If __blkdev_issue_discard is in progress and a device mapper device is
reloaded with a table that doesn't support discard,
q->limits.max_discard_sectors is set to zero. This results in infinite
loop in __blkdev_issue_discard.
This patch checks if max_discard_sectors is zero and aborts with
-EOPNOTSUPP.
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Tested-by: Zdenek Kabelac <mpatocka@redhat.com>
Cc: stable@vger.kernel.org
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block/blk-lib.c')
-rw-r--r-- | block/blk-lib.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/block/blk-lib.c b/block/blk-lib.c index 8faa70f26fcd..d1b9dd03da25 100644 --- a/block/blk-lib.c +++ b/block/blk-lib.c | |||
@@ -68,6 +68,8 @@ int __blkdev_issue_discard(struct block_device *bdev, sector_t sector, | |||
68 | */ | 68 | */ |
69 | req_sects = min_t(sector_t, nr_sects, | 69 | req_sects = min_t(sector_t, nr_sects, |
70 | q->limits.max_discard_sectors); | 70 | q->limits.max_discard_sectors); |
71 | if (!req_sects) | ||
72 | goto fail; | ||
71 | if (req_sects > UINT_MAX >> 9) | 73 | if (req_sects > UINT_MAX >> 9) |
72 | req_sects = UINT_MAX >> 9; | 74 | req_sects = UINT_MAX >> 9; |
73 | 75 | ||
@@ -105,6 +107,14 @@ int __blkdev_issue_discard(struct block_device *bdev, sector_t sector, | |||
105 | 107 | ||
106 | *biop = bio; | 108 | *biop = bio; |
107 | return 0; | 109 | return 0; |
110 | |||
111 | fail: | ||
112 | if (bio) { | ||
113 | submit_bio_wait(bio); | ||
114 | bio_put(bio); | ||
115 | } | ||
116 | *biop = NULL; | ||
117 | return -EOPNOTSUPP; | ||
108 | } | 118 | } |
109 | EXPORT_SYMBOL(__blkdev_issue_discard); | 119 | EXPORT_SYMBOL(__blkdev_issue_discard); |
110 | 120 | ||