1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58#include <linux/errno.h>
59#include <linux/kernel.h>
60#include <linux/fs.h>
61#include <linux/mount.h>
62#include <linux/mm.h>
63#include <linux/time.h>
64#include <linux/types.h>
65#include <linux/string.h>
66#include <linux/fcntl.h>
67#include <linux/stat.h>
68#include <linux/tty.h>
69#include <linux/file.h>
70#include <linux/slab.h>
71#include <linux/sysctl.h>
72#include <linux/smp_lock.h>
73#include <linux/init.h>
74#include <linux/module.h>
75#include <linux/proc_fs.h>
76#include <linux/security.h>
77#include <linux/kmod.h>
78
79#include <asm/uaccess.h>
80
81#define __DQUOT_PARANOIA
82
83
84
85
86
87
88
89
90
91
92
93
94
95spinlock_t dq_list_lock = SPIN_LOCK_UNLOCKED;
96spinlock_t dq_data_lock = SPIN_LOCK_UNLOCKED;
97
98static char *quotatypes[] = INITQFNAMES;
99static struct quota_format_type *quota_formats;
100static struct quota_module_name module_names[] = INIT_QUOTA_MODULE_NAMES;
101
102int register_quota_format(struct quota_format_type *fmt)
103{
104 spin_lock(&dq_list_lock);
105 fmt->qf_next = quota_formats;
106 quota_formats = fmt;
107 spin_unlock(&dq_list_lock);
108 return 0;
109}
110
111void unregister_quota_format(struct quota_format_type *fmt)
112{
113 struct quota_format_type **actqf;
114
115 spin_lock(&dq_list_lock);
116 for (actqf = "a_formats; *actqf && *actqf != fmt; actqf = &(*actqf)->qf_next);
117 if (*actqf)
118 *actqf = (*actqf)->qf_next;
119 spin_unlock(&dq_list_lock);
120}
121
122static struct quota_format_type *find_quota_format(int id)
123{
124 struct quota_format_type *actqf;
125
126 spin_lock(&dq_list_lock);
127 for (actqf = quota_formats; actqf && actqf->qf_fmt_id != id; actqf = actqf->qf_next);
128 if (!actqf || !try_module_get(actqf->qf_owner)) {
129 int qm;
130
131 spin_unlock(&dq_list_lock);
132
133 for (qm = 0; module_names[qm].qm_fmt_id && module_names[qm].qm_fmt_id != id; qm++);
134 if (!module_names[qm].qm_fmt_id || request_module(module_names[qm].qm_mod_name))
135 return NULL;
136
137 spin_lock(&dq_list_lock);
138 for (actqf = quota_formats; actqf && actqf->qf_fmt_id != id; actqf = actqf->qf_next);
139 if (actqf && !try_module_get(actqf->qf_owner))
140 actqf = NULL;
141 }
142 spin_unlock(&dq_list_lock);
143 return actqf;
144}
145
146static void put_quota_format(struct quota_format_type *fmt)
147{
148 module_put(fmt->qf_owner);
149}
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189static LIST_HEAD(inuse_list);
190static LIST_HEAD(free_dquots);
191static struct list_head dquot_hash[NR_DQHASH];
192
193struct dqstats dqstats;
194
195static void dqput(struct dquot *dquot);
196
197static inline int const hashfn(struct super_block *sb, unsigned int id, int type)
198{
199 return((((unsigned long)sb>>L1_CACHE_SHIFT) ^ id) * (MAXQUOTAS - type)) % NR_DQHASH;
200}
201
202
203
204
205static inline void insert_dquot_hash(struct dquot *dquot)
206{
207 struct list_head *head = dquot_hash + hashfn(dquot->dq_sb, dquot->dq_id, dquot->dq_type);
208 list_add(&dquot->dq_hash, head);
209}
210
211static inline void remove_dquot_hash(struct dquot *dquot)
212{
213 list_del_init(&dquot->dq_hash);
214}
215
216static inline struct dquot *find_dquot(unsigned int hashent, struct super_block *sb, unsigned int id, int type)
217{
218 struct list_head *head;
219 struct dquot *dquot;
220
221 for (head = dquot_hash[hashent].next; head != dquot_hash+hashent; head = head->next) {
222 dquot = list_entry(head, struct dquot, dq_hash);
223 if (dquot->dq_sb == sb && dquot->dq_id == id && dquot->dq_type == type)
224 return dquot;
225 }
226 return NODQUOT;
227}
228
229
230static inline void put_dquot_last(struct dquot *dquot)
231{
232 list_add(&dquot->dq_free, free_dquots.prev);
233 dqstats.free_dquots++;
234}
235
236static inline void remove_free_dquot(struct dquot *dquot)
237{
238 if (list_empty(&dquot->dq_free))
239 return;
240 list_del_init(&dquot->dq_free);
241 dqstats.free_dquots--;
242}
243
244static inline void put_inuse(struct dquot *dquot)
245{
246
247
248 list_add(&dquot->dq_inuse, inuse_list.prev);
249 dqstats.allocated_dquots++;
250}
251
252static inline void remove_inuse(struct dquot *dquot)
253{
254 dqstats.allocated_dquots--;
255 list_del(&dquot->dq_inuse);
256}
257
258static void wait_on_dquot(struct dquot *dquot)
259{
260 down(&dquot->dq_lock);
261 up(&dquot->dq_lock);
262}
263
264static int read_dqblk(struct dquot *dquot)
265{
266 int ret;
267 struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
268
269 down(&dquot->dq_lock);
270 down(&dqopt->dqio_sem);
271 ret = dqopt->ops[dquot->dq_type]->read_dqblk(dquot);
272 up(&dqopt->dqio_sem);
273 up(&dquot->dq_lock);
274 return ret;
275}
276
277static int commit_dqblk(struct dquot *dquot)
278{
279 int ret;
280 struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
281
282 down(&dqopt->dqio_sem);
283 ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot);
284 up(&dqopt->dqio_sem);
285 return ret;
286}
287
288
289
290
291
292static void invalidate_dquots(struct super_block *sb, int type)
293{
294 struct dquot *dquot;
295 struct list_head *head;
296
297 spin_lock(&dq_list_lock);
298 for (head = inuse_list.next; head != &inuse_list;) {
299 dquot = list_entry(head, struct dquot, dq_inuse);
300 head = head->next;
301 if (dquot->dq_sb != sb)
302 continue;
303 if (dquot->dq_type != type)
304 continue;
305#ifdef __DQUOT_PARANOIA
306
307 if (atomic_read(&dquot->dq_count))
308 BUG();
309#endif
310
311 remove_dquot_hash(dquot);
312 remove_free_dquot(dquot);
313 remove_inuse(dquot);
314 kmem_cache_free(dquot_cachep, dquot);
315 }
316 spin_unlock(&dq_list_lock);
317}
318
319static int vfs_quota_sync(struct super_block *sb, int type)
320{
321 struct list_head *head;
322 struct dquot *dquot;
323 struct quota_info *dqopt = sb_dqopt(sb);
324 int cnt;
325
326 down_read(&dqopt->dqptr_sem);
327restart:
328
329
330 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
331 if ((cnt == type || type == -1) && sb_has_quota_enabled(sb, cnt))
332 clear_bit(DQF_ANY_DQUOT_DIRTY_B, &dqopt->info[cnt].dqi_flags);
333 spin_lock(&dq_list_lock);
334 list_for_each(head, &inuse_list) {
335 dquot = list_entry(head, struct dquot, dq_inuse);
336 if (sb && dquot->dq_sb != sb)
337 continue;
338 if (type != -1 && dquot->dq_type != type)
339 continue;
340 if (!dquot->dq_sb)
341 continue;
342 if (!dquot_dirty(dquot))
343 continue;
344 atomic_inc(&dquot->dq_count);
345 dqstats.lookups++;
346 spin_unlock(&dq_list_lock);
347 sb->dq_op->write_dquot(dquot);
348 dqput(dquot);
349 goto restart;
350 }
351 spin_unlock(&dq_list_lock);
352
353 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
354 if ((cnt == type || type == -1) && sb_has_quota_enabled(sb, cnt) && info_dirty(&dqopt->info[cnt])) {
355 down(&dqopt->dqio_sem);
356 dqopt->ops[cnt]->write_file_info(sb, cnt);
357 up(&dqopt->dqio_sem);
358 }
359 spin_lock(&dq_list_lock);
360 dqstats.syncs++;
361 spin_unlock(&dq_list_lock);
362 up_read(&dqopt->dqptr_sem);
363
364 return 0;
365}
366
367
368static void prune_dqcache(int count)
369{
370 struct list_head *head;
371 struct dquot *dquot;
372
373 head = free_dquots.prev;
374 while (head != &free_dquots && count) {
375 dquot = list_entry(head, struct dquot, dq_free);
376 remove_dquot_hash(dquot);
377 remove_free_dquot(dquot);
378 remove_inuse(dquot);
379 kmem_cache_free(dquot_cachep, dquot);
380 count--;
381 head = free_dquots.prev;
382 }
383}
384
385
386
387
388
389
390static int shrink_dqcache_memory(int nr, unsigned int gfp_mask)
391{
392 int ret;
393
394 spin_lock(&dq_list_lock);
395 if (nr)
396 prune_dqcache(nr);
397 ret = dqstats.allocated_dquots;
398 spin_unlock(&dq_list_lock);
399 return ret;
400}
401
402
403
404
405
406
407static void dqput(struct dquot *dquot)
408{
409 if (!dquot)
410 return;
411#ifdef __DQUOT_PARANOIA
412 if (!atomic_read(&dquot->dq_count)) {
413 printk("VFS: dqput: trying to free free dquot\n");
414 printk("VFS: device %s, dquot of %s %d\n",
415 dquot->dq_sb->s_id,
416 quotatypes[dquot->dq_type],
417 dquot->dq_id);
418 BUG();
419 }
420#endif
421
422 spin_lock(&dq_list_lock);
423 dqstats.drops++;
424 spin_unlock(&dq_list_lock);
425we_slept:
426 spin_lock(&dq_list_lock);
427 if (atomic_read(&dquot->dq_count) > 1) {
428
429 atomic_dec(&dquot->dq_count);
430 spin_unlock(&dq_list_lock);
431 return;
432 }
433 if (dquot_dirty(dquot)) {
434 spin_unlock(&dq_list_lock);
435 dquot->dq_sb->dq_op->write_dquot(dquot);
436 goto we_slept;
437 }
438 atomic_dec(&dquot->dq_count);
439#ifdef __DQUOT_PARANOIA
440
441 if (!list_empty(&dquot->dq_free))
442 BUG();
443#endif
444 put_dquot_last(dquot);
445 spin_unlock(&dq_list_lock);
446}
447
448static struct dquot *get_empty_dquot(struct super_block *sb, int type)
449{
450 struct dquot *dquot;
451
452 dquot = kmem_cache_alloc(dquot_cachep, SLAB_KERNEL);
453 if(!dquot)
454 return NODQUOT;
455
456 memset((caddr_t)dquot, 0, sizeof(struct dquot));
457 sema_init(&dquot->dq_lock, 1);
458 INIT_LIST_HEAD(&dquot->dq_free);
459 INIT_LIST_HEAD(&dquot->dq_inuse);
460 INIT_LIST_HEAD(&dquot->dq_hash);
461 dquot->dq_sb = sb;
462 dquot->dq_type = type;
463 atomic_set(&dquot->dq_count, 1);
464
465 return dquot;
466}
467
468
469
470
471
472static struct dquot *dqget(struct super_block *sb, unsigned int id, int type)
473{
474 unsigned int hashent = hashfn(sb, id, type);
475 struct dquot *dquot, *empty = NODQUOT;
476
477 if (!sb_has_quota_enabled(sb, type))
478 return NODQUOT;
479we_slept:
480 spin_lock(&dq_list_lock);
481 if ((dquot = find_dquot(hashent, sb, id, type)) == NODQUOT) {
482 if (empty == NODQUOT) {
483 spin_unlock(&dq_list_lock);
484 if ((empty = get_empty_dquot(sb, type)) == NODQUOT)
485 schedule();
486 goto we_slept;
487 }
488 dquot = empty;
489 dquot->dq_id = id;
490
491 put_inuse(dquot);
492
493 insert_dquot_hash(dquot);
494 dqstats.lookups++;
495 spin_unlock(&dq_list_lock);
496 read_dqblk(dquot);
497 } else {
498 if (!atomic_read(&dquot->dq_count))
499 remove_free_dquot(dquot);
500 atomic_inc(&dquot->dq_count);
501 dqstats.cache_hits++;
502 dqstats.lookups++;
503 spin_unlock(&dq_list_lock);
504 wait_on_dquot(dquot);
505 if (empty)
506 kmem_cache_free(dquot_cachep, empty);
507 }
508
509#ifdef __DQUOT_PARANOIA
510 if (!dquot->dq_sb)
511 BUG();
512#endif
513
514 return dquot;
515}
516
517static int dqinit_needed(struct inode *inode, int type)
518{
519 int cnt;
520
521 if (IS_NOQUOTA(inode))
522 return 0;
523 if (type != -1)
524 return inode->i_dquot[type] == NODQUOT;
525 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
526 if (inode->i_dquot[cnt] == NODQUOT)
527 return 1;
528 return 0;
529}
530
531
532static void add_dquot_ref(struct super_block *sb, int type)
533{
534 struct list_head *p;
535
536restart:
537 file_list_lock();
538 list_for_each(p, &sb->s_files) {
539 struct file *filp = list_entry(p, struct file, f_list);
540 struct inode *inode = filp->f_dentry->d_inode;
541 if (filp->f_mode & FMODE_WRITE && dqinit_needed(inode, type)) {
542 struct vfsmount *mnt = mntget(filp->f_vfsmnt);
543 struct dentry *dentry = dget(filp->f_dentry);
544 file_list_unlock();
545 sb->dq_op->initialize(inode, type);
546 dput(dentry);
547 mntput(mnt);
548
549 goto restart;
550 }
551 }
552 file_list_unlock();
553}
554
555
556static inline int dqput_blocks(struct dquot *dquot)
557{
558 if (atomic_read(&dquot->dq_count) <= 1 && dquot_dirty(dquot))
559 return 1;
560 return 0;
561}
562
563
564
565int remove_inode_dquot_ref(struct inode *inode, int type, struct list_head *tofree_head)
566{
567 struct dquot *dquot = inode->i_dquot[type];
568 int cnt;
569
570 inode->i_dquot[type] = NODQUOT;
571
572 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
573 if (inode->i_dquot[cnt] != NODQUOT)
574 goto put_it;
575 }
576 inode->i_flags &= ~S_QUOTA;
577put_it:
578 if (dquot != NODQUOT) {
579 if (dqput_blocks(dquot)) {
580#ifdef __DQUOT_PARANOIA
581 if (atomic_read(&dquot->dq_count) != 1)
582 printk(KERN_WARNING "VFS: Adding dquot with dq_count %d to dispose list.\n", atomic_read(&dquot->dq_count));
583#endif
584 spin_lock(&dq_list_lock);
585 list_add(&dquot->dq_free, tofree_head);
586 spin_unlock(&dq_list_lock);
587 return 1;
588 }
589 else
590 dqput(dquot);
591 }
592 return 0;
593}
594
595
596
597void put_dquot_list(struct list_head *tofree_head)
598{
599 struct list_head *act_head;
600 struct dquot *dquot;
601
602 act_head = tofree_head->next;
603
604 while (act_head != tofree_head) {
605 dquot = list_entry(act_head, struct dquot, dq_free);
606 act_head = act_head->next;
607 list_del_init(&dquot->dq_free);
608 dqput(dquot);
609 }
610}
611
612static inline void dquot_incr_inodes(struct dquot *dquot, unsigned long number)
613{
614 dquot->dq_dqb.dqb_curinodes += number;
615 mark_dquot_dirty(dquot);
616}
617
618static inline void dquot_incr_space(struct dquot *dquot, qsize_t number)
619{
620 dquot->dq_dqb.dqb_curspace += number;
621 mark_dquot_dirty(dquot);
622}
623
624static inline void dquot_decr_inodes(struct dquot *dquot, unsigned long number)
625{
626 if (dquot->dq_dqb.dqb_curinodes > number)
627 dquot->dq_dqb.dqb_curinodes -= number;
628 else
629 dquot->dq_dqb.dqb_curinodes = 0;
630 if (dquot->dq_dqb.dqb_curinodes < dquot->dq_dqb.dqb_isoftlimit)
631 dquot->dq_dqb.dqb_itime = (time_t) 0;
632 clear_bit(DQ_INODES_B, &dquot->dq_flags);
633 mark_dquot_dirty(dquot);
634}
635
636static inline void dquot_decr_space(struct dquot *dquot, qsize_t number)
637{
638 if (dquot->dq_dqb.dqb_curspace > number)
639 dquot->dq_dqb.dqb_curspace -= number;
640 else
641 dquot->dq_dqb.dqb_curspace = 0;
642 if (toqb(dquot->dq_dqb.dqb_curspace) < dquot->dq_dqb.dqb_bsoftlimit)
643 dquot->dq_dqb.dqb_btime = (time_t) 0;
644 clear_bit(DQ_BLKS_B, &dquot->dq_flags);
645 mark_dquot_dirty(dquot);
646}
647
648static inline int need_print_warning(struct dquot *dquot)
649{
650 switch (dquot->dq_type) {
651 case USRQUOTA:
652 return current->fsuid == dquot->dq_id;
653 case GRPQUOTA:
654 return in_group_p(dquot->dq_id);
655 }
656 return 0;
657}
658
659
660#define NOWARN 0
661#define IHARDWARN 1
662#define ISOFTLONGWARN 2
663#define ISOFTWARN 3
664#define BHARDWARN 4
665#define BSOFTLONGWARN 5
666#define BSOFTWARN 6
667
668
669static void print_warning(struct dquot *dquot, const char warntype)
670{
671 char *msg = NULL;
672 int flag = (warntype == BHARDWARN || warntype == BSOFTLONGWARN) ? DQ_BLKS_B :
673 ((warntype == IHARDWARN || warntype == ISOFTLONGWARN) ? DQ_INODES_B : 0);
674
675 if (!need_print_warning(dquot) || (flag && test_and_set_bit(flag, &dquot->dq_flags)))
676 return;
677 tty_write_message(current->tty, dquot->dq_sb->s_id);
678 if (warntype == ISOFTWARN || warntype == BSOFTWARN)
679 tty_write_message(current->tty, ": warning, ");
680 else
681 tty_write_message(current->tty, ": write failed, ");
682 tty_write_message(current->tty, quotatypes[dquot->dq_type]);
683 switch (warntype) {
684 case IHARDWARN:
685 msg = " file limit reached.\n";
686 break;
687 case ISOFTLONGWARN:
688 msg = " file quota exceeded too long.\n";
689 break;
690 case ISOFTWARN:
691 msg = " file quota exceeded.\n";
692 break;
693 case BHARDWARN:
694 msg = " block limit reached.\n";
695 break;
696 case BSOFTLONGWARN:
697 msg = " block quota exceeded too long.\n";
698 break;
699 case BSOFTWARN:
700 msg = " block quota exceeded.\n";
701 break;
702 }
703 tty_write_message(current->tty, msg);
704}
705
706static inline void flush_warnings(struct dquot **dquots, char *warntype)
707{
708 int i;
709
710 for (i = 0; i < MAXQUOTAS; i++)
711 if (dquots[i] != NODQUOT && warntype[i] != NOWARN)
712 print_warning(dquots[i], warntype[i]);
713}
714
715static inline char ignore_hardlimit(struct dquot *dquot)
716{
717 struct mem_dqinfo *info = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_type];
718
719 return capable(CAP_SYS_RESOURCE) &&
720 (info->dqi_format->qf_fmt_id != QFMT_VFS_OLD || !(info->dqi_flags & V1_DQF_RSQUASH));
721}
722
723
724static int check_idq(struct dquot *dquot, ulong inodes, char *warntype)
725{
726 *warntype = NOWARN;
727 if (inodes <= 0 || test_bit(DQ_FAKE_B, &dquot->dq_flags))
728 return QUOTA_OK;
729
730 if (dquot->dq_dqb.dqb_ihardlimit &&
731 (dquot->dq_dqb.dqb_curinodes + inodes) > dquot->dq_dqb.dqb_ihardlimit &&
732 !ignore_hardlimit(dquot)) {
733 *warntype = IHARDWARN;
734 return NO_QUOTA;
735 }
736
737 if (dquot->dq_dqb.dqb_isoftlimit &&
738 (dquot->dq_dqb.dqb_curinodes + inodes) > dquot->dq_dqb.dqb_isoftlimit &&
739 dquot->dq_dqb.dqb_itime && get_seconds() >= dquot->dq_dqb.dqb_itime &&
740 !ignore_hardlimit(dquot)) {
741 *warntype = ISOFTLONGWARN;
742 return NO_QUOTA;
743 }
744
745 if (dquot->dq_dqb.dqb_isoftlimit &&
746 (dquot->dq_dqb.dqb_curinodes + inodes) > dquot->dq_dqb.dqb_isoftlimit &&
747 dquot->dq_dqb.dqb_itime == 0) {
748 *warntype = ISOFTWARN;
749 dquot->dq_dqb.dqb_itime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace;
750 }
751
752 return QUOTA_OK;
753}
754
755
756static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *warntype)
757{
758 *warntype = 0;
759 if (space <= 0 || test_bit(DQ_FAKE_B, &dquot->dq_flags))
760 return QUOTA_OK;
761
762 if (dquot->dq_dqb.dqb_bhardlimit &&
763 toqb(dquot->dq_dqb.dqb_curspace + space) > dquot->dq_dqb.dqb_bhardlimit &&
764 !ignore_hardlimit(dquot)) {
765 if (!prealloc)
766 *warntype = BHARDWARN;
767 return NO_QUOTA;
768 }
769
770 if (dquot->dq_dqb.dqb_bsoftlimit &&
771 toqb(dquot->dq_dqb.dqb_curspace + space) > dquot->dq_dqb.dqb_bsoftlimit &&
772 dquot->dq_dqb.dqb_btime && get_seconds() >= dquot->dq_dqb.dqb_btime &&
773 !ignore_hardlimit(dquot)) {
774 if (!prealloc)
775 *warntype = BSOFTLONGWARN;
776 return NO_QUOTA;
777 }
778
779 if (dquot->dq_dqb.dqb_bsoftlimit &&
780 toqb(dquot->dq_dqb.dqb_curspace + space) > dquot->dq_dqb.dqb_bsoftlimit &&
781 dquot->dq_dqb.dqb_btime == 0) {
782 if (!prealloc) {
783 *warntype = BSOFTWARN;
784 dquot->dq_dqb.dqb_btime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_bgrace;
785 }
786 else
787
788
789
790
791 return NO_QUOTA;
792 }
793
794 return QUOTA_OK;
795}
796
797
798
799
800
801
802void dquot_initialize(struct inode *inode, int type)
803{
804 unsigned int id = 0;
805 int cnt;
806
807 down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
808
809 if (IS_NOQUOTA(inode)) {
810 up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
811 return;
812 }
813
814 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
815 if (type != -1 && cnt != type)
816 continue;
817 if (inode->i_dquot[cnt] == NODQUOT) {
818 switch (cnt) {
819 case USRQUOTA:
820 id = inode->i_uid;
821 break;
822 case GRPQUOTA:
823 id = inode->i_gid;
824 break;
825 }
826 inode->i_dquot[cnt] = dqget(inode->i_sb, id, cnt);
827 if (inode->i_dquot[cnt])
828 inode->i_flags |= S_QUOTA;
829 }
830 }
831 up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
832}
833
834
835
836
837
838static void dquot_drop_iupdate(struct inode *inode, struct dquot **to_drop)
839{
840 int cnt;
841
842 inode->i_flags &= ~S_QUOTA;
843 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
844 to_drop[cnt] = inode->i_dquot[cnt];
845 inode->i_dquot[cnt] = NODQUOT;
846 }
847}
848
849
850
851
852void dquot_drop(struct inode *inode)
853{
854 struct dquot *to_drop[MAXQUOTAS];
855 int cnt;
856
857 down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
858 dquot_drop_iupdate(inode, to_drop);
859 up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
860 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
861 if (to_drop[cnt] != NODQUOT)
862 dqput(to_drop[cnt]);
863}
864
865
866
867
868
869void dquot_drop_nolock(struct inode *inode)
870{
871 struct dquot *to_drop[MAXQUOTAS];
872 int cnt;
873
874 dquot_drop_iupdate(inode, to_drop);
875 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
876 if (to_drop[cnt] != NODQUOT)
877 dqput(to_drop[cnt]);
878}
879
880
881
882
883int dquot_alloc_space(struct inode *inode, qsize_t number, int warn)
884{
885 int cnt, ret = NO_QUOTA;
886 char warntype[MAXQUOTAS];
887
888 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
889 warntype[cnt] = NOWARN;
890
891 down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
892 if (IS_NOQUOTA(inode)) {
893 up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
894 return QUOTA_OK;
895 }
896 spin_lock(&dq_data_lock);
897 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
898 if (inode->i_dquot[cnt] == NODQUOT)
899 continue;
900 if (check_bdq(inode->i_dquot[cnt], number, warn, warntype+cnt) == NO_QUOTA)
901 goto warn_put_all;
902 }
903 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
904 if (inode->i_dquot[cnt] == NODQUOT)
905 continue;
906 dquot_incr_space(inode->i_dquot[cnt], number);
907 }
908 inode_add_bytes(inode, number);
909 ret = QUOTA_OK;
910warn_put_all:
911 spin_unlock(&dq_data_lock);
912 flush_warnings(inode->i_dquot, warntype);
913 up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
914 return ret;
915}
916
917
918
919
920int dquot_alloc_inode(const struct inode *inode, unsigned long number)
921{
922 int cnt, ret = NO_QUOTA;
923 char warntype[MAXQUOTAS];
924
925 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
926 warntype[cnt] = NOWARN;
927 down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
928 if (IS_NOQUOTA(inode)) {
929 up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
930 return QUOTA_OK;
931 }
932 spin_lock(&dq_data_lock);
933 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
934 if (inode->i_dquot[cnt] == NODQUOT)
935 continue;
936 if (check_idq(inode->i_dquot[cnt], number, warntype+cnt) == NO_QUOTA)
937 goto warn_put_all;
938 }
939
940 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
941 if (inode->i_dquot[cnt] == NODQUOT)
942 continue;
943 dquot_incr_inodes(inode->i_dquot[cnt], number);
944 }
945 ret = QUOTA_OK;
946warn_put_all:
947 spin_unlock(&dq_data_lock);
948 flush_warnings((struct dquot **)inode->i_dquot, warntype);
949 up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
950 return ret;
951}
952
953
954
955
956void dquot_free_space(struct inode *inode, qsize_t number)
957{
958 unsigned int cnt;
959
960 down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
961 if (IS_NOQUOTA(inode)) {
962 up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
963 return;
964 }
965 spin_lock(&dq_data_lock);
966 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
967 if (inode->i_dquot[cnt] == NODQUOT)
968 continue;
969 dquot_decr_space(inode->i_dquot[cnt], number);
970 }
971 inode_sub_bytes(inode, number);
972 spin_unlock(&dq_data_lock);
973 up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
974}
975
976
977
978
979void dquot_free_inode(const struct inode *inode, unsigned long number)
980{
981 unsigned int cnt;
982
983 down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
984 if (IS_NOQUOTA(inode)) {
985 up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
986 return;
987 }
988 spin_lock(&dq_data_lock);
989 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
990 if (inode->i_dquot[cnt] == NODQUOT)
991 continue;
992 dquot_decr_inodes(inode->i_dquot[cnt], number);
993 }
994 spin_unlock(&dq_data_lock);
995 up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
996}
997
998
999
1000
1001
1002
1003int dquot_transfer(struct inode *inode, struct iattr *iattr)
1004{
1005 qsize_t space;
1006 struct dquot *transfer_from[MAXQUOTAS];
1007 struct dquot *transfer_to[MAXQUOTAS];
1008 int cnt, ret = NO_QUOTA, chuid = (iattr->ia_valid & ATTR_UID) && inode->i_uid != iattr->ia_uid,
1009 chgid = (iattr->ia_valid & ATTR_GID) && inode->i_gid != iattr->ia_gid;
1010 char warntype[MAXQUOTAS];
1011
1012
1013 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1014 transfer_to[cnt] = transfer_from[cnt] = NODQUOT;
1015 warntype[cnt] = NOWARN;
1016 }
1017 down_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
1018 if (IS_NOQUOTA(inode))
1019 goto warn_put_all;
1020
1021 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1022 switch (cnt) {
1023 case USRQUOTA:
1024 if (!chuid)
1025 continue;
1026 transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_uid, cnt);
1027 break;
1028 case GRPQUOTA:
1029 if (!chgid)
1030 continue;
1031 transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_gid, cnt);
1032 break;
1033 }
1034 }
1035 spin_lock(&dq_data_lock);
1036 space = inode_get_bytes(inode);
1037
1038 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1039 if (transfer_to[cnt] == NODQUOT)
1040 continue;
1041 transfer_from[cnt] = inode->i_dquot[cnt];
1042 if (check_idq(transfer_to[cnt], 1, warntype+cnt) == NO_QUOTA ||
1043 check_bdq(transfer_to[cnt], space, 0, warntype+cnt) == NO_QUOTA)
1044 goto warn_put_all;
1045 }
1046
1047
1048
1049
1050 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1051
1052
1053
1054 if (transfer_to[cnt] == NODQUOT)
1055 continue;
1056
1057 dquot_decr_inodes(transfer_from[cnt], 1);
1058 dquot_decr_space(transfer_from[cnt], space);
1059
1060 dquot_incr_inodes(transfer_to[cnt], 1);
1061 dquot_incr_space(transfer_to[cnt], space);
1062
1063 inode->i_dquot[cnt] = transfer_to[cnt];
1064 }
1065 ret = QUOTA_OK;
1066warn_put_all:
1067 spin_unlock(&dq_data_lock);
1068 flush_warnings(transfer_to, warntype);
1069
1070 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1071 if (ret == QUOTA_OK && transfer_from[cnt] != NODQUOT)
1072 dqput(transfer_from[cnt]);
1073 if (ret == NO_QUOTA && transfer_to[cnt] != NODQUOT)
1074 dqput(transfer_to[cnt]);
1075 }
1076 up_write(&sb_dqopt(inode->i_sb)->dqptr_sem);
1077 return ret;
1078}
1079
1080
1081
1082
1083struct dquot_operations dquot_operations = {
1084 .initialize = dquot_initialize,
1085 .drop = dquot_drop,
1086 .alloc_space = dquot_alloc_space,
1087 .alloc_inode = dquot_alloc_inode,
1088 .free_space = dquot_free_space,
1089 .free_inode = dquot_free_inode,
1090 .transfer = dquot_transfer,
1091 .write_dquot = commit_dqblk
1092};
1093
1094
1095void init_dquot_operations(struct dquot_operations *fsdqops)
1096{
1097 memcpy(fsdqops, &dquot_operations, sizeof(dquot_operations));
1098}
1099
1100static inline void set_enable_flags(struct quota_info *dqopt, int type)
1101{
1102 switch (type) {
1103 case USRQUOTA:
1104 dqopt->flags |= DQUOT_USR_ENABLED;
1105 break;
1106 case GRPQUOTA:
1107 dqopt->flags |= DQUOT_GRP_ENABLED;
1108 break;
1109 }
1110}
1111
1112static inline void reset_enable_flags(struct quota_info *dqopt, int type)
1113{
1114 switch (type) {
1115 case USRQUOTA:
1116 dqopt->flags &= ~DQUOT_USR_ENABLED;
1117 break;
1118 case GRPQUOTA:
1119 dqopt->flags &= ~DQUOT_GRP_ENABLED;
1120 break;
1121 }
1122}
1123
1124
1125extern void remove_dquot_ref(struct super_block *, int);
1126
1127
1128
1129
1130int vfs_quota_off(struct super_block *sb, int type)
1131{
1132 int cnt;
1133 struct quota_info *dqopt = sb_dqopt(sb);
1134
1135 if (!sb)
1136 goto out;
1137
1138
1139 down(&dqopt->dqonoff_sem);
1140 down_write(&dqopt->dqptr_sem);
1141 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1142 if (type != -1 && cnt != type)
1143 continue;
1144 if (!sb_has_quota_enabled(sb, cnt))
1145 continue;
1146 reset_enable_flags(dqopt, cnt);
1147
1148
1149 remove_dquot_ref(sb, cnt);
1150 invalidate_dquots(sb, cnt);
1151
1152
1153
1154
1155 if (info_dirty(&dqopt->info[cnt])) {
1156 down(&dqopt->dqio_sem);
1157 dqopt->ops[cnt]->write_file_info(sb, cnt);
1158 up(&dqopt->dqio_sem);
1159 }
1160 if (dqopt->ops[cnt]->free_file_info)
1161 dqopt->ops[cnt]->free_file_info(sb, cnt);
1162 put_quota_format(dqopt->info[cnt].dqi_format);
1163
1164 fput(dqopt->files[cnt]);
1165 dqopt->files[cnt] = (struct file *)NULL;
1166 dqopt->info[cnt].dqi_flags = 0;
1167 dqopt->info[cnt].dqi_igrace = 0;
1168 dqopt->info[cnt].dqi_bgrace = 0;
1169 dqopt->ops[cnt] = NULL;
1170 }
1171 up_write(&dqopt->dqptr_sem);
1172 up(&dqopt->dqonoff_sem);
1173out:
1174 return 0;
1175}
1176
1177int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path)
1178{
1179 struct file *f;
1180 struct inode *inode;
1181 struct quota_info *dqopt = sb_dqopt(sb);
1182 struct quota_format_type *fmt = find_quota_format(format_id);
1183 int error;
1184 unsigned int oldflags;
1185
1186 if (!fmt)
1187 return -ESRCH;
1188 f = filp_open(path, O_RDWR, 0600);
1189 if (IS_ERR(f)) {
1190 error = PTR_ERR(f);
1191 goto out_fmt;
1192 }
1193 error = -EIO;
1194 if (!f->f_op || !f->f_op->read || !f->f_op->write)
1195 goto out_f;
1196 error = security_quota_on(f);
1197 if (error)
1198 goto out_f;
1199 inode = f->f_dentry->d_inode;
1200 error = -EACCES;
1201 if (!S_ISREG(inode->i_mode))
1202 goto out_f;
1203
1204 down(&dqopt->dqonoff_sem);
1205 down_write(&dqopt->dqptr_sem);
1206 if (sb_has_quota_enabled(sb, type)) {
1207 error = -EBUSY;
1208 goto out_lock;
1209 }
1210 oldflags = inode->i_flags;
1211 dqopt->files[type] = f;
1212 error = -EINVAL;
1213 if (!fmt->qf_ops->check_quota_file(sb, type))
1214 goto out_file_init;
1215
1216 dquot_drop_nolock(inode);
1217 inode->i_flags |= S_NOQUOTA | S_NOATIME;
1218
1219 dqopt->ops[type] = fmt->qf_ops;
1220 dqopt->info[type].dqi_format = fmt;
1221 down(&dqopt->dqio_sem);
1222 if ((error = dqopt->ops[type]->read_file_info(sb, type)) < 0) {
1223 up(&dqopt->dqio_sem);
1224 goto out_file_init;
1225 }
1226 up(&dqopt->dqio_sem);
1227 set_enable_flags(dqopt, type);
1228 up_write(&dqopt->dqptr_sem);
1229
1230 add_dquot_ref(sb, type);
1231 up(&dqopt->dqonoff_sem);
1232
1233 return 0;
1234
1235out_file_init:
1236 inode->i_flags = oldflags;
1237 dqopt->files[type] = NULL;
1238out_lock:
1239 up_write(&dqopt->dqptr_sem);
1240 up(&dqopt->dqonoff_sem);
1241out_f:
1242 filp_close(f, NULL);
1243out_fmt:
1244 put_quota_format(fmt);
1245
1246 return error;
1247}
1248
1249
1250static void do_get_dqblk(struct dquot *dquot, struct if_dqblk *di)
1251{
1252 struct mem_dqblk *dm = &dquot->dq_dqb;
1253
1254 spin_lock(&dq_data_lock);
1255 di->dqb_bhardlimit = dm->dqb_bhardlimit;
1256 di->dqb_bsoftlimit = dm->dqb_bsoftlimit;
1257 di->dqb_curspace = dm->dqb_curspace;
1258 di->dqb_ihardlimit = dm->dqb_ihardlimit;
1259 di->dqb_isoftlimit = dm->dqb_isoftlimit;
1260 di->dqb_curinodes = dm->dqb_curinodes;
1261 di->dqb_btime = dm->dqb_btime;
1262 di->dqb_itime = dm->dqb_itime;
1263 di->dqb_valid = QIF_ALL;
1264 spin_unlock(&dq_data_lock);
1265}
1266
1267int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di)
1268{
1269 struct dquot *dquot;
1270
1271 down_read(&sb_dqopt(sb)->dqptr_sem);
1272 if (!(dquot = dqget(sb, id, type))) {
1273 up_read(&sb_dqopt(sb)->dqptr_sem);
1274 return -ESRCH;
1275 }
1276 do_get_dqblk(dquot, di);
1277 dqput(dquot);
1278 up_read(&sb_dqopt(sb)->dqptr_sem);
1279 return 0;
1280}
1281
1282
1283static void do_set_dqblk(struct dquot *dquot, struct if_dqblk *di)
1284{
1285 struct mem_dqblk *dm = &dquot->dq_dqb;
1286 int check_blim = 0, check_ilim = 0;
1287
1288 spin_lock(&dq_data_lock);
1289 if (di->dqb_valid & QIF_SPACE) {
1290 dm->dqb_curspace = di->dqb_curspace;
1291 check_blim = 1;
1292 }
1293 if (di->dqb_valid & QIF_BLIMITS) {
1294 dm->dqb_bsoftlimit = di->dqb_bsoftlimit;
1295 dm->dqb_bhardlimit = di->dqb_bhardlimit;
1296 check_blim = 1;
1297 }
1298 if (di->dqb_valid & QIF_INODES) {
1299 dm->dqb_curinodes = di->dqb_curinodes;
1300 check_ilim = 1;
1301 }
1302 if (di->dqb_valid & QIF_ILIMITS) {
1303 dm->dqb_isoftlimit = di->dqb_isoftlimit;
1304 dm->dqb_ihardlimit = di->dqb_ihardlimit;
1305 check_ilim = 1;
1306 }
1307 if (di->dqb_valid & QIF_BTIME)
1308 dm->dqb_btime = di->dqb_btime;
1309 if (di->dqb_valid & QIF_ITIME)
1310 dm->dqb_itime = di->dqb_itime;
1311
1312 if (check_blim) {
1313 if (!dm->dqb_bsoftlimit || toqb(dm->dqb_curspace) < dm->dqb_bsoftlimit) {
1314 dm->dqb_btime = 0;
1315 clear_bit(DQ_BLKS_B, &dquot->dq_flags);
1316 }
1317 else if (!(di->dqb_valid & QIF_BTIME))
1318 dm->dqb_btime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_bgrace;
1319 }
1320 if (check_ilim) {
1321 if (!dm->dqb_isoftlimit || dm->dqb_curinodes < dm->dqb_isoftlimit) {
1322 dm->dqb_itime = 0;
1323 clear_bit(DQ_INODES_B, &dquot->dq_flags);
1324 }
1325 else if (!(di->dqb_valid & QIF_ITIME))
1326 dm->dqb_itime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace;
1327 }
1328 if (dm->dqb_bhardlimit || dm->dqb_bsoftlimit || dm->dqb_ihardlimit || dm->dqb_isoftlimit)
1329 clear_bit(DQ_FAKE_B, &dquot->dq_flags);
1330 else
1331 set_bit(DQ_FAKE_B, &dquot->dq_flags);
1332 mark_dquot_dirty(dquot);
1333 spin_unlock(&dq_data_lock);
1334}
1335
1336int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di)
1337{
1338 struct dquot *dquot;
1339
1340 down_read(&sb_dqopt(sb)->dqptr_sem);
1341 if (!(dquot = dqget(sb, id, type))) {
1342 up_read(&sb_dqopt(sb)->dqptr_sem);
1343 return -ESRCH;
1344 }
1345 do_set_dqblk(dquot, di);
1346 dqput(dquot);
1347 up_read(&sb_dqopt(sb)->dqptr_sem);
1348 return 0;
1349}
1350
1351
1352int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
1353{
1354 struct mem_dqinfo *mi;
1355
1356 down_read(&sb_dqopt(sb)->dqptr_sem);
1357 if (!sb_has_quota_enabled(sb, type)) {
1358 up_read(&sb_dqopt(sb)->dqptr_sem);
1359 return -ESRCH;
1360 }
1361 mi = sb_dqopt(sb)->info + type;
1362 spin_lock(&dq_data_lock);
1363 ii->dqi_bgrace = mi->dqi_bgrace;
1364 ii->dqi_igrace = mi->dqi_igrace;
1365 ii->dqi_flags = mi->dqi_flags & DQF_MASK;
1366 ii->dqi_valid = IIF_ALL;
1367 spin_unlock(&dq_data_lock);
1368 up_read(&sb_dqopt(sb)->dqptr_sem);
1369 return 0;
1370}
1371
1372
1373int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
1374{
1375 struct mem_dqinfo *mi;
1376
1377 down_read(&sb_dqopt(sb)->dqptr_sem);
1378 if (!sb_has_quota_enabled(sb, type)) {
1379 up_read(&sb_dqopt(sb)->dqptr_sem);
1380 return -ESRCH;
1381 }
1382 mi = sb_dqopt(sb)->info + type;
1383 spin_lock(&dq_data_lock);
1384 if (ii->dqi_valid & IIF_BGRACE)
1385 mi->dqi_bgrace = ii->dqi_bgrace;
1386 if (ii->dqi_valid & IIF_IGRACE)
1387 mi->dqi_igrace = ii->dqi_igrace;
1388 if (ii->dqi_valid & IIF_FLAGS)
1389 mi->dqi_flags = (mi->dqi_flags & ~DQF_MASK) | (ii->dqi_flags & DQF_MASK);
1390 mark_info_dirty(mi);
1391 spin_unlock(&dq_data_lock);
1392 up_read(&sb_dqopt(sb)->dqptr_sem);
1393 return 0;
1394}
1395
1396struct quotactl_ops vfs_quotactl_ops = {
1397 .quota_on = vfs_quota_on,
1398 .quota_off = vfs_quota_off,
1399 .quota_sync = vfs_quota_sync,
1400 .get_info = vfs_get_dqinfo,
1401 .set_info = vfs_set_dqinfo,
1402 .get_dqblk = vfs_get_dqblk,
1403 .set_dqblk = vfs_set_dqblk
1404};
1405
1406static ctl_table fs_dqstats_table[] = {
1407 {
1408 .ctl_name = FS_DQ_LOOKUPS,
1409 .procname = "lookups",
1410 .data = &dqstats.lookups,
1411 .maxlen = sizeof(int),
1412 .mode = 0444,
1413 .proc_handler = &proc_dointvec,
1414 },
1415 {
1416 .ctl_name = FS_DQ_DROPS,
1417 .procname = "drops",
1418 .data = &dqstats.drops,
1419 .maxlen = sizeof(int),
1420 .mode = 0444,
1421 .proc_handler = &proc_dointvec,
1422 },
1423 {
1424 .ctl_name = FS_DQ_READS,
1425 .procname = "reads",
1426 .data = &dqstats.reads,
1427 .maxlen = sizeof(int),
1428 .mode = 0444,
1429 .proc_handler = &proc_dointvec,
1430 },
1431 {
1432 .ctl_name = FS_DQ_WRITES,
1433 .procname = "writes",
1434 .data = &dqstats.writes,
1435 .maxlen = sizeof(int),
1436 .mode = 0444,
1437 .proc_handler = &proc_dointvec,
1438 },
1439 {
1440 .ctl_name = FS_DQ_CACHE_HITS,
1441 .procname = "cache_hits",
1442 .data = &dqstats.cache_hits,
1443 .maxlen = sizeof(int),
1444 .mode = 0444,
1445 .proc_handler = &proc_dointvec,
1446 },
1447 {
1448 .ctl_name = FS_DQ_ALLOCATED,
1449 .procname = "allocated_dquots",
1450 .data = &dqstats.allocated_dquots,
1451 .maxlen = sizeof(int),
1452 .mode = 0444,
1453 .proc_handler = &proc_dointvec,
1454 },
1455 {
1456 .ctl_name = FS_DQ_FREE,
1457 .procname = "free_dquots",
1458 .data = &dqstats.free_dquots,
1459 .maxlen = sizeof(int),
1460 .mode = 0444,
1461 .proc_handler = &proc_dointvec,
1462 },
1463 {
1464 .ctl_name = FS_DQ_SYNCS,
1465 .procname = "syncs",
1466 .data = &dqstats.syncs,
1467 .maxlen = sizeof(int),
1468 .mode = 0444,
1469 .proc_handler = &proc_dointvec,
1470 },
1471 { .ctl_name = 0 },
1472};
1473
1474static ctl_table fs_table[] = {
1475 {
1476 .ctl_name = FS_DQSTATS,
1477 .procname = "quota",
1478 .mode = 0555,
1479 .child = fs_dqstats_table,
1480 },
1481 { .ctl_name = 0 },
1482};
1483
1484static ctl_table sys_table[] = {
1485 {
1486 .ctl_name = CTL_FS,
1487 .procname = "fs",
1488 .mode = 0555,
1489 .child = fs_table,
1490 },
1491 { .ctl_name = 0 },
1492};
1493
1494
1495kmem_cache_t *dquot_cachep;
1496
1497static int __init dquot_init(void)
1498{
1499 int i;
1500
1501 register_sysctl_table(sys_table, 0);
1502 for (i = 0; i < NR_DQHASH; i++)
1503 INIT_LIST_HEAD(dquot_hash + i);
1504 printk(KERN_NOTICE "VFS: Disk quotas %s\n", __DQUOT_VERSION__);
1505
1506 dquot_cachep = kmem_cache_create("dquot",
1507 sizeof(struct dquot), sizeof(unsigned long) * 4,
1508 SLAB_HWCACHE_ALIGN|SLAB_RECLAIM_ACCOUNT, NULL, NULL);
1509 if (!dquot_cachep)
1510 panic("Cannot create dquot SLAB cache");
1511
1512 set_shrinker(DEFAULT_SEEKS, shrink_dqcache_memory);
1513
1514 return 0;
1515}
1516module_init(dquot_init);
1517
1518EXPORT_SYMBOL(register_quota_format);
1519EXPORT_SYMBOL(unregister_quota_format);
1520EXPORT_SYMBOL(dqstats);
1521EXPORT_SYMBOL(dq_list_lock);
1522EXPORT_SYMBOL(dq_data_lock);
1523EXPORT_SYMBOL(init_dquot_operations);
1524