Merge with Linux 2.4.0-test5-pre1. This works again on Origin UP.
[linux-2.6/linux-mips.git] / fs / dquot.c
blob022dd3423d1d610e3d97c2266b8dd90d0771fc61
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) && !S_ISDIR(inode->i_mode) &&
1031 !S_ISLNK(inode->i_mode))
1032 return;
1033 lock_kernel();
1034 /* We don't want to have quotas on quota files - nasty deadlocks possible */
1035 if (is_quotafile(inode)) {
1036 unlock_kernel();
1037 return;
1039 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1040 if (type != -1 && cnt != type)
1041 continue;
1043 if (!sb_has_quota_enabled(inode->i_sb, cnt))
1044 continue;
1046 if (inode->i_dquot[cnt] == NODQUOT) {
1047 switch (cnt) {
1048 case USRQUOTA:
1049 id = inode->i_uid;
1050 break;
1051 case GRPQUOTA:
1052 id = inode->i_gid;
1053 break;
1055 dquot = dqget(inode->i_sb, id, cnt);
1056 if (dquot == NODQUOT)
1057 continue;
1058 if (inode->i_dquot[cnt] != NODQUOT) {
1059 dqput(dquot);
1060 continue;
1062 inode->i_dquot[cnt] = dquot;
1063 inode->i_flags |= S_QUOTA;
1066 unlock_kernel();
1070 * Release all quota for the specified inode.
1072 * Note: this is a blocking operation.
1074 void dquot_drop(struct inode *inode)
1076 struct dquot *dquot;
1077 short cnt;
1079 lock_kernel();
1080 inode->i_flags &= ~S_QUOTA;
1081 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1082 if (inode->i_dquot[cnt] == NODQUOT)
1083 continue;
1084 dquot = inode->i_dquot[cnt];
1085 inode->i_dquot[cnt] = NODQUOT;
1086 dqput(dquot);
1088 unlock_kernel();
1092 * Note: this is a blocking operation.
1094 int dquot_alloc_block(const struct inode *inode, unsigned long number, char warn)
1096 int cnt;
1097 struct dquot *dquot[MAXQUOTAS];
1099 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1100 dquot[cnt] = dqduplicate(inode->i_dquot[cnt]);
1101 if (dquot[cnt] == NODQUOT)
1102 continue;
1103 lock_dquot(dquot[cnt]);
1104 if (check_bdq(dquot[cnt], number, warn))
1105 goto put_all;
1108 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1109 if (dquot[cnt] == NODQUOT)
1110 continue;
1111 dquot_incr_blocks(dquot[cnt], number);
1112 unlock_dquot(dquot[cnt]);
1113 dqput(dquot[cnt]);
1116 return QUOTA_OK;
1117 put_all:
1118 for (; cnt >= 0; cnt--) {
1119 if (dquot[cnt] == NODQUOT)
1120 continue;
1121 unlock_dquot(dquot[cnt]);
1122 dqput(dquot[cnt]);
1124 return NO_QUOTA;
1128 * Note: this is a blocking operation.
1130 int dquot_alloc_inode(const struct inode *inode, unsigned long number)
1132 int cnt;
1133 struct dquot *dquot[MAXQUOTAS];
1135 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1136 dquot[cnt] = dqduplicate(inode -> i_dquot[cnt]);
1137 if (dquot[cnt] == NODQUOT)
1138 continue;
1139 lock_dquot(dquot[cnt]);
1140 if (check_idq(dquot[cnt], number))
1141 goto put_all;
1144 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1145 if (dquot[cnt] == NODQUOT)
1146 continue;
1147 dquot_incr_inodes(dquot[cnt], number);
1148 unlock_dquot(dquot[cnt]);
1149 dqput(dquot[cnt]);
1152 return QUOTA_OK;
1153 put_all:
1154 for (; cnt >= 0; cnt--) {
1155 if (dquot[cnt] == NODQUOT)
1156 continue;
1157 unlock_dquot(dquot[cnt]);
1158 dqput(dquot[cnt]);
1160 return NO_QUOTA;
1164 * Note: this is a blocking operation.
1166 void dquot_free_block(const struct inode *inode, unsigned long number)
1168 unsigned short cnt;
1169 struct dquot *dquot;
1171 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1172 dquot = inode->i_dquot[cnt];
1173 if (dquot == NODQUOT)
1174 continue;
1175 wait_on_dquot(dquot);
1176 dquot_decr_blocks(dquot, number);
1181 * Note: this is a blocking operation.
1183 void dquot_free_inode(const struct inode *inode, unsigned long number)
1185 unsigned short cnt;
1186 struct dquot *dquot;
1188 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1189 dquot = inode->i_dquot[cnt];
1190 if (dquot == NODQUOT)
1191 continue;
1192 wait_on_dquot(dquot);
1193 dquot_decr_inodes(dquot, number);
1198 * Transfer the number of inode and blocks from one diskquota to an other.
1200 * Note: this is a blocking operation.
1202 int dquot_transfer(struct dentry *dentry, struct iattr *iattr)
1204 struct inode *inode = dentry -> d_inode;
1205 unsigned long blocks;
1206 struct dquot *transfer_from[MAXQUOTAS];
1207 struct dquot *transfer_to[MAXQUOTAS];
1208 short cnt, disc;
1209 int error = -EDQUOT;
1211 if (!inode)
1212 return -ENOENT;
1213 /* Arguably we could consider that as error, but... no fs - no quota */
1214 if (!inode->i_sb)
1215 return 0;
1217 lock_kernel();
1219 * Find out if this filesystem uses i_blocks.
1221 if (!inode->i_sb->s_blocksize)
1222 blocks = isize_to_blocks(inode->i_size, BLOCK_SIZE_BITS);
1223 else
1224 blocks = (inode->i_blocks >> 1);
1227 * Build the transfer_from and transfer_to lists and check quotas to see
1228 * if operation is permitted.
1230 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1231 transfer_from[cnt] = NODQUOT;
1232 transfer_to[cnt] = NODQUOT;
1234 if (!sb_has_quota_enabled(inode->i_sb, cnt))
1235 continue;
1237 switch (cnt) {
1238 case USRQUOTA:
1239 if (inode->i_uid == iattr->ia_uid)
1240 continue;
1241 /* We can get transfer_from from inode, can't we? */
1242 transfer_from[cnt] = dqget(inode->i_sb, inode->i_uid, cnt);
1243 transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_uid, cnt);
1244 break;
1245 case GRPQUOTA:
1246 if (inode->i_gid == iattr->ia_gid)
1247 continue;
1248 transfer_from[cnt] = dqget(inode->i_sb, inode->i_gid, cnt);
1249 transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_gid, cnt);
1250 break;
1253 /* Something bad (eg. quotaoff) happened while we were sleeping? */
1254 if (transfer_from[cnt] == NODQUOT || transfer_to[cnt] == NODQUOT)
1256 if (transfer_from[cnt] != NODQUOT) {
1257 dqput(transfer_from[cnt]);
1258 transfer_from[cnt] = NODQUOT;
1260 if (transfer_to[cnt] != NODQUOT) {
1261 dqput(transfer_to[cnt]);
1262 transfer_to[cnt] = NODQUOT;
1264 continue;
1267 * We have to lock the quotas to prevent races...
1269 if (transfer_from[cnt] < transfer_to[cnt])
1271 lock_dquot(transfer_from[cnt]);
1272 lock_dquot(transfer_to[cnt]);
1274 else
1276 lock_dquot(transfer_to[cnt]);
1277 lock_dquot(transfer_from[cnt]);
1281 * The entries might got invalidated while locking. The second
1282 * dqget() could block and so the first structure might got
1283 * invalidated or locked...
1285 if (!transfer_to[cnt]->dq_sb || !transfer_from[cnt]->dq_sb ||
1286 check_idq(transfer_to[cnt], 1) == NO_QUOTA ||
1287 check_bdq(transfer_to[cnt], blocks, 0) == NO_QUOTA) {
1288 cnt++;
1289 goto put_all;
1293 if ((error = notify_change(dentry, iattr)))
1294 goto put_all;
1296 * Finally perform the needed transfer from transfer_from to transfer_to,
1297 * and release any pointers to dquots not needed anymore.
1299 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1301 * Skip changes for same uid or gid or for non-existing quota-type.
1303 if (transfer_from[cnt] == NODQUOT && transfer_to[cnt] == NODQUOT)
1304 continue;
1306 dquot_decr_inodes(transfer_from[cnt], 1);
1307 dquot_decr_blocks(transfer_from[cnt], blocks);
1309 dquot_incr_inodes(transfer_to[cnt], 1);
1310 dquot_incr_blocks(transfer_to[cnt], blocks);
1312 unlock_dquot(transfer_from[cnt]);
1313 dqput(transfer_from[cnt]);
1314 if (inode->i_dquot[cnt] != NODQUOT) {
1315 struct dquot *temp = inode->i_dquot[cnt];
1316 inode->i_dquot[cnt] = transfer_to[cnt];
1317 unlock_dquot(transfer_to[cnt]);
1318 dqput(temp);
1319 } else {
1320 unlock_dquot(transfer_to[cnt]);
1321 dqput(transfer_to[cnt]);
1325 unlock_kernel();
1326 return 0;
1327 put_all:
1328 for (disc = 0; disc < cnt; disc++) {
1329 /* There should be none or both pointers set but... */
1330 if (transfer_to[disc] != NODQUOT) {
1331 unlock_dquot(transfer_to[disc]);
1332 dqput(transfer_to[disc]);
1334 if (transfer_from[disc] != NODQUOT) {
1335 unlock_dquot(transfer_from[disc]);
1336 dqput(transfer_from[disc]);
1339 unlock_kernel();
1340 return error;
1344 void __init dquot_init_hash(void)
1346 printk(KERN_NOTICE "VFS: Diskquotas version %s initialized\n", __DQUOT_VERSION__);
1348 dquot_cachep = kmem_cache_create("dquot", sizeof(struct dquot),
1349 sizeof(unsigned long) * 4,
1350 SLAB_HWCACHE_ALIGN, NULL, NULL);
1352 if (!dquot_cachep)
1353 panic("Cannot create dquot SLAB cache\n");
1355 memset(dquot_hash, 0, sizeof(dquot_hash));
1356 memset((caddr_t)&dqstats, 0, sizeof(dqstats));
1360 * Definitions of diskquota operations.
1362 struct dquot_operations dquot_operations = {
1363 dquot_initialize, /* mandatory */
1364 dquot_drop, /* mandatory */
1365 dquot_alloc_block,
1366 dquot_alloc_inode,
1367 dquot_free_block,
1368 dquot_free_inode,
1369 dquot_transfer
1372 static inline void set_enable_flags(struct quota_mount_options *dqopt, short type)
1374 switch (type) {
1375 case USRQUOTA:
1376 dqopt->flags |= DQUOT_USR_ENABLED;
1377 break;
1378 case GRPQUOTA:
1379 dqopt->flags |= DQUOT_GRP_ENABLED;
1380 break;
1384 static inline void reset_enable_flags(struct quota_mount_options *dqopt, short type)
1386 switch (type) {
1387 case USRQUOTA:
1388 dqopt->flags &= ~DQUOT_USR_ENABLED;
1389 break;
1390 case GRPQUOTA:
1391 dqopt->flags &= ~DQUOT_GRP_ENABLED;
1392 break;
1396 /* Function in inode.c - remove pointers to dquots in icache */
1397 extern void remove_dquot_ref(kdev_t, short);
1400 * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount)
1402 int quota_off(struct super_block *sb, short type)
1404 struct file *filp;
1405 short cnt;
1406 int enabled = 0;
1407 struct quota_mount_options *dqopt = sb_dqopt(sb);
1409 if (!sb)
1410 goto out;
1412 /* We need to serialize quota_off() for device */
1413 down(&dqopt->dqoff_sem);
1414 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1415 if (type != -1 && cnt != type)
1416 continue;
1417 if (!is_enabled(dqopt, cnt))
1418 continue;
1419 reset_enable_flags(dqopt, cnt);
1421 /* Note: these are blocking operations */
1422 remove_dquot_ref(sb->s_dev, cnt);
1423 invalidate_dquots(sb->s_dev, cnt);
1425 /* Wait for any pending IO - remove me as soon as invalidate is more polite */
1426 down(&dqopt->dqio_sem);
1427 filp = dqopt->files[cnt];
1428 dqopt->files[cnt] = (struct file *)NULL;
1429 dqopt->inode_expire[cnt] = 0;
1430 dqopt->block_expire[cnt] = 0;
1431 up(&dqopt->dqio_sem);
1432 fput(filp);
1436 * Check whether any quota is still enabled,
1437 * and if not clear the dq_op pointer.
1439 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
1440 enabled |= is_enabled(dqopt, cnt);
1441 if (!enabled)
1442 sb->dq_op = NULL;
1443 up(&dqopt->dqoff_sem);
1444 out:
1445 return(0);
1448 static inline int check_quotafile_size(loff_t size)
1450 ulong blocks = size >> BLOCK_SIZE_BITS;
1451 size_t off = size & (BLOCK_SIZE - 1);
1453 return !(((blocks % sizeof(struct dqblk)) * BLOCK_SIZE + off % sizeof(struct dqblk)) % sizeof(struct dqblk));
1456 static int quota_on(struct super_block *sb, short type, char *path)
1458 struct file *f;
1459 struct inode *inode;
1460 struct dquot *dquot;
1461 struct quota_mount_options *dqopt = sb_dqopt(sb);
1462 char *tmp;
1463 int error;
1465 if (is_enabled(dqopt, type))
1466 return -EBUSY;
1468 down(&dqopt->dqoff_sem);
1469 tmp = getname(path);
1470 error = PTR_ERR(tmp);
1471 if (IS_ERR(tmp))
1472 goto out_lock;
1474 f = filp_open(tmp, O_RDWR, 0600);
1475 putname(tmp);
1477 error = PTR_ERR(f);
1478 if (IS_ERR(f))
1479 goto out_lock;
1480 error = -EIO;
1481 if (!f->f_op->read && !f->f_op->write)
1482 goto out_f;
1483 inode = f->f_dentry->d_inode;
1484 error = -EACCES;
1485 if (!S_ISREG(inode->i_mode))
1486 goto out_f;
1487 error = -EINVAL;
1488 if (inode->i_size == 0 || !check_quotafile_size(inode->i_size))
1489 goto out_f;
1490 dquot_drop(inode); /* We don't want quota on quota files */
1492 set_enable_flags(dqopt, type);
1493 dqopt->files[type] = f;
1495 dquot = dqget(sb, 0, type);
1496 dqopt->inode_expire[type] = (dquot != NODQUOT) ? dquot->dq_itime : MAX_IQ_TIME;
1497 dqopt->block_expire[type] = (dquot != NODQUOT) ? dquot->dq_btime : MAX_DQ_TIME;
1498 dqput(dquot);
1500 sb->dq_op = &dquot_operations;
1501 add_dquot_ref(sb, type);
1503 up(&dqopt->dqoff_sem);
1504 return 0;
1506 out_f:
1507 filp_close(f, NULL);
1508 out_lock:
1509 up(&dqopt->dqoff_sem);
1511 return error;
1515 * This is the system call interface. This communicates with
1516 * the user-level programs. Currently this only supports diskquota
1517 * calls. Maybe we need to add the process quotas etc. in the future,
1518 * but we probably should use rlimits for that.
1520 asmlinkage long sys_quotactl(int cmd, const char *special, int id, caddr_t addr)
1522 int cmds = 0, type = 0, flags = 0;
1523 kdev_t dev;
1524 struct super_block *sb = NULL;
1525 int ret = -EINVAL;
1527 lock_kernel();
1528 cmds = cmd >> SUBCMDSHIFT;
1529 type = cmd & SUBCMDMASK;
1531 if ((u_int) type >= MAXQUOTAS)
1532 goto out;
1533 if (id & ~0xFFFF)
1534 goto out;
1536 ret = -EPERM;
1537 switch (cmds) {
1538 case Q_SYNC:
1539 case Q_GETSTATS:
1540 break;
1541 case Q_GETQUOTA:
1542 if (((type == USRQUOTA && current->euid != id) ||
1543 (type == GRPQUOTA && in_egroup_p(id))) &&
1544 !capable(CAP_SYS_RESOURCE))
1545 goto out;
1546 break;
1547 default:
1548 if (!capable(CAP_SYS_RESOURCE))
1549 goto out;
1552 ret = -EINVAL;
1553 dev = NODEV;
1554 if (special != NULL || (cmds != Q_SYNC && cmds != Q_GETSTATS)) {
1555 mode_t mode;
1556 struct nameidata nd;
1558 ret = user_path_walk(special, &nd);
1559 if (ret)
1560 goto out;
1562 dev = nd.dentry->d_inode->i_rdev;
1563 mode = nd.dentry->d_inode->i_mode;
1564 path_release(&nd);
1566 ret = -ENOTBLK;
1567 if (!S_ISBLK(mode))
1568 goto out;
1569 sb = get_super(dev);
1572 ret = -EINVAL;
1573 switch (cmds) {
1574 case Q_QUOTAON:
1575 ret = sb ? quota_on(sb, type, (char *) addr) : -ENODEV;
1576 goto out;
1577 case Q_QUOTAOFF:
1578 ret = quota_off(sb, type);
1579 goto out;
1580 case Q_GETQUOTA:
1581 ret = get_quota(sb, id, type, (struct dqblk *) addr);
1582 goto out;
1583 case Q_SETQUOTA:
1584 flags |= SET_QUOTA;
1585 break;
1586 case Q_SETUSE:
1587 flags |= SET_USE;
1588 break;
1589 case Q_SETQLIM:
1590 flags |= SET_QLIMIT;
1591 break;
1592 case Q_SYNC:
1593 ret = sync_dquots(dev, type);
1594 goto out;
1595 case Q_GETSTATS:
1596 ret = get_stats(addr);
1597 goto out;
1598 case Q_RSQUASH:
1599 ret = quota_root_squash(sb, type, (int *) addr);
1600 goto out;
1601 default:
1602 goto out;
1605 flags |= QUOTA_SYSCALL;
1607 ret = -ESRCH;
1608 if (sb && sb_has_quota_enabled(sb, type))
1609 ret = set_dqblk(sb, id, type, flags, (struct dqblk *) addr);
1610 out:
1611 unlock_kernel();
1612 return ret;