[PATCH 15/18] gfs2: inode directory consistency checks

Andreas Gruenbacher <[email protected]> Mon, 13 Apr 2026 16:52:08 +0200
Newsgroups dev.linux.lists.gfs2
Message-ID <[email protected]>
In gfs2_dinode_in(), only allow directories to have the GFS2_DIF_EXHASH
flag set.  This will prevent other parts of the code from treating
regular inodes as directories based on the presence of that flag.

In sweep_bh_for_rgrps() and __gfs2_free_blocks(), check if the
GFS2_DIF_EXHASH flag is set instead of checking if i_depth is non-zero.
This matches what the directory code does.  (The i_depth checks were
introduced in commit 6d3117b412951 ("GFS2: Wipe directory hash table
metadata when deallocating a directory").)

Signed-off-by: Andreas Gruenbacher <[email protected]>
---
 fs/gfs2/bmap.c  | 2 +-
 fs/gfs2/glops.c | 5 +++++
 fs/gfs2/rgrp.c  | 2 +-
 3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index fdcac8e3f2ba..89b043f70651 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -1539,7 +1539,7 @@ static int sweep_bh_for_rgrps(struct gfs2_inode *ip, struct gfs2_holder *rd_gh,
 			revokes = jblocks_rqsted;
 			if (meta)
 				revokes += end - start;
-			else if (ip->i_depth)
+			else if (ip->i_diskflags & GFS2_DIF_EXHASH)
 				revokes += sdp->sd_inptrs;
 			ret = gfs2_trans_begin(sdp, jblocks_rqsted, revokes);
 			if (ret)
diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c
index aff7e890bf60..28f32424ee64 100644
--- a/fs/gfs2/glops.c
+++ b/fs/gfs2/glops.c
@@ -457,6 +457,11 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf)
 	ip->i_depth = (u8)depth;
 	ip->i_entries = be32_to_cpu(str->di_entries);
 
+	if (!S_ISDIR(inode->i_mode) && (ip->i_diskflags & GFS2_DIF_EXHASH)) {
+		gfs2_consist_inode(ip);
+		return -EIO;
+	}
+
 	if (gfs2_is_stuffed(ip) && inode->i_size > gfs2_max_stuffed_size(ip)) {
 		gfs2_consist_inode(ip);
 		return -EIO;
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index 8a97ca734afc..7ada7707e99a 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -2529,7 +2529,7 @@ void __gfs2_free_blocks(struct gfs2_inode *ip, struct gfs2_rgrpd *rgd,
 	rgrp_unlock_local(rgd);
 
 	/* Directories keep their data in the metadata address space */
-	if (meta || ip->i_depth || gfs2_is_jdata(ip))
+	if (meta || (ip->i_diskflags & GFS2_DIF_EXHASH) || gfs2_is_jdata(ip))
 		gfs2_journal_wipe(ip, bstart, blen);
 }
 
-- 
2.53.0