]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
xfs: prepare to reuse the dquot pointer space in struct xfs_inode
authorDarrick J. Wong <djwong@kernel.org>
Thu, 21 Nov 2024 00:20:18 +0000 (16:20 -0800)
committerDarrick J. Wong <djwong@kernel.org>
Mon, 23 Dec 2024 21:06:03 +0000 (13:06 -0800)
Files participating in the metadata directory tree are not accounted to
the quota subsystem.  Therefore, the i_[ugp]dquot pointers in struct
xfs_inode are never used and should always be NULL.

In the next patch we want to add a u64 count of fs blocks reserved for
metadata btree expansion, but we don't want every inode in the fs to pay
the memory price for this feature.  The intent is to union those three
pointers with the u64 counter, but for that to work we must guard
against all access to the dquot pointers for metadata files.

Signed-off-by: "Darrick J. Wong" <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
fs/xfs/libxfs/xfs_attr.c
fs/xfs/libxfs/xfs_bmap.c
fs/xfs/scrub/tempfile.c
fs/xfs/xfs_dquot.h
fs/xfs/xfs_exchrange.c
fs/xfs/xfs_inode.h
fs/xfs/xfs_qm.c
fs/xfs/xfs_quota.h
fs/xfs/xfs_trans.c
fs/xfs/xfs_trans_dquot.c

index 17875ad865f5d6b2fc0ccec7d988d322c4323292..8c04acd30d489cb29c7259b0d1816b64ff2eb002 100644 (file)
@@ -1004,9 +1004,7 @@ xfs_attr_add_fork(
        unsigned int            blks;           /* space reservation */
        int                     error;          /* error return value */
 
-       if (xfs_is_metadir_inode(ip))
-               ASSERT(XFS_IS_DQDETACHED(ip));
-       else
+       if (!xfs_is_metadir_inode(ip))
                ASSERT(!XFS_NOT_DQATTACHED(mp, ip));
 
        blks = XFS_ADDAFORK_SPACE_RES(mp);
index 0842577755f7bb5afc69fe1e4da2dfb206a6bfe1..02323936cc9b203ef5fd039d534acc9848f2693c 100644 (file)
@@ -1042,9 +1042,7 @@ xfs_bmap_add_attrfork(
        int                     error;          /* error return value */
 
        xfs_assert_ilocked(ip, XFS_ILOCK_EXCL);
-       if (xfs_is_metadir_inode(ip))
-               ASSERT(XFS_IS_DQDETACHED(ip));
-       else
+       if (!xfs_is_metadir_inode(ip))
                ASSERT(!XFS_NOT_DQATTACHED(mp, ip));
        ASSERT(!xfs_inode_has_attr_fork(ip));
 
index 2d7ca7e1bbca0f0ab1c91b8c401797f710d88fd2..4ebb5f8459e8f3478a8522e8ffdca3d7c332feb8 100644 (file)
@@ -749,6 +749,7 @@ xrep_tempexch_reserve_quota(
         * or the two inodes have the same dquots.
         */
        if (!XFS_IS_QUOTA_ON(tp->t_mountp) || req->ip1 == req->ip2 ||
+           xfs_is_metadir_inode(req->ip1) ||
            (req->ip1->i_udquot == req->ip2->i_udquot &&
             req->ip1->i_gdquot == req->ip2->i_gdquot &&
             req->ip1->i_pdquot == req->ip2->i_pdquot))
index c617bac75361b2d095066d15de8718b56aa868a8..61217adf5ba5512b5087fc7e0c11590ad6f85e1f 100644 (file)
@@ -160,6 +160,9 @@ static inline struct xfs_dquot *xfs_inode_dquot(
        struct xfs_inode        *ip,
        xfs_dqtype_t            type)
 {
+       if (xfs_is_metadir_inode(ip))
+               return NULL;
+
        switch (type) {
        case XFS_DQTYPE_USER:
                return ip->i_udquot;
index 265c424498933e99f2224a84e0f96f7e834e97cd..f340a2015c4c71363aff6a8abacd05a0c8343d65 100644 (file)
@@ -119,6 +119,9 @@ xfs_exchrange_reserve_quota(
        int                             ip1_error = 0;
        int                             error;
 
+       ASSERT(!xfs_is_metadir_inode(req->ip1));
+       ASSERT(!xfs_is_metadir_inode(req->ip2));
+
        /*
         * Don't bother with a quota reservation if we're not enforcing them
         * or the two inodes have the same dquots.
index 1648dc5a806882278d7eec1cc7451cc9818332fa..1141c2e8e123ae466490519726e913bfe2833bfb 100644 (file)
@@ -25,9 +25,13 @@ struct xfs_dquot;
 typedef struct xfs_inode {
        /* Inode linking and identification information. */
        struct xfs_mount        *i_mount;       /* fs mount struct ptr */
-       struct xfs_dquot        *i_udquot;      /* user dquot */
-       struct xfs_dquot        *i_gdquot;      /* group dquot */
-       struct xfs_dquot        *i_pdquot;      /* project dquot */
+       union {
+               struct {
+                       struct xfs_dquot *i_udquot;     /* user dquot */
+                       struct xfs_dquot *i_gdquot;     /* group dquot */
+                       struct xfs_dquot *i_pdquot;     /* project dquot */
+               };
+       };
 
        /* Inode location stuff */
        xfs_ino_t               i_ino;          /* inode number (agno/agino)*/
index dc8b1010d4d332fe219070caa6de89f50418d575..3abab5fb593e370c03b3b3113d3c859d0aca26c8 100644 (file)
@@ -428,6 +428,8 @@ void
 xfs_qm_dqdetach(
        xfs_inode_t     *ip)
 {
+       if (xfs_is_metadir_inode(ip))
+               return;
        if (!(ip->i_udquot || ip->i_gdquot || ip->i_pdquot))
                return;
 
index d7565462af3dc4920198e529dfed4aff412663e5..105e6eb5762011ab5464955b3531ba7c9f5b8f93 100644 (file)
@@ -29,11 +29,6 @@ struct xfs_buf;
         (XFS_IS_GQUOTA_ON(mp) && (ip)->i_gdquot == NULL) || \
         (XFS_IS_PQUOTA_ON(mp) && (ip)->i_pdquot == NULL))
 
-#define XFS_IS_DQDETACHED(ip) \
-       ((ip)->i_udquot == NULL && \
-        (ip)->i_gdquot == NULL && \
-        (ip)->i_pdquot == NULL)
-
 #define XFS_QM_NEED_QUOTACHECK(mp) \
        ((XFS_IS_UQUOTA_ON(mp) && \
                (mp->m_sb.sb_qflags & XFS_UQUOTA_CHKD) == 0) || \
index 4cd25717c9d13065c488dc1c94cf5734c5f43c56..f53f82456288e5dc7edf36cedb4ac7856550815c 100644 (file)
@@ -1266,6 +1266,9 @@ retry:
        xfs_ilock(ip, XFS_ILOCK_EXCL);
        xfs_trans_ijoin(tp, ip, XFS_ILOCK_EXCL);
 
+       if (xfs_is_metadir_inode(ip))
+               goto out;
+
        error = xfs_qm_dqattach_locked(ip, false);
        if (error) {
                /* Caller should have allocated the dquots! */
@@ -1334,6 +1337,7 @@ retry:
                        goto out_cancel;
        }
 
+out:
        *tpp = tp;
        return 0;
 
index 713b6d243e56313beb6f3a8eaf783b5af72d2d17..765456bf342851850cc2da914a8a75d689a27106 100644 (file)
@@ -156,7 +156,8 @@ xfs_trans_mod_ino_dquot(
        unsigned int                    field,
        int64_t                         delta)
 {
-       ASSERT(!xfs_is_metadir_inode(ip) || XFS_IS_DQDETACHED(ip));
+       if (xfs_is_metadir_inode(ip))
+               return;
 
        xfs_trans_mod_dquot(tp, dqp, field, delta);
 
@@ -246,11 +247,10 @@ xfs_trans_mod_dquot_byino(
        xfs_mount_t     *mp = tp->t_mountp;
 
        if (!XFS_IS_QUOTA_ON(mp) ||
-           xfs_is_quota_inode(&mp->m_sb, ip->i_ino))
+           xfs_is_quota_inode(&mp->m_sb, ip->i_ino) ||
+           xfs_is_metadir_inode(ip))
                return;
 
-       ASSERT(!xfs_is_metadir_inode(ip) || XFS_IS_DQDETACHED(ip));
-
        if (XFS_IS_UQUOTA_ON(mp) && ip->i_udquot)
                xfs_trans_mod_ino_dquot(tp, ip, ip->i_udquot, field, delta);
        if (XFS_IS_GQUOTA_ON(mp) && ip->i_gdquot)