[PATCH 2/2] loop: use vfs_getattr_nosec for accurate file size

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Rajeev Mishra <rajeevm@xxxxxxx>

In lo_calculate_size(), use vfs_getattr_nosec() for non-block files.
For block files, continue using i_size_read(). This improves size
accuracy on network and distributed filesystems.

Signed-off-by: Rajeev Mishra <rajeevm@xxxxxxx>
---
 drivers/block/loop.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 0e1b9eb9db10..a6214ae40ef0 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -139,9 +139,24 @@ 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.
+	 */
+	if (S_ISBLK(file->f_inode->i_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;
+	}
+
 	if (lo->lo_offset > 0)
 		loopsize -= lo->lo_offset;
 	/* offset is beyond i_size, weird but possible */
-- 
2.47.3





[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux