diff options
Diffstat (limited to 'fs/xfs/quota/xfs_qm.c')
-rw-r--r-- | fs/xfs/quota/xfs_qm.c | 80 |
1 files changed, 52 insertions, 28 deletions
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c index 45b1bfef7388..417e61e3d9dd 100644 --- a/fs/xfs/quota/xfs_qm.c +++ b/fs/xfs/quota/xfs_qm.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include "xfs_trans_space.h" | 47 | #include "xfs_trans_space.h" |
48 | #include "xfs_utils.h" | 48 | #include "xfs_utils.h" |
49 | #include "xfs_qm.h" | 49 | #include "xfs_qm.h" |
50 | #include "xfs_trace.h" | ||
50 | 51 | ||
51 | /* | 52 | /* |
52 | * The global quota manager. There is only one of these for the entire | 53 | * The global quota manager. There is only one of these for the entire |
@@ -117,9 +118,14 @@ xfs_Gqm_init(void) | |||
117 | */ | 118 | */ |
118 | udqhash = kmem_zalloc_greedy(&hsize, | 119 | udqhash = kmem_zalloc_greedy(&hsize, |
119 | XFS_QM_HASHSIZE_LOW * sizeof(xfs_dqhash_t), | 120 | XFS_QM_HASHSIZE_LOW * sizeof(xfs_dqhash_t), |
120 | XFS_QM_HASHSIZE_HIGH * sizeof(xfs_dqhash_t), | 121 | XFS_QM_HASHSIZE_HIGH * sizeof(xfs_dqhash_t)); |
121 | KM_SLEEP | KM_MAYFAIL | KM_LARGE); | 122 | if (!udqhash) |
122 | gdqhash = kmem_zalloc(hsize, KM_SLEEP | KM_LARGE); | 123 | goto out; |
124 | |||
125 | gdqhash = kmem_zalloc_large(hsize); | ||
126 | if (!gdqhash) | ||
127 | goto out_free_udqhash; | ||
128 | |||
123 | hsize /= sizeof(xfs_dqhash_t); | 129 | hsize /= sizeof(xfs_dqhash_t); |
124 | ndquot = hsize << 8; | 130 | ndquot = hsize << 8; |
125 | 131 | ||
@@ -169,6 +175,11 @@ xfs_Gqm_init(void) | |||
169 | mutex_init(&qcheck_lock); | 175 | mutex_init(&qcheck_lock); |
170 | #endif | 176 | #endif |
171 | return xqm; | 177 | return xqm; |
178 | |||
179 | out_free_udqhash: | ||
180 | kmem_free_large(udqhash); | ||
181 | out: | ||
182 | return NULL; | ||
172 | } | 183 | } |
173 | 184 | ||
174 | /* | 185 | /* |
@@ -188,8 +199,8 @@ xfs_qm_destroy( | |||
188 | xfs_qm_list_destroy(&(xqm->qm_usr_dqhtable[i])); | 199 | xfs_qm_list_destroy(&(xqm->qm_usr_dqhtable[i])); |
189 | xfs_qm_list_destroy(&(xqm->qm_grp_dqhtable[i])); | 200 | xfs_qm_list_destroy(&(xqm->qm_grp_dqhtable[i])); |
190 | } | 201 | } |
191 | kmem_free(xqm->qm_usr_dqhtable); | 202 | kmem_free_large(xqm->qm_usr_dqhtable); |
192 | kmem_free(xqm->qm_grp_dqhtable); | 203 | kmem_free_large(xqm->qm_grp_dqhtable); |
193 | xqm->qm_usr_dqhtable = NULL; | 204 | xqm->qm_usr_dqhtable = NULL; |
194 | xqm->qm_grp_dqhtable = NULL; | 205 | xqm->qm_grp_dqhtable = NULL; |
195 | xqm->qm_dqhashmask = 0; | 206 | xqm->qm_dqhashmask = 0; |
@@ -218,8 +229,12 @@ xfs_qm_hold_quotafs_ref( | |||
218 | */ | 229 | */ |
219 | mutex_lock(&xfs_Gqm_lock); | 230 | mutex_lock(&xfs_Gqm_lock); |
220 | 231 | ||
221 | if (xfs_Gqm == NULL) | 232 | if (!xfs_Gqm) { |
222 | xfs_Gqm = xfs_Gqm_init(); | 233 | xfs_Gqm = xfs_Gqm_init(); |
234 | if (!xfs_Gqm) | ||
235 | return ENOMEM; | ||
236 | } | ||
237 | |||
223 | /* | 238 | /* |
224 | * We can keep a list of all filesystems with quotas mounted for | 239 | * We can keep a list of all filesystems with quotas mounted for |
225 | * debugging and statistical purposes, but ... | 240 | * debugging and statistical purposes, but ... |
@@ -435,7 +450,7 @@ xfs_qm_unmount_quotas( | |||
435 | STATIC int | 450 | STATIC int |
436 | xfs_qm_dqflush_all( | 451 | xfs_qm_dqflush_all( |
437 | xfs_mount_t *mp, | 452 | xfs_mount_t *mp, |
438 | int flags) | 453 | int sync_mode) |
439 | { | 454 | { |
440 | int recl; | 455 | int recl; |
441 | xfs_dquot_t *dqp; | 456 | xfs_dquot_t *dqp; |
@@ -453,7 +468,7 @@ again: | |||
453 | xfs_dqunlock(dqp); | 468 | xfs_dqunlock(dqp); |
454 | continue; | 469 | continue; |
455 | } | 470 | } |
456 | xfs_dqtrace_entry(dqp, "FLUSHALL: DQDIRTY"); | 471 | |
457 | /* XXX a sentinel would be better */ | 472 | /* XXX a sentinel would be better */ |
458 | recl = XFS_QI_MPLRECLAIMS(mp); | 473 | recl = XFS_QI_MPLRECLAIMS(mp); |
459 | if (!xfs_dqflock_nowait(dqp)) { | 474 | if (!xfs_dqflock_nowait(dqp)) { |
@@ -471,7 +486,7 @@ again: | |||
471 | * across a disk write. | 486 | * across a disk write. |
472 | */ | 487 | */ |
473 | xfs_qm_mplist_unlock(mp); | 488 | xfs_qm_mplist_unlock(mp); |
474 | error = xfs_qm_dqflush(dqp, flags); | 489 | error = xfs_qm_dqflush(dqp, sync_mode); |
475 | xfs_dqunlock(dqp); | 490 | xfs_dqunlock(dqp); |
476 | if (error) | 491 | if (error) |
477 | return error; | 492 | return error; |
@@ -651,7 +666,7 @@ xfs_qm_dqattach_one( | |||
651 | */ | 666 | */ |
652 | dqp = *IO_idqpp; | 667 | dqp = *IO_idqpp; |
653 | if (dqp) { | 668 | if (dqp) { |
654 | xfs_dqtrace_entry(dqp, "DQATTACH: found in ip"); | 669 | trace_xfs_dqattach_found(dqp); |
655 | return 0; | 670 | return 0; |
656 | } | 671 | } |
657 | 672 | ||
@@ -704,7 +719,7 @@ xfs_qm_dqattach_one( | |||
704 | if (error) | 719 | if (error) |
705 | return error; | 720 | return error; |
706 | 721 | ||
707 | xfs_dqtrace_entry(dqp, "DQATTACH: found by dqget"); | 722 | trace_xfs_dqattach_get(dqp); |
708 | 723 | ||
709 | /* | 724 | /* |
710 | * dqget may have dropped and re-acquired the ilock, but it guarantees | 725 | * dqget may have dropped and re-acquired the ilock, but it guarantees |
@@ -890,15 +905,15 @@ xfs_qm_dqdetach( | |||
890 | if (!(ip->i_udquot || ip->i_gdquot)) | 905 | if (!(ip->i_udquot || ip->i_gdquot)) |
891 | return; | 906 | return; |
892 | 907 | ||
908 | trace_xfs_dquot_dqdetach(ip); | ||
909 | |||
893 | ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_uquotino); | 910 | ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_uquotino); |
894 | ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_gquotino); | 911 | ASSERT(ip->i_ino != ip->i_mount->m_sb.sb_gquotino); |
895 | if (ip->i_udquot) { | 912 | if (ip->i_udquot) { |
896 | xfs_dqtrace_entry_ino(ip->i_udquot, "DQDETTACH", ip); | ||
897 | xfs_qm_dqrele(ip->i_udquot); | 913 | xfs_qm_dqrele(ip->i_udquot); |
898 | ip->i_udquot = NULL; | 914 | ip->i_udquot = NULL; |
899 | } | 915 | } |
900 | if (ip->i_gdquot) { | 916 | if (ip->i_gdquot) { |
901 | xfs_dqtrace_entry_ino(ip->i_gdquot, "DQDETTACH", ip); | ||
902 | xfs_qm_dqrele(ip->i_gdquot); | 917 | xfs_qm_dqrele(ip->i_gdquot); |
903 | ip->i_gdquot = NULL; | 918 | ip->i_gdquot = NULL; |
904 | } | 919 | } |
@@ -911,13 +926,11 @@ xfs_qm_sync( | |||
911 | { | 926 | { |
912 | int recl, restarts; | 927 | int recl, restarts; |
913 | xfs_dquot_t *dqp; | 928 | xfs_dquot_t *dqp; |
914 | uint flush_flags; | ||
915 | int error; | 929 | int error; |
916 | 930 | ||
917 | if (!XFS_IS_QUOTA_RUNNING(mp) || !XFS_IS_QUOTA_ON(mp)) | 931 | if (!XFS_IS_QUOTA_RUNNING(mp) || !XFS_IS_QUOTA_ON(mp)) |
918 | return 0; | 932 | return 0; |
919 | 933 | ||
920 | flush_flags = (flags & SYNC_WAIT) ? XFS_QMOPT_SYNC : XFS_QMOPT_DELWRI; | ||
921 | restarts = 0; | 934 | restarts = 0; |
922 | 935 | ||
923 | again: | 936 | again: |
@@ -977,8 +990,7 @@ xfs_qm_sync( | |||
977 | * across a disk write | 990 | * across a disk write |
978 | */ | 991 | */ |
979 | xfs_qm_mplist_unlock(mp); | 992 | xfs_qm_mplist_unlock(mp); |
980 | xfs_dqtrace_entry(dqp, "XQM_SYNC: DQFLUSH"); | 993 | error = xfs_qm_dqflush(dqp, flags); |
981 | error = xfs_qm_dqflush(dqp, flush_flags); | ||
982 | xfs_dqunlock(dqp); | 994 | xfs_dqunlock(dqp); |
983 | if (error && XFS_FORCED_SHUTDOWN(mp)) | 995 | if (error && XFS_FORCED_SHUTDOWN(mp)) |
984 | return 0; /* Need to prevent umount failure */ | 996 | return 0; /* Need to prevent umount failure */ |
@@ -1350,7 +1362,8 @@ xfs_qm_reset_dqcounts( | |||
1350 | xfs_disk_dquot_t *ddq; | 1362 | xfs_disk_dquot_t *ddq; |
1351 | int j; | 1363 | int j; |
1352 | 1364 | ||
1353 | xfs_buftrace("RESET DQUOTS", bp); | 1365 | trace_xfs_reset_dqcounts(bp, _RET_IP_); |
1366 | |||
1354 | /* | 1367 | /* |
1355 | * Reset all counters and timers. They'll be | 1368 | * Reset all counters and timers. They'll be |
1356 | * started afresh by xfs_qm_quotacheck. | 1369 | * started afresh by xfs_qm_quotacheck. |
@@ -1543,7 +1556,9 @@ xfs_qm_quotacheck_dqadjust( | |||
1543 | xfs_qcnt_t rtblks) | 1556 | xfs_qcnt_t rtblks) |
1544 | { | 1557 | { |
1545 | ASSERT(XFS_DQ_IS_LOCKED(dqp)); | 1558 | ASSERT(XFS_DQ_IS_LOCKED(dqp)); |
1546 | xfs_dqtrace_entry(dqp, "QCHECK DQADJUST"); | 1559 | |
1560 | trace_xfs_dqadjust(dqp); | ||
1561 | |||
1547 | /* | 1562 | /* |
1548 | * Adjust the inode count and the block count to reflect this inode's | 1563 | * Adjust the inode count and the block count to reflect this inode's |
1549 | * resource usage. | 1564 | * resource usage. |
@@ -1779,7 +1794,7 @@ xfs_qm_quotacheck( | |||
1779 | * successfully. | 1794 | * successfully. |
1780 | */ | 1795 | */ |
1781 | if (!error) | 1796 | if (!error) |
1782 | error = xfs_qm_dqflush_all(mp, XFS_QMOPT_DELWRI); | 1797 | error = xfs_qm_dqflush_all(mp, 0); |
1783 | 1798 | ||
1784 | /* | 1799 | /* |
1785 | * We can get this error if we couldn't do a dquot allocation inside | 1800 | * We can get this error if we couldn't do a dquot allocation inside |
@@ -1994,12 +2009,14 @@ xfs_qm_shake_freelist( | |||
1994 | */ | 2009 | */ |
1995 | if (XFS_DQ_IS_DIRTY(dqp)) { | 2010 | if (XFS_DQ_IS_DIRTY(dqp)) { |
1996 | int error; | 2011 | int error; |
1997 | xfs_dqtrace_entry(dqp, "DQSHAKE: DQDIRTY"); | 2012 | |
2013 | trace_xfs_dqshake_dirty(dqp); | ||
2014 | |||
1998 | /* | 2015 | /* |
1999 | * We flush it delayed write, so don't bother | 2016 | * We flush it delayed write, so don't bother |
2000 | * releasing the mplock. | 2017 | * releasing the mplock. |
2001 | */ | 2018 | */ |
2002 | error = xfs_qm_dqflush(dqp, XFS_QMOPT_DELWRI); | 2019 | error = xfs_qm_dqflush(dqp, 0); |
2003 | if (error) { | 2020 | if (error) { |
2004 | xfs_fs_cmn_err(CE_WARN, dqp->q_mount, | 2021 | xfs_fs_cmn_err(CE_WARN, dqp->q_mount, |
2005 | "xfs_qm_dqflush_all: dquot %p flush failed", dqp); | 2022 | "xfs_qm_dqflush_all: dquot %p flush failed", dqp); |
@@ -2038,7 +2055,9 @@ xfs_qm_shake_freelist( | |||
2038 | return nreclaimed; | 2055 | return nreclaimed; |
2039 | goto tryagain; | 2056 | goto tryagain; |
2040 | } | 2057 | } |
2041 | xfs_dqtrace_entry(dqp, "DQSHAKE: UNLINKING"); | 2058 | |
2059 | trace_xfs_dqshake_unlink(dqp); | ||
2060 | |||
2042 | #ifdef QUOTADEBUG | 2061 | #ifdef QUOTADEBUG |
2043 | cmn_err(CE_DEBUG, "Shake 0x%p, ID 0x%x\n", | 2062 | cmn_err(CE_DEBUG, "Shake 0x%p, ID 0x%x\n", |
2044 | dqp, be32_to_cpu(dqp->q_core.d_id)); | 2063 | dqp, be32_to_cpu(dqp->q_core.d_id)); |
@@ -2125,7 +2144,9 @@ xfs_qm_dqreclaim_one(void) | |||
2125 | */ | 2144 | */ |
2126 | if (dqp->dq_flags & XFS_DQ_WANT) { | 2145 | if (dqp->dq_flags & XFS_DQ_WANT) { |
2127 | ASSERT(! (dqp->dq_flags & XFS_DQ_INACTIVE)); | 2146 | ASSERT(! (dqp->dq_flags & XFS_DQ_INACTIVE)); |
2128 | xfs_dqtrace_entry(dqp, "DQRECLAIM: DQWANT"); | 2147 | |
2148 | trace_xfs_dqreclaim_want(dqp); | ||
2149 | |||
2129 | xfs_dqunlock(dqp); | 2150 | xfs_dqunlock(dqp); |
2130 | xfs_qm_freelist_unlock(xfs_Gqm); | 2151 | xfs_qm_freelist_unlock(xfs_Gqm); |
2131 | if (++restarts >= XFS_QM_RECLAIM_MAX_RESTARTS) | 2152 | if (++restarts >= XFS_QM_RECLAIM_MAX_RESTARTS) |
@@ -2171,12 +2192,14 @@ xfs_qm_dqreclaim_one(void) | |||
2171 | */ | 2192 | */ |
2172 | if (XFS_DQ_IS_DIRTY(dqp)) { | 2193 | if (XFS_DQ_IS_DIRTY(dqp)) { |
2173 | int error; | 2194 | int error; |
2174 | xfs_dqtrace_entry(dqp, "DQRECLAIM: DQDIRTY"); | 2195 | |
2196 | trace_xfs_dqreclaim_dirty(dqp); | ||
2197 | |||
2175 | /* | 2198 | /* |
2176 | * We flush it delayed write, so don't bother | 2199 | * We flush it delayed write, so don't bother |
2177 | * releasing the freelist lock. | 2200 | * releasing the freelist lock. |
2178 | */ | 2201 | */ |
2179 | error = xfs_qm_dqflush(dqp, XFS_QMOPT_DELWRI); | 2202 | error = xfs_qm_dqflush(dqp, 0); |
2180 | if (error) { | 2203 | if (error) { |
2181 | xfs_fs_cmn_err(CE_WARN, dqp->q_mount, | 2204 | xfs_fs_cmn_err(CE_WARN, dqp->q_mount, |
2182 | "xfs_qm_dqreclaim: dquot %p flush failed", dqp); | 2205 | "xfs_qm_dqreclaim: dquot %p flush failed", dqp); |
@@ -2194,8 +2217,9 @@ xfs_qm_dqreclaim_one(void) | |||
2194 | if (!mutex_trylock(&dqp->q_hash->qh_lock)) | 2217 | if (!mutex_trylock(&dqp->q_hash->qh_lock)) |
2195 | goto mplistunlock; | 2218 | goto mplistunlock; |
2196 | 2219 | ||
2220 | trace_xfs_dqreclaim_unlink(dqp); | ||
2221 | |||
2197 | ASSERT(dqp->q_nrefs == 0); | 2222 | ASSERT(dqp->q_nrefs == 0); |
2198 | xfs_dqtrace_entry(dqp, "DQRECLAIM: UNLINKING"); | ||
2199 | XQM_MPLIST_REMOVE(&(XFS_QI_MPL_LIST(dqp->q_mount)), dqp); | 2223 | XQM_MPLIST_REMOVE(&(XFS_QI_MPL_LIST(dqp->q_mount)), dqp); |
2200 | XQM_HASHLIST_REMOVE(dqp->q_hash, dqp); | 2224 | XQM_HASHLIST_REMOVE(dqp->q_hash, dqp); |
2201 | XQM_FREELIST_REMOVE(dqp); | 2225 | XQM_FREELIST_REMOVE(dqp); |
@@ -2430,7 +2454,7 @@ xfs_qm_vop_dqalloc( | |||
2430 | } | 2454 | } |
2431 | } | 2455 | } |
2432 | if (uq) | 2456 | if (uq) |
2433 | xfs_dqtrace_entry_ino(uq, "DQALLOC", ip); | 2457 | trace_xfs_dquot_dqalloc(ip); |
2434 | 2458 | ||
2435 | xfs_iunlock(ip, lockflags); | 2459 | xfs_iunlock(ip, lockflags); |
2436 | if (O_udqpp) | 2460 | if (O_udqpp) |