On Mon, Aug 25, 2025 at 02:23:00PM +0800, Yu Kuai wrote: > From: Yu Kuai <yukuai3@xxxxxxxxxx> > > By default, /dev/sda is block specail file from devtmpfs, getattr will > return file size as zero, causing loop failed for raw block device. > > We can add bdev_statx() to return device size, however this may introduce > changes that are not acknowledged by user. Fix this problem by reverting > changes for block special file, file mapping host is set to bdev inode > while opening, and use i_size_read() directly to get device size. > > Fixes: 47b71abd5846 ("loop: use vfs_getattr_nosec for accurate file size") > Reported-by: kernel test robot <oliver.sang@xxxxxxxxx> > Closes: https://lore.kernel.org/oe-lkp/202508200409.b2459c02-lkp@xxxxxxxxx > Signed-off-by: Yu Kuai <yukuai3@xxxxxxxxxx> > --- > drivers/block/loop.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/drivers/block/loop.c b/drivers/block/loop.c > index 57263c273f0f..cde235bd883c 100644 > --- a/drivers/block/loop.c > +++ b/drivers/block/loop.c > @@ -153,6 +153,9 @@ static loff_t lo_calculate_size(struct loop_device *lo, struct file *file) > return 0; > > loopsize = stat.size; > + if (!loopsize && S_ISBLK(stat.mode)) > + loopsize = i_size_read(file->f_mapping->host); `stat $BDEV_PATH` never works for getting bdev size, so it looks wrong to call vfs_getattr_nosec() with bdev path for retrieving bdev's size. So just wondering why not take the following more readable way? /* vfs_getattr() never works for retrieving bdev size */ if (S_ISBLK(stat.mode)) { loopsize = i_size_read(file->f_mapping->host); } else { ret = vfs_getattr_nosec(&file->f_path, &stat, STATX_SIZE, 0); if (ret) return 0; loopsize = stat.size; } Also the above looks like how application reads file size in case of bdev involved. Thanks, Ming