]> git.proxmox.com Git - mirror_ubuntu-hirsute-kernel.git/commitdiff
xfs: stop using q_core.d_flags in the quota code
authorDarrick J. Wong <darrick.wong@oracle.com>
Tue, 14 Jul 2020 17:37:22 +0000 (10:37 -0700)
committerDarrick J. Wong <darrick.wong@oracle.com>
Wed, 29 Jul 2020 03:24:14 +0000 (20:24 -0700)
Use the incore dq_flags to figure out the dquot type.  This is the first
step towards removing xfs_disk_dquot from the incore dquot.

Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Chandan Babu R <chandanrlinux@gmail.com>
fs/xfs/xfs_dquot.c
fs/xfs/xfs_dquot.h
fs/xfs/xfs_dquot_item.c

index 5408ec82e0d9fe16dfb9a3f90cc8105afd4d8bf4..3d1d876b45fcb23287d498cdbdcdb8fe7b9764dd 100644 (file)
@@ -561,6 +561,15 @@ xfs_dquot_from_disk(
        return 0;
 }
 
+/* Copy the in-core quota fields into the on-disk buffer. */
+void
+xfs_dquot_to_disk(
+       struct xfs_disk_dquot   *ddqp,
+       struct xfs_dquot        *dqp)
+{
+       memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot));
+}
+
 /* Allocate and initialize the dquot buffer for this in-core dquot. */
 static int
 xfs_qm_dqread_alloc(
@@ -1115,6 +1124,21 @@ xfs_dquot_done(
        }
 }
 
+/* Check incore dquot for errors before we flush. */
+static xfs_failaddr_t
+xfs_qm_dqflush_check(
+       struct xfs_dquot        *dqp)
+{
+       __u8                    type = dqp->dq_flags & XFS_DQ_ALLTYPES;
+
+       if (type != XFS_DQ_USER &&
+           type != XFS_DQ_GROUP &&
+           type != XFS_DQ_PROJ)
+               return __this_address;
+
+       return NULL;
+}
+
 /*
  * Write a modified dquot to disk.
  * The dquot must be locked and the flush lock too taken by caller.
@@ -1173,8 +1197,16 @@ xfs_qm_dqflush(
                goto out_abort;
        }
 
-       /* This is the only portion of data that needs to persist */
-       memcpy(ddqp, &dqp->q_core, sizeof(struct xfs_disk_dquot));
+       fa = xfs_qm_dqflush_check(dqp);
+       if (fa) {
+               xfs_alert(mp, "corrupt dquot ID 0x%x in memory at %pS",
+                               be32_to_cpu(dqp->q_core.d_id), fa);
+               xfs_buf_relse(bp);
+               error = -EFSCORRUPTED;
+               goto out_abort;
+       }
+
+       xfs_dquot_to_disk(ddqp, dqp);
 
        /*
         * Clear the dirty field and remember the flush lsn for later use.
index 6d43c48c67a17f661dafcef709528dde10cf9d2c..944e43a0e2028a18ec8a623fa8ed9f1b1bd9e2d5 100644 (file)
@@ -145,6 +145,8 @@ static inline bool xfs_dquot_lowsp(struct xfs_dquot *dqp)
        return false;
 }
 
+void xfs_dquot_to_disk(struct xfs_disk_dquot *ddqp, struct xfs_dquot *dqp);
+
 #define XFS_DQ_IS_LOCKED(dqp)  (mutex_is_locked(&((dqp)->q_qlock)))
 #define XFS_DQ_IS_DIRTY(dqp)   ((dqp)->q_flags & XFS_DQFLAG_DIRTY)
 #define XFS_QM_ISUDQ(dqp)      ((dqp)->dq_flags & XFS_DQ_USER)
index d7e4de7151d7f5ee9e4fc82272aaf4026313e05e..fc21e48c889c81cde1d133d774edc0bb0a706618 100644 (file)
@@ -45,6 +45,7 @@ xfs_qm_dquot_logitem_format(
        struct xfs_log_item     *lip,
        struct xfs_log_vec      *lv)
 {
+       struct xfs_disk_dquot   ddq;
        struct xfs_dq_logitem   *qlip = DQUOT_ITEM(lip);
        struct xfs_log_iovec    *vecp = NULL;
        struct xfs_dq_logformat *qlf;
@@ -58,8 +59,9 @@ xfs_qm_dquot_logitem_format(
        qlf->qlf_boffset = qlip->qli_dquot->q_bufoffset;
        xlog_finish_iovec(lv, vecp, sizeof(struct xfs_dq_logformat));
 
-       xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_DQUOT,
-                       &qlip->qli_dquot->q_core,
+       xfs_dquot_to_disk(&ddq, qlip->qli_dquot);
+
+       xlog_copy_iovec(lv, &vecp, XLOG_REG_TYPE_DQUOT, &ddq,
                        sizeof(struct xfs_disk_dquot));
 }