HFS+ Disk Quotas

From Secure Computing Wiki
Revision as of 14:11, 2 February 2009 by (talk)
Jump to navigation Jump to search


HFS+ on Mac OS X supports volume=level quotas based on user and group IDs. The corresponding quota file names are .quota.user and .quota.group. These files reside in the file system's root directory. Each file contains a header, followed by a hash table of structures specifying various quota limits and usage values for user or group IDs.

Enabling Disk Quotas

To enable disk quotas on Mac OS X systems, we need to create .quota.ops.user (or .quota.ops.group) within the file system's root directory. For my example here, I'm using my MacBook Pro with a single partition.

  1. First, we need to escalate our privileges to root.
    ecrist@Swordfish:~-> sudo csh
  2. Next, we need to create an empty options file:
    root@Swordfish:~-> touch /.quota.ops.user
  3. After the options file is created, we should be able to run repquoata -a to get a list of current disk usage, by user name. Note that this command, when run initially, may take a few moments.
    root@Swordfish:~-> repquota -a
                            1K Block limits               File limits
    User                used        soft        hard  grace    used  soft  hard  grace
    _spotlight--           0           0           0              2     0     0       
    _lp       --           0           0           0              3     0     0       
    _teamsserver--         128           0           0             10     0     0       
    _xgridagent--           0           0           0              2     0     0       
    _mdnsresponder--          36           0           0              4     0     0       
    _unknown  --       14560           0           0              2     0     0       
    test      --       26812           0           0            664     0     0       
    _amavisd  --           8           0           0              6     0     0       
    _installer--      326832           0           0             67     0     0       
    _uucp     --        1520           0           0             10     0     0       
    504       --      114476           0           0            289     0     0       
    _xgridcontroller--           0           0           0              2     0     0       
    6185      --           0           0           0              4     0     0       
    daemon    --       27000           0           0            301     0     0       
    ecrist    --    66636284           0           0         156581     0     0       
    _postfix  --           0           0           0             13     0     0       
    _update_sharing--       11372           0           0             10     0     0       
    nobody    --        9080           0           0              9     0     0       
    _securityagent--          32           0           0              5     0     0       
    _atsserver--       20680           0           0              5     0     0
    My user name, ecrist, you'll notice, has a current usage of around 6GB (listed in 1K blocks).
  4. Turn quotas on with the quotaon command:
    root@Swordfish:~-> quotaon /
    The above command requires a filesystem device or mount path after quotaon. In my example, I've only got one mounted system. If you've got a USB device, or a second hard disk, use the mount point in place of / above.

At this point, disk quotas have been enabled, but there's currently no policy in place to enforce.

Setting Quota Limits

Once disk quotas have been enabled, we can set limits for our users. For this example, I've created a user, test, to test quotas.

We can edit user quotas with the edquota command. edquota has many options, see the man page for a complete description. For our uses, we're going to use the -u (user) option, followed by a user name.

root@Swordfish:~-> edquota -u test

You will get a vi session with a temp file opened for editing. In our example, after running the above command, we have the following on our screen:

Quotas for user test:
/: 1K blocks in use: 26940, limits (soft = 0, hard = 0)
|       inodes in use: 664, limits (soft = 0, hard = 0)

While this isn't a vi how-to, I'll try to walk you through a bit so you can get your quotas defined. What we want to change in this file is the number (currently 0 for both) for hard and soft limits. Once vi has opened, press the i key to enable insert mode. You should now be able to use your arrow keys and change the values as you see fit. Once you're done editing the file, press ESCAPE and then :wq<enter> to quit and save your changes.

You can set both hard and soft limits. Hard limits are limits which are not allowed to be bypassed. The user, once reaching the hard limit, will be informed that there is no longer any space available on the disk.

Hfs quota exceed.png

Soft limits are able to be bypassed, temporarily. Users are permitted to exceed their soft limits for a grace period that may be specified per filesystem. Once the grace period has expired, the soft limit is enforced as a hard limit. Use the command edquota -t to change the grace period.


For reference, inodes are files on the file system. Each and every file gets a single inode. Hard and soft links each get their own inode, even though they point to another file. They are files, themselves.

Grace Period

As mentioned above, there is a configurable grace period for soft quota limits. Section 8 of the manual for edquota mentions the default limit is set in /usr/include/sys/quota.h. That file doesn't exist on most default-installed Macs, so I'll tell you it's 1 week. The noted lines from this file are as follows:

 * Definitions for disk quotas imposed on the average user
 * (big brother finally hits UNIX).
 * The following constants define the amount of time given a user before the
 * soft limits are treated as hard limits (usually resulting in an allocation
 * failure). The timer is started when the user crosses their soft limit, it
 * is reset when they go below their soft limit.
#define|MAX_IQ_TIME|    (7*24*60*60)|   /* seconds in 1 week */
#define|MAX_DQ_TIME|    (7*24*60*60)|   /* seconds in 1 week */

You can change this default with the edquota command. Use the -t option to edit the grace period. When invoked, this command will give you, similar to above, a vi session will open, with the file to be configured. (See above for basic instruction on how to use vi.) From the edquota man page:

The grace period

may be specified in days, hours, minutes, or seconds. Setting a grace period to zero indicates that the default grace period should be imposed. Setting a grace period to one second indicates that no grace period should be granted.

Only changes to the numbers following block grace period or file grace period will have any affect. To change grace period for groups, make certain to specify -g on the command line with -t.


Setting a file number limit is easily bypassed with disk images. A disk image, itself, uses only one inode, regardless of how many files it contains, or how large it grows. The file number limit can be useful for daemon users and such which may pose a risk to overflowing your file systems with files such as logs or core dumps.

More Information

More information on HFS+ can be found at http://en.wikipedia.org/wiki/Hierarchical_File_System

External Links