diff options
| -rw-r--r-- | fs/quota/dquot.c | 181 | ||||
| -rw-r--r-- | fs/quota/quota.c | 35 | ||||
| -rw-r--r-- | fs/quota/quota_tree.c | 42 | ||||
| -rw-r--r-- | fs/quota/quota_v1.c | 48 | ||||
| -rw-r--r-- | fs/quota/quota_v2.c | 3 |
5 files changed, 198 insertions, 111 deletions
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 4a37b8e32b4e..a1bd5eabbe50 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c | |||
| @@ -156,7 +156,9 @@ void unregister_quota_format(struct quota_format_type *fmt) | |||
| 156 | struct quota_format_type **actqf; | 156 | struct quota_format_type **actqf; |
| 157 | 157 | ||
| 158 | spin_lock(&dq_list_lock); | 158 | spin_lock(&dq_list_lock); |
| 159 | for (actqf = "a_formats; *actqf && *actqf != fmt; actqf = &(*actqf)->qf_next); | 159 | for (actqf = "a_formats; *actqf && *actqf != fmt; |
| 160 | actqf = &(*actqf)->qf_next) | ||
| 161 | ; | ||
| 160 | if (*actqf) | 162 | if (*actqf) |
| 161 | *actqf = (*actqf)->qf_next; | 163 | *actqf = (*actqf)->qf_next; |
| 162 | spin_unlock(&dq_list_lock); | 164 | spin_unlock(&dq_list_lock); |
| @@ -168,18 +170,25 @@ static struct quota_format_type *find_quota_format(int id) | |||
| 168 | struct quota_format_type *actqf; | 170 | struct quota_format_type *actqf; |
| 169 | 171 | ||
| 170 | spin_lock(&dq_list_lock); | 172 | spin_lock(&dq_list_lock); |
| 171 | for (actqf = quota_formats; actqf && actqf->qf_fmt_id != id; actqf = actqf->qf_next); | 173 | for (actqf = quota_formats; actqf && actqf->qf_fmt_id != id; |
| 174 | actqf = actqf->qf_next) | ||
| 175 | ; | ||
| 172 | if (!actqf || !try_module_get(actqf->qf_owner)) { | 176 | if (!actqf || !try_module_get(actqf->qf_owner)) { |
| 173 | int qm; | 177 | int qm; |
| 174 | 178 | ||
| 175 | spin_unlock(&dq_list_lock); | 179 | spin_unlock(&dq_list_lock); |
| 176 | 180 | ||
| 177 | for (qm = 0; module_names[qm].qm_fmt_id && module_names[qm].qm_fmt_id != id; qm++); | 181 | for (qm = 0; module_names[qm].qm_fmt_id && |
| 178 | if (!module_names[qm].qm_fmt_id || request_module(module_names[qm].qm_mod_name)) | 182 | module_names[qm].qm_fmt_id != id; qm++) |
| 183 | ; | ||
| 184 | if (!module_names[qm].qm_fmt_id || | ||
| 185 | request_module(module_names[qm].qm_mod_name)) | ||
| 179 | return NULL; | 186 | return NULL; |
| 180 | 187 | ||
| 181 | spin_lock(&dq_list_lock); | 188 | spin_lock(&dq_list_lock); |
| 182 | for (actqf = quota_formats; actqf && actqf->qf_fmt_id != id; actqf = actqf->qf_next); | 189 | for (actqf = quota_formats; actqf && actqf->qf_fmt_id != id; |
| 190 | actqf = actqf->qf_next) | ||
| 191 | ; | ||
| 183 | if (actqf && !try_module_get(actqf->qf_owner)) | 192 | if (actqf && !try_module_get(actqf->qf_owner)) |
| 184 | actqf = NULL; | 193 | actqf = NULL; |
| 185 | } | 194 | } |
| @@ -234,7 +243,8 @@ hashfn(const struct super_block *sb, unsigned int id, int type) | |||
| 234 | */ | 243 | */ |
| 235 | static inline void insert_dquot_hash(struct dquot *dquot) | 244 | static inline void insert_dquot_hash(struct dquot *dquot) |
| 236 | { | 245 | { |
| 237 | struct hlist_head *head = dquot_hash + hashfn(dquot->dq_sb, dquot->dq_id, dquot->dq_type); | 246 | struct hlist_head *head; |
| 247 | head = dquot_hash + hashfn(dquot->dq_sb, dquot->dq_id, dquot->dq_type); | ||
| 238 | hlist_add_head(&dquot->dq_hash, head); | 248 | hlist_add_head(&dquot->dq_hash, head); |
| 239 | } | 249 | } |
| 240 | 250 | ||
| @@ -251,7 +261,8 @@ static struct dquot *find_dquot(unsigned int hashent, struct super_block *sb, | |||
| 251 | 261 | ||
| 252 | hlist_for_each (node, dquot_hash+hashent) { | 262 | hlist_for_each (node, dquot_hash+hashent) { |
| 253 | dquot = hlist_entry(node, struct dquot, dq_hash); | 263 | dquot = hlist_entry(node, struct dquot, dq_hash); |
| 254 | if (dquot->dq_sb == sb && dquot->dq_id == id && dquot->dq_type == type) | 264 | if (dquot->dq_sb == sb && dquot->dq_id == id && |
| 265 | dquot->dq_type == type) | ||
| 255 | return dquot; | 266 | return dquot; |
| 256 | } | 267 | } |
| 257 | return NULL; | 268 | return NULL; |
| @@ -351,8 +362,10 @@ int dquot_acquire(struct dquot *dquot) | |||
| 351 | if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && !dquot->dq_off) { | 362 | if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && !dquot->dq_off) { |
| 352 | ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot); | 363 | ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot); |
| 353 | /* Write the info if needed */ | 364 | /* Write the info if needed */ |
| 354 | if (info_dirty(&dqopt->info[dquot->dq_type])) | 365 | if (info_dirty(&dqopt->info[dquot->dq_type])) { |
| 355 | ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type); | 366 | ret2 = dqopt->ops[dquot->dq_type]->write_file_info( |
| 367 | dquot->dq_sb, dquot->dq_type); | ||
| 368 | } | ||
| 356 | if (ret < 0) | 369 | if (ret < 0) |
| 357 | goto out_iolock; | 370 | goto out_iolock; |
| 358 | if (ret2 < 0) { | 371 | if (ret2 < 0) { |
| @@ -387,8 +400,10 @@ int dquot_commit(struct dquot *dquot) | |||
| 387 | * => we have better not writing it */ | 400 | * => we have better not writing it */ |
| 388 | if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { | 401 | if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { |
| 389 | ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot); | 402 | ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot); |
| 390 | if (info_dirty(&dqopt->info[dquot->dq_type])) | 403 | if (info_dirty(&dqopt->info[dquot->dq_type])) { |
| 391 | ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type); | 404 | ret2 = dqopt->ops[dquot->dq_type]->write_file_info( |
| 405 | dquot->dq_sb, dquot->dq_type); | ||
| 406 | } | ||
| 392 | if (ret >= 0) | 407 | if (ret >= 0) |
| 393 | ret = ret2; | 408 | ret = ret2; |
| 394 | } | 409 | } |
| @@ -414,8 +429,10 @@ int dquot_release(struct dquot *dquot) | |||
| 414 | if (dqopt->ops[dquot->dq_type]->release_dqblk) { | 429 | if (dqopt->ops[dquot->dq_type]->release_dqblk) { |
| 415 | ret = dqopt->ops[dquot->dq_type]->release_dqblk(dquot); | 430 | ret = dqopt->ops[dquot->dq_type]->release_dqblk(dquot); |
| 416 | /* Write the info */ | 431 | /* Write the info */ |
| 417 | if (info_dirty(&dqopt->info[dquot->dq_type])) | 432 | if (info_dirty(&dqopt->info[dquot->dq_type])) { |
| 418 | ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type); | 433 | ret2 = dqopt->ops[dquot->dq_type]->write_file_info( |
| 434 | dquot->dq_sb, dquot->dq_type); | ||
| 435 | } | ||
| 419 | if (ret >= 0) | 436 | if (ret >= 0) |
| 420 | ret = ret2; | 437 | ret = ret2; |
| 421 | } | 438 | } |
| @@ -543,7 +560,8 @@ int vfs_quota_sync(struct super_block *sb, int type) | |||
| 543 | spin_lock(&dq_list_lock); | 560 | spin_lock(&dq_list_lock); |
| 544 | dirty = &dqopt->info[cnt].dqi_dirty_list; | 561 | dirty = &dqopt->info[cnt].dqi_dirty_list; |
| 545 | while (!list_empty(dirty)) { | 562 | while (!list_empty(dirty)) { |
| 546 | dquot = list_first_entry(dirty, struct dquot, dq_dirty); | 563 | dquot = list_first_entry(dirty, struct dquot, |
| 564 | dq_dirty); | ||
| 547 | /* Dirty and inactive can be only bad dquot... */ | 565 | /* Dirty and inactive can be only bad dquot... */ |
| 548 | if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { | 566 | if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) { |
| 549 | clear_dquot_dirty(dquot); | 567 | clear_dquot_dirty(dquot); |
| @@ -763,11 +781,12 @@ we_slept: | |||
| 763 | dqstats.lookups++; | 781 | dqstats.lookups++; |
| 764 | spin_unlock(&dq_list_lock); | 782 | spin_unlock(&dq_list_lock); |
| 765 | } | 783 | } |
| 766 | /* Wait for dq_lock - after this we know that either dquot_release() is already | 784 | /* Wait for dq_lock - after this we know that either dquot_release() is |
| 767 | * finished or it will be canceled due to dq_count > 1 test */ | 785 | * already finished or it will be canceled due to dq_count > 1 test */ |
| 768 | wait_on_dquot(dquot); | 786 | wait_on_dquot(dquot); |
| 769 | /* Read the dquot and instantiate it (everything done only if needed) */ | 787 | /* Read the dquot / allocate space in quota file */ |
| 770 | if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && sb->dq_op->acquire_dquot(dquot) < 0) { | 788 | if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && |
| 789 | sb->dq_op->acquire_dquot(dquot) < 0) { | ||
| 771 | dqput(dquot); | 790 | dqput(dquot); |
| 772 | dquot = NULL; | 791 | dquot = NULL; |
| 773 | goto out; | 792 | goto out; |
| @@ -828,7 +847,10 @@ static void add_dquot_ref(struct super_block *sb, int type) | |||
| 828 | iput(old_inode); | 847 | iput(old_inode); |
| 829 | } | 848 | } |
| 830 | 849 | ||
| 831 | /* Return 0 if dqput() won't block (note that 1 doesn't necessarily mean blocking) */ | 850 | /* |
| 851 | * Return 0 if dqput() won't block. | ||
| 852 | * (note that 1 doesn't necessarily mean blocking) | ||
| 853 | */ | ||
| 832 | static inline int dqput_blocks(struct dquot *dquot) | 854 | static inline int dqput_blocks(struct dquot *dquot) |
| 833 | { | 855 | { |
| 834 | if (atomic_read(&dquot->dq_count) <= 1) | 856 | if (atomic_read(&dquot->dq_count) <= 1) |
| @@ -836,8 +858,11 @@ static inline int dqput_blocks(struct dquot *dquot) | |||
| 836 | return 0; | 858 | return 0; |
| 837 | } | 859 | } |
| 838 | 860 | ||
| 839 | /* Remove references to dquots from inode - add dquot to list for freeing if needed */ | 861 | /* |
| 840 | /* We can't race with anybody because we hold dqptr_sem for writing... */ | 862 | * Remove references to dquots from inode and add dquot to list for freeing |
| 863 | * if we have the last referece to dquot | ||
| 864 | * We can't race with anybody because we hold dqptr_sem for writing... | ||
| 865 | */ | ||
| 841 | static int remove_inode_dquot_ref(struct inode *inode, int type, | 866 | static int remove_inode_dquot_ref(struct inode *inode, int type, |
| 842 | struct list_head *tofree_head) | 867 | struct list_head *tofree_head) |
| 843 | { | 868 | { |
| @@ -851,7 +876,9 @@ static int remove_inode_dquot_ref(struct inode *inode, int type, | |||
| 851 | printk(KERN_WARNING "VFS: Adding dquot with dq_count %d to dispose list.\n", atomic_read(&dquot->dq_count)); | 876 | printk(KERN_WARNING "VFS: Adding dquot with dq_count %d to dispose list.\n", atomic_read(&dquot->dq_count)); |
| 852 | #endif | 877 | #endif |
| 853 | spin_lock(&dq_list_lock); | 878 | spin_lock(&dq_list_lock); |
| 854 | list_add(&dquot->dq_free, tofree_head); /* As dquot must have currently users it can't be on the free list... */ | 879 | /* As dquot must have currently users it can't be on |
| 880 | * the free list... */ | ||
| 881 | list_add(&dquot->dq_free, tofree_head); | ||
| 855 | spin_unlock(&dq_list_lock); | 882 | spin_unlock(&dq_list_lock); |
| 856 | return 1; | 883 | return 1; |
| 857 | } | 884 | } |
| @@ -861,19 +888,22 @@ static int remove_inode_dquot_ref(struct inode *inode, int type, | |||
| 861 | return 0; | 888 | return 0; |
| 862 | } | 889 | } |
| 863 | 890 | ||
| 864 | /* Free list of dquots - called from inode.c */ | 891 | /* |
| 865 | /* dquots are removed from inodes, no new references can be got so we are the only ones holding reference */ | 892 | * Free list of dquots |
| 893 | * Dquots are removed from inodes and no new references can be got so we are | ||
| 894 | * the only ones holding reference | ||
| 895 | */ | ||
| 866 | static void put_dquot_list(struct list_head *tofree_head) | 896 | static void put_dquot_list(struct list_head *tofree_head) |
| 867 | { | 897 | { |
| 868 | struct list_head *act_head; | 898 | struct list_head *act_head; |
| 869 | struct dquot *dquot; | 899 | struct dquot *dquot; |
| 870 | 900 | ||
| 871 | act_head = tofree_head->next; | 901 | act_head = tofree_head->next; |
| 872 | /* So now we have dquots on the list... Just free them */ | ||
| 873 | while (act_head != tofree_head) { | 902 | while (act_head != tofree_head) { |
| 874 | dquot = list_entry(act_head, struct dquot, dq_free); | 903 | dquot = list_entry(act_head, struct dquot, dq_free); |
| 875 | act_head = act_head->next; | 904 | act_head = act_head->next; |
| 876 | list_del_init(&dquot->dq_free); /* Remove dquot from the list so we won't have problems... */ | 905 | /* Remove dquot from the list so we won't have problems... */ |
| 906 | list_del_init(&dquot->dq_free); | ||
| 877 | dqput(dquot); | 907 | dqput(dquot); |
| 878 | } | 908 | } |
| 879 | } | 909 | } |
| @@ -1131,37 +1161,42 @@ static int ignore_hardlimit(struct dquot *dquot) | |||
| 1131 | struct mem_dqinfo *info = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_type]; | 1161 | struct mem_dqinfo *info = &sb_dqopt(dquot->dq_sb)->info[dquot->dq_type]; |
| 1132 | 1162 | ||
| 1133 | return capable(CAP_SYS_RESOURCE) && | 1163 | return capable(CAP_SYS_RESOURCE) && |
| 1134 | (info->dqi_format->qf_fmt_id != QFMT_VFS_OLD || !(info->dqi_flags & V1_DQF_RSQUASH)); | 1164 | (info->dqi_format->qf_fmt_id != QFMT_VFS_OLD || |
| 1165 | !(info->dqi_flags & V1_DQF_RSQUASH)); | ||
| 1135 | } | 1166 | } |
| 1136 | 1167 | ||
| 1137 | /* needs dq_data_lock */ | 1168 | /* needs dq_data_lock */ |
| 1138 | static int check_idq(struct dquot *dquot, qsize_t inodes, char *warntype) | 1169 | static int check_idq(struct dquot *dquot, qsize_t inodes, char *warntype) |
| 1139 | { | 1170 | { |
| 1171 | qsize_t newinodes = dquot->dq_dqb.dqb_curinodes + inodes; | ||
| 1172 | |||
| 1140 | *warntype = QUOTA_NL_NOWARN; | 1173 | *warntype = QUOTA_NL_NOWARN; |
| 1141 | if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type) || | 1174 | if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type) || |
| 1142 | test_bit(DQ_FAKE_B, &dquot->dq_flags)) | 1175 | test_bit(DQ_FAKE_B, &dquot->dq_flags)) |
| 1143 | return QUOTA_OK; | 1176 | return QUOTA_OK; |
| 1144 | 1177 | ||
| 1145 | if (dquot->dq_dqb.dqb_ihardlimit && | 1178 | if (dquot->dq_dqb.dqb_ihardlimit && |
| 1146 | (dquot->dq_dqb.dqb_curinodes + inodes) > dquot->dq_dqb.dqb_ihardlimit && | 1179 | newinodes > dquot->dq_dqb.dqb_ihardlimit && |
| 1147 | !ignore_hardlimit(dquot)) { | 1180 | !ignore_hardlimit(dquot)) { |
| 1148 | *warntype = QUOTA_NL_IHARDWARN; | 1181 | *warntype = QUOTA_NL_IHARDWARN; |
| 1149 | return NO_QUOTA; | 1182 | return NO_QUOTA; |
| 1150 | } | 1183 | } |
| 1151 | 1184 | ||
| 1152 | if (dquot->dq_dqb.dqb_isoftlimit && | 1185 | if (dquot->dq_dqb.dqb_isoftlimit && |
| 1153 | (dquot->dq_dqb.dqb_curinodes + inodes) > dquot->dq_dqb.dqb_isoftlimit && | 1186 | newinodes > dquot->dq_dqb.dqb_isoftlimit && |
| 1154 | dquot->dq_dqb.dqb_itime && get_seconds() >= dquot->dq_dqb.dqb_itime && | 1187 | dquot->dq_dqb.dqb_itime && |
| 1188 | get_seconds() >= dquot->dq_dqb.dqb_itime && | ||
| 1155 | !ignore_hardlimit(dquot)) { | 1189 | !ignore_hardlimit(dquot)) { |
| 1156 | *warntype = QUOTA_NL_ISOFTLONGWARN; | 1190 | *warntype = QUOTA_NL_ISOFTLONGWARN; |
| 1157 | return NO_QUOTA; | 1191 | return NO_QUOTA; |
| 1158 | } | 1192 | } |
| 1159 | 1193 | ||
| 1160 | if (dquot->dq_dqb.dqb_isoftlimit && | 1194 | if (dquot->dq_dqb.dqb_isoftlimit && |
| 1161 | (dquot->dq_dqb.dqb_curinodes + inodes) > dquot->dq_dqb.dqb_isoftlimit && | 1195 | newinodes > dquot->dq_dqb.dqb_isoftlimit && |
| 1162 | dquot->dq_dqb.dqb_itime == 0) { | 1196 | dquot->dq_dqb.dqb_itime == 0) { |
| 1163 | *warntype = QUOTA_NL_ISOFTWARN; | 1197 | *warntype = QUOTA_NL_ISOFTWARN; |
| 1164 | dquot->dq_dqb.dqb_itime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace; | 1198 | dquot->dq_dqb.dqb_itime = get_seconds() + |
| 1199 | sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_igrace; | ||
| 1165 | } | 1200 | } |
| 1166 | 1201 | ||
| 1167 | return QUOTA_OK; | 1202 | return QUOTA_OK; |
| @@ -1171,9 +1206,10 @@ static int check_idq(struct dquot *dquot, qsize_t inodes, char *warntype) | |||
| 1171 | static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *warntype) | 1206 | static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *warntype) |
| 1172 | { | 1207 | { |
| 1173 | qsize_t tspace; | 1208 | qsize_t tspace; |
| 1209 | struct super_block *sb = dquot->dq_sb; | ||
| 1174 | 1210 | ||
| 1175 | *warntype = QUOTA_NL_NOWARN; | 1211 | *warntype = QUOTA_NL_NOWARN; |
| 1176 | if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type) || | 1212 | if (!sb_has_quota_limits_enabled(sb, dquot->dq_type) || |
| 1177 | test_bit(DQ_FAKE_B, &dquot->dq_flags)) | 1213 | test_bit(DQ_FAKE_B, &dquot->dq_flags)) |
| 1178 | return QUOTA_OK; | 1214 | return QUOTA_OK; |
| 1179 | 1215 | ||
| @@ -1190,7 +1226,8 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war | |||
| 1190 | 1226 | ||
| 1191 | if (dquot->dq_dqb.dqb_bsoftlimit && | 1227 | if (dquot->dq_dqb.dqb_bsoftlimit && |
| 1192 | tspace > dquot->dq_dqb.dqb_bsoftlimit && | 1228 | tspace > dquot->dq_dqb.dqb_bsoftlimit && |
| 1193 | dquot->dq_dqb.dqb_btime && get_seconds() >= dquot->dq_dqb.dqb_btime && | 1229 | dquot->dq_dqb.dqb_btime && |
| 1230 | get_seconds() >= dquot->dq_dqb.dqb_btime && | ||
| 1194 | !ignore_hardlimit(dquot)) { | 1231 | !ignore_hardlimit(dquot)) { |
| 1195 | if (!prealloc) | 1232 | if (!prealloc) |
| 1196 | *warntype = QUOTA_NL_BSOFTLONGWARN; | 1233 | *warntype = QUOTA_NL_BSOFTLONGWARN; |
| @@ -1202,7 +1239,8 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war | |||
| 1202 | dquot->dq_dqb.dqb_btime == 0) { | 1239 | dquot->dq_dqb.dqb_btime == 0) { |
| 1203 | if (!prealloc) { | 1240 | if (!prealloc) { |
| 1204 | *warntype = QUOTA_NL_BSOFTWARN; | 1241 | *warntype = QUOTA_NL_BSOFTWARN; |
| 1205 | dquot->dq_dqb.dqb_btime = get_seconds() + sb_dqopt(dquot->dq_sb)->info[dquot->dq_type].dqi_bgrace; | 1242 | dquot->dq_dqb.dqb_btime = get_seconds() + |
| 1243 | sb_dqopt(sb)->info[dquot->dq_type].dqi_bgrace; | ||
| 1206 | } | 1244 | } |
| 1207 | else | 1245 | else |
| 1208 | /* | 1246 | /* |
| @@ -1217,15 +1255,18 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war | |||
| 1217 | 1255 | ||
| 1218 | static int info_idq_free(struct dquot *dquot, qsize_t inodes) | 1256 | static int info_idq_free(struct dquot *dquot, qsize_t inodes) |
| 1219 | { | 1257 | { |
| 1258 | qsize_t newinodes; | ||
| 1259 | |||
| 1220 | if (test_bit(DQ_FAKE_B, &dquot->dq_flags) || | 1260 | if (test_bit(DQ_FAKE_B, &dquot->dq_flags) || |
| 1221 | dquot->dq_dqb.dqb_curinodes <= dquot->dq_dqb.dqb_isoftlimit || | 1261 | dquot->dq_dqb.dqb_curinodes <= dquot->dq_dqb.dqb_isoftlimit || |
| 1222 | !sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type)) | 1262 | !sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type)) |
| 1223 | return QUOTA_NL_NOWARN; | 1263 | return QUOTA_NL_NOWARN; |
| 1224 | 1264 | ||
| 1225 | if (dquot->dq_dqb.dqb_curinodes - inodes <= dquot->dq_dqb.dqb_isoftlimit) | 1265 | newinodes = dquot->dq_dqb.dqb_curinodes - inodes; |
| 1266 | if (newinodes <= dquot->dq_dqb.dqb_isoftlimit) | ||
| 1226 | return QUOTA_NL_ISOFTBELOW; | 1267 | return QUOTA_NL_ISOFTBELOW; |
| 1227 | if (dquot->dq_dqb.dqb_curinodes >= dquot->dq_dqb.dqb_ihardlimit && | 1268 | if (dquot->dq_dqb.dqb_curinodes >= dquot->dq_dqb.dqb_ihardlimit && |
| 1228 | dquot->dq_dqb.dqb_curinodes - inodes < dquot->dq_dqb.dqb_ihardlimit) | 1269 | newinodes < dquot->dq_dqb.dqb_ihardlimit) |
| 1229 | return QUOTA_NL_IHARDBELOW; | 1270 | return QUOTA_NL_IHARDBELOW; |
| 1230 | return QUOTA_NL_NOWARN; | 1271 | return QUOTA_NL_NOWARN; |
| 1231 | } | 1272 | } |
| @@ -1466,7 +1507,8 @@ int dquot_alloc_inode(const struct inode *inode, qsize_t number) | |||
| 1466 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1507 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
| 1467 | if (!inode->i_dquot[cnt]) | 1508 | if (!inode->i_dquot[cnt]) |
| 1468 | continue; | 1509 | continue; |
| 1469 | if (check_idq(inode->i_dquot[cnt], number, warntype+cnt) == NO_QUOTA) | 1510 | if (check_idq(inode->i_dquot[cnt], number, warntype+cnt) |
| 1511 | == NO_QUOTA) | ||
| 1470 | goto warn_put_all; | 1512 | goto warn_put_all; |
| 1471 | } | 1513 | } |
| 1472 | 1514 | ||
| @@ -1673,19 +1715,13 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) | |||
| 1673 | transfer_from[cnt] = NULL; | 1715 | transfer_from[cnt] = NULL; |
| 1674 | transfer_to[cnt] = NULL; | 1716 | transfer_to[cnt] = NULL; |
| 1675 | warntype_to[cnt] = QUOTA_NL_NOWARN; | 1717 | warntype_to[cnt] = QUOTA_NL_NOWARN; |
| 1676 | switch (cnt) { | ||
| 1677 | case USRQUOTA: | ||
| 1678 | if (!chuid) | ||
| 1679 | continue; | ||
| 1680 | transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_uid, cnt); | ||
| 1681 | break; | ||
| 1682 | case GRPQUOTA: | ||
| 1683 | if (!chgid) | ||
| 1684 | continue; | ||
| 1685 | transfer_to[cnt] = dqget(inode->i_sb, iattr->ia_gid, cnt); | ||
| 1686 | break; | ||
| 1687 | } | ||
| 1688 | } | 1718 | } |
| 1719 | if (chuid) | ||
| 1720 | transfer_to[USRQUOTA] = dqget(inode->i_sb, iattr->ia_uid, | ||
| 1721 | USRQUOTA); | ||
| 1722 | if (chgid) | ||
| 1723 | transfer_to[GRPQUOTA] = dqget(inode->i_sb, iattr->ia_gid, | ||
| 1724 | GRPQUOTA); | ||
| 1689 | 1725 | ||
| 1690 | down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1726 | down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); |
| 1691 | /* Now recheck reliably when holding dqptr_sem */ | 1727 | /* Now recheck reliably when holding dqptr_sem */ |
| @@ -1881,8 +1917,8 @@ int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags) | |||
| 1881 | drop_dquot_ref(sb, cnt); | 1917 | drop_dquot_ref(sb, cnt); |
| 1882 | invalidate_dquots(sb, cnt); | 1918 | invalidate_dquots(sb, cnt); |
| 1883 | /* | 1919 | /* |
| 1884 | * Now all dquots should be invalidated, all writes done so we should be only | 1920 | * Now all dquots should be invalidated, all writes done so we |
| 1885 | * users of the info. No locks needed. | 1921 | * should be only users of the info. No locks needed. |
| 1886 | */ | 1922 | */ |
| 1887 | if (info_dirty(&dqopt->info[cnt])) | 1923 | if (info_dirty(&dqopt->info[cnt])) |
| 1888 | sb->dq_op->write_info(sb, cnt); | 1924 | sb->dq_op->write_info(sb, cnt); |
| @@ -1920,10 +1956,12 @@ int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags) | |||
| 1920 | /* If quota was reenabled in the meantime, we have | 1956 | /* If quota was reenabled in the meantime, we have |
| 1921 | * nothing to do */ | 1957 | * nothing to do */ |
| 1922 | if (!sb_has_quota_loaded(sb, cnt)) { | 1958 | if (!sb_has_quota_loaded(sb, cnt)) { |
| 1923 | mutex_lock_nested(&toputinode[cnt]->i_mutex, I_MUTEX_QUOTA); | 1959 | mutex_lock_nested(&toputinode[cnt]->i_mutex, |
| 1960 | I_MUTEX_QUOTA); | ||
| 1924 | toputinode[cnt]->i_flags &= ~(S_IMMUTABLE | | 1961 | toputinode[cnt]->i_flags &= ~(S_IMMUTABLE | |
| 1925 | S_NOATIME | S_NOQUOTA); | 1962 | S_NOATIME | S_NOQUOTA); |
| 1926 | truncate_inode_pages(&toputinode[cnt]->i_data, 0); | 1963 | truncate_inode_pages(&toputinode[cnt]->i_data, |
| 1964 | 0); | ||
| 1927 | mutex_unlock(&toputinode[cnt]->i_mutex); | 1965 | mutex_unlock(&toputinode[cnt]->i_mutex); |
| 1928 | mark_inode_dirty(toputinode[cnt]); | 1966 | mark_inode_dirty(toputinode[cnt]); |
| 1929 | } | 1967 | } |
| @@ -2013,7 +2051,8 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id, | |||
| 2013 | * possible) Also nobody should write to the file - we use | 2051 | * possible) Also nobody should write to the file - we use |
| 2014 | * special IO operations which ignore the immutable bit. */ | 2052 | * special IO operations which ignore the immutable bit. */ |
| 2015 | down_write(&dqopt->dqptr_sem); | 2053 | down_write(&dqopt->dqptr_sem); |
| 2016 | oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE | S_NOQUOTA); | 2054 | oldflags = inode->i_flags & (S_NOATIME | S_IMMUTABLE | |
| 2055 | S_NOQUOTA); | ||
| 2017 | inode->i_flags |= S_NOQUOTA | S_NOATIME | S_IMMUTABLE; | 2056 | inode->i_flags |= S_NOQUOTA | S_NOATIME | S_IMMUTABLE; |
| 2018 | up_write(&dqopt->dqptr_sem); | 2057 | up_write(&dqopt->dqptr_sem); |
| 2019 | sb->dq_op->drop(inode); | 2058 | sb->dq_op->drop(inode); |
| @@ -2032,7 +2071,8 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id, | |||
| 2032 | dqopt->info[type].dqi_fmt_id = format_id; | 2071 | dqopt->info[type].dqi_fmt_id = format_id; |
| 2033 | INIT_LIST_HEAD(&dqopt->info[type].dqi_dirty_list); | 2072 | INIT_LIST_HEAD(&dqopt->info[type].dqi_dirty_list); |
| 2034 | mutex_lock(&dqopt->dqio_mutex); | 2073 | mutex_lock(&dqopt->dqio_mutex); |
| 2035 | if ((error = dqopt->ops[type]->read_file_info(sb, type)) < 0) { | 2074 | error = dqopt->ops[type]->read_file_info(sb, type); |
| 2075 | if (error < 0) { | ||
| 2036 | mutex_unlock(&dqopt->dqio_mutex); | 2076 | mutex_unlock(&dqopt->dqio_mutex); |
| 2037 | goto out_file_init; | 2077 | goto out_file_init; |
| 2038 | } | 2078 | } |
| @@ -2254,7 +2294,8 @@ static void do_get_dqblk(struct dquot *dquot, struct if_dqblk *di) | |||
| 2254 | spin_unlock(&dq_data_lock); | 2294 | spin_unlock(&dq_data_lock); |
| 2255 | } | 2295 | } |
| 2256 | 2296 | ||
| 2257 | int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di) | 2297 | int vfs_get_dqblk(struct super_block *sb, int type, qid_t id, |
| 2298 | struct if_dqblk *di) | ||
| 2258 | { | 2299 | { |
| 2259 | struct dquot *dquot; | 2300 | struct dquot *dquot; |
| 2260 | 2301 | ||
| @@ -2318,22 +2359,25 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di) | |||
| 2318 | } | 2359 | } |
| 2319 | 2360 | ||
| 2320 | if (check_blim) { | 2361 | if (check_blim) { |
| 2321 | if (!dm->dqb_bsoftlimit || dm->dqb_curspace < dm->dqb_bsoftlimit) { | 2362 | if (!dm->dqb_bsoftlimit || |
| 2363 | dm->dqb_curspace < dm->dqb_bsoftlimit) { | ||
| 2322 | dm->dqb_btime = 0; | 2364 | dm->dqb_btime = 0; |
| 2323 | clear_bit(DQ_BLKS_B, &dquot->dq_flags); | 2365 | clear_bit(DQ_BLKS_B, &dquot->dq_flags); |
| 2324 | } | 2366 | } else if (!(di->dqb_valid & QIF_BTIME)) |
| 2325 | else if (!(di->dqb_valid & QIF_BTIME)) /* Set grace only if user hasn't provided his own... */ | 2367 | /* Set grace only if user hasn't provided his own... */ |
| 2326 | dm->dqb_btime = get_seconds() + dqi->dqi_bgrace; | 2368 | dm->dqb_btime = get_seconds() + dqi->dqi_bgrace; |
| 2327 | } | 2369 | } |
| 2328 | if (check_ilim) { | 2370 | if (check_ilim) { |
| 2329 | if (!dm->dqb_isoftlimit || dm->dqb_curinodes < dm->dqb_isoftlimit) { | 2371 | if (!dm->dqb_isoftlimit || |
| 2372 | dm->dqb_curinodes < dm->dqb_isoftlimit) { | ||
| 2330 | dm->dqb_itime = 0; | 2373 | dm->dqb_itime = 0; |
| 2331 | clear_bit(DQ_INODES_B, &dquot->dq_flags); | 2374 | clear_bit(DQ_INODES_B, &dquot->dq_flags); |
| 2332 | } | 2375 | } else if (!(di->dqb_valid & QIF_ITIME)) |
| 2333 | else if (!(di->dqb_valid & QIF_ITIME)) /* Set grace only if user hasn't provided his own... */ | 2376 | /* Set grace only if user hasn't provided his own... */ |
| 2334 | dm->dqb_itime = get_seconds() + dqi->dqi_igrace; | 2377 | dm->dqb_itime = get_seconds() + dqi->dqi_igrace; |
| 2335 | } | 2378 | } |
| 2336 | if (dm->dqb_bhardlimit || dm->dqb_bsoftlimit || dm->dqb_ihardlimit || dm->dqb_isoftlimit) | 2379 | if (dm->dqb_bhardlimit || dm->dqb_bsoftlimit || dm->dqb_ihardlimit || |
| 2380 | dm->dqb_isoftlimit) | ||
| 2337 | clear_bit(DQ_FAKE_B, &dquot->dq_flags); | 2381 | clear_bit(DQ_FAKE_B, &dquot->dq_flags); |
| 2338 | else | 2382 | else |
| 2339 | set_bit(DQ_FAKE_B, &dquot->dq_flags); | 2383 | set_bit(DQ_FAKE_B, &dquot->dq_flags); |
| @@ -2343,7 +2387,8 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di) | |||
| 2343 | return 0; | 2387 | return 0; |
| 2344 | } | 2388 | } |
| 2345 | 2389 | ||
| 2346 | int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *di) | 2390 | int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, |
| 2391 | struct if_dqblk *di) | ||
| 2347 | { | 2392 | { |
| 2348 | struct dquot *dquot; | 2393 | struct dquot *dquot; |
| 2349 | int rc; | 2394 | int rc; |
| @@ -2400,7 +2445,8 @@ int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii) | |||
| 2400 | if (ii->dqi_valid & IIF_IGRACE) | 2445 | if (ii->dqi_valid & IIF_IGRACE) |
| 2401 | mi->dqi_igrace = ii->dqi_igrace; | 2446 | mi->dqi_igrace = ii->dqi_igrace; |
| 2402 | if (ii->dqi_valid & IIF_FLAGS) | 2447 | if (ii->dqi_valid & IIF_FLAGS) |
| 2403 | mi->dqi_flags = (mi->dqi_flags & ~DQF_MASK) | (ii->dqi_flags & DQF_MASK); | 2448 | mi->dqi_flags = (mi->dqi_flags & ~DQF_MASK) | |
| 2449 | (ii->dqi_flags & DQF_MASK); | ||
| 2404 | spin_unlock(&dq_data_lock); | 2450 | spin_unlock(&dq_data_lock); |
| 2405 | mark_info_dirty(sb, type); | 2451 | mark_info_dirty(sb, type); |
| 2406 | /* Force write to disk */ | 2452 | /* Force write to disk */ |
| @@ -2559,7 +2605,8 @@ static int __init dquot_init(void) | |||
| 2559 | 2605 | ||
| 2560 | #ifdef CONFIG_QUOTA_NETLINK_INTERFACE | 2606 | #ifdef CONFIG_QUOTA_NETLINK_INTERFACE |
| 2561 | if (genl_register_family("a_genl_family) != 0) | 2607 | if (genl_register_family("a_genl_family) != 0) |
| 2562 | printk(KERN_ERR "VFS: Failed to create quota netlink interface.\n"); | 2608 | printk(KERN_ERR |
| 2609 | "VFS: Failed to create quota netlink interface.\n"); | ||
| 2563 | #endif | 2610 | #endif |
| 2564 | 2611 | ||
| 2565 | return 0; | 2612 | return 0; |
diff --git a/fs/quota/quota.c b/fs/quota/quota.c index 89541bcbe27c..b7f5a468f076 100644 --- a/fs/quota/quota.c +++ b/fs/quota/quota.c | |||
| @@ -20,7 +20,8 @@ | |||
| 20 | #include <linux/types.h> | 20 | #include <linux/types.h> |
| 21 | 21 | ||
| 22 | /* Check validity of generic quotactl commands */ | 22 | /* Check validity of generic quotactl commands */ |
| 23 | static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id) | 23 | static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, |
| 24 | qid_t id) | ||
| 24 | { | 25 | { |
| 25 | if (type >= MAXQUOTAS) | 26 | if (type >= MAXQUOTAS) |
| 26 | return -EINVAL; | 27 | return -EINVAL; |
| @@ -72,7 +73,8 @@ static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, qid | |||
| 72 | case Q_SETINFO: | 73 | case Q_SETINFO: |
| 73 | case Q_SETQUOTA: | 74 | case Q_SETQUOTA: |
| 74 | case Q_GETQUOTA: | 75 | case Q_GETQUOTA: |
| 75 | /* This is just informative test so we are satisfied without a lock */ | 76 | /* This is just an informative test so we are satisfied |
| 77 | * without the lock */ | ||
| 76 | if (!sb_has_quota_active(sb, type)) | 78 | if (!sb_has_quota_active(sb, type)) |
| 77 | return -ESRCH; | 79 | return -ESRCH; |
| 78 | } | 80 | } |
| @@ -92,7 +94,8 @@ static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, qid | |||
| 92 | } | 94 | } |
| 93 | 95 | ||
| 94 | /* Check validity of XFS Quota Manager commands */ | 96 | /* Check validity of XFS Quota Manager commands */ |
| 95 | static int xqm_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id) | 97 | static int xqm_quotactl_valid(struct super_block *sb, int type, int cmd, |
| 98 | qid_t id) | ||
| 96 | { | 99 | { |
| 97 | if (type >= XQM_MAXQUOTAS) | 100 | if (type >= XQM_MAXQUOTAS) |
| 98 | return -EINVAL; | 101 | return -EINVAL; |
| @@ -142,7 +145,8 @@ static int xqm_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t i | |||
| 142 | return 0; | 145 | return 0; |
| 143 | } | 146 | } |
| 144 | 147 | ||
| 145 | static int check_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id) | 148 | static int check_quotactl_valid(struct super_block *sb, int type, int cmd, |
| 149 | qid_t id) | ||
| 146 | { | 150 | { |
| 147 | int error; | 151 | int error; |
| 148 | 152 | ||
| @@ -180,7 +184,8 @@ static void quota_sync_sb(struct super_block *sb, int type) | |||
| 180 | continue; | 184 | continue; |
| 181 | if (!sb_has_quota_active(sb, cnt)) | 185 | if (!sb_has_quota_active(sb, cnt)) |
| 182 | continue; | 186 | continue; |
| 183 | mutex_lock_nested(&sb_dqopt(sb)->files[cnt]->i_mutex, I_MUTEX_QUOTA); | 187 | mutex_lock_nested(&sb_dqopt(sb)->files[cnt]->i_mutex, |
| 188 | I_MUTEX_QUOTA); | ||
| 184 | truncate_inode_pages(&sb_dqopt(sb)->files[cnt]->i_data, 0); | 189 | truncate_inode_pages(&sb_dqopt(sb)->files[cnt]->i_data, 0); |
| 185 | mutex_unlock(&sb_dqopt(sb)->files[cnt]->i_mutex); | 190 | mutex_unlock(&sb_dqopt(sb)->files[cnt]->i_mutex); |
| 186 | } | 191 | } |
| @@ -200,14 +205,15 @@ void sync_dquots(struct super_block *sb, int type) | |||
| 200 | spin_lock(&sb_lock); | 205 | spin_lock(&sb_lock); |
| 201 | restart: | 206 | restart: |
| 202 | list_for_each_entry(sb, &super_blocks, s_list) { | 207 | list_for_each_entry(sb, &super_blocks, s_list) { |
| 203 | /* This test just improves performance so it needn't be reliable... */ | 208 | /* This test just improves performance so it needn't be |
| 209 | * reliable... */ | ||
| 204 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 210 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
| 205 | if (type != -1 && type != cnt) | 211 | if (type != -1 && type != cnt) |
| 206 | continue; | 212 | continue; |
| 207 | if (!sb_has_quota_active(sb, cnt)) | 213 | if (!sb_has_quota_active(sb, cnt)) |
| 208 | continue; | 214 | continue; |
| 209 | if (!info_dirty(&sb_dqopt(sb)->info[cnt]) && | 215 | if (!info_dirty(&sb_dqopt(sb)->info[cnt]) && |
| 210 | list_empty(&sb_dqopt(sb)->info[cnt].dqi_dirty_list)) | 216 | list_empty(&sb_dqopt(sb)->info[cnt].dqi_dirty_list)) |
| 211 | continue; | 217 | continue; |
| 212 | break; | 218 | break; |
| 213 | } | 219 | } |
| @@ -227,7 +233,8 @@ restart: | |||
| 227 | } | 233 | } |
| 228 | 234 | ||
| 229 | /* Copy parameters and call proper function */ | 235 | /* Copy parameters and call proper function */ |
| 230 | static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, void __user *addr) | 236 | static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, |
| 237 | void __user *addr) | ||
| 231 | { | 238 | { |
| 232 | int ret; | 239 | int ret; |
| 233 | 240 | ||
| @@ -235,7 +242,8 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, void | |||
| 235 | case Q_QUOTAON: { | 242 | case Q_QUOTAON: { |
| 236 | char *pathname; | 243 | char *pathname; |
| 237 | 244 | ||
| 238 | if (IS_ERR(pathname = getname(addr))) | 245 | pathname = getname(addr); |
| 246 | if (IS_ERR(pathname)) | ||
| 239 | return PTR_ERR(pathname); | 247 | return PTR_ERR(pathname); |
| 240 | ret = sb->s_qcop->quota_on(sb, type, id, pathname, 0); | 248 | ret = sb->s_qcop->quota_on(sb, type, id, pathname, 0); |
| 241 | putname(pathname); | 249 | putname(pathname); |
| @@ -261,7 +269,8 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, void | |||
| 261 | case Q_GETINFO: { | 269 | case Q_GETINFO: { |
| 262 | struct if_dqinfo info; | 270 | struct if_dqinfo info; |
| 263 | 271 | ||
| 264 | if ((ret = sb->s_qcop->get_info(sb, type, &info))) | 272 | ret = sb->s_qcop->get_info(sb, type, &info); |
| 273 | if (ret) | ||
| 265 | return ret; | 274 | return ret; |
| 266 | if (copy_to_user(addr, &info, sizeof(info))) | 275 | if (copy_to_user(addr, &info, sizeof(info))) |
| 267 | return -EFAULT; | 276 | return -EFAULT; |
| @@ -277,7 +286,8 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, void | |||
| 277 | case Q_GETQUOTA: { | 286 | case Q_GETQUOTA: { |
| 278 | struct if_dqblk idq; | 287 | struct if_dqblk idq; |
| 279 | 288 | ||
| 280 | if ((ret = sb->s_qcop->get_dqblk(sb, type, id, &idq))) | 289 | ret = sb->s_qcop->get_dqblk(sb, type, id, &idq); |
| 290 | if (ret) | ||
| 281 | return ret; | 291 | return ret; |
| 282 | if (copy_to_user(addr, &idq, sizeof(idq))) | 292 | if (copy_to_user(addr, &idq, sizeof(idq))) |
| 283 | return -EFAULT; | 293 | return -EFAULT; |
| @@ -322,7 +332,8 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, void | |||
| 322 | case Q_XGETQUOTA: { | 332 | case Q_XGETQUOTA: { |
| 323 | struct fs_disk_quota fdq; | 333 | struct fs_disk_quota fdq; |
| 324 | 334 | ||
| 325 | if ((ret = sb->s_qcop->get_xquota(sb, type, id, &fdq))) | 335 | ret = sb->s_qcop->get_xquota(sb, type, id, &fdq); |
| 336 | if (ret) | ||
| 326 | return ret; | 337 | return ret; |
| 327 | if (copy_to_user(addr, &fdq, sizeof(fdq))) | 338 | if (copy_to_user(addr, &fdq, sizeof(fdq))) |
| 328 | return -EFAULT; | 339 | return -EFAULT; |
diff --git a/fs/quota/quota_tree.c b/fs/quota/quota_tree.c index 48e35a48f1c2..f81f4bcfb178 100644 --- a/fs/quota/quota_tree.c +++ b/fs/quota/quota_tree.c | |||
| @@ -43,7 +43,8 @@ static char *getdqbuf(size_t size) | |||
| 43 | { | 43 | { |
| 44 | char *buf = kmalloc(size, GFP_NOFS); | 44 | char *buf = kmalloc(size, GFP_NOFS); |
| 45 | if (!buf) | 45 | if (!buf) |
| 46 | printk(KERN_WARNING "VFS: Not enough memory for quota buffers.\n"); | 46 | printk(KERN_WARNING |
| 47 | "VFS: Not enough memory for quota buffers.\n"); | ||
| 47 | return buf; | 48 | return buf; |
| 48 | } | 49 | } |
| 49 | 50 | ||
| @@ -113,7 +114,8 @@ static int put_free_dqblk(struct qtree_mem_dqinfo *info, char *buf, uint blk) | |||
| 113 | } | 114 | } |
| 114 | 115 | ||
| 115 | /* Remove given block from the list of blocks with free entries */ | 116 | /* Remove given block from the list of blocks with free entries */ |
| 116 | static int remove_free_dqentry(struct qtree_mem_dqinfo *info, char *buf, uint blk) | 117 | static int remove_free_dqentry(struct qtree_mem_dqinfo *info, char *buf, |
| 118 | uint blk) | ||
| 117 | { | 119 | { |
| 118 | char *tmpbuf = getdqbuf(info->dqi_usable_bs); | 120 | char *tmpbuf = getdqbuf(info->dqi_usable_bs); |
| 119 | struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf; | 121 | struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf; |
| @@ -150,7 +152,9 @@ static int remove_free_dqentry(struct qtree_mem_dqinfo *info, char *buf, uint bl | |||
| 150 | dh->dqdh_next_free = dh->dqdh_prev_free = cpu_to_le32(0); | 152 | dh->dqdh_next_free = dh->dqdh_prev_free = cpu_to_le32(0); |
| 151 | /* No matter whether write succeeds block is out of list */ | 153 | /* No matter whether write succeeds block is out of list */ |
| 152 | if (write_blk(info, blk, buf) < 0) | 154 | if (write_blk(info, blk, buf) < 0) |
| 153 | printk(KERN_ERR "VFS: Can't write block (%u) with free entries.\n", blk); | 155 | printk(KERN_ERR |
| 156 | "VFS: Can't write block (%u) with free entries.\n", | ||
| 157 | blk); | ||
| 154 | return 0; | 158 | return 0; |
| 155 | out_buf: | 159 | out_buf: |
| 156 | kfree(tmpbuf); | 160 | kfree(tmpbuf); |
| @@ -158,7 +162,8 @@ out_buf: | |||
| 158 | } | 162 | } |
| 159 | 163 | ||
| 160 | /* Insert given block to the beginning of list with free entries */ | 164 | /* Insert given block to the beginning of list with free entries */ |
| 161 | static int insert_free_dqentry(struct qtree_mem_dqinfo *info, char *buf, uint blk) | 165 | static int insert_free_dqentry(struct qtree_mem_dqinfo *info, char *buf, |
| 166 | uint blk) | ||
| 162 | { | 167 | { |
| 163 | char *tmpbuf = getdqbuf(info->dqi_usable_bs); | 168 | char *tmpbuf = getdqbuf(info->dqi_usable_bs); |
| 164 | struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf; | 169 | struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf; |
| @@ -230,7 +235,8 @@ static uint find_free_dqentry(struct qtree_mem_dqinfo *info, | |||
| 230 | return 0; | 235 | return 0; |
| 231 | } | 236 | } |
| 232 | memset(buf, 0, info->dqi_usable_bs); | 237 | memset(buf, 0, info->dqi_usable_bs); |
| 233 | /* This is enough as block is already zeroed and entry list is empty... */ | 238 | /* This is enough as the block is already zeroed and the entry |
| 239 | * list is empty... */ | ||
| 234 | info->dqi_free_entry = blk; | 240 | info->dqi_free_entry = blk; |
| 235 | mark_info_dirty(dquot->dq_sb, dquot->dq_type); | 241 | mark_info_dirty(dquot->dq_sb, dquot->dq_type); |
| 236 | } | 242 | } |
| @@ -246,10 +252,12 @@ static uint find_free_dqentry(struct qtree_mem_dqinfo *info, | |||
| 246 | } | 252 | } |
| 247 | le16_add_cpu(&dh->dqdh_entries, 1); | 253 | le16_add_cpu(&dh->dqdh_entries, 1); |
| 248 | /* Find free structure in block */ | 254 | /* Find free structure in block */ |
| 249 | for (i = 0, ddquot = buf + sizeof(struct qt_disk_dqdbheader); | 255 | ddquot = buf + sizeof(struct qt_disk_dqdbheader); |
| 250 | i < qtree_dqstr_in_blk(info) && !qtree_entry_unused(info, ddquot); | 256 | for (i = 0; i < qtree_dqstr_in_blk(info); i++) { |
| 251 | i++, ddquot += info->dqi_entry_size) | 257 | if (qtree_entry_unused(info, ddquot)) |
| 252 | ; | 258 | break; |
| 259 | ddquot += info->dqi_entry_size; | ||
| 260 | } | ||
| 253 | #ifdef __QUOTA_QT_PARANOIA | 261 | #ifdef __QUOTA_QT_PARANOIA |
| 254 | if (i == qtree_dqstr_in_blk(info)) { | 262 | if (i == qtree_dqstr_in_blk(info)) { |
| 255 | printk(KERN_ERR "VFS: find_free_dqentry(): Data block full " | 263 | printk(KERN_ERR "VFS: find_free_dqentry(): Data block full " |
| @@ -340,7 +348,8 @@ static inline int dq_insert_tree(struct qtree_mem_dqinfo *info, | |||
| 340 | } | 348 | } |
| 341 | 349 | ||
| 342 | /* | 350 | /* |
| 343 | * We don't have to be afraid of deadlocks as we never have quotas on quota files... | 351 | * We don't have to be afraid of deadlocks as we never have quotas on quota |
| 352 | * files... | ||
| 344 | */ | 353 | */ |
| 345 | int qtree_write_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) | 354 | int qtree_write_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) |
| 346 | { | 355 | { |
| @@ -515,10 +524,12 @@ static loff_t find_block_dqentry(struct qtree_mem_dqinfo *info, | |||
| 515 | printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk); | 524 | printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk); |
| 516 | goto out_buf; | 525 | goto out_buf; |
| 517 | } | 526 | } |
| 518 | for (i = 0, ddquot = buf + sizeof(struct qt_disk_dqdbheader); | 527 | ddquot = buf + sizeof(struct qt_disk_dqdbheader); |
| 519 | i < qtree_dqstr_in_blk(info) && !info->dqi_ops->is_id(ddquot, dquot); | 528 | for (i = 0; i < qtree_dqstr_in_blk(info); i++) { |
| 520 | i++, ddquot += info->dqi_entry_size) | 529 | if (info->dqi_ops->is_id(ddquot, dquot)) |
| 521 | ; | 530 | break; |
| 531 | ddquot += info->dqi_entry_size; | ||
| 532 | } | ||
| 522 | if (i == qtree_dqstr_in_blk(info)) { | 533 | if (i == qtree_dqstr_in_blk(info)) { |
| 523 | printk(KERN_ERR "VFS: Quota for id %u referenced " | 534 | printk(KERN_ERR "VFS: Quota for id %u referenced " |
| 524 | "but not present.\n", dquot->dq_id); | 535 | "but not present.\n", dquot->dq_id); |
| @@ -632,7 +643,8 @@ EXPORT_SYMBOL(qtree_read_dquot); | |||
| 632 | * the only one operating on dquot (thanks to dq_lock) */ | 643 | * the only one operating on dquot (thanks to dq_lock) */ |
| 633 | int qtree_release_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) | 644 | int qtree_release_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot) |
| 634 | { | 645 | { |
| 635 | if (test_bit(DQ_FAKE_B, &dquot->dq_flags) && !(dquot->dq_dqb.dqb_curinodes | dquot->dq_dqb.dqb_curspace)) | 646 | if (test_bit(DQ_FAKE_B, &dquot->dq_flags) && |
| 647 | !(dquot->dq_dqb.dqb_curinodes | dquot->dq_dqb.dqb_curspace)) | ||
| 636 | return qtree_delete_dquot(info, dquot); | 648 | return qtree_delete_dquot(info, dquot); |
| 637 | return 0; | 649 | return 0; |
| 638 | } | 650 | } |
diff --git a/fs/quota/quota_v1.c b/fs/quota/quota_v1.c index b4af1c69ad16..0edcf42b1778 100644 --- a/fs/quota/quota_v1.c +++ b/fs/quota/quota_v1.c | |||
| @@ -62,11 +62,14 @@ static int v1_read_dqblk(struct dquot *dquot) | |||
| 62 | 62 | ||
| 63 | /* Set structure to 0s in case read fails/is after end of file */ | 63 | /* Set structure to 0s in case read fails/is after end of file */ |
| 64 | memset(&dqblk, 0, sizeof(struct v1_disk_dqblk)); | 64 | memset(&dqblk, 0, sizeof(struct v1_disk_dqblk)); |
| 65 | dquot->dq_sb->s_op->quota_read(dquot->dq_sb, type, (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(dquot->dq_id)); | 65 | dquot->dq_sb->s_op->quota_read(dquot->dq_sb, type, (char *)&dqblk, |
| 66 | sizeof(struct v1_disk_dqblk), v1_dqoff(dquot->dq_id)); | ||
| 66 | 67 | ||
| 67 | v1_disk2mem_dqblk(&dquot->dq_dqb, &dqblk); | 68 | v1_disk2mem_dqblk(&dquot->dq_dqb, &dqblk); |
| 68 | if (dquot->dq_dqb.dqb_bhardlimit == 0 && dquot->dq_dqb.dqb_bsoftlimit == 0 && | 69 | if (dquot->dq_dqb.dqb_bhardlimit == 0 && |
| 69 | dquot->dq_dqb.dqb_ihardlimit == 0 && dquot->dq_dqb.dqb_isoftlimit == 0) | 70 | dquot->dq_dqb.dqb_bsoftlimit == 0 && |
| 71 | dquot->dq_dqb.dqb_ihardlimit == 0 && | ||
| 72 | dquot->dq_dqb.dqb_isoftlimit == 0) | ||
| 70 | set_bit(DQ_FAKE_B, &dquot->dq_flags); | 73 | set_bit(DQ_FAKE_B, &dquot->dq_flags); |
| 71 | dqstats.reads++; | 74 | dqstats.reads++; |
| 72 | 75 | ||
| @@ -81,13 +84,16 @@ static int v1_commit_dqblk(struct dquot *dquot) | |||
| 81 | 84 | ||
| 82 | v1_mem2disk_dqblk(&dqblk, &dquot->dq_dqb); | 85 | v1_mem2disk_dqblk(&dqblk, &dquot->dq_dqb); |
| 83 | if (dquot->dq_id == 0) { | 86 | if (dquot->dq_id == 0) { |
| 84 | dqblk.dqb_btime = sb_dqopt(dquot->dq_sb)->info[type].dqi_bgrace; | 87 | dqblk.dqb_btime = |
| 85 | dqblk.dqb_itime = sb_dqopt(dquot->dq_sb)->info[type].dqi_igrace; | 88 | sb_dqopt(dquot->dq_sb)->info[type].dqi_bgrace; |
| 89 | dqblk.dqb_itime = | ||
| 90 | sb_dqopt(dquot->dq_sb)->info[type].dqi_igrace; | ||
| 86 | } | 91 | } |
| 87 | ret = 0; | 92 | ret = 0; |
| 88 | if (sb_dqopt(dquot->dq_sb)->files[type]) | 93 | if (sb_dqopt(dquot->dq_sb)->files[type]) |
| 89 | ret = dquot->dq_sb->s_op->quota_write(dquot->dq_sb, type, (char *)&dqblk, | 94 | ret = dquot->dq_sb->s_op->quota_write(dquot->dq_sb, type, |
| 90 | sizeof(struct v1_disk_dqblk), v1_dqoff(dquot->dq_id)); | 95 | (char *)&dqblk, sizeof(struct v1_disk_dqblk), |
| 96 | v1_dqoff(dquot->dq_id)); | ||
| 91 | if (ret != sizeof(struct v1_disk_dqblk)) { | 97 | if (ret != sizeof(struct v1_disk_dqblk)) { |
| 92 | printk(KERN_WARNING "VFS: dquota write failed on dev %s\n", | 98 | printk(KERN_WARNING "VFS: dquota write failed on dev %s\n", |
| 93 | dquot->dq_sb->s_id); | 99 | dquot->dq_sb->s_id); |
| @@ -130,15 +136,20 @@ static int v1_check_quota_file(struct super_block *sb, int type) | |||
| 130 | return 0; | 136 | return 0; |
| 131 | blocks = isize >> BLOCK_SIZE_BITS; | 137 | blocks = isize >> BLOCK_SIZE_BITS; |
| 132 | off = isize & (BLOCK_SIZE - 1); | 138 | off = isize & (BLOCK_SIZE - 1); |
| 133 | if ((blocks % sizeof(struct v1_disk_dqblk) * BLOCK_SIZE + off) % sizeof(struct v1_disk_dqblk)) | 139 | if ((blocks % sizeof(struct v1_disk_dqblk) * BLOCK_SIZE + off) % |
| 140 | sizeof(struct v1_disk_dqblk)) | ||
| 134 | return 0; | 141 | return 0; |
| 135 | /* Doublecheck whether we didn't get file with new format - with old quotactl() this could happen */ | 142 | /* Doublecheck whether we didn't get file with new format - with old |
| 136 | size = sb->s_op->quota_read(sb, type, (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0); | 143 | * quotactl() this could happen */ |
| 144 | size = sb->s_op->quota_read(sb, type, (char *)&dqhead, | ||
| 145 | sizeof(struct v2_disk_dqheader), 0); | ||
| 137 | if (size != sizeof(struct v2_disk_dqheader)) | 146 | if (size != sizeof(struct v2_disk_dqheader)) |
| 138 | return 1; /* Probably not new format */ | 147 | return 1; /* Probably not new format */ |
| 139 | if (le32_to_cpu(dqhead.dqh_magic) != quota_magics[type]) | 148 | if (le32_to_cpu(dqhead.dqh_magic) != quota_magics[type]) |
| 140 | return 1; /* Definitely not new format */ | 149 | return 1; /* Definitely not new format */ |
| 141 | printk(KERN_INFO "VFS: %s: Refusing to turn on old quota format on given file. It probably contains newer quota format.\n", sb->s_id); | 150 | printk(KERN_INFO |
| 151 | "VFS: %s: Refusing to turn on old quota format on given file." | ||
| 152 | " It probably contains newer quota format.\n", sb->s_id); | ||
| 142 | return 0; /* Seems like a new format file -> refuse it */ | 153 | return 0; /* Seems like a new format file -> refuse it */ |
| 143 | } | 154 | } |
| 144 | 155 | ||
| @@ -148,7 +159,9 @@ static int v1_read_file_info(struct super_block *sb, int type) | |||
| 148 | struct v1_disk_dqblk dqblk; | 159 | struct v1_disk_dqblk dqblk; |
| 149 | int ret; | 160 | int ret; |
| 150 | 161 | ||
| 151 | if ((ret = sb->s_op->quota_read(sb, type, (char *)&dqblk, sizeof(struct v1_disk_dqblk), v1_dqoff(0))) != sizeof(struct v1_disk_dqblk)) { | 162 | ret = sb->s_op->quota_read(sb, type, (char *)&dqblk, |
| 163 | sizeof(struct v1_disk_dqblk), v1_dqoff(0)); | ||
| 164 | if (ret != sizeof(struct v1_disk_dqblk)) { | ||
| 152 | if (ret >= 0) | 165 | if (ret >= 0) |
| 153 | ret = -EIO; | 166 | ret = -EIO; |
| 154 | goto out; | 167 | goto out; |
| @@ -157,8 +170,10 @@ static int v1_read_file_info(struct super_block *sb, int type) | |||
| 157 | /* limits are stored as unsigned 32-bit data */ | 170 | /* limits are stored as unsigned 32-bit data */ |
| 158 | dqopt->info[type].dqi_maxblimit = 0xffffffff; | 171 | dqopt->info[type].dqi_maxblimit = 0xffffffff; |
| 159 | dqopt->info[type].dqi_maxilimit = 0xffffffff; | 172 | dqopt->info[type].dqi_maxilimit = 0xffffffff; |
| 160 | dqopt->info[type].dqi_igrace = dqblk.dqb_itime ? dqblk.dqb_itime : MAX_IQ_TIME; | 173 | dqopt->info[type].dqi_igrace = |
| 161 | dqopt->info[type].dqi_bgrace = dqblk.dqb_btime ? dqblk.dqb_btime : MAX_DQ_TIME; | 174 | dqblk.dqb_itime ? dqblk.dqb_itime : MAX_IQ_TIME; |
| 175 | dqopt->info[type].dqi_bgrace = | ||
| 176 | dqblk.dqb_btime ? dqblk.dqb_btime : MAX_DQ_TIME; | ||
| 162 | out: | 177 | out: |
| 163 | return ret; | 178 | return ret; |
| 164 | } | 179 | } |
| @@ -170,8 +185,9 @@ static int v1_write_file_info(struct super_block *sb, int type) | |||
| 170 | int ret; | 185 | int ret; |
| 171 | 186 | ||
| 172 | dqopt->info[type].dqi_flags &= ~DQF_INFO_DIRTY; | 187 | dqopt->info[type].dqi_flags &= ~DQF_INFO_DIRTY; |
| 173 | if ((ret = sb->s_op->quota_read(sb, type, (char *)&dqblk, | 188 | ret = sb->s_op->quota_read(sb, type, (char *)&dqblk, |
| 174 | sizeof(struct v1_disk_dqblk), v1_dqoff(0))) != sizeof(struct v1_disk_dqblk)) { | 189 | sizeof(struct v1_disk_dqblk), v1_dqoff(0)); |
| 190 | if (ret != sizeof(struct v1_disk_dqblk)) { | ||
| 175 | if (ret >= 0) | 191 | if (ret >= 0) |
| 176 | ret = -EIO; | 192 | ret = -EIO; |
| 177 | goto out; | 193 | goto out; |
diff --git a/fs/quota/quota_v2.c b/fs/quota/quota_v2.c index b618b563635c..a5475fb1ae44 100644 --- a/fs/quota/quota_v2.c +++ b/fs/quota/quota_v2.c | |||
| @@ -54,7 +54,8 @@ static int v2_check_quota_file(struct super_block *sb, int type) | |||
| 54 | static const uint quota_magics[] = V2_INITQMAGICS; | 54 | static const uint quota_magics[] = V2_INITQMAGICS; |
| 55 | static const uint quota_versions[] = V2_INITQVERSIONS; | 55 | static const uint quota_versions[] = V2_INITQVERSIONS; |
| 56 | 56 | ||
| 57 | size = sb->s_op->quota_read(sb, type, (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0); | 57 | size = sb->s_op->quota_read(sb, type, (char *)&dqhead, |
| 58 | sizeof(struct v2_disk_dqheader), 0); | ||
| 58 | if (size != sizeof(struct v2_disk_dqheader)) { | 59 | if (size != sizeof(struct v2_disk_dqheader)) { |
| 59 | printk("quota_v2: failed read expected=%zd got=%zd\n", | 60 | printk("quota_v2: failed read expected=%zd got=%zd\n", |
| 60 | sizeof(struct v2_disk_dqheader), size); | 61 | sizeof(struct v2_disk_dqheader), size); |
