diff options
Diffstat (limited to 'fs/dquot.c')
-rw-r--r-- | fs/dquot.c | 436 |
1 files changed, 303 insertions, 133 deletions
diff --git a/fs/dquot.c b/fs/dquot.c index c237ccc8581c..61bfff64e5af 100644 --- a/fs/dquot.c +++ b/fs/dquot.c | |||
@@ -211,8 +211,6 @@ static struct hlist_head *dquot_hash; | |||
211 | 211 | ||
212 | struct dqstats dqstats; | 212 | struct dqstats dqstats; |
213 | 213 | ||
214 | static void dqput(struct dquot *dquot); | ||
215 | |||
216 | static inline unsigned int | 214 | static inline unsigned int |
217 | hashfn(const struct super_block *sb, unsigned int id, int type) | 215 | hashfn(const struct super_block *sb, unsigned int id, int type) |
218 | { | 216 | { |
@@ -415,6 +413,17 @@ out_dqlock: | |||
415 | return ret; | 413 | return ret; |
416 | } | 414 | } |
417 | 415 | ||
416 | void dquot_destroy(struct dquot *dquot) | ||
417 | { | ||
418 | kmem_cache_free(dquot_cachep, dquot); | ||
419 | } | ||
420 | EXPORT_SYMBOL(dquot_destroy); | ||
421 | |||
422 | static inline void do_destroy_dquot(struct dquot *dquot) | ||
423 | { | ||
424 | dquot->dq_sb->dq_op->destroy_dquot(dquot); | ||
425 | } | ||
426 | |||
418 | /* Invalidate all dquots on the list. Note that this function is called after | 427 | /* 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 | 428 | * 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 | 429 | * quota users. There can still be some users of quotas due to inodes being |
@@ -463,9 +472,44 @@ restart: | |||
463 | remove_dquot_hash(dquot); | 472 | remove_dquot_hash(dquot); |
464 | remove_free_dquot(dquot); | 473 | remove_free_dquot(dquot); |
465 | remove_inuse(dquot); | 474 | remove_inuse(dquot); |
466 | kmem_cache_free(dquot_cachep, dquot); | 475 | do_destroy_dquot(dquot); |
476 | } | ||
477 | spin_unlock(&dq_list_lock); | ||
478 | } | ||
479 | |||
480 | /* Call callback for every active dquot on given filesystem */ | ||
481 | int dquot_scan_active(struct super_block *sb, | ||
482 | int (*fn)(struct dquot *dquot, unsigned long priv), | ||
483 | unsigned long priv) | ||
484 | { | ||
485 | struct dquot *dquot, *old_dquot = NULL; | ||
486 | int ret = 0; | ||
487 | |||
488 | mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); | ||
489 | spin_lock(&dq_list_lock); | ||
490 | list_for_each_entry(dquot, &inuse_list, dq_inuse) { | ||
491 | if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) | ||
492 | continue; | ||
493 | if (dquot->dq_sb != sb) | ||
494 | continue; | ||
495 | /* Now we have active dquot so we can just increase use count */ | ||
496 | atomic_inc(&dquot->dq_count); | ||
497 | dqstats.lookups++; | ||
498 | spin_unlock(&dq_list_lock); | ||
499 | dqput(old_dquot); | ||
500 | old_dquot = dquot; | ||
501 | ret = fn(dquot, priv); | ||
502 | if (ret < 0) | ||
503 | goto out; | ||
504 | spin_lock(&dq_list_lock); | ||
505 | /* We are safe to continue now because our dquot could not | ||
506 | * be moved out of the inuse list while we hold the reference */ | ||
467 | } | 507 | } |
468 | spin_unlock(&dq_list_lock); | 508 | spin_unlock(&dq_list_lock); |
509 | out: | ||
510 | dqput(old_dquot); | ||
511 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); | ||
512 | return ret; | ||
469 | } | 513 | } |
470 | 514 | ||
471 | int vfs_quota_sync(struct super_block *sb, int type) | 515 | int vfs_quota_sync(struct super_block *sb, int type) |
@@ -479,7 +523,7 @@ int vfs_quota_sync(struct super_block *sb, int type) | |||
479 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 523 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
480 | if (type != -1 && cnt != type) | 524 | if (type != -1 && cnt != type) |
481 | continue; | 525 | continue; |
482 | if (!sb_has_quota_enabled(sb, cnt)) | 526 | if (!sb_has_quota_active(sb, cnt)) |
483 | continue; | 527 | continue; |
484 | spin_lock(&dq_list_lock); | 528 | spin_lock(&dq_list_lock); |
485 | dirty = &dqopt->info[cnt].dqi_dirty_list; | 529 | dirty = &dqopt->info[cnt].dqi_dirty_list; |
@@ -504,8 +548,8 @@ int vfs_quota_sync(struct super_block *sb, int type) | |||
504 | } | 548 | } |
505 | 549 | ||
506 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | 550 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) |
507 | if ((cnt == type || type == -1) && sb_has_quota_enabled(sb, cnt) | 551 | if ((cnt == type || type == -1) && sb_has_quota_active(sb, cnt) |
508 | && info_dirty(&dqopt->info[cnt])) | 552 | && info_dirty(&dqopt->info[cnt])) |
509 | sb->dq_op->write_info(sb, cnt); | 553 | sb->dq_op->write_info(sb, cnt); |
510 | spin_lock(&dq_list_lock); | 554 | spin_lock(&dq_list_lock); |
511 | dqstats.syncs++; | 555 | dqstats.syncs++; |
@@ -527,7 +571,7 @@ static void prune_dqcache(int count) | |||
527 | remove_dquot_hash(dquot); | 571 | remove_dquot_hash(dquot); |
528 | remove_free_dquot(dquot); | 572 | remove_free_dquot(dquot); |
529 | remove_inuse(dquot); | 573 | remove_inuse(dquot); |
530 | kmem_cache_free(dquot_cachep, dquot); | 574 | do_destroy_dquot(dquot); |
531 | count--; | 575 | count--; |
532 | head = free_dquots.prev; | 576 | head = free_dquots.prev; |
533 | } | 577 | } |
@@ -558,7 +602,7 @@ static struct shrinker dqcache_shrinker = { | |||
558 | * NOTE: If you change this function please check whether dqput_blocks() works right... | 602 | * 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 | 603 | * MUST be called with either dqptr_sem or dqonoff_mutex held |
560 | */ | 604 | */ |
561 | static void dqput(struct dquot *dquot) | 605 | void dqput(struct dquot *dquot) |
562 | { | 606 | { |
563 | int ret; | 607 | int ret; |
564 | 608 | ||
@@ -584,7 +628,7 @@ we_slept: | |||
584 | /* We have more than one user... nothing to do */ | 628 | /* We have more than one user... nothing to do */ |
585 | atomic_dec(&dquot->dq_count); | 629 | atomic_dec(&dquot->dq_count); |
586 | /* Releasing dquot during quotaoff phase? */ | 630 | /* Releasing dquot during quotaoff phase? */ |
587 | if (!sb_has_quota_enabled(dquot->dq_sb, dquot->dq_type) && | 631 | if (!sb_has_quota_active(dquot->dq_sb, dquot->dq_type) && |
588 | atomic_read(&dquot->dq_count) == 1) | 632 | atomic_read(&dquot->dq_count) == 1) |
589 | wake_up(&dquot->dq_wait_unused); | 633 | wake_up(&dquot->dq_wait_unused); |
590 | spin_unlock(&dq_list_lock); | 634 | spin_unlock(&dq_list_lock); |
@@ -625,11 +669,17 @@ we_slept: | |||
625 | spin_unlock(&dq_list_lock); | 669 | spin_unlock(&dq_list_lock); |
626 | } | 670 | } |
627 | 671 | ||
672 | struct dquot *dquot_alloc(struct super_block *sb, int type) | ||
673 | { | ||
674 | return kmem_cache_zalloc(dquot_cachep, GFP_NOFS); | ||
675 | } | ||
676 | EXPORT_SYMBOL(dquot_alloc); | ||
677 | |||
628 | static struct dquot *get_empty_dquot(struct super_block *sb, int type) | 678 | static struct dquot *get_empty_dquot(struct super_block *sb, int type) |
629 | { | 679 | { |
630 | struct dquot *dquot; | 680 | struct dquot *dquot; |
631 | 681 | ||
632 | dquot = kmem_cache_zalloc(dquot_cachep, GFP_NOFS); | 682 | dquot = sb->dq_op->alloc_dquot(sb, type); |
633 | if(!dquot) | 683 | if(!dquot) |
634 | return NODQUOT; | 684 | return NODQUOT; |
635 | 685 | ||
@@ -647,15 +697,33 @@ static struct dquot *get_empty_dquot(struct super_block *sb, int type) | |||
647 | } | 697 | } |
648 | 698 | ||
649 | /* | 699 | /* |
700 | * Check whether dquot is in memory. | ||
701 | * MUST be called with either dqptr_sem or dqonoff_mutex held | ||
702 | */ | ||
703 | int dquot_is_cached(struct super_block *sb, unsigned int id, int type) | ||
704 | { | ||
705 | unsigned int hashent = hashfn(sb, id, type); | ||
706 | int ret = 0; | ||
707 | |||
708 | if (!sb_has_quota_active(sb, type)) | ||
709 | return 0; | ||
710 | spin_lock(&dq_list_lock); | ||
711 | if (find_dquot(hashent, sb, id, type) != NODQUOT) | ||
712 | ret = 1; | ||
713 | spin_unlock(&dq_list_lock); | ||
714 | return ret; | ||
715 | } | ||
716 | |||
717 | /* | ||
650 | * Get reference to dquot | 718 | * Get reference to dquot |
651 | * MUST be called with either dqptr_sem or dqonoff_mutex held | 719 | * MUST be called with either dqptr_sem or dqonoff_mutex held |
652 | */ | 720 | */ |
653 | static struct dquot *dqget(struct super_block *sb, unsigned int id, int type) | 721 | struct dquot *dqget(struct super_block *sb, unsigned int id, int type) |
654 | { | 722 | { |
655 | unsigned int hashent = hashfn(sb, id, type); | 723 | unsigned int hashent = hashfn(sb, id, type); |
656 | struct dquot *dquot, *empty = NODQUOT; | 724 | struct dquot *dquot, *empty = NODQUOT; |
657 | 725 | ||
658 | if (!sb_has_quota_enabled(sb, type)) | 726 | if (!sb_has_quota_active(sb, type)) |
659 | return NODQUOT; | 727 | return NODQUOT; |
660 | we_slept: | 728 | we_slept: |
661 | spin_lock(&dq_list_lock); | 729 | spin_lock(&dq_list_lock); |
@@ -682,7 +750,7 @@ we_slept: | |||
682 | dqstats.lookups++; | 750 | dqstats.lookups++; |
683 | spin_unlock(&dq_list_lock); | 751 | spin_unlock(&dq_list_lock); |
684 | if (empty) | 752 | if (empty) |
685 | kmem_cache_free(dquot_cachep, empty); | 753 | do_destroy_dquot(empty); |
686 | } | 754 | } |
687 | /* Wait for dq_lock - after this we know that either dquot_release() is already | 755 | /* 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 */ | 756 | * finished or it will be canceled due to dq_count > 1 test */ |
@@ -820,7 +888,7 @@ static void drop_dquot_ref(struct super_block *sb, int type) | |||
820 | } | 888 | } |
821 | } | 889 | } |
822 | 890 | ||
823 | static inline void dquot_incr_inodes(struct dquot *dquot, unsigned long number) | 891 | static inline void dquot_incr_inodes(struct dquot *dquot, qsize_t number) |
824 | { | 892 | { |
825 | dquot->dq_dqb.dqb_curinodes += number; | 893 | dquot->dq_dqb.dqb_curinodes += number; |
826 | } | 894 | } |
@@ -830,9 +898,10 @@ static inline void dquot_incr_space(struct dquot *dquot, qsize_t number) | |||
830 | dquot->dq_dqb.dqb_curspace += number; | 898 | dquot->dq_dqb.dqb_curspace += number; |
831 | } | 899 | } |
832 | 900 | ||
833 | static inline void dquot_decr_inodes(struct dquot *dquot, unsigned long number) | 901 | static inline void dquot_decr_inodes(struct dquot *dquot, qsize_t number) |
834 | { | 902 | { |
835 | if (dquot->dq_dqb.dqb_curinodes > number) | 903 | if (sb_dqopt(dquot->dq_sb)->flags & DQUOT_NEGATIVE_USAGE || |
904 | dquot->dq_dqb.dqb_curinodes >= number) | ||
836 | dquot->dq_dqb.dqb_curinodes -= number; | 905 | dquot->dq_dqb.dqb_curinodes -= number; |
837 | else | 906 | else |
838 | dquot->dq_dqb.dqb_curinodes = 0; | 907 | dquot->dq_dqb.dqb_curinodes = 0; |
@@ -843,11 +912,12 @@ static inline void dquot_decr_inodes(struct dquot *dquot, unsigned long number) | |||
843 | 912 | ||
844 | static inline void dquot_decr_space(struct dquot *dquot, qsize_t number) | 913 | static inline void dquot_decr_space(struct dquot *dquot, qsize_t number) |
845 | { | 914 | { |
846 | if (dquot->dq_dqb.dqb_curspace > number) | 915 | if (sb_dqopt(dquot->dq_sb)->flags & DQUOT_NEGATIVE_USAGE || |
916 | dquot->dq_dqb.dqb_curspace >= number) | ||
847 | dquot->dq_dqb.dqb_curspace -= number; | 917 | dquot->dq_dqb.dqb_curspace -= number; |
848 | else | 918 | else |
849 | dquot->dq_dqb.dqb_curspace = 0; | 919 | dquot->dq_dqb.dqb_curspace = 0; |
850 | if (toqb(dquot->dq_dqb.dqb_curspace) <= dquot->dq_dqb.dqb_bsoftlimit) | 920 | if (dquot->dq_dqb.dqb_curspace <= dquot->dq_dqb.dqb_bsoftlimit) |
851 | dquot->dq_dqb.dqb_btime = (time_t) 0; | 921 | dquot->dq_dqb.dqb_btime = (time_t) 0; |
852 | clear_bit(DQ_BLKS_B, &dquot->dq_flags); | 922 | clear_bit(DQ_BLKS_B, &dquot->dq_flags); |
853 | } | 923 | } |
@@ -1023,10 +1093,11 @@ static inline char ignore_hardlimit(struct dquot *dquot) | |||
1023 | } | 1093 | } |
1024 | 1094 | ||
1025 | /* needs dq_data_lock */ | 1095 | /* needs dq_data_lock */ |
1026 | static int check_idq(struct dquot *dquot, ulong inodes, char *warntype) | 1096 | static int check_idq(struct dquot *dquot, qsize_t inodes, char *warntype) |
1027 | { | 1097 | { |
1028 | *warntype = QUOTA_NL_NOWARN; | 1098 | *warntype = QUOTA_NL_NOWARN; |
1029 | if (inodes <= 0 || test_bit(DQ_FAKE_B, &dquot->dq_flags)) | 1099 | if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type) || |
1100 | test_bit(DQ_FAKE_B, &dquot->dq_flags)) | ||
1030 | return QUOTA_OK; | 1101 | return QUOTA_OK; |
1031 | 1102 | ||
1032 | if (dquot->dq_dqb.dqb_ihardlimit && | 1103 | if (dquot->dq_dqb.dqb_ihardlimit && |
@@ -1058,11 +1129,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) | 1129 | static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *warntype) |
1059 | { | 1130 | { |
1060 | *warntype = QUOTA_NL_NOWARN; | 1131 | *warntype = QUOTA_NL_NOWARN; |
1061 | if (space <= 0 || test_bit(DQ_FAKE_B, &dquot->dq_flags)) | 1132 | if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type) || |
1133 | test_bit(DQ_FAKE_B, &dquot->dq_flags)) | ||
1062 | return QUOTA_OK; | 1134 | return QUOTA_OK; |
1063 | 1135 | ||
1064 | if (dquot->dq_dqb.dqb_bhardlimit && | 1136 | if (dquot->dq_dqb.dqb_bhardlimit && |
1065 | toqb(dquot->dq_dqb.dqb_curspace + space) > dquot->dq_dqb.dqb_bhardlimit && | 1137 | dquot->dq_dqb.dqb_curspace + space > dquot->dq_dqb.dqb_bhardlimit && |
1066 | !ignore_hardlimit(dquot)) { | 1138 | !ignore_hardlimit(dquot)) { |
1067 | if (!prealloc) | 1139 | if (!prealloc) |
1068 | *warntype = QUOTA_NL_BHARDWARN; | 1140 | *warntype = QUOTA_NL_BHARDWARN; |
@@ -1070,7 +1142,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war | |||
1070 | } | 1142 | } |
1071 | 1143 | ||
1072 | if (dquot->dq_dqb.dqb_bsoftlimit && | 1144 | if (dquot->dq_dqb.dqb_bsoftlimit && |
1073 | toqb(dquot->dq_dqb.dqb_curspace + space) > dquot->dq_dqb.dqb_bsoftlimit && | 1145 | dquot->dq_dqb.dqb_curspace + space > dquot->dq_dqb.dqb_bsoftlimit && |
1074 | dquot->dq_dqb.dqb_btime && get_seconds() >= dquot->dq_dqb.dqb_btime && | 1146 | dquot->dq_dqb.dqb_btime && get_seconds() >= dquot->dq_dqb.dqb_btime && |
1075 | !ignore_hardlimit(dquot)) { | 1147 | !ignore_hardlimit(dquot)) { |
1076 | if (!prealloc) | 1148 | if (!prealloc) |
@@ -1079,7 +1151,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war | |||
1079 | } | 1151 | } |
1080 | 1152 | ||
1081 | if (dquot->dq_dqb.dqb_bsoftlimit && | 1153 | if (dquot->dq_dqb.dqb_bsoftlimit && |
1082 | toqb(dquot->dq_dqb.dqb_curspace + space) > dquot->dq_dqb.dqb_bsoftlimit && | 1154 | dquot->dq_dqb.dqb_curspace + space > dquot->dq_dqb.dqb_bsoftlimit && |
1083 | dquot->dq_dqb.dqb_btime == 0) { | 1155 | dquot->dq_dqb.dqb_btime == 0) { |
1084 | if (!prealloc) { | 1156 | if (!prealloc) { |
1085 | *warntype = QUOTA_NL_BSOFTWARN; | 1157 | *warntype = QUOTA_NL_BSOFTWARN; |
@@ -1096,10 +1168,11 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war | |||
1096 | return QUOTA_OK; | 1168 | return QUOTA_OK; |
1097 | } | 1169 | } |
1098 | 1170 | ||
1099 | static int info_idq_free(struct dquot *dquot, ulong inodes) | 1171 | static int info_idq_free(struct dquot *dquot, qsize_t inodes) |
1100 | { | 1172 | { |
1101 | if (test_bit(DQ_FAKE_B, &dquot->dq_flags) || | 1173 | if (test_bit(DQ_FAKE_B, &dquot->dq_flags) || |
1102 | dquot->dq_dqb.dqb_curinodes <= dquot->dq_dqb.dqb_isoftlimit) | 1174 | dquot->dq_dqb.dqb_curinodes <= dquot->dq_dqb.dqb_isoftlimit || |
1175 | !sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type)) | ||
1103 | return QUOTA_NL_NOWARN; | 1176 | return QUOTA_NL_NOWARN; |
1104 | 1177 | ||
1105 | if (dquot->dq_dqb.dqb_curinodes - inodes <= dquot->dq_dqb.dqb_isoftlimit) | 1178 | if (dquot->dq_dqb.dqb_curinodes - inodes <= dquot->dq_dqb.dqb_isoftlimit) |
@@ -1113,15 +1186,13 @@ static int info_idq_free(struct dquot *dquot, ulong inodes) | |||
1113 | static int info_bdq_free(struct dquot *dquot, qsize_t space) | 1186 | static int info_bdq_free(struct dquot *dquot, qsize_t space) |
1114 | { | 1187 | { |
1115 | if (test_bit(DQ_FAKE_B, &dquot->dq_flags) || | 1188 | if (test_bit(DQ_FAKE_B, &dquot->dq_flags) || |
1116 | toqb(dquot->dq_dqb.dqb_curspace) <= dquot->dq_dqb.dqb_bsoftlimit) | 1189 | dquot->dq_dqb.dqb_curspace <= dquot->dq_dqb.dqb_bsoftlimit) |
1117 | return QUOTA_NL_NOWARN; | 1190 | return QUOTA_NL_NOWARN; |
1118 | 1191 | ||
1119 | if (toqb(dquot->dq_dqb.dqb_curspace - space) <= | 1192 | if (dquot->dq_dqb.dqb_curspace - space <= dquot->dq_dqb.dqb_bsoftlimit) |
1120 | dquot->dq_dqb.dqb_bsoftlimit) | ||
1121 | return QUOTA_NL_BSOFTBELOW; | 1193 | return QUOTA_NL_BSOFTBELOW; |
1122 | if (toqb(dquot->dq_dqb.dqb_curspace) >= dquot->dq_dqb.dqb_bhardlimit && | 1194 | if (dquot->dq_dqb.dqb_curspace >= dquot->dq_dqb.dqb_bhardlimit && |
1123 | toqb(dquot->dq_dqb.dqb_curspace - space) < | 1195 | dquot->dq_dqb.dqb_curspace - space < dquot->dq_dqb.dqb_bhardlimit) |
1124 | dquot->dq_dqb.dqb_bhardlimit) | ||
1125 | return QUOTA_NL_BHARDBELOW; | 1196 | return QUOTA_NL_BHARDBELOW; |
1126 | return QUOTA_NL_NOWARN; | 1197 | return QUOTA_NL_NOWARN; |
1127 | } | 1198 | } |
@@ -1166,17 +1237,23 @@ out_err: | |||
1166 | * Release all quotas referenced by inode | 1237 | * Release all quotas referenced by inode |
1167 | * Transaction must be started at an entry | 1238 | * Transaction must be started at an entry |
1168 | */ | 1239 | */ |
1169 | int dquot_drop(struct inode *inode) | 1240 | int dquot_drop_locked(struct inode *inode) |
1170 | { | 1241 | { |
1171 | int cnt; | 1242 | int cnt; |
1172 | 1243 | ||
1173 | down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | ||
1174 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1244 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1175 | if (inode->i_dquot[cnt] != NODQUOT) { | 1245 | if (inode->i_dquot[cnt] != NODQUOT) { |
1176 | dqput(inode->i_dquot[cnt]); | 1246 | dqput(inode->i_dquot[cnt]); |
1177 | inode->i_dquot[cnt] = NODQUOT; | 1247 | inode->i_dquot[cnt] = NODQUOT; |
1178 | } | 1248 | } |
1179 | } | 1249 | } |
1250 | return 0; | ||
1251 | } | ||
1252 | |||
1253 | int dquot_drop(struct inode *inode) | ||
1254 | { | ||
1255 | down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | ||
1256 | dquot_drop_locked(inode); | ||
1180 | up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1257 | up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1181 | return 0; | 1258 | return 0; |
1182 | } | 1259 | } |
@@ -1264,7 +1341,7 @@ warn_put_all: | |||
1264 | /* | 1341 | /* |
1265 | * This operation can block, but only after everything is updated | 1342 | * This operation can block, but only after everything is updated |
1266 | */ | 1343 | */ |
1267 | int dquot_alloc_inode(const struct inode *inode, unsigned long number) | 1344 | int dquot_alloc_inode(const struct inode *inode, qsize_t number) |
1268 | { | 1345 | { |
1269 | int cnt, ret = NO_QUOTA; | 1346 | int cnt, ret = NO_QUOTA; |
1270 | char warntype[MAXQUOTAS]; | 1347 | char warntype[MAXQUOTAS]; |
@@ -1349,7 +1426,7 @@ out_sub: | |||
1349 | /* | 1426 | /* |
1350 | * This operation can block, but only after everything is updated | 1427 | * This operation can block, but only after everything is updated |
1351 | */ | 1428 | */ |
1352 | int dquot_free_inode(const struct inode *inode, unsigned long number) | 1429 | int dquot_free_inode(const struct inode *inode, qsize_t number) |
1353 | { | 1430 | { |
1354 | unsigned int cnt; | 1431 | unsigned int cnt; |
1355 | char warntype[MAXQUOTAS]; | 1432 | char warntype[MAXQUOTAS]; |
@@ -1495,7 +1572,7 @@ warn_put_all: | |||
1495 | /* Wrapper for transferring ownership of an inode */ | 1572 | /* Wrapper for transferring ownership of an inode */ |
1496 | int vfs_dq_transfer(struct inode *inode, struct iattr *iattr) | 1573 | int vfs_dq_transfer(struct inode *inode, struct iattr *iattr) |
1497 | { | 1574 | { |
1498 | if (sb_any_quota_enabled(inode->i_sb) && !IS_NOQUOTA(inode)) { | 1575 | if (sb_any_quota_active(inode->i_sb) && !IS_NOQUOTA(inode)) { |
1499 | vfs_dq_init(inode); | 1576 | vfs_dq_init(inode); |
1500 | if (inode->i_sb->dq_op->transfer(inode, iattr) == NO_QUOTA) | 1577 | if (inode->i_sb->dq_op->transfer(inode, iattr) == NO_QUOTA) |
1501 | return 1; | 1578 | return 1; |
@@ -1533,54 +1610,27 @@ struct dquot_operations dquot_operations = { | |||
1533 | .acquire_dquot = dquot_acquire, | 1610 | .acquire_dquot = dquot_acquire, |
1534 | .release_dquot = dquot_release, | 1611 | .release_dquot = dquot_release, |
1535 | .mark_dirty = dquot_mark_dquot_dirty, | 1612 | .mark_dirty = dquot_mark_dquot_dirty, |
1536 | .write_info = dquot_commit_info | 1613 | .write_info = dquot_commit_info, |
1614 | .alloc_dquot = dquot_alloc, | ||
1615 | .destroy_dquot = dquot_destroy, | ||
1537 | }; | 1616 | }; |
1538 | 1617 | ||
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 | /* | 1618 | /* |
1576 | * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount) | 1619 | * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount) |
1577 | */ | 1620 | */ |
1578 | int vfs_quota_off(struct super_block *sb, int type, int remount) | 1621 | int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags) |
1579 | { | 1622 | { |
1580 | int cnt, ret = 0; | 1623 | int cnt, ret = 0; |
1581 | struct quota_info *dqopt = sb_dqopt(sb); | 1624 | struct quota_info *dqopt = sb_dqopt(sb); |
1582 | struct inode *toputinode[MAXQUOTAS]; | 1625 | struct inode *toputinode[MAXQUOTAS]; |
1583 | 1626 | ||
1627 | /* Cannot turn off usage accounting without turning off limits, or | ||
1628 | * suspend quotas and simultaneously turn quotas off. */ | ||
1629 | if ((flags & DQUOT_USAGE_ENABLED && !(flags & DQUOT_LIMITS_ENABLED)) | ||
1630 | || (flags & DQUOT_SUSPENDED && flags & (DQUOT_LIMITS_ENABLED | | ||
1631 | DQUOT_USAGE_ENABLED))) | ||
1632 | return -EINVAL; | ||
1633 | |||
1584 | /* We need to serialize quota_off() for device */ | 1634 | /* We need to serialize quota_off() for device */ |
1585 | mutex_lock(&dqopt->dqonoff_mutex); | 1635 | mutex_lock(&dqopt->dqonoff_mutex); |
1586 | 1636 | ||
@@ -1589,7 +1639,7 @@ int vfs_quota_off(struct super_block *sb, int type, int remount) | |||
1589 | * sometimes we are called when fill_super() failed and calling | 1639 | * sometimes we are called when fill_super() failed and calling |
1590 | * sync_fs() in such cases does no good. | 1640 | * sync_fs() in such cases does no good. |
1591 | */ | 1641 | */ |
1592 | if (!sb_any_quota_enabled(sb) && !sb_any_quota_suspended(sb)) { | 1642 | if (!sb_any_quota_loaded(sb)) { |
1593 | mutex_unlock(&dqopt->dqonoff_mutex); | 1643 | mutex_unlock(&dqopt->dqonoff_mutex); |
1594 | return 0; | 1644 | return 0; |
1595 | } | 1645 | } |
@@ -1597,17 +1647,28 @@ int vfs_quota_off(struct super_block *sb, int type, int remount) | |||
1597 | toputinode[cnt] = NULL; | 1647 | toputinode[cnt] = NULL; |
1598 | if (type != -1 && cnt != type) | 1648 | if (type != -1 && cnt != type) |
1599 | continue; | 1649 | continue; |
1600 | /* If we keep inodes of quota files after remount and quotaoff | 1650 | 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; | 1651 | continue; |
1652 | |||
1653 | if (flags & DQUOT_SUSPENDED) { | ||
1654 | dqopt->flags |= | ||
1655 | dquot_state_flag(DQUOT_SUSPENDED, cnt); | ||
1656 | } else { | ||
1657 | dqopt->flags &= ~dquot_state_flag(flags, cnt); | ||
1658 | /* Turning off suspended quotas? */ | ||
1659 | if (!sb_has_quota_loaded(sb, cnt) && | ||
1660 | sb_has_quota_suspended(sb, cnt)) { | ||
1661 | dqopt->flags &= ~dquot_state_flag( | ||
1662 | DQUOT_SUSPENDED, cnt); | ||
1663 | iput(dqopt->files[cnt]); | ||
1664 | dqopt->files[cnt] = NULL; | ||
1665 | continue; | ||
1666 | } | ||
1607 | } | 1667 | } |
1608 | if (!sb_has_quota_enabled(sb, cnt)) | 1668 | |
1669 | /* We still have to keep quota loaded? */ | ||
1670 | if (sb_has_quota_loaded(sb, cnt) && !(flags & DQUOT_SUSPENDED)) | ||
1609 | continue; | 1671 | continue; |
1610 | reset_enable_flags(dqopt, cnt, remount); | ||
1611 | 1672 | ||
1612 | /* Note: these are blocking operations */ | 1673 | /* Note: these are blocking operations */ |
1613 | drop_dquot_ref(sb, cnt); | 1674 | drop_dquot_ref(sb, cnt); |
@@ -1623,7 +1684,7 @@ int vfs_quota_off(struct super_block *sb, int type, int remount) | |||
1623 | put_quota_format(dqopt->info[cnt].dqi_format); | 1684 | put_quota_format(dqopt->info[cnt].dqi_format); |
1624 | 1685 | ||
1625 | toputinode[cnt] = dqopt->files[cnt]; | 1686 | toputinode[cnt] = dqopt->files[cnt]; |
1626 | if (!remount) | 1687 | if (!sb_has_quota_loaded(sb, cnt)) |
1627 | dqopt->files[cnt] = NULL; | 1688 | dqopt->files[cnt] = NULL; |
1628 | dqopt->info[cnt].dqi_flags = 0; | 1689 | dqopt->info[cnt].dqi_flags = 0; |
1629 | dqopt->info[cnt].dqi_igrace = 0; | 1690 | dqopt->info[cnt].dqi_igrace = 0; |
@@ -1631,6 +1692,11 @@ int vfs_quota_off(struct super_block *sb, int type, int remount) | |||
1631 | dqopt->ops[cnt] = NULL; | 1692 | dqopt->ops[cnt] = NULL; |
1632 | } | 1693 | } |
1633 | mutex_unlock(&dqopt->dqonoff_mutex); | 1694 | mutex_unlock(&dqopt->dqonoff_mutex); |
1695 | |||
1696 | /* Skip syncing and setting flags if quota files are hidden */ | ||
1697 | if (dqopt->flags & DQUOT_QUOTA_SYS_FILE) | ||
1698 | goto put_inodes; | ||
1699 | |||
1634 | /* Sync the superblock so that buffers with quota data are written to | 1700 | /* Sync the superblock so that buffers with quota data are written to |
1635 | * disk (and so userspace sees correct data afterwards). */ | 1701 | * disk (and so userspace sees correct data afterwards). */ |
1636 | if (sb->s_op->sync_fs) | 1702 | if (sb->s_op->sync_fs) |
@@ -1646,7 +1712,7 @@ int vfs_quota_off(struct super_block *sb, int type, int remount) | |||
1646 | mutex_lock(&dqopt->dqonoff_mutex); | 1712 | mutex_lock(&dqopt->dqonoff_mutex); |
1647 | /* If quota was reenabled in the meantime, we have | 1713 | /* If quota was reenabled in the meantime, we have |
1648 | * nothing to do */ | 1714 | * nothing to do */ |
1649 | if (!sb_has_quota_enabled(sb, cnt)) { | 1715 | if (!sb_has_quota_loaded(sb, cnt)) { |
1650 | mutex_lock_nested(&toputinode[cnt]->i_mutex, I_MUTEX_QUOTA); | 1716 | mutex_lock_nested(&toputinode[cnt]->i_mutex, I_MUTEX_QUOTA); |
1651 | toputinode[cnt]->i_flags &= ~(S_IMMUTABLE | | 1717 | toputinode[cnt]->i_flags &= ~(S_IMMUTABLE | |
1652 | S_NOATIME | S_NOQUOTA); | 1718 | S_NOATIME | S_NOQUOTA); |
@@ -1655,26 +1721,43 @@ int vfs_quota_off(struct super_block *sb, int type, int remount) | |||
1655 | mark_inode_dirty(toputinode[cnt]); | 1721 | mark_inode_dirty(toputinode[cnt]); |
1656 | } | 1722 | } |
1657 | mutex_unlock(&dqopt->dqonoff_mutex); | 1723 | mutex_unlock(&dqopt->dqonoff_mutex); |
1724 | } | ||
1725 | if (sb->s_bdev) | ||
1726 | invalidate_bdev(sb->s_bdev); | ||
1727 | put_inodes: | ||
1728 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | ||
1729 | if (toputinode[cnt]) { | ||
1658 | /* On remount RO, we keep the inode pointer so that we | 1730 | /* On remount RO, we keep the inode pointer so that we |
1659 | * can reenable quota on the subsequent remount RW. | 1731 | * can reenable quota on the subsequent remount RW. We |
1660 | * But we have better not keep inode pointer when there | 1732 | * have to check 'flags' variable and not use sb_has_ |
1661 | * is pending delete on the quota file... */ | 1733 | * function because another quotaon / quotaoff could |
1662 | if (!remount) | 1734 | * change global state before we got here. We refuse |
1735 | * to suspend quotas when there is pending delete on | ||
1736 | * the quota file... */ | ||
1737 | if (!(flags & DQUOT_SUSPENDED)) | ||
1663 | iput(toputinode[cnt]); | 1738 | iput(toputinode[cnt]); |
1664 | else if (!toputinode[cnt]->i_nlink) | 1739 | else if (!toputinode[cnt]->i_nlink) |
1665 | ret = -EBUSY; | 1740 | ret = -EBUSY; |
1666 | } | 1741 | } |
1667 | if (sb->s_bdev) | ||
1668 | invalidate_bdev(sb->s_bdev); | ||
1669 | return ret; | 1742 | return ret; |
1670 | } | 1743 | } |
1671 | 1744 | ||
1745 | int vfs_quota_off(struct super_block *sb, int type, int remount) | ||
1746 | { | ||
1747 | return vfs_quota_disable(sb, type, remount ? DQUOT_SUSPENDED : | ||
1748 | (DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED)); | ||
1749 | } | ||
1750 | |||
1672 | /* | 1751 | /* |
1673 | * Turn quotas on on a device | 1752 | * Turn quotas on on a device |
1674 | */ | 1753 | */ |
1675 | 1754 | ||
1676 | /* Helper function when we already have the inode */ | 1755 | /* |
1677 | static int vfs_quota_on_inode(struct inode *inode, int type, int format_id) | 1756 | * Helper function to turn quotas on when we already have the inode of |
1757 | * quota file and no quota information is loaded. | ||
1758 | */ | ||
1759 | static int vfs_load_quota_inode(struct inode *inode, int type, int format_id, | ||
1760 | unsigned int flags) | ||
1678 | { | 1761 | { |
1679 | struct quota_format_type *fmt = find_quota_format(format_id); | 1762 | struct quota_format_type *fmt = find_quota_format(format_id); |
1680 | struct super_block *sb = inode->i_sb; | 1763 | struct super_block *sb = inode->i_sb; |
@@ -1696,27 +1779,37 @@ static int vfs_quota_on_inode(struct inode *inode, int type, int format_id) | |||
1696 | error = -EINVAL; | 1779 | error = -EINVAL; |
1697 | goto out_fmt; | 1780 | goto out_fmt; |
1698 | } | 1781 | } |
1782 | /* Usage always has to be set... */ | ||
1783 | if (!(flags & DQUOT_USAGE_ENABLED)) { | ||
1784 | error = -EINVAL; | ||
1785 | goto out_fmt; | ||
1786 | } | ||
1699 | 1787 | ||
1700 | /* As we bypass the pagecache we must now flush the inode so that | 1788 | if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE)) { |
1701 | * we see all the changes from userspace... */ | 1789 | /* As we bypass the pagecache we must now flush the inode so |
1702 | write_inode_now(inode, 1); | 1790 | * that we see all the changes from userspace... */ |
1703 | /* And now flush the block cache so that kernel sees the changes */ | 1791 | write_inode_now(inode, 1); |
1704 | invalidate_bdev(sb->s_bdev); | 1792 | /* And now flush the block cache so that kernel sees the |
1793 | * changes */ | ||
1794 | invalidate_bdev(sb->s_bdev); | ||
1795 | } | ||
1705 | mutex_lock(&inode->i_mutex); | 1796 | mutex_lock(&inode->i_mutex); |
1706 | mutex_lock(&dqopt->dqonoff_mutex); | 1797 | mutex_lock(&dqopt->dqonoff_mutex); |
1707 | if (sb_has_quota_enabled(sb, type) || | 1798 | if (sb_has_quota_loaded(sb, type)) { |
1708 | sb_has_quota_suspended(sb, type)) { | ||
1709 | error = -EBUSY; | 1799 | error = -EBUSY; |
1710 | goto out_lock; | 1800 | goto out_lock; |
1711 | } | 1801 | } |
1712 | /* We don't want quota and atime on quota files (deadlocks possible) | 1802 | |
1713 | * Also nobody should write to the file - we use special IO operations | 1803 | if (!(dqopt->flags & DQUOT_QUOTA_SYS_FILE)) { |
1714 | * which ignore the immutable bit. */ | 1804 | /* We don't want quota and atime on quota files (deadlocks |
1715 | down_write(&dqopt->dqptr_sem); | 1805 | * possible) Also nobody should write to the file - we use |
1716 | oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE | S_NOQUOTA); | 1806 | * special IO operations which ignore the immutable bit. */ |
1717 | inode->i_flags |= S_NOQUOTA | S_NOATIME | S_IMMUTABLE; | 1807 | down_write(&dqopt->dqptr_sem); |
1718 | up_write(&dqopt->dqptr_sem); | 1808 | oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE | S_NOQUOTA); |
1719 | sb->dq_op->drop(inode); | 1809 | inode->i_flags |= S_NOQUOTA | S_NOATIME | S_IMMUTABLE; |
1810 | up_write(&dqopt->dqptr_sem); | ||
1811 | sb->dq_op->drop(inode); | ||
1812 | } | ||
1720 | 1813 | ||
1721 | error = -EIO; | 1814 | error = -EIO; |
1722 | dqopt->files[type] = igrab(inode); | 1815 | dqopt->files[type] = igrab(inode); |
@@ -1737,7 +1830,7 @@ static int vfs_quota_on_inode(struct inode *inode, int type, int format_id) | |||
1737 | } | 1830 | } |
1738 | mutex_unlock(&dqopt->dqio_mutex); | 1831 | mutex_unlock(&dqopt->dqio_mutex); |
1739 | mutex_unlock(&inode->i_mutex); | 1832 | mutex_unlock(&inode->i_mutex); |
1740 | set_enable_flags(dqopt, type); | 1833 | dqopt->flags |= dquot_state_flag(flags, type); |
1741 | 1834 | ||
1742 | add_dquot_ref(sb, type); | 1835 | add_dquot_ref(sb, type); |
1743 | mutex_unlock(&dqopt->dqonoff_mutex); | 1836 | mutex_unlock(&dqopt->dqonoff_mutex); |
@@ -1770,20 +1863,23 @@ static int vfs_quota_on_remount(struct super_block *sb, int type) | |||
1770 | struct quota_info *dqopt = sb_dqopt(sb); | 1863 | struct quota_info *dqopt = sb_dqopt(sb); |
1771 | struct inode *inode; | 1864 | struct inode *inode; |
1772 | int ret; | 1865 | int ret; |
1866 | unsigned int flags; | ||
1773 | 1867 | ||
1774 | mutex_lock(&dqopt->dqonoff_mutex); | 1868 | mutex_lock(&dqopt->dqonoff_mutex); |
1775 | if (!sb_has_quota_suspended(sb, type)) { | 1869 | if (!sb_has_quota_suspended(sb, type)) { |
1776 | mutex_unlock(&dqopt->dqonoff_mutex); | 1870 | mutex_unlock(&dqopt->dqonoff_mutex); |
1777 | return 0; | 1871 | return 0; |
1778 | } | 1872 | } |
1779 | BUG_ON(sb_has_quota_enabled(sb, type)); | ||
1780 | |||
1781 | inode = dqopt->files[type]; | 1873 | inode = dqopt->files[type]; |
1782 | dqopt->files[type] = NULL; | 1874 | dqopt->files[type] = NULL; |
1783 | reset_enable_flags(dqopt, type, 0); | 1875 | flags = dqopt->flags & dquot_state_flag(DQUOT_USAGE_ENABLED | |
1876 | DQUOT_LIMITS_ENABLED, type); | ||
1877 | dqopt->flags &= ~dquot_state_flag(DQUOT_STATE_FLAGS, type); | ||
1784 | mutex_unlock(&dqopt->dqonoff_mutex); | 1878 | mutex_unlock(&dqopt->dqonoff_mutex); |
1785 | 1879 | ||
1786 | ret = vfs_quota_on_inode(inode, type, dqopt->info[type].dqi_fmt_id); | 1880 | flags = dquot_generic_flag(flags, type); |
1881 | ret = vfs_load_quota_inode(inode, type, dqopt->info[type].dqi_fmt_id, | ||
1882 | flags); | ||
1787 | iput(inode); | 1883 | iput(inode); |
1788 | 1884 | ||
1789 | return ret; | 1885 | return ret; |
@@ -1799,12 +1895,12 @@ int vfs_quota_on_path(struct super_block *sb, int type, int format_id, | |||
1799 | if (path->mnt->mnt_sb != sb) | 1895 | if (path->mnt->mnt_sb != sb) |
1800 | error = -EXDEV; | 1896 | error = -EXDEV; |
1801 | else | 1897 | else |
1802 | error = vfs_quota_on_inode(path->dentry->d_inode, type, | 1898 | error = vfs_load_quota_inode(path->dentry->d_inode, type, |
1803 | format_id); | 1899 | format_id, DQUOT_USAGE_ENABLED | |
1900 | DQUOT_LIMITS_ENABLED); | ||
1804 | return error; | 1901 | return error; |
1805 | } | 1902 | } |
1806 | 1903 | ||
1807 | /* Actual function called from quotactl() */ | ||
1808 | int vfs_quota_on(struct super_block *sb, int type, int format_id, char *name, | 1904 | int vfs_quota_on(struct super_block *sb, int type, int format_id, char *name, |
1809 | int remount) | 1905 | int remount) |
1810 | { | 1906 | { |
@@ -1823,6 +1919,50 @@ int vfs_quota_on(struct super_block *sb, int type, int format_id, char *name, | |||
1823 | } | 1919 | } |
1824 | 1920 | ||
1825 | /* | 1921 | /* |
1922 | * More powerful function for turning on quotas allowing setting | ||
1923 | * of individual quota flags | ||
1924 | */ | ||
1925 | int vfs_quota_enable(struct inode *inode, int type, int format_id, | ||
1926 | unsigned int flags) | ||
1927 | { | ||
1928 | int ret = 0; | ||
1929 | struct super_block *sb = inode->i_sb; | ||
1930 | struct quota_info *dqopt = sb_dqopt(sb); | ||
1931 | |||
1932 | /* Just unsuspend quotas? */ | ||
1933 | if (flags & DQUOT_SUSPENDED) | ||
1934 | return vfs_quota_on_remount(sb, type); | ||
1935 | if (!flags) | ||
1936 | return 0; | ||
1937 | /* Just updating flags needed? */ | ||
1938 | if (sb_has_quota_loaded(sb, type)) { | ||
1939 | mutex_lock(&dqopt->dqonoff_mutex); | ||
1940 | /* Now do a reliable test... */ | ||
1941 | if (!sb_has_quota_loaded(sb, type)) { | ||
1942 | mutex_unlock(&dqopt->dqonoff_mutex); | ||
1943 | goto load_quota; | ||
1944 | } | ||
1945 | if (flags & DQUOT_USAGE_ENABLED && | ||
1946 | sb_has_quota_usage_enabled(sb, type)) { | ||
1947 | ret = -EBUSY; | ||
1948 | goto out_lock; | ||
1949 | } | ||
1950 | if (flags & DQUOT_LIMITS_ENABLED && | ||
1951 | sb_has_quota_limits_enabled(sb, type)) { | ||
1952 | ret = -EBUSY; | ||
1953 | goto out_lock; | ||
1954 | } | ||
1955 | sb_dqopt(sb)->flags |= dquot_state_flag(flags, type); | ||
1956 | out_lock: | ||
1957 | mutex_unlock(&dqopt->dqonoff_mutex); | ||
1958 | return ret; | ||
1959 | } | ||
1960 | |||
1961 | load_quota: | ||
1962 | return vfs_load_quota_inode(inode, type, format_id, flags); | ||
1963 | } | ||
1964 | |||
1965 | /* | ||
1826 | * This function is used when filesystem needs to initialize quotas | 1966 | * This function is used when filesystem needs to initialize quotas |
1827 | * during mount time. | 1967 | * during mount time. |
1828 | */ | 1968 | */ |
@@ -1843,7 +1983,8 @@ int vfs_quota_on_mount(struct super_block *sb, char *qf_name, | |||
1843 | 1983 | ||
1844 | error = security_quota_on(dentry); | 1984 | error = security_quota_on(dentry); |
1845 | if (!error) | 1985 | if (!error) |
1846 | error = vfs_quota_on_inode(dentry->d_inode, type, format_id); | 1986 | error = vfs_load_quota_inode(dentry->d_inode, type, format_id, |
1987 | DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED); | ||
1847 | 1988 | ||
1848 | out: | 1989 | out: |
1849 | dput(dentry); | 1990 | dput(dentry); |
@@ -1866,14 +2007,24 @@ int vfs_dq_quota_on_remount(struct super_block *sb) | |||
1866 | return ret; | 2007 | return ret; |
1867 | } | 2008 | } |
1868 | 2009 | ||
2010 | static inline qsize_t qbtos(qsize_t blocks) | ||
2011 | { | ||
2012 | return blocks << QIF_DQBLKSIZE_BITS; | ||
2013 | } | ||
2014 | |||
2015 | static inline qsize_t stoqb(qsize_t space) | ||
2016 | { | ||
2017 | return (space + QIF_DQBLKSIZE - 1) >> QIF_DQBLKSIZE_BITS; | ||
2018 | } | ||
2019 | |||
1869 | /* Generic routine for getting common part of quota structure */ | 2020 | /* Generic routine for getting common part of quota structure */ |
1870 | static void do_get_dqblk(struct dquot *dquot, struct if_dqblk *di) | 2021 | static void do_get_dqblk(struct dquot *dquot, struct if_dqblk *di) |
1871 | { | 2022 | { |
1872 | struct mem_dqblk *dm = &dquot->dq_dqb; | 2023 | struct mem_dqblk *dm = &dquot->dq_dqb; |
1873 | 2024 | ||
1874 | spin_lock(&dq_data_lock); | 2025 | spin_lock(&dq_data_lock); |
1875 | di->dqb_bhardlimit = dm->dqb_bhardlimit; | 2026 | di->dqb_bhardlimit = stoqb(dm->dqb_bhardlimit); |
1876 | di->dqb_bsoftlimit = dm->dqb_bsoftlimit; | 2027 | di->dqb_bsoftlimit = stoqb(dm->dqb_bsoftlimit); |
1877 | di->dqb_curspace = dm->dqb_curspace; | 2028 | di->dqb_curspace = dm->dqb_curspace; |
1878 | di->dqb_ihardlimit = dm->dqb_ihardlimit; | 2029 | di->dqb_ihardlimit = dm->dqb_ihardlimit; |
1879 | di->dqb_isoftlimit = dm->dqb_isoftlimit; | 2030 | di->dqb_isoftlimit = dm->dqb_isoftlimit; |
@@ -1918,28 +2069,36 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di) | |||
1918 | if (di->dqb_valid & QIF_SPACE) { | 2069 | if (di->dqb_valid & QIF_SPACE) { |
1919 | dm->dqb_curspace = di->dqb_curspace; | 2070 | dm->dqb_curspace = di->dqb_curspace; |
1920 | check_blim = 1; | 2071 | check_blim = 1; |
2072 | __set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags); | ||
1921 | } | 2073 | } |
1922 | if (di->dqb_valid & QIF_BLIMITS) { | 2074 | if (di->dqb_valid & QIF_BLIMITS) { |
1923 | dm->dqb_bsoftlimit = di->dqb_bsoftlimit; | 2075 | dm->dqb_bsoftlimit = qbtos(di->dqb_bsoftlimit); |
1924 | dm->dqb_bhardlimit = di->dqb_bhardlimit; | 2076 | dm->dqb_bhardlimit = qbtos(di->dqb_bhardlimit); |
1925 | check_blim = 1; | 2077 | check_blim = 1; |
2078 | __set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags); | ||
1926 | } | 2079 | } |
1927 | if (di->dqb_valid & QIF_INODES) { | 2080 | if (di->dqb_valid & QIF_INODES) { |
1928 | dm->dqb_curinodes = di->dqb_curinodes; | 2081 | dm->dqb_curinodes = di->dqb_curinodes; |
1929 | check_ilim = 1; | 2082 | check_ilim = 1; |
2083 | __set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags); | ||
1930 | } | 2084 | } |
1931 | if (di->dqb_valid & QIF_ILIMITS) { | 2085 | if (di->dqb_valid & QIF_ILIMITS) { |
1932 | dm->dqb_isoftlimit = di->dqb_isoftlimit; | 2086 | dm->dqb_isoftlimit = di->dqb_isoftlimit; |
1933 | dm->dqb_ihardlimit = di->dqb_ihardlimit; | 2087 | dm->dqb_ihardlimit = di->dqb_ihardlimit; |
1934 | check_ilim = 1; | 2088 | check_ilim = 1; |
2089 | __set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags); | ||
1935 | } | 2090 | } |
1936 | if (di->dqb_valid & QIF_BTIME) | 2091 | if (di->dqb_valid & QIF_BTIME) { |
1937 | dm->dqb_btime = di->dqb_btime; | 2092 | dm->dqb_btime = di->dqb_btime; |
1938 | if (di->dqb_valid & QIF_ITIME) | 2093 | __set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags); |
2094 | } | ||
2095 | if (di->dqb_valid & QIF_ITIME) { | ||
1939 | dm->dqb_itime = di->dqb_itime; | 2096 | dm->dqb_itime = di->dqb_itime; |
2097 | __set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags); | ||
2098 | } | ||
1940 | 2099 | ||
1941 | if (check_blim) { | 2100 | if (check_blim) { |
1942 | if (!dm->dqb_bsoftlimit || toqb(dm->dqb_curspace) < dm->dqb_bsoftlimit) { | 2101 | if (!dm->dqb_bsoftlimit || dm->dqb_curspace < dm->dqb_bsoftlimit) { |
1943 | dm->dqb_btime = 0; | 2102 | dm->dqb_btime = 0; |
1944 | clear_bit(DQ_BLKS_B, &dquot->dq_flags); | 2103 | clear_bit(DQ_BLKS_B, &dquot->dq_flags); |
1945 | } | 2104 | } |
@@ -1970,12 +2129,14 @@ int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *d | |||
1970 | int rc; | 2129 | int rc; |
1971 | 2130 | ||
1972 | mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); | 2131 | mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); |
1973 | if (!(dquot = dqget(sb, id, type))) { | 2132 | dquot = dqget(sb, id, type); |
1974 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); | 2133 | if (!dquot) { |
1975 | return -ESRCH; | 2134 | rc = -ESRCH; |
2135 | goto out; | ||
1976 | } | 2136 | } |
1977 | rc = do_set_dqblk(dquot, di); | 2137 | rc = do_set_dqblk(dquot, di); |
1978 | dqput(dquot); | 2138 | dqput(dquot); |
2139 | out: | ||
1979 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); | 2140 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); |
1980 | return rc; | 2141 | return rc; |
1981 | } | 2142 | } |
@@ -1986,7 +2147,7 @@ int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) | |||
1986 | struct mem_dqinfo *mi; | 2147 | struct mem_dqinfo *mi; |
1987 | 2148 | ||
1988 | mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); | 2149 | mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); |
1989 | if (!sb_has_quota_enabled(sb, type)) { | 2150 | if (!sb_has_quota_active(sb, type)) { |
1990 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); | 2151 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); |
1991 | return -ESRCH; | 2152 | return -ESRCH; |
1992 | } | 2153 | } |
@@ -2005,11 +2166,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) | 2166 | int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) |
2006 | { | 2167 | { |
2007 | struct mem_dqinfo *mi; | 2168 | struct mem_dqinfo *mi; |
2169 | int err = 0; | ||
2008 | 2170 | ||
2009 | mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); | 2171 | mutex_lock(&sb_dqopt(sb)->dqonoff_mutex); |
2010 | if (!sb_has_quota_enabled(sb, type)) { | 2172 | if (!sb_has_quota_active(sb, type)) { |
2011 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); | 2173 | err = -ESRCH; |
2012 | return -ESRCH; | 2174 | goto out; |
2013 | } | 2175 | } |
2014 | mi = sb_dqopt(sb)->info + type; | 2176 | mi = sb_dqopt(sb)->info + type; |
2015 | spin_lock(&dq_data_lock); | 2177 | spin_lock(&dq_data_lock); |
@@ -2023,8 +2185,9 @@ int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) | |||
2023 | mark_info_dirty(sb, type); | 2185 | mark_info_dirty(sb, type); |
2024 | /* Force write to disk */ | 2186 | /* Force write to disk */ |
2025 | sb->dq_op->write_info(sb, type); | 2187 | sb->dq_op->write_info(sb, type); |
2188 | out: | ||
2026 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); | 2189 | mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex); |
2027 | return 0; | 2190 | return err; |
2028 | } | 2191 | } |
2029 | 2192 | ||
2030 | struct quotactl_ops vfs_quotactl_ops = { | 2193 | struct quotactl_ops vfs_quotactl_ops = { |
@@ -2186,10 +2349,13 @@ EXPORT_SYMBOL(register_quota_format); | |||
2186 | EXPORT_SYMBOL(unregister_quota_format); | 2349 | EXPORT_SYMBOL(unregister_quota_format); |
2187 | EXPORT_SYMBOL(dqstats); | 2350 | EXPORT_SYMBOL(dqstats); |
2188 | EXPORT_SYMBOL(dq_data_lock); | 2351 | EXPORT_SYMBOL(dq_data_lock); |
2352 | EXPORT_SYMBOL(vfs_quota_enable); | ||
2189 | EXPORT_SYMBOL(vfs_quota_on); | 2353 | EXPORT_SYMBOL(vfs_quota_on); |
2190 | EXPORT_SYMBOL(vfs_quota_on_path); | 2354 | EXPORT_SYMBOL(vfs_quota_on_path); |
2191 | EXPORT_SYMBOL(vfs_quota_on_mount); | 2355 | EXPORT_SYMBOL(vfs_quota_on_mount); |
2356 | EXPORT_SYMBOL(vfs_quota_disable); | ||
2192 | EXPORT_SYMBOL(vfs_quota_off); | 2357 | EXPORT_SYMBOL(vfs_quota_off); |
2358 | EXPORT_SYMBOL(dquot_scan_active); | ||
2193 | EXPORT_SYMBOL(vfs_quota_sync); | 2359 | EXPORT_SYMBOL(vfs_quota_sync); |
2194 | EXPORT_SYMBOL(vfs_get_dqinfo); | 2360 | EXPORT_SYMBOL(vfs_get_dqinfo); |
2195 | EXPORT_SYMBOL(vfs_set_dqinfo); | 2361 | EXPORT_SYMBOL(vfs_set_dqinfo); |
@@ -2202,7 +2368,11 @@ EXPORT_SYMBOL(dquot_release); | |||
2202 | EXPORT_SYMBOL(dquot_mark_dquot_dirty); | 2368 | EXPORT_SYMBOL(dquot_mark_dquot_dirty); |
2203 | EXPORT_SYMBOL(dquot_initialize); | 2369 | EXPORT_SYMBOL(dquot_initialize); |
2204 | EXPORT_SYMBOL(dquot_drop); | 2370 | EXPORT_SYMBOL(dquot_drop); |
2371 | EXPORT_SYMBOL(dquot_drop_locked); | ||
2205 | EXPORT_SYMBOL(vfs_dq_drop); | 2372 | EXPORT_SYMBOL(vfs_dq_drop); |
2373 | EXPORT_SYMBOL(dqget); | ||
2374 | EXPORT_SYMBOL(dqput); | ||
2375 | EXPORT_SYMBOL(dquot_is_cached); | ||
2206 | EXPORT_SYMBOL(dquot_alloc_space); | 2376 | EXPORT_SYMBOL(dquot_alloc_space); |
2207 | EXPORT_SYMBOL(dquot_alloc_inode); | 2377 | EXPORT_SYMBOL(dquot_alloc_inode); |
2208 | EXPORT_SYMBOL(dquot_free_space); | 2378 | EXPORT_SYMBOL(dquot_free_space); |