diff options
Diffstat (limited to 'fs/dquot.c')
-rw-r--r-- | fs/dquot.c | 594 |
1 files changed, 396 insertions, 198 deletions
diff --git a/fs/dquot.c b/fs/dquot.c index c237ccc8581c..bca3cac4bee7 100644 --- a/fs/dquot.c +++ b/fs/dquot.c | |||
@@ -87,14 +87,17 @@ | |||
87 | #define __DQUOT_PARANOIA | 87 | #define __DQUOT_PARANOIA |
88 | 88 | ||
89 | /* | 89 | /* |
90 | * There are two quota SMP locks. dq_list_lock protects all lists with quotas | 90 | * There are three quota SMP locks. dq_list_lock protects all lists with quotas |
91 | * and quota formats and also dqstats structure containing statistics about the | 91 | * and quota formats, dqstats structure containing statistics about the lists |
92 | * lists. dq_data_lock protects data from dq_dqb and also mem_dqinfo structures | 92 | * dq_data_lock protects data from dq_dqb and also mem_dqinfo structures and |
93 | * and also guards consistency of dquot->dq_dqb with inode->i_blocks, i_bytes. | 93 | * also guards consistency of dquot->dq_dqb with inode->i_blocks, i_bytes. |
94 | * i_blocks and i_bytes updates itself are guarded by i_lock acquired directly | 94 | * i_blocks and i_bytes updates itself are guarded by i_lock acquired directly |
95 | * in inode_add_bytes() and inode_sub_bytes(). | 95 | * in inode_add_bytes() and inode_sub_bytes(). dq_state_lock protects |
96 | * modifications of quota state (on quotaon and quotaoff) and readers who care | ||
97 | * about latest values take it as well. | ||
96 | * | 98 | * |
97 | * The spinlock ordering is hence: dq_data_lock > dq_list_lock > i_lock | 99 | * The spinlock ordering is hence: dq_data_lock > dq_list_lock > i_lock, |
100 | * dq_list_lock > dq_state_lock | ||
98 | * | 101 | * |
99 | * Note that some things (eg. sb pointer, type, id) doesn't change during | 102 | * Note that some things (eg. sb pointer, type, id) doesn't change during |
100 | * the life of the dquot structure and so needn't to be protected by a lock | 103 | * the life of the dquot structure and so needn't to be protected by a lock |
@@ -103,12 +106,7 @@ | |||
103 | * operation is just reading pointers from inode (or not using them at all) the | 106 | * operation is just reading pointers from inode (or not using them at all) the |
104 | * read lock is enough. If pointers are altered function must hold write lock | 107 | * read lock is enough. If pointers are altered function must hold write lock |
105 | * (these locking rules also apply for S_NOQUOTA flag in the inode - note that | 108 | * (these locking rules also apply for S_NOQUOTA flag in the inode - note that |
106 | * for altering the flag i_mutex is also needed). If operation is holding | 109 | * for altering the flag i_mutex is also needed). |
107 | * reference to dquot in other way (e.g. quotactl ops) it must be guarded by | ||
108 | * dqonoff_mutex. | ||
109 | * This locking assures that: | ||
110 | * a) update/access to dquot pointers in inode is serialized | ||
111 | * b) everyone is guarded against invalidate_dquots() | ||
112 | * | 110 | * |
113 | * Each dquot has its dq_lock mutex. Locked dquots might not be referenced | 111 | * Each dquot has its dq_lock mutex. Locked dquots might not be referenced |
114 | * from inodes (dquot_alloc_space() and such don't check the dq_lock). | 112 | * from inodes (dquot_alloc_space() and such don't check the dq_lock). |
@@ -122,10 +120,17 @@ | |||
122 | * Lock ordering (including related VFS locks) is the following: | 120 | * Lock ordering (including related VFS locks) is the following: |
123 | * i_mutex > dqonoff_sem > journal_lock > dqptr_sem > dquot->dq_lock > | 121 | * i_mutex > dqonoff_sem > journal_lock > dqptr_sem > dquot->dq_lock > |
124 | * dqio_mutex | 122 | * dqio_mutex |
123 | * The lock ordering of dqptr_sem imposed by quota code is only dqonoff_sem > | ||
124 | * dqptr_sem. But filesystem has to count with the fact that functions such as | ||
125 | * dquot_alloc_space() acquire dqptr_sem and they usually have to be called | ||
126 | * from inside a transaction to keep filesystem consistency after a crash. Also | ||
127 | * filesystems usually want to do some IO on dquot from ->mark_dirty which is | ||
128 | * called with dqptr_sem held. | ||
125 | * i_mutex on quota files is special (it's below dqio_mutex) | 129 | * i_mutex on quota files is special (it's below dqio_mutex) |
126 | */ | 130 | */ |
127 | 131 | ||
128 | static DEFINE_SPINLOCK(dq_list_lock); | 132 | static DEFINE_SPINLOCK(dq_list_lock); |
133 | static DEFINE_SPINLOCK(dq_state_lock); | ||
129 | DEFINE_SPINLOCK(dq_data_lock); | 134 | DEFINE_SPINLOCK(dq_data_lock); |
130 | 135 | ||
131 | static char *quotatypes[] = INITQFNAMES; | 136 | static char *quotatypes[] = INITQFNAMES; |
@@ -211,8 +216,6 @@ static struct hlist_head *dquot_hash; | |||
211 | 216 | ||
212 | struct dqstats dqstats; | 217 | struct dqstats dqstats; |
213 | 218 | ||
214 | static void dqput(struct dquot *dquot); | ||
215 | |||
216 | static inline unsigned int | 219 | static inline unsigned int |
217 | hashfn(const struct super_block *sb, unsigned int id, int type) | 220 | hashfn(const struct super_block *sb, unsigned int id, int type) |
218 | { | 221 | { |
@@ -415,11 +418,22 @@ out_dqlock: | |||
415 | return ret; | 418 | return ret; |
416 | } | 419 | } |
417 | 420 | ||
421 | void dquot_destroy(struct dquot *dquot) | ||
422 | { | ||
423 | kmem_cache_free(dquot_cachep, dquot); | ||
424 | } | ||
425 | EXPORT_SYMBOL(dquot_destroy); | ||
426 | |||
427 | static inline void do_destroy_dquot(struct dquot *dquot) | ||
428 | { | ||
429 | dquot->dq_sb->dq_op->destroy_dquot(dquot); | ||
430 | } | ||
431 | |||
418 | /* Invalidate all dquots on the list. Note that this function is called after | 432 | /* Invalidate all dquots on the list. Note that this function is called after |
419 | * quota is disabled and pointers from inodes removed so there cannot be new | 433 | * quota is disabled and pointers from inodes removed so there cannot be new |
420 | * quota users. There can still be some users of quotas due to inodes being | 434 | * quota users. There can still be some users of quotas due to inodes being |
421 | * just deleted or pruned by prune_icache() (those are not attached to any | 435 | * just deleted or pruned by prune_icache() (those are not attached to any |
422 | * list). We have to wait for such users. | 436 | * list) or parallel quotactl call. We have to wait for such users. |
423 | */ | 437 | */ |
424 | static void invalidate_dquots(struct super_block *sb, int type) | 438 | static void invalidate_dquots(struct super_block *sb, int type) |
425 | { | 439 | { |
@@ -463,11 +477,46 @@ restart: | |||
463 | remove_dquot_hash(dquot); | 477 | remove_dquot_hash(dquot); |
464 | remove_free_dquot(dquot); | 478 | remove_free_dquot(dquot); |
465 | remove_inuse(dquot); | 479 | remove_inuse(dquot); |
466 | kmem_cache_free(dquot_cachep, dquot); | 480 | do_destroy_dquot(dquot); |
467 | } | 481 | } |
468 | spin_unlock(&dq_list_lock); | 482 | spin_unlock(&dq_list_lock); |
469 | } | 483 | } |
470 | 484 | ||
485 | /* Call callback for every active dquot on given filesystem */ | ||
486 | int dquot_scan_active(struct super_block *sb, | ||
487 | int (*fn)(struct dquot *dquot, unsigned long priv), | ||
488 | unsigned long priv) | ||
489 | { | ||
490 | struct dquot *dquot, *old_dquot = NULL; | ||
491 | int ret = 0; | ||
492 | |||
493 | mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); | ||
494 | spin_lock(&dq_list_lock); | ||
495 | list_for_each_entry(dquot, &inuse_list, dq_inuse) { | ||
496 | if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) | ||
497 | continue; | ||
498 | if (dquot->dq_sb != sb) | ||
499 | continue; | ||
500 | /* Now we have active dquot so we can just increase use count */ | ||
501 | atomic_inc(&dquot->dq_count); | ||
502 | dqstats.lookups++; | ||
503 | spin_unlock(&dq_list_lock); | ||
504 | dqput(old_dquot); | ||
505 | old_dquot = dquot; | ||
506 | ret = fn(dquot, priv); | ||
507 | if (ret < 0) | ||
508 | goto out; | ||
509 | spin_lock(&dq_list_lock); | ||
510 | /* We are safe to continue now because our dquot could not | ||
511 | * be moved out of the inuse list while we hold the reference */ | ||
512 | } | ||
513 | spin_unlock(&dq_list_lock); | ||
514 | out: | ||
515 | dqput(old_dquot); | ||
516 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); | ||
517 | return ret; | ||
518 | } | ||
519 | |||
471 | int vfs_quota_sync(struct super_block *sb, int type) | 520 | int vfs_quota_sync(struct super_block *sb, int type) |
472 | { | 521 | { |
473 | struct list_head *dirty; | 522 | struct list_head *dirty; |
@@ -479,7 +528,7 @@ int vfs_quota_sync(struct super_block *sb, int type) | |||
479 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 528 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
480 | if (type != -1 && cnt != type) | 529 | if (type != -1 && cnt != type) |
481 | continue; | 530 | continue; |
482 | if (!sb_has_quota_enabled(sb, cnt)) | 531 | if (!sb_has_quota_active(sb, cnt)) |
483 | continue; | 532 | continue; |
484 | spin_lock(&dq_list_lock); | 533 | spin_lock(&dq_list_lock); |
485 | dirty = &dqopt->info[cnt].dqi_dirty_list; | 534 | dirty = &dqopt->info[cnt].dqi_dirty_list; |
@@ -504,8 +553,8 @@ int vfs_quota_sync(struct super_block *sb, int type) | |||
504 | } | 553 | } |
505 | 554 | ||
506 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | 555 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) |
507 | if ((cnt == type || type == -1) && sb_has_quota_enabled(sb, cnt) | 556 | if ((cnt == type || type == -1) && sb_has_quota_active(sb, cnt) |
508 | && info_dirty(&dqopt->info[cnt])) | 557 | && info_dirty(&dqopt->info[cnt])) |
509 | sb->dq_op->write_info(sb, cnt); | 558 | sb->dq_op->write_info(sb, cnt); |
510 | spin_lock(&dq_list_lock); | 559 | spin_lock(&dq_list_lock); |
511 | dqstats.syncs++; | 560 | dqstats.syncs++; |
@@ -527,7 +576,7 @@ static void prune_dqcache(int count) | |||
527 | remove_dquot_hash(dquot); | 576 | remove_dquot_hash(dquot); |
528 | remove_free_dquot(dquot); | 577 | remove_free_dquot(dquot); |
529 | remove_inuse(dquot); | 578 | remove_inuse(dquot); |
530 | kmem_cache_free(dquot_cachep, dquot); | 579 | do_destroy_dquot(dquot); |
531 | count--; | 580 | count--; |
532 | head = free_dquots.prev; | 581 | head = free_dquots.prev; |
533 | } | 582 | } |
@@ -556,9 +605,8 @@ static struct shrinker dqcache_shrinker = { | |||
556 | /* | 605 | /* |
557 | * Put reference to dquot | 606 | * Put reference to dquot |
558 | * NOTE: If you change this function please check whether dqput_blocks() works right... | 607 | * NOTE: If you change this function please check whether dqput_blocks() works right... |
559 | * MUST be called with either dqptr_sem or dqonoff_mutex held | ||
560 | */ | 608 | */ |
561 | static void dqput(struct dquot *dquot) | 609 | void dqput(struct dquot *dquot) |
562 | { | 610 | { |
563 | int ret; | 611 | int ret; |
564 | 612 | ||
@@ -584,7 +632,7 @@ we_slept: | |||
584 | /* We have more than one user... nothing to do */ | 632 | /* We have more than one user... nothing to do */ |
585 | atomic_dec(&dquot->dq_count); | 633 | atomic_dec(&dquot->dq_count); |
586 | /* Releasing dquot during quotaoff phase? */ | 634 | /* Releasing dquot during quotaoff phase? */ |
587 | if (!sb_has_quota_enabled(dquot->dq_sb, dquot->dq_type) && | 635 | if (!sb_has_quota_active(dquot->dq_sb, dquot->dq_type) && |
588 | atomic_read(&dquot->dq_count) == 1) | 636 | atomic_read(&dquot->dq_count) == 1) |
589 | wake_up(&dquot->dq_wait_unused); | 637 | wake_up(&dquot->dq_wait_unused); |
590 | spin_unlock(&dq_list_lock); | 638 | spin_unlock(&dq_list_lock); |
@@ -625,11 +673,17 @@ we_slept: | |||
625 | spin_unlock(&dq_list_lock); | 673 | spin_unlock(&dq_list_lock); |
626 | } | 674 | } |
627 | 675 | ||
676 | struct dquot *dquot_alloc(struct super_block *sb, int type) | ||
677 | { | ||
678 | return kmem_cache_zalloc(dquot_cachep, GFP_NOFS); | ||
679 | } | ||
680 | EXPORT_SYMBOL(dquot_alloc); | ||
681 | |||
628 | static struct dquot *get_empty_dquot(struct super_block *sb, int type) | 682 | static struct dquot *get_empty_dquot(struct super_block *sb, int type) |
629 | { | 683 | { |
630 | struct dquot *dquot; | 684 | struct dquot *dquot; |
631 | 685 | ||
632 | dquot = kmem_cache_zalloc(dquot_cachep, GFP_NOFS); | 686 | dquot = sb->dq_op->alloc_dquot(sb, type); |
633 | if(!dquot) | 687 | if(!dquot) |
634 | return NODQUOT; | 688 | return NODQUOT; |
635 | 689 | ||
@@ -648,17 +702,29 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type) | |||
648 | 702 | ||
649 | /* | 703 | /* |
650 | * Get reference to dquot | 704 | * Get reference to dquot |
651 | * MUST be called with either dqptr_sem or dqonoff_mutex held | 705 | * |
706 | * Locking is slightly tricky here. We are guarded from parallel quotaoff() | ||
707 | * destroying our dquot by: | ||
708 | * a) checking for quota flags under dq_list_lock and | ||
709 | * b) getting a reference to dquot before we release dq_list_lock | ||
652 | */ | 710 | */ |
653 | static struct dquot *dqget(struct super_block *sb, unsigned int id, int type) | 711 | struct dquot *dqget(struct super_block *sb, unsigned int id, int type) |
654 | { | 712 | { |
655 | unsigned int hashent = hashfn(sb, id, type); | 713 | unsigned int hashent = hashfn(sb, id, type); |
656 | struct dquot *dquot, *empty = NODQUOT; | 714 | struct dquot *dquot = NODQUOT, *empty = NODQUOT; |
657 | 715 | ||
658 | if (!sb_has_quota_enabled(sb, type)) | 716 | if (!sb_has_quota_active(sb, type)) |
659 | return NODQUOT; | 717 | return NODQUOT; |
660 | we_slept: | 718 | we_slept: |
661 | spin_lock(&dq_list_lock); | 719 | spin_lock(&dq_list_lock); |
720 | spin_lock(&dq_state_lock); | ||
721 | if (!sb_has_quota_active(sb, type)) { | ||
722 | spin_unlock(&dq_state_lock); | ||
723 | spin_unlock(&dq_list_lock); | ||
724 | goto out; | ||
725 | } | ||
726 | spin_unlock(&dq_state_lock); | ||
727 | |||
662 | if ((dquot = find_dquot(hashent, sb, id, type)) == NODQUOT) { | 728 | if ((dquot = find_dquot(hashent, sb, id, type)) == NODQUOT) { |
663 | if (empty == NODQUOT) { | 729 | if (empty == NODQUOT) { |
664 | spin_unlock(&dq_list_lock); | 730 | spin_unlock(&dq_list_lock); |
@@ -667,6 +733,7 @@ we_slept: | |||
667 | goto we_slept; | 733 | goto we_slept; |
668 | } | 734 | } |
669 | dquot = empty; | 735 | dquot = empty; |
736 | empty = NODQUOT; | ||
670 | dquot->dq_id = id; | 737 | dquot->dq_id = id; |
671 | /* all dquots go on the inuse_list */ | 738 | /* all dquots go on the inuse_list */ |
672 | put_inuse(dquot); | 739 | put_inuse(dquot); |
@@ -681,8 +748,6 @@ we_slept: | |||
681 | dqstats.cache_hits++; | 748 | dqstats.cache_hits++; |
682 | dqstats.lookups++; | 749 | dqstats.lookups++; |
683 | spin_unlock(&dq_list_lock); | 750 | spin_unlock(&dq_list_lock); |
684 | if (empty) | ||
685 | kmem_cache_free(dquot_cachep, empty); | ||
686 | } | 751 | } |
687 | /* Wait for dq_lock - after this we know that either dquot_release() is already | 752 | /* Wait for dq_lock - after this we know that either dquot_release() is already |
688 | * finished or it will be canceled due to dq_count > 1 test */ | 753 | * finished or it will be canceled due to dq_count > 1 test */ |
@@ -690,11 +755,15 @@ we_slept: | |||
690 | /* Read the dquot and instantiate it (everything done only if needed) */ | 755 | /* Read the dquot and instantiate it (everything done only if needed) */ |
691 | if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && sb->dq_op->acquire_dquot(dquot) < 0) { | 756 | if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && sb->dq_op->acquire_dquot(dquot) < 0) { |
692 | dqput(dquot); | 757 | dqput(dquot); |
693 | return NODQUOT; | 758 | dquot = NODQUOT; |
759 | goto out; | ||
694 | } | 760 | } |
695 | #ifdef __DQUOT_PARANOIA | 761 | #ifdef __DQUOT_PARANOIA |
696 | BUG_ON(!dquot->dq_sb); /* Has somebody invalidated entry under us? */ | 762 | BUG_ON(!dquot->dq_sb); /* Has somebody invalidated entry under us? */ |
697 | #endif | 763 | #endif |
764 | out: | ||
765 | if (empty) | ||
766 | do_destroy_dquot(empty); | ||
698 | 767 | ||
699 | return dquot; | 768 | return dquot; |
700 | } | 769 | } |
@@ -820,7 +889,7 @@ static void drop_dquot_ref(struct super_block *sb, int type) | |||
820 | } | 889 | } |
821 | } | 890 | } |
822 | 891 | ||
823 | static inline void dquot_incr_inodes(struct dquot *dquot, unsigned long number) | 892 | static inline void dquot_incr_inodes(struct dquot *dquot, qsize_t number) |
824 | { | 893 | { |
825 | dquot->dq_dqb.dqb_curinodes += number; | 894 | dquot->dq_dqb.dqb_curinodes += number; |
826 | } | 895 | } |
@@ -830,9 +899,10 @@ static inline void dquot_incr_space(struct dquot *dquot, qsize_t number) | |||
830 | dquot->dq_dqb.dqb_curspace += number; | 899 | dquot->dq_dqb.dqb_curspace += number; |
831 | } | 900 | } |
832 | 901 | ||
833 | static inline void dquot_decr_inodes(struct dquot *dquot, unsigned long number) | 902 | static inline void dquot_decr_inodes(struct dquot *dquot, qsize_t number) |
834 | { | 903 | { |
835 | if (dquot->dq_dqb.dqb_curinodes > number) | 904 | if (sb_dqopt(dquot->dq_sb)->flags & DQUOT_NEGATIVE_USAGE || |
905 | dquot->dq_dqb.dqb_curinodes >= number) | ||
836 | dquot->dq_dqb.dqb_curinodes -= number; | 906 | dquot->dq_dqb.dqb_curinodes -= number; |
837 | else | 907 | else |
838 | dquot->dq_dqb.dqb_curinodes = 0; | 908 | dquot->dq_dqb.dqb_curinodes = 0; |
@@ -843,11 +913,12 @@ static inline void dquot_decr_inodes(struct dquot *dquot, unsigned long number) | |||
843 | 913 | ||
844 | static inline void dquot_decr_space(struct dquot *dquot, qsize_t number) | 914 | static inline void dquot_decr_space(struct dquot *dquot, qsize_t number) |
845 | { | 915 | { |
846 | if (dquot->dq_dqb.dqb_curspace > number) | 916 | if (sb_dqopt(dquot->dq_sb)->flags & DQUOT_NEGATIVE_USAGE || |
917 | dquot->dq_dqb.dqb_curspace >= number) | ||
847 | dquot->dq_dqb.dqb_curspace -= number; | 918 | dquot->dq_dqb.dqb_curspace -= number; |
848 | else | 919 | else |
849 | dquot->dq_dqb.dqb_curspace = 0; | 920 | dquot->dq_dqb.dqb_curspace = 0; |
850 | if (toqb(dquot->dq_dqb.dqb_curspace) <= dquot->dq_dqb.dqb_bsoftlimit) | 921 | if (dquot->dq_dqb.dqb_curspace <= dquot->dq_dqb.dqb_bsoftlimit) |
851 | dquot->dq_dqb.dqb_btime = (time_t) 0; | 922 | dquot->dq_dqb.dqb_btime = (time_t) 0; |
852 | clear_bit(DQ_BLKS_B, &dquot->dq_flags); | 923 | clear_bit(DQ_BLKS_B, &dquot->dq_flags); |
853 | } | 924 | } |
@@ -1023,10 +1094,11 @@ static inline char ignore_hardlimit(struct dquot *dquot) | |||
1023 | } | 1094 | } |
1024 | 1095 | ||
1025 | /* needs dq_data_lock */ | 1096 | /* needs dq_data_lock */ |
1026 | static int check_idq(struct dquot *dquot, ulong inodes, char *warntype) | 1097 | static int check_idq(struct dquot *dquot, qsize_t inodes, char *warntype) |
1027 | { | 1098 | { |
1028 | *warntype = QUOTA_NL_NOWARN; | 1099 | *warntype = QUOTA_NL_NOWARN; |
1029 | if (inodes <= 0 || test_bit(DQ_FAKE_B, &dquot->dq_flags)) | 1100 | if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type) || |
1101 | test_bit(DQ_FAKE_B, &dquot->dq_flags)) | ||
1030 | return QUOTA_OK; | 1102 | return QUOTA_OK; |
1031 | 1103 | ||
1032 | if (dquot->dq_dqb.dqb_ihardlimit && | 1104 | if (dquot->dq_dqb.dqb_ihardlimit && |
@@ -1058,11 +1130,12 @@ static int check_idq(struct dquot *dquot, ulong inodes, char *warntype) | |||
1058 | static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *warntype) | 1130 | static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *warntype) |
1059 | { | 1131 | { |
1060 | *warntype = QUOTA_NL_NOWARN; | 1132 | *warntype = QUOTA_NL_NOWARN; |
1061 | if (space <= 0 || test_bit(DQ_FAKE_B, &dquot->dq_flags)) | 1133 | if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type) || |
1134 | test_bit(DQ_FAKE_B, &dquot->dq_flags)) | ||
1062 | return QUOTA_OK; | 1135 | return QUOTA_OK; |
1063 | 1136 | ||
1064 | if (dquot->dq_dqb.dqb_bhardlimit && | 1137 | if (dquot->dq_dqb.dqb_bhardlimit && |
1065 | toqb(dquot->dq_dqb.dqb_curspace + space) > dquot->dq_dqb.dqb_bhardlimit && | 1138 | dquot->dq_dqb.dqb_curspace + space > dquot->dq_dqb.dqb_bhardlimit && |
1066 | !ignore_hardlimit(dquot)) { | 1139 | !ignore_hardlimit(dquot)) { |
1067 | if (!prealloc) | 1140 | if (!prealloc) |
1068 | *warntype = QUOTA_NL_BHARDWARN; | 1141 | *warntype = QUOTA_NL_BHARDWARN; |
@@ -1070,7 +1143,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war | |||
1070 | } | 1143 | } |
1071 | 1144 | ||
1072 | if (dquot->dq_dqb.dqb_bsoftlimit && | 1145 | if (dquot->dq_dqb.dqb_bsoftlimit && |
1073 | toqb(dquot->dq_dqb.dqb_curspace + space) > dquot->dq_dqb.dqb_bsoftlimit && | 1146 | dquot->dq_dqb.dqb_curspace + space > dquot->dq_dqb.dqb_bsoftlimit && |
1074 | dquot->dq_dqb.dqb_btime && get_seconds() >= dquot->dq_dqb.dqb_btime && | 1147 | dquot->dq_dqb.dqb_btime && get_seconds() >= dquot->dq_dqb.dqb_btime && |
1075 | !ignore_hardlimit(dquot)) { | 1148 | !ignore_hardlimit(dquot)) { |
1076 | if (!prealloc) | 1149 | if (!prealloc) |
@@ -1079,7 +1152,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war | |||
1079 | } | 1152 | } |
1080 | 1153 | ||
1081 | if (dquot->dq_dqb.dqb_bsoftlimit && | 1154 | if (dquot->dq_dqb.dqb_bsoftlimit && |
1082 | toqb(dquot->dq_dqb.dqb_curspace + space) > dquot->dq_dqb.dqb_bsoftlimit && | 1155 | dquot->dq_dqb.dqb_curspace + space > dquot->dq_dqb.dqb_bsoftlimit && |
1083 | dquot->dq_dqb.dqb_btime == 0) { | 1156 | dquot->dq_dqb.dqb_btime == 0) { |
1084 | if (!prealloc) { | 1157 | if (!prealloc) { |
1085 | *warntype = QUOTA_NL_BSOFTWARN; | 1158 | *warntype = QUOTA_NL_BSOFTWARN; |
@@ -1096,10 +1169,11 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war | |||
1096 | return QUOTA_OK; | 1169 | return QUOTA_OK; |
1097 | } | 1170 | } |
1098 | 1171 | ||
1099 | static int info_idq_free(struct dquot *dquot, ulong inodes) | 1172 | static int info_idq_free(struct dquot *dquot, qsize_t inodes) |
1100 | { | 1173 | { |
1101 | if (test_bit(DQ_FAKE_B, &dquot->dq_flags) || | 1174 | if (test_bit(DQ_FAKE_B, &dquot->dq_flags) || |
1102 | dquot->dq_dqb.dqb_curinodes <= dquot->dq_dqb.dqb_isoftlimit) | 1175 | dquot->dq_dqb.dqb_curinodes <= dquot->dq_dqb.dqb_isoftlimit || |
1176 | !sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type)) | ||
1103 | return QUOTA_NL_NOWARN; | 1177 | return QUOTA_NL_NOWARN; |
1104 | 1178 | ||
1105 | if (dquot->dq_dqb.dqb_curinodes - inodes <= dquot->dq_dqb.dqb_isoftlimit) | 1179 | if (dquot->dq_dqb.dqb_curinodes - inodes <= dquot->dq_dqb.dqb_isoftlimit) |
@@ -1113,71 +1187,88 @@ static int info_idq_free(struct dquot *dquot, ulong inodes) | |||
1113 | static int info_bdq_free(struct dquot *dquot, qsize_t space) | 1187 | static int info_bdq_free(struct dquot *dquot, qsize_t space) |
1114 | { | 1188 | { |
1115 | if (test_bit(DQ_FAKE_B, &dquot->dq_flags) || | 1189 | if (test_bit(DQ_FAKE_B, &dquot->dq_flags) || |
1116 | toqb(dquot->dq_dqb.dqb_curspace) <= dquot->dq_dqb.dqb_bsoftlimit) | 1190 | dquot->dq_dqb.dqb_curspace <= dquot->dq_dqb.dqb_bsoftlimit) |
1117 | return QUOTA_NL_NOWARN; | 1191 | return QUOTA_NL_NOWARN; |
1118 | 1192 | ||
1119 | if (toqb(dquot->dq_dqb.dqb_curspace - space) <= | 1193 | if (dquot->dq_dqb.dqb_curspace - space <= dquot->dq_dqb.dqb_bsoftlimit) |
1120 | dquot->dq_dqb.dqb_bsoftlimit) | ||
1121 | return QUOTA_NL_BSOFTBELOW; | 1194 | return QUOTA_NL_BSOFTBELOW; |
1122 | if (toqb(dquot->dq_dqb.dqb_curspace) >= dquot->dq_dqb.dqb_bhardlimit && | 1195 | if (dquot->dq_dqb.dqb_curspace >= dquot->dq_dqb.dqb_bhardlimit && |
1123 | toqb(dquot->dq_dqb.dqb_curspace - space) < | 1196 | dquot->dq_dqb.dqb_curspace - space < dquot->dq_dqb.dqb_bhardlimit) |
1124 | dquot->dq_dqb.dqb_bhardlimit) | ||
1125 | return QUOTA_NL_BHARDBELOW; | 1197 | return QUOTA_NL_BHARDBELOW; |
1126 | return QUOTA_NL_NOWARN; | 1198 | return QUOTA_NL_NOWARN; |
1127 | } | 1199 | } |
1128 | /* | 1200 | /* |
1129 | * Initialize quota pointers in inode | 1201 | * Initialize quota pointers in inode |
1130 | * Transaction must be started at entry | 1202 | * We do things in a bit complicated way but by that we avoid calling |
1203 | * dqget() and thus filesystem callbacks under dqptr_sem. | ||
1131 | */ | 1204 | */ |
1132 | int dquot_initialize(struct inode *inode, int type) | 1205 | int dquot_initialize(struct inode *inode, int type) |
1133 | { | 1206 | { |
1134 | unsigned int id = 0; | 1207 | unsigned int id = 0; |
1135 | int cnt, ret = 0; | 1208 | int cnt, ret = 0; |
1209 | struct dquot *got[MAXQUOTAS] = { NODQUOT, NODQUOT }; | ||
1210 | struct super_block *sb = inode->i_sb; | ||
1136 | 1211 | ||
1137 | /* First test before acquiring mutex - solves deadlocks when we | 1212 | /* First test before acquiring mutex - solves deadlocks when we |
1138 | * re-enter the quota code and are already holding the mutex */ | 1213 | * re-enter the quota code and are already holding the mutex */ |
1139 | if (IS_NOQUOTA(inode)) | 1214 | if (IS_NOQUOTA(inode)) |
1140 | return 0; | 1215 | return 0; |
1141 | down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1216 | |
1217 | /* First get references to structures we might need. */ | ||
1218 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | ||
1219 | if (type != -1 && cnt != type) | ||
1220 | continue; | ||
1221 | switch (cnt) { | ||
1222 | case USRQUOTA: | ||
1223 | id = inode->i_uid; | ||
1224 | break; | ||
1225 | case GRPQUOTA: | ||
1226 | id = inode->i_gid; | ||
1227 | break; | ||
1228 | } | ||
1229 | got[cnt] = dqget(sb, id, cnt); | ||
1230 | } | ||
1231 | |||
1232 | down_write(&sb_dqopt(sb)->dqptr_sem); | ||
1142 | /* Having dqptr_sem we know NOQUOTA flags can't be altered... */ | 1233 | /* Having dqptr_sem we know NOQUOTA flags can't be altered... */ |
1143 | if (IS_NOQUOTA(inode)) | 1234 | if (IS_NOQUOTA(inode)) |
1144 | goto out_err; | 1235 | goto out_err; |
1145 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1236 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1146 | if (type != -1 && cnt != type) | 1237 | if (type != -1 && cnt != type) |
1147 | continue; | 1238 | continue; |
1239 | /* Avoid races with quotaoff() */ | ||
1240 | if (!sb_has_quota_active(sb, cnt)) | ||
1241 | continue; | ||
1148 | if (inode->i_dquot[cnt] == NODQUOT) { | 1242 | if (inode->i_dquot[cnt] == NODQUOT) { |
1149 | switch (cnt) { | 1243 | inode->i_dquot[cnt] = got[cnt]; |
1150 | case USRQUOTA: | 1244 | got[cnt] = NODQUOT; |
1151 | id = inode->i_uid; | ||
1152 | break; | ||
1153 | case GRPQUOTA: | ||
1154 | id = inode->i_gid; | ||
1155 | break; | ||
1156 | } | ||
1157 | inode->i_dquot[cnt] = dqget(inode->i_sb, id, cnt); | ||
1158 | } | 1245 | } |
1159 | } | 1246 | } |
1160 | out_err: | 1247 | out_err: |
1161 | up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1248 | up_write(&sb_dqopt(sb)->dqptr_sem); |
1249 | /* Drop unused references */ | ||
1250 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | ||
1251 | dqput(got[cnt]); | ||
1162 | return ret; | 1252 | return ret; |
1163 | } | 1253 | } |
1164 | 1254 | ||
1165 | /* | 1255 | /* |
1166 | * Release all quotas referenced by inode | 1256 | * Release all quotas referenced by inode |
1167 | * Transaction must be started at an entry | ||
1168 | */ | 1257 | */ |
1169 | int dquot_drop(struct inode *inode) | 1258 | int dquot_drop(struct inode *inode) |
1170 | { | 1259 | { |
1171 | int cnt; | 1260 | int cnt; |
1261 | struct dquot *put[MAXQUOTAS]; | ||
1172 | 1262 | ||
1173 | down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1263 | down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1174 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1264 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1175 | if (inode->i_dquot[cnt] != NODQUOT) { | 1265 | put[cnt] = inode->i_dquot[cnt]; |
1176 | dqput(inode->i_dquot[cnt]); | 1266 | inode->i_dquot[cnt] = NODQUOT; |
1177 | inode->i_dquot[cnt] = NODQUOT; | ||
1178 | } | ||
1179 | } | 1267 | } |
1180 | up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1268 | up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1269 | |||
1270 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | ||
1271 | dqput(put[cnt]); | ||
1181 | return 0; | 1272 | return 0; |
1182 | } | 1273 | } |
1183 | 1274 | ||
@@ -1264,7 +1355,7 @@ warn_put_all: | |||
1264 | /* | 1355 | /* |
1265 | * This operation can block, but only after everything is updated | 1356 | * This operation can block, but only after everything is updated |
1266 | */ | 1357 | */ |
1267 | int dquot_alloc_inode(const struct inode *inode, unsigned long number) | 1358 | int dquot_alloc_inode(const struct inode *inode, qsize_t number) |
1268 | { | 1359 | { |
1269 | int cnt, ret = NO_QUOTA; | 1360 | int cnt, ret = NO_QUOTA; |
1270 | char warntype[MAXQUOTAS]; | 1361 | char warntype[MAXQUOTAS]; |
@@ -1349,7 +1440,7 @@ out_sub: | |||
1349 | /* | 1440 | /* |
1350 | * This operation can block, but only after everything is updated | 1441 | * This operation can block, but only after everything is updated |
1351 | */ | 1442 | */ |
1352 | int dquot_free_inode(const struct inode *inode, unsigned long number) | 1443 | int dquot_free_inode(const struct inode *inode, qsize_t number) |
1353 | { | 1444 | { |
1354 | unsigned int cnt; | 1445 | unsigned int cnt; |
1355 | char warntype[MAXQUOTAS]; | 1446 | char warntype[MAXQUOTAS]; |
@@ -1393,8 +1484,9 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) | |||
1393 | qsize_t space; | 1484 | qsize_t space; |
1394 | struct dquot *transfer_from[MAXQUOTAS]; | 1485 | struct dquot *transfer_from[MAXQUOTAS]; |
1395 | struct dquot *transfer_to[MAXQUOTAS]; | 1486 | struct dquot *transfer_to[MAXQUOTAS]; |
1396 | int cnt, ret = NO_QUOTA, chuid = (iattr->ia_valid & ATTR_UID) && inode->i_uid != iattr->ia_uid, | 1487 | int cnt, ret = QUOTA_OK; |
1397 | chgid = (iattr->ia_valid & ATTR_GID) && inode->i_gid != iattr->ia_gid; | 1488 | int chuid = iattr->ia_valid & ATTR_UID && inode->i_uid != iattr->ia_uid, |
1489 | chgid = iattr->ia_valid & ATTR_GID && inode->i_gid != iattr->ia_gid; | ||
1398 | char warntype_to[MAXQUOTAS]; | 1490 | char warntype_to[MAXQUOTAS]; |
1399 | char warntype_from_inodes[MAXQUOTAS], warntype_from_space[MAXQUOTAS]; | 1491 | char warntype_from_inodes[MAXQUOTAS], warntype_from_space[MAXQUOTAS]; |
1400 | 1492 | ||
@@ -1402,21 +1494,11 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) | |||
1402 | * re-enter the quota code and are already holding the mutex */ | 1494 | * re-enter the quota code and are already holding the mutex */ |
1403 | if (IS_NOQUOTA(inode)) | 1495 | if (IS_NOQUOTA(inode)) |
1404 | return QUOTA_OK; | 1496 | return QUOTA_OK; |
1405 | /* Clear the arrays */ | 1497 | /* Initialize the arrays */ |
1406 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1498 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1407 | transfer_to[cnt] = transfer_from[cnt] = NODQUOT; | 1499 | transfer_from[cnt] = NODQUOT; |
1500 | transfer_to[cnt] = NODQUOT; | ||
1408 | warntype_to[cnt] = QUOTA_NL_NOWARN; | 1501 | warntype_to[cnt] = QUOTA_NL_NOWARN; |
1409 | } | ||
1410 | down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | ||
1411 | /* Now recheck reliably when holding dqptr_sem */ | ||
1412 | if (IS_NOQUOTA(inode)) { /* File without quota accounting? */ | ||
1413 | up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | ||
1414 | return QUOTA_OK; | ||
1415 | } | ||
1416 | /* First build the transfer_to list - here we can block on | ||
1417 | * reading/instantiating of dquots. We know that the transaction for | ||
1418 | * us was already started so we don't violate lock ranking here */ | ||
1419 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | ||
1420 | switch (cnt) { | 1502 | switch (cnt) { |
1421 | case USRQUOTA: | 1503 | case USRQUOTA: |
1422 | if (!chuid) | 1504 | if (!chuid) |
@@ -1430,6 +1512,13 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) | |||
1430 | break; | 1512 | break; |
1431 | } | 1513 | } |
1432 | } | 1514 | } |
1515 | |||
1516 | down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | ||
1517 | /* Now recheck reliably when holding dqptr_sem */ | ||
1518 | if (IS_NOQUOTA(inode)) { /* File without quota accounting? */ | ||
1519 | up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | ||
1520 | goto put_all; | ||
1521 | } | ||
1433 | spin_lock(&dq_data_lock); | 1522 | spin_lock(&dq_data_lock); |
1434 | space = inode_get_bytes(inode); | 1523 | space = inode_get_bytes(inode); |
1435 | /* Build the transfer_from list and check the limits */ | 1524 | /* Build the transfer_from list and check the limits */ |
@@ -1440,7 +1529,7 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) | |||
1440 | if (check_idq(transfer_to[cnt], 1, warntype_to + cnt) == | 1529 | if (check_idq(transfer_to[cnt], 1, warntype_to + cnt) == |
1441 | NO_QUOTA || check_bdq(transfer_to[cnt], space, 0, | 1530 | NO_QUOTA || check_bdq(transfer_to[cnt], space, 0, |
1442 | warntype_to + cnt) == NO_QUOTA) | 1531 | warntype_to + cnt) == NO_QUOTA) |
1443 | goto warn_put_all; | 1532 | goto over_quota; |
1444 | } | 1533 | } |
1445 | 1534 | ||
1446 | /* | 1535 | /* |
@@ -1468,34 +1557,43 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) | |||
1468 | 1557 | ||
1469 | inode->i_dquot[cnt] = transfer_to[cnt]; | 1558 | inode->i_dquot[cnt] = transfer_to[cnt]; |
1470 | } | 1559 | } |
1471 | ret = QUOTA_OK; | ||
1472 | warn_put_all: | ||
1473 | spin_unlock(&dq_data_lock); | 1560 | spin_unlock(&dq_data_lock); |
1561 | up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | ||
1562 | |||
1474 | /* Dirtify all the dquots - this can block when journalling */ | 1563 | /* Dirtify all the dquots - this can block when journalling */ |
1475 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1564 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1476 | if (transfer_from[cnt]) | 1565 | if (transfer_from[cnt]) |
1477 | mark_dquot_dirty(transfer_from[cnt]); | 1566 | mark_dquot_dirty(transfer_from[cnt]); |
1478 | if (transfer_to[cnt]) | 1567 | if (transfer_to[cnt]) { |
1479 | mark_dquot_dirty(transfer_to[cnt]); | 1568 | mark_dquot_dirty(transfer_to[cnt]); |
1569 | /* The reference we got is transferred to the inode */ | ||
1570 | transfer_to[cnt] = NODQUOT; | ||
1571 | } | ||
1480 | } | 1572 | } |
1573 | warn_put_all: | ||
1481 | flush_warnings(transfer_to, warntype_to); | 1574 | flush_warnings(transfer_to, warntype_to); |
1482 | flush_warnings(transfer_from, warntype_from_inodes); | 1575 | flush_warnings(transfer_from, warntype_from_inodes); |
1483 | flush_warnings(transfer_from, warntype_from_space); | 1576 | flush_warnings(transfer_from, warntype_from_space); |
1484 | 1577 | put_all: | |
1485 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1578 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1486 | if (ret == QUOTA_OK && transfer_from[cnt] != NODQUOT) | 1579 | dqput(transfer_from[cnt]); |
1487 | dqput(transfer_from[cnt]); | 1580 | dqput(transfer_to[cnt]); |
1488 | if (ret == NO_QUOTA && transfer_to[cnt] != NODQUOT) | ||
1489 | dqput(transfer_to[cnt]); | ||
1490 | } | 1581 | } |
1491 | up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | ||
1492 | return ret; | 1582 | return ret; |
1583 | over_quota: | ||
1584 | spin_unlock(&dq_data_lock); | ||
1585 | up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | ||
1586 | /* Clear dquot pointers we don't want to dqput() */ | ||
1587 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | ||
1588 | transfer_from[cnt] = NODQUOT; | ||
1589 | ret = NO_QUOTA; | ||
1590 | goto warn_put_all; | ||
1493 | } | 1591 | } |
1494 | 1592 | ||
1495 | /* Wrapper for transferring ownership of an inode */ | 1593 | /* Wrapper for transferring ownership of an inode */ |
1496 | int vfs_dq_transfer(struct inode *inode, struct iattr *iattr) | 1594 | int vfs_dq_transfer(struct inode *inode, struct iattr *iattr) |
1497 | { | 1595 | { |
1498 | if (sb_any_quota_enabled(inode->i_sb) && !IS_NOQUOTA(inode)) { | 1596 | if (sb_any_quota_active(inode->i_sb) && !IS_NOQUOTA(inode)) { |
1499 | vfs_dq_init(inode); | 1597 | vfs_dq_init(inode); |
1500 | if (inode->i_sb->dq_op->transfer(inode, iattr) == NO_QUOTA) | 1598 | if (inode->i_sb->dq_op->transfer(inode, iattr) == NO_QUOTA) |
1501 | return 1; | 1599 | return 1; |
@@ -1533,54 +1631,27 @@ struct dquot_operations dquot_operations = { | |||
1533 | .acquire_dquot = dquot_acquire, | 1631 | .acquire_dquot = dquot_acquire, |
1534 | .release_dquot = dquot_release, | 1632 | .release_dquot = dquot_release, |
1535 | .mark_dirty = dquot_mark_dquot_dirty, | 1633 | .mark_dirty = dquot_mark_dquot_dirty, |
1536 | .write_info = dquot_commit_info | 1634 | .write_info = dquot_commit_info, |
1635 | .alloc_dquot = dquot_alloc, | ||
1636 | .destroy_dquot = dquot_destroy, | ||
1537 | }; | 1637 | }; |
1538 | 1638 | ||
1539 | static inline void set_enable_flags(struct quota_info *dqopt, int type) | ||
1540 | { | ||
1541 | switch (type) { | ||
1542 | case USRQUOTA: | ||
1543 | dqopt->flags |= DQUOT_USR_ENABLED; | ||
1544 | dqopt->flags &= ~DQUOT_USR_SUSPENDED; | ||
1545 | break; | ||
1546 | case GRPQUOTA: | ||
1547 | dqopt->flags |= DQUOT_GRP_ENABLED; | ||
1548 | dqopt->flags &= ~DQUOT_GRP_SUSPENDED; | ||
1549 | break; | ||
1550 | } | ||
1551 | } | ||
1552 | |||
1553 | static inline void reset_enable_flags(struct quota_info *dqopt, int type, | ||
1554 | int remount) | ||
1555 | { | ||
1556 | switch (type) { | ||
1557 | case USRQUOTA: | ||
1558 | dqopt->flags &= ~DQUOT_USR_ENABLED; | ||
1559 | if (remount) | ||
1560 | dqopt->flags |= DQUOT_USR_SUSPENDED; | ||
1561 | else | ||
1562 | dqopt->flags &= ~DQUOT_USR_SUSPENDED; | ||
1563 | break; | ||
1564 | case GRPQUOTA: | ||
1565 | dqopt->flags &= ~DQUOT_GRP_ENABLED; | ||
1566 | if (remount) | ||
1567 | dqopt->flags |= DQUOT_GRP_SUSPENDED; | ||
1568 | else | ||
1569 | dqopt->flags &= ~DQUOT_GRP_SUSPENDED; | ||
1570 | break; | ||
1571 | } | ||
1572 | } | ||
1573 | |||
1574 | |||
1575 | /* | 1639 | /* |
1576 | * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount) | 1640 | * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount) |
1577 | */ | 1641 | */ |
1578 | int vfs_quota_off(struct super_block *sb, int type, int remount) | 1642 | int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags) |
1579 | { | 1643 | { |
1580 | int cnt, ret = 0; | 1644 | int cnt, ret = 0; |
1581 | struct quota_info *dqopt = sb_dqopt(sb); | 1645 | struct quota_info *dqopt = sb_dqopt(sb); |
1582 | struct inode *toputinode[MAXQUOTAS]; | 1646 | struct inode *toputinode[MAXQUOTAS]; |
1583 | 1647 | ||
1648 | /* Cannot turn off usage accounting without turning off limits, or | ||
1649 | * suspend quotas and simultaneously turn quotas off. */ | ||
1650 | if ((flags & DQUOT_USAGE_ENABLED && !(flags & DQUOT_LIMITS_ENABLED)) | ||
1651 | || (flags & DQUOT_SUSPENDED && flags & (DQUOT_LIMITS_ENABLED | | ||
1652 | DQUOT_USAGE_ENABLED))) | ||
1653 | return -EINVAL; | ||
1654 | |||
1584 | /* We need to serialize quota_off() for device */ | 1655 | /* We need to serialize quota_off() for device */ |
1585 | mutex_lock(&dqopt->dqonoff_mutex); | 1656 | mutex_lock(&dqopt->dqonoff_mutex); |
1586 | 1657 | ||
@@ -1589,7 +1660,7 @@ int vfs_quota_off(struct super_block *sb, int type, int remount) | |||
1589 | * sometimes we are called when fill_super() failed and calling | 1660 | * sometimes we are called when fill_super() failed and calling |
1590 | * sync_fs() in such cases does no good. | 1661 | * sync_fs() in such cases does no good. |
1591 | */ | 1662 | */ |
1592 | if (!sb_any_quota_enabled(sb) && !sb_any_quota_suspended(sb)) { | 1663 | if (!sb_any_quota_loaded(sb)) { |
1593 | mutex_unlock(&dqopt->dqonoff_mutex); | 1664 | mutex_unlock(&dqopt->dqonoff_mutex); |
1594 | return 0; | 1665 | return 0; |
1595 | } | 1666 | } |
@@ -1597,17 +1668,33 @@ int vfs_quota_off(struct super_block *sb, int type, int remount) | |||
1597 | toputinode[cnt] = NULL; | 1668 | toputinode[cnt] = NULL; |
1598 | if (type != -1 && cnt != type) | 1669 | if (type != -1 && cnt != type) |
1599 | continue; | 1670 | continue; |
1600 | /* If we keep inodes of quota files after remount and quotaoff | 1671 | if (!sb_has_quota_loaded(sb, cnt)) |
1601 | * is called, drop kept inodes. */ | ||
1602 | if (!remount && sb_has_quota_suspended(sb, cnt)) { | ||
1603 | iput(dqopt->files[cnt]); | ||
1604 | dqopt->files[cnt] = NULL; | ||
1605 | reset_enable_flags(dqopt, cnt, 0); | ||
1606 | continue; | 1672 | continue; |
1673 | |||
1674 | if (flags & DQUOT_SUSPENDED) { | ||
1675 | spin_lock(&dq_state_lock); | ||
1676 | dqopt->flags |= | ||
1677 | dquot_state_flag(DQUOT_SUSPENDED, cnt); | ||
1678 | spin_unlock(&dq_state_lock); | ||
1679 | } else { | ||
1680 | spin_lock(&dq_state_lock); | ||
1681 | dqopt->flags &= ~dquot_state_flag(flags, cnt); | ||
1682 | /* Turning off suspended quotas? */ | ||
1683 | if (!sb_has_quota_loaded(sb, cnt) && | ||
1684 | sb_has_quota_suspended(sb, cnt)) { | ||
1685 | dqopt->flags &= ~dquot_state_flag( | ||
1686 | DQUOT_SUSPENDED, cnt); | ||
1687 | spin_unlock(&dq_state_lock); | ||
1688 | iput(dqopt->files[cnt]); | ||
1689 | dqopt->files[cnt] = NULL; | ||
1690 | continue; | ||
1691 | } | ||
1692 | spin_unlock(&dq_state_lock); | ||
1607 | } | 1693 | } |
1608 | if (!sb_has_quota_enabled(sb, cnt)) | 1694 | |
1695 | /* We still have to keep quota loaded? */ | ||
1696 | if (sb_has_quota_loaded(sb, cnt) && !(flags & DQUOT_SUSPENDED)) | ||
1609 | continue; | 1697 | continue; |
1610 | reset_enable_flags(dqopt, cnt, remount); | ||
1611 | 1698 | ||
1612 | /* Note: these are blocking operations */ | 1699 | /* Note: these are blocking operations */ |
1613 | drop_dquot_ref(sb, cnt); | 1700 | drop_dquot_ref(sb, cnt); |
@@ -1623,7 +1710,7 @@ int vfs_quota_off(struct super_block *sb, int type, int remount) | |||
1623 | put_quota_format(dqopt->info[cnt].dqi_format); | 1710 | put_quota_format(dqopt->info[cnt].dqi_format); |
1624 | 1711 | ||
1625 | toputinode[cnt] = dqopt->files[cnt]; | 1712 | toputinode[cnt] = dqopt->files[cnt]; |
1626 | if (!remount) | 1713 | if (!sb_has_quota_loaded(sb, cnt)) |
1627 | dqopt->files[cnt] = NULL; | 1714 | dqopt->files[cnt] = NULL; |
1628 | dqopt->info[cnt].dqi_flags = 0; | 1715 | dqopt->info[cnt].dqi_flags = 0; |
1629 | dqopt->info[cnt].dqi_igrace = 0; | 1716 | dqopt->info[cnt].dqi_igrace = 0; |
@@ -1631,6 +1718,11 @@ int vfs_quota_off(struct super_block *sb, int type, int remount) | |||
1631 | dqopt->ops[cnt] = NULL; | 1718 | dqopt->ops[cnt] = NULL; |
1632 | } | 1719 | } |
1633 | mutex_unlock(&dqopt->dqonoff_mutex); | 1720 | mutex_unlock(&dqopt->dqonoff_mutex); |
1721 | |||
1722 | /* Skip syncing and setting flags if quota files are hidden */ | ||
1723 | if (dqopt->flags & DQUOT_QUOTA_SYS_FILE) | ||
1724 | goto put_inodes; | ||
1725 | |||
1634 | /* Sync the superblock so that buffers with quota data are written to | 1726 | /* Sync the superblock so that buffers with quota data are written to |
1635 | * disk (and so userspace sees correct data afterwards). */ | 1727 | * disk (and so userspace sees correct data afterwards). */ |
1636 | if (sb->s_op->sync_fs) | 1728 | if (sb->s_op->sync_fs) |
@@ -1646,7 +1738,7 @@ int vfs_quota_off(struct super_block *sb, int type, int remount) | |||
1646 | mutex_lock(&dqopt->dqonoff_mutex); | 1738 | mutex_lock(&dqopt->dqonoff_mutex); |
1647 | /* If quota was reenabled in the meantime, we have | 1739 | /* If quota was reenabled in the meantime, we have |
1648 | * nothing to do */ | 1740 | * nothing to do */ |
1649 | if (!sb_has_quota_enabled(sb, cnt)) { | 1741 | if (!sb_has_quota_loaded(sb, cnt)) { |
1650 | mutex_lock_nested(&toputinode[cnt]->i_mutex, I_MUTEX_QUOTA); | 1742 | mutex_lock_nested(&toputinode[cnt]->i_mutex, I_MUTEX_QUOTA); |
1651 | toputinode[cnt]->i_flags &= ~(S_IMMUTABLE | | 1743 | toputinode[cnt]->i_flags &= ~(S_IMMUTABLE | |
1652 | S_NOATIME | S_NOQUOTA); | 1744 | S_NOATIME | S_NOQUOTA); |
@@ -1655,26 +1747,43 @@ int vfs_quota_off(struct super_block *sb, int type, int remount) | |||
1655 | mark_inode_dirty(toputinode[cnt]); | 1747 | mark_inode_dirty(toputinode[cnt]); |
1656 | } | 1748 | } |
1657 | mutex_unlock(&dqopt->dqonoff_mutex); | 1749 | mutex_unlock(&dqopt->dqonoff_mutex); |
1750 | } | ||
1751 | if (sb->s_bdev) | ||
1752 | invalidate_bdev(sb->s_bdev); | ||
1753 | put_inodes: | ||
1754 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | ||
1755 | if (toputinode[cnt]) { | ||
1658 | /* On remount RO, we keep the inode pointer so that we | 1756 | /* On remount RO, we keep the inode pointer so that we |
1659 | * can reenable quota on the subsequent remount RW. | 1757 | * can reenable quota on the subsequent remount RW. We |
1660 | * But we have better not keep inode pointer when there | 1758 | * have to check 'flags' variable and not use sb_has_ |
1661 | * is pending delete on the quota file... */ | 1759 | * function because another quotaon / quotaoff could |
1662 | if (!remount) | 1760 | * change global state before we got here. We refuse |
1761 | * to suspend quotas when there is pending delete on | ||
1762 | * the quota file... */ | ||
1763 | if (!(flags & DQUOT_SUSPENDED)) | ||
1663 | iput(toputinode[cnt]); | 1764 | iput(toputinode[cnt]); |
1664 | else if (!toputinode[cnt]->i_nlink) | 1765 | else if (!toputinode[cnt]->i_nlink) |
1665 | ret = -EBUSY; | 1766 | ret = -EBUSY; |
1666 | } | 1767 | } |
1667 | if (sb->s_bdev) | ||
1668 | invalidate_bdev(sb->s_bdev); | ||
1669 | return ret; | 1768 | return ret; |
1670 | } | 1769 | } |
1671 | 1770 | ||
1771 | int vfs_quota_off(struct super_block *sb, int type, int remount) | ||
1772 | { | ||
1773 | return vfs_quota_disable(sb, type, remount ? DQUOT_SUSPENDED : | ||
1774 | (DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED)); | ||
1775 | } | ||
1776 | |||
1672 | /* | 1777 | /* |
1673 | * Turn quotas on on a device | 1778 | * Turn quotas on on a device |
1674 | */ | 1779 | */ |
1675 | 1780 | ||
1676 | /* Helper function when we already have the inode */ | 1781 | /* |
1677 | static int vfs_quota_on_inode(struct inode *inode, int type, int format_id) | 1782 | * Helper function to turn quotas on when we already have the inode of |
1783 | * quota file and no quota information is loaded. | ||
1784 | */ | ||
1785 | static int vfs_load_quota_inode(struct inode *inode, int type, int format_id, | ||
1786 | unsigned int flags) | ||
1678 | { | 1787 | { |
1679 | struct quota_format_type *fmt = find_quota_format(format_id); | 1788 | struct quota_format_type *fmt = find_quota_format(format_id); |
1680 | struct super_block *sb = inode->i_sb; | 1789 | struct super_block *sb = inode->i_sb; |
@@ -1696,27 +1805,37 @@ static int vfs_quota_on_inode(struct inode *inode, int type, int format_id) | |||
1696 | error = -EINVAL; | 1805 | error = -EINVAL; |
1697 | goto out_fmt; | 1806 | goto out_fmt; |
1698 | } | 1807 | } |
1808 | /* Usage always has to be set... */ | ||
1809 | if (!(flags & DQUOT_USAGE_ENABLED)) { | ||
1810 | error = -EINVAL; | ||
1811 | goto out_fmt; | ||
1812 | } | ||
1699 | 1813 | ||
1700 | /* As we bypass the pagecache we must now flush the inode so that | 1814 | if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE)) { |
1701 | * we see all the changes from userspace... */ | 1815 | /* As we bypass the pagecache we must now flush the inode so |
1702 | write_inode_now(inode, 1); | 1816 | * that we see all the changes from userspace... */ |
1703 | /* And now flush the block cache so that kernel sees the changes */ | 1817 | write_inode_now(inode, 1); |
1704 | invalidate_bdev(sb->s_bdev); | 1818 | /* And now flush the block cache so that kernel sees the |
1819 | * changes */ | ||
1820 | invalidate_bdev(sb->s_bdev); | ||
1821 | } | ||
1705 | mutex_lock(&inode->i_mutex); | 1822 | mutex_lock(&inode->i_mutex); |
1706 | mutex_lock(&dqopt->dqonoff_mutex); | 1823 | mutex_lock(&dqopt->dqonoff_mutex); |
1707 | if (sb_has_quota_enabled(sb, type) || | 1824 | if (sb_has_quota_loaded(sb, type)) { |
1708 | sb_has_quota_suspended(sb, type)) { | ||
1709 | error = -EBUSY; | 1825 | error = -EBUSY; |
1710 | goto out_lock; | 1826 | goto out_lock; |
1711 | } | 1827 | } |
1712 | /* We don't want quota and atime on quota files (deadlocks possible) | 1828 | |
1713 | * Also nobody should write to the file - we use special IO operations | 1829 | if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE)) { |
1714 | * which ignore the immutable bit. */ | 1830 | /* We don't want quota and atime on quota files (deadlocks |
1715 | down_write(&dqopt->dqptr_sem); | 1831 | * possible) Also nobody should write to the file - we use |
1716 | oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE | S_NOQUOTA); | 1832 | * special IO operations which ignore the immutable bit. */ |
1717 | inode->i_flags |= S_NOQUOTA | S_NOATIME | S_IMMUTABLE; | 1833 | down_write(&dqopt->dqptr_sem); |
1718 | up_write(&dqopt->dqptr_sem); | 1834 | oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE | S_NOQUOTA); |
1719 | sb->dq_op->drop(inode); | 1835 | inode->i_flags |= S_NOQUOTA | S_NOATIME | S_IMMUTABLE; |
1836 | up_write(&dqopt->dqptr_sem); | ||
1837 | sb->dq_op->drop(inode); | ||
1838 | } | ||
1720 | 1839 | ||
1721 | error = -EIO; | 1840 | error = -EIO; |
1722 | dqopt->files[type] = igrab(inode); | 1841 | dqopt->files[type] = igrab(inode); |
@@ -1737,7 +1856,9 @@ static int vfs_quota_on_inode(struct inode *inode, int type, int format_id) | |||
1737 | } | 1856 | } |
1738 | mutex_unlock(&dqopt->dqio_mutex); | 1857 | mutex_unlock(&dqopt->dqio_mutex); |
1739 | mutex_unlock(&inode->i_mutex); | 1858 | mutex_unlock(&inode->i_mutex); |
1740 | set_enable_flags(dqopt, type); | 1859 | spin_lock(&dq_state_lock); |
1860 | dqopt->flags |= dquot_state_flag(flags, type); | ||
1861 | spin_unlock(&dq_state_lock); | ||
1741 | 1862 | ||
1742 | add_dquot_ref(sb, type); | 1863 | add_dquot_ref(sb, type); |
1743 | mutex_unlock(&dqopt->dqonoff_mutex); | 1864 | mutex_unlock(&dqopt->dqonoff_mutex); |
@@ -1770,20 +1891,25 @@ static int vfs_quota_on_remount(struct super_block *sb, int type) | |||
1770 | struct quota_info *dqopt = sb_dqopt(sb); | 1891 | struct quota_info *dqopt = sb_dqopt(sb); |
1771 | struct inode *inode; | 1892 | struct inode *inode; |
1772 | int ret; | 1893 | int ret; |
1894 | unsigned int flags; | ||
1773 | 1895 | ||
1774 | mutex_lock(&dqopt->dqonoff_mutex); | 1896 | mutex_lock(&dqopt->dqonoff_mutex); |
1775 | if (!sb_has_quota_suspended(sb, type)) { | 1897 | if (!sb_has_quota_suspended(sb, type)) { |
1776 | mutex_unlock(&dqopt->dqonoff_mutex); | 1898 | mutex_unlock(&dqopt->dqonoff_mutex); |
1777 | return 0; | 1899 | return 0; |
1778 | } | 1900 | } |
1779 | BUG_ON(sb_has_quota_enabled(sb, type)); | ||
1780 | |||
1781 | inode = dqopt->files[type]; | 1901 | inode = dqopt->files[type]; |
1782 | dqopt->files[type] = NULL; | 1902 | dqopt->files[type] = NULL; |
1783 | reset_enable_flags(dqopt, type, 0); | 1903 | spin_lock(&dq_state_lock); |
1904 | flags = dqopt->flags & dquot_state_flag(DQUOT_USAGE_ENABLED | | ||
1905 | DQUOT_LIMITS_ENABLED, type); | ||
1906 | dqopt->flags &= ~dquot_state_flag(DQUOT_STATE_FLAGS, type); | ||
1907 | spin_unlock(&dq_state_lock); | ||
1784 | mutex_unlock(&dqopt->dqonoff_mutex); | 1908 | mutex_unlock(&dqopt->dqonoff_mutex); |
1785 | 1909 | ||
1786 | ret = vfs_quota_on_inode(inode, type, dqopt->info[type].dqi_fmt_id); | 1910 | flags = dquot_generic_flag(flags, type); |
1911 | ret = vfs_load_quota_inode(inode, type, dqopt->info[type].dqi_fmt_id, | ||
1912 | flags); | ||
1787 | iput(inode); | 1913 | iput(inode); |
1788 | 1914 | ||
1789 | return ret; | 1915 | return ret; |
@@ -1799,12 +1925,12 @@ int vfs_quota_on_path(struct super_block *sb, int type, int format_id, | |||
1799 | if (path->mnt->mnt_sb != sb) | 1925 | if (path->mnt->mnt_sb != sb) |
1800 | error = -EXDEV; | 1926 | error = -EXDEV; |
1801 | else | 1927 | else |
1802 | error = vfs_quota_on_inode(path->dentry->d_inode, type, | 1928 | error = vfs_load_quota_inode(path->dentry->d_inode, type, |
1803 | format_id); | 1929 | format_id, DQUOT_USAGE_ENABLED | |
1930 | DQUOT_LIMITS_ENABLED); | ||
1804 | return error; | 1931 | return error; |
1805 | } | 1932 | } |
1806 | 1933 | ||
1807 | /* Actual function called from quotactl() */ | ||
1808 | int vfs_quota_on(struct super_block *sb, int type, int format_id, char *name, | 1934 | int vfs_quota_on(struct super_block *sb, int type, int format_id, char *name, |
1809 | int remount) | 1935 | int remount) |
1810 | { | 1936 | { |
@@ -1823,6 +1949,52 @@ int vfs_quota_on(struct super_block *sb, int type, int format_id, char *name, | |||
1823 | } | 1949 | } |
1824 | 1950 | ||
1825 | /* | 1951 | /* |
1952 | * More powerful function for turning on quotas allowing setting | ||
1953 | * of individual quota flags | ||
1954 | */ | ||
1955 | int vfs_quota_enable(struct inode *inode, int type, int format_id, | ||
1956 | unsigned int flags) | ||
1957 | { | ||
1958 | int ret = 0; | ||
1959 | struct super_block *sb = inode->i_sb; | ||
1960 | struct quota_info *dqopt = sb_dqopt(sb); | ||
1961 | |||
1962 | /* Just unsuspend quotas? */ | ||
1963 | if (flags & DQUOT_SUSPENDED) | ||
1964 | return vfs_quota_on_remount(sb, type); | ||
1965 | if (!flags) | ||
1966 | return 0; | ||
1967 | /* Just updating flags needed? */ | ||
1968 | if (sb_has_quota_loaded(sb, type)) { | ||
1969 | mutex_lock(&dqopt->dqonoff_mutex); | ||
1970 | /* Now do a reliable test... */ | ||
1971 | if (!sb_has_quota_loaded(sb, type)) { | ||
1972 | mutex_unlock(&dqopt->dqonoff_mutex); | ||
1973 | goto load_quota; | ||
1974 | } | ||
1975 | if (flags & DQUOT_USAGE_ENABLED && | ||
1976 | sb_has_quota_usage_enabled(sb, type)) { | ||
1977 | ret = -EBUSY; | ||
1978 | goto out_lock; | ||
1979 | } | ||
1980 | if (flags & DQUOT_LIMITS_ENABLED && | ||
1981 | sb_has_quota_limits_enabled(sb, type)) { | ||
1982 | ret = -EBUSY; | ||
1983 | goto out_lock; | ||
1984 | } | ||
1985 | spin_lock(&dq_state_lock); | ||
1986 | sb_dqopt(sb)->flags |= dquot_state_flag(flags, type); | ||
1987 | spin_unlock(&dq_state_lock); | ||
1988 | out_lock: | ||
1989 | mutex_unlock(&dqopt->dqonoff_mutex); | ||
1990 | return ret; | ||
1991 | } | ||
1992 | |||
1993 | load_quota: | ||
1994 | return vfs_load_quota_inode(inode, type, format_id, flags); | ||
1995 | } | ||
1996 | |||
1997 | /* | ||
1826 | * This function is used when filesystem needs to initialize quotas | 1998 | * This function is used when filesystem needs to initialize quotas |
1827 | * during mount time. | 1999 | * during mount time. |
1828 | */ | 2000 | */ |
@@ -1843,7 +2015,8 @@ int vfs_quota_on_mount(struct super_block *sb, char *qf_name, | |||
1843 | 2015 | ||
1844 | error = security_quota_on(dentry); | 2016 | error = security_quota_on(dentry); |
1845 | if (!error) | 2017 | if (!error) |
1846 | error = vfs_quota_on_inode(dentry->d_inode, type, format_id); | 2018 | error = vfs_load_quota_inode(dentry->d_inode, type, format_id, |
2019 | DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); | ||
1847 | 2020 | ||
1848 | out: | 2021 | out: |
1849 | dput(dentry); | 2022 | dput(dentry); |
@@ -1866,14 +2039,24 @@ int vfs_dq_quota_on_remount(struct super_block *sb) | |||
1866 | return ret; | 2039 | return ret; |
1867 | } | 2040 | } |
1868 | 2041 | ||
2042 | static inline qsize_t qbtos(qsize_t blocks) | ||
2043 | { | ||
2044 | return blocks << QIF_DQBLKSIZE_BITS; | ||
2045 | } | ||
2046 | |||
2047 | static inline qsize_t stoqb(qsize_t space) | ||
2048 | { | ||
2049 | return (space + QIF_DQBLKSIZE - 1) >> QIF_DQBLKSIZE_BITS; | ||
2050 | } | ||
2051 | |||
1869 | /* Generic routine for getting common part of quota structure */ | 2052 | /* Generic routine for getting common part of quota structure */ |
1870 | static void do_get_dqblk(struct dquot *dquot, struct if_dqblk *di) | 2053 | static void do_get_dqblk(struct dquot *dquot, struct if_dqblk *di) |
1871 | { | 2054 | { |
1872 | struct mem_dqblk *dm = &dquot->dq_dqb; | 2055 | struct mem_dqblk *dm = &dquot->dq_dqb; |
1873 | 2056 | ||
1874 | spin_lock(&dq_data_lock); | 2057 | spin_lock(&dq_data_lock); |
1875 | di->dqb_bhardlimit = dm->dqb_bhardlimit; | 2058 | di->dqb_bhardlimit = stoqb(dm->dqb_bhardlimit); |
1876 | di->dqb_bsoftlimit = dm->dqb_bsoftlimit; | 2059 | di->dqb_bsoftlimit = stoqb(dm->dqb_bsoftlimit); |
1877 | di->dqb_curspace = dm->dqb_curspace; | 2060 | di->dqb_curspace = dm->dqb_curspace; |
1878 | di->dqb_ihardlimit = dm->dqb_ihardlimit; | 2061 | di->dqb_ihardlimit = dm->dqb_ihardlimit; |
1879 | di->dqb_isoftlimit = dm->dqb_isoftlimit; | 2062 | di->dqb_isoftlimit = dm->dqb_isoftlimit; |
@@ -1888,14 +2071,12 @@ int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *d | |||
1888 | { | 2071 | { |
1889 | struct dquot *dquot; | 2072 | struct dquot *dquot; |
1890 | 2073 | ||
1891 | mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); | 2074 | dquot = dqget(sb, id, type); |
1892 | if (!(dquot = dqget(sb, id, type))) { | 2075 | if (dquot == NODQUOT) |
1893 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); | ||
1894 | return -ESRCH; | 2076 | return -ESRCH; |
1895 | } | ||
1896 | do_get_dqblk(dquot, di); | 2077 | do_get_dqblk(dquot, di); |
1897 | dqput(dquot); | 2078 | dqput(dquot); |
1898 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); | 2079 | |
1899 | return 0; | 2080 | return 0; |
1900 | } | 2081 | } |
1901 | 2082 | ||
@@ -1918,28 +2099,38 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di) | |||
1918 | if (di->dqb_valid & QIF_SPACE) { | 2099 | if (di->dqb_valid & QIF_SPACE) { |
1919 | dm->dqb_curspace = di->dqb_curspace; | 2100 | dm->dqb_curspace = di->dqb_curspace; |
1920 | check_blim = 1; | 2101 | check_blim = 1; |
2102 | __set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags); | ||
1921 | } | 2103 | } |
1922 | if (di->dqb_valid & QIF_BLIMITS) { | 2104 | if (di->dqb_valid & QIF_BLIMITS) { |
1923 | dm->dqb_bsoftlimit = di->dqb_bsoftlimit; | 2105 | dm->dqb_bsoftlimit = qbtos(di->dqb_bsoftlimit); |
1924 | dm->dqb_bhardlimit = di->dqb_bhardlimit; | 2106 | dm->dqb_bhardlimit = qbtos(di->dqb_bhardlimit); |
1925 | check_blim = 1; | 2107 | check_blim = 1; |
2108 | __set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags); | ||
1926 | } | 2109 | } |
1927 | if (di->dqb_valid & QIF_INODES) { | 2110 | if (di->dqb_valid & QIF_INODES) { |
1928 | dm->dqb_curinodes = di->dqb_curinodes; | 2111 | dm->dqb_curinodes = di->dqb_curinodes; |
1929 | check_ilim = 1; | 2112 | check_ilim = 1; |
2113 | __set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags); | ||
1930 | } | 2114 | } |
1931 | if (di->dqb_valid & QIF_ILIMITS) { | 2115 | if (di->dqb_valid & QIF_ILIMITS) { |
1932 | dm->dqb_isoftlimit = di->dqb_isoftlimit; | 2116 | dm->dqb_isoftlimit = di->dqb_isoftlimit; |
1933 | dm->dqb_ihardlimit = di->dqb_ihardlimit; | 2117 | dm->dqb_ihardlimit = di->dqb_ihardlimit; |
1934 | check_ilim = 1; | 2118 | check_ilim = 1; |
2119 | __set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags); | ||
1935 | } | 2120 | } |
1936 | if (di->dqb_valid & QIF_BTIME) | 2121 | if (di->dqb_valid & QIF_BTIME) { |
1937 | dm->dqb_btime = di->dqb_btime; | 2122 | dm->dqb_btime = di->dqb_btime; |
1938 | if (di->dqb_valid & QIF_ITIME) | 2123 | check_blim = 1; |
2124 | __set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags); | ||
2125 | } | ||
2126 | if (di->dqb_valid & QIF_ITIME) { | ||
1939 | dm->dqb_itime = di->dqb_itime; | 2127 | dm->dqb_itime = di->dqb_itime; |
2128 | check_ilim = 1; | ||
2129 | __set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags); | ||
2130 | } | ||
1940 | 2131 | ||
1941 | if (check_blim) { | 2132 | if (check_blim) { |
1942 | if (!dm->dqb_bsoftlimit || toqb(dm->dqb_curspace) < dm->dqb_bsoftlimit) { | 2133 | if (!dm->dqb_bsoftlimit || dm->dqb_curspace < dm->dqb_bsoftlimit) { |
1943 | dm->dqb_btime = 0; | 2134 | dm->dqb_btime = 0; |
1944 | clear_bit(DQ_BLKS_B, &dquot->dq_flags); | 2135 | clear_bit(DQ_BLKS_B, &dquot->dq_flags); |
1945 | } | 2136 | } |
@@ -1969,14 +2160,14 @@ int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *d | |||
1969 | struct dquot *dquot; | 2160 | struct dquot *dquot; |
1970 | int rc; | 2161 | int rc; |
1971 | 2162 | ||
1972 | mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); | 2163 | dquot = dqget(sb, id, type); |
1973 | if (!(dquot = dqget(sb, id, type))) { | 2164 | if (!dquot) { |
1974 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); | 2165 | rc = -ESRCH; |
1975 | return -ESRCH; | 2166 | goto out; |
1976 | } | 2167 | } |
1977 | rc = do_set_dqblk(dquot, di); | 2168 | rc = do_set_dqblk(dquot, di); |
1978 | dqput(dquot); | 2169 | dqput(dquot); |
1979 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); | 2170 | out: |
1980 | return rc; | 2171 | return rc; |
1981 | } | 2172 | } |
1982 | 2173 | ||
@@ -1986,7 +2177,7 @@ int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) | |||
1986 | struct mem_dqinfo *mi; | 2177 | struct mem_dqinfo *mi; |
1987 | 2178 | ||
1988 | mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); | 2179 | mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); |
1989 | if (!sb_has_quota_enabled(sb, type)) { | 2180 | if (!sb_has_quota_active(sb, type)) { |
1990 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); | 2181 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); |
1991 | return -ESRCH; | 2182 | return -ESRCH; |
1992 | } | 2183 | } |
@@ -2005,11 +2196,12 @@ int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) | |||
2005 | int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) | 2196 | int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) |
2006 | { | 2197 | { |
2007 | struct mem_dqinfo *mi; | 2198 | struct mem_dqinfo *mi; |
2199 | int err = 0; | ||
2008 | 2200 | ||
2009 | mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); | 2201 | mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); |
2010 | if (!sb_has_quota_enabled(sb, type)) { | 2202 | if (!sb_has_quota_active(sb, type)) { |
2011 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); | 2203 | err = -ESRCH; |
2012 | return -ESRCH; | 2204 | goto out; |
2013 | } | 2205 | } |
2014 | mi = sb_dqopt(sb)->info + type; | 2206 | mi = sb_dqopt(sb)->info + type; |
2015 | spin_lock(&dq_data_lock); | 2207 | spin_lock(&dq_data_lock); |
@@ -2023,8 +2215,9 @@ int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) | |||
2023 | mark_info_dirty(sb, type); | 2215 | mark_info_dirty(sb, type); |
2024 | /* Force write to disk */ | 2216 | /* Force write to disk */ |
2025 | sb->dq_op->write_info(sb, type); | 2217 | sb->dq_op->write_info(sb, type); |
2218 | out: | ||
2026 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); | 2219 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); |
2027 | return 0; | 2220 | return err; |
2028 | } | 2221 | } |
2029 | 2222 | ||
2030 | struct quotactl_ops vfs_quotactl_ops = { | 2223 | struct quotactl_ops vfs_quotactl_ops = { |
@@ -2186,10 +2379,13 @@ EXPORT_SYMBOL(register_quota_format); | |||
2186 | EXPORT_SYMBOL(unregister_quota_format); | 2379 | EXPORT_SYMBOL(unregister_quota_format); |
2187 | EXPORT_SYMBOL(dqstats); | 2380 | EXPORT_SYMBOL(dqstats); |
2188 | EXPORT_SYMBOL(dq_data_lock); | 2381 | EXPORT_SYMBOL(dq_data_lock); |
2382 | EXPORT_SYMBOL(vfs_quota_enable); | ||
2189 | EXPORT_SYMBOL(vfs_quota_on); | 2383 | EXPORT_SYMBOL(vfs_quota_on); |
2190 | EXPORT_SYMBOL(vfs_quota_on_path); | 2384 | EXPORT_SYMBOL(vfs_quota_on_path); |
2191 | EXPORT_SYMBOL(vfs_quota_on_mount); | 2385 | EXPORT_SYMBOL(vfs_quota_on_mount); |
2386 | EXPORT_SYMBOL(vfs_quota_disable); | ||
2192 | EXPORT_SYMBOL(vfs_quota_off); | 2387 | EXPORT_SYMBOL(vfs_quota_off); |
2388 | EXPORT_SYMBOL(dquot_scan_active); | ||
2193 | EXPORT_SYMBOL(vfs_quota_sync); | 2389 | EXPORT_SYMBOL(vfs_quota_sync); |
2194 | EXPORT_SYMBOL(vfs_get_dqinfo); | 2390 | EXPORT_SYMBOL(vfs_get_dqinfo); |
2195 | EXPORT_SYMBOL(vfs_set_dqinfo); | 2391 | EXPORT_SYMBOL(vfs_set_dqinfo); |
@@ -2203,6 +2399,8 @@ EXPORT_SYMBOL(dquot_mark_dquot_dirty); | |||
2203 | EXPORT_SYMBOL(dquot_initialize); | 2399 | EXPORT_SYMBOL(dquot_initialize); |
2204 | EXPORT_SYMBOL(dquot_drop); | 2400 | EXPORT_SYMBOL(dquot_drop); |
2205 | EXPORT_SYMBOL(vfs_dq_drop); | 2401 | EXPORT_SYMBOL(vfs_dq_drop); |
2402 | EXPORT_SYMBOL(dqget); | ||
2403 | EXPORT_SYMBOL(dqput); | ||
2206 | EXPORT_SYMBOL(dquot_alloc_space); | 2404 | EXPORT_SYMBOL(dquot_alloc_space); |
2207 | EXPORT_SYMBOL(dquot_alloc_inode); | 2405 | EXPORT_SYMBOL(dquot_alloc_inode); |
2208 | EXPORT_SYMBOL(dquot_free_space); | 2406 | EXPORT_SYMBOL(dquot_free_space); |