linux-xfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Darrick J. Wong" <darrick.wong@oracle.com>
To: Eric Sandeen <sandeen@redhat.com>
Cc: linux-xfs <linux-xfs@vger.kernel.org>
Subject: Re: [PATCH 1/1 V2] xfs_quota: allow individual timer extension
Date: Tue, 19 May 2020 09:38:10 -0700	[thread overview]
Message-ID: <20200519163810.GP17627@magnolia> (raw)
In-Reply-To: <37e9d7d7-d783-69a1-f44f-dfcc4baeb773@redhat.com>

On Mon, May 18, 2020 at 03:09:30PM -0500, Eric Sandeen wrote:
> The only grace period which can be set via xfs_quota today is for id 0,
> i.e. the default grace period for all users.  However, setting an
> individual grace period is useful; for example:
> 
>  Alice has a soft quota of 100 inodes, and a hard quota of 200 inodes
>  Alice uses 150 inodes, and enters a short grace period
>  Alice really needs to use those 150 inodes past the grace period
>  The administrator extends Alice's grace period until next Monday
> 
> vfs quota users such as ext4 can do this today, with setquota -T
> 
> xfs_quota can now accept an optional user id or name (symmetric with
> how warn limits are specified), in which case that user's grace period
> is extended to expire the given amount of time from now(). 
> 
> To maintain compatibility with old command lines, if none of 
> [-d|id|name] are specified, default limits are set as before.
> 
> (kernelspace requires updates to enable all this as well.)
> 
> Signed-off-by: Eric Sandeen <sandeen@redhat.com>
> ---
> 
> V2: Add comments about only extending if past soft limits
>     Fix typo/mistake checking block hard limits instead of soft
> 
> diff --git a/man/man8/xfs_quota.8 b/man/man8/xfs_quota.8
> index e6fe7cd1..dd0479cd 100644
> --- a/man/man8/xfs_quota.8
> +++ b/man/man8/xfs_quota.8
> @@ -457,14 +457,46 @@ must be specified.
>  .B \-bir
>  ]
>  .I value
> +[
> +.B -d
> +|
> +.I id
> +|
> +.I name
> +]
>  .br
>  Allows the quota enforcement timeout (i.e. the amount of time allowed
>  to pass before the soft limits are enforced as the hard limits) to
>  be modified. The current timeout setting can be displayed using the
>  .B state
> -command. The value argument is a number of seconds, but units of
> -\&'minutes', 'hours', 'days', and 'weeks' are also understood
> +command.
> +.br
> +When setting the default timer via the
> +.B \-d
> +option, or for
> +.B id
> +0, or if no argument is given after
> +.I value
> +the
> +.I value
> +argument is a number of seconds indicating the relative amount of time after
> +soft limits are exceeded, before hard limits are enforced.
> +.br
> +When setting any other individual timer by
> +.I id
> +or
> +.I name,
> +the
> +.I value
> +is the number of seconds from now, at which time the hard limits will be enforced.
> +This allows extending the grace time of an individual user who has exceeded soft
> +limits.
> +.br
> +For
> +.I value,
> +units of \&'minutes', 'hours', 'days', and 'weeks' are also understood
>  (as are their abbreviations 'm', 'h', 'd', and 'w').
> +.br
>  .HP
>  .B warn
>  [
> diff --git a/quota/edit.c b/quota/edit.c
> index 442b608c..5fdb8ce7 100644
> --- a/quota/edit.c
> +++ b/quota/edit.c
> @@ -419,6 +419,7 @@ restore_f(
>  
>  static void
>  set_timer(
> +	uint32_t	id,
>  	uint		type,
>  	uint		mask,
>  	char		*dev,
> @@ -427,14 +428,43 @@ set_timer(
>  	fs_disk_quota_t	d;
>  
>  	memset(&d, 0, sizeof(d));
> +
> +	/*
> +	 * If id is specified we are extending grace time by value
> +	 * Otherwise we are setting the default grace time
> +	 */
> +	if (id) {
> +		time_t	now;
> +
> +		/* Get quota to find out whether user is past soft limits */
> +		if (xfsquotactl(XFS_GETQUOTA, dev, type, id, (void *)&d) < 0) {
> +			exitcode = 1;
> +			fprintf(stderr, _("%s: cannot get quota: %s\n"),
> +					progname, strerror(errno));
> +				return;
> +		}
> +
> +		time(&now);
> +
> +		/* Only set grace time if user is already past soft limit */
> +		if (d.d_blk_softlimit && d.d_bcount > d.d_blk_softlimit)
> +			d.d_btimer = now + value;
> +		if (d.d_ino_softlimit && d.d_icount > d.d_ino_softlimit)
> +			d.d_itimer = now + value;
> +		if (d.d_rtb_softlimit && d.d_rtbcount > d.d_rtb_softlimit)
> +			d.d_rtbtimer = now + value;

Hmm, I /was/ going to complain about 32-bit wraparound, but then
realized that the whole ioctl interface is totally __s32 and needs
y2038 updates and meh.

Someone looking for a project could work on either fixing the xfs quota
ioctls, or the vfs quota ioctls, or both, assuming Arnd didn't already
fix the VFS...

Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>

--D

> +	} else {
> +		d.d_btimer = value;
> +		d.d_itimer = value;
> +		d.d_rtbtimer = value;
> +	}
> +
>  	d.d_version = FS_DQUOT_VERSION;
>  	d.d_flags = type;
>  	d.d_fieldmask = mask;
> -	d.d_itimer = value;
> -	d.d_btimer = value;
> -	d.d_rtbtimer = value;
> +	d.d_id = id;
>  
> -	if (xfsquotactl(XFS_SETQLIM, dev, type, 0, (void *)&d) < 0) {
> +	if (xfsquotactl(XFS_SETQLIM, dev, type, id, (void *)&d) < 0) {
>  		exitcode = 1;
>  		fprintf(stderr, _("%s: cannot set timer: %s\n"),
>  				progname, strerror(errno));
> @@ -447,10 +477,15 @@ timer_f(
>  	char		**argv)
>  {
>  	uint		value;
> -	int		c, type = 0, mask = 0;
> +	char		*name = NULL;
> +	uint32_t	id = 0;
> +	int		c, flags = 0, type = 0, mask = 0;
>  
> -	while ((c = getopt(argc, argv, "bgipru")) != EOF) {
> +	while ((c = getopt(argc, argv, "bdgipru")) != EOF) {
>  		switch (c) {
> +		case 'd':
> +			flags |= DEFAULTS_FLAG;
> +			break;
>  		case 'b':
>  			mask |= FS_DQ_BTIMER;
>  			break;
> @@ -474,23 +509,45 @@ timer_f(
>  		}
>  	}
>  
> -	if (argc != optind + 1)
> +	 /*
> +	 * Older versions of the command did not accept -d|id|name,
> +	 * so in that case we assume we're setting default timer,
> +	 * and the last arg is the timer value.
> +	 *
> +	 * Otherwise, if the defaults flag is set, we expect 1 more arg for
> +	 * timer value ; if not, 2 more args: 1 for value, one for id/name.
> +	 */
> +	if (!(flags & DEFAULTS_FLAG) && (argc == optind + 1)) {
> +		value = cvttime(argv[optind++]);
> +	} else if (flags & DEFAULTS_FLAG) {
> +		if (argc != optind + 1)
> +			return command_usage(&timer_cmd);
> +		value = cvttime(argv[optind++]);
> +	} else if (argc == optind + 2) {
> +		value = cvttime(argv[optind++]);
> +		name = (flags & DEFAULTS_FLAG) ? "0" : argv[optind++];
> +	} else
>  		return command_usage(&timer_cmd);
>  
> -	value = cvttime(argv[optind++]);
>  
> +	/* if none of -bir specified, set them all */
>  	if (!mask)
>  		mask = FS_DQ_TIMER_MASK;
>  
>  	if (!type) {
>  		type = XFS_USER_QUOTA;
>  	} else if (type != XFS_GROUP_QUOTA &&
> -	           type != XFS_PROJ_QUOTA &&
> -	           type != XFS_USER_QUOTA) {
> +		   type != XFS_PROJ_QUOTA &&
> +		   type != XFS_USER_QUOTA) {
>  		return command_usage(&timer_cmd);
>  	}
>  
> -	set_timer(type, mask, fs_path->fs_name, value);
> +	if (name)
> +		id = id_from_string(name, type);
> +
> +	if (id >= 0)
> +		set_timer(id, type, mask, fs_path->fs_name, value);
> +
>  	return 0;
>  }
>  
> @@ -616,9 +673,9 @@ edit_init(void)
>  
>  	timer_cmd.name = "timer";
>  	timer_cmd.cfunc = timer_f;
> -	timer_cmd.argmin = 2;
> +	timer_cmd.argmin = 1;
>  	timer_cmd.argmax = -1;
> -	timer_cmd.args = _("[-bir] [-g|-p|-u] value");
> +	timer_cmd.args = _("[-bir] [-g|-p|-u] value [-d|id|name]");
>  	timer_cmd.oneline = _("set quota enforcement timeouts");
>  	timer_cmd.help = timer_help;
>  	timer_cmd.flags = CMD_FLAG_FOREIGN_OK;
> 

  reply	other threads:[~2020-05-19 16:38 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-18 18:46 [PATCH 0/SEVERAL] xfs, xfstests, xfsprogs: quota timer updates Eric Sandeen
2020-05-18 18:48 ` [PATCH 0/6] xfs: quota timer enhancements Eric Sandeen
2020-05-18 18:48   ` [PATCH 1/6] xfs: group quota should return EDQUOT when prj quota enabled Eric Sandeen
2020-05-19 16:22     ` Darrick J. Wong
2020-05-18 18:49   ` [PATCH 2/6] xfs: always return -ENOSPC on project quota reservation failure Eric Sandeen
2020-05-19 16:18     ` Darrick J. Wong
2020-05-18 18:49   ` [PATCH 3/6] xfs: fix up some whitespace in quota code Eric Sandeen
2020-05-19 16:25     ` Darrick J. Wong
2020-05-18 18:50   ` [PATCH 4/6] xfs: pass xfs_dquot to xfs_qm_adjust_dqtimers Eric Sandeen
2020-05-19 16:26     ` Darrick J. Wong
2020-05-18 18:51   ` [PATCH 5/6] xfs: per-type quota timers and warn limits Eric Sandeen
2020-05-19 16:27     ` Darrick J. Wong
2020-05-20 18:41     ` [PATCH 4.5/6] xfs: switch xfs_get_defquota to take explicit type Eric Sandeen
2020-05-20 20:36       ` Darrick J. Wong
2020-05-20 20:41         ` Eric Sandeen
2020-05-20 20:49           ` Darrick J. Wong
2020-05-20 18:43     ` [PATCH 5/6 V2] xfs: per-type quota timers and warn limits Eric Sandeen
2020-05-20 20:31       ` Darrick J. Wong
2020-05-20 20:42         ` Eric Sandeen
2020-05-18 18:52   ` [PATCH 6/6] xfs: allow individual quota grace period extension Eric Sandeen
2020-05-19 16:39     ` Darrick J. Wong
2020-05-19 17:21       ` Eric Sandeen
2020-05-18 19:23 ` [PATCH 0/1] xfs_quota: allow individual timer extension Eric Sandeen
2020-05-18 19:24   ` [PATCH 1/1] " Eric Sandeen
2020-05-18 20:04     ` Eric Sandeen
2020-05-18 20:09     ` [PATCH 1/1 V2] " Eric Sandeen
2020-05-19 16:38       ` Darrick J. Wong [this message]
2020-05-19 21:34         ` Darrick J. Wong
2020-05-18 19:59 ` [PATCH 0/4] fstests: more quota related tests Eric Sandeen
2020-05-18 19:59   ` [PATCH 1/4] xfs: make sure our default quota warning limits and grace periods survive quotacheck Eric Sandeen
2020-05-31 16:17     ` Eryu Guan
2020-05-18 20:00   ` [PATCH 2/4] generic: test per-type quota softlimit enforcement timeout Eric Sandeen
2020-05-31 16:15     ` Eryu Guan
2020-06-01 12:48       ` Zorro Lang
2020-06-01 14:36         ` Eric Sandeen
2020-06-01 16:39         ` Darrick J. Wong
2020-06-11  5:12           ` Zorro Lang
2020-06-11 15:40             ` Darrick J. Wong
2020-05-18 20:00   ` [PATCH 3/4] fstests: individual user grace period extension via setquota Eric Sandeen
2020-05-18 20:01   ` [PATCH 4/4] fstests: individual user grace period extension via xfs_quota Eric Sandeen
2020-05-20 15:39   ` [PATCH 0/4] fstests: more quota related tests Darrick J. Wong
2020-05-20 15:46     ` Eric Sandeen

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=20200519163810.GP17627@magnolia \
    --to=darrick.wong@oracle.com \
    --cc=linux-xfs@vger.kernel.org \
    --cc=sandeen@redhat.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).