diff options
author | Christoph Hellwig <hch@lst.de> | 2012-03-14 12:53:34 -0400 |
---|---|---|
committer | Ben Myers <bpm@sgi.com> | 2012-03-14 12:53:34 -0400 |
commit | b84a3a96751f93071c1863f2962273973c8b8f5e (patch) | |
tree | 26409cbc65a9b4457e6c52e90879361fc42d2386 /fs/xfs/xfs_dquot.c | |
parent | 9f920f116426806bfa34c1422742e1bf7b7a2b4b (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.c | 95 |
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 | */ | ||
1024 | void | ||
1025 | xfs_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 | */ |