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