]> git.baikalelectronics.ru Git - kernel.git/commitdiff
xfs: only check the superblock version for dinode size calculation
authorChristoph Hellwig <hch@lst.de>
Wed, 12 Apr 2023 04:26:14 +0000 (09:56 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 20 Apr 2023 10:07:37 +0000 (12:07 +0200)
commit 54bef14faa8a38d3e3f506b86d41318dfc346ebe upstream.

The size of the dinode structure is only dependent on the file system
version, so instead of checking the individual inode version just use
the newly added xfs_sb_version_has_large_dinode helper, and simplify
various calling conventions.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Chandan Rajendra <chandanrlinux@gmail.com>
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Chandan Babu R <chandan.babu@oracle.com>
Acked-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/xfs/libxfs/xfs_attr_leaf.c
fs/xfs/libxfs/xfs_bmap.c
fs/xfs/libxfs/xfs_format.h
fs/xfs/libxfs/xfs_ialloc.c
fs/xfs/libxfs/xfs_inode_buf.c
fs/xfs/libxfs/xfs_inode_fork.c
fs/xfs/libxfs/xfs_inode_fork.h
fs/xfs/libxfs/xfs_log_format.h
fs/xfs/xfs_inode_item.c
fs/xfs/xfs_log_recover.c
fs/xfs/xfs_symlink.c

index 3d5e09f7e3a7c4442029a0740f22117d51bac46e..f5b16120c64dbb0d3d0f07b0d084e11ba09f2f50 100644 (file)
@@ -456,7 +456,7 @@ xfs_attr_shortform_bytesfit(
        int                     offset;
 
        /* rounded down */
-       offset = (XFS_LITINO(mp, dp->i_d.di_version) - bytes) >> 3;
+       offset = (XFS_LITINO(mp) - bytes) >> 3;
 
        if (dp->i_d.di_format == XFS_DINODE_FMT_DEV) {
                minforkoff = roundup(sizeof(xfs_dev_t), 8) >> 3;
@@ -523,8 +523,7 @@ xfs_attr_shortform_bytesfit(
        minforkoff = roundup(minforkoff, 8) >> 3;
 
        /* attr fork btree root can have at least this many key/ptr pairs */
-       maxforkoff = XFS_LITINO(mp, dp->i_d.di_version) -
-                       XFS_BMDR_SPACE_CALC(MINABTPTRS);
+       maxforkoff = XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(MINABTPTRS);
        maxforkoff = maxforkoff >> 3;   /* rounded down */
 
        if (offset >= maxforkoff)
index d900e3e6c93375f65b3b7c7941f2736484d2b86d..1e0fab62cd7dc6f422d508bdee49b85120a3dd92 100644 (file)
@@ -192,14 +192,12 @@ xfs_default_attroffset(
        struct xfs_mount        *mp = ip->i_mount;
        uint                    offset;
 
-       if (mp->m_sb.sb_inodesize == 256) {
-               offset = XFS_LITINO(mp, ip->i_d.di_version) -
-                               XFS_BMDR_SPACE_CALC(MINABTPTRS);
-       } else {
+       if (mp->m_sb.sb_inodesize == 256)
+               offset = XFS_LITINO(mp) - XFS_BMDR_SPACE_CALC(MINABTPTRS);
+       else
                offset = XFS_BMDR_SPACE_CALC(6 * MINABTPTRS);
-       }
 
-       ASSERT(offset < XFS_LITINO(mp, ip->i_d.di_version));
+       ASSERT(offset < XFS_LITINO(mp));
        return offset;
 }
 
index c20c4dd6e1d3242859eb051a3f5be08b04dd3a8d..31fa9ab2ab612d9f98604e7add9979e15310a4f3 100644 (file)
@@ -963,8 +963,12 @@ typedef enum xfs_dinode_fmt {
 /*
  * Inode size for given fs.
  */
-#define XFS_LITINO(mp, version) \
-       ((int)(((mp)->m_sb.sb_inodesize) - xfs_dinode_size(version)))
+#define XFS_DINODE_SIZE(sbp) \
+       (xfs_sb_version_has_v3inode(sbp) ? \
+               sizeof(struct xfs_dinode) : \
+               offsetof(struct xfs_dinode, di_crc))
+#define XFS_LITINO(mp) \
+       ((mp)->m_sb.sb_inodesize - XFS_DINODE_SIZE(&(mp)->m_sb))
 
 /*
  * Inode data & attribute fork sizes, per inode.
@@ -973,13 +977,9 @@ typedef enum xfs_dinode_fmt {
 #define XFS_DFORK_BOFF(dip)            ((int)((dip)->di_forkoff << 3))
 
 #define XFS_DFORK_DSIZE(dip,mp) \
-       (XFS_DFORK_Q(dip) ? \
-               XFS_DFORK_BOFF(dip) : \
-               XFS_LITINO(mp, (dip)->di_version))
+       (XFS_DFORK_Q(dip) ? XFS_DFORK_BOFF(dip) : XFS_LITINO(mp))
 #define XFS_DFORK_ASIZE(dip,mp) \
-       (XFS_DFORK_Q(dip) ? \
-               XFS_LITINO(mp, (dip)->di_version) - XFS_DFORK_BOFF(dip) : \
-               0)
+       (XFS_DFORK_Q(dip) ? XFS_LITINO(mp) - XFS_DFORK_BOFF(dip) : 0)
 #define XFS_DFORK_SIZE(dip,mp,w) \
        ((w) == XFS_DATA_FORK ? \
                XFS_DFORK_DSIZE(dip, mp) : \
index ddf92b14223abf853d2922e94c57c1e0ad230e53..391e441d43a033d94307c73c4a42d57bdd2c86c5 100644 (file)
@@ -339,7 +339,7 @@ xfs_ialloc_inode_init(
                xfs_buf_zero(fbuf, 0, BBTOB(fbuf->b_length));
                for (i = 0; i < M_IGEO(mp)->inodes_per_cluster; i++) {
                        int     ioffset = i << mp->m_sb.sb_inodelog;
-                       uint    isize = xfs_dinode_size(version);
+                       uint    isize = XFS_DINODE_SIZE(&mp->m_sb);
 
                        free = xfs_make_iptr(mp, fbuf, i);
                        free->di_magic = cpu_to_be16(XFS_DINODE_MAGIC);
index c4fdb0c012aaf16e9c05e2976a2573c2cfb5e4fa..3505691a17e2bc5e6f5171cbad1feb509e426430 100644 (file)
@@ -417,7 +417,7 @@ xfs_dinode_verify_forkoff(
        case XFS_DINODE_FMT_LOCAL:      /* fall through ... */
        case XFS_DINODE_FMT_EXTENTS:    /* fall through ... */
        case XFS_DINODE_FMT_BTREE:
-               if (dip->di_forkoff >= (XFS_LITINO(mp, dip->di_version) >> 3))
+               if (dip->di_forkoff >= (XFS_LITINO(mp) >> 3))
                        return __this_address;
                break;
        default:
index 93357072b19da184170f9946fdca5c72cd9aca91..e758d74b2b629c3935cc3da9e3e5158f3eea5c04 100644 (file)
@@ -183,7 +183,7 @@ xfs_iformat_local(
         */
        if (unlikely(size > XFS_DFORK_SIZE(dip, ip->i_mount, whichfork))) {
                xfs_warn(ip->i_mount,
-       "corrupt inode %Lu (bad size %d for local fork, size = %d).",
+       "corrupt inode %Lu (bad size %d for local fork, size = %zd).",
                        (unsigned long long) ip->i_ino, size,
                        XFS_DFORK_SIZE(dip, ip->i_mount, whichfork));
                xfs_inode_verifier_error(ip, -EFSCORRUPTED,
index 7b845c052fb455ec56359956cc72f8a094348c8a..a84a1557d11ce25f6b25ce81911effe9da2c8c09 100644 (file)
@@ -46,14 +46,9 @@ struct xfs_ifork {
                        (ip)->i_afp : \
                        (ip)->i_cowfp))
 #define XFS_IFORK_DSIZE(ip) \
-       (XFS_IFORK_Q(ip) ? \
-               XFS_IFORK_BOFF(ip) : \
-               XFS_LITINO((ip)->i_mount, (ip)->i_d.di_version))
+       (XFS_IFORK_Q(ip) ? XFS_IFORK_BOFF(ip) : XFS_LITINO((ip)->i_mount))
 #define XFS_IFORK_ASIZE(ip) \
-       (XFS_IFORK_Q(ip) ? \
-               XFS_LITINO((ip)->i_mount, (ip)->i_d.di_version) - \
-                       XFS_IFORK_BOFF(ip) : \
-               0)
+       (XFS_IFORK_Q(ip) ? XFS_LITINO((ip)->i_mount) - XFS_IFORK_BOFF(ip) : 0)
 #define XFS_IFORK_SIZE(ip,w) \
        ((w) == XFS_DATA_FORK ? \
                XFS_IFORK_DSIZE(ip) : \
index e5f97c69b3205e96c38b14b729fd10f3b42fff8a..d3b255f427893e5c4a1b9382a18af712d0ae4c9c 100644 (file)
@@ -424,12 +424,10 @@ struct xfs_log_dinode {
        /* structure must be padded to 64 bit alignment */
 };
 
-static inline uint xfs_log_dinode_size(int version)
-{
-       if (version == 3)
-               return sizeof(struct xfs_log_dinode);
-       return offsetof(struct xfs_log_dinode, di_next_unlinked);
-}
+#define xfs_log_dinode_size(mp)                                                \
+       (xfs_sb_version_has_v3inode(&(mp)->m_sb) ?                      \
+               sizeof(struct xfs_log_dinode) :                         \
+               offsetof(struct xfs_log_dinode, di_next_unlinked))
 
 /*
  * Buffer Log Format defintions
index 9d673bb1f9956cb39c868999a148310381c54de7..2f995455559727a14b54ff9080b333b0675ce1fd 100644 (file)
@@ -125,7 +125,7 @@ xfs_inode_item_size(
 
        *nvecs += 2;
        *nbytes += sizeof(struct xfs_inode_log_format) +
-                  xfs_log_dinode_size(ip->i_d.di_version);
+                  xfs_log_dinode_size(ip->i_mount);
 
        xfs_inode_item_data_fork_size(iip, nvecs, nbytes);
        if (XFS_IFORK_Q(ip))
@@ -370,7 +370,7 @@ xfs_inode_item_format_core(
 
        dic = xlog_prepare_iovec(lv, vecp, XLOG_REG_TYPE_ICORE);
        xfs_inode_to_log_dinode(ip, dic, ip->i_itemp->ili_item.li_lsn);
-       xlog_finish_iovec(lv, *vecp, xfs_log_dinode_size(ip->i_d.di_version));
+       xlog_finish_iovec(lv, *vecp, xfs_log_dinode_size(ip->i_mount));
 }
 
 /*
index 598a8c00a082e183b2ca8f6e396f86a4d2955687..884e0c6689bf19923135ed3ed87b97cb2c3ea3ac 100644 (file)
@@ -3089,7 +3089,7 @@ xlog_recover_inode_pass2(
                error = -EFSCORRUPTED;
                goto out_release;
        }
-       isize = xfs_log_dinode_size(ldip->di_version);
+       isize = xfs_log_dinode_size(mp);
        if (unlikely(item->ri_buf[1].i_len > isize)) {
                XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(7)",
                                     XFS_ERRLEVEL_LOW, mp, ldip,
index 97336fb9119ac376805a3b94af118f270d97b9e8..3312820700f315a847b985e7b7038adec00467ba 100644 (file)
@@ -201,7 +201,7 @@ xfs_symlink(
         * The symlink will fit into the inode data fork?
         * There can't be any attributes so we get the whole variable part.
         */
-       if (pathlen <= XFS_LITINO(mp, dp->i_d.di_version))
+       if (pathlen <= XFS_LITINO(mp))
                fs_blocks = 0;
        else
                fs_blocks = xfs_symlink_blocks(mp, pathlen);