diff --git a/fs/gfs2/dir.c b/fs/gfs2/dir.c index e37002560c11f6982f1624f5b25ddb13cf76b8b5..0cf704b2b08a916b833e51f2c1448b6f9f39fb8b 100644 --- a/fs/gfs2/dir.c +++ b/fs/gfs2/dir.c @@ -63,6 +63,7 @@ #include #include #include +#include #include "gfs2.h" #include "incore.h" @@ -914,7 +915,6 @@ static int dir_make_exhash(struct inode *inode) struct qstr args; struct buffer_head *bh, *dibh; struct gfs2_leaf *leaf; - int y; u32 x; __be64 *lp; u64 bn; @@ -981,9 +981,7 @@ static int dir_make_exhash(struct inode *inode) i_size_write(inode, sdp->sd_sb.sb_bsize / 2); gfs2_add_inode_blocks(&dip->i_inode, 1); dip->i_diskflags |= GFS2_DIF_EXHASH; - - for (x = sdp->sd_hash_ptrs, y = -1; x; x >>= 1, y++) ; - dip->i_depth = y; + dip->i_depth = ilog2(sdp->sd_hash_ptrs); gfs2_dinode_out(dip, dibh->b_data); diff --git a/fs/gfs2/glops.c b/fs/gfs2/glops.c index c63bee9adb6a8e175d8e2cfc78abe197264acf5e..be6839451aaf7f1dc212c45de9f9325fd11dba86 100644 --- a/fs/gfs2/glops.c +++ b/fs/gfs2/glops.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "gfs2.h" #include "incore.h" @@ -337,6 +338,7 @@ static int inode_go_demote_ok(const struct gfs2_glock *gl) static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) { + struct gfs2_sbd *sdp = GFS2_SB(&ip->i_inode); const struct gfs2_dinode *str = buf; struct timespec64 atime; u16 height, depth; @@ -383,6 +385,9 @@ static int gfs2_dinode_in(struct gfs2_inode *ip, const void *buf) depth = be16_to_cpu(str->di_depth); if (unlikely(depth > GFS2_DIR_MAX_DEPTH)) goto corrupt; + if ((ip->i_diskflags & GFS2_DIF_EXHASH) && + depth < ilog2(sdp->sd_hash_ptrs)) + goto corrupt; ip->i_depth = (u8)depth; ip->i_entries = be32_to_cpu(str->di_entries);