From: Eric Sandeen <sandeen@sandeen.net>
To: xfs@oss.sgi.com
Subject: Re: [PATCH V2] xfs_quota: wire up XFS_GETQSTATV
Date: Wed, 17 Aug 2016 09:43:36 -0500 [thread overview]
Message-ID: <82f3c5f9-204d-845f-16cf-c267085242ac@sandeen.net> (raw)
In-Reply-To: <20160817083340.GB7193@zlang.usersys.redhat.com>
On 8/17/16 3:33 AM, Zorro Lang wrote:
> Hi Eric,
>
> This's what I tried to explain to you:
>
> [root@dhcp-13-149 ~]# mount /dev/mapper/testvg-scratchdev /mnt/scratch -o pquota,gquota,uquota
> [root@dhcp-13-149 xfsprogs-dev]# xfs_quota -xc "limit bsoft=100m bhard=200m fsgqa" /mnt/scratch
> [root@dhcp-13-149 xfsprogs-dev]# xfs_quota -xc "limit -g bsoft=100m bhard=200m fsgqa" /mnt/scratch
> [root@dhcp-13-149 xfsprogs-dev]# xfs_quota -xc "state" /mnt/scratch
> User quota state on /mnt/scratch (/dev/mapper/testvg-scratchdev)
> Accounting: ON
> Enforcement: ON
> Inode: #101 (2 blocks, 2 extents)
> Group quota state on /mnt/scratch (/dev/mapper/testvg-scratchdev)
> Accounting: ON
> Enforcement: ON
> Inode: #99 (2 blocks, 2 extents)
> Project quota state on /mnt/scratch (/dev/mapper/testvg-scratchdev)
> Accounting: ON
> Enforcement: ON
> Inode: #100 (1 blocks, 1 extents)
> Blocks grace time: [7 days]
> Inodes grace time: [7 days]
> Realtime Blocks grace time: [7 days]
And that's all correct, right.
> [root@dhcp-13-149 xfsprogs-dev]# umount /mnt/scratch
> [root@dhcp-13-149 xfsprogs-dev]# mount /dev/mapper/testvg-scratchdev /mnt/scratch -o pquota
Now you have only pquota...
> [root@dhcp-13-149 xfsprogs-dev]# xfs_quota -xc "state" /mnt/scratch
> User quota state on /mnt/scratch (/dev/mapper/testvg-scratchdev)
> Accounting: OFF
> Enforcement: OFF
> Inode: #0 (0 blocks, 0 extents)
> Group quota state on /mnt/scratch (/dev/mapper/testvg-scratchdev)
> Accounting: OFF
> Enforcement: OFF
> Inode: #0 (0 blocks, 0 extents)
> Project quota state on /mnt/scratch (/dev/mapper/testvg-scratchdev)
> Accounting: ON
> Enforcement: ON
> Inode: #100 (1 blocks, 1 extents)
> Blocks grace time: [7 days]
> Inodes grace time: [7 days]
> Realtime Blocks grace time: [7 days]
And pquota is properly shown, but user and group show inode 0.
> [root@dhcp-13-149 ~]# xfs_db -r -c "sb 0" -c "p" /dev/mapper/testvg-scratchdev|grep quot
> uquotino = 101
> gquotino = 99
> pquotino = 100
>
>
> If I someone quota isn't enable, "state" command will print that inode
> number, blocks and extents as 0.
*nod*
> Do you think this's a problem should be fixed?
> If it's a bug, maybe we can fix it on another patch later, because
> it's another bug?
This is a bug in the kernel, because it does not fill in inode information
for inactive quota types, and fills in 0 instead (so we don't even
get NULLFSINO).
I did send a patch for this,
[PATCH] quota: fill in Q_XGETQSTAT inode information for inactive quotas
to the linux-fsdevel list (it is in common vfs quota code, but I probably
should have cc'd the xfs list as well). Jan has indicated that he has
merged it.
With that patch and this one, it should all work as expected.
Thanks,
-Eric
> Thanks,
> Zorro
>
>>
>> I probably could have done some memcpy()'s in
>> state_stat_to_statv(), but opted for the explicit copy-out;
>> the structures aren't identical, although the newer one
>> only differs by padding on the end. If memcpy() is preferable
>> I could send a V2...
>>
>> V2: set sv.qs_version = FS_QSTATV_VERSION1; before calling
>> the quotactl (thanks Zorro!)
>>
>> diff --git a/include/xqm.h b/include/xqm.h
>> index c084b2d..5b6934a 100644
>> --- a/include/xqm.h
>> +++ b/include/xqm.h
>> @@ -32,6 +32,7 @@
>> #define Q_XGETQSTAT XQM_CMD(5) /* get quota subsystem status */
>> #define Q_XQUOTARM XQM_CMD(6) /* free disk space used by dquots */
>> #define Q_XQUOTASYNC XQM_CMD(7) /* delalloc flush, updates dquots */
>> +#define Q_XGETQSTATV XQM_CMD(8) /* newer version of get quota */
>> #define Q_XGETNEXTQUOTA XQM_CMD(9) /* get disk limits and usage */
>>
>> /*
>> @@ -149,4 +150,35 @@ typedef struct fs_quota_stat {
>> __u16 qs_iwarnlimit; /* limit for num warnings */
>> } fs_quota_stat_t;
>>
>> +
>> +#ifndef FS_QSTATV_VERSION1
>> +#define FS_QSTATV_VERSION1 1 /* fs_quota_statv.qs_version */
>> +#endif
>> +
>> +/*
>> + * Some basic information about 'quota files' for Q_XGETQSTATV command
>> + */
>> +struct fs_qfilestatv {
>> + __u64 qfs_ino; /* inode number */
>> + __u64 qfs_nblks; /* number of BBs 512-byte-blks */
>> + __u32 qfs_nextents; /* number of extents */
>> + __u32 qfs_pad; /* pad for 8-byte alignment */
>> +};
>> +
>> +struct fs_quota_statv {
>> + __s8 qs_version; /* version for future changes */
>> + __u8 qs_pad1; /* pad for 16bit alignment */
>> + __u16 qs_flags; /* FS_QUOTA_.* flags */
>> + __u32 qs_incoredqs; /* number of dquots incore */
>> + struct fs_qfilestatv qs_uquota; /* user quota information */
>> + struct fs_qfilestatv qs_gquota; /* group quota information */
>> + struct fs_qfilestatv qs_pquota; /* project quota information */
>> + __s32 qs_btimelimit; /* limit for blks timer */
>> + __s32 qs_itimelimit; /* limit for inodes timer */
>> + __s32 qs_rtbtimelimit;/* limit for rt blks timer */
>> + __u16 qs_bwarnlimit; /* limit for num warnings */
>> + __u16 qs_iwarnlimit; /* limit for num warnings */
>> + __u64 qs_pad2[8]; /* for future proofing */
>> +};
>> +
>> #endif /* __XQM_H__ */
>> diff --git a/quota/linux.c b/quota/linux.c
>> index 74dba01..4f1f3c4 100644
>> --- a/quota/linux.c
>> +++ b/quota/linux.c
>> @@ -55,6 +55,8 @@ xcommand_to_qcommand(
>> return Q_XSETQLIM;
>> case XFS_GETQSTAT:
>> return Q_XGETQSTAT;
>> + case XFS_GETQSTATV:
>> + return Q_XGETQSTATV;
>> case XFS_QUOTARM:
>> return Q_XQUOTARM;
>> case XFS_QSYNC:
>> diff --git a/quota/state.c b/quota/state.c
>> index 8186762..9f6616e 100644
>> --- a/quota/state.c
>> +++ b/quota/state.c
>> @@ -111,12 +111,12 @@ remove_help(void)
>>
>> static void
>> state_qfilestat(
>> - FILE *fp,
>> - fs_path_t *mount,
>> - uint type,
>> - fs_qfilestat_t *qfs,
>> - int accounting,
>> - int enforcing)
>> + FILE *fp,
>> + struct fs_path *mount,
>> + uint type,
>> + struct fs_qfilestatv *qfs,
>> + int accounting,
>> + int enforcing)
>> {
>> fprintf(fp, _("%s quota state on %s (%s)\n"), type_to_string(type),
>> mount->fs_dir, mount->fs_name);
>> @@ -142,39 +142,96 @@ state_timelimit(
>> time_to_string(timelimit, VERBOSE_FLAG | ABSOLUTE_FLAG));
>> }
>>
>> +/*
>> + * fs_quota_stat holds a subset of fs_quota_statv; this copies
>> + * the smaller into the larger, leaving any not-present fields
>> + * empty. This is so the same reporting function can be used
>> + * for both XFS_GETQSTAT and XFS_GETQSTATV results.
>> + */
>> static void
>> -state_quotafile_mount(
>> - FILE *fp,
>> - uint type,
>> - fs_path_t *mount,
>> - uint flags)
>> +state_stat_to_statv(
>> + struct fs_quota_stat *s,
>> + struct fs_quota_statv *sv)
>> {
>> - fs_quota_stat_t s;
>> - char *dev = mount->fs_name;
>> + memset(sv, 0, sizeof(struct fs_quota_statv));
>> +
>> + /* shared information */
>> + sv->qs_version = s->qs_version;
>> + sv->qs_flags = s->qs_flags;
>> + sv->qs_incoredqs = s->qs_incoredqs;
>> + sv->qs_btimelimit = s->qs_btimelimit;
>> + sv->qs_itimelimit = s->qs_itimelimit;
>> + sv->qs_rtbtimelimit = s->qs_rtbtimelimit;
>> + sv->qs_bwarnlimit = s->qs_bwarnlimit;
>> + sv->qs_iwarnlimit = s->qs_iwarnlimit;
>> +
>> + /* Always room for uquota */
>> + sv->qs_uquota.qfs_ino = s->qs_uquota.qfs_ino;
>> + sv->qs_uquota.qfs_nblks = s->qs_uquota.qfs_nblks;
>> + sv->qs_uquota.qfs_nextents = s->qs_uquota.qfs_nextents;
>> +
>> + /*
>> + * If we are here, XFS_GETQSTATV failed and XFS_GETQSTAT passed;
>> + * that is a very strong hint that we're on a kernel which predates
>> + * the on-disk pquota inode; both were added in v3.12. So, we do
>> + * some tricksy determination here.
>> + * gs_gquota may hold either group quota inode info, or project
>> + * quota if that is used instead; which one it actually holds depends
>> + * on the quota flags. (If neither is set, neither is used)
>> + */
>> + if (s->qs_flags & XFS_QUOTA_GDQ_ACCT) {
>> + /* gs_gquota holds group quota info */
>> + sv->qs_gquota.qfs_ino = s->qs_gquota.qfs_ino;
>> + sv->qs_gquota.qfs_nblks = s->qs_gquota.qfs_nblks;
>> + sv->qs_gquota.qfs_nextents = s->qs_gquota.qfs_nextents;
>> + } else if (s->qs_flags & XFS_QUOTA_PDQ_ACCT) {
>> + /* gs_gquota actually holds project quota info */
>> + sv->qs_pquota.qfs_ino = s->qs_gquota.qfs_ino;
>> + sv->qs_pquota.qfs_nblks = s->qs_gquota.qfs_nblks;
>> + sv->qs_pquota.qfs_nextents = s->qs_gquota.qfs_nextents;
>> + }
>> +}
>>
>> - if (xfsquotactl(XFS_GETQSTAT, dev, type, 0, (void *)&s) < 0) {
>> - if (flags & VERBOSE_FLAG)
>> - fprintf(fp, _("%s quota are not enabled on %s\n"),
>> - type_to_string(type), dev);
>> - return;
>> +static void
>> +state_quotafile_mount(
>> + FILE *fp,
>> + uint type,
>> + struct fs_path *mount,
>> + uint flags)
>> +{
>> + struct fs_quota_stat s;
>> + struct fs_quota_statv sv;
>> + char *dev = mount->fs_name;
>> +
>> + sv.qs_version = FS_QSTATV_VERSION1;
>> +
>> + if (xfsquotactl(XFS_GETQSTATV, dev, type, 0, (void *)&sv) < 0) {
>> + if (xfsquotactl(XFS_GETQSTAT, dev, type, 0, (void *)&s) < 0) {
>> + if (flags & VERBOSE_FLAG)
>> + fprintf(fp,
>> + _("%s quota are not enabled on %s\n"),
>> + type_to_string(type), dev);
>> + return;
>> + }
>> + state_stat_to_statv(&s, &sv);
>> }
>>
>> if (type & XFS_USER_QUOTA)
>> - state_qfilestat(fp, mount, XFS_USER_QUOTA, &s.qs_uquota,
>> - s.qs_flags & XFS_QUOTA_UDQ_ACCT,
>> - s.qs_flags & XFS_QUOTA_UDQ_ENFD);
>> + state_qfilestat(fp, mount, XFS_USER_QUOTA, &sv.qs_uquota,
>> + sv.qs_flags & XFS_QUOTA_UDQ_ACCT,
>> + sv.qs_flags & XFS_QUOTA_UDQ_ENFD);
>> if (type & XFS_GROUP_QUOTA)
>> - state_qfilestat(fp, mount, XFS_GROUP_QUOTA, &s.qs_gquota,
>> - s.qs_flags & XFS_QUOTA_GDQ_ACCT,
>> - s.qs_flags & XFS_QUOTA_GDQ_ENFD);
>> + state_qfilestat(fp, mount, XFS_GROUP_QUOTA, &sv.qs_gquota,
>> + sv.qs_flags & XFS_QUOTA_GDQ_ACCT,
>> + sv.qs_flags & XFS_QUOTA_GDQ_ENFD);
>> if (type & XFS_PROJ_QUOTA)
>> - state_qfilestat(fp, mount, XFS_PROJ_QUOTA, &s.qs_gquota,
>> - s.qs_flags & XFS_QUOTA_PDQ_ACCT,
>> - s.qs_flags & XFS_QUOTA_PDQ_ENFD);
>> + state_qfilestat(fp, mount, XFS_PROJ_QUOTA, &sv.qs_pquota,
>> + sv.qs_flags & XFS_QUOTA_PDQ_ACCT,
>> + sv.qs_flags & XFS_QUOTA_PDQ_ENFD);
>>
>> - state_timelimit(fp, XFS_BLOCK_QUOTA, s.qs_btimelimit);
>> - state_timelimit(fp, XFS_INODE_QUOTA, s.qs_itimelimit);
>> - state_timelimit(fp, XFS_RTBLOCK_QUOTA, s.qs_rtbtimelimit);
>> + state_timelimit(fp, XFS_BLOCK_QUOTA, sv.qs_btimelimit);
>> + state_timelimit(fp, XFS_INODE_QUOTA, sv.qs_itimelimit);
>> + state_timelimit(fp, XFS_RTBLOCK_QUOTA, sv.qs_rtbtimelimit);
>> }
>>
>> static void
>>
>> _______________________________________________
>> xfs mailing list
>> xfs@oss.sgi.com
>> http://oss.sgi.com/mailman/listinfo/xfs
>
> _______________________________________________
> xfs mailing list
> xfs@oss.sgi.com
> http://oss.sgi.com/mailman/listinfo/xfs
>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
next prev parent reply other threads:[~2016-08-17 14:43 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-08-12 23:07 [PATCH] xfs_quota: wire up XFS_GETQSTATV Eric Sandeen
2016-08-15 13:44 ` Bill O'Donnell
2016-08-15 16:38 ` Zorro Lang
2016-08-15 16:43 ` Eric Sandeen
2016-08-16 3:17 ` [PATCH V2] " Eric Sandeen
2016-08-17 8:33 ` Zorro Lang
2016-08-17 14:43 ` Eric Sandeen [this message]
2016-08-17 14:58 ` Zorro Lang
2016-08-17 15:02 ` Zorro Lang
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=82f3c5f9-204d-845f-16cf-c267085242ac@sandeen.net \
--to=sandeen@sandeen.net \
--cc=xfs@oss.sgi.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).