Ok. I didn't make 2.4.0 in 2000. Tough. I tried, but we had some
[davej-history.git] / fs / dquot.c
bloba63685d34fddc61c52805b16b7aa00da4263db1d
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 inline struct quota_mount_options *sb_dqopt(struct super_block *sb)
69 return &sb->s_dquot;
73 * Dquot List Management:
74 * The quota code uses three lists for dquot management: the inuse_list,
75 * free_dquots, and dquot_hash[] array. A single dquot structure may be
76 * on all three lists, depending on its current state.
78 * All dquots are placed on the inuse_list when first created, and this
79 * list is used for the sync and invalidate operations, which must look
80 * at every dquot.
82 * Unused dquots (dq_count == 0) are added to the free_dquots list when
83 * freed, and this list is searched whenever we need an available dquot.
84 * Dquots are removed from the list as soon as they are used again, and
85 * nr_free_dquots gives the number of dquots on the list.
87 * Dquots with a specific identity (device, type and id) are placed on
88 * one of the dquot_hash[] hash chains. The provides an efficient search
89 * mechanism to lcoate a specific dquot.
92 static struct dquot *inuse_list;
93 static LIST_HEAD(free_dquots);
94 static struct dquot *dquot_hash[NR_DQHASH];
95 static int dquot_updating[NR_DQHASH];
97 static struct dqstats dqstats;
98 static DECLARE_WAIT_QUEUE_HEAD(dquot_wait);
99 static DECLARE_WAIT_QUEUE_HEAD(update_wait);
101 static void dqput(struct dquot *);
102 static struct dquot *dqduplicate(struct dquot *);
104 static inline char is_enabled(struct quota_mount_options *dqopt, short type)
106 switch (type) {
107 case USRQUOTA:
108 return((dqopt->flags & DQUOT_USR_ENABLED) != 0);
109 case GRPQUOTA:
110 return((dqopt->flags & DQUOT_GRP_ENABLED) != 0);
112 return(0);
115 static inline char sb_has_quota_enabled(struct super_block *sb, short type)
117 return is_enabled(sb_dqopt(sb), type);
120 static inline int const hashfn(kdev_t dev, unsigned int id, short type)
122 return((HASHDEV(dev) ^ id) * (MAXQUOTAS - type)) % NR_DQHASH;
125 static inline void insert_dquot_hash(struct dquot *dquot)
127 struct dquot **htable;
129 htable = &dquot_hash[hashfn(dquot->dq_dev, dquot->dq_id, dquot->dq_type)];
130 if ((dquot->dq_hash_next = *htable) != NULL)
131 (*htable)->dq_hash_pprev = &dquot->dq_hash_next;
132 *htable = dquot;
133 dquot->dq_hash_pprev = htable;
136 static inline void hash_dquot(struct dquot *dquot)
138 insert_dquot_hash(dquot);
141 static inline void unhash_dquot(struct dquot *dquot)
143 if (dquot->dq_hash_pprev) {
144 if (dquot->dq_hash_next)
145 dquot->dq_hash_next->dq_hash_pprev = dquot->dq_hash_pprev;
146 *(dquot->dq_hash_pprev) = dquot->dq_hash_next;
147 dquot->dq_hash_pprev = NULL;
151 static inline struct dquot *find_dquot(unsigned int hashent, kdev_t dev, unsigned int id, short type)
153 struct dquot *dquot;
155 for (dquot = dquot_hash[hashent]; dquot; dquot = dquot->dq_hash_next)
156 if (dquot->dq_dev == dev && dquot->dq_id == id && dquot->dq_type == type)
157 break;
158 return dquot;
161 /* Add a dquot to the head of the free list */
162 static inline void put_dquot_head(struct dquot *dquot)
164 list_add(&dquot->dq_free, &free_dquots);
165 nr_free_dquots++;
168 /* Add a dquot to the tail of the free list */
169 static inline void put_dquot_last(struct dquot *dquot)
171 list_add(&dquot->dq_free, free_dquots.prev);
172 nr_free_dquots++;
175 static inline void remove_free_dquot(struct dquot *dquot)
177 /* sanity check */
178 if (list_empty(&dquot->dq_free)) {
179 printk("remove_free_dquot: dquot not on the free list??\n");
180 return; /* J.K. Just don't do anything */
182 list_del(&dquot->dq_free);
183 INIT_LIST_HEAD(&dquot->dq_free);
184 nr_free_dquots--;
187 static inline void put_inuse(struct dquot *dquot)
189 if ((dquot->dq_next = inuse_list) != NULL)
190 inuse_list->dq_pprev = &dquot->dq_next;
191 inuse_list = dquot;
192 dquot->dq_pprev = &inuse_list;
195 #if 0 /* currently not needed */
196 static inline void remove_inuse(struct dquot *dquot)
198 if (dquot->dq_pprev) {
199 if (dquot->dq_next)
200 dquot->dq_next->dq_pprev = dquot->dq_pprev;
201 *dquot->dq_pprev = dquot->dq_next;
202 dquot->dq_pprev = NULL;
205 #endif
207 static void __wait_on_dquot(struct dquot *dquot)
209 DECLARE_WAITQUEUE(wait, current);
211 add_wait_queue(&dquot->dq_wait, &wait);
212 repeat:
213 set_current_state(TASK_UNINTERRUPTIBLE);
214 if (dquot->dq_flags & DQ_LOCKED) {
215 schedule();
216 goto repeat;
218 remove_wait_queue(&dquot->dq_wait, &wait);
219 current->state = TASK_RUNNING;
222 static inline void wait_on_dquot(struct dquot *dquot)
224 if (dquot->dq_flags & DQ_LOCKED)
225 __wait_on_dquot(dquot);
228 static inline void lock_dquot(struct dquot *dquot)
230 wait_on_dquot(dquot);
231 dquot->dq_flags |= DQ_LOCKED;
234 static inline void unlock_dquot(struct dquot *dquot)
236 dquot->dq_flags &= ~DQ_LOCKED;
237 wake_up(&dquot->dq_wait);
241 * We don't have to be afraid of deadlocks as we never have quotas on quota files...
243 static void write_dquot(struct dquot *dquot)
245 short type = dquot->dq_type;
246 struct file *filp;
247 mm_segment_t fs;
248 loff_t offset;
249 ssize_t ret;
250 struct semaphore *sem = &dquot->dq_sb->s_dquot.dqio_sem;
252 lock_dquot(dquot);
253 if (!dquot->dq_sb) { /* Invalidated quota? */
254 unlock_dquot(dquot);
255 return;
257 down(sem);
258 filp = dquot->dq_sb->s_dquot.files[type];
259 offset = dqoff(dquot->dq_id);
260 fs = get_fs();
261 set_fs(KERNEL_DS);
264 * Note: clear the DQ_MOD flag unconditionally,
265 * so we don't loop forever on failure.
267 dquot->dq_flags &= ~DQ_MOD;
268 ret = 0;
269 if (filp)
270 ret = filp->f_op->write(filp, (char *)&dquot->dq_dqb,
271 sizeof(struct dqblk), &offset);
272 if (ret != sizeof(struct dqblk))
273 printk(KERN_WARNING "VFS: dquota write failed on dev %s\n",
274 kdevname(dquot->dq_dev));
276 set_fs(fs);
277 up(sem);
278 unlock_dquot(dquot);
280 dqstats.writes++;
283 static void read_dquot(struct dquot *dquot)
285 short type = dquot->dq_type;
286 struct file *filp;
287 mm_segment_t fs;
288 loff_t offset;
290 filp = dquot->dq_sb->s_dquot.files[type];
291 if (filp == (struct file *)NULL)
292 return;
294 lock_dquot(dquot);
295 if (!dquot->dq_sb) /* Invalidated quota? */
296 goto out_lock;
297 /* Now we are sure filp is valid - the dquot isn't invalidated */
298 down(&dquot->dq_sb->s_dquot.dqio_sem);
299 offset = dqoff(dquot->dq_id);
300 fs = get_fs();
301 set_fs(KERNEL_DS);
302 filp->f_op->read(filp, (char *)&dquot->dq_dqb, sizeof(struct dqblk), &offset);
303 up(&dquot->dq_sb->s_dquot.dqio_sem);
304 set_fs(fs);
306 if (dquot->dq_bhardlimit == 0 && dquot->dq_bsoftlimit == 0 &&
307 dquot->dq_ihardlimit == 0 && dquot->dq_isoftlimit == 0)
308 dquot->dq_flags |= DQ_FAKE;
309 dqstats.reads++;
310 out_lock:
311 unlock_dquot(dquot);
315 * Unhash and selectively clear the dquot structure,
316 * but preserve the use count, list pointers, and
317 * wait queue.
319 void clear_dquot(struct dquot *dquot)
321 /* unhash it first */
322 unhash_dquot(dquot);
323 dquot->dq_sb = NULL;
324 dquot->dq_flags = 0;
325 dquot->dq_referenced = 0;
326 memset(&dquot->dq_dqb, 0, sizeof(struct dqblk));
329 void invalidate_dquots(kdev_t dev, short type)
331 struct dquot *dquot, *next;
332 int need_restart;
334 restart:
335 next = inuse_list; /* Here it is better. Otherwise the restart doesn't have any sense ;-) */
336 need_restart = 0;
337 while ((dquot = next) != NULL) {
338 next = dquot->dq_next;
339 if (dquot->dq_dev != dev)
340 continue;
341 if (dquot->dq_type != type)
342 continue;
343 if (!dquot->dq_sb) /* Already invalidated entry? */
344 continue;
345 if (dquot->dq_flags & DQ_LOCKED) {
346 __wait_on_dquot(dquot);
348 /* Set the flag for another pass. */
349 need_restart = 1;
351 * Make sure it's still the same dquot.
353 if (dquot->dq_dev != dev)
354 continue;
355 if (dquot->dq_type != type)
356 continue;
357 if (!dquot->dq_sb)
358 continue;
361 * Because inodes needn't to be the only holders of dquot
362 * the quota needn't to be written to disk. So we write it
363 * ourselves before discarding the data just for sure...
365 if (dquot->dq_flags & DQ_MOD && dquot->dq_sb)
367 write_dquot(dquot);
368 need_restart = 1; /* We slept on IO */
370 clear_dquot(dquot);
373 * If anything blocked, restart the operation
374 * to ensure we don't miss any dquots.
376 if (need_restart)
377 goto restart;
380 int sync_dquots(kdev_t dev, short type)
382 struct dquot *dquot, *next, *ddquot;
383 int need_restart;
385 restart:
386 next = inuse_list;
387 need_restart = 0;
388 while ((dquot = next) != NULL) {
389 next = dquot->dq_next;
390 if (dev && dquot->dq_dev != dev)
391 continue;
392 if (type != -1 && dquot->dq_type != type)
393 continue;
394 if (!dquot->dq_sb) /* Invalidated? */
395 continue;
396 if (!(dquot->dq_flags & (DQ_LOCKED | DQ_MOD)))
397 continue;
399 if ((ddquot = dqduplicate(dquot)) == NODQUOT)
400 continue;
401 if (ddquot->dq_flags & DQ_MOD)
402 write_dquot(ddquot);
403 dqput(ddquot);
404 /* Set the flag for another pass. */
405 need_restart = 1;
408 * If anything blocked, restart the operation
409 * to ensure we don't miss any dquots.
411 if (need_restart)
412 goto restart;
414 dqstats.syncs++;
415 return(0);
418 /* NOTE: If you change this function please check whether dqput_blocks() works right... */
419 static void dqput(struct dquot *dquot)
421 if (!dquot)
422 return;
423 if (!dquot->dq_count) {
424 printk("VFS: dqput: trying to free free dquot\n");
425 printk("VFS: device %s, dquot of %s %d\n",
426 kdevname(dquot->dq_dev), quotatypes[dquot->dq_type],
427 dquot->dq_id);
428 return;
432 * If the dq_sb pointer isn't initialized this entry needs no
433 * checking and doesn't need to be written. It's just an empty
434 * dquot that is put back on to the freelist.
436 if (dquot->dq_sb)
437 dqstats.drops++;
438 we_slept:
439 if (dquot->dq_count > 1) {
440 /* We have more than one user... We can simply decrement use count */
441 dquot->dq_count--;
442 return;
444 if (dquot->dq_flags & DQ_LOCKED) {
445 printk(KERN_ERR "VFS: Locked quota to be put on the free list.\n");
446 dquot->dq_flags &= ~DQ_LOCKED;
448 if (dquot->dq_sb && dquot->dq_flags & DQ_MOD) {
449 write_dquot(dquot);
450 goto we_slept;
453 /* sanity check */
454 if (!list_empty(&dquot->dq_free)) {
455 printk(KERN_ERR "dqput: dquot already on free list??\n");
456 dquot->dq_count--; /* J.K. Just decrementing use count seems safer... */
457 return;
459 dquot->dq_count--;
460 dquot->dq_flags &= ~DQ_MOD; /* Modified flag has no sense on free list */
461 /* Place at end of LRU free queue */
462 put_dquot_last(dquot);
463 wake_up(&dquot_wait);
466 static int grow_dquots(void)
468 struct dquot *dquot;
469 int cnt = 0;
471 while (cnt < 32) {
472 dquot = kmem_cache_alloc(dquot_cachep, SLAB_KERNEL);
473 if(!dquot)
474 return cnt;
476 nr_dquots++;
477 memset((caddr_t)dquot, 0, sizeof(struct dquot));
478 init_waitqueue_head(&dquot->dq_wait);
479 /* all dquots go on the inuse_list */
480 put_inuse(dquot);
481 put_dquot_head(dquot);
482 cnt++;
484 return cnt;
487 static struct dquot *find_best_candidate_weighted(void)
489 struct list_head *tmp = &free_dquots;
490 struct dquot *dquot, *best = NULL;
491 unsigned long myscore, bestscore = ~0U;
492 int limit = (nr_free_dquots > 128) ? nr_free_dquots >> 2 : 32;
494 while ((tmp = tmp->next) != &free_dquots && --limit) {
495 dquot = list_entry(tmp, struct dquot, dq_free);
496 /* This should never happen... */
497 if (dquot->dq_flags & (DQ_LOCKED | DQ_MOD))
498 continue;
499 myscore = dquot->dq_referenced;
500 if (myscore < bestscore) {
501 bestscore = myscore;
502 best = dquot;
505 return best;
508 static inline struct dquot *find_best_free(void)
510 struct list_head *tmp = &free_dquots;
511 struct dquot *dquot;
512 int limit = (nr_free_dquots > 1024) ? nr_free_dquots >> 5 : 32;
514 while ((tmp = tmp->next) != &free_dquots && --limit) {
515 dquot = list_entry(tmp, struct dquot, dq_free);
516 if (dquot->dq_referenced == 0)
517 return dquot;
519 return NULL;
522 struct dquot *get_empty_dquot(void)
524 struct dquot *dquot;
525 int shrink = 8; /* Number of times we should try to shrink dcache and icache */
527 repeat:
528 dquot = find_best_free();
529 if (!dquot)
530 goto pressure;
531 got_it:
532 /* Sanity checks */
533 if (dquot->dq_flags & DQ_LOCKED)
534 printk(KERN_ERR "VFS: Locked dquot on the free list\n");
535 if (dquot->dq_count != 0)
536 printk(KERN_ERR "VFS: free dquot count=%d\n", dquot->dq_count);
538 remove_free_dquot(dquot);
539 dquot->dq_count = 1;
540 /* unhash and selectively clear the structure */
541 clear_dquot(dquot);
542 return dquot;
544 pressure:
545 if (nr_dquots < max_dquots)
546 if (grow_dquots())
547 goto repeat;
549 dquot = find_best_candidate_weighted();
550 if (dquot)
551 goto got_it;
553 * Try pruning the dcache to free up some dquots ...
555 if (shrink) {
556 printk(KERN_DEBUG "get_empty_dquot: pruning dcache and icache\n");
557 prune_dcache(128);
558 prune_icache(128);
559 shrink--;
560 goto repeat;
563 printk("VFS: No free dquots, contact mvw@planets.elm.net\n");
564 sleep_on(&dquot_wait);
565 goto repeat;
568 static struct dquot *dqget(struct super_block *sb, unsigned int id, short type)
570 unsigned int hashent = hashfn(sb->s_dev, id, type);
571 struct dquot *dquot, *empty = NULL;
572 struct quota_mount_options *dqopt = sb_dqopt(sb);
574 if (!is_enabled(dqopt, type))
575 return(NODQUOT);
577 we_slept:
578 if ((dquot = find_dquot(hashent, sb->s_dev, id, type)) == NULL) {
579 if (empty == NULL) {
580 dquot_updating[hashent]++;
581 empty = get_empty_dquot();
582 if (!--dquot_updating[hashent])
583 wake_up(&update_wait);
584 goto we_slept;
586 dquot = empty;
587 dquot->dq_id = id;
588 dquot->dq_type = type;
589 dquot->dq_dev = sb->s_dev;
590 dquot->dq_sb = sb;
591 /* hash it first so it can be found */
592 hash_dquot(dquot);
593 read_dquot(dquot);
594 } else {
595 if (!dquot->dq_count++) {
596 remove_free_dquot(dquot);
597 } else
598 dqstats.cache_hits++;
599 wait_on_dquot(dquot);
600 if (empty)
601 dqput(empty);
604 while (dquot_updating[hashent])
605 sleep_on(&update_wait);
607 if (!dquot->dq_sb) { /* Has somebody invalidated entry under us? */
609 * Do it as if the quota was invalidated before we started
611 dqput(dquot);
612 return NODQUOT;
614 dquot->dq_referenced++;
615 dqstats.lookups++;
617 return dquot;
620 static struct dquot *dqduplicate(struct dquot *dquot)
622 if (dquot == NODQUOT || !dquot->dq_sb)
623 return NODQUOT;
624 dquot->dq_count++;
625 wait_on_dquot(dquot);
626 if (!dquot->dq_sb) {
627 dquot->dq_count--;
628 return NODQUOT;
630 dquot->dq_referenced++;
631 dqstats.lookups++;
632 return dquot;
635 /* Check whether this inode is quota file */
636 static inline int is_quotafile(struct inode *inode)
638 int cnt;
639 struct quota_mount_options *dqopt = sb_dqopt(inode->i_sb);
640 struct file **files;
642 if (!dqopt)
643 return 0;
644 files = dqopt->files;
645 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
646 if (files[cnt] && files[cnt]->f_dentry->d_inode == inode)
647 return 1;
648 return 0;
651 static int dqinit_needed(struct inode *inode, short type)
653 int cnt;
655 if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)))
656 return 0;
657 if (is_quotafile(inode))
658 return 0;
659 if (type != -1)
660 return inode->i_dquot[type] == NODQUOT;
661 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
662 if (inode->i_dquot[cnt] == NODQUOT)
663 return 1;
664 return 0;
667 static void add_dquot_ref(struct super_block *sb, short type)
669 struct list_head *p;
670 struct inode *inode;
672 if (!sb->dq_op)
673 return; /* nothing to do */
675 restart:
676 file_list_lock();
677 for (p = sb->s_files.next; p != &sb->s_files; p = p->next) {
678 struct file *filp = list_entry(p, struct file, f_list);
679 if (!filp->f_dentry)
680 continue;
681 inode = filp->f_dentry->d_inode;
682 if (filp->f_mode & FMODE_WRITE && dqinit_needed(inode, type)) {
683 file_list_unlock();
684 sb->dq_op->initialize(inode, type);
685 inode->i_flags |= S_QUOTA;
686 /* As we may have blocked we had better restart... */
687 goto restart;
690 file_list_unlock();
693 /* Return 0 if dqput() won't block (note that 1 doesn't necessarily mean blocking) */
694 static inline int dqput_blocks(struct dquot *dquot)
696 if (dquot->dq_count == 1)
697 return 1;
698 return 0;
701 /* Remove references to dquots from inode - add dquot to list for freeing if needed */
702 int remove_inode_dquot_ref(struct inode *inode, short type, struct list_head *tofree_head)
704 struct dquot *dquot = inode->i_dquot[type];
705 int cnt;
707 inode->i_dquot[type] = NODQUOT;
708 /* any other quota in use? */
709 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
710 if (inode->i_dquot[cnt] != NODQUOT)
711 goto put_it;
713 inode->i_flags &= ~S_QUOTA;
714 put_it:
715 if (dquot != NODQUOT) {
716 if (dqput_blocks(dquot)) {
717 if (dquot->dq_count != 1)
718 printk(KERN_WARNING "VFS: Adding dquot with dq_count %d to dispose list.\n", dquot->dq_count);
719 list_add(&dquot->dq_free, tofree_head); /* As dquot must have currently users it can't be on the free list... */
720 return 1;
721 } else {
722 dqput(dquot); /* We have guaranteed we won't block */
725 return 0;
728 /* Free list of dquots - called from inode.c */
729 void put_dquot_list(struct list_head *tofree_head)
731 struct list_head *act_head = tofree_head->next;
732 struct dquot *dquot;
734 /* So now we have dquots on the list... Just free them */
735 while (act_head != tofree_head) {
736 dquot = list_entry(act_head, struct dquot, dq_free);
737 act_head = act_head->next;
738 list_del(&dquot->dq_free); /* Remove dquot from the list so we won't have problems... */
739 INIT_LIST_HEAD(&dquot->dq_free);
740 dqput(dquot);
744 static inline void dquot_incr_inodes(struct dquot *dquot, unsigned long number)
746 dquot->dq_curinodes += number;
747 dquot->dq_flags |= DQ_MOD;
750 static inline void dquot_incr_blocks(struct dquot *dquot, unsigned long number)
752 dquot->dq_curblocks += number;
753 dquot->dq_flags |= DQ_MOD;
756 static inline void dquot_decr_inodes(struct dquot *dquot, unsigned long number)
758 if (dquot->dq_curinodes > number)
759 dquot->dq_curinodes -= number;
760 else
761 dquot->dq_curinodes = 0;
762 if (dquot->dq_curinodes < dquot->dq_isoftlimit)
763 dquot->dq_itime = (time_t) 0;
764 dquot->dq_flags &= ~DQ_INODES;
765 dquot->dq_flags |= DQ_MOD;
768 static inline void dquot_decr_blocks(struct dquot *dquot, unsigned long number)
770 if (dquot->dq_curblocks > number)
771 dquot->dq_curblocks -= number;
772 else
773 dquot->dq_curblocks = 0;
774 if (dquot->dq_curblocks < dquot->dq_bsoftlimit)
775 dquot->dq_btime = (time_t) 0;
776 dquot->dq_flags &= ~DQ_BLKS;
777 dquot->dq_flags |= DQ_MOD;
780 static inline int need_print_warning(struct dquot *dquot, int flag)
782 switch (dquot->dq_type) {
783 case USRQUOTA:
784 return current->fsuid == dquot->dq_id && !(dquot->dq_flags & flag);
785 case GRPQUOTA:
786 return in_group_p(dquot->dq_id) && !(dquot->dq_flags & flag);
788 return 0;
791 static void print_warning(struct dquot *dquot, int flag, const char *fmtstr)
793 if (!need_print_warning(dquot, flag))
794 return;
795 sprintf(quotamessage, fmtstr,
796 bdevname(dquot->dq_sb->s_dev), quotatypes[dquot->dq_type]);
797 tty_write_message(current->tty, quotamessage);
798 dquot->dq_flags |= flag;
801 static inline char ignore_hardlimit(struct dquot *dquot)
803 return capable(CAP_SYS_RESOURCE) && !dquot->dq_sb->s_dquot.rsquash[dquot->dq_type];
806 static int check_idq(struct dquot *dquot, u_long inodes)
808 if (inodes <= 0 || dquot->dq_flags & DQ_FAKE)
809 return QUOTA_OK;
811 if (dquot->dq_ihardlimit &&
812 (dquot->dq_curinodes + inodes) > dquot->dq_ihardlimit &&
813 !ignore_hardlimit(dquot)) {
814 print_warning(dquot, DQ_INODES, "%s: write failed, %s file limit reached\n");
815 return NO_QUOTA;
818 if (dquot->dq_isoftlimit &&
819 (dquot->dq_curinodes + inodes) > dquot->dq_isoftlimit &&
820 dquot->dq_itime && CURRENT_TIME >= dquot->dq_itime &&
821 !ignore_hardlimit(dquot)) {
822 print_warning(dquot, DQ_INODES, "%s: warning, %s file quota exceeded too long.\n");
823 return NO_QUOTA;
826 if (dquot->dq_isoftlimit &&
827 (dquot->dq_curinodes + inodes) > dquot->dq_isoftlimit &&
828 dquot->dq_itime == 0) {
829 print_warning(dquot, 0, "%s: warning, %s file quota exceeded\n");
830 dquot->dq_itime = CURRENT_TIME + dquot->dq_sb->s_dquot.inode_expire[dquot->dq_type];
833 return QUOTA_OK;
836 static int check_bdq(struct dquot *dquot, u_long blocks, char prealloc)
838 if (blocks <= 0 || dquot->dq_flags & DQ_FAKE)
839 return QUOTA_OK;
841 if (dquot->dq_bhardlimit &&
842 (dquot->dq_curblocks + blocks) > dquot->dq_bhardlimit &&
843 !ignore_hardlimit(dquot)) {
844 if (!prealloc)
845 print_warning(dquot, DQ_BLKS, "%s: write failed, %s disk limit reached.\n");
846 return NO_QUOTA;
849 if (dquot->dq_bsoftlimit &&
850 (dquot->dq_curblocks + blocks) > dquot->dq_bsoftlimit &&
851 dquot->dq_btime && CURRENT_TIME >= dquot->dq_btime &&
852 !ignore_hardlimit(dquot)) {
853 if (!prealloc)
854 print_warning(dquot, DQ_BLKS, "%s: write failed, %s disk quota exceeded too long.\n");
855 return NO_QUOTA;
858 if (dquot->dq_bsoftlimit &&
859 (dquot->dq_curblocks + blocks) > dquot->dq_bsoftlimit &&
860 dquot->dq_btime == 0) {
861 if (!prealloc) {
862 print_warning(dquot, 0, "%s: warning, %s disk quota exceeded\n");
863 dquot->dq_btime = CURRENT_TIME + dquot->dq_sb->s_dquot.block_expire[dquot->dq_type];
865 else
867 * We don't allow preallocation to exceed softlimit so exceeding will
868 * be always printed
870 return NO_QUOTA;
873 return QUOTA_OK;
877 * Initialize a dquot-struct with new quota info. This is used by the
878 * system call interface functions.
880 static int set_dqblk(struct super_block *sb, int id, short type, int flags, struct dqblk *dqblk)
882 struct dquot *dquot;
883 int error = -EFAULT;
884 struct dqblk dq_dqblk;
886 if (dqblk == (struct dqblk *)NULL)
887 return error;
889 if (flags & QUOTA_SYSCALL) {
890 if (copy_from_user(&dq_dqblk, dqblk, sizeof(struct dqblk)))
891 return(error);
892 } else
893 memcpy((caddr_t)&dq_dqblk, (caddr_t)dqblk, sizeof(struct dqblk));
895 if (sb && (dquot = dqget(sb, id, type)) != NODQUOT) {
896 lock_dquot(dquot);
898 if (id > 0 && ((flags & SET_QUOTA) || (flags & SET_QLIMIT))) {
899 dquot->dq_bhardlimit = dq_dqblk.dqb_bhardlimit;
900 dquot->dq_bsoftlimit = dq_dqblk.dqb_bsoftlimit;
901 dquot->dq_ihardlimit = dq_dqblk.dqb_ihardlimit;
902 dquot->dq_isoftlimit = dq_dqblk.dqb_isoftlimit;
905 if ((flags & SET_QUOTA) || (flags & SET_USE)) {
906 if (dquot->dq_isoftlimit &&
907 dquot->dq_curinodes < dquot->dq_isoftlimit &&
908 dq_dqblk.dqb_curinodes >= dquot->dq_isoftlimit)
909 dquot->dq_itime = CURRENT_TIME + dquot->dq_sb->s_dquot.inode_expire[type];
910 dquot->dq_curinodes = dq_dqblk.dqb_curinodes;
911 if (dquot->dq_curinodes < dquot->dq_isoftlimit)
912 dquot->dq_flags &= ~DQ_INODES;
913 if (dquot->dq_bsoftlimit &&
914 dquot->dq_curblocks < dquot->dq_bsoftlimit &&
915 dq_dqblk.dqb_curblocks >= dquot->dq_bsoftlimit)
916 dquot->dq_btime = CURRENT_TIME + dquot->dq_sb->s_dquot.block_expire[type];
917 dquot->dq_curblocks = dq_dqblk.dqb_curblocks;
918 if (dquot->dq_curblocks < dquot->dq_bsoftlimit)
919 dquot->dq_flags &= ~DQ_BLKS;
922 if (id == 0) {
923 dquot->dq_sb->s_dquot.block_expire[type] = dquot->dq_btime = dq_dqblk.dqb_btime;
924 dquot->dq_sb->s_dquot.inode_expire[type] = dquot->dq_itime = dq_dqblk.dqb_itime;
927 if (dq_dqblk.dqb_bhardlimit == 0 && dq_dqblk.dqb_bsoftlimit == 0 &&
928 dq_dqblk.dqb_ihardlimit == 0 && dq_dqblk.dqb_isoftlimit == 0)
929 dquot->dq_flags |= DQ_FAKE;
930 else
931 dquot->dq_flags &= ~DQ_FAKE;
933 dquot->dq_flags |= DQ_MOD;
934 unlock_dquot(dquot);
935 dqput(dquot);
937 return(0);
940 static int get_quota(struct super_block *sb, int id, short type, struct dqblk *dqblk)
942 struct dquot *dquot;
943 int error = -ESRCH;
945 if (!sb || !sb_has_quota_enabled(sb, type))
946 goto out;
947 dquot = dqget(sb, id, type);
948 if (dquot == NODQUOT)
949 goto out;
951 lock_dquot(dquot); /* We must protect against invalidating the quota */
952 error = -EFAULT;
953 if (dqblk && !copy_to_user(dqblk, &dquot->dq_dqb, sizeof(struct dqblk)))
954 error = 0;
955 unlock_dquot(dquot);
956 dqput(dquot);
957 out:
958 return error;
961 static int get_stats(caddr_t addr)
963 int error = -EFAULT;
964 struct dqstats stats;
966 dqstats.allocated_dquots = nr_dquots;
967 dqstats.free_dquots = nr_free_dquots;
969 /* make a copy, in case we page-fault in user space */
970 memcpy(&stats, &dqstats, sizeof(struct dqstats));
971 if (!copy_to_user(addr, &stats, sizeof(struct dqstats)))
972 error = 0;
973 return error;
976 static int quota_root_squash(struct super_block *sb, short type, int *addr)
978 int new_value, error;
980 if (!sb)
981 return(-ENODEV);
983 error = -EFAULT;
984 if (!copy_from_user(&new_value, addr, sizeof(int))) {
985 sb_dqopt(sb)->rsquash[type] = new_value;
986 error = 0;
988 return error;
992 * This is a simple algorithm that calculates the size of a file in blocks.
993 * This is only used on filesystems that do not have an i_blocks count.
995 static u_long isize_to_blocks(loff_t isize, size_t blksize_bits)
997 u_long blocks;
998 u_long indirect;
1000 if (!blksize_bits)
1001 blksize_bits = BLOCK_SIZE_BITS;
1002 blocks = (isize >> blksize_bits) + ((isize & ~((1 << blksize_bits)-1)) ? 1 : 0);
1003 if (blocks > 10) {
1004 indirect = ((blocks - 11) >> 8) + 1; /* single indirect blocks */
1005 if (blocks > (10 + 256)) {
1006 indirect += ((blocks - 267) >> 16) + 1; /* double indirect blocks */
1007 if (blocks > (10 + 256 + (256 << 8)))
1008 indirect++; /* triple indirect blocks */
1010 blocks += indirect;
1012 return blocks;
1016 * Externally referenced functions through dquot_operations in inode.
1018 * Note: this is a blocking operation.
1020 void dquot_initialize(struct inode *inode, short type)
1022 struct dquot *dquot;
1023 unsigned int id = 0;
1024 short cnt;
1026 if (!S_ISREG(inode->i_mode) && !S_ISDIR(inode->i_mode) &&
1027 !S_ISLNK(inode->i_mode))
1028 return;
1029 lock_kernel();
1030 /* We don't want to have quotas on quota files - nasty deadlocks possible */
1031 if (is_quotafile(inode)) {
1032 unlock_kernel();
1033 return;
1035 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1036 if (type != -1 && cnt != type)
1037 continue;
1039 if (!sb_has_quota_enabled(inode->i_sb, cnt))
1040 continue;
1042 if (inode->i_dquot[cnt] == NODQUOT) {
1043 switch (cnt) {
1044 case USRQUOTA:
1045 id = inode->i_uid;
1046 break;
1047 case GRPQUOTA:
1048 id = inode->i_gid;
1049 break;
1051 dquot = dqget(inode->i_sb, id, cnt);
1052 if (dquot == NODQUOT)
1053 continue;
1054 if (inode->i_dquot[cnt] != NODQUOT) {
1055 dqput(dquot);
1056 continue;
1058 inode->i_dquot[cnt] = dquot;
1059 inode->i_flags |= S_QUOTA;
1062 unlock_kernel();
1066 * Release all quota for the specified inode.
1068 * Note: this is a blocking operation.
1070 void dquot_drop(struct inode *inode)
1072 struct dquot *dquot;
1073 short cnt;
1075 lock_kernel();
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);
1084 unlock_kernel();
1088 * Note: this is a blocking operation.
1090 int dquot_alloc_block(const struct inode *inode, unsigned long number, char warn)
1092 int cnt;
1093 struct dquot *dquot[MAXQUOTAS];
1095 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1096 dquot[cnt] = dqduplicate(inode->i_dquot[cnt]);
1097 if (dquot[cnt] == NODQUOT)
1098 continue;
1099 lock_dquot(dquot[cnt]);
1100 if (check_bdq(dquot[cnt], number, warn))
1101 goto put_all;
1104 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1105 if (dquot[cnt] == NODQUOT)
1106 continue;
1107 dquot_incr_blocks(dquot[cnt], number);
1108 unlock_dquot(dquot[cnt]);
1109 dqput(dquot[cnt]);
1112 return QUOTA_OK;
1113 put_all:
1114 for (; cnt >= 0; cnt--) {
1115 if (dquot[cnt] == NODQUOT)
1116 continue;
1117 unlock_dquot(dquot[cnt]);
1118 dqput(dquot[cnt]);
1120 return NO_QUOTA;
1124 * Note: this is a blocking operation.
1126 int dquot_alloc_inode(const struct inode *inode, unsigned long number)
1128 int cnt;
1129 struct dquot *dquot[MAXQUOTAS];
1131 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1132 dquot[cnt] = dqduplicate(inode -> i_dquot[cnt]);
1133 if (dquot[cnt] == NODQUOT)
1134 continue;
1135 lock_dquot(dquot[cnt]);
1136 if (check_idq(dquot[cnt], number))
1137 goto put_all;
1140 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1141 if (dquot[cnt] == NODQUOT)
1142 continue;
1143 dquot_incr_inodes(dquot[cnt], number);
1144 unlock_dquot(dquot[cnt]);
1145 dqput(dquot[cnt]);
1148 return QUOTA_OK;
1149 put_all:
1150 for (; cnt >= 0; cnt--) {
1151 if (dquot[cnt] == NODQUOT)
1152 continue;
1153 unlock_dquot(dquot[cnt]);
1154 dqput(dquot[cnt]);
1156 return NO_QUOTA;
1160 * Note: this is a blocking operation.
1162 void dquot_free_block(const struct inode *inode, unsigned long number)
1164 unsigned short cnt;
1165 struct dquot *dquot;
1167 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1168 dquot = inode->i_dquot[cnt];
1169 if (dquot == NODQUOT)
1170 continue;
1171 wait_on_dquot(dquot);
1172 dquot_decr_blocks(dquot, number);
1177 * Note: this is a blocking operation.
1179 void dquot_free_inode(const struct inode *inode, unsigned long number)
1181 unsigned short cnt;
1182 struct dquot *dquot;
1184 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1185 dquot = inode->i_dquot[cnt];
1186 if (dquot == NODQUOT)
1187 continue;
1188 wait_on_dquot(dquot);
1189 dquot_decr_inodes(dquot, number);
1194 * Transfer the number of inode and blocks from one diskquota to an other.
1196 * Note: this is a blocking operation.
1198 int dquot_transfer(struct dentry *dentry, struct iattr *iattr)
1200 struct inode *inode = dentry -> d_inode;
1201 unsigned long blocks;
1202 struct dquot *transfer_from[MAXQUOTAS];
1203 struct dquot *transfer_to[MAXQUOTAS];
1204 short cnt, disc;
1205 int error = -EDQUOT;
1207 if (!inode)
1208 return -ENOENT;
1209 /* Arguably we could consider that as error, but... no fs - no quota */
1210 if (!inode->i_sb)
1211 return 0;
1213 lock_kernel();
1215 * Build the transfer_from and transfer_to lists and check quotas to see
1216 * if operation is permitted.
1218 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1219 transfer_from[cnt] = NODQUOT;
1220 transfer_to[cnt] = NODQUOT;
1222 if (!sb_has_quota_enabled(inode->i_sb, cnt))
1223 continue;
1225 switch (cnt) {
1226 case USRQUOTA:
1227 if (inode->i_uid == iattr->ia_uid)
1228 continue;
1229 /* We can get transfer_from from inode, can't we? */
1230 transfer_from[cnt] = dqget(inode->i_sb, inode->i_uid, cnt);
1231 transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_uid, cnt);
1232 break;
1233 case GRPQUOTA:
1234 if (inode->i_gid == iattr->ia_gid)
1235 continue;
1236 transfer_from[cnt] = dqget(inode->i_sb, inode->i_gid, cnt);
1237 transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_gid, cnt);
1238 break;
1241 /* Something bad (eg. quotaoff) happened while we were sleeping? */
1242 if (transfer_from[cnt] == NODQUOT || transfer_to[cnt] == NODQUOT)
1244 if (transfer_from[cnt] != NODQUOT) {
1245 dqput(transfer_from[cnt]);
1246 transfer_from[cnt] = NODQUOT;
1248 if (transfer_to[cnt] != NODQUOT) {
1249 dqput(transfer_to[cnt]);
1250 transfer_to[cnt] = NODQUOT;
1252 continue;
1255 * We have to lock the quotas to prevent races...
1257 if (transfer_from[cnt] < transfer_to[cnt])
1259 lock_dquot(transfer_from[cnt]);
1260 lock_dquot(transfer_to[cnt]);
1262 else
1264 lock_dquot(transfer_to[cnt]);
1265 lock_dquot(transfer_from[cnt]);
1269 * The entries might got invalidated while locking. The second
1270 * dqget() could block and so the first structure might got
1271 * invalidated or locked...
1273 if (!transfer_to[cnt]->dq_sb || !transfer_from[cnt]->dq_sb) {
1274 cnt++;
1275 goto put_all;
1280 * Find out if this filesystem uses i_blocks.
1282 if (!inode->i_sb->s_blocksize)
1283 blocks = isize_to_blocks(inode->i_size, BLOCK_SIZE_BITS);
1284 else
1285 blocks = (inode->i_blocks >> 1);
1286 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1287 if (!transfer_to[cnt])
1288 continue;
1289 if (check_idq(transfer_to[cnt], 1) == NO_QUOTA ||
1290 check_bdq(transfer_to[cnt], blocks, 0) == NO_QUOTA) {
1291 cnt = MAXQUOTAS;
1292 goto put_all;
1296 if ((error = notify_change(dentry, iattr)))
1297 goto put_all;
1299 * Finally perform the needed transfer from transfer_from to transfer_to,
1300 * and release any pointers to dquots not needed anymore.
1302 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1304 * Skip changes for same uid or gid or for non-existing quota-type.
1306 if (transfer_from[cnt] == NODQUOT && transfer_to[cnt] == NODQUOT)
1307 continue;
1309 dquot_decr_inodes(transfer_from[cnt], 1);
1310 dquot_decr_blocks(transfer_from[cnt], blocks);
1312 dquot_incr_inodes(transfer_to[cnt], 1);
1313 dquot_incr_blocks(transfer_to[cnt], blocks);
1315 unlock_dquot(transfer_from[cnt]);
1316 dqput(transfer_from[cnt]);
1317 if (inode->i_dquot[cnt] != NODQUOT) {
1318 struct dquot *temp = inode->i_dquot[cnt];
1319 inode->i_dquot[cnt] = transfer_to[cnt];
1320 unlock_dquot(transfer_to[cnt]);
1321 dqput(temp);
1322 } else {
1323 unlock_dquot(transfer_to[cnt]);
1324 dqput(transfer_to[cnt]);
1328 unlock_kernel();
1329 return 0;
1330 put_all:
1331 for (disc = 0; disc < cnt; disc++) {
1332 /* There should be none or both pointers set but... */
1333 if (transfer_to[disc] != NODQUOT) {
1334 unlock_dquot(transfer_to[disc]);
1335 dqput(transfer_to[disc]);
1337 if (transfer_from[disc] != NODQUOT) {
1338 unlock_dquot(transfer_from[disc]);
1339 dqput(transfer_from[disc]);
1342 unlock_kernel();
1343 return error;
1347 void __init dquot_init_hash(void)
1349 printk(KERN_NOTICE "VFS: Diskquotas version %s initialized\n", __DQUOT_VERSION__);
1351 memset(dquot_hash, 0, sizeof(dquot_hash));
1352 memset((caddr_t)&dqstats, 0, sizeof(dqstats));
1356 * Definitions of diskquota operations.
1358 struct dquot_operations dquot_operations = {
1359 dquot_initialize, /* mandatory */
1360 dquot_drop, /* mandatory */
1361 dquot_alloc_block,
1362 dquot_alloc_inode,
1363 dquot_free_block,
1364 dquot_free_inode,
1365 dquot_transfer
1368 static inline void set_enable_flags(struct quota_mount_options *dqopt, short type)
1370 switch (type) {
1371 case USRQUOTA:
1372 dqopt->flags |= DQUOT_USR_ENABLED;
1373 break;
1374 case GRPQUOTA:
1375 dqopt->flags |= DQUOT_GRP_ENABLED;
1376 break;
1380 static inline void reset_enable_flags(struct quota_mount_options *dqopt, short type)
1382 switch (type) {
1383 case USRQUOTA:
1384 dqopt->flags &= ~DQUOT_USR_ENABLED;
1385 break;
1386 case GRPQUOTA:
1387 dqopt->flags &= ~DQUOT_GRP_ENABLED;
1388 break;
1392 /* Function in inode.c - remove pointers to dquots in icache */
1393 extern void remove_dquot_ref(kdev_t, short);
1396 * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount)
1398 int quota_off(struct super_block *sb, short type)
1400 struct file *filp;
1401 short cnt;
1402 int enabled = 0;
1403 struct quota_mount_options *dqopt = sb_dqopt(sb);
1405 if (!sb)
1406 goto out;
1408 /* We need to serialize quota_off() for device */
1409 down(&dqopt->dqoff_sem);
1410 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1411 if (type != -1 && cnt != type)
1412 continue;
1413 if (!is_enabled(dqopt, cnt))
1414 continue;
1415 reset_enable_flags(dqopt, cnt);
1417 /* Note: these are blocking operations */
1418 remove_dquot_ref(sb->s_dev, cnt);
1419 invalidate_dquots(sb->s_dev, cnt);
1421 /* Wait for any pending IO - remove me as soon as invalidate is more polite */
1422 down(&dqopt->dqio_sem);
1423 filp = dqopt->files[cnt];
1424 dqopt->files[cnt] = (struct file *)NULL;
1425 dqopt->inode_expire[cnt] = 0;
1426 dqopt->block_expire[cnt] = 0;
1427 up(&dqopt->dqio_sem);
1428 fput(filp);
1432 * Check whether any quota is still enabled,
1433 * and if not clear the dq_op pointer.
1435 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
1436 enabled |= is_enabled(dqopt, cnt);
1437 if (!enabled)
1438 sb->dq_op = NULL;
1439 up(&dqopt->dqoff_sem);
1440 out:
1441 return(0);
1444 static inline int check_quotafile_size(loff_t size)
1446 ulong blocks = size >> BLOCK_SIZE_BITS;
1447 size_t off = size & (BLOCK_SIZE - 1);
1449 return !(((blocks % sizeof(struct dqblk)) * BLOCK_SIZE + off % sizeof(struct dqblk)) % sizeof(struct dqblk));
1452 static int quota_on(struct super_block *sb, short type, char *path)
1454 struct file *f;
1455 struct inode *inode;
1456 struct dquot *dquot;
1457 struct quota_mount_options *dqopt = sb_dqopt(sb);
1458 char *tmp;
1459 int error;
1461 if (is_enabled(dqopt, type))
1462 return -EBUSY;
1464 down(&dqopt->dqoff_sem);
1465 tmp = getname(path);
1466 error = PTR_ERR(tmp);
1467 if (IS_ERR(tmp))
1468 goto out_lock;
1470 f = filp_open(tmp, O_RDWR, 0600);
1471 putname(tmp);
1473 error = PTR_ERR(f);
1474 if (IS_ERR(f))
1475 goto out_lock;
1476 error = -EIO;
1477 if (!f->f_op || (!f->f_op->read && !f->f_op->write))
1478 goto out_f;
1479 inode = f->f_dentry->d_inode;
1480 error = -EACCES;
1481 if (!S_ISREG(inode->i_mode))
1482 goto out_f;
1483 error = -EINVAL;
1484 if (inode->i_size == 0 || !check_quotafile_size(inode->i_size))
1485 goto out_f;
1486 dquot_drop(inode); /* We don't want quota on quota files */
1488 set_enable_flags(dqopt, type);
1489 dqopt->files[type] = f;
1491 dquot = dqget(sb, 0, type);
1492 dqopt->inode_expire[type] = (dquot != NODQUOT) ? dquot->dq_itime : MAX_IQ_TIME;
1493 dqopt->block_expire[type] = (dquot != NODQUOT) ? dquot->dq_btime : MAX_DQ_TIME;
1494 dqput(dquot);
1496 sb->dq_op = &dquot_operations;
1497 add_dquot_ref(sb, type);
1499 up(&dqopt->dqoff_sem);
1500 return 0;
1502 out_f:
1503 filp_close(f, NULL);
1504 out_lock:
1505 up(&dqopt->dqoff_sem);
1507 return error;
1511 * This is the system call interface. This communicates with
1512 * the user-level programs. Currently this only supports diskquota
1513 * calls. Maybe we need to add the process quotas etc. in the future,
1514 * but we probably should use rlimits for that.
1516 asmlinkage long sys_quotactl(int cmd, const char *special, int id, caddr_t addr)
1518 int cmds = 0, type = 0, flags = 0;
1519 kdev_t dev;
1520 struct super_block *sb = NULL;
1521 int ret = -EINVAL;
1523 lock_kernel();
1524 cmds = cmd >> SUBCMDSHIFT;
1525 type = cmd & SUBCMDMASK;
1527 if ((u_int) type >= MAXQUOTAS)
1528 goto out;
1529 if (id & ~0xFFFF)
1530 goto out;
1532 ret = -EPERM;
1533 switch (cmds) {
1534 case Q_SYNC:
1535 case Q_GETSTATS:
1536 break;
1537 case Q_GETQUOTA:
1538 if (((type == USRQUOTA && current->euid != id) ||
1539 (type == GRPQUOTA && in_egroup_p(id))) &&
1540 !capable(CAP_SYS_RESOURCE))
1541 goto out;
1542 break;
1543 default:
1544 if (!capable(CAP_SYS_RESOURCE))
1545 goto out;
1548 ret = -EINVAL;
1549 dev = NODEV;
1550 if (special != NULL || (cmds != Q_SYNC && cmds != Q_GETSTATS)) {
1551 mode_t mode;
1552 struct nameidata nd;
1554 ret = user_path_walk(special, &nd);
1555 if (ret)
1556 goto out;
1558 dev = nd.dentry->d_inode->i_rdev;
1559 mode = nd.dentry->d_inode->i_mode;
1560 path_release(&nd);
1562 ret = -ENOTBLK;
1563 if (!S_ISBLK(mode))
1564 goto out;
1565 sb = get_super(dev);
1568 ret = -EINVAL;
1569 switch (cmds) {
1570 case Q_QUOTAON:
1571 ret = sb ? quota_on(sb, type, (char *) addr) : -ENODEV;
1572 goto out;
1573 case Q_QUOTAOFF:
1574 ret = quota_off(sb, type);
1575 goto out;
1576 case Q_GETQUOTA:
1577 ret = get_quota(sb, id, type, (struct dqblk *) addr);
1578 goto out;
1579 case Q_SETQUOTA:
1580 flags |= SET_QUOTA;
1581 break;
1582 case Q_SETUSE:
1583 flags |= SET_USE;
1584 break;
1585 case Q_SETQLIM:
1586 flags |= SET_QLIMIT;
1587 break;
1588 case Q_SYNC:
1589 ret = sync_dquots(dev, type);
1590 goto out;
1591 case Q_GETSTATS:
1592 ret = get_stats(addr);
1593 goto out;
1594 case Q_RSQUASH:
1595 ret = quota_root_squash(sb, type, (int *) addr);
1596 goto out;
1597 default:
1598 goto out;
1601 flags |= QUOTA_SYSCALL;
1603 ret = -ESRCH;
1604 if (sb && sb_has_quota_enabled(sb, type))
1605 ret = set_dqblk(sb, id, type, flags, (struct dqblk *) addr);
1606 out:
1607 unlock_kernel();
1608 return ret;