aboutsummaryrefslogtreecommitdiffstats
path: root/fs/quota/dquot.c
diff options
context:
space:
mode:
authorDmitry Monakhov <dmonakhov@openvz.org>2009-12-14 07:21:13 -0500
committerJan Kara <jack@suse.cz>2009-12-23 07:33:54 -0500
commitfd8fbfc1709822bd94247c5b2ab15a5f5041e103 (patch)
tree225be57d6afafcd7c893c5b9026719f9b23def69 /fs/quota/dquot.c
parentb462707e7ccad058ae151e5c5b06eb5cadcb737f (diff)
quota: decouple fs reserved space from quota reservation
Currently inode_reservation is managed by fs itself and this reservation is transfered on dquot_transfer(). This means what inode_reservation must always be in sync with dquot->dq_dqb.dqb_rsvspace. Otherwise dquot_transfer() will result in incorrect quota(WARN_ON in dquot_claim_reserved_space() will be triggered) This is not easy because of complex locking order issues for example http://bugzilla.kernel.org/show_bug.cgi?id=14739 The patch introduce quota reservation field for each fs-inode (fs specific inode is used in order to prevent bloating generic vfs inode). This reservation is managed by quota code internally similar to i_blocks/i_bytes and may not be always in sync with internal fs reservation. Also perform some code rearrangement: - Unify dquot_reserve_space() and dquot_reserve_space() - Unify dquot_release_reserved_space() and dquot_free_space() - Also this patch add missing warning update to release_rsv() dquot_release_reserved_space() must call flush_warnings() as dquot_free_space() does. Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org> Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/quota/dquot.c')
-rw-r--r--fs/quota/dquot.c213
1 files changed, 119 insertions, 94 deletions
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index cd6bb9a33c13..1cb8fa84300f 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -1319,6 +1319,67 @@ void vfs_dq_drop(struct inode *inode)
1319EXPORT_SYMBOL(vfs_dq_drop); 1319EXPORT_SYMBOL(vfs_dq_drop);
1320 1320
1321/* 1321/*
1322 * inode_reserved_space is managed internally by quota, and protected by
1323 * i_lock similar to i_blocks+i_bytes.
1324 */
1325static qsize_t *inode_reserved_space(struct inode * inode)
1326{
1327 /* Filesystem must explicitly define it's own method in order to use
1328 * quota reservation interface */
1329 BUG_ON(!inode->i_sb->dq_op->get_reserved_space);
1330 return inode->i_sb->dq_op->get_reserved_space(inode);
1331}
1332
1333static void inode_add_rsv_space(struct inode *inode, qsize_t number)
1334{
1335 spin_lock(&inode->i_lock);
1336 *inode_reserved_space(inode) += number;
1337 spin_unlock(&inode->i_lock);
1338}
1339
1340
1341static void inode_claim_rsv_space(struct inode *inode, qsize_t number)
1342{
1343 spin_lock(&inode->i_lock);
1344 *inode_reserved_space(inode) -= number;
1345 __inode_add_bytes(inode, number);
1346 spin_unlock(&inode->i_lock);
1347}
1348
1349static void inode_sub_rsv_space(struct inode *inode, qsize_t number)
1350{
1351 spin_lock(&inode->i_lock);
1352 *inode_reserved_space(inode) -= number;
1353 spin_unlock(&inode->i_lock);
1354}
1355
1356static qsize_t inode_get_rsv_space(struct inode *inode)
1357{
1358 qsize_t ret;
1359 spin_lock(&inode->i_lock);
1360 ret = *inode_reserved_space(inode);
1361 spin_unlock(&inode->i_lock);
1362 return ret;
1363}
1364
1365static void inode_incr_space(struct inode *inode, qsize_t number,
1366 int reserve)
1367{
1368 if (reserve)
1369 inode_add_rsv_space(inode, number);
1370 else
1371 inode_add_bytes(inode, number);
1372}
1373
1374static void inode_decr_space(struct inode *inode, qsize_t number, int reserve)
1375{
1376 if (reserve)
1377 inode_sub_rsv_space(inode, number);
1378 else
1379 inode_sub_bytes(inode, number);
1380}
1381
1382/*
1322 * Following four functions update i_blocks+i_bytes fields and 1383 * Following four functions update i_blocks+i_bytes fields and
1323 * quota information (together with appropriate checks) 1384 * quota information (together with appropriate checks)
1324 * NOTE: We absolutely rely on the fact that caller dirties 1385 * NOTE: We absolutely rely on the fact that caller dirties
@@ -1336,6 +1397,21 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number,
1336 int cnt, ret = QUOTA_OK; 1397 int cnt, ret = QUOTA_OK;
1337 char warntype[MAXQUOTAS]; 1398 char warntype[MAXQUOTAS];
1338 1399
1400 /*
1401 * First test before acquiring mutex - solves deadlocks when we
1402 * re-enter the quota code and are already holding the mutex
1403 */
1404 if (IS_NOQUOTA(inode)) {
1405 inode_incr_space(inode, number, reserve);
1406 goto out;
1407 }
1408
1409 down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
1410 if (IS_NOQUOTA(inode)) {
1411 inode_incr_space(inode, number, reserve);
1412 goto out_unlock;
1413 }
1414
1339 for (cnt = 0; cnt < MAXQUOTAS; cnt++) 1415 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
1340 warntype[cnt] = QUOTA_NL_NOWARN; 1416 warntype[cnt] = QUOTA_NL_NOWARN;
1341 1417
@@ -1346,7 +1422,8 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number,
1346 if (check_bdq(inode->i_dquot[cnt], number, warn, warntype+cnt) 1422 if (check_bdq(inode->i_dquot[cnt], number, warn, warntype+cnt)
1347 == NO_QUOTA) { 1423 == NO_QUOTA) {
1348 ret = NO_QUOTA; 1424 ret = NO_QUOTA;
1349 goto out_unlock; 1425 spin_unlock(&dq_data_lock);
1426 goto out_flush_warn;
1350 } 1427 }
1351 } 1428 }
1352 for (cnt = 0; cnt < MAXQUOTAS; cnt++) { 1429 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
@@ -1357,64 +1434,32 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number,
1357 else 1434 else
1358 dquot_incr_space(inode->i_dquot[cnt], number); 1435 dquot_incr_space(inode->i_dquot[cnt], number);
1359 } 1436 }
1360 if (!reserve) 1437 inode_incr_space(inode, number, reserve);
1361 inode_add_bytes(inode, number);
1362out_unlock:
1363 spin_unlock(&dq_data_lock); 1438 spin_unlock(&dq_data_lock);
1364 flush_warnings(inode->i_dquot, warntype);
1365 return ret;
1366}
1367
1368int dquot_alloc_space(struct inode *inode, qsize_t number, int warn)
1369{
1370 int cnt, ret = QUOTA_OK;
1371
1372 /*
1373 * First test before acquiring mutex - solves deadlocks when we
1374 * re-enter the quota code and are already holding the mutex
1375 */
1376 if (IS_NOQUOTA(inode)) {
1377 inode_add_bytes(inode, number);
1378 goto out;
1379 }
1380
1381 down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
1382 if (IS_NOQUOTA(inode)) {
1383 inode_add_bytes(inode, number);
1384 goto out_unlock;
1385 }
1386
1387 ret = __dquot_alloc_space(inode, number, warn, 0);
1388 if (ret == NO_QUOTA)
1389 goto out_unlock;
1390 1439
1440 if (reserve)
1441 goto out_flush_warn;
1391 /* Dirtify all the dquots - this can block when journalling */ 1442 /* Dirtify all the dquots - this can block when journalling */
1392 for (cnt = 0; cnt < MAXQUOTAS; cnt++) 1443 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
1393 if (inode->i_dquot[cnt]) 1444 if (inode->i_dquot[cnt])
1394 mark_dquot_dirty(inode->i_dquot[cnt]); 1445 mark_dquot_dirty(inode->i_dquot[cnt]);
1446out_flush_warn:
1447 flush_warnings(inode->i_dquot, warntype);
1395out_unlock: 1448out_unlock:
1396 up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); 1449 up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
1397out: 1450out:
1398 return ret; 1451 return ret;
1399} 1452}
1453
1454int dquot_alloc_space(struct inode *inode, qsize_t number, int warn)
1455{
1456 return __dquot_alloc_space(inode, number, warn, 0);
1457}
1400EXPORT_SYMBOL(dquot_alloc_space); 1458EXPORT_SYMBOL(dquot_alloc_space);
1401 1459
1402int dquot_reserve_space(struct inode *inode, qsize_t number, int warn) 1460int dquot_reserve_space(struct inode *inode, qsize_t number, int warn)
1403{ 1461{
1404 int ret = QUOTA_OK; 1462 return __dquot_alloc_space(inode, number, warn, 1);
1405
1406 if (IS_NOQUOTA(inode))
1407 goto out;
1408
1409 down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
1410 if (IS_NOQUOTA(inode))
1411 goto out_unlock;
1412
1413 ret = __dquot_alloc_space(inode, number, warn, 1);
1414out_unlock:
1415 up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
1416out:
1417 return ret;
1418} 1463}
1419EXPORT_SYMBOL(dquot_reserve_space); 1464EXPORT_SYMBOL(dquot_reserve_space);
1420 1465
@@ -1471,14 +1516,14 @@ int dquot_claim_space(struct inode *inode, qsize_t number)
1471 int ret = QUOTA_OK; 1516 int ret = QUOTA_OK;
1472 1517
1473 if (IS_NOQUOTA(inode)) { 1518 if (IS_NOQUOTA(inode)) {
1474 inode_add_bytes(inode, number); 1519 inode_claim_rsv_space(inode, number);
1475 goto out; 1520 goto out;
1476 } 1521 }
1477 1522
1478 down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); 1523 down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
1479 if (IS_NOQUOTA(inode)) { 1524 if (IS_NOQUOTA(inode)) {
1480 up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); 1525 up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
1481 inode_add_bytes(inode, number); 1526 inode_claim_rsv_space(inode, number);
1482 goto out; 1527 goto out;
1483 } 1528 }
1484 1529
@@ -1490,7 +1535,7 @@ int dquot_claim_space(struct inode *inode, qsize_t number)
1490 number); 1535 number);
1491 } 1536 }
1492 /* Update inode bytes */ 1537 /* Update inode bytes */
1493 inode_add_bytes(inode, number); 1538 inode_claim_rsv_space(inode, number);
1494 spin_unlock(&dq_data_lock); 1539 spin_unlock(&dq_data_lock);
1495 /* Dirtify all the dquots - this can block when journalling */ 1540 /* Dirtify all the dquots - this can block when journalling */
1496 for (cnt = 0; cnt < MAXQUOTAS; cnt++) 1541 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
@@ -1503,38 +1548,9 @@ out:
1503EXPORT_SYMBOL(dquot_claim_space); 1548EXPORT_SYMBOL(dquot_claim_space);
1504 1549
1505/* 1550/*
1506 * Release reserved quota space
1507 */
1508void dquot_release_reserved_space(struct inode *inode, qsize_t number)
1509{
1510 int cnt;
1511
1512 if (IS_NOQUOTA(inode))
1513 goto out;
1514
1515 down_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
1516 if (IS_NOQUOTA(inode))
1517 goto out_unlock;
1518
1519 spin_lock(&dq_data_lock);
1520 /* Release reserved dquots */
1521 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
1522 if (inode->i_dquot[cnt])
1523 dquot_free_reserved_space(inode->i_dquot[cnt], number);
1524 }
1525 spin_unlock(&dq_data_lock);
1526
1527out_unlock:
1528 up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
1529out:
1530 return;
1531}
1532EXPORT_SYMBOL(dquot_release_reserved_space);
1533
1534/*
1535 * This operation can block, but only after everything is updated 1551 * This operation can block, but only after everything is updated
1536 */ 1552 */
1537int dquot_free_space(struct inode *inode, qsize_t number) 1553int __dquot_free_space(struct inode *inode, qsize_t number, int reserve)
1538{ 1554{
1539 unsigned int cnt; 1555 unsigned int cnt;
1540 char warntype[MAXQUOTAS]; 1556 char warntype[MAXQUOTAS];
@@ -1543,7 +1559,7 @@ int dquot_free_space(struct inode *inode, qsize_t number)
1543 * re-enter the quota code and are already holding the mutex */ 1559 * re-enter the quota code and are already holding the mutex */
1544 if (IS_NOQUOTA(inode)) { 1560 if (IS_NOQUOTA(inode)) {
1545out_sub: 1561out_sub:
1546 inode_sub_bytes(inode, number); 1562 inode_decr_space(inode, number, reserve);
1547 return QUOTA_OK; 1563 return QUOTA_OK;
1548 } 1564 }
1549 1565
@@ -1558,21 +1574,43 @@ out_sub:
1558 if (!inode->i_dquot[cnt]) 1574 if (!inode->i_dquot[cnt])
1559 continue; 1575 continue;
1560 warntype[cnt] = info_bdq_free(inode->i_dquot[cnt], number); 1576 warntype[cnt] = info_bdq_free(inode->i_dquot[cnt], number);
1561 dquot_decr_space(inode->i_dquot[cnt], number); 1577 if (reserve)
1578 dquot_free_reserved_space(inode->i_dquot[cnt], number);
1579 else
1580 dquot_decr_space(inode->i_dquot[cnt], number);
1562 } 1581 }
1563 inode_sub_bytes(inode, number); 1582 inode_decr_space(inode, number, reserve);
1564 spin_unlock(&dq_data_lock); 1583 spin_unlock(&dq_data_lock);
1584
1585 if (reserve)
1586 goto out_unlock;
1565 /* Dirtify all the dquots - this can block when journalling */ 1587 /* Dirtify all the dquots - this can block when journalling */
1566 for (cnt = 0; cnt < MAXQUOTAS; cnt++) 1588 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
1567 if (inode->i_dquot[cnt]) 1589 if (inode->i_dquot[cnt])
1568 mark_dquot_dirty(inode->i_dquot[cnt]); 1590 mark_dquot_dirty(inode->i_dquot[cnt]);
1591out_unlock:
1569 flush_warnings(inode->i_dquot, warntype); 1592 flush_warnings(inode->i_dquot, warntype);
1570 up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); 1593 up_read(&sb_dqopt(inode->i_sb)->dqptr_sem);
1571 return QUOTA_OK; 1594 return QUOTA_OK;
1572} 1595}
1596
1597int dquot_free_space(struct inode *inode, qsize_t number)
1598{
1599 return __dquot_free_space(inode, number, 0);
1600}
1573EXPORT_SYMBOL(dquot_free_space); 1601EXPORT_SYMBOL(dquot_free_space);
1574 1602
1575/* 1603/*
1604 * Release reserved quota space
1605 */
1606void dquot_release_reserved_space(struct inode *inode, qsize_t number)
1607{
1608 __dquot_free_space(inode, number, 1);
1609
1610}
1611EXPORT_SYMBOL(dquot_release_reserved_space);
1612
1613/*
1576 * This operation can block, but only after everything is updated 1614 * This operation can block, but only after everything is updated
1577 */ 1615 */
1578int dquot_free_inode(const struct inode *inode, qsize_t number) 1616int dquot_free_inode(const struct inode *inode, qsize_t number)
@@ -1610,19 +1648,6 @@ int dquot_free_inode(const struct inode *inode, qsize_t number)
1610EXPORT_SYMBOL(dquot_free_inode); 1648EXPORT_SYMBOL(dquot_free_inode);
1611 1649
1612/* 1650/*
1613 * call back function, get reserved quota space from underlying fs
1614 */
1615qsize_t dquot_get_reserved_space(struct inode *inode)
1616{
1617 qsize_t reserved_space = 0;
1618
1619 if (sb_any_quota_active(inode->i_sb) &&
1620 inode->i_sb->dq_op->get_reserved_space)
1621 reserved_space = inode->i_sb->dq_op->get_reserved_space(inode);
1622 return reserved_space;
1623}
1624
1625/*
1626 * Transfer the number of inode and blocks from one diskquota to an other. 1651 * Transfer the number of inode and blocks from one diskquota to an other.
1627 * 1652 *
1628 * This operation can block, but only after everything is updated 1653 * This operation can block, but only after everything is updated
@@ -1665,7 +1690,7 @@ int dquot_transfer(struct inode *inode, struct iattr *iattr)
1665 } 1690 }
1666 spin_lock(&dq_data_lock); 1691 spin_lock(&dq_data_lock);
1667 cur_space = inode_get_bytes(inode); 1692 cur_space = inode_get_bytes(inode);
1668 rsv_space = dquot_get_reserved_space(inode); 1693 rsv_space = inode_get_rsv_space(inode);
1669 space = cur_space + rsv_space; 1694 space = cur_space + rsv_space;
1670 /* Build the transfer_from list and check the limits */ 1695 /* Build the transfer_from list and check the limits */
1671 for (cnt = 0; cnt < MAXQUOTAS; cnt++) { 1696 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {