Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
422 | giacomo | 1 | /* |
2 | * Copyright (c) 1982, 1986 Regents of the University of California. |
||
3 | * All rights reserved. |
||
4 | * |
||
5 | * This code is derived from software contributed to Berkeley by |
||
6 | * Robert Elz at The University of Melbourne. |
||
7 | * |
||
8 | * Redistribution and use in source and binary forms, with or without |
||
9 | * modification, are permitted provided that the following conditions |
||
10 | * are met: |
||
11 | * 1. Redistributions of source code must retain the above copyright |
||
12 | * notice, this list of conditions and the following disclaimer. |
||
13 | * 2. Redistributions in binary form must reproduce the above copyright |
||
14 | * notice, this list of conditions and the following disclaimer in the |
||
15 | * documentation and/or other materials provided with the distribution. |
||
16 | * 3. Neither the name of the University nor the names of its contributors |
||
17 | * may be used to endorse or promote products derived from this software |
||
18 | * without specific prior written permission. |
||
19 | * |
||
20 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
||
21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
||
22 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
||
23 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
||
24 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
||
25 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
||
26 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
||
27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
||
28 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
||
29 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
||
30 | * SUCH DAMAGE. |
||
31 | * |
||
32 | * Version: $Id: quota.h,v 1.1 2004-01-28 15:26:24 giacomo Exp $ |
||
33 | */ |
||
34 | |||
35 | #ifndef _LINUX_QUOTA_ |
||
36 | #define _LINUX_QUOTA_ |
||
37 | |||
38 | #include <linux/errno.h> |
||
39 | #include <linux/types.h> |
||
40 | #include <linux/spinlock.h> |
||
41 | |||
42 | #define __DQUOT_VERSION__ "dquot_6.5.1" |
||
43 | #define __DQUOT_NUM_VERSION__ 6*10000+5*100+1 |
||
44 | |||
45 | typedef __kernel_uid32_t qid_t; /* Type in which we store ids in memory */ |
||
46 | typedef __u64 qsize_t; /* Type in which we store sizes */ |
||
47 | |||
48 | extern spinlock_t dq_list_lock; |
||
49 | extern spinlock_t dq_data_lock; |
||
50 | |||
51 | /* Size of blocks in which are counted size limits */ |
||
52 | #define QUOTABLOCK_BITS 10 |
||
53 | #define QUOTABLOCK_SIZE (1 << QUOTABLOCK_BITS) |
||
54 | |||
55 | /* Conversion routines from and to quota blocks */ |
||
56 | #define qb2kb(x) ((x) << (QUOTABLOCK_BITS-10)) |
||
57 | #define kb2qb(x) ((x) >> (QUOTABLOCK_BITS-10)) |
||
58 | #define toqb(x) (((x) + QUOTABLOCK_SIZE - 1) >> QUOTABLOCK_BITS) |
||
59 | |||
60 | #define MAXQUOTAS 2 |
||
61 | #define USRQUOTA 0 /* element used for user quotas */ |
||
62 | #define GRPQUOTA 1 /* element used for group quotas */ |
||
63 | |||
64 | /* |
||
65 | * Definitions for the default names of the quotas files. |
||
66 | */ |
||
67 | #define INITQFNAMES { \ |
||
68 | "user", /* USRQUOTA */ \ |
||
69 | "group", /* GRPQUOTA */ \ |
||
70 | "undefined", \ |
||
71 | }; |
||
72 | |||
73 | /* |
||
74 | * Command definitions for the 'quotactl' system call. |
||
75 | * The commands are broken into a main command defined below |
||
76 | * and a subcommand that is used to convey the type of |
||
77 | * quota that is being manipulated (see above). |
||
78 | */ |
||
79 | #define SUBCMDMASK 0x00ff |
||
80 | #define SUBCMDSHIFT 8 |
||
81 | #define QCMD(cmd, type) (((cmd) << SUBCMDSHIFT) | ((type) & SUBCMDMASK)) |
||
82 | |||
83 | #define Q_SYNC 0x800001 /* sync disk copy of a filesystems quotas */ |
||
84 | #define Q_QUOTAON 0x800002 /* turn quotas on */ |
||
85 | #define Q_QUOTAOFF 0x800003 /* turn quotas off */ |
||
86 | #define Q_GETFMT 0x800004 /* get quota format used on given filesystem */ |
||
87 | #define Q_GETINFO 0x800005 /* get information about quota files */ |
||
88 | #define Q_SETINFO 0x800006 /* set information about quota files */ |
||
89 | #define Q_GETQUOTA 0x800007 /* get user quota structure */ |
||
90 | #define Q_SETQUOTA 0x800008 /* set user quota structure */ |
||
91 | |||
92 | /* |
||
93 | * Quota structure used for communication with userspace via quotactl |
||
94 | * Following flags are used to specify which fields are valid |
||
95 | */ |
||
96 | #define QIF_BLIMITS 1 |
||
97 | #define QIF_SPACE 2 |
||
98 | #define QIF_ILIMITS 4 |
||
99 | #define QIF_INODES 8 |
||
100 | #define QIF_BTIME 16 |
||
101 | #define QIF_ITIME 32 |
||
102 | #define QIF_LIMITS (QIF_BLIMITS | QIF_ILIMITS) |
||
103 | #define QIF_USAGE (QIF_SPACE | QIF_INODES) |
||
104 | #define QIF_TIMES (QIF_BTIME | QIF_ITIME) |
||
105 | #define QIF_ALL (QIF_LIMITS | QIF_USAGE | QIF_TIMES) |
||
106 | |||
107 | struct if_dqblk { |
||
108 | __u64 dqb_bhardlimit; |
||
109 | __u64 dqb_bsoftlimit; |
||
110 | __u64 dqb_curspace; |
||
111 | __u64 dqb_ihardlimit; |
||
112 | __u64 dqb_isoftlimit; |
||
113 | __u64 dqb_curinodes; |
||
114 | __u64 dqb_btime; |
||
115 | __u64 dqb_itime; |
||
116 | __u32 dqb_valid; |
||
117 | }; |
||
118 | |||
119 | /* |
||
120 | * Structure used for setting quota information about file via quotactl |
||
121 | * Following flags are used to specify which fields are valid |
||
122 | */ |
||
123 | #define IIF_BGRACE 1 |
||
124 | #define IIF_IGRACE 2 |
||
125 | #define IIF_FLAGS 4 |
||
126 | #define IIF_ALL (IIF_BGRACE | IIF_IGRACE | IIF_FLAGS) |
||
127 | |||
128 | struct if_dqinfo { |
||
129 | __u64 dqi_bgrace; |
||
130 | __u64 dqi_igrace; |
||
131 | __u32 dqi_flags; |
||
132 | __u32 dqi_valid; |
||
133 | }; |
||
134 | |||
135 | #ifdef __KERNEL__ |
||
136 | |||
137 | #include <linux/dqblk_xfs.h> |
||
138 | #include <linux/dqblk_v1.h> |
||
139 | #include <linux/dqblk_v2.h> |
||
140 | |||
141 | /* |
||
142 | * Data for one user/group kept in memory |
||
143 | */ |
||
144 | struct mem_dqblk { |
||
145 | __u32 dqb_bhardlimit; /* absolute limit on disk blks alloc */ |
||
146 | __u32 dqb_bsoftlimit; /* preferred limit on disk blks */ |
||
147 | qsize_t dqb_curspace; /* current used space */ |
||
148 | __u32 dqb_ihardlimit; /* absolute limit on allocated inodes */ |
||
149 | __u32 dqb_isoftlimit; /* preferred inode limit */ |
||
150 | __u32 dqb_curinodes; /* current # allocated inodes */ |
||
151 | time_t dqb_btime; /* time limit for excessive disk use */ |
||
152 | time_t dqb_itime; /* time limit for excessive inode use */ |
||
153 | }; |
||
154 | |||
155 | /* |
||
156 | * Data for one quotafile kept in memory |
||
157 | */ |
||
158 | struct quota_format_type; |
||
159 | |||
160 | struct mem_dqinfo { |
||
161 | struct quota_format_type *dqi_format; |
||
162 | unsigned long dqi_flags; |
||
163 | unsigned int dqi_bgrace; |
||
164 | unsigned int dqi_igrace; |
||
165 | union { |
||
166 | struct v1_mem_dqinfo v1_i; |
||
167 | struct v2_mem_dqinfo v2_i; |
||
168 | } u; |
||
169 | }; |
||
170 | |||
171 | #define DQF_MASK 0xffff /* Mask for format specific flags */ |
||
172 | #define DQF_INFO_DIRTY_B 16 |
||
173 | #define DQF_ANY_DQUOT_DIRTY_B 17 |
||
174 | #define DQF_INFO_DIRTY (1 << DQF_INFO_DIRTY_B) /* Is info dirty? */ |
||
175 | #define DQF_ANY_DQUOT_DIRTY (1 << DQF_ANY_DQUOT_DIRTY_B) /* Is any dquot dirty? */ |
||
176 | |||
177 | extern inline void mark_info_dirty(struct mem_dqinfo *info) |
||
178 | { |
||
179 | set_bit(DQF_INFO_DIRTY_B, &info->dqi_flags); |
||
180 | } |
||
181 | |||
182 | #define info_dirty(info) test_bit(DQF_INFO_DIRTY_B, &(info)->dqi_flags) |
||
183 | #define info_any_dquot_dirty(info) test_bit(DQF_ANY_DQUOT_DIRTY_B, &(info)->dqi_flags) |
||
184 | #define info_any_dirty(info) (info_dirty(info) || info_any_dquot_dirty(info)) |
||
185 | |||
186 | #define sb_dqopt(sb) (&(sb)->s_dquot) |
||
187 | |||
188 | struct dqstats { |
||
189 | int lookups; |
||
190 | int drops; |
||
191 | int reads; |
||
192 | int writes; |
||
193 | int cache_hits; |
||
194 | int allocated_dquots; |
||
195 | int free_dquots; |
||
196 | int syncs; |
||
197 | }; |
||
198 | |||
199 | extern struct dqstats dqstats; |
||
200 | |||
201 | #define NR_DQHASH 43 /* Just an arbitrary number */ |
||
202 | |||
203 | #define DQ_MOD_B 0 |
||
204 | #define DQ_BLKS_B 1 |
||
205 | #define DQ_INODES_B 2 |
||
206 | #define DQ_FAKE_B 3 |
||
207 | |||
208 | #define DQ_MOD (1 << DQ_MOD_B) /* dquot modified since read */ |
||
209 | #define DQ_BLKS (1 << DQ_BLKS_B) /* uid/gid has been warned about blk limit */ |
||
210 | #define DQ_INODES (1 << DQ_INODES_B) /* uid/gid has been warned about inode limit */ |
||
211 | #define DQ_FAKE (1 << DQ_FAKE_B) /* no limits only usage */ |
||
212 | |||
213 | struct dquot { |
||
214 | struct list_head dq_hash; /* Hash list in memory */ |
||
215 | struct list_head dq_inuse; /* List of all quotas */ |
||
216 | struct list_head dq_free; /* Free list element */ |
||
217 | struct semaphore dq_lock; /* dquot IO lock */ |
||
218 | atomic_t dq_count; /* Use count */ |
||
219 | |||
220 | /* fields after this point are cleared when invalidating */ |
||
221 | struct super_block *dq_sb; /* superblock this applies to */ |
||
222 | unsigned int dq_id; /* ID this applies to (uid, gid) */ |
||
223 | loff_t dq_off; /* Offset of dquot on disk */ |
||
224 | unsigned long dq_flags; /* See DQ_* */ |
||
225 | short dq_type; /* Type of quota */ |
||
226 | struct mem_dqblk dq_dqb; /* Diskquota usage */ |
||
227 | }; |
||
228 | |||
229 | #define NODQUOT (struct dquot *)NULL |
||
230 | |||
231 | #define QUOTA_OK 0 |
||
232 | #define NO_QUOTA 1 |
||
233 | |||
234 | /* Operations which must be implemented by each quota format */ |
||
235 | struct quota_format_ops { |
||
236 | int (*check_quota_file)(struct super_block *sb, int type); /* Detect whether file is in our format */ |
||
237 | int (*read_file_info)(struct super_block *sb, int type); /* Read main info about file - called on quotaon() */ |
||
238 | int (*write_file_info)(struct super_block *sb, int type); /* Write main info about file */ |
||
239 | int (*free_file_info)(struct super_block *sb, int type); /* Called on quotaoff() */ |
||
240 | int (*read_dqblk)(struct dquot *dquot); /* Read structure for one user */ |
||
241 | int (*commit_dqblk)(struct dquot *dquot); /* Write (or delete) structure for one user */ |
||
242 | }; |
||
243 | |||
244 | /* Operations working with dquots */ |
||
245 | struct dquot_operations { |
||
246 | void (*initialize) (struct inode *, int); |
||
247 | void (*drop) (struct inode *); |
||
248 | int (*alloc_space) (struct inode *, qsize_t, int); |
||
249 | int (*alloc_inode) (const struct inode *, unsigned long); |
||
250 | void (*free_space) (struct inode *, qsize_t); |
||
251 | void (*free_inode) (const struct inode *, unsigned long); |
||
252 | int (*transfer) (struct inode *, struct iattr *); |
||
253 | int (*sync_dquot) (struct dquot *); |
||
254 | }; |
||
255 | |||
256 | /* Operations handling requests from userspace */ |
||
257 | struct quotactl_ops { |
||
258 | int (*quota_on)(struct super_block *, int, int, char *); |
||
259 | int (*quota_off)(struct super_block *, int); |
||
260 | int (*quota_sync)(struct super_block *, int); |
||
261 | int (*get_info)(struct super_block *, int, struct if_dqinfo *); |
||
262 | int (*set_info)(struct super_block *, int, struct if_dqinfo *); |
||
263 | int (*get_dqblk)(struct super_block *, int, qid_t, struct if_dqblk *); |
||
264 | int (*set_dqblk)(struct super_block *, int, qid_t, struct if_dqblk *); |
||
265 | int (*get_xstate)(struct super_block *, struct fs_quota_stat *); |
||
266 | int (*set_xstate)(struct super_block *, unsigned int, int); |
||
267 | int (*get_xquota)(struct super_block *, int, qid_t, struct fs_disk_quota *); |
||
268 | int (*set_xquota)(struct super_block *, int, qid_t, struct fs_disk_quota *); |
||
269 | }; |
||
270 | |||
271 | struct quota_format_type { |
||
272 | int qf_fmt_id; /* Quota format id */ |
||
273 | struct quota_format_ops *qf_ops; /* Operations of format */ |
||
274 | struct module *qf_owner; /* Module implementing quota format */ |
||
275 | struct quota_format_type *qf_next; |
||
276 | }; |
||
277 | |||
278 | #define DQUOT_USR_ENABLED 0x01 /* User diskquotas enabled */ |
||
279 | #define DQUOT_GRP_ENABLED 0x02 /* Group diskquotas enabled */ |
||
280 | |||
281 | struct quota_info { |
||
282 | unsigned int flags; /* Flags for diskquotas on this device */ |
||
283 | struct semaphore dqio_sem; /* lock device while I/O in progress */ |
||
284 | struct semaphore dqonoff_sem; /* Serialize quotaon & quotaoff */ |
||
285 | struct rw_semaphore dqptr_sem; /* serialize ops using quota_info struct, pointers from inode to dquots */ |
||
286 | struct file *files[MAXQUOTAS]; /* fp's to quotafiles */ |
||
287 | struct mem_dqinfo info[MAXQUOTAS]; /* Information for each quota type */ |
||
288 | struct quota_format_ops *ops[MAXQUOTAS]; /* Operations for each type */ |
||
289 | }; |
||
290 | |||
291 | /* Inline would be better but we need to dereference super_block which is not defined yet */ |
||
292 | #define mark_dquot_dirty(dquot) do {\ |
||
293 | set_bit(DQF_ANY_DQUOT_DIRTY_B, &(sb_dqopt((dquot)->dq_sb)->info[(dquot)->dq_type].dqi_flags));\ |
||
294 | set_bit(DQ_MOD_B, &(dquot)->dq_flags);\ |
||
295 | } while (0) |
||
296 | |||
297 | #define dquot_dirty(dquot) test_bit(DQ_MOD_B, &(dquot)->dq_flags) |
||
298 | |||
299 | #define sb_has_quota_enabled(sb, type) ((type)==USRQUOTA ? \ |
||
300 | (sb_dqopt(sb)->flags & DQUOT_USR_ENABLED) : (sb_dqopt(sb)->flags & DQUOT_GRP_ENABLED)) |
||
301 | |||
302 | #define sb_any_quota_enabled(sb) (sb_has_quota_enabled(sb, USRQUOTA) | \ |
||
303 | sb_has_quota_enabled(sb, GRPQUOTA)) |
||
304 | |||
305 | int register_quota_format(struct quota_format_type *fmt); |
||
306 | void unregister_quota_format(struct quota_format_type *fmt); |
||
307 | void init_dquot_operations(struct dquot_operations *fsdqops); |
||
308 | |||
309 | struct quota_module_name { |
||
310 | int qm_fmt_id; |
||
311 | char *qm_mod_name; |
||
312 | }; |
||
313 | |||
314 | #define INIT_QUOTA_MODULE_NAMES {\ |
||
315 | {QFMT_VFS_OLD, "quota_v1"},\ |
||
316 | {QFMT_VFS_V0, "quota_v2"},\ |
||
317 | {0, NULL}} |
||
318 | |||
319 | #else |
||
320 | |||
321 | # /* nodep */ include <sys/cdefs.h> |
||
322 | |||
323 | __BEGIN_DECLS |
||
324 | long quotactl __P ((unsigned int, const char *, int, caddr_t)); |
||
325 | __END_DECLS |
||
326 | |||
327 | #endif /* __KERNEL__ */ |
||
328 | #endif /* _QUOTA_ */ |