diff options
| -rw-r--r-- | fs/quota/dquot.c | 114 | ||||
| -rw-r--r-- | fs/super.c | 1 | ||||
| -rw-r--r-- | include/linux/quota.h | 1 |
3 files changed, 49 insertions, 67 deletions
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c index fb2d2e2a89e7..f2d0eee9d1f1 100644 --- a/fs/quota/dquot.c +++ b/fs/quota/dquot.c | |||
| @@ -96,13 +96,16 @@ | |||
| 96 | * Note that some things (eg. sb pointer, type, id) doesn't change during | 96 | * Note that some things (eg. sb pointer, type, id) doesn't change during |
| 97 | * the life of the dquot structure and so needn't to be protected by a lock | 97 | * the life of the dquot structure and so needn't to be protected by a lock |
| 98 | * | 98 | * |
| 99 | * Any operation working on dquots via inode pointers must hold dqptr_sem. If | 99 | * Operation accessing dquots via inode pointers are protected by dquot_srcu. |
| 100 | * operation is just reading pointers from inode (or not using them at all) the | 100 | * Operation of reading pointer needs srcu_read_lock(&dquot_srcu), and |
| 101 | * read lock is enough. If pointers are altered function must hold write lock. | 101 | * synchronize_srcu(&dquot_srcu) is called after clearing pointers from |
| 102 | * inode and before dropping dquot references to avoid use of dquots after | ||
| 103 | * they are freed. dq_data_lock is used to serialize the pointer setting and | ||
| 104 | * clearing operations. | ||
| 102 | * Special care needs to be taken about S_NOQUOTA inode flag (marking that | 105 | * Special care needs to be taken about S_NOQUOTA inode flag (marking that |
| 103 | * inode is a quota file). Functions adding pointers from inode to dquots have | 106 | * inode is a quota file). Functions adding pointers from inode to dquots have |
| 104 | * to check this flag under dqptr_sem and then (if S_NOQUOTA is not set) they | 107 | * to check this flag under dq_data_lock and then (if S_NOQUOTA is not set) they |
| 105 | * have to do all pointer modifications before dropping dqptr_sem. This makes | 108 | * have to do all pointer modifications before dropping dq_data_lock. This makes |
| 106 | * sure they cannot race with quotaon which first sets S_NOQUOTA flag and | 109 | * sure they cannot race with quotaon which first sets S_NOQUOTA flag and |
| 107 | * then drops all pointers to dquots from an inode. | 110 | * then drops all pointers to dquots from an inode. |
| 108 | * | 111 | * |
| @@ -116,21 +119,15 @@ | |||
| 116 | * spinlock to internal buffers before writing. | 119 | * spinlock to internal buffers before writing. |
| 117 | * | 120 | * |
| 118 | * Lock ordering (including related VFS locks) is the following: | 121 | * Lock ordering (including related VFS locks) is the following: |
| 119 | * dqonoff_mutex > i_mutex > journal_lock > dqptr_sem > dquot->dq_lock > | 122 | * dqonoff_mutex > i_mutex > journal_lock > dquot->dq_lock > dqio_mutex |
| 120 | * dqio_mutex | ||
| 121 | * dqonoff_mutex > i_mutex comes from dquot_quota_sync, dquot_enable, etc. | 123 | * dqonoff_mutex > i_mutex comes from dquot_quota_sync, dquot_enable, etc. |
| 122 | * The lock ordering of dqptr_sem imposed by quota code is only dqonoff_sem > | ||
| 123 | * dqptr_sem. But filesystem has to count with the fact that functions such as | ||
| 124 | * dquot_alloc_space() acquire dqptr_sem and they usually have to be called | ||
| 125 | * from inside a transaction to keep filesystem consistency after a crash. Also | ||
| 126 | * filesystems usually want to do some IO on dquot from ->mark_dirty which is | ||
| 127 | * called with dqptr_sem held. | ||
| 128 | */ | 124 | */ |
| 129 | 125 | ||
| 130 | static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_list_lock); | 126 | static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_list_lock); |
| 131 | static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_state_lock); | 127 | static __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_state_lock); |
| 132 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_data_lock); | 128 | __cacheline_aligned_in_smp DEFINE_SPINLOCK(dq_data_lock); |
| 133 | EXPORT_SYMBOL(dq_data_lock); | 129 | EXPORT_SYMBOL(dq_data_lock); |
| 130 | DEFINE_STATIC_SRCU(dquot_srcu); | ||
| 134 | 131 | ||
| 135 | void __quota_error(struct super_block *sb, const char *func, | 132 | void __quota_error(struct super_block *sb, const char *func, |
| 136 | const char *fmt, ...) | 133 | const char *fmt, ...) |
| @@ -964,7 +961,6 @@ static void add_dquot_ref(struct super_block *sb, int type) | |||
| 964 | /* | 961 | /* |
| 965 | * Remove references to dquots from inode and add dquot to list for freeing | 962 | * Remove references to dquots from inode and add dquot to list for freeing |
| 966 | * if we have the last reference to dquot | 963 | * if we have the last reference to dquot |
| 967 | * We can't race with anybody because we hold dqptr_sem for writing... | ||
| 968 | */ | 964 | */ |
| 969 | static void remove_inode_dquot_ref(struct inode *inode, int type, | 965 | static void remove_inode_dquot_ref(struct inode *inode, int type, |
| 970 | struct list_head *tofree_head) | 966 | struct list_head *tofree_head) |
| @@ -1024,13 +1020,15 @@ static void remove_dquot_ref(struct super_block *sb, int type, | |||
| 1024 | * We have to scan also I_NEW inodes because they can already | 1020 | * We have to scan also I_NEW inodes because they can already |
| 1025 | * have quota pointer initialized. Luckily, we need to touch | 1021 | * have quota pointer initialized. Luckily, we need to touch |
| 1026 | * only quota pointers and these have separate locking | 1022 | * only quota pointers and these have separate locking |
| 1027 | * (dqptr_sem). | 1023 | * (dq_data_lock). |
| 1028 | */ | 1024 | */ |
| 1025 | spin_lock(&dq_data_lock); | ||
| 1029 | if (!IS_NOQUOTA(inode)) { | 1026 | if (!IS_NOQUOTA(inode)) { |
| 1030 | if (unlikely(inode_get_rsv_space(inode) > 0)) | 1027 | if (unlikely(inode_get_rsv_space(inode) > 0)) |
| 1031 | reserved = 1; | 1028 | reserved = 1; |
| 1032 | remove_inode_dquot_ref(inode, type, tofree_head); | 1029 | remove_inode_dquot_ref(inode, type, tofree_head); |
| 1033 | } | 1030 | } |
| 1031 | spin_unlock(&dq_data_lock); | ||
| 1034 | } | 1032 | } |
| 1035 | spin_unlock(&inode_sb_list_lock); | 1033 | spin_unlock(&inode_sb_list_lock); |
| 1036 | #ifdef CONFIG_QUOTA_DEBUG | 1034 | #ifdef CONFIG_QUOTA_DEBUG |
| @@ -1048,9 +1046,8 @@ static void drop_dquot_ref(struct super_block *sb, int type) | |||
| 1048 | LIST_HEAD(tofree_head); | 1046 | LIST_HEAD(tofree_head); |
| 1049 | 1047 | ||
| 1050 | if (sb->dq_op) { | 1048 | if (sb->dq_op) { |
| 1051 | down_write(&sb_dqopt(sb)->dqptr_sem); | ||
| 1052 | remove_dquot_ref(sb, type, &tofree_head); | 1049 | remove_dquot_ref(sb, type, &tofree_head); |
| 1053 | up_write(&sb_dqopt(sb)->dqptr_sem); | 1050 | synchronize_srcu(&dquot_srcu); |
| 1054 | put_dquot_list(&tofree_head); | 1051 | put_dquot_list(&tofree_head); |
| 1055 | } | 1052 | } |
| 1056 | } | 1053 | } |
| @@ -1381,9 +1378,6 @@ static int dquot_active(const struct inode *inode) | |||
| 1381 | /* | 1378 | /* |
| 1382 | * Initialize quota pointers in inode | 1379 | * Initialize quota pointers in inode |
| 1383 | * | 1380 | * |
| 1384 | * We do things in a bit complicated way but by that we avoid calling | ||
| 1385 | * dqget() and thus filesystem callbacks under dqptr_sem. | ||
| 1386 | * | ||
| 1387 | * It is better to call this function outside of any transaction as it | 1381 | * It is better to call this function outside of any transaction as it |
| 1388 | * might need a lot of space in journal for dquot structure allocation. | 1382 | * might need a lot of space in journal for dquot structure allocation. |
| 1389 | */ | 1383 | */ |
| @@ -1394,8 +1388,6 @@ static void __dquot_initialize(struct inode *inode, int type) | |||
| 1394 | struct super_block *sb = inode->i_sb; | 1388 | struct super_block *sb = inode->i_sb; |
| 1395 | qsize_t rsv; | 1389 | qsize_t rsv; |
| 1396 | 1390 | ||
| 1397 | /* First test before acquiring mutex - solves deadlocks when we | ||
| 1398 | * re-enter the quota code and are already holding the mutex */ | ||
| 1399 | if (!dquot_active(inode)) | 1391 | if (!dquot_active(inode)) |
| 1400 | return; | 1392 | return; |
| 1401 | 1393 | ||
| @@ -1429,7 +1421,7 @@ static void __dquot_initialize(struct inode *inode, int type) | |||
| 1429 | if (!init_needed) | 1421 | if (!init_needed) |
| 1430 | return; | 1422 | return; |
| 1431 | 1423 | ||
| 1432 | down_write(&sb_dqopt(sb)->dqptr_sem); | 1424 | spin_lock(&dq_data_lock); |
| 1433 | if (IS_NOQUOTA(inode)) | 1425 | if (IS_NOQUOTA(inode)) |
| 1434 | goto out_err; | 1426 | goto out_err; |
| 1435 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1427 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
| @@ -1449,15 +1441,12 @@ static void __dquot_initialize(struct inode *inode, int type) | |||
| 1449 | * did a write before quota was turned on | 1441 | * did a write before quota was turned on |
| 1450 | */ | 1442 | */ |
| 1451 | rsv = inode_get_rsv_space(inode); | 1443 | rsv = inode_get_rsv_space(inode); |
| 1452 | if (unlikely(rsv)) { | 1444 | if (unlikely(rsv)) |
| 1453 | spin_lock(&dq_data_lock); | ||
| 1454 | dquot_resv_space(inode->i_dquot[cnt], rsv); | 1445 | dquot_resv_space(inode->i_dquot[cnt], rsv); |
| 1455 | spin_unlock(&dq_data_lock); | ||
| 1456 | } | ||
| 1457 | } | 1446 | } |
| 1458 | } | 1447 | } |
| 1459 | out_err: | 1448 | out_err: |
| 1460 | up_write(&sb_dqopt(sb)->dqptr_sem); | 1449 | spin_unlock(&dq_data_lock); |
| 1461 | /* Drop unused references */ | 1450 | /* Drop unused references */ |
| 1462 | dqput_all(got); | 1451 | dqput_all(got); |
| 1463 | } | 1452 | } |
| @@ -1469,19 +1458,24 @@ void dquot_initialize(struct inode *inode) | |||
| 1469 | EXPORT_SYMBOL(dquot_initialize); | 1458 | EXPORT_SYMBOL(dquot_initialize); |
| 1470 | 1459 | ||
| 1471 | /* | 1460 | /* |
| 1472 | * Release all quotas referenced by inode | 1461 | * Release all quotas referenced by inode. |
| 1462 | * | ||
| 1463 | * This function only be called on inode free or converting | ||
| 1464 | * a file to quota file, no other users for the i_dquot in | ||
| 1465 | * both cases, so we needn't call synchronize_srcu() after | ||
| 1466 | * clearing i_dquot. | ||
| 1473 | */ | 1467 | */ |
| 1474 | static void __dquot_drop(struct inode *inode) | 1468 | static void __dquot_drop(struct inode *inode) |
| 1475 | { | 1469 | { |
| 1476 | int cnt; | 1470 | int cnt; |
| 1477 | struct dquot *put[MAXQUOTAS]; | 1471 | struct dquot *put[MAXQUOTAS]; |
| 1478 | 1472 | ||
| 1479 | down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1473 | spin_lock(&dq_data_lock); |
| 1480 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1474 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
| 1481 | put[cnt] = inode->i_dquot[cnt]; | 1475 | put[cnt] = inode->i_dquot[cnt]; |
| 1482 | inode->i_dquot[cnt] = NULL; | 1476 | inode->i_dquot[cnt] = NULL; |
| 1483 | } | 1477 | } |
| 1484 | up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1478 | spin_unlock(&dq_data_lock); |
| 1485 | dqput_all(put); | 1479 | dqput_all(put); |
| 1486 | } | 1480 | } |
| 1487 | 1481 | ||
| @@ -1599,15 +1593,11 @@ static void inode_decr_space(struct inode *inode, qsize_t number, int reserve) | |||
| 1599 | */ | 1593 | */ |
| 1600 | int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) | 1594 | int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) |
| 1601 | { | 1595 | { |
| 1602 | int cnt, ret = 0; | 1596 | int cnt, ret = 0, index; |
| 1603 | struct dquot_warn warn[MAXQUOTAS]; | 1597 | struct dquot_warn warn[MAXQUOTAS]; |
| 1604 | struct dquot **dquots = inode->i_dquot; | 1598 | struct dquot **dquots = inode->i_dquot; |
| 1605 | int reserve = flags & DQUOT_SPACE_RESERVE; | 1599 | int reserve = flags & DQUOT_SPACE_RESERVE; |
| 1606 | 1600 | ||
| 1607 | /* | ||
| 1608 | * First test before acquiring mutex - solves deadlocks when we | ||
| 1609 | * re-enter the quota code and are already holding the mutex | ||
| 1610 | */ | ||
| 1611 | if (!dquot_active(inode)) { | 1601 | if (!dquot_active(inode)) { |
| 1612 | inode_incr_space(inode, number, reserve); | 1602 | inode_incr_space(inode, number, reserve); |
| 1613 | goto out; | 1603 | goto out; |
| @@ -1616,7 +1606,7 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) | |||
| 1616 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | 1606 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) |
| 1617 | warn[cnt].w_type = QUOTA_NL_NOWARN; | 1607 | warn[cnt].w_type = QUOTA_NL_NOWARN; |
| 1618 | 1608 | ||
| 1619 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1609 | index = srcu_read_lock(&dquot_srcu); |
| 1620 | spin_lock(&dq_data_lock); | 1610 | spin_lock(&dq_data_lock); |
| 1621 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1611 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
| 1622 | if (!dquots[cnt]) | 1612 | if (!dquots[cnt]) |
| @@ -1643,7 +1633,7 @@ int __dquot_alloc_space(struct inode *inode, qsize_t number, int flags) | |||
| 1643 | goto out_flush_warn; | 1633 | goto out_flush_warn; |
| 1644 | mark_all_dquot_dirty(dquots); | 1634 | mark_all_dquot_dirty(dquots); |
| 1645 | out_flush_warn: | 1635 | out_flush_warn: |
| 1646 | up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1636 | srcu_read_unlock(&dquot_srcu, index); |
| 1647 | flush_warnings(warn); | 1637 | flush_warnings(warn); |
| 1648 | out: | 1638 | out: |
| 1649 | return ret; | 1639 | return ret; |
| @@ -1655,17 +1645,16 @@ EXPORT_SYMBOL(__dquot_alloc_space); | |||
| 1655 | */ | 1645 | */ |
| 1656 | int dquot_alloc_inode(const struct inode *inode) | 1646 | int dquot_alloc_inode(const struct inode *inode) |
| 1657 | { | 1647 | { |
| 1658 | int cnt, ret = 0; | 1648 | int cnt, ret = 0, index; |
| 1659 | struct dquot_warn warn[MAXQUOTAS]; | 1649 | struct dquot_warn warn[MAXQUOTAS]; |
| 1660 | struct dquot * const *dquots = inode->i_dquot; | 1650 | struct dquot * const *dquots = inode->i_dquot; |
| 1661 | 1651 | ||
| 1662 | /* First test before acquiring mutex - solves deadlocks when we | ||
| 1663 | * re-enter the quota code and are already holding the mutex */ | ||
| 1664 | if (!dquot_active(inode)) | 1652 | if (!dquot_active(inode)) |
| 1665 | return 0; | 1653 | return 0; |
| 1666 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) | 1654 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) |
| 1667 | warn[cnt].w_type = QUOTA_NL_NOWARN; | 1655 | warn[cnt].w_type = QUOTA_NL_NOWARN; |
| 1668 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1656 | |
| 1657 | index = srcu_read_lock(&dquot_srcu); | ||
| 1669 | spin_lock(&dq_data_lock); | 1658 | spin_lock(&dq_data_lock); |
| 1670 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1659 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
| 1671 | if (!dquots[cnt]) | 1660 | if (!dquots[cnt]) |
| @@ -1685,7 +1674,7 @@ warn_put_all: | |||
| 1685 | spin_unlock(&dq_data_lock); | 1674 | spin_unlock(&dq_data_lock); |
| 1686 | if (ret == 0) | 1675 | if (ret == 0) |
| 1687 | mark_all_dquot_dirty(dquots); | 1676 | mark_all_dquot_dirty(dquots); |
| 1688 | up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1677 | srcu_read_unlock(&dquot_srcu, index); |
| 1689 | flush_warnings(warn); | 1678 | flush_warnings(warn); |
| 1690 | return ret; | 1679 | return ret; |
| 1691 | } | 1680 | } |
| @@ -1696,14 +1685,14 @@ EXPORT_SYMBOL(dquot_alloc_inode); | |||
| 1696 | */ | 1685 | */ |
| 1697 | int dquot_claim_space_nodirty(struct inode *inode, qsize_t number) | 1686 | int dquot_claim_space_nodirty(struct inode *inode, qsize_t number) |
| 1698 | { | 1687 | { |
| 1699 | int cnt; | 1688 | int cnt, index; |
| 1700 | 1689 | ||
| 1701 | if (!dquot_active(inode)) { | 1690 | if (!dquot_active(inode)) { |
| 1702 | inode_claim_rsv_space(inode, number); | 1691 | inode_claim_rsv_space(inode, number); |
| 1703 | return 0; | 1692 | return 0; |
| 1704 | } | 1693 | } |
| 1705 | 1694 | ||
| 1706 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1695 | index = srcu_read_lock(&dquot_srcu); |
| 1707 | spin_lock(&dq_data_lock); | 1696 | spin_lock(&dq_data_lock); |
| 1708 | /* Claim reserved quotas to allocated quotas */ | 1697 | /* Claim reserved quotas to allocated quotas */ |
| 1709 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1698 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
| @@ -1715,7 +1704,7 @@ int dquot_claim_space_nodirty(struct inode *inode, qsize_t number) | |||
| 1715 | inode_claim_rsv_space(inode, number); | 1704 | inode_claim_rsv_space(inode, number); |
| 1716 | spin_unlock(&dq_data_lock); | 1705 | spin_unlock(&dq_data_lock); |
| 1717 | mark_all_dquot_dirty(inode->i_dquot); | 1706 | mark_all_dquot_dirty(inode->i_dquot); |
| 1718 | up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1707 | srcu_read_unlock(&dquot_srcu, index); |
| 1719 | return 0; | 1708 | return 0; |
| 1720 | } | 1709 | } |
| 1721 | EXPORT_SYMBOL(dquot_claim_space_nodirty); | 1710 | EXPORT_SYMBOL(dquot_claim_space_nodirty); |
| @@ -1725,14 +1714,14 @@ EXPORT_SYMBOL(dquot_claim_space_nodirty); | |||
| 1725 | */ | 1714 | */ |
| 1726 | void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number) | 1715 | void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number) |
| 1727 | { | 1716 | { |
| 1728 | int cnt; | 1717 | int cnt, index; |
| 1729 | 1718 | ||
| 1730 | if (!dquot_active(inode)) { | 1719 | if (!dquot_active(inode)) { |
| 1731 | inode_reclaim_rsv_space(inode, number); | 1720 | inode_reclaim_rsv_space(inode, number); |
| 1732 | return; | 1721 | return; |
| 1733 | } | 1722 | } |
| 1734 | 1723 | ||
| 1735 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1724 | index = srcu_read_lock(&dquot_srcu); |
| 1736 | spin_lock(&dq_data_lock); | 1725 | spin_lock(&dq_data_lock); |
| 1737 | /* Claim reserved quotas to allocated quotas */ | 1726 | /* Claim reserved quotas to allocated quotas */ |
| 1738 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1727 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
| @@ -1744,7 +1733,7 @@ void dquot_reclaim_space_nodirty(struct inode *inode, qsize_t number) | |||
| 1744 | inode_reclaim_rsv_space(inode, number); | 1733 | inode_reclaim_rsv_space(inode, number); |
| 1745 | spin_unlock(&dq_data_lock); | 1734 | spin_unlock(&dq_data_lock); |
| 1746 | mark_all_dquot_dirty(inode->i_dquot); | 1735 | mark_all_dquot_dirty(inode->i_dquot); |
| 1747 | up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1736 | srcu_read_unlock(&dquot_srcu, index); |
| 1748 | return; | 1737 | return; |
| 1749 | } | 1738 | } |
| 1750 | EXPORT_SYMBOL(dquot_reclaim_space_nodirty); | 1739 | EXPORT_SYMBOL(dquot_reclaim_space_nodirty); |
| @@ -1757,16 +1746,14 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags) | |||
| 1757 | unsigned int cnt; | 1746 | unsigned int cnt; |
| 1758 | struct dquot_warn warn[MAXQUOTAS]; | 1747 | struct dquot_warn warn[MAXQUOTAS]; |
| 1759 | struct dquot **dquots = inode->i_dquot; | 1748 | struct dquot **dquots = inode->i_dquot; |
| 1760 | int reserve = flags & DQUOT_SPACE_RESERVE; | 1749 | int reserve = flags & DQUOT_SPACE_RESERVE, index; |
| 1761 | 1750 | ||
| 1762 | /* First test before acquiring mutex - solves deadlocks when we | ||
| 1763 | * re-enter the quota code and are already holding the mutex */ | ||
| 1764 | if (!dquot_active(inode)) { | 1751 | if (!dquot_active(inode)) { |
| 1765 | inode_decr_space(inode, number, reserve); | 1752 | inode_decr_space(inode, number, reserve); |
| 1766 | return; | 1753 | return; |
| 1767 | } | 1754 | } |
| 1768 | 1755 | ||
| 1769 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1756 | index = srcu_read_lock(&dquot_srcu); |
| 1770 | spin_lock(&dq_data_lock); | 1757 | spin_lock(&dq_data_lock); |
| 1771 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1758 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
| 1772 | int wtype; | 1759 | int wtype; |
| @@ -1789,7 +1776,7 @@ void __dquot_free_space(struct inode *inode, qsize_t number, int flags) | |||
| 1789 | goto out_unlock; | 1776 | goto out_unlock; |
| 1790 | mark_all_dquot_dirty(dquots); | 1777 | mark_all_dquot_dirty(dquots); |
| 1791 | out_unlock: | 1778 | out_unlock: |
| 1792 | up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1779 | srcu_read_unlock(&dquot_srcu, index); |
| 1793 | flush_warnings(warn); | 1780 | flush_warnings(warn); |
| 1794 | } | 1781 | } |
| 1795 | EXPORT_SYMBOL(__dquot_free_space); | 1782 | EXPORT_SYMBOL(__dquot_free_space); |
| @@ -1802,13 +1789,12 @@ void dquot_free_inode(const struct inode *inode) | |||
| 1802 | unsigned int cnt; | 1789 | unsigned int cnt; |
| 1803 | struct dquot_warn warn[MAXQUOTAS]; | 1790 | struct dquot_warn warn[MAXQUOTAS]; |
| 1804 | struct dquot * const *dquots = inode->i_dquot; | 1791 | struct dquot * const *dquots = inode->i_dquot; |
| 1792 | int index; | ||
| 1805 | 1793 | ||
| 1806 | /* First test before acquiring mutex - solves deadlocks when we | ||
| 1807 | * re-enter the quota code and are already holding the mutex */ | ||
| 1808 | if (!dquot_active(inode)) | 1794 | if (!dquot_active(inode)) |
| 1809 | return; | 1795 | return; |
| 1810 | 1796 | ||
| 1811 | down_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1797 | index = srcu_read_lock(&dquot_srcu); |
| 1812 | spin_lock(&dq_data_lock); | 1798 | spin_lock(&dq_data_lock); |
| 1813 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { | 1799 | for (cnt = 0; cnt < MAXQUOTAS; cnt++) { |
| 1814 | int wtype; | 1800 | int wtype; |
| @@ -1823,7 +1809,7 @@ void dquot_free_inode(const struct inode *inode) | |||
| 1823 | } | 1809 | } |
| 1824 | spin_unlock(&dq_data_lock); | 1810 | spin_unlock(&dq_data_lock); |
| 1825 | mark_all_dquot_dirty(dquots); | 1811 | mark_all_dquot_dirty(dquots); |
| 1826 | up_read(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1812 | srcu_read_unlock(&dquot_srcu, index); |
| 1827 | flush_warnings(warn); | 1813 | flush_warnings(warn); |
| 1828 | } | 1814 | } |
| 1829 | EXPORT_SYMBOL(dquot_free_inode); | 1815 | EXPORT_SYMBOL(dquot_free_inode); |
| @@ -1837,6 +1823,8 @@ EXPORT_SYMBOL(dquot_free_inode); | |||
| 1837 | * This operation can block, but only after everything is updated | 1823 | * This operation can block, but only after everything is updated |
| 1838 | * A transaction must be started when entering this function. | 1824 | * A transaction must be started when entering this function. |
| 1839 | * | 1825 | * |
| 1826 | * We are holding reference on transfer_from & transfer_to, no need to | ||
| 1827 | * protect them by srcu_read_lock(). | ||
| 1840 | */ | 1828 | */ |
| 1841 | int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) | 1829 | int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) |
| 1842 | { | 1830 | { |
| @@ -1849,8 +1837,6 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) | |||
| 1849 | struct dquot_warn warn_from_inodes[MAXQUOTAS]; | 1837 | struct dquot_warn warn_from_inodes[MAXQUOTAS]; |
| 1850 | struct dquot_warn warn_from_space[MAXQUOTAS]; | 1838 | struct dquot_warn warn_from_space[MAXQUOTAS]; |
| 1851 | 1839 | ||
| 1852 | /* First test before acquiring mutex - solves deadlocks when we | ||
| 1853 | * re-enter the quota code and are already holding the mutex */ | ||
| 1854 | if (IS_NOQUOTA(inode)) | 1840 | if (IS_NOQUOTA(inode)) |
| 1855 | return 0; | 1841 | return 0; |
| 1856 | /* Initialize the arrays */ | 1842 | /* Initialize the arrays */ |
| @@ -1859,12 +1845,12 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) | |||
| 1859 | warn_from_inodes[cnt].w_type = QUOTA_NL_NOWARN; | 1845 | warn_from_inodes[cnt].w_type = QUOTA_NL_NOWARN; |
| 1860 | warn_from_space[cnt].w_type = QUOTA_NL_NOWARN; | 1846 | warn_from_space[cnt].w_type = QUOTA_NL_NOWARN; |
| 1861 | } | 1847 | } |
| 1862 | down_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1848 | |
| 1849 | spin_lock(&dq_data_lock); | ||
| 1863 | if (IS_NOQUOTA(inode)) { /* File without quota accounting? */ | 1850 | if (IS_NOQUOTA(inode)) { /* File without quota accounting? */ |
| 1864 | up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | 1851 | spin_unlock(&dq_data_lock); |
| 1865 | return 0; | 1852 | return 0; |
| 1866 | } | 1853 | } |
| 1867 | spin_lock(&dq_data_lock); | ||
| 1868 | cur_space = inode_get_bytes(inode); | 1854 | cur_space = inode_get_bytes(inode); |
| 1869 | rsv_space = inode_get_rsv_space(inode); | 1855 | rsv_space = inode_get_rsv_space(inode); |
| 1870 | space = cur_space + rsv_space; | 1856 | space = cur_space + rsv_space; |
| @@ -1918,7 +1904,6 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) | |||
| 1918 | inode->i_dquot[cnt] = transfer_to[cnt]; | 1904 | inode->i_dquot[cnt] = transfer_to[cnt]; |
| 1919 | } | 1905 | } |
| 1920 | spin_unlock(&dq_data_lock); | 1906 | spin_unlock(&dq_data_lock); |
| 1921 | up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | ||
| 1922 | 1907 | ||
| 1923 | mark_all_dquot_dirty(transfer_from); | 1908 | mark_all_dquot_dirty(transfer_from); |
| 1924 | mark_all_dquot_dirty(transfer_to); | 1909 | mark_all_dquot_dirty(transfer_to); |
| @@ -1932,7 +1917,6 @@ int __dquot_transfer(struct inode *inode, struct dquot **transfer_to) | |||
| 1932 | return 0; | 1917 | return 0; |
| 1933 | over_quota: | 1918 | over_quota: |
| 1934 | spin_unlock(&dq_data_lock); | 1919 | spin_unlock(&dq_data_lock); |
| 1935 | up_write(&sb_dqopt(inode->i_sb)->dqptr_sem); | ||
| 1936 | flush_warnings(warn_to); | 1920 | flush_warnings(warn_to); |
| 1937 | return ret; | 1921 | return ret; |
| 1938 | } | 1922 | } |
diff --git a/fs/super.c b/fs/super.c index d20d5b11dedf..872b26bf06dd 100644 --- a/fs/super.c +++ b/fs/super.c | |||
| @@ -218,7 +218,6 @@ static struct super_block *alloc_super(struct file_system_type *type, int flags) | |||
| 218 | lockdep_set_class(&s->s_vfs_rename_mutex, &type->s_vfs_rename_key); | 218 | lockdep_set_class(&s->s_vfs_rename_mutex, &type->s_vfs_rename_key); |
| 219 | mutex_init(&s->s_dquot.dqio_mutex); | 219 | mutex_init(&s->s_dquot.dqio_mutex); |
| 220 | mutex_init(&s->s_dquot.dqonoff_mutex); | 220 | mutex_init(&s->s_dquot.dqonoff_mutex); |
| 221 | init_rwsem(&s->s_dquot.dqptr_sem); | ||
| 222 | s->s_maxbytes = MAX_NON_LFS; | 221 | s->s_maxbytes = MAX_NON_LFS; |
| 223 | s->s_op = &default_op; | 222 | s->s_op = &default_op; |
| 224 | s->s_time_gran = 1000000000; | 223 | s->s_time_gran = 1000000000; |
diff --git a/include/linux/quota.h b/include/linux/quota.h index 0f3c5d38da1f..80d345a3524c 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h | |||
| @@ -390,7 +390,6 @@ struct quota_info { | |||
| 390 | unsigned int flags; /* Flags for diskquotas on this device */ | 390 | unsigned int flags; /* Flags for diskquotas on this device */ |
| 391 | struct mutex dqio_mutex; /* lock device while I/O in progress */ | 391 | struct mutex dqio_mutex; /* lock device while I/O in progress */ |
| 392 | struct mutex dqonoff_mutex; /* Serialize quotaon & quotaoff */ | 392 | struct mutex dqonoff_mutex; /* Serialize quotaon & quotaoff */ |
| 393 | struct rw_semaphore dqptr_sem; /* serialize ops using quota_info struct, pointers from inode to dquots */ | ||
| 394 | struct inode *files[MAXQUOTAS]; /* inodes of quotafiles */ | 393 | struct inode *files[MAXQUOTAS]; /* inodes of quotafiles */ |
| 395 | struct mem_dqinfo info[MAXQUOTAS]; /* Information for each quota type */ | 394 | struct mem_dqinfo info[MAXQUOTAS]; /* Information for each quota type */ |
| 396 | const struct quota_format_ops *ops[MAXQUOTAS]; /* Operations for each type */ | 395 | const struct quota_format_ops *ops[MAXQUOTAS]; /* Operations for each type */ |
