aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/quota/xfs_qm.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/quota/xfs_qm.c')
-rw-r--r--fs/xfs/quota/xfs_qm.c80
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(
435STATIC int 450STATIC int
436xfs_qm_dqflush_all( 451xfs_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)