On Tue, Jul 14, 2020 at 08:57:56AM +0100, Christoph Hellwig wrote: > On Mon, Jul 13, 2020 at 06:32:00PM -0700, Darrick J. Wong wrote: > > From: Darrick J. Wong <darrick.wong@xxxxxxxxxx> > > > > Create a new type (xfs_dqtype_t) to represent the type of an incore > > dquot. Break the type field out from the dq_flags field of the incore > > dquot. > > I don't understand why we need separate in-core vs on-disk values for > the type. Why not something like this on top of the whole series: I want to keep the ondisk d_type values separate from the incore q_type values because they don't describe exactly the same concepts: First, the incore qtype has a NONE value that we can pass to the dquot core verifier when we don't actually know if this is a user, group, or project dquot. This should never end up on disk. Second, xfs_dqtype_t is a (barely concealed) enumeration type for quota callers to tell us that they want to perform an action on behalf of user, group, or project quotas. The incore q_flags and the ondisk d_type contain internal state that should not be exposed to quota callers. I feel a need to reiterate that I'm about to start adding more flags to d_type (for y2038+ time support), for which it will be very important to keep d_type and q_{type,flags} separate. I will change the series to define the DQTYPE flags to match the DDQTYPE flags when they do overlap so that I can drop xfs_dquot_type_to_disk, but I'm not going to separate the flag/type/whatever namespaces just to combine them again. --D > diff --git a/fs/xfs/libxfs/xfs_dquot_buf.c b/fs/xfs/libxfs/xfs_dquot_buf.c > index 889e34b1a03335..ef9b8559ff6197 100644 > --- a/fs/xfs/libxfs/xfs_dquot_buf.c > +++ b/fs/xfs/libxfs/xfs_dquot_buf.c > @@ -62,15 +62,14 @@ xfs_dquot_verify( > if (ddq->d_version != XFS_DQUOT_VERSION) > return __this_address; > > - if (ddq->d_type & ~XFS_DDQTYPE_ANY) > + if (ddq->d_type & ~XFS_DQTYPE_ANY) > return __this_address; > - ddq_type = ddq->d_type & XFS_DDQTYPE_REC_MASK; > - if (type != XFS_DQTYPE_NONE && > - ddq_type != xfs_dquot_type_to_disk(type)) > + ddq_type = ddq->d_type & XFS_DQTYPE_REC_MASK; > + if (type != XFS_DQTYPE_NONE && ddq_type != type) > return __this_address; > - if (ddq_type != XFS_DDQTYPE_USER && > - ddq_type != XFS_DDQTYPE_PROJ && > - ddq_type != XFS_DDQTYPE_GROUP) > + if (ddq_type != XFS_DQTYPE_USER && > + ddq_type != XFS_DQTYPE_PROJ && > + ddq_type != XFS_DQTYPE_GROUP) > return __this_address; > > if (id != -1 && id != be32_to_cpu(ddq->d_id)) > @@ -129,7 +128,7 @@ xfs_dqblk_repair( > > dqb->dd_diskdq.d_magic = cpu_to_be16(XFS_DQUOT_MAGIC); > dqb->dd_diskdq.d_version = XFS_DQUOT_VERSION; > - dqb->dd_diskdq.d_type = xfs_dquot_type_to_disk(type); > + dqb->dd_diskdq.d_type = type; > dqb->dd_diskdq.d_id = cpu_to_be32(id); > > if (xfs_sb_version_hascrc(&mp->m_sb)) { > diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h > index eed0c4d5baddbe..e4178c804abf06 100644 > --- a/fs/xfs/libxfs/xfs_format.h > +++ b/fs/xfs/libxfs/xfs_format.h > @@ -1150,16 +1150,25 @@ static inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev) > #define XFS_DQUOT_MAGIC 0x4451 /* 'DQ' */ > #define XFS_DQUOT_VERSION (uint8_t)0x01 /* latest version number */ > > -#define XFS_DDQTYPE_USER 0x01 /* user dquot record */ > -#define XFS_DDQTYPE_PROJ 0x02 /* project dquot record */ > -#define XFS_DDQTYPE_GROUP 0x04 /* group dquot record */ > +#define XFS_DQTYPE_NONE 0 > +#define XFS_DQTYPE_USER 0x01 /* user dquot record */ > +#define XFS_DQTYPE_PROJ 0x02 /* project dquot record */ > +#define XFS_DQTYPE_GROUP 0x04 /* group dquot record */ > + > +#define XFS_DQTYPE_STRINGS \ > + { XFS_DQTYPE_NONE, "NONE" }, \ > + { XFS_DQTYPE_USER, "USER" }, \ > + { XFS_DQTYPE_PROJ, "PROJ" }, \ > + { XFS_DQTYPE_GROUP, "GROUP" } > > /* bitmask to determine if this is a user/group/project dquot */ > -#define XFS_DDQTYPE_REC_MASK (XFS_DDQTYPE_USER | \ > - XFS_DDQTYPE_PROJ | \ > - XFS_DDQTYPE_GROUP) > +#define XFS_DQTYPE_REC_MASK (XFS_DQTYPE_USER | \ > + XFS_DQTYPE_PROJ | \ > + XFS_DQTYPE_GROUP) > + > +#define XFS_DQTYPE_ANY (XFS_DQTYPE_REC_MASK) > > -#define XFS_DDQTYPE_ANY (XFS_DDQTYPE_REC_MASK) > +typedef uint8_t xfs_dqtype_t; > > /* > * This is the main portion of the on-disk representation of quota > @@ -1170,7 +1179,7 @@ static inline void xfs_dinode_put_rdev(struct xfs_dinode *dip, xfs_dev_t rdev) > struct xfs_disk_dquot { > __be16 d_magic; /* dquot magic = XFS_DQUOT_MAGIC */ > __u8 d_version; /* dquot version */ > - __u8 d_type; /* XFS_DDQTYPE_* */ > + xfs_dqtype_t d_type; /* XFS_DQTYPE_* */ > __be32 d_id; /* user,project,group id */ > __be64 d_blk_hardlimit;/* absolute limit on disk blks */ > __be64 d_blk_softlimit;/* preferred limit on disk blks */ > diff --git a/fs/xfs/libxfs/xfs_quota_defs.h b/fs/xfs/libxfs/xfs_quota_defs.h > index 0650fa71fa2bcf..6edd249fdef4ea 100644 > --- a/fs/xfs/libxfs/xfs_quota_defs.h > +++ b/fs/xfs/libxfs/xfs_quota_defs.h > @@ -18,36 +18,6 @@ > typedef uint64_t xfs_qcnt_t; > typedef uint16_t xfs_qwarncnt_t; > > -typedef uint8_t xfs_dqtype_t; > - > -#define XFS_DQTYPE_NONE (0) > -#define XFS_DQTYPE_USER (1) > -#define XFS_DQTYPE_PROJ (2) > -#define XFS_DQTYPE_GROUP (3) > - > -#define XFS_DQTYPE_STRINGS \ > - { XFS_DQTYPE_NONE, "NONE?" }, \ > - { XFS_DQTYPE_USER, "USER" }, \ > - { XFS_DQTYPE_PROJ, "PROJ" }, \ > - { XFS_DQTYPE_GROUP, "GROUP" } > - > -static inline __u8 > -xfs_dquot_type_to_disk( > - xfs_dqtype_t type) > -{ > - switch (type) { > - case XFS_DQTYPE_USER: > - return XFS_DDQTYPE_USER; > - case XFS_DQTYPE_GROUP: > - return XFS_DDQTYPE_GROUP; > - case XFS_DQTYPE_PROJ: > - return XFS_DDQTYPE_PROJ; > - default: > - ASSERT(0); > - return 0; > - } > -} > - > /* > * flags for q_flags field in the dquot. > */ > diff --git a/fs/xfs/xfs_buf_item_recover.c b/fs/xfs/xfs_buf_item_recover.c > index dd150f8bbf5a2a..c2f19d35e05dbd 100644 > --- a/fs/xfs/xfs_buf_item_recover.c > +++ b/fs/xfs/xfs_buf_item_recover.c > @@ -548,11 +548,11 @@ xlog_recover_do_dquot_buffer( > > type = 0; > if (buf_f->blf_flags & XFS_BLF_UDQUOT_BUF) > - type |= XFS_DDQTYPE_USER; > + type |= XFS_DQTYPE_USER; > if (buf_f->blf_flags & XFS_BLF_PDQUOT_BUF) > - type |= XFS_DDQTYPE_PROJ; > + type |= XFS_DQTYPE_PROJ; > if (buf_f->blf_flags & XFS_BLF_GDQUOT_BUF) > - type |= XFS_DDQTYPE_GROUP; > + type |= XFS_DQTYPE_GROUP; > /* > * This type of quotas was turned off, so ignore this buffer > */ > diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c > index 14b0c62943d54e..0581cb930cd75e 100644 > --- a/fs/xfs/xfs_dquot.c > +++ b/fs/xfs/xfs_dquot.c > @@ -182,7 +182,7 @@ xfs_qm_init_dquot_blk( > d->dd_diskdq.d_magic = cpu_to_be16(XFS_DQUOT_MAGIC); > d->dd_diskdq.d_version = XFS_DQUOT_VERSION; > d->dd_diskdq.d_id = cpu_to_be32(curid); > - d->dd_diskdq.d_type = xfs_dquot_type_to_disk(type); > + d->dd_diskdq.d_type = type; > if (xfs_sb_version_hascrc(&mp->m_sb)) { > uuid_copy(&d->dd_uuid, &mp->m_sb.sb_meta_uuid); > xfs_update_cksum((char *)d, sizeof(struct xfs_dqblk), > @@ -481,13 +481,13 @@ xfs_dquot_from_disk( > struct xfs_buf *bp) > { > struct xfs_disk_dquot *ddqp = bp->b_addr + dqp->q_bufoffset; > - __u8 ddq_type = xfs_dquot_type_to_disk(dqp->q_type); > + __u8 ddq_type = dqp->q_type; > > /* > * Ensure that we got the type and ID we were looking for. > * Everything else was checked by the dquot buffer verifier. > */ > - if ((ddqp->d_type & XFS_DDQTYPE_REC_MASK) != ddq_type || > + if ((ddqp->d_type & XFS_DQTYPE_REC_MASK) != ddq_type || > be32_to_cpu(ddqp->d_id) != dqp->q_id) { > xfs_alert_tag(bp->b_mount, XFS_PTAG_VERIFIER_ERROR, > "Metadata corruption detected at %pS, quota %u", > @@ -537,7 +537,7 @@ xfs_dquot_to_disk( > { > ddqp->d_magic = cpu_to_be16(XFS_DQUOT_MAGIC); > ddqp->d_version = XFS_DQUOT_VERSION; > - ddqp->d_type = xfs_dquot_type_to_disk(dqp->q_type); > + ddqp->d_type = dqp->q_type; > ddqp->d_id = cpu_to_be32(dqp->q_id); > ddqp->d_pad0 = 0; > ddqp->d_pad = 0; > diff --git a/fs/xfs/xfs_dquot_item_recover.c b/fs/xfs/xfs_dquot_item_recover.c > index 0955f183a02758..b5afb9fb8cd4fd 100644 > --- a/fs/xfs/xfs_dquot_item_recover.c > +++ b/fs/xfs/xfs_dquot_item_recover.c > @@ -39,7 +39,7 @@ xlog_recover_dquot_ra_pass2( > if (item->ri_buf[1].i_len < sizeof(struct xfs_disk_dquot)) > return; > > - type = recddq->d_type & XFS_DDQTYPE_REC_MASK; > + type = recddq->d_type & XFS_DQTYPE_REC_MASK; > ASSERT(type); > if (log->l_quotaoffs_flag & type) > return; > @@ -91,7 +91,7 @@ xlog_recover_dquot_commit_pass2( > /* > * This type of quotas was turned off, so ignore this record. > */ > - type = recddq->d_type & XFS_DDQTYPE_REC_MASK; > + type = recddq->d_type & XFS_DQTYPE_REC_MASK; > ASSERT(type); > if (log->l_quotaoffs_flag & type) > return 0; > @@ -185,11 +185,11 @@ xlog_recover_quotaoff_commit_pass1( > * group/project quotaoff or both. > */ > if (qoff_f->qf_flags & XFS_UQUOTA_ACCT) > - log->l_quotaoffs_flag |= XFS_DDQTYPE_USER; > + log->l_quotaoffs_flag |= XFS_DQTYPE_USER; > if (qoff_f->qf_flags & XFS_PQUOTA_ACCT) > - log->l_quotaoffs_flag |= XFS_DDQTYPE_PROJ; > + log->l_quotaoffs_flag |= XFS_DQTYPE_PROJ; > if (qoff_f->qf_flags & XFS_GQUOTA_ACCT) > - log->l_quotaoffs_flag |= XFS_DDQTYPE_GROUP; > + log->l_quotaoffs_flag |= XFS_DQTYPE_GROUP; > > return 0; > }