summaryrefslogtreecommitdiff
path: root/doc/quotadoc.sgml
blob: 45663997b7a886586d9461fbc49da65af05872f2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
<!doctype linuxdoc system>

<!--
	Documentation of quota utilities
-->

<article>

<title>Disk quota system for Linux
<author>Jan Kara <tt/jack@suse.cz/

<date>2000, 2001
<abstract>
This document contains documentation of Linux quota disk formats and appropriate quota utilities
(currenly in version 3.01).
</abstract>

<!-- Table of contents -->
<toc>
<!-- Document begins -->

<sect>Introduction
<label id="intro">
<p>
Quota subsystem allows system administrator to set limits on used space and number of
used inodes (<it/inode/ is a filesystem structure which is associated which each file or
directory) for users and/or groups. For both used space and number of used inodes there are actually
two limits. The first one is called <it/softlimit/ and the second one <it/hardlimit/.
User can never exceed hardlimit for any resource. When user exceeds softlimit (s)he's warned
that (s)he uses more space than (s)he should but space/inode is allocated (of course only
if user also doesn't exceed hardlimit). If a user is exceeding softlimit for specified period
of time (this period is called <it/grace time/) (s)he's not allowed to allocate more
resources (so he must free some space/inodes to get under softlimit).
<p>
Quota limits are set independently for each filesystem. Currently following filesystems
are supporting quota: Ext2, Ext3, ReiserFS, XFS.

<label id="config">
<sect>Configuration
<label id="new_quota">
<sect1>Setting up new quota
<p>
In order for quota subsystem to work you have to have quota compiled in kernel and
configured appropriately. That means that filesystem on which you want to use quotas
must be mounted with option <tt/usrquota/ (if you want to use limits for users),
<tt/grpquota/ (if you want to use limits for groups) or <tt/quota/ (this is
equivalent to <tt/usrquota/ option). These mount options are used by quota utils
to recognize filesystems they should work with. For XFS you have to specify
additional mount options ??which??. On each such filesystem you have to have
files with quota data. The name of these quota files depends on <ref id="quota_formats"
name="quota format"> (and you can even specify the filenames by yourself by
adding <tt/=filename/ to <tt/usrquota/ or <tt/grpquota/ options -- eg.
<tt/usrquota=file.quota/. But note that by this you prevent quota utilities to
do some useful autodetection). The quotafiles can be created by
<tt/quotacheck(8)/ utility. When you have successfully created quota files you
can turn quotas on (ie. system will start tracking how much each user uses and
will check set limits). This is done by <tt/quotaon(8)/ program.
<label id="converting_quota">
<sect1>Converting quota formats
<p>
When you already have working quota subsystem but you want to use newer quota format
you have to convert quota files. This can be done by <tt/convertquota(8)/ utility.
<label id="setting_limits">
<sect1>Setting user limits
<p>
You can edit user (group) limits by <tt/edquota(8)/ or <tt/setquota(8)/ programs.
By these programs you can also set grace times.

<label id="quota_formats">
<sect>Quota formats
<label id="quota_format_old">
<sect1>Original quota format
<p>
Original quota format is used by kernels up to 2.4 Linux kernels (including). Note
that vendors such as <it/RedHat/ or <it/SuSE/ have already included quota format patches into
their kernels and so they use <ref id="quota_format_v0" name="newer quota format">.
This quota format is in manpages and quota utils called <tt/vfsold/.
<p>
Data for this format are usually stored in files <tt/quota.user/ (for user quotas) and
<tt/quota.group/ (for group quotas). Both files have same structure. They are just
the arrays of following structures:
<code>
struct v1_disk_dqblk {
        u_int32_t dqb_bhardlimit;       /* Absolute limit on disk blks alloc */
        u_int32_t dqb_bsoftlimit;       /* Preferred limit on disk blks */
        u_int32_t dqb_curblocks;        /* Current block count */
        u_int32_t dqb_ihardlimit;       /* Maximum # allocated inodes */
        u_int32_t dqb_isoftlimit;       /* Preferred limit on inodes */
        u_int32_t dqb_curinodes;        /* Current # allocated inodes */
        time_t dqb_btime;       /* Time limit for excessive disk use */
        time_t dqb_itime;       /* Time limit for excessive files */
};
</code>
Structure for user (group) with id <tt/N/ is stored as <tt/N/-th structure in file.
In fields <tt/dqb_btime/ and <tt/dqb_itime/ of first structure (id = 0) are stored
grace times for this filesystem.
<label id="quota_format_v0">
<sect1>V0 quota format
<p>
This quota format is currently used in -ac series of kernels and also in new kernels distributed
by RedHat (>= 7.1) and SuSE (>= 7.2). There are also patches for standard 2.4 kernels
which implement this format. You can download them at <tt>ftp://atrey.karlin.mff.cuni.cz/pub/local/jack/quota/v2.4/</tt>.
This format is called <tt/vfsv0/ in manpages and utilities and quotafiles are usually
called <tt/aquota.user/ and <tt/aquota.group/.
<p>
This quota format has following advantages against old quota format:
<itemize>
<item>It allows 32-bit UIDs/GIDs.
<item>Used space is stored in bytes and so ReiserFS can do precise accounting.
<item>UID/GID 0 is no longer special (grace times are stored independently).
<item>Header which allows quota format and version detection was added.
</itemize>
<p>
Format of quotafile is following:
In the beginning of quota file there is a generic header which is intended to be present
in every quota file in future. A header has following structure:
<code>
struct disk_dqheader {
  __u32 dqh_magic;        /* Magic number identifying file */
  __u32 dqh_version;      /* File version */
};
</code>
From this header any utility or kernel code should be able to recognize whether they
understand a format of file and eventually refuse to continue.
<p>
Following header might be specific for quotatype and version (currently this header is same
for user and group quota and there is only one version of quotafile format).
<code>
struct disk_dqinfo {
  __u32 dqi_bgrace;     /* Time before block soft limit becomes hard limit - in seconds */
  __u32 dqi_igrace;     /* Time before inode soft limit becomes hard limit - in seconds */
  __u32 dqi_flags;      /* Flags for quotafile (DQF_*) (currently there are no ondisk flags) */
  __u32 dqi_blocks;     /* Number of blocks in file */
  __u32 dqi_free_blk;   /* Number of first free block in the list */
  __u32 dqi_free_entry; /* Number of block with at least one free entry */
};
</code>
There are two link lists of blocks in quotafile. First one direction link list is used
to link all blocks that are completely unused (<tt/dqi_free_blk/ points to the first
element of this list). Second double direction link list is used to link all <it/data
blocks/ which have at least one entry free and which also have at least one used entry.
The beginning of the list is pointed by <tt/dqi_free_entry/.
<p>
The rest of file (starting at 1KB) is divided into 1KB blocks. In these blocks is stored
a radix tree with quotas. The key for the radix tree is UID or GID (I'll use just ID)
depending on quota file type.  One node of the tree is 1KB block so there are upto
256 references to the sons. At each level we choose reference corresponding to one
byte of ID so having four-level radix tree we can support 32-bit IDs.
Reference from last level points to <it/data block/ which contains quota structure for
proper ID.
<p>
<it/Data block/ has following structure: In the beginning there is header with following
structure:
<code>
struct disk_dqdbheader {
  __u32 dqdh_next_free;   /* Number of next block with free entry */
  __u32 dqdh_prev_free;   /* Number of previous block with free entry */
  __u16 dqdh_entries;     /* Number of valid entries in block */
  __u16 dqdh_pad1;
  __u32 dqdh_pad2;
};
</code>
Entries <tt/dqdh_next_free/ and <tt/dqdh_prev_free/ are used only if block has at least one
free and one used entry. If it has no free entry these references are set to 0. When block
is completely free only <tt/dqdh_next_free/ is used for link list of free blocks.
<p>
The rest of block is divided into 21 quota entries. Unused entry is entry that contains
only zeros. Note that used entries might be freely scattered in the block. Quota entry
has following structure:
<code>
struct disk_dqblk {
        __u32 dqb_id;           /* id this quota applies to */
        __u32 dqb_ihardlimit;   /* absolute limit on allocated inodes */
        __u32 dqb_isoftlimit;   /* preferred inode limit */
        __u32 dqb_curinodes;    /* current # allocated inodes */
        __u32 dqb_bhardlimit;   /* absolute limit on disk space (in kb) */
        __u32 dqb_bsoftlimit;   /* preferred limit on disk space (in kb) */
        __u64 dqb_curspace;     /* current space occupied (in bytes) */
        __u64 dqb_btime;        /* time limit for excessive disk use */
        __u64 dqb_itime;        /* time limit for excessive inode use */
};
</code>
<label id="utils">
<sect>Utilities
<p>
As of version 3.01 quota utilities support original, vfsv0 and xfs quota format.
You can download latest version of utils from <tt>http://www.sf.net/projects/linuxquota/</tt>.
<p>
Utils try to do autodetection of currently used quota format (ie. they detect which
format is compiled into kernel and they try to use this one). Anytime you can
force utils to use different format by specifying <tt>-F &lt;format&gt;</tt>. More information
about quota utils can be found in appropriate manpages.
</article>