xfs
[Top] [All Lists]

Re: [PATCH 3/7] quota: add new quotactl Q_GETNEXTQUOTA

To: Eric Sandeen <sandeen@xxxxxxxxxx>
Subject: Re: [PATCH 3/7] quota: add new quotactl Q_GETNEXTQUOTA
From: Jan Kara <jack@xxxxxxx>
Date: Mon, 25 Jan 2016 15:51:17 +0100
Cc: linux-fsdevel@xxxxxxxxxxxxxxx, xfs@xxxxxxxxxxx, jack@xxxxxxx
Delivered-to: xfs@xxxxxxxxxxx
In-reply-to: <1453487136-12681-4-git-send-email-sandeen@xxxxxxxxxx>
References: <1453487136-12681-1-git-send-email-sandeen@xxxxxxxxxx> <1453487136-12681-4-git-send-email-sandeen@xxxxxxxxxx>
User-agent: Mutt/1.5.24 (2015-08-30)
On Fri 22-01-16 12:25:32, Eric Sandeen wrote:
> Q_GETNEXTQUOTA is exactly like Q_GETQUOTA, except that it
> will return quota information for the id equal to or greater
> than the id requested.  In other words, if the requested id has
> no quota, the command will return quota information for the
> next higher id which does have a quota set.  If no higher id
> has an active quota, -ESRCH is returned.
> 
> This allows filesystems to do efficient iteration in kernelspace,
> much like extN filesystems do in userspace when asked to report
> all active quotas.
> 
> This does require a new data structure for userspace, as the
> current structure does not include an ID for the returned quota
> information.
> 
> Today, Ext4 with a hidden quota inode requires getpwent-style
> iterations, and for systems which have i.e. LDAP backends,
> this can be very slow, or even impossible if iteration is not
> allowed in the configuration.
> 
> Signed-off-by: Eric Sandeen <sandeen@xxxxxxxxxx>

The patch seems to be missing addition of Q_GETNEXTQUOTA into
quotactl_cmd_write(). Otherwise it looks good to me.

                                                        Honza

> ---
>  fs/quota/quota.c           |   30 ++++++++++++++++++++++++++++++
>  include/uapi/linux/quota.h |   14 ++++++++++++++
>  2 files changed, 44 insertions(+), 0 deletions(-)
> 
> diff --git a/fs/quota/quota.c b/fs/quota/quota.c
> index 0a6dd71..ffa4e0b 100644
> --- a/fs/quota/quota.c
> +++ b/fs/quota/quota.c
> @@ -222,6 +222,34 @@ static int quota_getquota(struct super_block *sb, int 
> type, qid_t id,
>       return 0;
>  }
>  
> +/*
> + * Return quota for next active quota >= this id, if any exists,
> + * otherwise return -ESRCH via ->get_nextdqblk
> + */
> +static int quota_getnextquota(struct super_block *sb, int type, qid_t id,
> +                       void __user *addr)
> +{
> +     struct kqid qid;
> +     struct qc_dqblk fdq;
> +     struct if_nextdqblk idq;
> +     int ret;
> +
> +     if (!sb->s_qcop->get_nextdqblk)
> +             return -ENOSYS;
> +     qid = make_kqid(current_user_ns(), type, id);
> +     if (!qid_valid(qid))
> +             return -EINVAL;
> +     ret = sb->s_qcop->get_nextdqblk(sb, &qid, &fdq);
> +     if (ret)
> +             return ret;
> +     /* struct if_nextdqblk is a superset of struct if_dqblk */
> +     copy_to_if_dqblk((struct if_dqblk *)&idq, &fdq);
> +     idq.dqb_id = from_kqid(current_user_ns(), qid);
> +     if (copy_to_user(addr, &idq, sizeof(idq)))
> +             return -EFAULT;
> +     return 0;
> +}
> +
>  static void copy_from_if_dqblk(struct qc_dqblk *dst, struct if_dqblk *src)
>  {
>       dst->d_spc_hardlimit = qbtos(src->dqb_bhardlimit);
> @@ -698,6 +726,8 @@ static int do_quotactl(struct super_block *sb, int type, 
> int cmd, qid_t id,
>               return quota_setinfo(sb, type, addr);
>       case Q_GETQUOTA:
>               return quota_getquota(sb, type, id, addr);
> +     case Q_GETNEXTQUOTA:
> +             return quota_getnextquota(sb, type, id, addr);
>       case Q_SETQUOTA:
>               return quota_setquota(sb, type, id, addr);
>       case Q_SYNC:
> diff --git a/include/uapi/linux/quota.h b/include/uapi/linux/quota.h
> index 9c95b2c..38baddb 100644
> --- a/include/uapi/linux/quota.h
> +++ b/include/uapi/linux/quota.h
> @@ -71,6 +71,7 @@
>  #define Q_SETINFO  0x800006  /* set information about quota files */
>  #define Q_GETQUOTA 0x800007  /* get user quota structure */
>  #define Q_SETQUOTA 0x800008  /* set user quota structure */
> +#define Q_GETNEXTQUOTA 0x800009      /* get disk limits and usage >= ID */
>  
>  /* Quota format type IDs */
>  #define      QFMT_VFS_OLD 1
> @@ -119,6 +120,19 @@ struct if_dqblk {
>       __u32 dqb_valid;
>  };
>  
> +struct if_nextdqblk {
> +     __u64 dqb_bhardlimit;
> +     __u64 dqb_bsoftlimit;
> +     __u64 dqb_curspace;
> +     __u64 dqb_ihardlimit;
> +     __u64 dqb_isoftlimit;
> +     __u64 dqb_curinodes;
> +     __u64 dqb_btime;
> +     __u64 dqb_itime;
> +     __u32 dqb_valid;
> +     __u32 dqb_id;
> +};
> +
>  /*
>   * Structure used for setting quota information about file via quotactl
>   * Following flags are used to specify which fields are valid
> -- 
> 1.7.1
> 
-- 
Jan Kara <jack@xxxxxxxx>
SUSE Labs, CR

<Prev in Thread] Current Thread [Next in Thread>