lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:   Thu, 31 Mar 2022 16:02:56 +0800
From:   Yi Wang <wang.yi59@....com.cn>
To:     djwong@...nel.org
Cc:     linux-xfs@...r.kernel.org, linux-kernel@...r.kernel.org,
        xue.zhihong@....com.cn, wang.yi59@....com.cn,
        wang.liang82@....com.cn, Cheng Lin <cheng.lin130@....com.cn>
Subject: [PATCH] xfs: getattr ignore blocks beyond eof

From: Cheng Lin <cheng.lin130@....com.cn>

Blocks beyond EOF, which preallocated, will be reclaimed at some time.
These blocks can be ignored when getattr.

This patch will optimize query accuracy for getattr blocks.

Signed-off-by: Cheng Lin <cheng.lin130@....com.cn>
Signed-off-by: Yi Wang <wang.yi59@....com.cn>
---
 fs/xfs/xfs_bmap_util.c |  1 +
 fs/xfs/xfs_icache.c    |  1 +
 fs/xfs/xfs_inode.h     |  1 +
 fs/xfs/xfs_iomap.c     |  5 +++++
 fs/xfs/xfs_iops.c      | 19 ++++++++++++++++++-
 5 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
index eb2e387..9f4081d 100644
--- a/fs/xfs/xfs_bmap_util.c
+++ b/fs/xfs/xfs_bmap_util.c
@@ -753,6 +753,7 @@
 	if (error)
 		goto out_unlock;
 
+	ip->i_last_fsb = end_fsb;
 	xfs_inode_clear_eofblocks_tag(ip);
 	goto out_unlock;
 
diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
index 9644f93..43ffb9e 100644
--- a/fs/xfs/xfs_icache.c
+++ b/fs/xfs/xfs_icache.c
@@ -102,6 +102,7 @@ struct xfs_inode *
 	memset(&ip->i_df, 0, sizeof(ip->i_df));
 	ip->i_flags = 0;
 	ip->i_delayed_blks = 0;
+	ip->i_last_fsb = 0;
 	ip->i_diflags2 = mp->m_ino_geo.new_diflags2;
 	ip->i_nblocks = 0;
 	ip->i_forkoff = 0;
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index b7e8f14..56fc41b 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -55,6 +55,7 @@
 	unsigned long		i_flags;	/* see defined flags below */
 	uint64_t		i_delayed_blks;	/* count of delay alloc blks */
 	xfs_fsize_t		i_disk_size;	/* number of bytes in file */
+	xfs_fileoff_t		i_last_fsb;	/* last fsb preallocated */
 	xfs_rfsblock_t		i_nblocks;	/* # of direct & btree blocks */
 	prid_t			i_projid;	/* owner's project id */
 	xfs_extlen_t		i_extsize;	/* basic/minimum extent size */
diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c
index e552ce5..bd9266e 100644
--- a/fs/xfs/xfs_iomap.c
+++ b/fs/xfs/xfs_iomap.c
@@ -881,6 +881,7 @@
 	bool			eof = false, cow_eof = false, shared = false;
 	int			allocfork = XFS_DATA_FORK;
 	int			error = 0;
+	xfs_fileoff_t		prealloc_last_fsb = 0;
 
 	if (xfs_is_shutdown(mp))
 		return -EIO;
@@ -1024,6 +1025,7 @@
 				XFS_B_TO_FSB(mp, mp->m_super->s_maxbytes));
 			ASSERT(p_end_fsb > offset_fsb);
 			prealloc_blocks = p_end_fsb - end_fsb;
+			prealloc_last_fsb = p_end_fsb;
 		}
 	}
 
@@ -1049,6 +1051,9 @@
 		goto out_unlock;
 	}
 
+	if (prealloc_last_fsb && prealloc_blocks)
+		ip->i_last_fsb = prealloc_last_fsb;
+
 	if (allocfork == XFS_COW_FORK) {
 		trace_xfs_iomap_alloc(ip, offset, count, allocfork, &cmap);
 		goto found_cow;
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index b79b384..ca0372c 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -559,8 +559,14 @@
 	struct xfs_inode	*ip = XFS_I(inode);
 	struct xfs_mount	*mp = ip->i_mount;
 
+	xfs_off_t		fsb_beyond_eof;
+	xfs_fileoff_t		end_fsb;
+
 	trace_xfs_getattr(ip);
 
+	end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)XFS_ISIZE(ip));
+	fsb_beyond_eof = ip->i_last_fsb - end_fsb;
+
 	if (xfs_is_shutdown(mp))
 		return -EIO;
 
@@ -574,7 +580,15 @@
 	stat->atime = inode->i_atime;
 	stat->mtime = inode->i_mtime;
 	stat->ctime = inode->i_ctime;
-	stat->blocks = XFS_FSB_TO_BB(mp, ip->i_nblocks + ip->i_delayed_blks);
+
+	if (fsb_beyond_eof > 0) {
+		stat->blocks =
+		XFS_FSB_TO_BB(mp, ip->i_nblocks + ip->i_delayed_blks)
+				  - fsb_beyond_eof;
+	} else {
+		stat->blocks =
+		XFS_FSB_TO_BB(mp, ip->i_nblocks + ip->i_delayed_blks);
+	}
 
 	if (xfs_has_v3inodes(mp)) {
 		if (request_mask & STATX_BTIME) {
@@ -988,6 +1002,9 @@
 	ip->i_disk_size = newsize;
 	xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
 
+	/* update i_last_fsb to newsize when truncate.*/
+	ip->i_last_fsb = XFS_B_TO_FSB(mp, newsize);
+
 	if (newsize <= oldsize) {
 		error = xfs_itruncate_extents(&tp, ip, XFS_DATA_FORK, newsize);
 		if (error)
-- 
1.8.3.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ