Skip to content

Commit 99800ce

Browse files
Christoph Hellwigaxboe
Christoph Hellwig
authored andcommitted
block: refacto blkdev_issue_zeroout
Split out two well-defined helpers for hardware supported Write Zeroes and manually writing zeroes using the Write command. Signed-off-by: Christoph Hellwig <[email protected]> Reviewed-by: Martin K. Petersen <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jens Axboe <[email protected]>
1 parent f6eacb2 commit 99800ce

File tree

1 file changed

+55
-39
lines changed

1 file changed

+55
-39
lines changed

block/blk-lib.c

+55-39
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,32 @@ static void __blkdev_issue_write_zeroes(struct block_device *bdev,
135135
*biop = bio;
136136
}
137137

138+
static int blkdev_issue_write_zeroes(struct block_device *bdev, sector_t sector,
139+
sector_t nr_sects, gfp_t gfp, unsigned flags)
140+
{
141+
struct bio *bio = NULL;
142+
struct blk_plug plug;
143+
int ret = 0;
144+
145+
blk_start_plug(&plug);
146+
__blkdev_issue_write_zeroes(bdev, sector, nr_sects, gfp, &bio, flags);
147+
if (bio) {
148+
ret = submit_bio_wait(bio);
149+
bio_put(bio);
150+
}
151+
blk_finish_plug(&plug);
152+
153+
/*
154+
* For some devices there is no non-destructive way to verify whether
155+
* WRITE ZEROES is actually supported. These will clear the capability
156+
* on an I/O error, in which case we'll turn any error into
157+
* "not supported" here.
158+
*/
159+
if (ret && !bdev_write_zeroes_sectors(bdev))
160+
return -EOPNOTSUPP;
161+
return ret;
162+
}
163+
138164
/*
139165
* Convert a number of 512B sectors to a number of pages.
140166
* The result is limited to a number of pages that can fit into a BIO.
@@ -175,6 +201,27 @@ static void __blkdev_issue_zero_pages(struct block_device *bdev,
175201
*biop = bio;
176202
}
177203

204+
static int blkdev_issue_zero_pages(struct block_device *bdev, sector_t sector,
205+
sector_t nr_sects, gfp_t gfp, unsigned flags)
206+
{
207+
struct bio *bio = NULL;
208+
struct blk_plug plug;
209+
int ret = 0;
210+
211+
if (flags & BLKDEV_ZERO_NOFALLBACK)
212+
return -EOPNOTSUPP;
213+
214+
blk_start_plug(&plug);
215+
__blkdev_issue_zero_pages(bdev, sector, nr_sects, gfp, &bio);
216+
if (bio) {
217+
ret = submit_bio_wait(bio);
218+
bio_put(bio);
219+
}
220+
blk_finish_plug(&plug);
221+
222+
return ret;
223+
}
224+
178225
/**
179226
* __blkdev_issue_zeroout - generate number of zero filed write bios
180227
* @bdev: blockdev to issue
@@ -230,52 +277,21 @@ EXPORT_SYMBOL(__blkdev_issue_zeroout);
230277
int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
231278
sector_t nr_sects, gfp_t gfp_mask, unsigned flags)
232279
{
233-
int ret = 0;
234-
sector_t bs_mask;
235-
struct bio *bio;
236-
struct blk_plug plug;
237-
bool try_write_zeroes = !!bdev_write_zeroes_sectors(bdev);
280+
int ret;
238281

239-
bs_mask = (bdev_logical_block_size(bdev) >> 9) - 1;
240-
if ((sector | nr_sects) & bs_mask)
282+
if ((sector | nr_sects) & ((bdev_logical_block_size(bdev) >> 9) - 1))
241283
return -EINVAL;
242284
if (bdev_read_only(bdev))
243285
return -EPERM;
244-
if ((flags & BLKDEV_ZERO_NOFALLBACK) && !try_write_zeroes)
245-
return -EOPNOTSUPP;
246286

247-
retry:
248-
bio = NULL;
249-
blk_start_plug(&plug);
250-
if (try_write_zeroes) {
251-
__blkdev_issue_write_zeroes(bdev, sector, nr_sects, gfp_mask,
252-
&bio, flags);
253-
} else {
254-
__blkdev_issue_zero_pages(bdev, sector, nr_sects, gfp_mask,
255-
&bio);
256-
}
257-
if (bio) {
258-
ret = submit_bio_wait(bio);
259-
bio_put(bio);
260-
}
261-
blk_finish_plug(&plug);
262-
if (ret && try_write_zeroes) {
263-
if (!(flags & BLKDEV_ZERO_NOFALLBACK)) {
264-
try_write_zeroes = false;
265-
goto retry;
266-
}
267-
if (!bdev_write_zeroes_sectors(bdev)) {
268-
/*
269-
* Zeroing offload support was indicated, but the
270-
* device reported ILLEGAL REQUEST (for some devices
271-
* there is no non-destructive way to verify whether
272-
* WRITE ZEROES is actually supported).
273-
*/
274-
ret = -EOPNOTSUPP;
275-
}
287+
if (bdev_write_zeroes_sectors(bdev)) {
288+
ret = blkdev_issue_write_zeroes(bdev, sector, nr_sects,
289+
gfp_mask, flags);
290+
if (!ret)
291+
return ret;
276292
}
277293

278-
return ret;
294+
return blkdev_issue_zero_pages(bdev, sector, nr_sects, gfp_mask, flags);
279295
}
280296
EXPORT_SYMBOL(blkdev_issue_zeroout);
281297

0 commit comments

Comments
 (0)