]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
gfs2: inode directory consistency checks
authorAndreas Gruenbacher <agruenba@redhat.com>
Thu, 26 Mar 2026 21:56:26 +0000 (22:56 +0100)
committerAndreas Gruenbacher <agruenba@redhat.com>
Tue, 7 Apr 2026 20:20:00 +0000 (22:20 +0200)
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 <agruenba@redhat.com>
fs/gfs2/bmap.c
fs/gfs2/glops.c
fs/gfs2/rgrp.c

index fdcac8e3f2ba26a737b282803d1635fc50c83681..89b043f7065117a24cb22856afe9a832720c178a 100644 (file)
@@ -1539,7 +1539,7 @@ more_rgrps:
                        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)
index aff7e890bf60abd991647ccf25b709dfbd59e096..28f32424ee64bfa8cb976c47e216e7598765c1a2 100644 (file)
@@ -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;
index 8a97ca734afc90b94cf29751fc518bc5fb94278c..7ada7707e99aff66492c4b3ac2de5cb2b21a2acb 100644 (file)
@@ -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);
 }