aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/dquot.c117
1 files changed, 86 insertions, 31 deletions
diff --git a/fs/dquot.c b/fs/dquot.c
index bca3cac4bee7..9b1c4d3c9d83 100644
--- a/fs/dquot.c
+++ b/fs/dquot.c
@@ -899,6 +899,11 @@ static inline void dquot_incr_space(struct dquot *dquot, qsize_t number)
899 dquot->dq_dqb.dqb_curspace += number; 899 dquot->dq_dqb.dqb_curspace += number;
900} 900}
901 901
902static inline void dquot_resv_space(struct dquot *dquot, qsize_t number)
903{
904 dquot->dq_dqb.dqb_rsvspace += number;
905}
906
902static inline void dquot_decr_inodes(struct dquot *dquot, qsize_t number) 907static inline void dquot_decr_inodes(struct dquot *dquot, qsize_t number)
903{ 908{
904 if (sb_dqopt(dquot->dq_sb)->flags & DQUOT_NEGATIVE_USAGE || 909 if (sb_dqopt(dquot->dq_sb)->flags & DQUOT_NEGATIVE_USAGE ||
@@ -1068,7 +1073,11 @@ err_out:
1068 kfree_skb(skb); 1073 kfree_skb(skb);
1069} 1074}
1070#endif 1075#endif
1071 1076/*
1077 * Write warnings to the console and send warning messages over netlink.
1078 *
1079 * Note that this function can sleep.
1080 */
1072static inline void flush_warnings(struct dquot * const *dquots, char *warntype) 1081static inline void flush_warnings(struct dquot * const *dquots, char *warntype)
1073{ 1082{
1074 int i; 1083 int i;
@@ -1129,13 +1138,18 @@ static int check_idq(struct dquot *dquot, qsize_t inodes, char *warntype)
1129/* needs dq_data_lock */ 1138/* needs dq_data_lock */
1130static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *warntype) 1139static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *warntype)
1131{ 1140{
1141 qsize_t tspace;
1142
1132 *warntype = QUOTA_NL_NOWARN; 1143 *warntype = QUOTA_NL_NOWARN;
1133 if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type) || 1144 if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type) ||
1134 test_bit(DQ_FAKE_B, &dquot->dq_flags)) 1145 test_bit(DQ_FAKE_B, &dquot->dq_flags))
1135 return QUOTA_OK; 1146 return QUOTA_OK;
1136 1147
1148 tspace = dquot->dq_dqb.dqb_curspace + dquot->dq_dqb.dqb_rsvspace
1149 + space;
1150
1137 if (dquot->dq_dqb.dqb_bhardlimit && 1151 if (dquot->dq_dqb.dqb_bhardlimit &&
1138 dquot->dq_dqb.dqb_curspace + space > dquot->dq_dqb.dqb_bhardlimit && 1152 tspace > dquot->dq_dqb.dqb_bhardlimit &&
1139 !ignore_hardlimit(dquot)) { 1153 !ignore_hardlimit(dquot)) {
1140 if (!prealloc) 1154 if (!prealloc)
1141 *warntype = QUOTA_NL_BHARDWARN; 1155 *warntype = QUOTA_NL_BHARDWARN;
@@ -1143,7 +1157,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war
1143 } 1157 }
1144 1158
1145 if (dquot->dq_dqb.dqb_bsoftlimit && 1159 if (dquot->dq_dqb.dqb_bsoftlimit &&
1146 dquot->dq_dqb.dqb_curspace + space > dquot->dq_dqb.dqb_bsoftlimit && 1160 tspace > dquot->dq_dqb.dqb_bsoftlimit &&
1147 dquot->dq_dqb.dqb_btime && get_seconds() >= dquot->dq_dqb.dqb_btime && 1161 dquot->dq_dqb.dqb_btime && get_seconds() >= dquot->dq_dqb.dqb_btime &&
1148 !ignore_hardlimit(dquot)) { 1162 !ignore_hardlimit(dquot)) {
1149 if (!prealloc) 1163 if (!prealloc)
@@ -1152,7 +1166,7 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war
1152 } 1166 }
1153 1167
1154 if (dquot->dq_dqb.dqb_bsoftlimit && 1168 if (dquot->dq_dqb.dqb_bsoftlimit &&
1155 dquot->dq_dqb.dqb_curspace + space > dquot->dq_dqb.dqb_bsoftlimit && 1169 tspace > dquot->dq_dqb.dqb_bsoftlimit &&
1156 dquot->dq_dqb.dqb_btime == 0) { 1170 dquot->dq_dqb.dqb_btime == 0) {
1157 if (!prealloc) { 1171 if (!prealloc) {
1158 *warntype = QUOTA_NL_BSOFTWARN; 1172 *warntype = QUOTA_NL_BSOFTWARN;
@@ -1306,51 +1320,92 @@ void vfs_dq_drop(struct inode *inode)
1306/* 1320/*
1307 * This operation can block, but only after everything is updated 1321 * This operation can block, but only after everything is updated
1308 */ 1322 */
1309int dquot_alloc_space(struct inode *inode, qsize_t number, int warn) 1323int __dquot_alloc_space(struct inode *inode, qsize_t number,
1324 int warn, int reserve)
1310{ 1325{
1311 int cnt, ret = NO_QUOTA; 1326 int cnt, ret = QUOTA_OK;
1312 char warntype[MAXQUOTAS]; 1327 char warntype[MAXQUOTAS];
1313 1328
1314 /* First test before acquiring mutex - solves deadlocks when we
1315 * re-enter the quota code and are already holding the mutex */
1316 if (IS_NOQUOTA(inode)) {
1317out_add:
1318 inode_add_bytes(inode, number);
1319 return QUOTA_OK;
1320 }
1321 for (cnt = 0; cnt < MAXQUOTAS; cnt++) 1329 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
1322 warntype[cnt] = QUOTA_NL_NOWARN; 1330 warntype[cnt] = QUOTA_NL_NOWARN;
1323 1331
1324 down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
1325 if (IS_NOQUOTA(inode)) { /* Now we can do reliable test... */
1326 up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
1327 goto out_add;
1328 }
1329 spin_lock(&dq_data_lock); 1332 spin_lock(&dq_data_lock);
1330 for (cnt = 0; cnt < MAXQUOTAS; cnt++) { 1333 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1331 if (inode->i_dquot[cnt] == NODQUOT) 1334 if (inode->i_dquot[cnt] == NODQUOT)
1332 continue; 1335 continue;
1333 if (check_bdq(inode->i_dquot[cnt], number, warn, warntype+cnt) == NO_QUOTA) 1336 if (check_bdq(inode->i_dquot[cnt], number, warn, warntype+cnt)
1334 goto warn_put_all; 1337 == NO_QUOTA) {
1338 ret = NO_QUOTA;
1339 goto out_unlock;
1340 }
1335 } 1341 }
1336 for (cnt = 0; cnt < MAXQUOTAS; cnt++) { 1342 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1337 if (inode->i_dquot[cnt] == NODQUOT) 1343 if (inode->i_dquot[cnt] == NODQUOT)
1338 continue; 1344 continue;
1339 dquot_incr_space(inode->i_dquot[cnt], number); 1345 if (reserve)
1346 dquot_resv_space(inode->i_dquot[cnt], number);
1347 else
1348 dquot_incr_space(inode->i_dquot[cnt], number);
1340 } 1349 }
1341 inode_add_bytes(inode, number); 1350 if (!reserve)
1342 ret = QUOTA_OK; 1351 inode_add_bytes(inode, number);
1343warn_put_all: 1352out_unlock:
1344 spin_unlock(&dq_data_lock); 1353 spin_unlock(&dq_data_lock);
1345 if (ret == QUOTA_OK)
1346 /* Dirtify all the dquots - this can block when journalling */
1347 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
1348 if (inode->i_dquot[cnt])
1349 mark_dquot_dirty(inode->i_dquot[cnt]);
1350 flush_warnings(inode->i_dquot, warntype); 1354 flush_warnings(inode->i_dquot, warntype);
1355 return ret;
1356}
1357
1358int dquot_alloc_space(struct inode *inode, qsize_t number, int warn)
1359{
1360 int cnt, ret = QUOTA_OK;
1361
1362 /*
1363 * First test before acquiring mutex - solves deadlocks when we
1364 * re-enter the quota code and are already holding the mutex
1365 */
1366 if (IS_NOQUOTA(inode)) {
1367 inode_add_bytes(inode, number);
1368 goto out;
1369 }
1370
1371 down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
1372 if (IS_NOQUOTA(inode)) {
1373 inode_add_bytes(inode, number);
1374 goto out_unlock;
1375 }
1376
1377 ret = __dquot_alloc_space(inode, number, warn, 0);
1378 if (ret == NO_QUOTA)
1379 goto out_unlock;
1380
1381 /* Dirtify all the dquots - this can block when journalling */
1382 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
1383 if (inode->i_dquot[cnt])
1384 mark_dquot_dirty(inode->i_dquot[cnt]);
1385out_unlock:
1351 up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); 1386 up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
1387out:
1388 return ret;
1389}
1390
1391int dquot_reserve_space(struct inode *inode, qsize_t number, int warn)
1392{
1393 int ret = QUOTA_OK;
1394
1395 if (IS_NOQUOTA(inode))
1396 goto out;
1397
1398 down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
1399 if (IS_NOQUOTA(inode))
1400 goto out_unlock;
1401
1402 ret = __dquot_alloc_space(inode, number, warn, 1);
1403out_unlock:
1404 up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
1405out:
1352 return ret; 1406 return ret;
1353} 1407}
1408EXPORT_SYMBOL(dquot_reserve_space);
1354 1409
1355/* 1410/*
1356 * This operation can block, but only after everything is updated 1411 * This operation can block, but only after everything is updated
@@ -2057,7 +2112,7 @@ static void do_get_dqblk(struct dquot *dquot, struct if_dqblk *di)
2057 spin_lock(&dq_data_lock); 2112 spin_lock(&dq_data_lock);
2058 di->dqb_bhardlimit = stoqb(dm->dqb_bhardlimit); 2113 di->dqb_bhardlimit = stoqb(dm->dqb_bhardlimit);
2059 di->dqb_bsoftlimit = stoqb(dm->dqb_bsoftlimit); 2114 di->dqb_bsoftlimit = stoqb(dm->dqb_bsoftlimit);
2060 di->dqb_curspace = dm->dqb_curspace; 2115 di->dqb_curspace = dm->dqb_curspace + dm->dqb_rsvspace;
2061 di->dqb_ihardlimit = dm->dqb_ihardlimit; 2116 di->dqb_ihardlimit = dm->dqb_ihardlimit;
2062 di->dqb_isoftlimit = dm->dqb_isoftlimit; 2117 di->dqb_isoftlimit = dm->dqb_isoftlimit;
2063 di->dqb_curinodes = dm->dqb_curinodes; 2118 di->dqb_curinodes = dm->dqb_curinodes;
@@ -2097,7 +2152,7 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di)
2097 2152
2098 spin_lock(&dq_data_lock); 2153 spin_lock(&dq_data_lock);
2099 if (di->dqb_valid & QIF_SPACE) { 2154 if (di->dqb_valid & QIF_SPACE) {
2100 dm->dqb_curspace = di->dqb_curspace; 2155 dm->dqb_curspace = di->dqb_curspace - dm->dqb_rsvspace;
2101 check_blim = 1; 2156 check_blim = 1;
2102 __set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags); 2157 __set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags);
2103 } 2158 }