All of lore.kernel.org
 help / color / mirror / Atom feed
From: Allison Collins <allison.henderson@oracle.com>
To: "Darrick J. Wong" <darrick.wong@oracle.com>,
	david@fromorbit.com, hch@infradead.org
Cc: linux-xfs@vger.kernel.org, amir73il@gmail.com, sandeen@sandeen.net
Subject: Re: [PATCH 09/11] xfs: widen ondisk quota expiration timestamps to handle y2038+
Date: Thu, 27 Aug 2020 23:08:55 -0700	[thread overview]
Message-ID: <2a2a678f-673c-f735-903e-c9f8128818b4@oracle.com> (raw)
In-Reply-To: <159847955663.2601708.15732334977032233773.stgit@magnolia>



On 8/26/20 3:05 PM, Darrick J. Wong wrote:
> From: Darrick J. Wong <darrick.wong@oracle.com>
> 
> Enable the bigtime feature for quota timers.  We decrease the accuracy
> of the timers to ~4s in exchange for being able to set timers up to the
> bigtime maximum.
> 
> Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
ok, looks ok to me
Reviewed-by: Allison Collins <allison.henderson@oracle.com>

> ---
>   fs/xfs/libxfs/xfs_dquot_buf.c  |   21 +++++++++++++++--
>   fs/xfs/libxfs/xfs_format.h     |   50 +++++++++++++++++++++++++++++++++++++++-
>   fs/xfs/libxfs/xfs_quota_defs.h |    3 ++
>   fs/xfs/xfs_dquot.c             |   10 ++++++++
>   fs/xfs/xfs_ondisk.h            |    5 ++++
>   fs/xfs/xfs_qm.c                |   13 +++++++++-
>   fs/xfs/xfs_trans_dquot.c       |    6 +++++
>   7 files changed, 102 insertions(+), 6 deletions(-)
> 
> 
> diff --git a/fs/xfs/libxfs/xfs_dquot_buf.c b/fs/xfs/libxfs/xfs_dquot_buf.c
> index cf85bad8a894..6766417d5ba4 100644
> --- a/fs/xfs/libxfs/xfs_dquot_buf.c
> +++ b/fs/xfs/libxfs/xfs_dquot_buf.c
> @@ -69,6 +69,13 @@ xfs_dquot_verify(
>   	    ddq_type != XFS_DQTYPE_GROUP)
>   		return __this_address;
>   
> +	if ((ddq->d_type & XFS_DQTYPE_BIGTIME) &&
> +	    !xfs_sb_version_hasbigtime(&mp->m_sb))
> +		return __this_address;
> +
> +	if ((ddq->d_type & XFS_DQTYPE_BIGTIME) && !ddq->d_id)
> +		return __this_address;
> +
>   	if (id != -1 && id != be32_to_cpu(ddq->d_id))
>   		return __this_address;
>   
> @@ -295,7 +302,12 @@ xfs_dquot_from_disk_ts(
>   	struct xfs_disk_dquot	*ddq,
>   	__be32			dtimer)
>   {
> -	return be32_to_cpu(dtimer);
> +	uint32_t		t = be32_to_cpu(dtimer);
> +
> +	if (t != 0 && (ddq->d_type & XFS_DQTYPE_BIGTIME))
> +		return xfs_dq_bigtime_to_unix(t);
> +
> +	return t;
>   }
>   
>   /* Convert an incore timer value into an on-disk timer value. */
> @@ -304,5 +316,10 @@ xfs_dquot_to_disk_ts(
>   	struct xfs_dquot	*dqp,
>   	time64_t		timer)
>   {
> -	return cpu_to_be32(timer);
> +	uint32_t		t = timer;
> +
> +	if (timer != 0 && (dqp->q_type & XFS_DQTYPE_BIGTIME))
> +		t = xfs_dq_unix_to_bigtime(timer);
> +
> +	return cpu_to_be32(t);
>   }
> diff --git a/fs/xfs/libxfs/xfs_format.h b/fs/xfs/libxfs/xfs_format.h
> index 972c740aaf7b..9cf84b57e2ce 100644
> --- a/fs/xfs/libxfs/xfs_format.h
> +++ b/fs/xfs/libxfs/xfs_format.h
> @@ -1257,13 +1257,15 @@ static inline bool xfs_dinode_has_bigtime(const struct xfs_dinode *dip)
>   #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_BIGTIME	0x08		/* large expiry timestamps */
>   
>   /* bitmask to determine if this is a user/group/project dquot */
>   #define XFS_DQTYPE_REC_MASK	(XFS_DQTYPE_USER | \
>   				 XFS_DQTYPE_PROJ | \
>   				 XFS_DQTYPE_GROUP)
>   
> -#define XFS_DQTYPE_ANY		(XFS_DQTYPE_REC_MASK)
> +#define XFS_DQTYPE_ANY		(XFS_DQTYPE_REC_MASK | \
> +				 XFS_DQTYPE_BIGTIME)
>   
>   /*
>    * XFS Quota Timers
> @@ -1276,6 +1278,10 @@ static inline bool xfs_dinode_has_bigtime(const struct xfs_dinode *dip)
>    * ondisk min and max defined here can be used directly to constrain the incore
>    * quota expiration timestamps on a Unix system.
>    *
> + * When bigtime is enabled, we trade two bits of precision to expand the
> + * expiration timeout range to match that of big inode timestamps.  The min and
> + * max recorded here are the on-disk limits, not a Unix timestamp.
> + *
>    * The grace period for each quota type is stored in the root dquot (id = 0)
>    * and is applied to a non-root dquot when it exceeds the soft or hard limits.
>    * The length of quota grace periods are unsigned 32-bit quantities measured in
> @@ -1294,6 +1300,48 @@ static inline bool xfs_dinode_has_bigtime(const struct xfs_dinode *dip)
>    */
>   #define XFS_DQ_LEGACY_EXPIRY_MAX	((int64_t)U32_MAX)
>   
> +/*
> + * Smallest possible ondisk quota expiration value with bigtime timestamps.
> + * This corresponds (after conversion to a Unix timestamp) with the incore
> + * expiration of Jan  1 00:00:04 UTC 1970.
> + */
> +#define XFS_DQ_BIGTIME_EXPIRY_MIN	(XFS_DQ_LEGACY_EXPIRY_MIN)
> +
> +/*
> + * Largest supported ondisk quota expiration value with bigtime timestamps.
> + * This corresponds (after conversion to a Unix timestamp) with an incore
> + * expiration of Jul  2 20:20:24 UTC 2486.
> + *
> + * The ondisk field supports values up to -1U, which corresponds to an incore
> + * expiration in 2514.  This is beyond the maximum the bigtime inode timestamp,
> + * so we cap the maximum bigtime quota expiration to the max inode timestamp.
> + */
> +#define XFS_DQ_BIGTIME_EXPIRY_MAX	((int64_t)4074815106U)
> +
> +/*
> + * The following conversion factors assist in converting a quota expiration
> + * timestamp between the incore and ondisk formats.
> + */
> +#define XFS_DQ_BIGTIME_SHIFT	(2)
> +#define XFS_DQ_BIGTIME_SLACK	((int64_t)(1ULL << XFS_DQ_BIGTIME_SHIFT) - 1)
> +
> +/* Convert an incore quota expiration timestamp to an ondisk bigtime value. */
> +static inline uint32_t xfs_dq_unix_to_bigtime(time64_t unix_seconds)
> +{
> +	/*
> +	 * Round the expiration timestamp up to the nearest bigtime timestamp
> +	 * that we can store, to give users the most time to fix problems.
> +	 */
> +	return ((uint64_t)unix_seconds + XFS_DQ_BIGTIME_SLACK) >>
> +			XFS_DQ_BIGTIME_SHIFT;
> +}
> +
> +/* Convert an ondisk bigtime quota expiration value to an incore timestamp. */
> +static inline time64_t xfs_dq_bigtime_to_unix(uint32_t ondisk_seconds)
> +{
> +	return (time64_t)ondisk_seconds << XFS_DQ_BIGTIME_SHIFT;
> +}
> +
>   /*
>    * Default quota grace periods, ranging from zero (use the compiled defaults)
>    * to ~136 years.  These are applied to a non-root dquot that has exceeded
> diff --git a/fs/xfs/libxfs/xfs_quota_defs.h b/fs/xfs/libxfs/xfs_quota_defs.h
> index 9a99910d857e..0f0af4e35032 100644
> --- a/fs/xfs/libxfs/xfs_quota_defs.h
> +++ b/fs/xfs/libxfs/xfs_quota_defs.h
> @@ -23,7 +23,8 @@ typedef uint8_t		xfs_dqtype_t;
>   #define XFS_DQTYPE_STRINGS \
>   	{ XFS_DQTYPE_USER,	"USER" }, \
>   	{ XFS_DQTYPE_PROJ,	"PROJ" }, \
> -	{ XFS_DQTYPE_GROUP,	"GROUP" }
> +	{ XFS_DQTYPE_GROUP,	"GROUP" }, \
> +	{ XFS_DQTYPE_BIGTIME,	"BIGTIME" }
>   
>   /*
>    * flags for q_flags field in the dquot.
> diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
> index 59c03e973741..3f9e11c3df1e 100644
> --- a/fs/xfs/xfs_dquot.c
> +++ b/fs/xfs/xfs_dquot.c
> @@ -223,6 +223,8 @@ xfs_qm_init_dquot_blk(
>   		d->dd_diskdq.d_version = XFS_DQUOT_VERSION;
>   		d->dd_diskdq.d_id = cpu_to_be32(curid);
>   		d->dd_diskdq.d_type = type;
> +		if (curid > 0 && xfs_sb_version_hasbigtime(&mp->m_sb))
> +			d->dd_diskdq.d_type |= XFS_DQTYPE_BIGTIME;
>   		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),
> @@ -1167,6 +1169,14 @@ xfs_qm_dqflush_check(
>   	    !dqp->q_rtb.timer)
>   		return __this_address;
>   
> +	/* bigtime flag should never be set on root dquots */
> +	if (dqp->q_type & XFS_DQTYPE_BIGTIME) {
> +		if (!xfs_sb_version_hasbigtime(&dqp->q_mount->m_sb))
> +			return __this_address;
> +		if (dqp->q_id == 0)
> +			return __this_address;
> +	}
> +
>   	return NULL;
>   }
>   
> diff --git a/fs/xfs/xfs_ondisk.h b/fs/xfs/xfs_ondisk.h
> index 52db8743def1..a13686ce0626 100644
> --- a/fs/xfs/xfs_ondisk.h
> +++ b/fs/xfs/xfs_ondisk.h
> @@ -165,6 +165,11 @@ xfs_check_ondisk_structs(void)
>   			XFS_LEGACY_TIME_MIN);
>   	XFS_CHECK_VALUE(XFS_BIGTIME_TIME_MAX - XFS_BIGTIME_EPOCH_OFFSET,
>   			16299260424LL);
> +
> +	/* Do the same with the incore quota expiration range. */
> +	XFS_CHECK_VALUE(XFS_DQ_BIGTIME_EXPIRY_MIN << XFS_DQ_BIGTIME_SHIFT, 4);
> +	XFS_CHECK_VALUE(XFS_DQ_BIGTIME_EXPIRY_MAX << XFS_DQ_BIGTIME_SHIFT,
> +			16299260424LL);
>   }
>   
>   #endif /* __XFS_ONDISK_H */
> diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c
> index b83a12ecfc35..259588a4227d 100644
> --- a/fs/xfs/xfs_qm.c
> +++ b/fs/xfs/xfs_qm.c
> @@ -661,8 +661,15 @@ xfs_qm_init_quotainfo(
>   	/* Precalc some constants */
>   	qinf->qi_dqchunklen = XFS_FSB_TO_BB(mp, XFS_DQUOT_CLUSTER_SIZE_FSB);
>   	qinf->qi_dqperchunk = xfs_calc_dquots_per_chunk(qinf->qi_dqchunklen);
> -	qinf->qi_expiry_min = XFS_DQ_LEGACY_EXPIRY_MIN;
> -	qinf->qi_expiry_max = XFS_DQ_LEGACY_EXPIRY_MAX;
> +	if (xfs_sb_version_hasbigtime(&mp->m_sb)) {
> +		qinf->qi_expiry_min =
> +			xfs_dq_bigtime_to_unix(XFS_DQ_BIGTIME_EXPIRY_MIN);
> +		qinf->qi_expiry_max =
> +			xfs_dq_bigtime_to_unix(XFS_DQ_BIGTIME_EXPIRY_MAX);
> +	} else {
> +		qinf->qi_expiry_min = XFS_DQ_LEGACY_EXPIRY_MIN;
> +		qinf->qi_expiry_max = XFS_DQ_LEGACY_EXPIRY_MAX;
> +	}
>   
>   	mp->m_qflags |= (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_CHKD);
>   
> @@ -881,6 +888,8 @@ xfs_qm_reset_dqcounts(
>   			ddq->d_bwarns = 0;
>   			ddq->d_iwarns = 0;
>   			ddq->d_rtbwarns = 0;
> +			if (xfs_sb_version_hasbigtime(&mp->m_sb))
> +				ddq->d_type |= XFS_DQTYPE_BIGTIME;
>   		}
>   
>   		if (xfs_sb_version_hascrc(&mp->m_sb)) {
> diff --git a/fs/xfs/xfs_trans_dquot.c b/fs/xfs/xfs_trans_dquot.c
> index c6ba7ef18e06..133fc6fc3edd 100644
> --- a/fs/xfs/xfs_trans_dquot.c
> +++ b/fs/xfs/xfs_trans_dquot.c
> @@ -55,6 +55,12 @@ xfs_trans_log_dquot(
>   {
>   	ASSERT(XFS_DQ_IS_LOCKED(dqp));
>   
> +	/* Upgrade the dquot to bigtime format if possible. */
> +	if (dqp->q_id != 0 &&
> +	    xfs_sb_version_hasbigtime(&tp->t_mountp->m_sb) &&
> +	    !(dqp->q_type & XFS_DQTYPE_BIGTIME))
> +		dqp->q_type |= XFS_DQTYPE_BIGTIME;
> +
>   	tp->t_flags |= XFS_TRANS_DIRTY;
>   	set_bit(XFS_LI_DIRTY, &dqp->q_logitem.qli_item.li_flags);
>   }
> 

  parent reply	other threads:[~2020-08-28  6:11 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-08-26 22:04 [PATCH v4 00/11] xfs: widen timestamps to deal with y2038 Darrick J. Wong
2020-08-26 22:05 ` [PATCH 01/11] xfs: explicitly define inode timestamp range Darrick J. Wong
2020-08-27  6:42   ` Christoph Hellwig
2020-08-28  4:08   ` Allison Collins
2020-08-26 22:05 ` [PATCH 02/11] xfs: refactor quota expiration timer modification Darrick J. Wong
2020-08-27  6:43   ` Christoph Hellwig
2020-08-28  4:08   ` Allison Collins
2020-08-26 22:05 ` [PATCH 03/11] xfs: refactor default quota grace period setting code Darrick J. Wong
2020-08-27  6:44   ` Christoph Hellwig
2020-08-28  4:08   ` Allison Collins
2020-08-26 22:05 ` [PATCH 04/11] xfs: refactor quota timestamp coding Darrick J. Wong
2020-08-27  6:44   ` Christoph Hellwig
2020-08-28  4:08   ` Allison Collins
2020-08-26 22:05 ` [PATCH 05/11] xfs: move xfs_log_dinode_to_disk to the log recovery code Darrick J. Wong
2020-08-27  6:45   ` Christoph Hellwig
2020-08-28  4:08   ` Allison Collins
2020-08-26 22:05 ` [PATCH 06/11] xfs: kill struct xfs_timestamp Darrick J. Wong
2020-08-28  4:08   ` Allison Collins
2020-08-26 22:05 ` [PATCH 07/11] xfs: kill struct xfs_ictimestamp Darrick J. Wong
2020-08-27  6:51   ` Christoph Hellwig
2020-08-27  8:17     ` Amir Goldstein
2020-08-27  8:18       ` Christoph Hellwig
2020-08-27  8:56         ` Amir Goldstein
2020-08-27 15:31     ` Darrick J. Wong
2020-08-26 22:05 ` [PATCH 08/11] xfs: widen ondisk inode timestamps to deal with y2038+ Darrick J. Wong
2020-08-27  6:58   ` Christoph Hellwig
2020-08-27 15:38     ` Darrick J. Wong
2020-08-26 22:05 ` [PATCH 09/11] xfs: widen ondisk quota expiration timestamps to handle y2038+ Darrick J. Wong
2020-08-27  7:00   ` Christoph Hellwig
2020-08-27 17:49     ` Darrick J. Wong
2020-08-28  6:08   ` Allison Collins [this message]
2020-08-26 22:06 ` [PATCH 10/11] xfs: trace timestamp limits Darrick J. Wong
2020-08-27  7:01   ` Christoph Hellwig
2020-08-28  6:08   ` Allison Collins
2020-08-26 22:06 ` [PATCH 11/11] xfs: enable big timestamps Darrick J. Wong
2020-08-28  6:09   ` Allison Collins
2020-08-27  6:41 ` [PATCH v4 00/11] xfs: widen timestamps to deal with y2038 Christoph Hellwig
2020-08-31  6:06 [PATCH v5 " Darrick J. Wong
2020-08-31  6:07 ` [PATCH 09/11] xfs: widen ondisk quota expiration timestamps to handle y2038+ Darrick J. Wong
2020-09-02  2:56 [PATCH v6 00/11] xfs: widen timestamps to deal with y2038 Darrick J. Wong
2020-09-02  2:57 ` [PATCH 09/11] xfs: widen ondisk quota expiration timestamps to handle y2038+ Darrick J. Wong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=2a2a678f-673c-f735-903e-c9f8128818b4@oracle.com \
    --to=allison.henderson@oracle.com \
    --cc=amir73il@gmail.com \
    --cc=darrick.wong@oracle.com \
    --cc=david@fromorbit.com \
    --cc=hch@infradead.org \
    --cc=linux-xfs@vger.kernel.org \
    --cc=sandeen@sandeen.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.