Skip to content

Commit 5f75e08

Browse files
metan-ucwaxboe
authored andcommitted
loop: Disable fallocate() zero and discard if not supported
If fallcate is implemented but zero and discard operations are not supported by the filesystem the backing file is on we continue to fill dmesg with errors from the blk_mq_end_request() since each time we call fallocate() on the loop device the EOPNOTSUPP error from lo_fallocate() ends up propagated into the block layer. In the end syscall succeeds since the blkdev_issue_zeroout() falls back to writing zeroes which makes the errors even more misleading and confusing. How to reproduce: 1. make sure /tmp is mounted as tmpfs 2. dd if=/dev/zero of=/tmp/disk.img bs=1M count=100 3. losetup /dev/loop0 /tmp/disk.img 4. mkfs.ext2 /dev/loop0 5. dmesg |tail [710690.898214] operation not supported error, dev loop0, sector 204672 op 0x9:(WRITE_ZEROES) flags 0x8000800 phys_seg 0 prio class 0 [710690.898279] operation not supported error, dev loop0, sector 522 op 0x9:(WRITE_ZEROES) flags 0x8000800 phys_seg 0 prio class 0 [710690.898603] operation not supported error, dev loop0, sector 16906 op 0x9:(WRITE_ZEROES) flags 0x8000800 phys_seg 0 prio class 0 [710690.898917] operation not supported error, dev loop0, sector 32774 op 0x9:(WRITE_ZEROES) flags 0x8000800 phys_seg 0 prio class 0 [710690.899218] operation not supported error, dev loop0, sector 49674 op 0x9:(WRITE_ZEROES) flags 0x8000800 phys_seg 0 prio class 0 [710690.899484] operation not supported error, dev loop0, sector 65542 op 0x9:(WRITE_ZEROES) flags 0x8000800 phys_seg 0 prio class 0 [710690.899743] operation not supported error, dev loop0, sector 82442 op 0x9:(WRITE_ZEROES) flags 0x8000800 phys_seg 0 prio class 0 [710690.900015] operation not supported error, dev loop0, sector 98310 op 0x9:(WRITE_ZEROES) flags 0x8000800 phys_seg 0 prio class 0 [710690.900276] operation not supported error, dev loop0, sector 115210 op 0x9:(WRITE_ZEROES) flags 0x8000800 phys_seg 0 prio class 0 [710690.900546] operation not supported error, dev loop0, sector 131078 op 0x9:(WRITE_ZEROES) flags 0x8000800 phys_seg 0 prio class 0 This patch changes the lo_fallocate() to clear the flags for zero and discard operations if we get EOPNOTSUPP from the backing file fallocate callback, that way we at least stop spewing errors after the first unsuccessful try. CC: Jan Kara <jack@suse.cz> Signed-off-by: Cyril Hrubis <chrubis@suse.cz> Reviewed-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Jan Kara <jack@suse.cz> Link: https://lore.kernel.org/r/20240613163817.22640-1-chrubis@suse.cz Signed-off-by: Jens Axboe <axboe@kernel.dk>
1 parent e3e5368 commit 5f75e08

File tree

1 file changed

+23
-0
lines changed

1 file changed

+23
-0
lines changed

drivers/block/loop.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,21 @@ static int lo_read_simple(struct loop_device *lo, struct request *rq,
302302
return 0;
303303
}
304304

305+
static void loop_clear_limits(struct loop_device *lo, int mode)
306+
{
307+
struct queue_limits lim = queue_limits_start_update(lo->lo_queue);
308+
309+
if (mode & FALLOC_FL_ZERO_RANGE)
310+
lim.max_write_zeroes_sectors = 0;
311+
312+
if (mode & FALLOC_FL_PUNCH_HOLE) {
313+
lim.max_hw_discard_sectors = 0;
314+
lim.discard_granularity = 0;
315+
}
316+
317+
queue_limits_commit_update(lo->lo_queue, &lim);
318+
}
319+
305320
static int lo_fallocate(struct loop_device *lo, struct request *rq, loff_t pos,
306321
int mode)
307322
{
@@ -320,6 +335,14 @@ static int lo_fallocate(struct loop_device *lo, struct request *rq, loff_t pos,
320335
ret = file->f_op->fallocate(file, mode, pos, blk_rq_bytes(rq));
321336
if (unlikely(ret && ret != -EINVAL && ret != -EOPNOTSUPP))
322337
return -EIO;
338+
339+
/*
340+
* We initially configure the limits in a hope that fallocate is
341+
* supported and clear them here if that turns out not to be true.
342+
*/
343+
if (unlikely(ret == -EOPNOTSUPP))
344+
loop_clear_limits(lo, mode);
345+
323346
return ret;
324347
}
325348

0 commit comments

Comments
 (0)