[v6] xfs: introduce protection for drop nlink

Message ID 202310101009011817522@zte.com.cn
State New
Headers
Series [v6] xfs: introduce protection for drop nlink |

Commit Message

cheng.lin130@zte.com.cn Oct. 10, 2023, 2:09 a.m. UTC
  From: Cheng Lin <cheng.lin130@zte.com.cn>

When abnormal drop_nlink are detected on the inode,
return error, to avoid corruption propagation.

Signed-off-by: Cheng Lin <cheng.lin130@zte.com.cn>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
---
 fs/xfs/xfs_inode.c | 7 +++++++
 1 file changed, 7 insertions(+)
  

Comments

Christoph Hellwig Oct. 10, 2023, 6:57 a.m. UTC | #1
On Tue, Oct 10, 2023 at 10:09:01AM +0800, cheng.lin130@zte.com.cn wrote:
> From: Cheng Lin <cheng.lin130@zte.com.cn>
> 
> When abnormal drop_nlink are detected on the inode,
> return error, to avoid corruption propagation.

I know this has been through a few cycles, but wouldn't it be useful
to have at least a little description here how that case could happen?
  
cheng.lin130@zte.com.cn Oct. 11, 2023, 6:51 a.m. UTC | #2
> On Tue, Oct 10, 2023 at 10:09:01AM +0800, cheng.lin130@zte.com.cn wrote:
> > From: Cheng Lin <cheng.lin130@zte.com.cn>
> > 
> > When abnormal drop_nlink are detected on the inode,
> > return error, to avoid corruption propagation.
> I know this has been through a few cycles, but wouldn't it be useful
> to have at least a little description here how that case could happen?
Unfortunately, I don't know how the underflow happened. The purpose
of this patch is to prevent the situation from getting worse and provide
users can repair it at the appropriate moment afterwards.
  

Patch

diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 9e62cc500..0fa1ac5e0 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -919,6 +919,13 @@  xfs_droplink(
 	xfs_trans_t *tp,
 	xfs_inode_t *ip)
 {
+	if (VFS_I(ip)->i_nlink == 0) {
+		xfs_alert(ip->i_mount,
+			  "%s: Attempt to drop inode (%llu) with nlink zero.",
+			  __func__, ip->i_ino);
+		return -EFSCORRUPTED;
+	}
+
 	xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG);

 	drop_nlink(VFS_I(ip));