diff options
-rw-r--r-- | fs/dquot.c | 60 | ||||
-rw-r--r-- | include/linux/quota.h | 4 |
2 files changed, 58 insertions, 6 deletions
diff --git a/fs/dquot.c b/fs/dquot.c index 0bcaf970bbb4..1346eebe74ce 100644 --- a/fs/dquot.c +++ b/fs/dquot.c | |||
@@ -889,7 +889,10 @@ static void print_warning(struct dquot *dquot, const int warntype) | |||
889 | char *msg = NULL; | 889 | char *msg = NULL; |
890 | struct tty_struct *tty; | 890 | struct tty_struct *tty; |
891 | 891 | ||
892 | if (!need_print_warning(dquot)) | 892 | if (warntype == QUOTA_NL_IHARDBELOW || |
893 | warntype == QUOTA_NL_ISOFTBELOW || | ||
894 | warntype == QUOTA_NL_BHARDBELOW || | ||
895 | warntype == QUOTA_NL_BSOFTBELOW || !need_print_warning(dquot)) | ||
893 | return; | 896 | return; |
894 | 897 | ||
895 | mutex_lock(&tty_mutex); | 898 | mutex_lock(&tty_mutex); |
@@ -1097,6 +1100,35 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war | |||
1097 | return QUOTA_OK; | 1100 | return QUOTA_OK; |
1098 | } | 1101 | } |
1099 | 1102 | ||
1103 | static int info_idq_free(struct dquot *dquot, ulong inodes) | ||
1104 | { | ||
1105 | if (test_bit(DQ_FAKE_B, &dquot->dq_flags) || | ||
1106 | dquot->dq_dqb.dqb_curinodes <= dquot->dq_dqb.dqb_isoftlimit) | ||
1107 | return QUOTA_NL_NOWARN; | ||
1108 | |||
1109 | if (dquot->dq_dqb.dqb_curinodes - inodes <= dquot->dq_dqb.dqb_isoftlimit) | ||
1110 | return QUOTA_NL_ISOFTBELOW; | ||
1111 | if (dquot->dq_dqb.dqb_curinodes >= dquot->dq_dqb.dqb_ihardlimit && | ||
1112 | dquot->dq_dqb.dqb_curinodes - inodes < dquot->dq_dqb.dqb_ihardlimit) | ||
1113 | return QUOTA_NL_IHARDBELOW; | ||
1114 | return QUOTA_NL_NOWARN; | ||
1115 | } | ||
1116 | |||
1117 | static int info_bdq_free(struct dquot *dquot, qsize_t space) | ||
1118 | { | ||
1119 | if (test_bit(DQ_FAKE_B, &dquot->dq_flags) || | ||
1120 | toqb(dquot->dq_dqb.dqb_curspace) <= dquot->dq_dqb.dqb_bsoftlimit) | ||
1121 | return QUOTA_NL_NOWARN; | ||
1122 | |||
1123 | if (toqb(dquot->dq_dqb.dqb_curspace - space) <= | ||
1124 | dquot->dq_dqb.dqb_bsoftlimit) | ||
1125 | return QUOTA_NL_BSOFTBELOW; | ||
1126 | if (toqb(dquot->dq_dqb.dqb_curspace) >= dquot->dq_dqb.dqb_bhardlimit && | ||
1127 | toqb(dquot->dq_dqb.dqb_curspace - space) < | ||
1128 | dquot->dq_dqb.dqb_bhardlimit) | ||
1129 | return QUOTA_NL_BHARDBELOW; | ||
1130 | return QUOTA_NL_NOWARN; | ||
1131 | } | ||
1100 | /* | 1132 | /* |
1101 | * Initialize quota pointers in inode | 1133 | * Initialize quota pointers in inode |
1102 | * Transaction must be started at entry | 1134 | * Transaction must be started at entry |
@@ -1284,6 +1316,7 @@ warn_put_all: | |||
1284 | int dquot_free_space(struct inode *inode, qsize_t number) | 1316 | int dquot_free_space(struct inode *inode, qsize_t number) |
1285 | { | 1317 | { |
1286 | unsigned int cnt; | 1318 | unsigned int cnt; |
1319 | char warntype[MAXQUOTAS]; | ||
1287 | 1320 | ||
1288 | /* First test before acquiring mutex - solves deadlocks when we | 1321 | /* First test before acquiring mutex - solves deadlocks when we |
1289 | * re-enter the quota code and are already holding the mutex */ | 1322 | * re-enter the quota code and are already holding the mutex */ |
@@ -1292,6 +1325,7 @@ out_sub: | |||
1292 | inode_sub_bytes(inode, number); | 1325 | inode_sub_bytes(inode, number); |
1293 | return QUOTA_OK; | 1326 | return QUOTA_OK; |
1294 | } | 1327 | } |
1328 | |||
1295 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1329 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1296 | /* Now recheck reliably when holding dqptr_sem */ | 1330 | /* Now recheck reliably when holding dqptr_sem */ |
1297 | if (IS_NOQUOTA(inode)) { | 1331 | if (IS_NOQUOTA(inode)) { |
@@ -1302,6 +1336,7 @@ out_sub: | |||
1302 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1336 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1303 | if (inode->i_dquot[cnt] == NODQUOT) | 1337 | if (inode->i_dquot[cnt] == NODQUOT) |
1304 | continue; | 1338 | continue; |
1339 | warntype[cnt] = info_bdq_free(inode->i_dquot[cnt], number); | ||
1305 | dquot_decr_space(inode->i_dquot[cnt], number); | 1340 | dquot_decr_space(inode->i_dquot[cnt], number); |
1306 | } | 1341 | } |
1307 | inode_sub_bytes(inode, number); | 1342 | inode_sub_bytes(inode, number); |
@@ -1310,6 +1345,7 @@ out_sub: | |||
1310 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | 1345 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) |
1311 | if (inode->i_dquot[cnt]) | 1346 | if (inode->i_dquot[cnt]) |
1312 | mark_dquot_dirty(inode->i_dquot[cnt]); | 1347 | mark_dquot_dirty(inode->i_dquot[cnt]); |
1348 | flush_warnings(inode->i_dquot, warntype); | ||
1313 | up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1349 | up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1314 | return QUOTA_OK; | 1350 | return QUOTA_OK; |
1315 | } | 1351 | } |
@@ -1320,11 +1356,13 @@ out_sub: | |||
1320 | int dquot_free_inode(const struct inode *inode, unsigned long number) | 1356 | int dquot_free_inode(const struct inode *inode, unsigned long number) |
1321 | { | 1357 | { |
1322 | unsigned int cnt; | 1358 | unsigned int cnt; |
1359 | char warntype[MAXQUOTAS]; | ||
1323 | 1360 | ||
1324 | /* First test before acquiring mutex - solves deadlocks when we | 1361 | /* First test before acquiring mutex - solves deadlocks when we |
1325 | * re-enter the quota code and are already holding the mutex */ | 1362 | * re-enter the quota code and are already holding the mutex */ |
1326 | if (IS_NOQUOTA(inode)) | 1363 | if (IS_NOQUOTA(inode)) |
1327 | return QUOTA_OK; | 1364 | return QUOTA_OK; |
1365 | |||
1328 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1366 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1329 | /* Now recheck reliably when holding dqptr_sem */ | 1367 | /* Now recheck reliably when holding dqptr_sem */ |
1330 | if (IS_NOQUOTA(inode)) { | 1368 | if (IS_NOQUOTA(inode)) { |
@@ -1335,6 +1373,7 @@ int dquot_free_inode(const struct inode *inode, unsigned long number) | |||
1335 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1373 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1336 | if (inode->i_dquot[cnt] == NODQUOT) | 1374 | if (inode->i_dquot[cnt] == NODQUOT) |
1337 | continue; | 1375 | continue; |
1376 | warntype[cnt] = info_idq_free(inode->i_dquot[cnt], number); | ||
1338 | dquot_decr_inodes(inode->i_dquot[cnt], number); | 1377 | dquot_decr_inodes(inode->i_dquot[cnt], number); |
1339 | } | 1378 | } |
1340 | spin_unlock(&dq_data_lock); | 1379 | spin_unlock(&dq_data_lock); |
@@ -1342,6 +1381,7 @@ int dquot_free_inode(const struct inode *inode, unsigned long number) | |||
1342 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | 1381 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) |
1343 | if (inode->i_dquot[cnt]) | 1382 | if (inode->i_dquot[cnt]) |
1344 | mark_dquot_dirty(inode->i_dquot[cnt]); | 1383 | mark_dquot_dirty(inode->i_dquot[cnt]); |
1384 | flush_warnings(inode->i_dquot, warntype); | ||
1345 | up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1385 | up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1346 | return QUOTA_OK; | 1386 | return QUOTA_OK; |
1347 | } | 1387 | } |
@@ -1359,7 +1399,8 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) | |||
1359 | struct dquot *transfer_to[MAXQUOTAS]; | 1399 | struct dquot *transfer_to[MAXQUOTAS]; |
1360 | int cnt, ret = NO_QUOTA, chuid = (iattr->ia_valid & ATTR_UID) && inode->i_uid != iattr->ia_uid, | 1400 | int cnt, ret = NO_QUOTA, chuid = (iattr->ia_valid & ATTR_UID) && inode->i_uid != iattr->ia_uid, |
1361 | chgid = (iattr->ia_valid & ATTR_GID) && inode->i_gid != iattr->ia_gid; | 1401 | chgid = (iattr->ia_valid & ATTR_GID) && inode->i_gid != iattr->ia_gid; |
1362 | char warntype[MAXQUOTAS]; | 1402 | char warntype_to[MAXQUOTAS]; |
1403 | char warntype_from_inodes[MAXQUOTAS], warntype_from_space[MAXQUOTAS]; | ||
1363 | 1404 | ||
1364 | /* First test before acquiring mutex - solves deadlocks when we | 1405 | /* First test before acquiring mutex - solves deadlocks when we |
1365 | * re-enter the quota code and are already holding the mutex */ | 1406 | * re-enter the quota code and are already holding the mutex */ |
@@ -1368,7 +1409,7 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) | |||
1368 | /* Clear the arrays */ | 1409 | /* Clear the arrays */ |
1369 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1410 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1370 | transfer_to[cnt] = transfer_from[cnt] = NODQUOT; | 1411 | transfer_to[cnt] = transfer_from[cnt] = NODQUOT; |
1371 | warntype[cnt] = QUOTA_NL_NOWARN; | 1412 | warntype_to[cnt] = QUOTA_NL_NOWARN; |
1372 | } | 1413 | } |
1373 | down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1414 | down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); |
1374 | /* Now recheck reliably when holding dqptr_sem */ | 1415 | /* Now recheck reliably when holding dqptr_sem */ |
@@ -1400,8 +1441,9 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) | |||
1400 | if (transfer_to[cnt] == NODQUOT) | 1441 | if (transfer_to[cnt] == NODQUOT) |
1401 | continue; | 1442 | continue; |
1402 | transfer_from[cnt] = inode->i_dquot[cnt]; | 1443 | transfer_from[cnt] = inode->i_dquot[cnt]; |
1403 | if (check_idq(transfer_to[cnt], 1, warntype+cnt) == NO_QUOTA || | 1444 | if (check_idq(transfer_to[cnt], 1, warntype_to + cnt) == |
1404 | check_bdq(transfer_to[cnt], space, 0, warntype+cnt) == NO_QUOTA) | 1445 | NO_QUOTA || check_bdq(transfer_to[cnt], space, 0, |
1446 | warntype_to + cnt) == NO_QUOTA) | ||
1405 | goto warn_put_all; | 1447 | goto warn_put_all; |
1406 | } | 1448 | } |
1407 | 1449 | ||
@@ -1417,6 +1459,10 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr) | |||
1417 | 1459 | ||
1418 | /* Due to IO error we might not have transfer_from[] structure */ | 1460 | /* Due to IO error we might not have transfer_from[] structure */ |
1419 | if (transfer_from[cnt]) { | 1461 | if (transfer_from[cnt]) { |
1462 | warntype_from_inodes[cnt] = | ||
1463 | info_idq_free(transfer_from[cnt], 1); | ||
1464 | warntype_from_space[cnt] = | ||
1465 | info_bdq_free(transfer_from[cnt], space); | ||
1420 | dquot_decr_inodes(transfer_from[cnt], 1); | 1466 | dquot_decr_inodes(transfer_from[cnt], 1); |
1421 | dquot_decr_space(transfer_from[cnt], space); | 1467 | dquot_decr_space(transfer_from[cnt], space); |
1422 | } | 1468 | } |
@@ -1436,7 +1482,9 @@ warn_put_all: | |||
1436 | if (transfer_to[cnt]) | 1482 | if (transfer_to[cnt]) |
1437 | mark_dquot_dirty(transfer_to[cnt]); | 1483 | mark_dquot_dirty(transfer_to[cnt]); |
1438 | } | 1484 | } |
1439 | flush_warnings(transfer_to, warntype); | 1485 | flush_warnings(transfer_to, warntype_to); |
1486 | flush_warnings(transfer_from, warntype_from_inodes); | ||
1487 | flush_warnings(transfer_from, warntype_from_space); | ||
1440 | 1488 | ||
1441 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1489 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1442 | if (ret == QUOTA_OK && transfer_from[cnt] != NODQUOT) | 1490 | if (ret == QUOTA_OK && transfer_from[cnt] != NODQUOT) |
diff --git a/include/linux/quota.h b/include/linux/quota.h index 4e004fef8134..376a05048bc5 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h | |||
@@ -135,6 +135,10 @@ struct if_dqinfo { | |||
135 | #define QUOTA_NL_BHARDWARN 4 /* Block hardlimit reached */ | 135 | #define QUOTA_NL_BHARDWARN 4 /* Block hardlimit reached */ |
136 | #define QUOTA_NL_BSOFTLONGWARN 5 /* Block grace time expired */ | 136 | #define QUOTA_NL_BSOFTLONGWARN 5 /* Block grace time expired */ |
137 | #define QUOTA_NL_BSOFTWARN 6 /* Block softlimit reached */ | 137 | #define QUOTA_NL_BSOFTWARN 6 /* Block softlimit reached */ |
138 | #define QUOTA_NL_IHARDBELOW 7 /* Usage got below inode hardlimit */ | ||
139 | #define QUOTA_NL_ISOFTBELOW 8 /* Usage got below inode softlimit */ | ||
140 | #define QUOTA_NL_BHARDBELOW 9 /* Usage got below block hardlimit */ | ||
141 | #define QUOTA_NL_BSOFTBELOW 10 /* Usage got below block softlimit */ | ||
138 | 142 | ||
139 | enum { | 143 | enum { |
140 | QUOTA_NL_C_UNSPEC, | 144 | QUOTA_NL_C_UNSPEC, |