aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_dquot.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2012-03-14 12:53:34 -0400
committerBen Myers <bpm@sgi.com>2012-03-14 12:53:34 -0400
commitb84a3a96751f93071c1863f2962273973c8b8f5e (patch)
tree26409cbc65a9b4457e6c52e90879361fc42d2386 /fs/xfs/xfs_dquot.c
parent9f920f116426806bfa34c1422742e1bf7b7a2b4b (diff)
xfs: remove the per-filesystem list of dquots
Instead of keeping a separate per-filesystem list of dquots we can walk the radix tree for the two places where we need to iterate all quota structures. Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Ben Myers <bpm@sgi.com>
Diffstat (limited to 'fs/xfs/xfs_dquot.c')
-rw-r--r--fs/xfs/xfs_dquot.c95
1 files changed, 3 insertions, 92 deletions
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c
index 49456e555cfa..2896ac953ed6 100644
--- a/fs/xfs/xfs_dquot.c
+++ b/fs/xfs/xfs_dquot.c
@@ -44,10 +44,9 @@
44 * 44 *
45 * ip->i_lock 45 * ip->i_lock
46 * qi->qi_tree_lock 46 * qi->qi_tree_lock
47 * qi->qi_dqlist_lock 47 * dquot->q_qlock (xfs_dqlock() and friends)
48 * dquot->q_qlock (xfs_dqlock() and friends) 48 * dquot->q_flush (xfs_dqflock() and friends)
49 * dquot->q_flush (xfs_dqflock() and friends) 49 * qi->qi_lru_lock
50 * qi->qi_lru_lock
51 * 50 *
52 * If two dquots need to be locked the order is user before group/project, 51 * If two dquots need to be locked the order is user before group/project,
53 * otherwise by the lowest id first, see xfs_dqlock2. 52 * otherwise by the lowest id first, see xfs_dqlock2.
@@ -729,20 +728,12 @@ restart:
729 } 728 }
730 729
731 /* 730 /*
732 * Attach this dquot to this filesystem's list of all dquots,
733 * kept inside the mount structure in m_quotainfo field
734 */
735 mutex_lock(&qi->qi_dqlist_lock);
736
737 /*
738 * We return a locked dquot to the caller, with a reference taken 731 * We return a locked dquot to the caller, with a reference taken
739 */ 732 */
740 xfs_dqlock(dqp); 733 xfs_dqlock(dqp);
741 dqp->q_nrefs = 1; 734 dqp->q_nrefs = 1;
742 735
743 list_add(&dqp->q_mplist, &qi->qi_dqlist);
744 qi->qi_dquots++; 736 qi->qi_dquots++;
745 mutex_unlock(&qi->qi_dqlist_lock);
746 mutex_unlock(&qi->qi_tree_lock); 737 mutex_unlock(&qi->qi_tree_lock);
747 738
748 dqret: 739 dqret:
@@ -1018,86 +1009,6 @@ xfs_dqlock2(
1018} 1009}
1019 1010
1020/* 1011/*
1021 * Take a dquot out of the mount's dqlist as well as the hashlist. This is
1022 * called via unmount as well as quotaoff, and the purge will always succeed.
1023 */
1024void
1025xfs_qm_dqpurge(
1026 struct xfs_dquot *dqp)
1027{
1028 struct xfs_mount *mp = dqp->q_mount;
1029 struct xfs_quotainfo *qi = mp->m_quotainfo;
1030
1031 xfs_dqlock(dqp);
1032
1033 /*
1034 * If we're turning off quotas, we have to make sure that, for
1035 * example, we don't delete quota disk blocks while dquots are
1036 * in the process of getting written to those disk blocks.
1037 * This dquot might well be on AIL, and we can't leave it there
1038 * if we're turning off quotas. Basically, we need this flush
1039 * lock, and are willing to block on it.
1040 */
1041 if (!xfs_dqflock_nowait(dqp)) {
1042 /*
1043 * Block on the flush lock after nudging dquot buffer,
1044 * if it is incore.
1045 */
1046 xfs_dqflock_pushbuf_wait(dqp);
1047 }
1048
1049 /*
1050 * If we are turning this type of quotas off, we don't care
1051 * about the dirty metadata sitting in this dquot. OTOH, if
1052 * we're unmounting, we do care, so we flush it and wait.
1053 */
1054 if (XFS_DQ_IS_DIRTY(dqp)) {
1055 int error;
1056
1057 /*
1058 * We don't care about getting disk errors here. We need
1059 * to purge this dquot anyway, so we go ahead regardless.
1060 */
1061 error = xfs_qm_dqflush(dqp, SYNC_WAIT);
1062 if (error)
1063 xfs_warn(mp, "%s: dquot %p flush failed",
1064 __func__, dqp);
1065 xfs_dqflock(dqp);
1066 }
1067
1068 ASSERT(atomic_read(&dqp->q_pincount) == 0);
1069 ASSERT(XFS_FORCED_SHUTDOWN(mp) ||
1070 !(dqp->q_logitem.qli_item.li_flags & XFS_LI_IN_AIL));
1071
1072 xfs_dqfunlock(dqp);
1073 xfs_dqunlock(dqp);
1074
1075 mutex_lock(&qi->qi_tree_lock);
1076 radix_tree_delete(XFS_DQUOT_TREE(qi, dqp->q_core.d_flags),
1077 be32_to_cpu(dqp->q_core.d_id));
1078 mutex_unlock(&qi->qi_tree_lock);
1079
1080 mutex_lock(&qi->qi_dqlist_lock);
1081 list_del_init(&dqp->q_mplist);
1082 qi->qi_dqreclaims++;
1083 qi->qi_dquots--;
1084 mutex_unlock(&qi->qi_dqlist_lock);
1085
1086 /*
1087 * We move dquots to the freelist as soon as their reference count
1088 * hits zero, so it really should be on the freelist here.
1089 */
1090 mutex_lock(&qi->qi_lru_lock);
1091 ASSERT(!list_empty(&dqp->q_lru));
1092 list_del_init(&dqp->q_lru);
1093 qi->qi_lru_count--;
1094 XFS_STATS_DEC(xs_qm_dquot_unused);
1095 mutex_unlock(&qi->qi_lru_lock);
1096
1097 xfs_qm_dqdestroy(dqp);
1098}
1099
1100/*
1101 * Give the buffer a little push if it is incore and 1012 * Give the buffer a little push if it is incore and
1102 * wait on the flush lock. 1013 * wait on the flush lock.
1103 */ 1014 */