quotactl(2) units of reported sizes on ZFS

0 views
Skip to first unread message

Norman Gray

unread,
Jun 3, 2024, 12:26:29 PMJun 3
to FreeBSD Questions

Hello, list.

The call quotactl(2) reports quota sizes in units of 'blocks', but how big is a block?

Traditionally, of course, the answer is 512B, and when I use quotactl(2) to Q_GETQUOTA for a user, with reference to a ZFS filesystem, the results match the output of `zfs userspace` if I assume that block size.

But I can't see that written down anywhere, neither in the quotactl manpage, nor in /usr/include/ufs/ufs/quota.h. Also, I wouldn't be at all surprised if quotas were reported in different 'block sizes', on differently-configured zpools (for example with a different ashift value), so the assumption that 'block=512B' could be right on one machine/filesystem but wrong on another.

So how big is 'a block', when interpreting the result of quotactl(2)?

I've found this question weirdly hard to answer, asking on two of the forums and another freebsd.org list.

I'm aware of libzfs, but I can't find any documentation on that, either. I can see libzfs in the ZFS repo [1], but there doesn't seem to be a manpage covering the library, nor obviously relevant comments within /usr/include/libzfs.h. I can see a mention of zfs_prop_get_userquota in that header file (I should probably be using that, rather than quotactl()), but... no documentation.

(There is the separate anomaly that the quotactl(2) manpage says that it is only supported on UFS, but it manifestly also works without error on a ZFS filesystem.)

Can anyone shed some light?

Best wishes,

Norman


[1] https://github.com/openzfs/zfs/tree/master


--
Norman Gray : https://nxg.me.uk

Dag-Erling Smørgrav

unread,
Jun 4, 2024, 6:17:34 PMJun 4
to Norman Gray, FreeBSD Questions
Norman Gray <gr...@nxg.name> writes:
> The call quotactl(2) reports quota sizes in units of 'blocks', but how
> big is a block? Traditionally, of course, the answer is 512B, [...]

You could simply have stopped there, it's a POSIX requirement.

DES
--
Dag-Erling Smørgrav - d...@FreeBSD.org

Norman Gray

unread,
Jun 5, 2024, 4:49:53 AMJun 5
to Dag-Erling Smørgrav, FreeBSD Questions

Dag-Erling, hello.

On 4 Jun 2024, at 23:17, Dag-Erling Smørgrav wrote:

> Norman Gray <gr...@nxg.name> writes:
>> The call quotactl(2) reports quota sizes in units of 'blocks', but how
>> big is a block? Traditionally, of course, the answer is 512B, [...]
>
> You could simply have stopped there, it's a POSIX requirement.

That's an interesting direction to come from -- thanks!

Can you point to chapter and verse, though? Looking at [1], and specifically the specification of the contents of sys/stat.h [2], I find:

> The unit for the st_blocks member of the stat structure is not defined within POSIX.1-2017. In some implementations it is 512 bytes. It may differ on a file system basis. There is no correlation between values of the st_blocks and st_blksize, and the f_bsize (from <sys/statvfs.h>) structure members.

That's stat.h, of course, rather than anything to do with quotas specifically. But POSIX doesn't mention quotas (not surprisingly), so if the quotactl manpage were going to silently adopt a POSIX unit definition, it's stat.h I'd expect it to come from.

Individual utilities -- for example `ulimit` [3] or `df` -- document that one or other argument is in units of 512B 'blocks', but that's a user-interface issue.

Best wishes,

Norman



[1] The Open Group Base Specifications Issue 7, 2018 edition <https://pubs.opengroup.org/onlinepubs/9699919799/toc.htm>
[2] https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/sys_stat.h.html
[3] https://pubs.opengroup.org/onlinepubs/9699919799/utilities/ulimit.html

Norman Gray

unread,
Jul 1, 2024, 11:46:19 AM (4 days ago) Jul 1
to FreeBSD Questions

Dear list,

This might now be semi-solved?

Looping back to the thread excerpted below, I realise belatedly that statvfs(3) can give some information on this.

statvfs fills in a struct statvfs, which, according to statvfs(3) on FreeBSD, includes members

f_frsize The size in bytes of the minimum unit of allocation on
this file system. (This corresponds to the f_bsize
member of struct statfs.)

f_bsize The preferred length of I/O requests for files on this
file system. (Corresponds to the f_iosize member of
struct statfs.)

According to POSIX Issue 7 (2018) [1], these are

unsigned long f_bsize File system block size.
unsigned long f_frsize Fundamental file system block size.

As usual, POSIX is being a _little_ bit non-committal here!

Member f_frsize is 512 when I call this on FreeBSD (f_bsize is a lot bigger).

Thus, it _appears_ that:

* neither FreeBSD manpages nor POSIX specify what the block size is for quotactl(2) responses, as far as I can see (because POSIX doesn't talk about quotas), and
* neither of them explicitly say what units are used for struct dqblk's dqb_curblocks member and the like, and neither of them points towards statvfs,

...but the wording of statvfs(3) in both cases is consistent with f_frsize being those units.

That's not really satisfactory, but it's close enough to Documentation, for me, for the moment. Onward and upward...

Incidentally, on macOS, sys/quota.h defines the (non-POSIX) struct dqblk, that quotactl fills in, to have no field dqb_curblocks, but instead dqb_curbytes, which seems a lot more sensible.

Best wishes,

Norman


[1] Issue 7 is at <https://pubs.opengroup.org/onlinepubs/9699919799/toc.htm>; Issue 8 doesn't seem to differ in any respects relevant to this question.
Reply all
Reply to author
Forward
0 new messages