1 /*
2 * Implementation of the diskquota system for the LINUX operating
3 * system. QUOTA is implemented using the BSD system call interface as
4 * the means of communication with the user level. Currently only the
5 * ext2 filesystem has support for disk quotas. Other filesystems may
6 * be added in the future. This file contains the generic routines
7 * called by the different filesystems on allocation of an inode or
8 * block. These routines take care of the administration needed to
9 * have a consistent diskquota tracking system. The ideas of both
10 * user and group quotas are based on the Melbourne quota system as
11 * used on BSD derived systems. The internal implementation is
12 * based on one of the several variants of the LINUX inode-subsystem
13 * with added complexity of the diskquota system.
14 *
15 * Version: $Id: dquot.c,v 6.3 1996/11/17 18:35:34 mvw Exp mvw $
16 *
17 * Author: Marco van Wieringen <mvw@planets.elm.net>
18 *
19 * Fixes: Dmitry Gorodchanin <pgmdsg@ibi.com>, 11 Feb 96
20 *
21 * Revised list management to avoid races
22 * -- Bill Hawes, <whawes@star.net>, 9/98
23 *
24 * Fixed races in dquot_transfer(), dqget() and dquot_alloc_...().
25 * As the consequence the locking was moved from dquot_decr_...(),
26 * dquot_incr_...() to calling functions.
27 * invalidate_dquots() now writes modified dquots.
28 * Serialized quota_off() and quota_on() for mount point.
29 * Fixed a few bugs in grow_dquots().
30 * Fixed deadlock in write_dquot() - we no longer account quotas on
31 * quota files
32 * remove_dquot_ref() moved to inode.c - it now traverses through inodes
33 * add_dquot_ref() restarts after blocking
34 * Added check for bogus uid and fixed check for group in quotactl.
35 * Jan Kara, <jack@suse.cz>, sponsored by SuSE CR, 10-11/99
36 *
37 * Used struct list_head instead of own list struct
38 * Invalidation of referenced dquots is no longer possible
39 * Improved free_dquots list management
40 * Quota and i_blocks are now updated in one place to avoid races
41 * Warnings are now delayed so we won't block in critical section
42 * Write updated not to require dquot lock
43 * Jan Kara, <jack@suse.cz>, 9/2000
44 *
45 * Added dynamic quota structure allocation
46 * Jan Kara <jack@suse.cz> 12/2000
47 *
48 * Rewritten quota interface. Implemented new quota format and
49 * formats registering.
50 * Jan Kara, <jack@suse.cz>, 2001,2002
51 *
52 * (C) Copyright 1994 - 1997 Marco van Wieringen
53 */
54
55 #include <linux/errno.h>
56 #include <linux/kernel.h>
57 #include <linux/fs.h>
58 #include <linux/sched.h>
59 #include <linux/types.h>
60 #include <linux/string.h>
61 #include <linux/fcntl.h>
62 #include <linux/stat.h>
63 #include <linux/tty.h>
64 #include <linux/file.h>
65 #include <linux/slab.h>
66 #include <linux/sysctl.h>
67 #include <linux/smp_lock.h>
68 #include <linux/init.h>
69 #include <linux/module.h>
70 #include <linux/proc_fs.h>
71
72 #include <asm/uaccess.h>
73
74 static char *quotatypes[] = INITQFNAMES;
75 static struct quota_format_type *quota_formats; /* List of registered formats */
76
register_quota_format(struct quota_format_type * fmt)77 int register_quota_format(struct quota_format_type *fmt)
78 {
79 lock_kernel();
80 fmt->qf_next = quota_formats;
81 quota_formats = fmt;
82 unlock_kernel();
83 return 0;
84 }
85
unregister_quota_format(struct quota_format_type * fmt)86 void unregister_quota_format(struct quota_format_type *fmt)
87 {
88 struct quota_format_type **actqf;
89
90 lock_kernel();
91 for (actqf = "a_formats; *actqf && *actqf != fmt; actqf = &(*actqf)->qf_next);
92 if (*actqf)
93 *actqf = (*actqf)->qf_next;
94 unlock_kernel();
95 }
96
find_quota_format(int id)97 static struct quota_format_type *find_quota_format(int id)
98 {
99 struct quota_format_type *actqf;
100
101 lock_kernel();
102 for (actqf = quota_formats; actqf && actqf->qf_fmt_id != id; actqf = actqf->qf_next);
103 if (actqf && !try_inc_mod_count(actqf->qf_owner))
104 actqf = NULL;
105 unlock_kernel();
106 return actqf;
107 }
108
put_quota_format(struct quota_format_type * fmt)109 static void put_quota_format(struct quota_format_type *fmt)
110 {
111 if (fmt->qf_owner)
112 __MOD_DEC_USE_COUNT(fmt->qf_owner);
113 }
114
115 /*
116 * Dquot List Management:
117 * The quota code uses three lists for dquot management: the inuse_list,
118 * free_dquots, and dquot_hash[] array. A single dquot structure may be
119 * on all three lists, depending on its current state.
120 *
121 * All dquots are placed to the end of inuse_list when first created, and this
122 * list is used for the sync and invalidate operations, which must look
123 * at every dquot.
124 *
125 * Unused dquots (dq_count == 0) are added to the free_dquots list when freed,
126 * and this list is searched whenever we need an available dquot. Dquots are
127 * removed from the list as soon as they are used again, and
128 * dqstats.free_dquots gives the number of dquots on the list. When
129 * dquot is invalidated it's completely released from memory.
130 *
131 * Dquots with a specific identity (device, type and id) are placed on
132 * one of the dquot_hash[] hash chains. The provides an efficient search
133 * mechanism to locate a specific dquot.
134 */
135
136 /*
137 * Note that any operation which operates on dquot data (ie. dq_dqb) mustn't
138 * block while it's updating/reading it. Otherwise races would occur.
139 *
140 * Locked dquots might not be referenced in inodes - operations like
141 * add_dquot_space() does dqduplicate() and would complain. Currently
142 * dquot it locked only once in its existence - when it's being read
143 * to memory on first dqget() and at that time it can't be referenced
144 * from inode. Write operations on dquots don't hold dquot lock as they
145 * copy data to internal buffers before writing anyway and copying as well
146 * as any data update should be atomic. Also nobody can change used
147 * entries in dquot structure as this is done only when quota is destroyed
148 * and invalidate_dquots() waits for dquot to have dq_count == 0.
149 */
150
151 static LIST_HEAD(inuse_list);
152 static LIST_HEAD(free_dquots);
153 static struct list_head dquot_hash[NR_DQHASH];
154
155 static void dqput(struct dquot *);
156 static struct dquot *dqduplicate(struct dquot *);
157
get_dquot_ref(struct dquot * dquot)158 static inline void get_dquot_ref(struct dquot *dquot)
159 {
160 dquot->dq_count++;
161 }
162
put_dquot_ref(struct dquot * dquot)163 static inline void put_dquot_ref(struct dquot *dquot)
164 {
165 dquot->dq_count--;
166 }
167
get_dquot_dup_ref(struct dquot * dquot)168 static inline void get_dquot_dup_ref(struct dquot *dquot)
169 {
170 dquot->dq_dup_ref++;
171 }
172
put_dquot_dup_ref(struct dquot * dquot)173 static inline void put_dquot_dup_ref(struct dquot *dquot)
174 {
175 dquot->dq_dup_ref--;
176 }
177
hashfn(struct super_block * sb,unsigned int id,int type)178 static inline int const hashfn(struct super_block *sb, unsigned int id, int type)
179 {
180 return((HASHDEV(sb->s_dev) ^ id) * (MAXQUOTAS - type)) % NR_DQHASH;
181 }
182
insert_dquot_hash(struct dquot * dquot)183 static inline void insert_dquot_hash(struct dquot *dquot)
184 {
185 struct list_head *head = dquot_hash + hashfn(dquot->dq_sb, dquot->dq_id, dquot->dq_type);
186 list_add(&dquot->dq_hash, head);
187 }
188
remove_dquot_hash(struct dquot * dquot)189 static inline void remove_dquot_hash(struct dquot *dquot)
190 {
191 list_del(&dquot->dq_hash);
192 INIT_LIST_HEAD(&dquot->dq_hash);
193 }
194
find_dquot(unsigned int hashent,struct super_block * sb,unsigned int id,int type)195 static inline struct dquot *find_dquot(unsigned int hashent, struct super_block *sb, unsigned int id, int type)
196 {
197 struct list_head *head;
198 struct dquot *dquot;
199
200 for (head = dquot_hash[hashent].next; head != dquot_hash+hashent; head = head->next) {
201 dquot = list_entry(head, struct dquot, dq_hash);
202 if (dquot->dq_sb == sb && dquot->dq_id == id && dquot->dq_type == type)
203 return dquot;
204 }
205 return NODQUOT;
206 }
207
208 /* Add a dquot to the head of the free list */
put_dquot_head(struct dquot * dquot)209 static inline void put_dquot_head(struct dquot *dquot)
210 {
211 list_add(&dquot->dq_free, &free_dquots);
212 dqstats.free_dquots++;
213 }
214
215 /* Add a dquot to the tail of the free list */
put_dquot_last(struct dquot * dquot)216 static inline void put_dquot_last(struct dquot *dquot)
217 {
218 list_add(&dquot->dq_free, free_dquots.prev);
219 dqstats.free_dquots++;
220 }
221
222 /* Move dquot to the head of free list (it must be already on it) */
move_dquot_head(struct dquot * dquot)223 static inline void move_dquot_head(struct dquot *dquot)
224 {
225 list_del(&dquot->dq_free);
226 list_add(&dquot->dq_free, &free_dquots);
227 }
228
remove_free_dquot(struct dquot * dquot)229 static inline void remove_free_dquot(struct dquot *dquot)
230 {
231 if (list_empty(&dquot->dq_free))
232 return;
233 list_del(&dquot->dq_free);
234 INIT_LIST_HEAD(&dquot->dq_free);
235 dqstats.free_dquots--;
236 }
237
put_inuse(struct dquot * dquot)238 static inline void put_inuse(struct dquot *dquot)
239 {
240 /* We add to the back of inuse list so we don't have to restart
241 * when traversing this list and we block */
242 list_add(&dquot->dq_inuse, inuse_list.prev);
243 dqstats.allocated_dquots++;
244 }
245
remove_inuse(struct dquot * dquot)246 static inline void remove_inuse(struct dquot *dquot)
247 {
248 dqstats.allocated_dquots--;
249 list_del(&dquot->dq_inuse);
250 }
251
__wait_on_dquot(struct dquot * dquot)252 static void __wait_on_dquot(struct dquot *dquot)
253 {
254 DECLARE_WAITQUEUE(wait, current);
255
256 add_wait_queue(&dquot->dq_wait_lock, &wait);
257 repeat:
258 set_current_state(TASK_UNINTERRUPTIBLE);
259 if (dquot->dq_flags & DQ_LOCKED) {
260 schedule();
261 goto repeat;
262 }
263 remove_wait_queue(&dquot->dq_wait_lock, &wait);
264 current->state = TASK_RUNNING;
265 }
266
wait_on_dquot(struct dquot * dquot)267 static inline void wait_on_dquot(struct dquot *dquot)
268 {
269 if (dquot->dq_flags & DQ_LOCKED)
270 __wait_on_dquot(dquot);
271 }
272
lock_dquot(struct dquot * dquot)273 static inline void lock_dquot(struct dquot *dquot)
274 {
275 wait_on_dquot(dquot);
276 dquot->dq_flags |= DQ_LOCKED;
277 }
278
unlock_dquot(struct dquot * dquot)279 static inline void unlock_dquot(struct dquot *dquot)
280 {
281 dquot->dq_flags &= ~DQ_LOCKED;
282 wake_up(&dquot->dq_wait_lock);
283 }
284
285 /* Wait for dquot to be unused */
__wait_dquot_unused(struct dquot * dquot)286 static void __wait_dquot_unused(struct dquot *dquot)
287 {
288 DECLARE_WAITQUEUE(wait, current);
289
290 add_wait_queue(&dquot->dq_wait_free, &wait);
291 repeat:
292 set_current_state(TASK_UNINTERRUPTIBLE);
293 if (dquot->dq_count) {
294 schedule();
295 goto repeat;
296 }
297 remove_wait_queue(&dquot->dq_wait_free, &wait);
298 current->state = TASK_RUNNING;
299 }
300
301 /* Wait for all duplicated dquot references to be dropped */
__wait_dup_drop(struct dquot * dquot)302 static void __wait_dup_drop(struct dquot *dquot)
303 {
304 DECLARE_WAITQUEUE(wait, current);
305
306 add_wait_queue(&dquot->dq_wait_free, &wait);
307 repeat:
308 set_current_state(TASK_UNINTERRUPTIBLE);
309 if (dquot->dq_dup_ref) {
310 schedule();
311 goto repeat;
312 }
313 remove_wait_queue(&dquot->dq_wait_free, &wait);
314 current->state = TASK_RUNNING;
315 }
316
read_dqblk(struct dquot * dquot)317 static int read_dqblk(struct dquot *dquot)
318 {
319 int ret;
320 struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
321
322 lock_dquot(dquot);
323 down(&dqopt->dqio_sem);
324 ret = dqopt->ops[dquot->dq_type]->read_dqblk(dquot);
325 up(&dqopt->dqio_sem);
326 unlock_dquot(dquot);
327 return ret;
328 }
329
commit_dqblk(struct dquot * dquot)330 static int commit_dqblk(struct dquot *dquot)
331 {
332 int ret;
333 struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
334
335 down(&dqopt->dqio_sem);
336 ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot);
337 up(&dqopt->dqio_sem);
338 return ret;
339 }
340
341 /* Invalidate all dquots on the list, wait for all users. Note that this function is called
342 * after quota is disabled so no new quota might be created. As we only insert to the end of
343 * inuse list, we don't have to restart searching... */
invalidate_dquots(struct super_block * sb,int type)344 static void invalidate_dquots(struct super_block *sb, int type)
345 {
346 struct dquot *dquot;
347 struct list_head *head;
348
349 restart:
350 list_for_each(head, &inuse_list) {
351 dquot = list_entry(head, struct dquot, dq_inuse);
352 if (dquot->dq_sb != sb)
353 continue;
354 if (dquot->dq_type != type)
355 continue;
356 dquot->dq_flags |= DQ_INVAL;
357 if (dquot->dq_count)
358 /*
359 * Wait for any users of quota. As we have already cleared the flags in
360 * superblock and cleared all pointers from inodes we are assured
361 * that there will be no new users of this quota.
362 */
363 __wait_dquot_unused(dquot);
364 /* Quota now have no users and it has been written on last dqput() */
365 remove_dquot_hash(dquot);
366 remove_free_dquot(dquot);
367 remove_inuse(dquot);
368 kmem_cache_free(dquot_cachep, dquot);
369 goto restart;
370 }
371 }
372
vfs_quota_sync(struct super_block * sb,int type)373 static int vfs_quota_sync(struct super_block *sb, int type)
374 {
375 struct list_head *head;
376 struct dquot *dquot;
377 struct quota_info *dqopt = sb_dqopt(sb);
378 int cnt;
379
380 restart:
381 list_for_each(head, &inuse_list) {
382 dquot = list_entry(head, struct dquot, dq_inuse);
383 if (sb && dquot->dq_sb != sb)
384 continue;
385 if (type != -1 && dquot->dq_type != type)
386 continue;
387 if (!dquot->dq_sb) /* Invalidated? */
388 continue;
389 if (!dquot_dirty(dquot) && !(dquot->dq_flags & DQ_LOCKED))
390 continue;
391 /* Get reference to quota so it won't be invalidated. get_dquot_ref()
392 * is enough since if dquot is locked/modified it can't be
393 * on the free list */
394 get_dquot_ref(dquot);
395 dqstats.lookups++;
396 if (dquot->dq_flags & DQ_LOCKED)
397 wait_on_dquot(dquot);
398 if (dquot_dirty(dquot))
399 sb->dq_op->write_dquot(dquot);
400 /* Move the inuse_list head pointer to just after the
401 * current dquot, so that we'll restart the list walk
402 * after this point on the next pass. */
403 list_move(&inuse_list, &dquot->dq_inuse);
404 dqput(dquot);
405 goto restart;
406 }
407 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
408 if ((cnt == type || type == -1) && sb_has_quota_enabled(sb, cnt))
409 dqopt->info[cnt].dqi_flags &= ~DQF_ANY_DQUOT_DIRTY;
410 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
411 if ((cnt == type || type == -1) && sb_has_quota_enabled(sb, cnt) && info_dirty(&dqopt->info[cnt]))
412 dqopt->ops[cnt]->write_file_info(sb, cnt);
413 dqstats.syncs++;
414
415 return 0;
416 }
417
get_super_to_sync(int type)418 static struct super_block *get_super_to_sync(int type)
419 {
420 struct list_head *head;
421 int cnt, dirty;
422
423 restart:
424 spin_lock(&sb_lock);
425 list_for_each(head, &super_blocks) {
426 struct super_block *sb = list_entry(head, struct super_block, s_list);
427
428 for (cnt = 0, dirty = 0; cnt < MAXQUOTAS; cnt++)
429 if ((type == cnt || type == -1) && sb_has_quota_enabled(sb, cnt)
430 && sb_dqopt(sb)->info[cnt].dqi_flags & DQF_ANY_DQUOT_DIRTY)
431 dirty = 1;
432 if (!dirty)
433 continue;
434 sb->s_count++;
435 spin_unlock(&sb_lock);
436 down_read(&sb->s_umount);
437 if (!sb->s_root) {
438 drop_super(sb);
439 goto restart;
440 }
441 return sb;
442 }
443 spin_unlock(&sb_lock);
444 return NULL;
445 }
446
sync_dquots_dev(kdev_t dev,int type)447 void sync_dquots_dev(kdev_t dev, int type)
448 {
449 struct super_block *sb;
450
451 if (dev) {
452 if ((sb = get_super(dev))) {
453 lock_kernel();
454 if (sb->s_qcop->quota_sync)
455 sb->s_qcop->quota_sync(sb, type);
456 unlock_kernel();
457 drop_super(sb);
458 }
459 }
460 else {
461 while ((sb = get_super_to_sync(type))) {
462 lock_kernel();
463 if (sb->s_qcop->quota_sync)
464 sb->s_qcop->quota_sync(sb, type);
465 unlock_kernel();
466 drop_super(sb);
467 }
468 }
469 }
470
sync_dquots_sb(struct super_block * sb,int type)471 void sync_dquots_sb(struct super_block *sb, int type)
472 {
473 lock_kernel();
474 if (sb->s_qcop->quota_sync)
475 sb->s_qcop->quota_sync(sb, type);
476 unlock_kernel();
477 }
478
479 /* Free unused dquots from cache */
prune_dqcache(int count)480 static void prune_dqcache(int count)
481 {
482 struct list_head *head;
483 struct dquot *dquot;
484
485 head = free_dquots.prev;
486 while (head != &free_dquots && count) {
487 dquot = list_entry(head, struct dquot, dq_free);
488 remove_dquot_hash(dquot);
489 remove_free_dquot(dquot);
490 remove_inuse(dquot);
491 kmem_cache_free(dquot_cachep, dquot);
492 count--;
493 head = free_dquots.prev;
494 }
495 }
496
497 /*
498 * This is called from kswapd when we think we need some
499 * more memory, but aren't really sure how much. So we
500 * carefully try to free a _bit_ of our dqcache, but not
501 * too much.
502 *
503 * Priority:
504 * 1 - very urgent: shrink everything
505 * ...
506 * 6 - base-level: try to shrink a bit.
507 */
508
shrink_dqcache_memory(int priority,unsigned int gfp_mask)509 int shrink_dqcache_memory(int priority, unsigned int gfp_mask)
510 {
511 int count = 0;
512
513 lock_kernel();
514 count = dqstats.free_dquots / priority;
515 prune_dqcache(count);
516 unlock_kernel();
517 return kmem_cache_shrink(dquot_cachep);
518 }
519
520 /*
521 * Put reference to dquot
522 * NOTE: If you change this function please check whether dqput_blocks() works right...
523 */
dqput(struct dquot * dquot)524 static void dqput(struct dquot *dquot)
525 {
526 if (!dquot)
527 return;
528 #ifdef __DQUOT_PARANOIA
529 if (!dquot->dq_count) {
530 printk("VFS: dqput: trying to free free dquot\n");
531 printk("VFS: device %s, dquot of %s %d\n",
532 kdevname(dquot->dq_dev), quotatypes[dquot->dq_type],
533 dquot->dq_id);
534 return;
535 }
536 #endif
537
538 dqstats.drops++;
539 we_slept:
540 if (dquot->dq_dup_ref && dquot->dq_count - dquot->dq_dup_ref <= 1) { /* Last unduplicated reference? */
541 __wait_dup_drop(dquot);
542 goto we_slept;
543 }
544 if (dquot->dq_count > 1) {
545 /* We have more than one user... We can simply decrement use count */
546 put_dquot_ref(dquot);
547 return;
548 }
549 if (dquot_dirty(dquot)) {
550 dquot->dq_sb->dq_op->write_dquot(dquot);
551 goto we_slept;
552 }
553
554 /* sanity check */
555 if (!list_empty(&dquot->dq_free)) {
556 printk(KERN_ERR "dqput: dquot already on free list??\n");
557 put_dquot_ref(dquot);
558 return;
559 }
560 put_dquot_ref(dquot);
561 /* If dquot is going to be invalidated invalidate_dquots() is going to free it so */
562 if (!(dquot->dq_flags & DQ_INVAL))
563 put_dquot_last(dquot); /* Place at end of LRU free queue */
564 wake_up(&dquot->dq_wait_free);
565 }
566
get_empty_dquot(struct super_block * sb,int type)567 static struct dquot *get_empty_dquot(struct super_block *sb, int type)
568 {
569 struct dquot *dquot;
570
571 dquot = kmem_cache_alloc(dquot_cachep, SLAB_KERNEL);
572 if(!dquot)
573 return NODQUOT;
574
575 memset((caddr_t)dquot, 0, sizeof(struct dquot));
576 init_waitqueue_head(&dquot->dq_wait_free);
577 init_waitqueue_head(&dquot->dq_wait_lock);
578 INIT_LIST_HEAD(&dquot->dq_free);
579 INIT_LIST_HEAD(&dquot->dq_inuse);
580 INIT_LIST_HEAD(&dquot->dq_hash);
581 dquot->dq_sb = sb;
582 dquot->dq_dev = sb->s_dev;
583 dquot->dq_type = type;
584 dquot->dq_count = 1;
585 /* all dquots go on the inuse_list */
586 put_inuse(dquot);
587
588 return dquot;
589 }
590
dqget(struct super_block * sb,unsigned int id,int type)591 static struct dquot *dqget(struct super_block *sb, unsigned int id, int type)
592 {
593 unsigned int hashent = hashfn(sb, id, type);
594 struct dquot *dquot, *empty = NODQUOT;
595 struct quota_info *dqopt = sb_dqopt(sb);
596
597 we_slept:
598 if (!is_enabled(dqopt, type)) {
599 if (empty)
600 dqput(empty);
601 return NODQUOT;
602 }
603
604 if ((dquot = find_dquot(hashent, sb, id, type)) == NODQUOT) {
605 if (empty == NODQUOT) {
606 if ((empty = get_empty_dquot(sb, type)) == NODQUOT)
607 schedule(); /* Try to wait for a moment... */
608 goto we_slept;
609 }
610 dquot = empty;
611 dquot->dq_id = id;
612 /* hash it first so it can be found */
613 insert_dquot_hash(dquot);
614 read_dqblk(dquot);
615 } else {
616 if (!dquot->dq_count)
617 remove_free_dquot(dquot);
618 get_dquot_ref(dquot);
619 dqstats.cache_hits++;
620 wait_on_dquot(dquot);
621 if (empty)
622 dqput(empty);
623 }
624
625 if (!dquot->dq_sb) { /* Has somebody invalidated entry under us? */
626 printk(KERN_ERR "VFS: dqget(): Quota invalidated in dqget()!\n");
627 dqput(dquot);
628 return NODQUOT;
629 }
630 dqstats.lookups++;
631
632 return dquot;
633 }
634
635 /* Duplicate reference to dquot got from inode */
dqduplicate(struct dquot * dquot)636 static struct dquot *dqduplicate(struct dquot *dquot)
637 {
638 if (dquot == NODQUOT)
639 return NODQUOT;
640 get_dquot_ref(dquot);
641 if (!dquot->dq_sb) {
642 printk(KERN_ERR "VFS: dqduplicate(): Invalidated quota to be duplicated!\n");
643 put_dquot_ref(dquot);
644 return NODQUOT;
645 }
646 if (dquot->dq_flags & DQ_LOCKED)
647 printk(KERN_ERR "VFS: dqduplicate(): Locked quota to be duplicated!\n");
648 get_dquot_dup_ref(dquot);
649 dqstats.lookups++;
650
651 return dquot;
652 }
653
654 /* Put duplicated reference */
dqputduplicate(struct dquot * dquot)655 static void dqputduplicate(struct dquot *dquot)
656 {
657 if (!dquot->dq_dup_ref) {
658 printk(KERN_ERR "VFS: dqputduplicate(): Duplicated dquot put without duplicate reference.\n");
659 return;
660 }
661 put_dquot_dup_ref(dquot);
662 if (!dquot->dq_dup_ref)
663 wake_up(&dquot->dq_wait_free);
664 put_dquot_ref(dquot);
665 dqstats.drops++;
666 }
667
dqinit_needed(struct inode * inode,int type)668 static int dqinit_needed(struct inode *inode, int type)
669 {
670 int cnt;
671
672 if (IS_NOQUOTA(inode))
673 return 0;
674 if (type != -1)
675 return inode->i_dquot[type] == NODQUOT;
676 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
677 if (inode->i_dquot[cnt] == NODQUOT)
678 return 1;
679 return 0;
680 }
681
add_dquot_ref(struct super_block * sb,int type)682 static void add_dquot_ref(struct super_block *sb, int type)
683 {
684 struct list_head *p;
685
686 restart:
687 file_list_lock();
688 list_for_each(p, &sb->s_files) {
689 struct file *filp = list_entry(p, struct file, f_list);
690 struct inode *inode = filp->f_dentry->d_inode;
691 if (filp->f_mode & FMODE_WRITE && dqinit_needed(inode, type)) {
692 struct vfsmount *mnt = mntget(filp->f_vfsmnt);
693 struct dentry *dentry = dget(filp->f_dentry);
694 file_list_unlock();
695 sb->dq_op->initialize(inode, type);
696 dput(dentry);
697 mntput(mnt);
698 /* As we may have blocked we had better restart... */
699 goto restart;
700 }
701 }
702 file_list_unlock();
703 }
704
705 /* Return 0 if dqput() won't block (note that 1 doesn't necessarily mean blocking) */
dqput_blocks(struct dquot * dquot)706 static inline int dqput_blocks(struct dquot *dquot)
707 {
708 if (dquot->dq_dup_ref && dquot->dq_count - dquot->dq_dup_ref <= 1)
709 return 1;
710 if (dquot->dq_count <= 1 && dquot->dq_flags & DQ_MOD)
711 return 1;
712 return 0;
713 }
714
715 /* Remove references to dquots from inode - add dquot to list for freeing if needed */
remove_inode_dquot_ref(struct inode * inode,int type,struct list_head * tofree_head)716 int remove_inode_dquot_ref(struct inode *inode, int type, struct list_head *tofree_head)
717 {
718 struct dquot *dquot = inode->i_dquot[type];
719 int cnt;
720
721 inode->i_dquot[type] = NODQUOT;
722 /* any other quota in use? */
723 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
724 if (inode->i_dquot[cnt] != NODQUOT)
725 goto put_it;
726 }
727 inode->i_flags &= ~S_QUOTA;
728 put_it:
729 if (dquot != NODQUOT) {
730 if (dqput_blocks(dquot)) {
731 if (dquot->dq_count != 1)
732 printk(KERN_WARNING "VFS: Adding dquot with dq_count %d to dispose list.\n", dquot->dq_count);
733 list_add(&dquot->dq_free, tofree_head); /* As dquot must have currently users it can't be on the free list... */
734 return 1;
735 }
736 else
737 dqput(dquot); /* We have guaranteed we won't block */
738 }
739 return 0;
740 }
741
742 /* Free list of dquots - called from inode.c */
put_dquot_list(struct list_head * tofree_head)743 void put_dquot_list(struct list_head *tofree_head)
744 {
745 struct list_head *act_head;
746 struct dquot *dquot;
747
748 lock_kernel();
749 act_head = tofree_head->next;
750 /* So now we have dquots on the list... Just free them */
751 while (act_head != tofree_head) {
752 dquot = list_entry(act_head, struct dquot, dq_free);
753 act_head = act_head->next;
754 list_del(&dquot->dq_free); /* Remove dquot from the list so we won't have problems... */
755 INIT_LIST_HEAD(&dquot->dq_free);
756 dqput(dquot);
757 }
758 unlock_kernel();
759 }
760
dquot_incr_inodes(struct dquot * dquot,unsigned long number)761 static inline void dquot_incr_inodes(struct dquot *dquot, unsigned long number)
762 {
763 dquot->dq_dqb.dqb_curinodes += number;
764 mark_dquot_dirty(dquot);
765 }
766
dquot_incr_space(struct dquot * dquot,qsize_t number)767 static inline void dquot_incr_space(struct dquot *dquot, qsize_t number)
768 {
769 dquot->dq_dqb.dqb_curspace += number;
770 mark_dquot_dirty(dquot);
771 }
772
dquot_decr_inodes(struct dquot * dquot,unsigned long number)773 static inline void dquot_decr_inodes(struct dquot *dquot, unsigned long number)
774 {
775 if (dquot->dq_dqb.dqb_curinodes > number)
776 dquot->dq_dqb.dqb_curinodes -= number;
777 else
778 dquot->dq_dqb.dqb_curinodes = 0;
779 if (dquot->dq_dqb.dqb_curinodes < dquot->dq_dqb.dqb_isoftlimit)
780 dquot->dq_dqb.dqb_itime = (time_t) 0;
781 dquot->dq_flags &= ~DQ_INODES;
782 mark_dquot_dirty(dquot);
783 }
784
dquot_decr_space(struct dquot * dquot,qsize_t number)785 static inline void dquot_decr_space(struct dquot *dquot, qsize_t number)
786 {
787 if (dquot->dq_dqb.dqb_curspace > number)
788 dquot->dq_dqb.dqb_curspace -= number;
789 else
790 dquot->dq_dqb.dqb_curspace = 0;
791 if (toqb(dquot->dq_dqb.dqb_curspace) < dquot->dq_dqb.dqb_bsoftlimit)
792 dquot->dq_dqb.dqb_btime = (time_t) 0;
793 dquot->dq_flags &= ~DQ_BLKS;
794 mark_dquot_dirty(dquot);
795 }
796
797 static int flag_print_warnings = 1;
798
need_print_warning(struct dquot * dquot,int flag)799 static inline int need_print_warning(struct dquot *dquot, int flag)
800 {
801 if (!flag_print_warnings)
802 return 0;
803
804 switch (dquot->dq_type) {
805 case USRQUOTA:
806 return current->fsuid == dquot->dq_id && !(dquot->dq_flags & flag);
807 case GRPQUOTA:
808 return in_group_p(dquot->dq_id) && !(dquot->dq_flags & flag);
809 }
810 return 0;
811 }
812
813 /* Values of warnings */
814 #define NOWARN 0
815 #define IHARDWARN 1
816 #define ISOFTLONGWARN 2
817 #define ISOFTWARN 3
818 #define BHARDWARN 4
819 #define BSOFTLONGWARN 5
820 #define BSOFTWARN 6
821
822 /* Print warning to user which exceeded quota */
print_warning(struct dquot * dquot,const char warntype)823 static void print_warning(struct dquot *dquot, const char warntype)
824 {
825 char *msg = NULL;
826 int flag = (warntype == BHARDWARN || warntype == BSOFTLONGWARN) ? DQ_BLKS :
827 ((warntype == IHARDWARN || warntype == ISOFTLONGWARN) ? DQ_INODES : 0);
828
829 if (!need_print_warning(dquot, flag))
830 return;
831 dquot->dq_flags |= flag;
832 tty_write_message(current->tty, (char *)bdevname(dquot->dq_sb->s_dev));
833 if (warntype == ISOFTWARN || warntype == BSOFTWARN)
834 tty_write_message(current->tty, ": warning, ");
835 else
836 tty_write_message(current->tty, ": write failed, ");
837 tty_write_message(current->tty, quotatypes[dquot->dq_type]);
838 switch (warntype) {
839 case IHARDWARN:
840 msg = " file limit reached.\r\n";
841 break;
842 case ISOFTLONGWARN:
843 msg = " file quota exceeded too long.\r\n";
844 break;
845 case ISOFTWARN:
846 msg = " file quota exceeded.\r\n";
847 break;
848 case BHARDWARN:
849 msg = " block limit reached.\r\n";
850 break;
851 case BSOFTLONGWARN:
852 msg = " block quota exceeded too long.\r\n";
853 break;
854 case BSOFTWARN:
855 msg = " block quota exceeded.\r\n";
856 break;
857 }
858 tty_write_message(current->tty, msg);
859 }
860
flush_warnings(struct dquot ** dquots,char * warntype)861 static inline void flush_warnings(struct dquot **dquots, char *warntype)
862 {
863 int i;
864
865 for (i = 0; i < MAXQUOTAS; i++)
866 if (dquots[i] != NODQUOT && warntype[i] != NOWARN)
867 print_warning(dquots[i], warntype[i]);
868 }
869
ignore_hardlimit(struct dquot * dquot)870 static inline char ignore_hardlimit(struct dquot *dquot)
871 {
872 struct mem_dqinfo *info = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_type];
873
874 return capable(CAP_SYS_RESOURCE) &&
875 (info->dqi_format->qf_fmt_id != QFMT_VFS_OLD || !(info->dqi_flags & V1_DQF_RSQUASH));
876 }
877
check_idq(struct dquot * dquot,ulong inodes,char * warntype)878 static int check_idq(struct dquot *dquot, ulong inodes, char *warntype)
879 {
880 *warntype = NOWARN;
881 if (inodes <= 0 || dquot->dq_flags & DQ_FAKE)
882 return QUOTA_OK;
883
884 if (dquot->dq_dqb.dqb_ihardlimit &&
885 (dquot->dq_dqb.dqb_curinodes + inodes) > dquot->dq_dqb.dqb_ihardlimit &&
886 !ignore_hardlimit(dquot)) {
887 *warntype = IHARDWARN;
888 return NO_QUOTA;
889 }
890
891 if (dquot->dq_dqb.dqb_isoftlimit &&
892 (dquot->dq_dqb.dqb_curinodes + inodes) > dquot->dq_dqb.dqb_isoftlimit &&
893 dquot->dq_dqb.dqb_itime && CURRENT_TIME >= dquot->dq_dqb.dqb_itime &&
894 !ignore_hardlimit(dquot)) {
895 *warntype = ISOFTLONGWARN;
896 return NO_QUOTA;
897 }
898
899 if (dquot->dq_dqb.dqb_isoftlimit &&
900 (dquot->dq_dqb.dqb_curinodes + inodes) > dquot->dq_dqb.dqb_isoftlimit &&
901 dquot->dq_dqb.dqb_itime == 0) {
902 *warntype = ISOFTWARN;
903 dquot->dq_dqb.dqb_itime = CURRENT_TIME + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace;
904 }
905
906 return QUOTA_OK;
907 }
908
check_bdq(struct dquot * dquot,qsize_t space,int prealloc,char * warntype)909 static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *warntype)
910 {
911 *warntype = 0;
912 if (space <= 0 || dquot->dq_flags & DQ_FAKE)
913 return QUOTA_OK;
914
915 if (dquot->dq_dqb.dqb_bhardlimit &&
916 toqb(dquot->dq_dqb.dqb_curspace + space) > dquot->dq_dqb.dqb_bhardlimit &&
917 !ignore_hardlimit(dquot)) {
918 if (!prealloc)
919 *warntype = BHARDWARN;
920 return NO_QUOTA;
921 }
922
923 if (dquot->dq_dqb.dqb_bsoftlimit &&
924 toqb(dquot->dq_dqb.dqb_curspace + space) > dquot->dq_dqb.dqb_bsoftlimit &&
925 dquot->dq_dqb.dqb_btime && CURRENT_TIME >= dquot->dq_dqb.dqb_btime &&
926 !ignore_hardlimit(dquot)) {
927 if (!prealloc)
928 *warntype = BSOFTLONGWARN;
929 return NO_QUOTA;
930 }
931
932 if (dquot->dq_dqb.dqb_bsoftlimit &&
933 toqb(dquot->dq_dqb.dqb_curspace + space) > dquot->dq_dqb.dqb_bsoftlimit &&
934 dquot->dq_dqb.dqb_btime == 0) {
935 if (!prealloc) {
936 *warntype = BSOFTWARN;
937 dquot->dq_dqb.dqb_btime = CURRENT_TIME + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_bgrace;
938 }
939 else
940 /*
941 * We don't allow preallocation to exceed softlimit so exceeding will
942 * be always printed
943 */
944 return NO_QUOTA;
945 }
946
947 return QUOTA_OK;
948 }
949
950 /*
951 * Externally referenced functions through dquot_operations in inode.
952 *
953 * Note: this is a blocking operation.
954 */
dquot_initialize(struct inode * inode,int type)955 void dquot_initialize(struct inode *inode, int type)
956 {
957 struct dquot *dquot[MAXQUOTAS];
958 unsigned int id = 0;
959 int cnt;
960
961 if (IS_NOQUOTA(inode))
962 return;
963 /* Build list of quotas to initialize... We can block here */
964 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
965 dquot[cnt] = NODQUOT;
966 if (type != -1 && cnt != type)
967 continue;
968 if (!sb_has_quota_enabled(inode->i_sb, cnt))
969 continue;
970 if (inode->i_dquot[cnt] == NODQUOT) {
971 switch (cnt) {
972 case USRQUOTA:
973 id = inode->i_uid;
974 break;
975 case GRPQUOTA:
976 id = inode->i_gid;
977 break;
978 }
979 dquot[cnt] = dqget(inode->i_sb, id, cnt);
980 }
981 }
982 /* NOBLOCK START: Here we shouldn't block */
983 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
984 if (dquot[cnt] == NODQUOT || !sb_has_quota_enabled(inode->i_sb, cnt) || inode->i_dquot[cnt] != NODQUOT)
985 continue;
986 inode->i_dquot[cnt] = dquot[cnt];
987 dquot[cnt] = NODQUOT;
988 inode->i_flags |= S_QUOTA;
989 }
990 /* NOBLOCK END */
991 /* Put quotas which we didn't use */
992 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
993 if (dquot[cnt] != NODQUOT)
994 dqput(dquot[cnt]);
995 }
996
997 /*
998 * Release all quota for the specified inode.
999 *
1000 * Note: this is a blocking operation.
1001 */
dquot_drop(struct inode * inode)1002 void dquot_drop(struct inode *inode)
1003 {
1004 struct dquot *dquot;
1005 int cnt;
1006
1007 inode->i_flags &= ~S_QUOTA;
1008 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1009 if (inode->i_dquot[cnt] == NODQUOT)
1010 continue;
1011 dquot = inode->i_dquot[cnt];
1012 inode->i_dquot[cnt] = NODQUOT;
1013 dqput(dquot);
1014 }
1015 }
1016
1017 /*
1018 * This operation can block, but only after everything is updated
1019 */
dquot_alloc_space(struct inode * inode,qsize_t number,int warn)1020 int dquot_alloc_space(struct inode *inode, qsize_t number, int warn)
1021 {
1022 int cnt, ret = NO_QUOTA;
1023 struct dquot *dquot[MAXQUOTAS];
1024 char warntype[MAXQUOTAS];
1025
1026 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1027 dquot[cnt] = NODQUOT;
1028 warntype[cnt] = NOWARN;
1029 }
1030 /* NOBLOCK Start */
1031 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1032 dquot[cnt] = dqduplicate(inode->i_dquot[cnt]);
1033 if (dquot[cnt] == NODQUOT)
1034 continue;
1035 if (check_bdq(dquot[cnt], number, warn, warntype+cnt) == NO_QUOTA)
1036 goto warn_put_all;
1037 }
1038 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1039 if (dquot[cnt] == NODQUOT)
1040 continue;
1041 dquot_incr_space(dquot[cnt], number);
1042 }
1043 inode_add_bytes(inode, number);
1044 /* NOBLOCK End */
1045 ret = QUOTA_OK;
1046 warn_put_all:
1047 flush_warnings(dquot, warntype);
1048 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
1049 if (dquot[cnt] != NODQUOT)
1050 dqputduplicate(dquot[cnt]);
1051 return ret;
1052 }
1053
1054 /*
1055 * This operation can block, but only after everything is updated
1056 */
dquot_alloc_inode(const struct inode * inode,unsigned long number)1057 int dquot_alloc_inode(const struct inode *inode, unsigned long number)
1058 {
1059 int cnt, ret = NO_QUOTA;
1060 struct dquot *dquot[MAXQUOTAS];
1061 char warntype[MAXQUOTAS];
1062
1063 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1064 dquot[cnt] = NODQUOT;
1065 warntype[cnt] = NOWARN;
1066 }
1067 /* NOBLOCK Start */
1068 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1069 dquot[cnt] = dqduplicate(inode -> i_dquot[cnt]);
1070 if (dquot[cnt] == NODQUOT)
1071 continue;
1072 if (check_idq(dquot[cnt], number, warntype+cnt) == NO_QUOTA)
1073 goto warn_put_all;
1074 }
1075
1076 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1077 if (dquot[cnt] == NODQUOT)
1078 continue;
1079 dquot_incr_inodes(dquot[cnt], number);
1080 }
1081 /* NOBLOCK End */
1082 ret = QUOTA_OK;
1083 warn_put_all:
1084 flush_warnings(dquot, warntype);
1085 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
1086 if (dquot[cnt] != NODQUOT)
1087 dqputduplicate(dquot[cnt]);
1088 return ret;
1089 }
1090
1091 /*
1092 * This is a non-blocking operation.
1093 */
dquot_free_space(struct inode * inode,qsize_t number)1094 void dquot_free_space(struct inode *inode, qsize_t number)
1095 {
1096 unsigned int cnt;
1097 struct dquot *dquot;
1098
1099 /* NOBLOCK Start */
1100 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1101 dquot = dqduplicate(inode->i_dquot[cnt]);
1102 if (dquot == NODQUOT)
1103 continue;
1104 dquot_decr_space(dquot, number);
1105 dqputduplicate(dquot);
1106 }
1107 inode_sub_bytes(inode, number);
1108 /* NOBLOCK End */
1109 }
1110
1111 /*
1112 * This is a non-blocking operation.
1113 */
dquot_free_inode(const struct inode * inode,unsigned long number)1114 void dquot_free_inode(const struct inode *inode, unsigned long number)
1115 {
1116 unsigned int cnt;
1117 struct dquot *dquot;
1118
1119 /* NOBLOCK Start */
1120 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1121 dquot = dqduplicate(inode->i_dquot[cnt]);
1122 if (dquot == NODQUOT)
1123 continue;
1124 dquot_decr_inodes(dquot, number);
1125 dqputduplicate(dquot);
1126 }
1127 /* NOBLOCK End */
1128 }
1129
1130 /*
1131 * Transfer the number of inode and blocks from one diskquota to an other.
1132 *
1133 * This operation can block, but only after everything is updated
1134 */
dquot_transfer(struct inode * inode,struct iattr * iattr)1135 int dquot_transfer(struct inode *inode, struct iattr *iattr)
1136 {
1137 qsize_t space;
1138 struct dquot *transfer_from[MAXQUOTAS];
1139 struct dquot *transfer_to[MAXQUOTAS];
1140 int cnt, ret = NO_QUOTA, chuid = (iattr->ia_valid & ATTR_UID) && inode->i_uid != iattr->ia_uid,
1141 chgid = (iattr->ia_valid & ATTR_GID) && inode->i_gid != iattr->ia_gid;
1142 char warntype[MAXQUOTAS];
1143
1144 /* Clear the arrays */
1145 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1146 transfer_to[cnt] = transfer_from[cnt] = NODQUOT;
1147 warntype[cnt] = NOWARN;
1148 }
1149 /* First build the transfer_to list - here we can block on reading of dquots... */
1150 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1151 if (!sb_has_quota_enabled(inode->i_sb, cnt))
1152 continue;
1153 switch (cnt) {
1154 case USRQUOTA:
1155 if (!chuid)
1156 continue;
1157 transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_uid, cnt);
1158 break;
1159 case GRPQUOTA:
1160 if (!chgid)
1161 continue;
1162 transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_gid, cnt);
1163 break;
1164 }
1165 }
1166 /* NOBLOCK START: From now on we shouldn't block */
1167 space = inode_get_bytes(inode);
1168 /* Build the transfer_from list and check the limits */
1169 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1170 /* The second test can fail when quotaoff is in progress... */
1171 if (transfer_to[cnt] == NODQUOT || !sb_has_quota_enabled(inode->i_sb, cnt))
1172 continue;
1173 transfer_from[cnt] = dqduplicate(inode->i_dquot[cnt]);
1174 if (transfer_from[cnt] == NODQUOT) /* Can happen on quotafiles (quota isn't initialized on them)... */
1175 continue;
1176 if (check_idq(transfer_to[cnt], 1, warntype+cnt) == NO_QUOTA ||
1177 check_bdq(transfer_to[cnt], space, 0, warntype+cnt) == NO_QUOTA)
1178 goto warn_put_all;
1179 }
1180
1181 /*
1182 * Finally perform the needed transfer from transfer_from to transfer_to
1183 */
1184 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1185 /*
1186 * Skip changes for same uid or gid or for non-existing quota-type.
1187 */
1188 if (transfer_from[cnt] == NODQUOT || transfer_to[cnt] == NODQUOT)
1189 continue;
1190
1191 dquot_decr_inodes(transfer_from[cnt], 1);
1192 dquot_decr_space(transfer_from[cnt], space);
1193
1194 dquot_incr_inodes(transfer_to[cnt], 1);
1195 dquot_incr_space(transfer_to[cnt], space);
1196
1197 if (inode->i_dquot[cnt] == NODQUOT)
1198 BUG();
1199 inode->i_dquot[cnt] = transfer_to[cnt];
1200 /*
1201 * We've got to release transfer_from[] twice - once for dquot_transfer() and
1202 * once for inode. We don't want to release transfer_to[] as it's now placed in inode
1203 */
1204 transfer_to[cnt] = transfer_from[cnt];
1205 }
1206 /* NOBLOCK END. From now on we can block as we wish */
1207 ret = QUOTA_OK;
1208 warn_put_all:
1209 flush_warnings(transfer_to, warntype);
1210 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1211 /* First we must put duplicate - otherwise we might deadlock */
1212 if (transfer_from[cnt] != NODQUOT)
1213 dqputduplicate(transfer_from[cnt]);
1214 if (transfer_to[cnt] != NODQUOT)
1215 dqput(transfer_to[cnt]);
1216 }
1217 return ret;
1218 }
1219
1220 /*
1221 * Definitions of diskquota operations.
1222 */
1223 struct dquot_operations dquot_operations = {
1224 initialize: dquot_initialize, /* mandatory */
1225 drop: dquot_drop, /* mandatory */
1226 alloc_space: dquot_alloc_space,
1227 alloc_inode: dquot_alloc_inode,
1228 free_space: dquot_free_space,
1229 free_inode: dquot_free_inode,
1230 transfer: dquot_transfer,
1231 write_dquot: commit_dqblk
1232 };
1233
1234 /* Function used by filesystems for initializing the dquot_operations structure */
init_dquot_operations(struct dquot_operations * fsdqops)1235 void init_dquot_operations(struct dquot_operations *fsdqops)
1236 {
1237 memcpy(fsdqops, &dquot_operations, sizeof(dquot_operations));
1238 }
1239
set_enable_flags(struct quota_info * dqopt,int type)1240 static inline void set_enable_flags(struct quota_info *dqopt, int type)
1241 {
1242 switch (type) {
1243 case USRQUOTA:
1244 dqopt->flags |= DQUOT_USR_ENABLED;
1245 break;
1246 case GRPQUOTA:
1247 dqopt->flags |= DQUOT_GRP_ENABLED;
1248 break;
1249 }
1250 }
1251
reset_enable_flags(struct quota_info * dqopt,int type)1252 static inline void reset_enable_flags(struct quota_info *dqopt, int type)
1253 {
1254 switch (type) {
1255 case USRQUOTA:
1256 dqopt->flags &= ~DQUOT_USR_ENABLED;
1257 break;
1258 case GRPQUOTA:
1259 dqopt->flags &= ~DQUOT_GRP_ENABLED;
1260 break;
1261 }
1262 }
1263
1264 /* Function in inode.c - remove pointers to dquots in icache */
1265 extern void remove_dquot_ref(struct super_block *, int);
1266
1267 /*
1268 * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount)
1269 */
vfs_quota_off(struct super_block * sb,int type)1270 int vfs_quota_off(struct super_block *sb, int type)
1271 {
1272 int cnt;
1273 struct quota_info *dqopt = sb_dqopt(sb);
1274
1275 lock_kernel();
1276 if (!sb)
1277 goto out;
1278
1279 /* We need to serialize quota_off() for device */
1280 down(&dqopt->dqoff_sem);
1281 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1282 if (type != -1 && cnt != type)
1283 continue;
1284 if (!is_enabled(dqopt, cnt))
1285 continue;
1286 reset_enable_flags(dqopt, cnt);
1287
1288 /* Note: these are blocking operations */
1289 remove_dquot_ref(sb, cnt);
1290 invalidate_dquots(sb, cnt);
1291 if (info_dirty(&dqopt->info[cnt]))
1292 dqopt->ops[cnt]->write_file_info(sb, cnt);
1293 if (dqopt->ops[cnt]->free_file_info)
1294 dqopt->ops[cnt]->free_file_info(sb, cnt);
1295 put_quota_format(dqopt->info[cnt].dqi_format);
1296
1297 fput(dqopt->files[cnt]);
1298 dqopt->files[cnt] = (struct file *)NULL;
1299 dqopt->info[cnt].dqi_flags = 0;
1300 dqopt->info[cnt].dqi_igrace = 0;
1301 dqopt->info[cnt].dqi_bgrace = 0;
1302 dqopt->ops[cnt] = NULL;
1303 }
1304 up(&dqopt->dqoff_sem);
1305 out:
1306 unlock_kernel();
1307 return 0;
1308 }
1309
vfs_quota_on(struct super_block * sb,int type,int format_id,char * path)1310 int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path)
1311 {
1312 struct file *f = NULL;
1313 struct inode *inode;
1314 struct quota_info *dqopt = sb_dqopt(sb);
1315 struct quota_format_type *fmt = find_quota_format(format_id);
1316 int error;
1317
1318 if (!fmt)
1319 return -ESRCH;
1320 if (is_enabled(dqopt, type)) {
1321 error = -EBUSY;
1322 goto out_fmt;
1323 }
1324
1325 down(&dqopt->dqoff_sem);
1326
1327 f = filp_open(path, O_RDWR, 0600);
1328
1329 error = PTR_ERR(f);
1330 if (IS_ERR(f))
1331 goto out_lock;
1332 dqopt->files[type] = f;
1333 error = -EIO;
1334 if (!f->f_op || !f->f_op->read || !f->f_op->write)
1335 goto out_f;
1336 inode = f->f_dentry->d_inode;
1337 error = -EACCES;
1338 if (!S_ISREG(inode->i_mode))
1339 goto out_f;
1340 error = -EINVAL;
1341 if (!fmt->qf_ops->check_quota_file(sb, type))
1342 goto out_f;
1343 /* We don't want quota and atime on quota files */
1344 dquot_drop(inode);
1345 inode->i_flags |= S_NOQUOTA | S_NOATIME;
1346
1347 dqopt->ops[type] = fmt->qf_ops;
1348 dqopt->info[type].dqi_format = fmt;
1349 if ((error = dqopt->ops[type]->read_file_info(sb, type)) < 0)
1350 goto out_f;
1351 set_enable_flags(dqopt, type);
1352
1353 add_dquot_ref(sb, type);
1354
1355 up(&dqopt->dqoff_sem);
1356 return 0;
1357
1358 out_f:
1359 if (f)
1360 filp_close(f, NULL);
1361 dqopt->files[type] = NULL;
1362 out_lock:
1363 up(&dqopt->dqoff_sem);
1364 out_fmt:
1365 put_quota_format(fmt);
1366
1367 return error;
1368 }
1369
1370 /* Generic routine for getting common part of quota structure */
do_get_dqblk(struct dquot * dquot,struct if_dqblk * di)1371 static void do_get_dqblk(struct dquot *dquot, struct if_dqblk *di)
1372 {
1373 struct mem_dqblk *dm = &dquot->dq_dqb;
1374
1375 di->dqb_bhardlimit = dm->dqb_bhardlimit;
1376 di->dqb_bsoftlimit = dm->dqb_bsoftlimit;
1377 di->dqb_curspace = dm->dqb_curspace;
1378 di->dqb_ihardlimit = dm->dqb_ihardlimit;
1379 di->dqb_isoftlimit = dm->dqb_isoftlimit;
1380 di->dqb_curinodes = dm->dqb_curinodes;
1381 di->dqb_btime = dm->dqb_btime;
1382 di->dqb_itime = dm->dqb_itime;
1383 di->dqb_valid = QIF_ALL;
1384 }
1385
vfs_get_dqblk(struct super_block * sb,int type,qid_t id,struct if_dqblk * di)1386 int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di)
1387 {
1388 struct dquot *dquot = dqget(sb, id, type);
1389
1390 if (!dquot)
1391 return -EINVAL;
1392 do_get_dqblk(dquot, di);
1393 dqput(dquot);
1394 return 0;
1395 }
1396
1397 /* Generic routine for setting common part of quota structure */
do_set_dqblk(struct dquot * dquot,struct if_dqblk * di)1398 static void do_set_dqblk(struct dquot *dquot, struct if_dqblk *di)
1399 {
1400 struct mem_dqblk *dm = &dquot->dq_dqb;
1401 int check_blim = 0, check_ilim = 0;
1402
1403 if (di->dqb_valid & QIF_SPACE) {
1404 dm->dqb_curspace = di->dqb_curspace;
1405 check_blim = 1;
1406 }
1407 if (di->dqb_valid & QIF_BLIMITS) {
1408 dm->dqb_bsoftlimit = di->dqb_bsoftlimit;
1409 dm->dqb_bhardlimit = di->dqb_bhardlimit;
1410 check_blim = 1;
1411 }
1412 if (di->dqb_valid & QIF_INODES) {
1413 dm->dqb_curinodes = di->dqb_curinodes;
1414 check_ilim = 1;
1415 }
1416 if (di->dqb_valid & QIF_ILIMITS) {
1417 dm->dqb_isoftlimit = di->dqb_isoftlimit;
1418 dm->dqb_ihardlimit = di->dqb_ihardlimit;
1419 check_ilim = 1;
1420 }
1421 if (di->dqb_valid & QIF_BTIME)
1422 dm->dqb_btime = di->dqb_btime;
1423 if (di->dqb_valid & QIF_ITIME)
1424 dm->dqb_itime = di->dqb_itime;
1425
1426 if (check_blim) {
1427 if (!dm->dqb_bsoftlimit || toqb(dm->dqb_curspace) < dm->dqb_bsoftlimit) {
1428 dm->dqb_btime = 0;
1429 dquot->dq_flags &= ~DQ_BLKS;
1430 }
1431 else if (!(di->dqb_valid & QIF_BTIME)) /* Set grace only if user hasn't provided his own... */
1432 dm->dqb_btime = CURRENT_TIME + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_bgrace;
1433 }
1434 if (check_ilim) {
1435 if (!dm->dqb_isoftlimit || dm->dqb_curinodes < dm->dqb_isoftlimit) {
1436 dm->dqb_itime = 0;
1437 dquot->dq_flags &= ~DQ_INODES;
1438 }
1439 else if (!(di->dqb_valid & QIF_ITIME)) /* Set grace only if user hasn't provided his own... */
1440 dm->dqb_itime = CURRENT_TIME + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace;
1441 }
1442 if (dm->dqb_bhardlimit || dm->dqb_bsoftlimit || dm->dqb_ihardlimit || dm->dqb_isoftlimit)
1443 dquot->dq_flags &= ~DQ_FAKE;
1444 else
1445 dquot->dq_flags |= DQ_FAKE;
1446 dquot->dq_flags |= DQ_MOD;
1447 }
1448
vfs_set_dqblk(struct super_block * sb,int type,qid_t id,struct if_dqblk * di)1449 int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di)
1450 {
1451 struct dquot *dquot = dqget(sb, id, type);
1452
1453 if (!dquot)
1454 return -EINVAL;
1455 do_set_dqblk(dquot, di);
1456 dqput(dquot);
1457 return 0;
1458 }
1459
1460 /* Generic routine for getting common part of quota file information */
vfs_get_dqinfo(struct super_block * sb,int type,struct if_dqinfo * ii)1461 int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
1462 {
1463 struct mem_dqinfo *mi = sb_dqopt(sb)->info + type;
1464
1465 ii->dqi_bgrace = mi->dqi_bgrace;
1466 ii->dqi_igrace = mi->dqi_igrace;
1467 ii->dqi_flags = mi->dqi_flags & DQF_MASK;
1468 ii->dqi_valid = IIF_ALL;
1469 return 0;
1470 }
1471
1472 /* Generic routine for setting common part of quota file information */
vfs_set_dqinfo(struct super_block * sb,int type,struct if_dqinfo * ii)1473 int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
1474 {
1475 struct mem_dqinfo *mi = sb_dqopt(sb)->info + type;
1476
1477 if (ii->dqi_valid & IIF_BGRACE)
1478 mi->dqi_bgrace = ii->dqi_bgrace;
1479 if (ii->dqi_valid & IIF_IGRACE)
1480 mi->dqi_igrace = ii->dqi_igrace;
1481 if (ii->dqi_valid & IIF_FLAGS)
1482 mi->dqi_flags = (mi->dqi_flags & ~DQF_MASK) | (ii->dqi_flags & DQF_MASK);
1483 mark_info_dirty(mi);
1484 return 0;
1485 }
1486
1487 struct quotactl_ops vfs_quotactl_ops = {
1488 quota_on: vfs_quota_on,
1489 quota_off: vfs_quota_off,
1490 quota_sync: vfs_quota_sync,
1491 get_info: vfs_get_dqinfo,
1492 set_info: vfs_set_dqinfo,
1493 get_dqblk: vfs_get_dqblk,
1494 set_dqblk: vfs_set_dqblk
1495 };
1496
1497 static ctl_table fs_dqstats_table[] = {
1498 {FS_DQ_LOOKUPS, "lookups", &dqstats.lookups, sizeof(int), 0444, NULL, &proc_dointvec},
1499 {FS_DQ_DROPS, "drops", &dqstats.drops, sizeof(int), 0444, NULL, &proc_dointvec},
1500 {FS_DQ_READS, "reads", &dqstats.reads, sizeof(int), 0444, NULL, &proc_dointvec},
1501 {FS_DQ_WRITES, "writes", &dqstats.writes, sizeof(int), 0444, NULL, &proc_dointvec},
1502 {FS_DQ_CACHE_HITS, "cache_hits", &dqstats.cache_hits, sizeof(int), 0444, NULL, &proc_dointvec},
1503 {FS_DQ_ALLOCATED, "allocated_dquots", &dqstats.allocated_dquots, sizeof(int), 0444, NULL, &proc_dointvec},
1504 {FS_DQ_FREE, "free_dquots", &dqstats.free_dquots, sizeof(int), 0444, NULL, &proc_dointvec},
1505 {FS_DQ_SYNCS, "syncs", &dqstats.syncs, sizeof(int), 0444, NULL, &proc_dointvec},
1506 {FS_DQ_WARNINGS, "warnings", &flag_print_warnings, sizeof(int), 0644, NULL, &proc_dointvec},
1507 {},
1508 };
1509
1510 static ctl_table fs_table[] = {
1511 {FS_DQSTATS, "quota", NULL, 0, 0555, fs_dqstats_table},
1512 {},
1513 };
1514
1515 static ctl_table sys_table[] = {
1516 {CTL_FS, "fs", NULL, 0, 0555, fs_table},
1517 {},
1518 };
1519
dquot_init(void)1520 static int __init dquot_init(void)
1521 {
1522 int i;
1523
1524 register_sysctl_table(sys_table, 0);
1525 for (i = 0; i < NR_DQHASH; i++)
1526 INIT_LIST_HEAD(dquot_hash + i);
1527 printk(KERN_NOTICE "VFS: Disk quotas v%s\n", __DQUOT_VERSION__);
1528
1529 return 0;
1530 }
1531 __initcall(dquot_init);
1532
1533 EXPORT_SYMBOL(register_quota_format);
1534 EXPORT_SYMBOL(unregister_quota_format);
1535 EXPORT_SYMBOL(dqstats);
1536 EXPORT_SYMBOL(init_dquot_operations);
1537