Remove references to CONFIG_PROFILE. Kernel profiling is no longer a
[linux-2.6/linux-mips.git] / fs / dquot.c
blob56824a73aca4a51d049d1faae40622f84b22e98f
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.
15 * Version: $Id: dquot.c,v 6.3 1996/11/17 18:35:34 mvw Exp mvw $
17 * Author: Marco van Wieringen <mvw@planets.elm.net>
19 * Fixes: Dmitry Gorodchanin <pgmdsg@ibi.com>, 11 Feb 96
21 * Revised list management to avoid races
22 * -- Bill Hawes, <whawes@star.net>, 9/98
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
37 * (C) Copyright 1994 - 1997 Marco van Wieringen
40 #include <linux/errno.h>
41 #include <linux/kernel.h>
42 #include <linux/sched.h>
44 #include <linux/types.h>
45 #include <linux/string.h>
46 #include <linux/fcntl.h>
47 #include <linux/stat.h>
48 #include <linux/tty.h>
49 #include <linux/file.h>
50 #include <linux/malloc.h>
51 #include <linux/mount.h>
52 #include <linux/smp.h>
53 #include <linux/smp_lock.h>
54 #include <linux/init.h>
55 #include <linux/slab.h>
57 #include <asm/uaccess.h>
59 #define __DQUOT_VERSION__ "dquot_6.4.0"
61 int nr_dquots, nr_free_dquots;
62 int max_dquots = NR_DQUOTS;
64 static char quotamessage[MAX_QUOTA_MESSAGE];
65 static char *quotatypes[] = INITQFNAMES;
67 static kmem_cache_t *dquot_cachep;
69 static inline struct quota_mount_options *sb_dqopt(struct super_block *sb)
71 return &sb->s_dquot;
75 * Dquot List Management:
76 * The quota code uses three lists for dquot management: the inuse_list,
77 * free_dquots, and dquot_hash[] array. A single dquot structure may be
78 * on all three lists, depending on its current state.
80 * All dquots are placed on the inuse_list when first created, and this
81 * list is used for the sync and invalidate operations, which must look
82 * at every dquot.
84 * Unused dquots (dq_count == 0) are added to the free_dquots list when
85 * freed, and this list is searched whenever we need an available dquot.
86 * Dquots are removed from the list as soon as they are used again, and
87 * nr_free_dquots gives the number of dquots on the list.
89 * Dquots with a specific identity (device, type and id) are placed on
90 * one of the dquot_hash[] hash chains. The provides an efficient search
91 * mechanism to lcoate a specific dquot.
94 static struct dquot *inuse_list;
95 static LIST_HEAD(free_dquots);
96 static struct dquot *dquot_hash[NR_DQHASH];
97 static int dquot_updating[NR_DQHASH];
99 static struct dqstats dqstats;
100 static DECLARE_WAIT_QUEUE_HEAD(dquot_wait);
101 static DECLARE_WAIT_QUEUE_HEAD(update_wait);
103 static void dqput(struct dquot *);
104 static struct dquot *dqduplicate(struct dquot *);
106 static inline char is_enabled(struct quota_mount_options *dqopt, short type)
108 switch (type) {
109 case USRQUOTA:
110 return((dqopt->flags & DQUOT_USR_ENABLED) != 0);
111 case GRPQUOTA:
112 return((dqopt->flags & DQUOT_GRP_ENABLED) != 0);
114 return(0);
117 static inline char sb_has_quota_enabled(struct super_block *sb, short type)
119 return is_enabled(sb_dqopt(sb), type);
122 static inline int const hashfn(kdev_t dev, unsigned int id, short type)
124 return((HASHDEV(dev) ^ id) * (MAXQUOTAS - type)) % NR_DQHASH;
127 static inline void insert_dquot_hash(struct dquot *dquot)
129 struct dquot **htable;
131 htable = &dquot_hash[hashfn(dquot->dq_dev, dquot->dq_id, dquot->dq_type)];
132 if ((dquot->dq_hash_next = *htable) != NULL)
133 (*htable)->dq_hash_pprev = &dquot->dq_hash_next;
134 *htable = dquot;
135 dquot->dq_hash_pprev = htable;
138 static inline void hash_dquot(struct dquot *dquot)
140 insert_dquot_hash(dquot);
143 static inline void unhash_dquot(struct dquot *dquot)
145 if (dquot->dq_hash_pprev) {
146 if (dquot->dq_hash_next)
147 dquot->dq_hash_next->dq_hash_pprev = dquot->dq_hash_pprev;
148 *(dquot->dq_hash_pprev) = dquot->dq_hash_next;
149 dquot->dq_hash_pprev = NULL;
153 static inline struct dquot *find_dquot(unsigned int hashent, kdev_t dev, unsigned int id, short type)
155 struct dquot *dquot;
157 for (dquot = dquot_hash[hashent]; dquot; dquot = dquot->dq_hash_next)
158 if (dquot->dq_dev == dev && dquot->dq_id == id && dquot->dq_type == type)
159 break;
160 return dquot;
163 /* Add a dquot to the head of the free list */
164 static inline void put_dquot_head(struct dquot *dquot)
166 list_add(&dquot->dq_free, &free_dquots);
167 nr_free_dquots++;
170 /* Add a dquot to the tail of the free list */
171 static inline void put_dquot_last(struct dquot *dquot)
173 list_add(&dquot->dq_free, free_dquots.prev);
174 nr_free_dquots++;
177 static inline void remove_free_dquot(struct dquot *dquot)
179 /* sanity check */
180 if (list_empty(&dquot->dq_free)) {
181 printk("remove_free_dquot: dquot not on the free list??\n");
182 return; /* J.K. Just don't do anything */
184 list_del(&dquot->dq_free);
185 INIT_LIST_HEAD(&dquot->dq_free);
186 nr_free_dquots--;
189 static inline void put_inuse(struct dquot *dquot)
191 if ((dquot->dq_next = inuse_list) != NULL)
192 inuse_list->dq_pprev = &dquot->dq_next;
193 inuse_list = dquot;
194 dquot->dq_pprev = &inuse_list;
197 #if 0 /* currently not needed */
198 static inline void remove_inuse(struct dquot *dquot)
200 if (dquot->dq_pprev) {
201 if (dquot->dq_next)
202 dquot->dq_next->dq_pprev = dquot->dq_pprev;
203 *dquot->dq_pprev = dquot->dq_next;
204 dquot->dq_pprev = NULL;
207 #endif
209 static void __wait_on_dquot(struct dquot *dquot)
211 DECLARE_WAITQUEUE(wait, current);
213 add_wait_queue(&dquot->dq_wait, &wait);
214 repeat:
215 set_current_state(TASK_UNINTERRUPTIBLE);
216 if (dquot->dq_flags & DQ_LOCKED) {
217 schedule();
218 goto repeat;
220 remove_wait_queue(&dquot->dq_wait, &wait);
221 current->state = TASK_RUNNING;
224 static inline void wait_on_dquot(struct dquot *dquot)
226 if (dquot->dq_flags & DQ_LOCKED)
227 __wait_on_dquot(dquot);
230 static inline void lock_dquot(struct dquot *dquot)
232 wait_on_dquot(dquot);
233 dquot->dq_flags |= DQ_LOCKED;
236 static inline void unlock_dquot(struct dquot *dquot)
238 dquot->dq_flags &= ~DQ_LOCKED;
239 wake_up(&dquot->dq_wait);
243 * We don't have to be afraid of deadlocks as we never have quotas on quota files...
245 static void write_dquot(struct dquot *dquot)
247 short type = dquot->dq_type;
248 struct file *filp;
249 mm_segment_t fs;
250 loff_t offset;
251 ssize_t ret;
252 struct semaphore *sem = &dquot->dq_sb->s_dquot.dqio_sem;
254 lock_dquot(dquot);
255 if (!dquot->dq_sb) { /* Invalidated quota? */
256 unlock_dquot(dquot);
257 return;
259 down(sem);
260 filp = dquot->dq_sb->s_dquot.files[type];
261 offset = dqoff(dquot->dq_id);
262 fs = get_fs();
263 set_fs(KERNEL_DS);
266 * Note: clear the DQ_MOD flag unconditionally,
267 * so we don't loop forever on failure.
269 dquot->dq_flags &= ~DQ_MOD;
270 ret = 0;
271 if (filp)
272 ret = filp->f_op->write(filp, (char *)&dquot->dq_dqb,
273 sizeof(struct dqblk), &offset);
274 if (ret != sizeof(struct dqblk))
275 printk(KERN_WARNING "VFS: dquota write failed on dev %s\n",
276 kdevname(dquot->dq_dev));
278 set_fs(fs);
279 up(sem);
280 unlock_dquot(dquot);
282 dqstats.writes++;
285 static void read_dquot(struct dquot *dquot)
287 short type = dquot->dq_type;
288 struct file *filp;
289 mm_segment_t fs;
290 loff_t offset;
292 filp = dquot->dq_sb->s_dquot.files[type];
293 if (filp == (struct file *)NULL)
294 return;
296 lock_dquot(dquot);
297 if (!dquot->dq_sb) /* Invalidated quota? */
298 goto out_lock;
299 /* Now we are sure filp is valid - the dquot isn't invalidated */
300 down(&dquot->dq_sb->s_dquot.dqio_sem);
301 offset = dqoff(dquot->dq_id);
302 fs = get_fs();
303 set_fs(KERNEL_DS);
304 filp->f_op->read(filp, (char *)&dquot->dq_dqb, sizeof(struct dqblk), &offset);
305 up(&dquot->dq_sb->s_dquot.dqio_sem);
306 set_fs(fs);
308 if (dquot->dq_bhardlimit == 0 && dquot->dq_bsoftlimit == 0 &&
309 dquot->dq_ihardlimit == 0 && dquot->dq_isoftlimit == 0)
310 dquot->dq_flags |= DQ_FAKE;
311 dqstats.reads++;
312 out_lock:
313 unlock_dquot(dquot);
317 * Unhash and selectively clear the dquot structure,
318 * but preserve the use count, list pointers, and
319 * wait queue.
321 void clear_dquot(struct dquot *dquot)
323 /* unhash it first */
324 unhash_dquot(dquot);
325 dquot->dq_sb = NULL;
326 dquot->dq_flags = 0;
327 dquot->dq_referenced = 0;
328 memset(&dquot->dq_dqb, 0, sizeof(struct dqblk));
331 void invalidate_dquots(kdev_t dev, short type)
333 struct dquot *dquot, *next;
334 int need_restart;
336 restart:
337 next = inuse_list; /* Here it is better. Otherwise the restart doesn't have any sense ;-) */
338 need_restart = 0;
339 while ((dquot = next) != NULL) {
340 next = dquot->dq_next;
341 if (dquot->dq_dev != dev)
342 continue;
343 if (dquot->dq_type != type)
344 continue;
345 if (!dquot->dq_sb) /* Already invalidated entry? */
346 continue;
347 if (dquot->dq_flags & DQ_LOCKED) {
348 __wait_on_dquot(dquot);
350 /* Set the flag for another pass. */
351 need_restart = 1;
353 * Make sure it's still the same dquot.
355 if (dquot->dq_dev != dev)
356 continue;
357 if (dquot->dq_type != type)
358 continue;
359 if (!dquot->dq_sb)
360 continue;
363 * Because inodes needn't to be the only holders of dquot
364 * the quota needn't to be written to disk. So we write it
365 * ourselves before discarding the data just for sure...
367 if (dquot->dq_flags & DQ_MOD && dquot->dq_sb)
369 write_dquot(dquot);
370 need_restart = 1; /* We slept on IO */
372 clear_dquot(dquot);
375 * If anything blocked, restart the operation
376 * to ensure we don't miss any dquots.
378 if (need_restart)
379 goto restart;
382 int sync_dquots(kdev_t dev, short type)
384 struct dquot *dquot, *next, *ddquot;
385 int need_restart;
387 restart:
388 next = inuse_list;
389 need_restart = 0;
390 while ((dquot = next) != NULL) {
391 next = dquot->dq_next;
392 if (dev && dquot->dq_dev != dev)
393 continue;
394 if (type != -1 && dquot->dq_type != type)
395 continue;
396 if (!dquot->dq_sb) /* Invalidated? */
397 continue;
398 if (!(dquot->dq_flags & (DQ_LOCKED | DQ_MOD)))
399 continue;
401 if ((ddquot = dqduplicate(dquot)) == NODQUOT)
402 continue;
403 if (ddquot->dq_flags & DQ_MOD)
404 write_dquot(ddquot);
405 dqput(ddquot);
406 /* Set the flag for another pass. */
407 need_restart = 1;
410 * If anything blocked, restart the operation
411 * to ensure we don't miss any dquots.
413 if (need_restart)
414 goto restart;
416 dqstats.syncs++;
417 return(0);
420 /* NOTE: If you change this function please check whether dqput_blocks() works right... */
421 static void dqput(struct dquot *dquot)
423 if (!dquot)
424 return;
425 if (!dquot->dq_count) {
426 printk("VFS: dqput: trying to free free dquot\n");
427 printk("VFS: device %s, dquot of %s %d\n",
428 kdevname(dquot->dq_dev), quotatypes[dquot->dq_type],
429 dquot->dq_id);
430 return;
434 * If the dq_sb pointer isn't initialized this entry needs no
435 * checking and doesn't need to be written. It's just an empty
436 * dquot that is put back on to the freelist.
438 if (dquot->dq_sb)
439 dqstats.drops++;
440 we_slept:
441 if (dquot->dq_count > 1) {
442 /* We have more than one user... We can simply decrement use count */
443 dquot->dq_count--;
444 return;
446 if (dquot->dq_flags & DQ_LOCKED) {
447 printk(KERN_ERR "VFS: Locked quota to be put on the free list.\n");
448 dquot->dq_flags &= ~DQ_LOCKED;
450 if (dquot->dq_sb && dquot->dq_flags & DQ_MOD) {
451 write_dquot(dquot);
452 goto we_slept;
455 /* sanity check */
456 if (!list_empty(&dquot->dq_free)) {
457 printk(KERN_ERR "dqput: dquot already on free list??\n");
458 dquot->dq_count--; /* J.K. Just decrementing use count seems safer... */
459 return;
461 dquot->dq_count--;
462 dquot->dq_flags &= ~DQ_MOD; /* Modified flag has no sense on free list */
463 /* Place at end of LRU free queue */
464 put_dquot_last(dquot);
465 wake_up(&dquot_wait);
468 static int grow_dquots(void)
470 struct dquot *dquot;
471 int cnt = 0;
473 while (cnt < 32) {
474 dquot = kmem_cache_alloc(dquot_cachep, SLAB_KERNEL);
475 if(!dquot)
476 return cnt;
478 nr_dquots++;
479 memset((caddr_t)dquot, 0, sizeof(struct dquot));
480 init_waitqueue_head(&dquot->dq_wait);
481 /* all dquots go on the inuse_list */
482 put_inuse(dquot);
483 put_dquot_head(dquot);
484 cnt++;
486 return cnt;
489 static struct dquot *find_best_candidate_weighted(void)
491 struct list_head *tmp = &free_dquots;
492 struct dquot *dquot, *best = NULL;
493 unsigned long myscore, bestscore = ~0U;
494 int limit = (nr_free_dquots > 128) ? nr_free_dquots >> 2 : 32;
496 while ((tmp = tmp->next) != &free_dquots && --limit) {
497 dquot = list_entry(tmp, struct dquot, dq_free);
498 /* This should never happen... */
499 if (dquot->dq_flags & (DQ_LOCKED | DQ_MOD))
500 continue;
501 myscore = dquot->dq_referenced;
502 if (myscore < bestscore) {
503 bestscore = myscore;
504 best = dquot;
507 return best;
510 static inline struct dquot *find_best_free(void)
512 struct list_head *tmp = &free_dquots;
513 struct dquot *dquot;
514 int limit = (nr_free_dquots > 1024) ? nr_free_dquots >> 5 : 32;
516 while ((tmp = tmp->next) != &free_dquots && --limit) {
517 dquot = list_entry(tmp, struct dquot, dq_free);
518 if (dquot->dq_referenced == 0)
519 return dquot;
521 return NULL;
524 struct dquot *get_empty_dquot(void)
526 struct dquot *dquot;
527 int shrink = 1; /* Number of times we should try to shrink dcache and icache */
529 repeat:
530 dquot = find_best_free();
531 if (!dquot)
532 goto pressure;
533 got_it:
534 /* Sanity checks */
535 if (dquot->dq_flags & DQ_LOCKED)
536 printk(KERN_ERR "VFS: Locked dquot on the free list\n");
537 if (dquot->dq_count != 0)
538 printk(KERN_ERR "VFS: free dquot count=%d\n", dquot->dq_count);
540 remove_free_dquot(dquot);
541 dquot->dq_count = 1;
542 /* unhash and selectively clear the structure */
543 clear_dquot(dquot);
544 return dquot;
546 pressure:
547 if (nr_dquots < max_dquots)
548 if (grow_dquots())
549 goto repeat;
551 dquot = find_best_candidate_weighted();
552 if (dquot)
553 goto got_it;
555 * Try pruning the dcache to free up some dquots ...
557 if (shrink) {
558 printk(KERN_DEBUG "get_empty_dquot: pruning dcache and icache\n");
559 prune_dcache(128);
560 prune_icache(128);
561 shrink--;
562 goto repeat;
565 printk("VFS: No free dquots, contact mvw@planets.elm.net\n");
566 sleep_on(&dquot_wait);
567 goto repeat;
570 static struct dquot *dqget(struct super_block *sb, unsigned int id, short type)
572 unsigned int hashent = hashfn(sb->s_dev, id, type);
573 struct dquot *dquot, *empty = NULL;
574 struct quota_mount_options *dqopt = sb_dqopt(sb);
576 if (!is_enabled(dqopt, type))
577 return(NODQUOT);
579 we_slept:
580 if ((dquot = find_dquot(hashent, sb->s_dev, id, type)) == NULL) {
581 if (empty == NULL) {
582 dquot_updating[hashent]++;
583 empty = get_empty_dquot();
584 if (!--dquot_updating[hashent])
585 wake_up(&update_wait);
586 goto we_slept;
588 dquot = empty;
589 dquot->dq_id = id;
590 dquot->dq_type = type;
591 dquot->dq_dev = sb->s_dev;
592 dquot->dq_sb = sb;
593 /* hash it first so it can be found */
594 hash_dquot(dquot);
595 read_dquot(dquot);
596 } else {
597 if (!dquot->dq_count++) {
598 remove_free_dquot(dquot);
599 } else
600 dqstats.cache_hits++;
601 wait_on_dquot(dquot);
602 if (empty)
603 dqput(empty);
606 while (dquot_updating[hashent])
607 sleep_on(&update_wait);
609 if (!dquot->dq_sb) { /* Has somebody invalidated entry under us? */
611 * Do it as if the quota was invalidated before we started
613 dqput(dquot);
614 return NODQUOT;
616 dquot->dq_referenced++;
617 dqstats.lookups++;
619 return dquot;
622 static struct dquot *dqduplicate(struct dquot *dquot)
624 if (dquot == NODQUOT || !dquot->dq_sb)
625 return NODQUOT;
626 dquot->dq_count++;
627 wait_on_dquot(dquot);
628 if (!dquot->dq_sb) {
629 dquot->dq_count--;
630 return NODQUOT;
632 dquot->dq_referenced++;
633 dqstats.lookups++;
634 return dquot;
637 /* Check whether this inode is quota file */
638 static inline int is_quotafile(struct inode *inode)
640 int cnt;
641 struct quota_mount_options *dqopt = sb_dqopt(inode->i_sb);
642 struct file **files;
644 if (!dqopt)
645 return 0;
646 files = dqopt->files;
647 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
648 if (files[cnt] && files[cnt]->f_dentry->d_inode == inode)
649 return 1;
650 return 0;
653 static int dqinit_needed(struct inode *inode, short type)
655 int cnt;
657 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)))
658 return 0;
659 if (is_quotafile(inode))
660 return 0;
661 if (type != -1)
662 return inode->i_dquot[type] == NODQUOT;
663 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
664 if (inode->i_dquot[cnt] == NODQUOT)
665 return 1;
666 return 0;
669 static void add_dquot_ref(struct super_block *sb, short type)
671 struct list_head *p;
672 struct inode *inode;
674 if (!sb->dq_op)
675 return; /* nothing to do */
677 restart:
678 file_list_lock();
679 for (p = sb->s_files.next; p != &sb->s_files; p = p->next) {
680 struct file *filp = list_entry(p, struct file, f_list);
681 if (!filp->f_dentry)
682 continue;
683 inode = filp->f_dentry->d_inode;
684 if (!inode)
685 continue;
686 if (filp->f_mode & FMODE_WRITE && dqinit_needed(inode, type)) {
687 file_list_unlock();
688 sb->dq_op->initialize(inode, type);
689 inode->i_flags |= S_QUOTA;
690 /* As we may have blocked we had better restart... */
691 goto restart;
694 file_list_unlock();
697 /* Return 0 if dqput() won't block (note that 1 doesn't necessarily mean blocking) */
698 static inline int dqput_blocks(struct dquot *dquot)
700 if (dquot->dq_count == 1)
701 return 1;
702 return 0;
705 /* Remove references to dquots from inode - add dquot to list for freeing if needed */
706 int remove_inode_dquot_ref(struct inode *inode, short type, struct list_head *tofree_head)
708 struct dquot *dquot = inode->i_dquot[type];
709 int cnt;
711 inode->i_dquot[type] = NODQUOT;
712 /* any other quota in use? */
713 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
714 if (inode->i_dquot[cnt] != NODQUOT)
715 goto put_it;
717 inode->i_flags &= ~S_QUOTA;
718 put_it:
719 if (dquot != NODQUOT) {
720 if (dqput_blocks(dquot)) {
721 if (dquot->dq_count != 1)
722 printk(KERN_WARNING "VFS: Adding dquot with dq_count %d to dispose list.\n", dquot->dq_count);
723 list_add(&dquot->dq_free, tofree_head); /* As dquot must have currently users it can't be on the free list... */
724 return 1;
725 } else {
726 dqput(dquot); /* We have guaranteed we won't block */
729 return 0;
732 /* Free list of dquots - called from inode.c */
733 void put_dquot_list(struct list_head *tofree_head)
735 struct list_head *act_head = tofree_head;
736 struct dquot *dquot;
738 /* So now we have dquots on the list... Just free them */
739 while (act_head != tofree_head) {
740 dquot = list_entry(act_head, struct dquot, dq_free);
741 act_head = act_head->next;
742 list_del(&dquot->dq_free); /* Remove dquot from the list so we won't have problems... */
743 INIT_LIST_HEAD(&dquot->dq_free);
744 dqput(dquot);
748 static inline void dquot_incr_inodes(struct dquot *dquot, unsigned long number)
750 dquot->dq_curinodes += number;
751 dquot->dq_flags |= DQ_MOD;
754 static inline void dquot_incr_blocks(struct dquot *dquot, unsigned long number)
756 dquot->dq_curblocks += number;
757 dquot->dq_flags |= DQ_MOD;
760 static inline void dquot_decr_inodes(struct dquot *dquot, unsigned long number)
762 if (dquot->dq_curinodes > number)
763 dquot->dq_curinodes -= number;
764 else
765 dquot->dq_curinodes = 0;
766 if (dquot->dq_curinodes < dquot->dq_isoftlimit)
767 dquot->dq_itime = (time_t) 0;
768 dquot->dq_flags &= ~DQ_INODES;
769 dquot->dq_flags |= DQ_MOD;
772 static inline void dquot_decr_blocks(struct dquot *dquot, unsigned long number)
774 if (dquot->dq_curblocks > number)
775 dquot->dq_curblocks -= number;
776 else
777 dquot->dq_curblocks = 0;
778 if (dquot->dq_curblocks < dquot->dq_bsoftlimit)
779 dquot->dq_btime = (time_t) 0;
780 dquot->dq_flags &= ~DQ_BLKS;
781 dquot->dq_flags |= DQ_MOD;
784 static inline int need_print_warning(struct dquot *dquot, int flag)
786 switch (dquot->dq_type) {
787 case USRQUOTA:
788 return current->fsuid == dquot->dq_id && !(dquot->dq_flags & flag);
789 case GRPQUOTA:
790 return in_group_p(dquot->dq_id) && !(dquot->dq_flags & flag);
792 return 0;
795 static void print_warning(struct dquot *dquot, int flag, const char *fmtstr)
797 if (!need_print_warning(dquot, flag))
798 return;
799 sprintf(quotamessage, fmtstr,
800 bdevname(dquot->dq_sb->s_dev), quotatypes[dquot->dq_type]);
801 tty_write_message(current->tty, quotamessage);
802 dquot->dq_flags |= flag;
805 static inline char ignore_hardlimit(struct dquot *dquot)
807 return capable(CAP_SYS_RESOURCE) && !dquot->dq_sb->s_dquot.rsquash[dquot->dq_type];
810 static int check_idq(struct dquot *dquot, u_long inodes)
812 if (inodes <= 0 || dquot->dq_flags & DQ_FAKE)
813 return QUOTA_OK;
815 if (dquot->dq_ihardlimit &&
816 (dquot->dq_curinodes + inodes) > dquot->dq_ihardlimit &&
817 !ignore_hardlimit(dquot)) {
818 print_warning(dquot, DQ_INODES, "%s: write failed, %s file limit reached\n");
819 return NO_QUOTA;
822 if (dquot->dq_isoftlimit &&
823 (dquot->dq_curinodes + inodes) > dquot->dq_isoftlimit &&
824 dquot->dq_itime && CURRENT_TIME >= dquot->dq_itime &&
825 !ignore_hardlimit(dquot)) {
826 print_warning(dquot, DQ_INODES, "%s: warning, %s file quota exceeded too long.\n");
827 return NO_QUOTA;
830 if (dquot->dq_isoftlimit &&
831 (dquot->dq_curinodes + inodes) > dquot->dq_isoftlimit &&
832 dquot->dq_itime == 0) {
833 print_warning(dquot, 0, "%s: warning, %s file quota exceeded\n");
834 dquot->dq_itime = CURRENT_TIME + dquot->dq_sb->s_dquot.inode_expire[dquot->dq_type];
837 return QUOTA_OK;
840 static int check_bdq(struct dquot *dquot, u_long blocks, char prealloc)
842 if (blocks <= 0 || dquot->dq_flags & DQ_FAKE)
843 return QUOTA_OK;
845 if (dquot->dq_bhardlimit &&
846 (dquot->dq_curblocks + blocks) > dquot->dq_bhardlimit &&
847 !ignore_hardlimit(dquot)) {
848 if (!prealloc)
849 print_warning(dquot, DQ_BLKS, "%s: write failed, %s disk limit reached.\n");
850 return NO_QUOTA;
853 if (dquot->dq_bsoftlimit &&
854 (dquot->dq_curblocks + blocks) > dquot->dq_bsoftlimit &&
855 dquot->dq_btime && CURRENT_TIME >= dquot->dq_btime &&
856 !ignore_hardlimit(dquot)) {
857 if (!prealloc)
858 print_warning(dquot, DQ_BLKS, "%s: write failed, %s disk quota exceeded too long.\n");
859 return NO_QUOTA;
862 if (dquot->dq_bsoftlimit &&
863 (dquot->dq_curblocks + blocks) > dquot->dq_bsoftlimit &&
864 dquot->dq_btime == 0) {
865 if (!prealloc) {
866 print_warning(dquot, 0, "%s: warning, %s disk quota exceeded\n");
867 dquot->dq_btime = CURRENT_TIME + dquot->dq_sb->s_dquot.block_expire[dquot->dq_type];
869 else
871 * We don't allow preallocation to exceed softlimit so exceeding will
872 * be always printed
874 return NO_QUOTA;
877 return QUOTA_OK;
881 * Initialize a dquot-struct with new quota info. This is used by the
882 * system call interface functions.
884 static int set_dqblk(struct super_block *sb, int id, short type, int flags, struct dqblk *dqblk)
886 struct dquot *dquot;
887 int error = -EFAULT;
888 struct dqblk dq_dqblk;
890 if (dqblk == (struct dqblk *)NULL)
891 return error;
893 if (flags & QUOTA_SYSCALL) {
894 if (copy_from_user(&dq_dqblk, dqblk, sizeof(struct dqblk)))
895 return(error);
896 } else
897 memcpy((caddr_t)&dq_dqblk, (caddr_t)dqblk, sizeof(struct dqblk));
899 if (sb && (dquot = dqget(sb, id, type)) != NODQUOT) {
900 lock_dquot(dquot);
902 if (id > 0 && ((flags & SET_QUOTA) || (flags & SET_QLIMIT))) {
903 dquot->dq_bhardlimit = dq_dqblk.dqb_bhardlimit;
904 dquot->dq_bsoftlimit = dq_dqblk.dqb_bsoftlimit;
905 dquot->dq_ihardlimit = dq_dqblk.dqb_ihardlimit;
906 dquot->dq_isoftlimit = dq_dqblk.dqb_isoftlimit;
909 if ((flags & SET_QUOTA) || (flags & SET_USE)) {
910 if (dquot->dq_isoftlimit &&
911 dquot->dq_curinodes < dquot->dq_isoftlimit &&
912 dq_dqblk.dqb_curinodes >= dquot->dq_isoftlimit)
913 dquot->dq_itime = CURRENT_TIME + dquot->dq_sb->s_dquot.inode_expire[type];
914 dquot->dq_curinodes = dq_dqblk.dqb_curinodes;
915 if (dquot->dq_curinodes < dquot->dq_isoftlimit)
916 dquot->dq_flags &= ~DQ_INODES;
917 if (dquot->dq_bsoftlimit &&
918 dquot->dq_curblocks < dquot->dq_bsoftlimit &&
919 dq_dqblk.dqb_curblocks >= dquot->dq_bsoftlimit)
920 dquot->dq_btime = CURRENT_TIME + dquot->dq_sb->s_dquot.block_expire[type];
921 dquot->dq_curblocks = dq_dqblk.dqb_curblocks;
922 if (dquot->dq_curblocks < dquot->dq_bsoftlimit)
923 dquot->dq_flags &= ~DQ_BLKS;
926 if (id == 0) {
927 dquot->dq_sb->s_dquot.block_expire[type] = dquot->dq_btime = dq_dqblk.dqb_btime;
928 dquot->dq_sb->s_dquot.inode_expire[type] = dquot->dq_itime = dq_dqblk.dqb_itime;
931 if (dq_dqblk.dqb_bhardlimit == 0 && dq_dqblk.dqb_bsoftlimit == 0 &&
932 dq_dqblk.dqb_ihardlimit == 0 && dq_dqblk.dqb_isoftlimit == 0)
933 dquot->dq_flags |= DQ_FAKE;
934 else
935 dquot->dq_flags &= ~DQ_FAKE;
937 dquot->dq_flags |= DQ_MOD;
938 unlock_dquot(dquot);
939 dqput(dquot);
941 return(0);
944 static int get_quota(struct super_block *sb, int id, short type, struct dqblk *dqblk)
946 struct dquot *dquot;
947 int error = -ESRCH;
949 if (!sb || !sb_has_quota_enabled(sb, type))
950 goto out;
951 dquot = dqget(sb, id, type);
952 if (dquot == NODQUOT)
953 goto out;
955 lock_dquot(dquot); /* We must protect against invalidating the quota */
956 error = -EFAULT;
957 if (dqblk && !copy_to_user(dqblk, &dquot->dq_dqb, sizeof(struct dqblk)))
958 error = 0;
959 unlock_dquot(dquot);
960 dqput(dquot);
961 out:
962 return error;
965 static int get_stats(caddr_t addr)
967 int error = -EFAULT;
968 struct dqstats stats;
970 dqstats.allocated_dquots = nr_dquots;
971 dqstats.free_dquots = nr_free_dquots;
973 /* make a copy, in case we page-fault in user space */
974 memcpy(&stats, &dqstats, sizeof(struct dqstats));
975 if (!copy_to_user(addr, &stats, sizeof(struct dqstats)))
976 error = 0;
977 return error;
980 static int quota_root_squash(struct super_block *sb, short type, int *addr)
982 int new_value, error;
984 if (!sb)
985 return(-ENODEV);
987 error = -EFAULT;
988 if (!copy_from_user(&new_value, addr, sizeof(int))) {
989 sb_dqopt(sb)->rsquash[type] = new_value;
990 error = 0;
992 return error;
996 * This is a simple algorithm that calculates the size of a file in blocks.
997 * This is only used on filesystems that do not have an i_blocks count.
999 static u_long isize_to_blocks(loff_t isize, size_t blksize_bits)
1001 u_long blocks;
1002 u_long indirect;
1004 if (!blksize_bits)
1005 blksize_bits = BLOCK_SIZE_BITS;
1006 blocks = (isize >> blksize_bits) + ((isize & ~((1 << blksize_bits)-1)) ? 1 : 0);
1007 if (blocks > 10) {
1008 indirect = ((blocks - 11) >> 8) + 1; /* single indirect blocks */
1009 if (blocks > (10 + 256)) {
1010 indirect += ((blocks - 267) >> 16) + 1; /* double indirect blocks */
1011 if (blocks > (10 + 256 + (256 << 8)))
1012 indirect++; /* triple indirect blocks */
1014 blocks += indirect;
1016 return blocks;
1020 * Externally referenced functions through dquot_operations in inode.
1022 * Note: this is a blocking operation.
1024 void dquot_initialize(struct inode *inode, short type)
1026 struct dquot *dquot;
1027 unsigned int id = 0;
1028 short cnt;
1030 if (S_ISREG(inode->i_mode) ||
1031 S_ISDIR(inode->i_mode) ||
1032 S_ISLNK(inode->i_mode)) {
1033 /* We don't want to have quotas on quota files - nasty deadlocks possible */
1034 if (is_quotafile(inode))
1035 return;
1036 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1037 if (type != -1 && cnt != type)
1038 continue;
1040 if (!sb_has_quota_enabled(inode->i_sb, cnt))
1041 continue;
1043 if (inode->i_dquot[cnt] == NODQUOT) {
1044 switch (cnt) {
1045 case USRQUOTA:
1046 id = inode->i_uid;
1047 break;
1048 case GRPQUOTA:
1049 id = inode->i_gid;
1050 break;
1052 dquot = dqget(inode->i_sb, id, cnt);
1053 if (dquot == NODQUOT)
1054 continue;
1055 if (inode->i_dquot[cnt] != NODQUOT) {
1056 dqput(dquot);
1057 continue;
1059 inode->i_dquot[cnt] = dquot;
1060 inode->i_flags |= S_QUOTA;
1067 * Release all quota for the specified inode.
1069 * Note: this is a blocking operation.
1071 void dquot_drop(struct inode *inode)
1073 struct dquot *dquot;
1074 short cnt;
1076 inode->i_flags &= ~S_QUOTA;
1077 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1078 if (inode->i_dquot[cnt] == NODQUOT)
1079 continue;
1080 dquot = inode->i_dquot[cnt];
1081 inode->i_dquot[cnt] = NODQUOT;
1082 dqput(dquot);
1087 * Note: this is a blocking operation.
1089 int dquot_alloc_block(const struct inode *inode, unsigned long number, char warn)
1091 int cnt;
1092 struct dquot *dquot[MAXQUOTAS];
1094 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1095 dquot[cnt] = dqduplicate(inode->i_dquot[cnt]);
1096 if (dquot[cnt] == NODQUOT)
1097 continue;
1098 lock_dquot(dquot[cnt]);
1099 if (check_bdq(dquot[cnt], number, warn))
1100 goto put_all;
1103 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1104 if (dquot[cnt] == NODQUOT)
1105 continue;
1106 dquot_incr_blocks(dquot[cnt], number);
1107 unlock_dquot(dquot[cnt]);
1108 dqput(dquot[cnt]);
1111 return QUOTA_OK;
1112 put_all:
1113 for (; cnt >= 0; cnt--) {
1114 if (dquot[cnt] == NODQUOT)
1115 continue;
1116 unlock_dquot(dquot[cnt]);
1117 dqput(dquot[cnt]);
1119 return NO_QUOTA;
1123 * Note: this is a blocking operation.
1125 int dquot_alloc_inode(const struct inode *inode, unsigned long number)
1127 int cnt;
1128 struct dquot *dquot[MAXQUOTAS];
1130 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1131 dquot[cnt] = dqduplicate(inode -> i_dquot[cnt]);
1132 if (dquot[cnt] == NODQUOT)
1133 continue;
1134 lock_dquot(dquot[cnt]);
1135 if (check_idq(dquot[cnt], number))
1136 goto put_all;
1139 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1140 if (dquot[cnt] == NODQUOT)
1141 continue;
1142 dquot_incr_inodes(dquot[cnt], number);
1143 unlock_dquot(dquot[cnt]);
1144 dqput(dquot[cnt]);
1147 return QUOTA_OK;
1148 put_all:
1149 for (; cnt >= 0; cnt--) {
1150 if (dquot[cnt] == NODQUOT)
1151 continue;
1152 unlock_dquot(dquot[cnt]);
1153 dqput(dquot[cnt]);
1155 return NO_QUOTA;
1159 * Note: this is a blocking operation.
1161 void dquot_free_block(const struct inode *inode, unsigned long number)
1163 unsigned short cnt;
1164 struct dquot *dquot;
1166 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1167 dquot = inode->i_dquot[cnt];
1168 if (dquot == NODQUOT)
1169 continue;
1170 wait_on_dquot(dquot);
1171 dquot_decr_blocks(dquot, number);
1176 * Note: this is a blocking operation.
1178 void dquot_free_inode(const struct inode *inode, unsigned long number)
1180 unsigned short cnt;
1181 struct dquot *dquot;
1183 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1184 dquot = inode->i_dquot[cnt];
1185 if (dquot == NODQUOT)
1186 continue;
1187 wait_on_dquot(dquot);
1188 dquot_decr_inodes(dquot, number);
1193 * Transfer the number of inode and blocks from one diskquota to an other.
1195 * Note: this is a blocking operation.
1197 int dquot_transfer(struct dentry *dentry, struct iattr *iattr)
1199 struct inode *inode = dentry -> d_inode;
1200 unsigned long blocks;
1201 struct dquot *transfer_from[MAXQUOTAS];
1202 struct dquot *transfer_to[MAXQUOTAS];
1203 short cnt, disc;
1204 int error = -EDQUOT;
1206 if (!inode)
1207 return -ENOENT;
1208 /* Arguably we could consider that as error, but... no fs - no quota */
1209 if (!inode->i_sb)
1210 return 0;
1212 * Find out if this filesystem uses i_blocks.
1214 if (!inode->i_sb->s_blocksize)
1215 blocks = isize_to_blocks(inode->i_size, BLOCK_SIZE_BITS);
1216 else
1217 blocks = (inode->i_blocks >> 1);
1220 * Build the transfer_from and transfer_to lists and check quotas to see
1221 * if operation is permitted.
1223 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1224 transfer_from[cnt] = NODQUOT;
1225 transfer_to[cnt] = NODQUOT;
1227 if (!sb_has_quota_enabled(inode->i_sb, cnt))
1228 continue;
1230 switch (cnt) {
1231 case USRQUOTA:
1232 if (inode->i_uid == iattr->ia_uid)
1233 continue;
1234 /* We can get transfer_from from inode, can't we? */
1235 transfer_from[cnt] = dqget(inode->i_sb, inode->i_uid, cnt);
1236 transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_uid, cnt);
1237 break;
1238 case GRPQUOTA:
1239 if (inode->i_gid == iattr->ia_gid)
1240 continue;
1241 transfer_from[cnt] = dqget(inode->i_sb, inode->i_gid, cnt);
1242 transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_gid, cnt);
1243 break;
1246 /* Something bad (eg. quotaoff) happened while we were sleeping? */
1247 if (transfer_from[cnt] == NODQUOT || transfer_to[cnt] == NODQUOT)
1249 if (transfer_from[cnt] != NODQUOT) {
1250 dqput(transfer_from[cnt]);
1251 transfer_from[cnt] = NODQUOT;
1253 if (transfer_to[cnt] != NODQUOT) {
1254 dqput(transfer_to[cnt]);
1255 transfer_to[cnt] = NODQUOT;
1257 continue;
1260 * We have to lock the quotas to prevent races...
1262 if (transfer_from[cnt] < transfer_to[cnt])
1264 lock_dquot(transfer_from[cnt]);
1265 lock_dquot(transfer_to[cnt]);
1267 else
1269 lock_dquot(transfer_to[cnt]);
1270 lock_dquot(transfer_from[cnt]);
1274 * The entries might got invalidated while locking. The second
1275 * dqget() could block and so the first structure might got
1276 * invalidated or locked...
1278 if (!transfer_to[cnt]->dq_sb || !transfer_from[cnt]->dq_sb ||
1279 check_idq(transfer_to[cnt], 1) == NO_QUOTA ||
1280 check_bdq(transfer_to[cnt], blocks, 0) == NO_QUOTA) {
1281 cnt++;
1282 goto put_all;
1286 if ((error = notify_change(dentry, iattr)))
1287 goto put_all;
1289 * Finally perform the needed transfer from transfer_from to transfer_to,
1290 * and release any pointers to dquots not needed anymore.
1292 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1294 * Skip changes for same uid or gid or for non-existing quota-type.
1296 if (transfer_from[cnt] == NODQUOT && transfer_to[cnt] == NODQUOT)
1297 continue;
1299 dquot_decr_inodes(transfer_from[cnt], 1);
1300 dquot_decr_blocks(transfer_from[cnt], blocks);
1302 dquot_incr_inodes(transfer_to[cnt], 1);
1303 dquot_incr_blocks(transfer_to[cnt], blocks);
1305 unlock_dquot(transfer_from[cnt]);
1306 dqput(transfer_from[cnt]);
1307 if (inode->i_dquot[cnt] != NODQUOT) {
1308 struct dquot *temp = inode->i_dquot[cnt];
1309 inode->i_dquot[cnt] = transfer_to[cnt];
1310 unlock_dquot(transfer_to[cnt]);
1311 dqput(temp);
1312 } else {
1313 unlock_dquot(transfer_to[cnt]);
1314 dqput(transfer_to[cnt]);
1318 return 0;
1319 put_all:
1320 for (disc = 0; disc < cnt; disc++) {
1321 /* There should be none or both pointers set but... */
1322 if (transfer_to[disc] != NODQUOT) {
1323 unlock_dquot(transfer_to[disc]);
1324 dqput(transfer_to[disc]);
1326 if (transfer_from[disc] != NODQUOT) {
1327 unlock_dquot(transfer_from[disc]);
1328 dqput(transfer_from[disc]);
1331 return error;
1335 void __init dquot_init_hash(void)
1337 printk(KERN_NOTICE "VFS: Diskquotas version %s initialized\n", __DQUOT_VERSION__);
1339 dquot_cachep = kmem_cache_create("dquot", sizeof(struct dquot),
1340 sizeof(unsigned long) * 4,
1341 SLAB_HWCACHE_ALIGN, NULL, NULL);
1343 if (!dquot_cachep)
1344 panic("Cannot create dquot SLAB cache\n");
1346 memset(dquot_hash, 0, sizeof(dquot_hash));
1347 memset((caddr_t)&dqstats, 0, sizeof(dqstats));
1351 * Definitions of diskquota operations.
1353 struct dquot_operations dquot_operations = {
1354 dquot_initialize, /* mandatory */
1355 dquot_drop, /* mandatory */
1356 dquot_alloc_block,
1357 dquot_alloc_inode,
1358 dquot_free_block,
1359 dquot_free_inode,
1360 dquot_transfer
1363 static inline void set_enable_flags(struct quota_mount_options *dqopt, short type)
1365 switch (type) {
1366 case USRQUOTA:
1367 dqopt->flags |= DQUOT_USR_ENABLED;
1368 break;
1369 case GRPQUOTA:
1370 dqopt->flags |= DQUOT_GRP_ENABLED;
1371 break;
1375 static inline void reset_enable_flags(struct quota_mount_options *dqopt, short type)
1377 switch (type) {
1378 case USRQUOTA:
1379 dqopt->flags &= ~DQUOT_USR_ENABLED;
1380 break;
1381 case GRPQUOTA:
1382 dqopt->flags &= ~DQUOT_GRP_ENABLED;
1383 break;
1387 /* Function in inode.c - remove pointers to dquots in icache */
1388 extern void remove_dquot_ref(kdev_t, short);
1391 * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount)
1393 int quota_off(struct super_block *sb, short type)
1395 struct file *filp;
1396 short cnt;
1397 int enabled = 0;
1398 struct quota_mount_options *dqopt = sb_dqopt(sb);
1400 if (!sb)
1401 goto out;
1403 /* We need to serialize quota_off() for device */
1404 down(&dqopt->dqoff_sem);
1405 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1406 if (type != -1 && cnt != type)
1407 continue;
1408 if (!is_enabled(dqopt, cnt))
1409 continue;
1410 reset_enable_flags(dqopt, cnt);
1412 /* Note: these are blocking operations */
1413 remove_dquot_ref(sb->s_dev, cnt);
1414 invalidate_dquots(sb->s_dev, cnt);
1416 /* Wait for any pending IO - remove me as soon as invalidate is more polite */
1417 down(&dqopt->dqio_sem);
1418 filp = dqopt->files[cnt];
1419 dqopt->files[cnt] = (struct file *)NULL;
1420 dqopt->inode_expire[cnt] = 0;
1421 dqopt->block_expire[cnt] = 0;
1422 up(&dqopt->dqio_sem);
1423 fput(filp);
1427 * Check whether any quota is still enabled,
1428 * and if not clear the dq_op pointer.
1430 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
1431 enabled |= is_enabled(dqopt, cnt);
1432 if (!enabled)
1433 sb->dq_op = NULL;
1434 up(&dqopt->dqoff_sem);
1435 out:
1436 return(0);
1439 static inline int check_quotafile_size(loff_t size)
1441 ulong blocks = size >> BLOCK_SIZE_BITS;
1442 size_t off = size & (BLOCK_SIZE - 1);
1444 return !(((blocks % sizeof(struct dqblk)) * BLOCK_SIZE + off % sizeof(struct dqblk)) % sizeof(struct dqblk));
1447 static int quota_on(struct super_block *sb, short type, char *path)
1449 struct file *f;
1450 struct inode *inode;
1451 struct dquot *dquot;
1452 struct quota_mount_options *dqopt = sb_dqopt(sb);
1453 char *tmp;
1454 int error;
1456 if (is_enabled(dqopt, type))
1457 return -EBUSY;
1459 down(&dqopt->dqoff_sem);
1460 tmp = getname(path);
1461 error = PTR_ERR(tmp);
1462 if (IS_ERR(tmp))
1463 goto out_lock;
1465 f = filp_open(tmp, O_RDWR, 0600);
1466 putname(tmp);
1468 error = PTR_ERR(f);
1469 if (IS_ERR(f))
1470 goto out_lock;
1471 error = -EIO;
1472 if (!f->f_op->read && !f->f_op->write)
1473 goto out_f;
1474 inode = f->f_dentry->d_inode;
1475 error = -EACCES;
1476 if (!S_ISREG(inode->i_mode))
1477 goto out_f;
1478 error = -EINVAL;
1479 if (inode->i_size == 0 || !check_quotafile_size(inode->i_size))
1480 goto out_f;
1481 dquot_drop(inode); /* We don't want quota on quota files */
1483 set_enable_flags(dqopt, type);
1484 dqopt->files[type] = f;
1486 dquot = dqget(sb, 0, type);
1487 dqopt->inode_expire[type] = (dquot != NODQUOT) ? dquot->dq_itime : MAX_IQ_TIME;
1488 dqopt->block_expire[type] = (dquot != NODQUOT) ? dquot->dq_btime : MAX_DQ_TIME;
1489 dqput(dquot);
1491 sb->dq_op = &dquot_operations;
1492 add_dquot_ref(sb, type);
1494 up(&dqopt->dqoff_sem);
1495 return 0;
1497 out_f:
1498 filp_close(f, NULL);
1499 out_lock:
1500 up(&dqopt->dqoff_sem);
1502 return error;
1506 * This is the system call interface. This communicates with
1507 * the user-level programs. Currently this only supports diskquota
1508 * calls. Maybe we need to add the process quotas etc. in the future,
1509 * but we probably should use rlimits for that.
1511 asmlinkage long sys_quotactl(int cmd, const char *special, int id, caddr_t addr)
1513 int cmds = 0, type = 0, flags = 0;
1514 kdev_t dev;
1515 struct super_block *sb = NULL;
1516 int ret = -EINVAL;
1518 lock_kernel();
1519 cmds = cmd >> SUBCMDSHIFT;
1520 type = cmd & SUBCMDMASK;
1522 if ((u_int) type >= MAXQUOTAS)
1523 goto out;
1524 if (id & ~0xFFFF)
1525 goto out;
1527 ret = -EPERM;
1528 switch (cmds) {
1529 case Q_SYNC:
1530 case Q_GETSTATS:
1531 break;
1532 case Q_GETQUOTA:
1533 if (((type == USRQUOTA && current->euid != id) ||
1534 (type == GRPQUOTA && in_egroup_p(id))) &&
1535 !capable(CAP_SYS_RESOURCE))
1536 goto out;
1537 break;
1538 default:
1539 if (!capable(CAP_SYS_RESOURCE))
1540 goto out;
1543 ret = -EINVAL;
1544 dev = NODEV;
1545 if (special != NULL || (cmds != Q_SYNC && cmds != Q_GETSTATS)) {
1546 mode_t mode;
1547 struct nameidata nd;
1549 ret = user_path_walk(special, &nd);
1550 if (ret)
1551 goto out;
1553 dev = nd.dentry->d_inode->i_rdev;
1554 mode = nd.dentry->d_inode->i_mode;
1555 path_release(&nd);
1557 ret = -ENOTBLK;
1558 if (!S_ISBLK(mode))
1559 goto out;
1560 sb = get_super(dev);
1563 ret = -EINVAL;
1564 switch (cmds) {
1565 case Q_QUOTAON:
1566 ret = sb ? quota_on(sb, type, (char *) addr) : -ENODEV;
1567 goto out;
1568 case Q_QUOTAOFF:
1569 ret = quota_off(sb, type);
1570 goto out;
1571 case Q_GETQUOTA:
1572 ret = get_quota(sb, id, type, (struct dqblk *) addr);
1573 goto out;
1574 case Q_SETQUOTA:
1575 flags |= SET_QUOTA;
1576 break;
1577 case Q_SETUSE:
1578 flags |= SET_USE;
1579 break;
1580 case Q_SETQLIM:
1581 flags |= SET_QLIMIT;
1582 break;
1583 case Q_SYNC:
1584 ret = sync_dquots(dev, type);
1585 goto out;
1586 case Q_GETSTATS:
1587 ret = get_stats(addr);
1588 goto out;
1589 case Q_RSQUASH:
1590 ret = quota_root_squash(sb, type, (int *) addr);
1591 goto out;
1592 default:
1593 goto out;
1596 flags |= QUOTA_SYSCALL;
1598 ret = -ESRCH;
1599 if (sb && sb_has_quota_enabled(sb, type))
1600 ret = set_dqblk(sb, id, type, flags, (struct dqblk *) addr);
1601 out:
1602 unlock_kernel();
1603 return ret;