diff options
author | Konstantin Khlebnikov <khlebnikov@yandex-team.ru> | 2015-02-12 04:36:37 -0500 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2015-03-04 10:42:44 -0500 |
commit | 5bcd3b6f639c277ed7fa71f2f8ed6fb072615011 (patch) | |
tree | 1caa6a5cadac9c78763c732327ab529b2ebdb0d1 /fs/quota | |
parent | 023a6007a08d342b64895a7342e426d12d9627dd (diff) |
quota: optimize i_dquot access
Remove redundant calls of i_dquot(), keep pointer in local variable.
add/remove: 0/0 grow/shrink: 3/7 up/down: 40/-278 (-238)
function old new delta
__dquot_free_space 734 750 +16
__dquot_alloc_space 484 500 +16
dquot_free_inode 324 332 +8
dquot_drop 82 69 -13
vfs_load_quota_inode 1357 1341 -16
dquot_reclaim_space_nodirty 348 316 -32
dquot_disable 1980 1944 -36
dquot_claim_space_nodirty 354 314 -40
__dquot_drop 125 83 -42
__dquot_initialize 522 423 -99
Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/quota')
-rw-r--r-- | fs/quota/dquot.c | 63 |
1 files changed, 39 insertions, 24 deletions
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index 0ccd4ba3a246..2112ed33de41 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c | |||
@@ -900,14 +900,17 @@ static inline struct dquot **i_dquot(struct inode *inode) | |||
900 | 900 | ||
901 | static int dqinit_needed(struct inode *inode, int type) | 901 | static int dqinit_needed(struct inode *inode, int type) |
902 | { | 902 | { |
903 | struct dquot * const *dquots; | ||
903 | int cnt; | 904 | int cnt; |
904 | 905 | ||
905 | if (IS_NOQUOTA(inode)) | 906 | if (IS_NOQUOTA(inode)) |
906 | return 0; | 907 | return 0; |
908 | |||
909 | dquots = i_dquot(inode); | ||
907 | if (type != -1) | 910 | if (type != -1) |
908 | return !i_dquot(inode)[type]; | 911 | return !dquots[type]; |
909 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | 912 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) |
910 | if (!i_dquot(inode)[cnt]) | 913 | if (!dquots[cnt]) |
911 | return 1; | 914 | return 1; |
912 | return 0; | 915 | return 0; |
913 | } | 916 | } |
@@ -970,12 +973,13 @@ static void add_dquot_ref(struct super_block *sb, int type) | |||
970 | static void remove_inode_dquot_ref(struct inode *inode, int type, | 973 | static void remove_inode_dquot_ref(struct inode *inode, int type, |
971 | struct list_head *tofree_head) | 974 | struct list_head *tofree_head) |
972 | { | 975 | { |
973 | struct dquot *dquot = i_dquot(inode)[type]; | 976 | struct dquot **dquots = i_dquot(inode); |
977 | struct dquot *dquot = dquots[type]; | ||
974 | 978 | ||
975 | i_dquot(inode)[type] = NULL; | ||
976 | if (!dquot) | 979 | if (!dquot) |
977 | return; | 980 | return; |
978 | 981 | ||
982 | dquots[type] = NULL; | ||
979 | if (list_empty(&dquot->dq_free)) { | 983 | if (list_empty(&dquot->dq_free)) { |
980 | /* | 984 | /* |
981 | * The inode still has reference to dquot so it can't be in the | 985 | * The inode still has reference to dquot so it can't be in the |
@@ -1389,13 +1393,15 @@ static int dquot_active(const struct inode *inode) | |||
1389 | static void __dquot_initialize(struct inode *inode, int type) | 1393 | static void __dquot_initialize(struct inode *inode, int type) |
1390 | { | 1394 | { |
1391 | int cnt, init_needed = 0; | 1395 | int cnt, init_needed = 0; |
1392 | struct dquot *got[MAXQUOTAS]; | 1396 | struct dquot **dquots, *got[MAXQUOTAS]; |
1393 | struct super_block *sb = inode->i_sb; | 1397 | struct super_block *sb = inode->i_sb; |
1394 | qsize_t rsv; | 1398 | qsize_t rsv; |
1395 | 1399 | ||
1396 | if (!dquot_active(inode)) | 1400 | if (!dquot_active(inode)) |
1397 | return; | 1401 | return; |
1398 | 1402 | ||
1403 | dquots = i_dquot(inode); | ||
1404 | |||
1399 | /* First get references to structures we might need. */ | 1405 | /* First get references to structures we might need. */ |
1400 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1406 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1401 | struct kqid qid; | 1407 | struct kqid qid; |
@@ -1407,7 +1413,7 @@ static void __dquot_initialize(struct inode *inode, int type) | |||
1407 | * we check it without locking here to avoid unnecessary | 1413 | * we check it without locking here to avoid unnecessary |
1408 | * dqget()/dqput() calls. | 1414 | * dqget()/dqput() calls. |
1409 | */ | 1415 | */ |
1410 | if (i_dquot(inode)[cnt]) | 1416 | if (dquots[cnt]) |
1411 | continue; | 1417 | continue; |
1412 | init_needed = 1; | 1418 | init_needed = 1; |
1413 | 1419 | ||
@@ -1438,8 +1444,8 @@ static void __dquot_initialize(struct inode *inode, int type) | |||
1438 | /* We could race with quotaon or dqget() could have failed */ | 1444 | /* We could race with quotaon or dqget() could have failed */ |
1439 | if (!got[cnt]) | 1445 | if (!got[cnt]) |
1440 | continue; | 1446 | continue; |
1441 | if (!i_dquot(inode)[cnt]) { | 1447 | if (!dquots[cnt]) { |
1442 | i_dquot(inode)[cnt] = got[cnt]; | 1448 | dquots[cnt] = got[cnt]; |
1443 | got[cnt] = NULL; | 1449 | got[cnt] = NULL; |
1444 | /* | 1450 | /* |
1445 | * Make quota reservation system happy if someone | 1451 | * Make quota reservation system happy if someone |
@@ -1447,7 +1453,7 @@ static void __dquot_initialize(struct inode *inode, int type) | |||
1447 | */ | 1453 | */ |
1448 | rsv = inode_get_rsv_space(inode); | 1454 | rsv = inode_get_rsv_space(inode); |
1449 | if (unlikely(rsv)) | 1455 | if (unlikely(rsv)) |
1450 | dquot_resv_space(i_dquot(inode)[cnt], rsv); | 1456 | dquot_resv_space(dquots[cnt], rsv); |
1451 | } | 1457 | } |
1452 | } | 1458 | } |
1453 | out_err: | 1459 | out_err: |
@@ -1473,12 +1479,13 @@ EXPORT_SYMBOL(dquot_initialize); | |||
1473 | static void __dquot_drop(struct inode *inode) | 1479 | static void __dquot_drop(struct inode *inode) |
1474 | { | 1480 | { |
1475 | int cnt; | 1481 | int cnt; |
1482 | struct dquot **dquots = i_dquot(inode); | ||
1476 | struct dquot *put[MAXQUOTAS]; | 1483 | struct dquot *put[MAXQUOTAS]; |
1477 | 1484 | ||
1478 | spin_lock(&dq_data_lock); | 1485 | spin_lock(&dq_data_lock); |
1479 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1486 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1480 | put[cnt] = i_dquot(inode)[cnt]; | 1487 | put[cnt] = dquots[cnt]; |
1481 | i_dquot(inode)[cnt] = NULL; | 1488 | dquots[cnt] = NULL; |
1482 | } | 1489 | } |
1483 | spin_unlock(&dq_data_lock); | 1490 | spin_unlock(&dq_data_lock); |
1484 | dqput_all(put); | 1491 | dqput_all(put); |
@@ -1486,6 +1493,7 @@ static void __dquot_drop(struct inode *inode) | |||
1486 | 1493 | ||
1487 | void dquot_drop(struct inode *inode) | 1494 | void dquot_drop(struct inode *inode) |
1488 | { | 1495 | { |
1496 | struct dquot * const *dquots; | ||
1489 | int cnt; | 1497 | int cnt; |
1490 | 1498 | ||
1491 | if (IS_NOQUOTA(inode)) | 1499 | if (IS_NOQUOTA(inode)) |
@@ -1498,8 +1506,9 @@ void dquot_drop(struct inode *inode) | |||
1498 | * must assure that nobody can come after the DQUOT_DROP and | 1506 | * must assure that nobody can come after the DQUOT_DROP and |
1499 | * add quota pointers back anyway. | 1507 | * add quota pointers back anyway. |
1500 | */ | 1508 | */ |
1509 | dquots = i_dquot(inode); | ||
1501 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1510 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1502 | if (i_dquot(inode)[cnt]) | 1511 | if (dquots[cnt]) |
1503 | break; | 1512 | break; |
1504 | } | 1513 | } |
1505 | 1514 | ||
@@ -1600,8 +1609,8 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) | |||
1600 | { | 1609 | { |
1601 | int cnt, ret = 0, index; | 1610 | int cnt, ret = 0, index; |
1602 | struct dquot_warn warn[MAXQUOTAS]; | 1611 | struct dquot_warn warn[MAXQUOTAS]; |
1603 | struct dquot **dquots = i_dquot(inode); | ||
1604 | int reserve = flags & DQUOT_SPACE_RESERVE; | 1612 | int reserve = flags & DQUOT_SPACE_RESERVE; |
1613 | struct dquot **dquots; | ||
1605 | 1614 | ||
1606 | if (!dquot_active(inode)) { | 1615 | if (!dquot_active(inode)) { |
1607 | inode_incr_space(inode, number, reserve); | 1616 | inode_incr_space(inode, number, reserve); |
@@ -1611,6 +1620,7 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) | |||
1611 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | 1620 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) |
1612 | warn[cnt].w_type = QUOTA_NL_NOWARN; | 1621 | warn[cnt].w_type = QUOTA_NL_NOWARN; |
1613 | 1622 | ||
1623 | dquots = i_dquot(inode); | ||
1614 | index = srcu_read_lock(&dquot_srcu); | 1624 | index = srcu_read_lock(&dquot_srcu); |
1615 | spin_lock(&dq_data_lock); | 1625 | spin_lock(&dq_data_lock); |
1616 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1626 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
@@ -1652,13 +1662,14 @@ int dquot_alloc_inode(struct inode *inode) | |||
1652 | { | 1662 | { |
1653 | int cnt, ret = 0, index; | 1663 | int cnt, ret = 0, index; |
1654 | struct dquot_warn warn[MAXQUOTAS]; | 1664 | struct dquot_warn warn[MAXQUOTAS]; |
1655 | struct dquot * const *dquots = i_dquot(inode); | 1665 | struct dquot * const *dquots; |
1656 | 1666 | ||
1657 | if (!dquot_active(inode)) | 1667 | if (!dquot_active(inode)) |
1658 | return 0; | 1668 | return 0; |
1659 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | 1669 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) |
1660 | warn[cnt].w_type = QUOTA_NL_NOWARN; | 1670 | warn[cnt].w_type = QUOTA_NL_NOWARN; |
1661 | 1671 | ||
1672 | dquots = i_dquot(inode); | ||
1662 | index = srcu_read_lock(&dquot_srcu); | 1673 | index = srcu_read_lock(&dquot_srcu); |
1663 | spin_lock(&dq_data_lock); | 1674 | spin_lock(&dq_data_lock); |
1664 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1675 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
@@ -1690,6 +1701,7 @@ EXPORT_SYMBOL(dquot_alloc_inode); | |||
1690 | */ | 1701 | */ |
1691 | int dquot_claim_space_nodirty(struct inode *inode, qsize_t number) | 1702 | int dquot_claim_space_nodirty(struct inode *inode, qsize_t number) |
1692 | { | 1703 | { |
1704 | struct dquot **dquots; | ||
1693 | int cnt, index; | 1705 | int cnt, index; |
1694 | 1706 | ||
1695 | if (!dquot_active(inode)) { | 1707 | if (!dquot_active(inode)) { |
@@ -1697,18 +1709,18 @@ int dquot_claim_space_nodirty(struct inode *inode, qsize_t number) | |||
1697 | return 0; | 1709 | return 0; |
1698 | } | 1710 | } |
1699 | 1711 | ||
1712 | dquots = i_dquot(inode); | ||
1700 | index = srcu_read_lock(&dquot_srcu); | 1713 | index = srcu_read_lock(&dquot_srcu); |
1701 | spin_lock(&dq_data_lock); | 1714 | spin_lock(&dq_data_lock); |
1702 | /* Claim reserved quotas to allocated quotas */ | 1715 | /* Claim reserved quotas to allocated quotas */ |
1703 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1716 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1704 | if (i_dquot(inode)[cnt]) | 1717 | if (dquots[cnt]) |
1705 | dquot_claim_reserved_space(i_dquot(inode)[cnt], | 1718 | dquot_claim_reserved_space(dquots[cnt], number); |
1706 | number); | ||
1707 | } | 1719 | } |
1708 | /* Update inode bytes */ | 1720 | /* Update inode bytes */ |
1709 | inode_claim_rsv_space(inode, number); | 1721 | inode_claim_rsv_space(inode, number); |
1710 | spin_unlock(&dq_data_lock); | 1722 | spin_unlock(&dq_data_lock); |
1711 | mark_all_dquot_dirty(i_dquot(inode)); | 1723 | mark_all_dquot_dirty(dquots); |
1712 | srcu_read_unlock(&dquot_srcu, index); | 1724 | srcu_read_unlock(&dquot_srcu, index); |
1713 | return 0; | 1725 | return 0; |
1714 | } | 1726 | } |
@@ -1719,6 +1731,7 @@ EXPORT_SYMBOL(dquot_claim_space_nodirty); | |||
1719 | */ | 1731 | */ |
1720 | void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number) | 1732 | void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number) |
1721 | { | 1733 | { |
1734 | struct dquot **dquots; | ||
1722 | int cnt, index; | 1735 | int cnt, index; |
1723 | 1736 | ||
1724 | if (!dquot_active(inode)) { | 1737 | if (!dquot_active(inode)) { |
@@ -1726,18 +1739,18 @@ void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number) | |||
1726 | return; | 1739 | return; |
1727 | } | 1740 | } |
1728 | 1741 | ||
1742 | dquots = i_dquot(inode); | ||
1729 | index = srcu_read_lock(&dquot_srcu); | 1743 | index = srcu_read_lock(&dquot_srcu); |
1730 | spin_lock(&dq_data_lock); | 1744 | spin_lock(&dq_data_lock); |
1731 | /* Claim reserved quotas to allocated quotas */ | 1745 | /* Claim reserved quotas to allocated quotas */ |
1732 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1746 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
1733 | if (i_dquot(inode)[cnt]) | 1747 | if (dquots[cnt]) |
1734 | dquot_reclaim_reserved_space(i_dquot(inode)[cnt], | 1748 | dquot_reclaim_reserved_space(dquots[cnt], number); |
1735 | number); | ||
1736 | } | 1749 | } |
1737 | /* Update inode bytes */ | 1750 | /* Update inode bytes */ |
1738 | inode_reclaim_rsv_space(inode, number); | 1751 | inode_reclaim_rsv_space(inode, number); |
1739 | spin_unlock(&dq_data_lock); | 1752 | spin_unlock(&dq_data_lock); |
1740 | mark_all_dquot_dirty(i_dquot(inode)); | 1753 | mark_all_dquot_dirty(dquots); |
1741 | srcu_read_unlock(&dquot_srcu, index); | 1754 | srcu_read_unlock(&dquot_srcu, index); |
1742 | return; | 1755 | return; |
1743 | } | 1756 | } |
@@ -1750,7 +1763,7 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags) | |||
1750 | { | 1763 | { |
1751 | unsigned int cnt; | 1764 | unsigned int cnt; |
1752 | struct dquot_warn warn[MAXQUOTAS]; | 1765 | struct dquot_warn warn[MAXQUOTAS]; |
1753 | struct dquot **dquots = i_dquot(inode); | 1766 | struct dquot **dquots; |
1754 | int reserve = flags & DQUOT_SPACE_RESERVE, index; | 1767 | int reserve = flags & DQUOT_SPACE_RESERVE, index; |
1755 | 1768 | ||
1756 | if (!dquot_active(inode)) { | 1769 | if (!dquot_active(inode)) { |
@@ -1758,6 +1771,7 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags) | |||
1758 | return; | 1771 | return; |
1759 | } | 1772 | } |
1760 | 1773 | ||
1774 | dquots = i_dquot(inode); | ||
1761 | index = srcu_read_lock(&dquot_srcu); | 1775 | index = srcu_read_lock(&dquot_srcu); |
1762 | spin_lock(&dq_data_lock); | 1776 | spin_lock(&dq_data_lock); |
1763 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1777 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
@@ -1793,12 +1807,13 @@ void dquot_free_inode(struct inode *inode) | |||
1793 | { | 1807 | { |
1794 | unsigned int cnt; | 1808 | unsigned int cnt; |
1795 | struct dquot_warn warn[MAXQUOTAS]; | 1809 | struct dquot_warn warn[MAXQUOTAS]; |
1796 | struct dquot * const *dquots = i_dquot(inode); | 1810 | struct dquot * const *dquots; |
1797 | int index; | 1811 | int index; |
1798 | 1812 | ||
1799 | if (!dquot_active(inode)) | 1813 | if (!dquot_active(inode)) |
1800 | return; | 1814 | return; |
1801 | 1815 | ||
1816 | dquots = i_dquot(inode); | ||
1802 | index = srcu_read_lock(&dquot_srcu); | 1817 | index = srcu_read_lock(&dquot_srcu); |
1803 | spin_lock(&dq_data_lock); | 1818 | spin_lock(&dq_data_lock); |
1804 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1819 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |