summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRajeev Mishra <rajeevm@hpe.com>2025-08-18 18:48:21 +0000
committerJens Axboe <axboe@kernel.dk>2025-08-18 13:10:35 -0600
commit47b71abd58461a67cae71d2f2a9d44379e4e2fcf (patch)
treeaeb6c4c30fecf14adda0ba23a4061feb503966a2
parent8aa5a3b68ad144da49a3d17f165e6561255e3529 (diff)
loop: use vfs_getattr_nosec for accurate file size
Use vfs_getattr_nosec() in lo_calculate_size() for getting the file size, rather than just read the cached inode size via i_size_read(). This provides better results than cached inode data, particularly for network filesystems where metadata may be stale. Signed-off-by: Rajeev Mishra <rajeevm@hpe.com> Reviewed-by: Yu Kuai <yukuai3@huawei.com> Link: https://lore.kernel.org/r/20250818184821.115033-3-rajeevm@hpe.com [axboe: massage commit message] Signed-off-by: Jens Axboe <axboe@kernel.dk>
-rw-r--r--drivers/block/loop.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 0e1b9eb9db10..57263c273f0f 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -139,9 +139,20 @@ static int part_shift;
static loff_t lo_calculate_size(struct loop_device *lo, struct file *file)
{
+ struct kstat stat;
loff_t loopsize;
- /* Compute loopsize in bytes */
- loopsize = i_size_read(file->f_mapping->host);
+ int ret;
+
+ /*
+ * Get the accurate file size. This provides better results than
+ * cached inode data, particularly for network filesystems where
+ * metadata may be stale.
+ */
+ ret = vfs_getattr_nosec(&file->f_path, &stat, STATX_SIZE, 0);
+ if (ret)
+ return 0;
+
+ loopsize = stat.size;
if (lo->lo_offset > 0)
loopsize -= lo->lo_offset;
/* offset is beyond i_size, weird but possible */