diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-09 14:19:09 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-09-09 14:19:09 -0400 |
commit | 300893b08f3bc7057a7a5f84074090ba66c8b5ca (patch) | |
tree | 5fc5aef0b9dbab8e47e161303d57e631786c7d17 /fs/xfs/xfs_qm.c | |
parent | 45150c43b1b0c16e665fd0a5cdcca128b8192db1 (diff) | |
parent | 1d03c6fa88af35e55047a1f2ab116f0fdf2f55aa (diff) |
Merge tag 'xfs-for-linus-v3.12-rc1' of git://oss.sgi.com/xfs/xfs
Pull xfs updates from Ben Myers:
"For 3.12-rc1 there are a number of bugfixes in addition to work to
ease usage of shared code between libxfs and the kernel, the rest of
the work to enable project and group quotas to be used simultaneously,
performance optimisations in the log and the CIL, directory entry file
type support, fixes for log space reservations, some spelling/grammar
cleanups, and the addition of user namespace support.
- introduce readahead to log recovery
- add directory entry file type support
- fix a number of spelling errors in comments
- introduce new Q_XGETQSTATV quotactl for project quotas
- add USER_NS support
- log space reservation rework
- CIL optimisations
- kernel/userspace libxfs rework"
* tag 'xfs-for-linus-v3.12-rc1' of git://oss.sgi.com/xfs/xfs: (112 commits)
xfs: XFS_MOUNT_QUOTA_ALL needed by userspace
xfs: dtype changed xfs_dir2_sfe_put_ino to xfs_dir3_sfe_put_ino
Fix wrong flag ASSERT in xfs_attr_shortform_getvalue
xfs: finish removing IOP_* macros.
xfs: inode log reservations are too small
xfs: check correct status variable for xfs_inobt_get_rec() call
xfs: inode buffers may not be valid during recovery readahead
xfs: check LSN ordering for v5 superblocks during recovery
xfs: btree block LSN escaping to disk uninitialised
XFS: Assertion failed: first <= last && last < BBTOB(bp->b_length), file: fs/xfs/xfs_trans_buf.c, line: 568
xfs: fix bad dquot buffer size in log recovery readahead
xfs: don't account buffer cancellation during log recovery readahead
xfs: check for underflow in xfs_iformat_fork()
xfs: xfs_dir3_sfe_put_ino can be static
xfs: introduce object readahead to log recovery
xfs: Simplify xfs_ail_min() with list_first_entry_or_null()
xfs: Register hotcpu notifier after initialization
xfs: add xfs sb v4 support for dirent filetype field
xfs: Add write support for dirent filetype field
xfs: Add read-only support for dirent filetype field
...
Diffstat (limited to 'fs/xfs/xfs_qm.c')
-rw-r--r-- | fs/xfs/xfs_qm.c | 95 |
1 files changed, 64 insertions, 31 deletions
diff --git a/fs/xfs/xfs_qm.c b/fs/xfs/xfs_qm.c index d320794d03ce..6218a0aeeeea 100644 --- a/fs/xfs/xfs_qm.c +++ b/fs/xfs/xfs_qm.c | |||
@@ -17,6 +17,7 @@ | |||
17 | */ | 17 | */ |
18 | #include "xfs.h" | 18 | #include "xfs.h" |
19 | #include "xfs_fs.h" | 19 | #include "xfs_fs.h" |
20 | #include "xfs_format.h" | ||
20 | #include "xfs_bit.h" | 21 | #include "xfs_bit.h" |
21 | #include "xfs_log.h" | 22 | #include "xfs_log.h" |
22 | #include "xfs_trans.h" | 23 | #include "xfs_trans.h" |
@@ -37,7 +38,6 @@ | |||
37 | #include "xfs_attr.h" | 38 | #include "xfs_attr.h" |
38 | #include "xfs_buf_item.h" | 39 | #include "xfs_buf_item.h" |
39 | #include "xfs_trans_space.h" | 40 | #include "xfs_trans_space.h" |
40 | #include "xfs_utils.h" | ||
41 | #include "xfs_qm.h" | 41 | #include "xfs_qm.h" |
42 | #include "xfs_trace.h" | 42 | #include "xfs_trace.h" |
43 | #include "xfs_icache.h" | 43 | #include "xfs_icache.h" |
@@ -834,21 +834,52 @@ xfs_qm_qino_alloc( | |||
834 | int error; | 834 | int error; |
835 | int committed; | 835 | int committed; |
836 | 836 | ||
837 | *ip = NULL; | ||
838 | /* | ||
839 | * With superblock that doesn't have separate pquotino, we | ||
840 | * share an inode between gquota and pquota. If the on-disk | ||
841 | * superblock has GQUOTA and the filesystem is now mounted | ||
842 | * with PQUOTA, just use sb_gquotino for sb_pquotino and | ||
843 | * vice-versa. | ||
844 | */ | ||
845 | if (!xfs_sb_version_has_pquotino(&mp->m_sb) && | ||
846 | (flags & (XFS_QMOPT_PQUOTA|XFS_QMOPT_GQUOTA))) { | ||
847 | xfs_ino_t ino = NULLFSINO; | ||
848 | |||
849 | if ((flags & XFS_QMOPT_PQUOTA) && | ||
850 | (mp->m_sb.sb_gquotino != NULLFSINO)) { | ||
851 | ino = mp->m_sb.sb_gquotino; | ||
852 | ASSERT(mp->m_sb.sb_pquotino == NULLFSINO); | ||
853 | } else if ((flags & XFS_QMOPT_GQUOTA) && | ||
854 | (mp->m_sb.sb_pquotino != NULLFSINO)) { | ||
855 | ino = mp->m_sb.sb_pquotino; | ||
856 | ASSERT(mp->m_sb.sb_gquotino == NULLFSINO); | ||
857 | } | ||
858 | if (ino != NULLFSINO) { | ||
859 | error = xfs_iget(mp, NULL, ino, 0, 0, ip); | ||
860 | if (error) | ||
861 | return error; | ||
862 | mp->m_sb.sb_gquotino = NULLFSINO; | ||
863 | mp->m_sb.sb_pquotino = NULLFSINO; | ||
864 | } | ||
865 | } | ||
866 | |||
837 | tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QINOCREATE); | 867 | tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QINOCREATE); |
838 | if ((error = xfs_trans_reserve(tp, | 868 | error = xfs_trans_reserve(tp, &M_RES(mp)->tr_create, |
839 | XFS_QM_QINOCREATE_SPACE_RES(mp), | 869 | XFS_QM_QINOCREATE_SPACE_RES(mp), 0); |
840 | XFS_CREATE_LOG_RES(mp), 0, | 870 | if (error) { |
841 | XFS_TRANS_PERM_LOG_RES, | ||
842 | XFS_CREATE_LOG_COUNT))) { | ||
843 | xfs_trans_cancel(tp, 0); | 871 | xfs_trans_cancel(tp, 0); |
844 | return error; | 872 | return error; |
845 | } | 873 | } |
846 | 874 | ||
847 | error = xfs_dir_ialloc(&tp, NULL, S_IFREG, 1, 0, 0, 1, ip, &committed); | 875 | if (!*ip) { |
848 | if (error) { | 876 | error = xfs_dir_ialloc(&tp, NULL, S_IFREG, 1, 0, 0, 1, ip, |
849 | xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | | 877 | &committed); |
850 | XFS_TRANS_ABORT); | 878 | if (error) { |
851 | return error; | 879 | xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | |
880 | XFS_TRANS_ABORT); | ||
881 | return error; | ||
882 | } | ||
852 | } | 883 | } |
853 | 884 | ||
854 | /* | 885 | /* |
@@ -860,21 +891,25 @@ xfs_qm_qino_alloc( | |||
860 | if (flags & XFS_QMOPT_SBVERSION) { | 891 | if (flags & XFS_QMOPT_SBVERSION) { |
861 | ASSERT(!xfs_sb_version_hasquota(&mp->m_sb)); | 892 | ASSERT(!xfs_sb_version_hasquota(&mp->m_sb)); |
862 | ASSERT((sbfields & (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | | 893 | ASSERT((sbfields & (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | |
863 | XFS_SB_GQUOTINO | XFS_SB_QFLAGS)) == | 894 | XFS_SB_GQUOTINO | XFS_SB_PQUOTINO | XFS_SB_QFLAGS)) == |
864 | (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | | 895 | (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | |
865 | XFS_SB_GQUOTINO | XFS_SB_QFLAGS)); | 896 | XFS_SB_GQUOTINO | XFS_SB_PQUOTINO | |
897 | XFS_SB_QFLAGS)); | ||
866 | 898 | ||
867 | xfs_sb_version_addquota(&mp->m_sb); | 899 | xfs_sb_version_addquota(&mp->m_sb); |
868 | mp->m_sb.sb_uquotino = NULLFSINO; | 900 | mp->m_sb.sb_uquotino = NULLFSINO; |
869 | mp->m_sb.sb_gquotino = NULLFSINO; | 901 | mp->m_sb.sb_gquotino = NULLFSINO; |
902 | mp->m_sb.sb_pquotino = NULLFSINO; | ||
870 | 903 | ||
871 | /* qflags will get updated _after_ quotacheck */ | 904 | /* qflags will get updated fully _after_ quotacheck */ |
872 | mp->m_sb.sb_qflags = 0; | 905 | mp->m_sb.sb_qflags = mp->m_qflags & XFS_ALL_QUOTA_ACCT; |
873 | } | 906 | } |
874 | if (flags & XFS_QMOPT_UQUOTA) | 907 | if (flags & XFS_QMOPT_UQUOTA) |
875 | mp->m_sb.sb_uquotino = (*ip)->i_ino; | 908 | mp->m_sb.sb_uquotino = (*ip)->i_ino; |
876 | else | 909 | else if (flags & XFS_QMOPT_GQUOTA) |
877 | mp->m_sb.sb_gquotino = (*ip)->i_ino; | 910 | mp->m_sb.sb_gquotino = (*ip)->i_ino; |
911 | else | ||
912 | mp->m_sb.sb_pquotino = (*ip)->i_ino; | ||
878 | spin_unlock(&mp->m_sb_lock); | 913 | spin_unlock(&mp->m_sb_lock); |
879 | xfs_mod_sb(tp, sbfields); | 914 | xfs_mod_sb(tp, sbfields); |
880 | 915 | ||
@@ -1484,11 +1519,10 @@ xfs_qm_init_quotainos( | |||
1484 | if (error) | 1519 | if (error) |
1485 | goto error_rele; | 1520 | goto error_rele; |
1486 | } | 1521 | } |
1487 | /* XXX: Use gquotino for now */ | ||
1488 | if (XFS_IS_PQUOTA_ON(mp) && | 1522 | if (XFS_IS_PQUOTA_ON(mp) && |
1489 | mp->m_sb.sb_gquotino != NULLFSINO) { | 1523 | mp->m_sb.sb_pquotino != NULLFSINO) { |
1490 | ASSERT(mp->m_sb.sb_gquotino > 0); | 1524 | ASSERT(mp->m_sb.sb_pquotino > 0); |
1491 | error = xfs_iget(mp, NULL, mp->m_sb.sb_gquotino, | 1525 | error = xfs_iget(mp, NULL, mp->m_sb.sb_pquotino, |
1492 | 0, 0, &pip); | 1526 | 0, 0, &pip); |
1493 | if (error) | 1527 | if (error) |
1494 | goto error_rele; | 1528 | goto error_rele; |
@@ -1496,7 +1530,8 @@ xfs_qm_init_quotainos( | |||
1496 | } else { | 1530 | } else { |
1497 | flags |= XFS_QMOPT_SBVERSION; | 1531 | flags |= XFS_QMOPT_SBVERSION; |
1498 | sbflags |= (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | | 1532 | sbflags |= (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | |
1499 | XFS_SB_GQUOTINO | XFS_SB_QFLAGS); | 1533 | XFS_SB_GQUOTINO | XFS_SB_PQUOTINO | |
1534 | XFS_SB_QFLAGS); | ||
1500 | } | 1535 | } |
1501 | 1536 | ||
1502 | /* | 1537 | /* |
@@ -1524,9 +1559,8 @@ xfs_qm_init_quotainos( | |||
1524 | flags &= ~XFS_QMOPT_SBVERSION; | 1559 | flags &= ~XFS_QMOPT_SBVERSION; |
1525 | } | 1560 | } |
1526 | if (XFS_IS_PQUOTA_ON(mp) && pip == NULL) { | 1561 | if (XFS_IS_PQUOTA_ON(mp) && pip == NULL) { |
1527 | /* XXX: Use XFS_SB_GQUOTINO for now */ | ||
1528 | error = xfs_qm_qino_alloc(mp, &pip, | 1562 | error = xfs_qm_qino_alloc(mp, &pip, |
1529 | sbflags | XFS_SB_GQUOTINO, | 1563 | sbflags | XFS_SB_PQUOTINO, |
1530 | flags | XFS_QMOPT_PQUOTA); | 1564 | flags | XFS_QMOPT_PQUOTA); |
1531 | if (error) | 1565 | if (error) |
1532 | goto error_rele; | 1566 | goto error_rele; |
@@ -1704,8 +1738,7 @@ xfs_qm_write_sb_changes( | |||
1704 | int error; | 1738 | int error; |
1705 | 1739 | ||
1706 | tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SBCHANGE); | 1740 | tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SBCHANGE); |
1707 | error = xfs_trans_reserve(tp, 0, XFS_QM_SBCHANGE_LOG_RES(mp), | 1741 | error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_sbchange, 0, 0); |
1708 | 0, 0, XFS_DEFAULT_LOG_COUNT); | ||
1709 | if (error) { | 1742 | if (error) { |
1710 | xfs_trans_cancel(tp, 0); | 1743 | xfs_trans_cancel(tp, 0); |
1711 | return error; | 1744 | return error; |
@@ -1734,8 +1767,8 @@ xfs_qm_write_sb_changes( | |||
1734 | int | 1767 | int |
1735 | xfs_qm_vop_dqalloc( | 1768 | xfs_qm_vop_dqalloc( |
1736 | struct xfs_inode *ip, | 1769 | struct xfs_inode *ip, |
1737 | uid_t uid, | 1770 | xfs_dqid_t uid, |
1738 | gid_t gid, | 1771 | xfs_dqid_t gid, |
1739 | prid_t prid, | 1772 | prid_t prid, |
1740 | uint flags, | 1773 | uint flags, |
1741 | struct xfs_dquot **O_udqpp, | 1774 | struct xfs_dquot **O_udqpp, |
@@ -1782,7 +1815,7 @@ xfs_qm_vop_dqalloc( | |||
1782 | * holding ilock. | 1815 | * holding ilock. |
1783 | */ | 1816 | */ |
1784 | xfs_iunlock(ip, lockflags); | 1817 | xfs_iunlock(ip, lockflags); |
1785 | error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t) uid, | 1818 | error = xfs_qm_dqget(mp, NULL, uid, |
1786 | XFS_DQ_USER, | 1819 | XFS_DQ_USER, |
1787 | XFS_QMOPT_DQALLOC | | 1820 | XFS_QMOPT_DQALLOC | |
1788 | XFS_QMOPT_DOWARN, | 1821 | XFS_QMOPT_DOWARN, |
@@ -1809,7 +1842,7 @@ xfs_qm_vop_dqalloc( | |||
1809 | if ((flags & XFS_QMOPT_GQUOTA) && XFS_IS_GQUOTA_ON(mp)) { | 1842 | if ((flags & XFS_QMOPT_GQUOTA) && XFS_IS_GQUOTA_ON(mp)) { |
1810 | if (ip->i_d.di_gid != gid) { | 1843 | if (ip->i_d.di_gid != gid) { |
1811 | xfs_iunlock(ip, lockflags); | 1844 | xfs_iunlock(ip, lockflags); |
1812 | error = xfs_qm_dqget(mp, NULL, (xfs_dqid_t)gid, | 1845 | error = xfs_qm_dqget(mp, NULL, gid, |
1813 | XFS_DQ_GROUP, | 1846 | XFS_DQ_GROUP, |
1814 | XFS_QMOPT_DQALLOC | | 1847 | XFS_QMOPT_DQALLOC | |
1815 | XFS_QMOPT_DOWARN, | 1848 | XFS_QMOPT_DOWARN, |
@@ -1943,7 +1976,7 @@ xfs_qm_vop_chown_reserve( | |||
1943 | XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS; | 1976 | XFS_QMOPT_RES_RTBLKS : XFS_QMOPT_RES_REGBLKS; |
1944 | 1977 | ||
1945 | if (XFS_IS_UQUOTA_ON(mp) && udqp && | 1978 | if (XFS_IS_UQUOTA_ON(mp) && udqp && |
1946 | ip->i_d.di_uid != (uid_t)be32_to_cpu(udqp->q_core.d_id)) { | 1979 | ip->i_d.di_uid != be32_to_cpu(udqp->q_core.d_id)) { |
1947 | udq_delblks = udqp; | 1980 | udq_delblks = udqp; |
1948 | /* | 1981 | /* |
1949 | * If there are delayed allocation blocks, then we have to | 1982 | * If there are delayed allocation blocks, then we have to |