diff options
Diffstat (limited to 'fs/xfs/quota')
-rw-r--r-- | fs/xfs/quota/xfs_dquot.c | 157 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_dquot.h | 23 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_dquot_item.c | 99 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_dquot_item.h | 4 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_qm.c | 80 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_qm_bhv.c | 2 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_qm_syscalls.c | 10 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_trans_dquot.c | 49 |
8 files changed, 157 insertions, 267 deletions
diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c index 2f3f2229eaaf..5f79dd78626b 100644 --- a/fs/xfs/quota/xfs_dquot.c +++ b/fs/xfs/quota/xfs_dquot.c | |||
@@ -47,6 +47,7 @@ | |||
47 | #include "xfs_trans_space.h" | 47 | #include "xfs_trans_space.h" |
48 | #include "xfs_trans_priv.h" | 48 | #include "xfs_trans_priv.h" |
49 | #include "xfs_qm.h" | 49 | #include "xfs_qm.h" |
50 | #include "xfs_trace.h" | ||
50 | 51 | ||
51 | 52 | ||
52 | /* | 53 | /* |
@@ -112,10 +113,7 @@ xfs_qm_dqinit( | |||
112 | init_completion(&dqp->q_flush); | 113 | init_completion(&dqp->q_flush); |
113 | complete(&dqp->q_flush); | 114 | complete(&dqp->q_flush); |
114 | 115 | ||
115 | #ifdef XFS_DQUOT_TRACE | 116 | trace_xfs_dqinit(dqp); |
116 | dqp->q_trace = ktrace_alloc(DQUOT_TRACE_SIZE, KM_NOFS); | ||
117 | xfs_dqtrace_entry(dqp, "DQINIT"); | ||
118 | #endif | ||
119 | } else { | 117 | } else { |
120 | /* | 118 | /* |
121 | * Only the q_core portion was zeroed in dqreclaim_one(). | 119 | * Only the q_core portion was zeroed in dqreclaim_one(). |
@@ -136,10 +134,7 @@ xfs_qm_dqinit( | |||
136 | dqp->q_hash = NULL; | 134 | dqp->q_hash = NULL; |
137 | ASSERT(dqp->dq_flnext == dqp->dq_flprev); | 135 | ASSERT(dqp->dq_flnext == dqp->dq_flprev); |
138 | 136 | ||
139 | #ifdef XFS_DQUOT_TRACE | 137 | trace_xfs_dqreuse(dqp); |
140 | ASSERT(dqp->q_trace); | ||
141 | xfs_dqtrace_entry(dqp, "DQRECLAIMED_INIT"); | ||
142 | #endif | ||
143 | } | 138 | } |
144 | 139 | ||
145 | /* | 140 | /* |
@@ -167,13 +162,8 @@ xfs_qm_dqdestroy( | |||
167 | 162 | ||
168 | mutex_destroy(&dqp->q_qlock); | 163 | mutex_destroy(&dqp->q_qlock); |
169 | sv_destroy(&dqp->q_pinwait); | 164 | sv_destroy(&dqp->q_pinwait); |
170 | |||
171 | #ifdef XFS_DQUOT_TRACE | ||
172 | if (dqp->q_trace) | ||
173 | ktrace_free(dqp->q_trace); | ||
174 | dqp->q_trace = NULL; | ||
175 | #endif | ||
176 | kmem_zone_free(xfs_Gqm->qm_dqzone, dqp); | 165 | kmem_zone_free(xfs_Gqm->qm_dqzone, dqp); |
166 | |||
177 | atomic_dec(&xfs_Gqm->qm_totaldquots); | 167 | atomic_dec(&xfs_Gqm->qm_totaldquots); |
178 | } | 168 | } |
179 | 169 | ||
@@ -195,49 +185,6 @@ xfs_qm_dqinit_core( | |||
195 | d->dd_diskdq.d_flags = type; | 185 | d->dd_diskdq.d_flags = type; |
196 | } | 186 | } |
197 | 187 | ||
198 | |||
199 | #ifdef XFS_DQUOT_TRACE | ||
200 | /* | ||
201 | * Dquot tracing for debugging. | ||
202 | */ | ||
203 | /* ARGSUSED */ | ||
204 | void | ||
205 | __xfs_dqtrace_entry( | ||
206 | xfs_dquot_t *dqp, | ||
207 | char *func, | ||
208 | void *retaddr, | ||
209 | xfs_inode_t *ip) | ||
210 | { | ||
211 | xfs_dquot_t *udqp = NULL; | ||
212 | xfs_ino_t ino = 0; | ||
213 | |||
214 | ASSERT(dqp->q_trace); | ||
215 | if (ip) { | ||
216 | ino = ip->i_ino; | ||
217 | udqp = ip->i_udquot; | ||
218 | } | ||
219 | ktrace_enter(dqp->q_trace, | ||
220 | (void *)(__psint_t)DQUOT_KTRACE_ENTRY, | ||
221 | (void *)func, | ||
222 | (void *)(__psint_t)dqp->q_nrefs, | ||
223 | (void *)(__psint_t)dqp->dq_flags, | ||
224 | (void *)(__psint_t)dqp->q_res_bcount, | ||
225 | (void *)(__psint_t)be64_to_cpu(dqp->q_core.d_bcount), | ||
226 | (void *)(__psint_t)be64_to_cpu(dqp->q_core.d_icount), | ||
227 | (void *)(__psint_t)be64_to_cpu(dqp->q_core.d_blk_hardlimit), | ||
228 | (void *)(__psint_t)be64_to_cpu(dqp->q_core.d_blk_softlimit), | ||
229 | (void *)(__psint_t)be64_to_cpu(dqp->q_core.d_ino_hardlimit), | ||
230 | (void *)(__psint_t)be64_to_cpu(dqp->q_core.d_ino_softlimit), | ||
231 | (void *)(__psint_t)be32_to_cpu(dqp->q_core.d_id), | ||
232 | (void *)(__psint_t)current_pid(), | ||
233 | (void *)(__psint_t)ino, | ||
234 | (void *)(__psint_t)retaddr, | ||
235 | (void *)(__psint_t)udqp); | ||
236 | return; | ||
237 | } | ||
238 | #endif | ||
239 | |||
240 | |||
241 | /* | 188 | /* |
242 | * If default limits are in force, push them into the dquot now. | 189 | * If default limits are in force, push them into the dquot now. |
243 | * We overwrite the dquot limits only if they are zero and this | 190 | * We overwrite the dquot limits only if they are zero and this |
@@ -425,7 +372,8 @@ xfs_qm_dqalloc( | |||
425 | xfs_trans_t *tp = *tpp; | 372 | xfs_trans_t *tp = *tpp; |
426 | 373 | ||
427 | ASSERT(tp != NULL); | 374 | ASSERT(tp != NULL); |
428 | xfs_dqtrace_entry(dqp, "DQALLOC"); | 375 | |
376 | trace_xfs_dqalloc(dqp); | ||
429 | 377 | ||
430 | /* | 378 | /* |
431 | * Initialize the bmap freelist prior to calling bmapi code. | 379 | * Initialize the bmap freelist prior to calling bmapi code. |
@@ -612,7 +560,8 @@ xfs_qm_dqtobp( | |||
612 | * (in which case we already have the buf). | 560 | * (in which case we already have the buf). |
613 | */ | 561 | */ |
614 | if (! newdquot) { | 562 | if (! newdquot) { |
615 | xfs_dqtrace_entry(dqp, "DQTOBP READBUF"); | 563 | trace_xfs_dqtobp_read(dqp); |
564 | |||
616 | if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, | 565 | if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, |
617 | dqp->q_blkno, | 566 | dqp->q_blkno, |
618 | XFS_QI_DQCHUNKLEN(mp), | 567 | XFS_QI_DQCHUNKLEN(mp), |
@@ -670,11 +619,12 @@ xfs_qm_dqread( | |||
670 | 619 | ||
671 | ASSERT(tpp); | 620 | ASSERT(tpp); |
672 | 621 | ||
622 | trace_xfs_dqread(dqp); | ||
623 | |||
673 | /* | 624 | /* |
674 | * get a pointer to the on-disk dquot and the buffer containing it | 625 | * get a pointer to the on-disk dquot and the buffer containing it |
675 | * dqp already knows its own type (GROUP/USER). | 626 | * dqp already knows its own type (GROUP/USER). |
676 | */ | 627 | */ |
677 | xfs_dqtrace_entry(dqp, "DQREAD"); | ||
678 | if ((error = xfs_qm_dqtobp(tpp, dqp, &ddqp, &bp, flags))) { | 628 | if ((error = xfs_qm_dqtobp(tpp, dqp, &ddqp, &bp, flags))) { |
679 | return (error); | 629 | return (error); |
680 | } | 630 | } |
@@ -763,7 +713,7 @@ xfs_qm_idtodq( | |||
763 | * or if the dquot didn't exist on disk and we ask to | 713 | * or if the dquot didn't exist on disk and we ask to |
764 | * allocate (ENOENT). | 714 | * allocate (ENOENT). |
765 | */ | 715 | */ |
766 | xfs_dqtrace_entry(dqp, "DQREAD FAIL"); | 716 | trace_xfs_dqread_fail(dqp); |
767 | cancelflags |= XFS_TRANS_ABORT; | 717 | cancelflags |= XFS_TRANS_ABORT; |
768 | goto error0; | 718 | goto error0; |
769 | } | 719 | } |
@@ -817,7 +767,8 @@ xfs_qm_dqlookup( | |||
817 | * id can't be modified without the hashlock anyway. | 767 | * id can't be modified without the hashlock anyway. |
818 | */ | 768 | */ |
819 | if (be32_to_cpu(dqp->q_core.d_id) == id && dqp->q_mount == mp) { | 769 | if (be32_to_cpu(dqp->q_core.d_id) == id && dqp->q_mount == mp) { |
820 | xfs_dqtrace_entry(dqp, "DQFOUND BY LOOKUP"); | 770 | trace_xfs_dqlookup_found(dqp); |
771 | |||
821 | /* | 772 | /* |
822 | * All in core dquots must be on the dqlist of mp | 773 | * All in core dquots must be on the dqlist of mp |
823 | */ | 774 | */ |
@@ -827,7 +778,7 @@ xfs_qm_dqlookup( | |||
827 | if (dqp->q_nrefs == 0) { | 778 | if (dqp->q_nrefs == 0) { |
828 | ASSERT (XFS_DQ_IS_ON_FREELIST(dqp)); | 779 | ASSERT (XFS_DQ_IS_ON_FREELIST(dqp)); |
829 | if (! xfs_qm_freelist_lock_nowait(xfs_Gqm)) { | 780 | if (! xfs_qm_freelist_lock_nowait(xfs_Gqm)) { |
830 | xfs_dqtrace_entry(dqp, "DQLOOKUP: WANT"); | 781 | trace_xfs_dqlookup_want(dqp); |
831 | 782 | ||
832 | /* | 783 | /* |
833 | * We may have raced with dqreclaim_one() | 784 | * We may have raced with dqreclaim_one() |
@@ -857,8 +808,7 @@ xfs_qm_dqlookup( | |||
857 | /* | 808 | /* |
858 | * take it off the freelist | 809 | * take it off the freelist |
859 | */ | 810 | */ |
860 | xfs_dqtrace_entry(dqp, | 811 | trace_xfs_dqlookup_freelist(dqp); |
861 | "DQLOOKUP: TAKEOFF FL"); | ||
862 | XQM_FREELIST_REMOVE(dqp); | 812 | XQM_FREELIST_REMOVE(dqp); |
863 | /* xfs_qm_freelist_print(&(xfs_Gqm-> | 813 | /* xfs_qm_freelist_print(&(xfs_Gqm-> |
864 | qm_dqfreelist), | 814 | qm_dqfreelist), |
@@ -878,8 +828,7 @@ xfs_qm_dqlookup( | |||
878 | */ | 828 | */ |
879 | ASSERT(mutex_is_locked(&qh->qh_lock)); | 829 | ASSERT(mutex_is_locked(&qh->qh_lock)); |
880 | if (dqp->HL_PREVP != &qh->qh_next) { | 830 | if (dqp->HL_PREVP != &qh->qh_next) { |
881 | xfs_dqtrace_entry(dqp, | 831 | trace_xfs_dqlookup_move(dqp); |
882 | "DQLOOKUP: HASH MOVETOFRONT"); | ||
883 | if ((d = dqp->HL_NEXT)) | 832 | if ((d = dqp->HL_NEXT)) |
884 | d->HL_PREVP = dqp->HL_PREVP; | 833 | d->HL_PREVP = dqp->HL_PREVP; |
885 | *(dqp->HL_PREVP) = d; | 834 | *(dqp->HL_PREVP) = d; |
@@ -889,7 +838,7 @@ xfs_qm_dqlookup( | |||
889 | dqp->HL_PREVP = &qh->qh_next; | 838 | dqp->HL_PREVP = &qh->qh_next; |
890 | qh->qh_next = dqp; | 839 | qh->qh_next = dqp; |
891 | } | 840 | } |
892 | xfs_dqtrace_entry(dqp, "LOOKUP END"); | 841 | trace_xfs_dqlookup_done(dqp); |
893 | *O_dqpp = dqp; | 842 | *O_dqpp = dqp; |
894 | ASSERT(mutex_is_locked(&qh->qh_lock)); | 843 | ASSERT(mutex_is_locked(&qh->qh_lock)); |
895 | return (0); | 844 | return (0); |
@@ -971,7 +920,7 @@ xfs_qm_dqget( | |||
971 | ASSERT(*O_dqpp); | 920 | ASSERT(*O_dqpp); |
972 | ASSERT(XFS_DQ_IS_LOCKED(*O_dqpp)); | 921 | ASSERT(XFS_DQ_IS_LOCKED(*O_dqpp)); |
973 | mutex_unlock(&h->qh_lock); | 922 | mutex_unlock(&h->qh_lock); |
974 | xfs_dqtrace_entry(*O_dqpp, "DQGET DONE (FROM CACHE)"); | 923 | trace_xfs_dqget_hit(*O_dqpp); |
975 | return (0); /* success */ | 924 | return (0); /* success */ |
976 | } | 925 | } |
977 | XQM_STATS_INC(xqmstats.xs_qm_dqcachemisses); | 926 | XQM_STATS_INC(xqmstats.xs_qm_dqcachemisses); |
@@ -1104,7 +1053,7 @@ xfs_qm_dqget( | |||
1104 | mutex_unlock(&h->qh_lock); | 1053 | mutex_unlock(&h->qh_lock); |
1105 | dqret: | 1054 | dqret: |
1106 | ASSERT((ip == NULL) || xfs_isilocked(ip, XFS_ILOCK_EXCL)); | 1055 | ASSERT((ip == NULL) || xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
1107 | xfs_dqtrace_entry(dqp, "DQGET DONE"); | 1056 | trace_xfs_dqget_miss(dqp); |
1108 | *O_dqpp = dqp; | 1057 | *O_dqpp = dqp; |
1109 | return (0); | 1058 | return (0); |
1110 | } | 1059 | } |
@@ -1124,7 +1073,8 @@ xfs_qm_dqput( | |||
1124 | 1073 | ||
1125 | ASSERT(dqp->q_nrefs > 0); | 1074 | ASSERT(dqp->q_nrefs > 0); |
1126 | ASSERT(XFS_DQ_IS_LOCKED(dqp)); | 1075 | ASSERT(XFS_DQ_IS_LOCKED(dqp)); |
1127 | xfs_dqtrace_entry(dqp, "DQPUT"); | 1076 | |
1077 | trace_xfs_dqput(dqp); | ||
1128 | 1078 | ||
1129 | if (dqp->q_nrefs != 1) { | 1079 | if (dqp->q_nrefs != 1) { |
1130 | dqp->q_nrefs--; | 1080 | dqp->q_nrefs--; |
@@ -1137,7 +1087,7 @@ xfs_qm_dqput( | |||
1137 | * in the right order; but try to get it out-of-order first | 1087 | * in the right order; but try to get it out-of-order first |
1138 | */ | 1088 | */ |
1139 | if (! xfs_qm_freelist_lock_nowait(xfs_Gqm)) { | 1089 | if (! xfs_qm_freelist_lock_nowait(xfs_Gqm)) { |
1140 | xfs_dqtrace_entry(dqp, "DQPUT: FLLOCK-WAIT"); | 1090 | trace_xfs_dqput_wait(dqp); |
1141 | xfs_dqunlock(dqp); | 1091 | xfs_dqunlock(dqp); |
1142 | xfs_qm_freelist_lock(xfs_Gqm); | 1092 | xfs_qm_freelist_lock(xfs_Gqm); |
1143 | xfs_dqlock(dqp); | 1093 | xfs_dqlock(dqp); |
@@ -1148,7 +1098,8 @@ xfs_qm_dqput( | |||
1148 | 1098 | ||
1149 | /* We can't depend on nrefs being == 1 here */ | 1099 | /* We can't depend on nrefs being == 1 here */ |
1150 | if (--dqp->q_nrefs == 0) { | 1100 | if (--dqp->q_nrefs == 0) { |
1151 | xfs_dqtrace_entry(dqp, "DQPUT: ON FREELIST"); | 1101 | trace_xfs_dqput_free(dqp); |
1102 | |||
1152 | /* | 1103 | /* |
1153 | * insert at end of the freelist. | 1104 | * insert at end of the freelist. |
1154 | */ | 1105 | */ |
@@ -1196,7 +1147,7 @@ xfs_qm_dqrele( | |||
1196 | if (!dqp) | 1147 | if (!dqp) |
1197 | return; | 1148 | return; |
1198 | 1149 | ||
1199 | xfs_dqtrace_entry(dqp, "DQRELE"); | 1150 | trace_xfs_dqrele(dqp); |
1200 | 1151 | ||
1201 | xfs_dqlock(dqp); | 1152 | xfs_dqlock(dqp); |
1202 | /* | 1153 | /* |
@@ -1229,14 +1180,14 @@ xfs_qm_dqflush( | |||
1229 | 1180 | ||
1230 | ASSERT(XFS_DQ_IS_LOCKED(dqp)); | 1181 | ASSERT(XFS_DQ_IS_LOCKED(dqp)); |
1231 | ASSERT(!completion_done(&dqp->q_flush)); | 1182 | ASSERT(!completion_done(&dqp->q_flush)); |
1232 | xfs_dqtrace_entry(dqp, "DQFLUSH"); | 1183 | trace_xfs_dqflush(dqp); |
1233 | 1184 | ||
1234 | /* | 1185 | /* |
1235 | * If not dirty, or it's pinned and we are not supposed to | 1186 | * If not dirty, or it's pinned and we are not supposed to |
1236 | * block, nada. | 1187 | * block, nada. |
1237 | */ | 1188 | */ |
1238 | if (!XFS_DQ_IS_DIRTY(dqp) || | 1189 | if (!XFS_DQ_IS_DIRTY(dqp) || |
1239 | (!(flags & XFS_QMOPT_SYNC) && atomic_read(&dqp->q_pincount) > 0)) { | 1190 | (!(flags & SYNC_WAIT) && atomic_read(&dqp->q_pincount) > 0)) { |
1240 | xfs_dqfunlock(dqp); | 1191 | xfs_dqfunlock(dqp); |
1241 | return 0; | 1192 | return 0; |
1242 | } | 1193 | } |
@@ -1259,7 +1210,6 @@ xfs_qm_dqflush( | |||
1259 | * the ondisk-dquot has already been allocated for. | 1210 | * the ondisk-dquot has already been allocated for. |
1260 | */ | 1211 | */ |
1261 | if ((error = xfs_qm_dqtobp(NULL, dqp, &ddqp, &bp, XFS_QMOPT_DOWARN))) { | 1212 | if ((error = xfs_qm_dqtobp(NULL, dqp, &ddqp, &bp, XFS_QMOPT_DOWARN))) { |
1262 | xfs_dqtrace_entry(dqp, "DQTOBP FAIL"); | ||
1263 | ASSERT(error != ENOENT); | 1213 | ASSERT(error != ENOENT); |
1264 | /* | 1214 | /* |
1265 | * Quotas could have gotten turned off (ESRCH) | 1215 | * Quotas could have gotten turned off (ESRCH) |
@@ -1297,22 +1247,21 @@ xfs_qm_dqflush( | |||
1297 | * get stuck waiting in the write for too long. | 1247 | * get stuck waiting in the write for too long. |
1298 | */ | 1248 | */ |
1299 | if (XFS_BUF_ISPINNED(bp)) { | 1249 | if (XFS_BUF_ISPINNED(bp)) { |
1300 | xfs_dqtrace_entry(dqp, "DQFLUSH LOG FORCE"); | 1250 | trace_xfs_dqflush_force(dqp); |
1301 | xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE); | 1251 | xfs_log_force(mp, 0); |
1302 | } | 1252 | } |
1303 | 1253 | ||
1304 | if (flags & XFS_QMOPT_DELWRI) { | 1254 | if (flags & SYNC_WAIT) |
1305 | xfs_bdwrite(mp, bp); | ||
1306 | } else if (flags & XFS_QMOPT_ASYNC) { | ||
1307 | error = xfs_bawrite(mp, bp); | ||
1308 | } else { | ||
1309 | error = xfs_bwrite(mp, bp); | 1255 | error = xfs_bwrite(mp, bp); |
1310 | } | 1256 | else |
1311 | xfs_dqtrace_entry(dqp, "DQFLUSH END"); | 1257 | xfs_bdwrite(mp, bp); |
1258 | |||
1259 | trace_xfs_dqflush_done(dqp); | ||
1260 | |||
1312 | /* | 1261 | /* |
1313 | * dqp is still locked, but caller is free to unlock it now. | 1262 | * dqp is still locked, but caller is free to unlock it now. |
1314 | */ | 1263 | */ |
1315 | return (error); | 1264 | return error; |
1316 | 1265 | ||
1317 | } | 1266 | } |
1318 | 1267 | ||
@@ -1483,7 +1432,7 @@ xfs_qm_dqpurge( | |||
1483 | */ | 1432 | */ |
1484 | if (XFS_DQ_IS_DIRTY(dqp)) { | 1433 | if (XFS_DQ_IS_DIRTY(dqp)) { |
1485 | int error; | 1434 | int error; |
1486 | xfs_dqtrace_entry(dqp, "DQPURGE ->DQFLUSH: DQDIRTY"); | 1435 | |
1487 | /* dqflush unlocks dqflock */ | 1436 | /* dqflush unlocks dqflock */ |
1488 | /* | 1437 | /* |
1489 | * Given that dqpurge is a very rare occurrence, it is OK | 1438 | * Given that dqpurge is a very rare occurrence, it is OK |
@@ -1493,7 +1442,7 @@ xfs_qm_dqpurge( | |||
1493 | * We don't care about getting disk errors here. We need | 1442 | * We don't care about getting disk errors here. We need |
1494 | * to purge this dquot anyway, so we go ahead regardless. | 1443 | * to purge this dquot anyway, so we go ahead regardless. |
1495 | */ | 1444 | */ |
1496 | error = xfs_qm_dqflush(dqp, XFS_QMOPT_SYNC); | 1445 | error = xfs_qm_dqflush(dqp, SYNC_WAIT); |
1497 | if (error) | 1446 | if (error) |
1498 | xfs_fs_cmn_err(CE_WARN, mp, | 1447 | xfs_fs_cmn_err(CE_WARN, mp, |
1499 | "xfs_qm_dqpurge: dquot %p flush failed", dqp); | 1448 | "xfs_qm_dqpurge: dquot %p flush failed", dqp); |
@@ -1577,25 +1526,17 @@ xfs_qm_dqflock_pushbuf_wait( | |||
1577 | * the flush lock when the I/O completes. | 1526 | * the flush lock when the I/O completes. |
1578 | */ | 1527 | */ |
1579 | bp = xfs_incore(dqp->q_mount->m_ddev_targp, dqp->q_blkno, | 1528 | bp = xfs_incore(dqp->q_mount->m_ddev_targp, dqp->q_blkno, |
1580 | XFS_QI_DQCHUNKLEN(dqp->q_mount), | 1529 | XFS_QI_DQCHUNKLEN(dqp->q_mount), XBF_TRYLOCK); |
1581 | XFS_INCORE_TRYLOCK); | 1530 | if (!bp) |
1582 | if (bp != NULL) { | 1531 | goto out_lock; |
1583 | if (XFS_BUF_ISDELAYWRITE(bp)) { | 1532 | |
1584 | int error; | 1533 | if (XFS_BUF_ISDELAYWRITE(bp)) { |
1585 | if (XFS_BUF_ISPINNED(bp)) { | 1534 | if (XFS_BUF_ISPINNED(bp)) |
1586 | xfs_log_force(dqp->q_mount, | 1535 | xfs_log_force(dqp->q_mount, 0); |
1587 | (xfs_lsn_t)0, | 1536 | xfs_buf_delwri_promote(bp); |
1588 | XFS_LOG_FORCE); | 1537 | wake_up_process(bp->b_target->bt_task); |
1589 | } | ||
1590 | error = xfs_bawrite(dqp->q_mount, bp); | ||
1591 | if (error) | ||
1592 | xfs_fs_cmn_err(CE_WARN, dqp->q_mount, | ||
1593 | "xfs_qm_dqflock_pushbuf_wait: " | ||
1594 | "pushbuf error %d on dqp %p, bp %p", | ||
1595 | error, dqp, bp); | ||
1596 | } else { | ||
1597 | xfs_buf_relse(bp); | ||
1598 | } | ||
1599 | } | 1538 | } |
1539 | xfs_buf_relse(bp); | ||
1540 | out_lock: | ||
1600 | xfs_dqflock(dqp); | 1541 | xfs_dqflock(dqp); |
1601 | } | 1542 | } |
diff --git a/fs/xfs/quota/xfs_dquot.h b/fs/xfs/quota/xfs_dquot.h index 6533ead9b889..a0f7da586d1b 100644 --- a/fs/xfs/quota/xfs_dquot.h +++ b/fs/xfs/quota/xfs_dquot.h | |||
@@ -85,9 +85,6 @@ typedef struct xfs_dquot { | |||
85 | struct completion q_flush; /* flush completion queue */ | 85 | struct completion q_flush; /* flush completion queue */ |
86 | atomic_t q_pincount; /* dquot pin count */ | 86 | atomic_t q_pincount; /* dquot pin count */ |
87 | wait_queue_head_t q_pinwait; /* dquot pinning wait queue */ | 87 | wait_queue_head_t q_pinwait; /* dquot pinning wait queue */ |
88 | #ifdef XFS_DQUOT_TRACE | ||
89 | struct ktrace *q_trace; /* trace header structure */ | ||
90 | #endif | ||
91 | } xfs_dquot_t; | 88 | } xfs_dquot_t; |
92 | 89 | ||
93 | 90 | ||
@@ -98,7 +95,7 @@ typedef struct xfs_dquot { | |||
98 | #define dq_flags q_lists.dqm_flags | 95 | #define dq_flags q_lists.dqm_flags |
99 | 96 | ||
100 | /* | 97 | /* |
101 | * Lock hierachy for q_qlock: | 98 | * Lock hierarchy for q_qlock: |
102 | * XFS_QLOCK_NORMAL is the implicit default, | 99 | * XFS_QLOCK_NORMAL is the implicit default, |
103 | * XFS_QLOCK_NESTED is the dquot with the higher id in xfs_dqlock2 | 100 | * XFS_QLOCK_NESTED is the dquot with the higher id in xfs_dqlock2 |
104 | */ | 101 | */ |
@@ -144,24 +141,6 @@ static inline void xfs_dqfunlock(xfs_dquot_t *dqp) | |||
144 | (XFS_IS_UQUOTA_ON((d)->q_mount)) : \ | 141 | (XFS_IS_UQUOTA_ON((d)->q_mount)) : \ |
145 | (XFS_IS_OQUOTA_ON((d)->q_mount)))) | 142 | (XFS_IS_OQUOTA_ON((d)->q_mount)))) |
146 | 143 | ||
147 | #ifdef XFS_DQUOT_TRACE | ||
148 | /* | ||
149 | * Dquot Tracing stuff. | ||
150 | */ | ||
151 | #define DQUOT_TRACE_SIZE 64 | ||
152 | #define DQUOT_KTRACE_ENTRY 1 | ||
153 | |||
154 | extern void __xfs_dqtrace_entry(xfs_dquot_t *dqp, char *func, | ||
155 | void *, xfs_inode_t *); | ||
156 | #define xfs_dqtrace_entry_ino(a,b,ip) \ | ||
157 | __xfs_dqtrace_entry((a), (b), (void*)__return_address, (ip)) | ||
158 | #define xfs_dqtrace_entry(a,b) \ | ||
159 | __xfs_dqtrace_entry((a), (b), (void*)__return_address, NULL) | ||
160 | #else | ||
161 | #define xfs_dqtrace_entry(a,b) | ||
162 | #define xfs_dqtrace_entry_ino(a,b,ip) | ||
163 | #endif | ||
164 | |||
165 | #ifdef QUOTADEBUG | 144 | #ifdef QUOTADEBUG |
166 | extern void xfs_qm_dqprint(xfs_dquot_t *); | 145 | extern void xfs_qm_dqprint(xfs_dquot_t *); |
167 | #else | 146 | #else |
diff --git a/fs/xfs/quota/xfs_dquot_item.c b/fs/xfs/quota/xfs_dquot_item.c index d0d4a9a0bbd7..4e4ee9a57194 100644 --- a/fs/xfs/quota/xfs_dquot_item.c +++ b/fs/xfs/quota/xfs_dquot_item.c | |||
@@ -74,11 +74,11 @@ xfs_qm_dquot_logitem_format( | |||
74 | 74 | ||
75 | logvec->i_addr = (xfs_caddr_t)&logitem->qli_format; | 75 | logvec->i_addr = (xfs_caddr_t)&logitem->qli_format; |
76 | logvec->i_len = sizeof(xfs_dq_logformat_t); | 76 | logvec->i_len = sizeof(xfs_dq_logformat_t); |
77 | XLOG_VEC_SET_TYPE(logvec, XLOG_REG_TYPE_QFORMAT); | 77 | logvec->i_type = XLOG_REG_TYPE_QFORMAT; |
78 | logvec++; | 78 | logvec++; |
79 | logvec->i_addr = (xfs_caddr_t)&logitem->qli_dquot->q_core; | 79 | logvec->i_addr = (xfs_caddr_t)&logitem->qli_dquot->q_core; |
80 | logvec->i_len = sizeof(xfs_disk_dquot_t); | 80 | logvec->i_len = sizeof(xfs_disk_dquot_t); |
81 | XLOG_VEC_SET_TYPE(logvec, XLOG_REG_TYPE_DQUOT); | 81 | logvec->i_type = XLOG_REG_TYPE_DQUOT; |
82 | 82 | ||
83 | ASSERT(2 == logitem->qli_item.li_desc->lid_size); | 83 | ASSERT(2 == logitem->qli_item.li_desc->lid_size); |
84 | logitem->qli_format.qlf_size = 2; | 84 | logitem->qli_format.qlf_size = 2; |
@@ -153,7 +153,7 @@ xfs_qm_dquot_logitem_push( | |||
153 | * lock without sleeping, then there must not have been | 153 | * lock without sleeping, then there must not have been |
154 | * anyone in the process of flushing the dquot. | 154 | * anyone in the process of flushing the dquot. |
155 | */ | 155 | */ |
156 | error = xfs_qm_dqflush(dqp, XFS_QMOPT_DELWRI); | 156 | error = xfs_qm_dqflush(dqp, 0); |
157 | if (error) | 157 | if (error) |
158 | xfs_fs_cmn_err(CE_WARN, dqp->q_mount, | 158 | xfs_fs_cmn_err(CE_WARN, dqp->q_mount, |
159 | "xfs_qm_dquot_logitem_push: push error %d on dqp %p", | 159 | "xfs_qm_dquot_logitem_push: push error %d on dqp %p", |
@@ -190,7 +190,7 @@ xfs_qm_dqunpin_wait( | |||
190 | /* | 190 | /* |
191 | * Give the log a push so we don't wait here too long. | 191 | * Give the log a push so we don't wait here too long. |
192 | */ | 192 | */ |
193 | xfs_log_force(dqp->q_mount, (xfs_lsn_t)0, XFS_LOG_FORCE); | 193 | xfs_log_force(dqp->q_mount, 0); |
194 | wait_event(dqp->q_pinwait, (atomic_read(&dqp->q_pincount) == 0)); | 194 | wait_event(dqp->q_pinwait, (atomic_read(&dqp->q_pincount) == 0)); |
195 | } | 195 | } |
196 | 196 | ||
@@ -212,68 +212,31 @@ xfs_qm_dquot_logitem_pushbuf( | |||
212 | xfs_dquot_t *dqp; | 212 | xfs_dquot_t *dqp; |
213 | xfs_mount_t *mp; | 213 | xfs_mount_t *mp; |
214 | xfs_buf_t *bp; | 214 | xfs_buf_t *bp; |
215 | uint dopush; | ||
216 | 215 | ||
217 | dqp = qip->qli_dquot; | 216 | dqp = qip->qli_dquot; |
218 | ASSERT(XFS_DQ_IS_LOCKED(dqp)); | 217 | ASSERT(XFS_DQ_IS_LOCKED(dqp)); |
219 | 218 | ||
220 | /* | 219 | /* |
221 | * The qli_pushbuf_flag keeps others from | ||
222 | * trying to duplicate our effort. | ||
223 | */ | ||
224 | ASSERT(qip->qli_pushbuf_flag != 0); | ||
225 | ASSERT(qip->qli_push_owner == current_pid()); | ||
226 | |||
227 | /* | ||
228 | * If flushlock isn't locked anymore, chances are that the | 220 | * If flushlock isn't locked anymore, chances are that the |
229 | * inode flush completed and the inode was taken off the AIL. | 221 | * inode flush completed and the inode was taken off the AIL. |
230 | * So, just get out. | 222 | * So, just get out. |
231 | */ | 223 | */ |
232 | if (completion_done(&dqp->q_flush) || | 224 | if (completion_done(&dqp->q_flush) || |
233 | ((qip->qli_item.li_flags & XFS_LI_IN_AIL) == 0)) { | 225 | ((qip->qli_item.li_flags & XFS_LI_IN_AIL) == 0)) { |
234 | qip->qli_pushbuf_flag = 0; | ||
235 | xfs_dqunlock(dqp); | 226 | xfs_dqunlock(dqp); |
236 | return; | 227 | return; |
237 | } | 228 | } |
238 | mp = dqp->q_mount; | 229 | mp = dqp->q_mount; |
239 | bp = xfs_incore(mp->m_ddev_targp, qip->qli_format.qlf_blkno, | 230 | bp = xfs_incore(mp->m_ddev_targp, qip->qli_format.qlf_blkno, |
240 | XFS_QI_DQCHUNKLEN(mp), | 231 | XFS_QI_DQCHUNKLEN(mp), XBF_TRYLOCK); |
241 | XFS_INCORE_TRYLOCK); | 232 | xfs_dqunlock(dqp); |
242 | if (bp != NULL) { | 233 | if (!bp) |
243 | if (XFS_BUF_ISDELAYWRITE(bp)) { | ||
244 | dopush = ((qip->qli_item.li_flags & XFS_LI_IN_AIL) && | ||
245 | !completion_done(&dqp->q_flush)); | ||
246 | qip->qli_pushbuf_flag = 0; | ||
247 | xfs_dqunlock(dqp); | ||
248 | |||
249 | if (XFS_BUF_ISPINNED(bp)) { | ||
250 | xfs_log_force(mp, (xfs_lsn_t)0, | ||
251 | XFS_LOG_FORCE); | ||
252 | } | ||
253 | if (dopush) { | ||
254 | int error; | ||
255 | #ifdef XFSRACEDEBUG | ||
256 | delay_for_intr(); | ||
257 | delay(300); | ||
258 | #endif | ||
259 | error = xfs_bawrite(mp, bp); | ||
260 | if (error) | ||
261 | xfs_fs_cmn_err(CE_WARN, mp, | ||
262 | "xfs_qm_dquot_logitem_pushbuf: pushbuf error %d on qip %p, bp %p", | ||
263 | error, qip, bp); | ||
264 | } else { | ||
265 | xfs_buf_relse(bp); | ||
266 | } | ||
267 | } else { | ||
268 | qip->qli_pushbuf_flag = 0; | ||
269 | xfs_dqunlock(dqp); | ||
270 | xfs_buf_relse(bp); | ||
271 | } | ||
272 | return; | 234 | return; |
273 | } | 235 | if (XFS_BUF_ISDELAYWRITE(bp)) |
236 | xfs_buf_delwri_promote(bp); | ||
237 | xfs_buf_relse(bp); | ||
238 | return; | ||
274 | 239 | ||
275 | qip->qli_pushbuf_flag = 0; | ||
276 | xfs_dqunlock(dqp); | ||
277 | } | 240 | } |
278 | 241 | ||
279 | /* | 242 | /* |
@@ -291,50 +254,24 @@ xfs_qm_dquot_logitem_trylock( | |||
291 | xfs_dq_logitem_t *qip) | 254 | xfs_dq_logitem_t *qip) |
292 | { | 255 | { |
293 | xfs_dquot_t *dqp; | 256 | xfs_dquot_t *dqp; |
294 | uint retval; | ||
295 | 257 | ||
296 | dqp = qip->qli_dquot; | 258 | dqp = qip->qli_dquot; |
297 | if (atomic_read(&dqp->q_pincount) > 0) | 259 | if (atomic_read(&dqp->q_pincount) > 0) |
298 | return (XFS_ITEM_PINNED); | 260 | return XFS_ITEM_PINNED; |
299 | 261 | ||
300 | if (! xfs_qm_dqlock_nowait(dqp)) | 262 | if (! xfs_qm_dqlock_nowait(dqp)) |
301 | return (XFS_ITEM_LOCKED); | 263 | return XFS_ITEM_LOCKED; |
302 | 264 | ||
303 | retval = XFS_ITEM_SUCCESS; | ||
304 | if (!xfs_dqflock_nowait(dqp)) { | 265 | if (!xfs_dqflock_nowait(dqp)) { |
305 | /* | 266 | /* |
306 | * The dquot is already being flushed. It may have been | 267 | * dquot has already been flushed to the backing buffer, |
307 | * flushed delayed write, however, and we don't want to | 268 | * leave it locked, pushbuf routine will unlock it. |
308 | * get stuck waiting for that to complete. So, we want to check | ||
309 | * to see if we can lock the dquot's buffer without sleeping. | ||
310 | * If we can and it is marked for delayed write, then we | ||
311 | * hold it and send it out from the push routine. We don't | ||
312 | * want to do that now since we might sleep in the device | ||
313 | * strategy routine. We also don't want to grab the buffer lock | ||
314 | * here because we'd like not to call into the buffer cache | ||
315 | * while holding the AIL lock. | ||
316 | * Make sure to only return PUSHBUF if we set pushbuf_flag | ||
317 | * ourselves. If someone else is doing it then we don't | ||
318 | * want to go to the push routine and duplicate their efforts. | ||
319 | */ | 269 | */ |
320 | if (qip->qli_pushbuf_flag == 0) { | 270 | return XFS_ITEM_PUSHBUF; |
321 | qip->qli_pushbuf_flag = 1; | ||
322 | ASSERT(qip->qli_format.qlf_blkno == dqp->q_blkno); | ||
323 | #ifdef DEBUG | ||
324 | qip->qli_push_owner = current_pid(); | ||
325 | #endif | ||
326 | /* | ||
327 | * The dquot is left locked. | ||
328 | */ | ||
329 | retval = XFS_ITEM_PUSHBUF; | ||
330 | } else { | ||
331 | retval = XFS_ITEM_FLUSHING; | ||
332 | xfs_dqunlock_nonotify(dqp); | ||
333 | } | ||
334 | } | 271 | } |
335 | 272 | ||
336 | ASSERT(qip->qli_item.li_flags & XFS_LI_IN_AIL); | 273 | ASSERT(qip->qli_item.li_flags & XFS_LI_IN_AIL); |
337 | return (retval); | 274 | return XFS_ITEM_SUCCESS; |
338 | } | 275 | } |
339 | 276 | ||
340 | 277 | ||
@@ -467,7 +404,7 @@ xfs_qm_qoff_logitem_format(xfs_qoff_logitem_t *qf, | |||
467 | 404 | ||
468 | log_vector->i_addr = (xfs_caddr_t)&(qf->qql_format); | 405 | log_vector->i_addr = (xfs_caddr_t)&(qf->qql_format); |
469 | log_vector->i_len = sizeof(xfs_qoff_logitem_t); | 406 | log_vector->i_len = sizeof(xfs_qoff_logitem_t); |
470 | XLOG_VEC_SET_TYPE(log_vector, XLOG_REG_TYPE_QUOTAOFF); | 407 | log_vector->i_type = XLOG_REG_TYPE_QUOTAOFF; |
471 | qf->qql_format.qf_size = 1; | 408 | qf->qql_format.qf_size = 1; |
472 | } | 409 | } |
473 | 410 | ||
diff --git a/fs/xfs/quota/xfs_dquot_item.h b/fs/xfs/quota/xfs_dquot_item.h index 5a632531f843..5acae2ada70b 100644 --- a/fs/xfs/quota/xfs_dquot_item.h +++ b/fs/xfs/quota/xfs_dquot_item.h | |||
@@ -27,10 +27,6 @@ typedef struct xfs_dq_logitem { | |||
27 | xfs_log_item_t qli_item; /* common portion */ | 27 | xfs_log_item_t qli_item; /* common portion */ |
28 | struct xfs_dquot *qli_dquot; /* dquot ptr */ | 28 | struct xfs_dquot *qli_dquot; /* dquot ptr */ |
29 | xfs_lsn_t qli_flush_lsn; /* lsn at last flush */ | 29 | xfs_lsn_t qli_flush_lsn; /* lsn at last flush */ |
30 | unsigned short qli_pushbuf_flag; /* 1 bit used in push_ail */ | ||
31 | #ifdef DEBUG | ||
32 | uint64_t qli_push_owner; | ||
33 | #endif | ||
34 | xfs_dq_logformat_t qli_format; /* logged structure */ | 30 | xfs_dq_logformat_t qli_format; /* logged structure */ |
35 | } xfs_dq_logitem_t; | 31 | } xfs_dq_logitem_t; |
36 | 32 | ||
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) |
diff --git a/fs/xfs/quota/xfs_qm_bhv.c b/fs/xfs/quota/xfs_qm_bhv.c index a5346630dfae..97b410c12794 100644 --- a/fs/xfs/quota/xfs_qm_bhv.c +++ b/fs/xfs/quota/xfs_qm_bhv.c | |||
@@ -59,7 +59,7 @@ xfs_fill_statvfs_from_dquot( | |||
59 | be64_to_cpu(dp->d_blk_hardlimit); | 59 | be64_to_cpu(dp->d_blk_hardlimit); |
60 | if (limit && statp->f_blocks > limit) { | 60 | if (limit && statp->f_blocks > limit) { |
61 | statp->f_blocks = limit; | 61 | statp->f_blocks = limit; |
62 | statp->f_bfree = | 62 | statp->f_bfree = statp->f_bavail = |
63 | (statp->f_blocks > be64_to_cpu(dp->d_bcount)) ? | 63 | (statp->f_blocks > be64_to_cpu(dp->d_bcount)) ? |
64 | (statp->f_blocks - be64_to_cpu(dp->d_bcount)) : 0; | 64 | (statp->f_blocks - be64_to_cpu(dp->d_bcount)) : 0; |
65 | } | 65 | } |
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c index 5d1a3b98a6e6..5d0ee8d492db 100644 --- a/fs/xfs/quota/xfs_qm_syscalls.c +++ b/fs/xfs/quota/xfs_qm_syscalls.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #include "xfs_buf_item.h" | 49 | #include "xfs_buf_item.h" |
50 | #include "xfs_utils.h" | 50 | #include "xfs_utils.h" |
51 | #include "xfs_qm.h" | 51 | #include "xfs_qm.h" |
52 | #include "xfs_trace.h" | ||
52 | 53 | ||
53 | #ifdef DEBUG | 54 | #ifdef DEBUG |
54 | # define qdprintk(s, args...) cmn_err(CE_DEBUG, s, ## args) | 55 | # define qdprintk(s, args...) cmn_err(CE_DEBUG, s, ## args) |
@@ -496,7 +497,6 @@ xfs_qm_scall_setqlim( | |||
496 | ASSERT(error != ENOENT); | 497 | ASSERT(error != ENOENT); |
497 | return (error); | 498 | return (error); |
498 | } | 499 | } |
499 | xfs_dqtrace_entry(dqp, "Q_SETQLIM: AFT DQGET"); | ||
500 | xfs_trans_dqjoin(tp, dqp); | 500 | xfs_trans_dqjoin(tp, dqp); |
501 | ddq = &dqp->q_core; | 501 | ddq = &dqp->q_core; |
502 | 502 | ||
@@ -602,7 +602,6 @@ xfs_qm_scall_setqlim( | |||
602 | dqp->dq_flags |= XFS_DQ_DIRTY; | 602 | dqp->dq_flags |= XFS_DQ_DIRTY; |
603 | xfs_trans_log_dquot(tp, dqp); | 603 | xfs_trans_log_dquot(tp, dqp); |
604 | 604 | ||
605 | xfs_dqtrace_entry(dqp, "Q_SETQLIM: COMMIT"); | ||
606 | error = xfs_trans_commit(tp, 0); | 605 | error = xfs_trans_commit(tp, 0); |
607 | xfs_qm_dqprint(dqp); | 606 | xfs_qm_dqprint(dqp); |
608 | xfs_qm_dqrele(dqp); | 607 | xfs_qm_dqrele(dqp); |
@@ -630,7 +629,6 @@ xfs_qm_scall_getquota( | |||
630 | return (error); | 629 | return (error); |
631 | } | 630 | } |
632 | 631 | ||
633 | xfs_dqtrace_entry(dqp, "Q_GETQUOTA SUCCESS"); | ||
634 | /* | 632 | /* |
635 | * If everything's NULL, this dquot doesn't quite exist as far as | 633 | * If everything's NULL, this dquot doesn't quite exist as far as |
636 | * our utility programs are concerned. | 634 | * our utility programs are concerned. |
@@ -893,7 +891,7 @@ xfs_qm_dqrele_all_inodes( | |||
893 | uint flags) | 891 | uint flags) |
894 | { | 892 | { |
895 | ASSERT(mp->m_quotainfo); | 893 | ASSERT(mp->m_quotainfo); |
896 | xfs_inode_ag_iterator(mp, xfs_dqrele_inode, flags, XFS_ICI_NO_TAG); | 894 | xfs_inode_ag_iterator(mp, xfs_dqrele_inode, flags, XFS_ICI_NO_TAG, 0); |
897 | } | 895 | } |
898 | 896 | ||
899 | /*------------------------------------------------------------------------*/ | 897 | /*------------------------------------------------------------------------*/ |
@@ -1194,9 +1192,9 @@ xfs_qm_internalqcheck( | |||
1194 | if (! XFS_IS_QUOTA_ON(mp)) | 1192 | if (! XFS_IS_QUOTA_ON(mp)) |
1195 | return XFS_ERROR(ESRCH); | 1193 | return XFS_ERROR(ESRCH); |
1196 | 1194 | ||
1197 | xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE | XFS_LOG_SYNC); | 1195 | xfs_log_force(mp, XFS_LOG_SYNC); |
1198 | XFS_bflush(mp->m_ddev_targp); | 1196 | XFS_bflush(mp->m_ddev_targp); |
1199 | xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE | XFS_LOG_SYNC); | 1197 | xfs_log_force(mp, XFS_LOG_SYNC); |
1200 | XFS_bflush(mp->m_ddev_targp); | 1198 | XFS_bflush(mp->m_ddev_targp); |
1201 | 1199 | ||
1202 | mutex_lock(&qcheck_lock); | 1200 | mutex_lock(&qcheck_lock); |
diff --git a/fs/xfs/quota/xfs_trans_dquot.c b/fs/xfs/quota/xfs_trans_dquot.c index 97ac9640be98..c3ab75cb1d9a 100644 --- a/fs/xfs/quota/xfs_trans_dquot.c +++ b/fs/xfs/quota/xfs_trans_dquot.c | |||
@@ -589,12 +589,18 @@ xfs_trans_unreserve_and_mod_dquots( | |||
589 | } | 589 | } |
590 | } | 590 | } |
591 | 591 | ||
592 | STATIC int | 592 | STATIC void |
593 | xfs_quota_error(uint flags) | 593 | xfs_quota_warn( |
594 | struct xfs_mount *mp, | ||
595 | struct xfs_dquot *dqp, | ||
596 | int type) | ||
594 | { | 597 | { |
595 | if (flags & XFS_QMOPT_ENOSPC) | 598 | /* no warnings for project quotas - we just return ENOSPC later */ |
596 | return ENOSPC; | 599 | if (dqp->dq_flags & XFS_DQ_PROJ) |
597 | return EDQUOT; | 600 | return; |
601 | quota_send_warning((dqp->dq_flags & XFS_DQ_USER) ? USRQUOTA : GRPQUOTA, | ||
602 | be32_to_cpu(dqp->q_core.d_id), mp->m_super->s_dev, | ||
603 | type); | ||
598 | } | 604 | } |
599 | 605 | ||
600 | /* | 606 | /* |
@@ -612,7 +618,6 @@ xfs_trans_dqresv( | |||
612 | long ninos, | 618 | long ninos, |
613 | uint flags) | 619 | uint flags) |
614 | { | 620 | { |
615 | int error; | ||
616 | xfs_qcnt_t hardlimit; | 621 | xfs_qcnt_t hardlimit; |
617 | xfs_qcnt_t softlimit; | 622 | xfs_qcnt_t softlimit; |
618 | time_t timer; | 623 | time_t timer; |
@@ -649,7 +654,6 @@ xfs_trans_dqresv( | |||
649 | warnlimit = XFS_QI_RTBWARNLIMIT(dqp->q_mount); | 654 | warnlimit = XFS_QI_RTBWARNLIMIT(dqp->q_mount); |
650 | resbcountp = &dqp->q_res_rtbcount; | 655 | resbcountp = &dqp->q_res_rtbcount; |
651 | } | 656 | } |
652 | error = 0; | ||
653 | 657 | ||
654 | if ((flags & XFS_QMOPT_FORCE_RES) == 0 && | 658 | if ((flags & XFS_QMOPT_FORCE_RES) == 0 && |
655 | dqp->q_core.d_id && | 659 | dqp->q_core.d_id && |
@@ -667,18 +671,20 @@ xfs_trans_dqresv( | |||
667 | * nblks. | 671 | * nblks. |
668 | */ | 672 | */ |
669 | if (hardlimit > 0ULL && | 673 | if (hardlimit > 0ULL && |
670 | (hardlimit <= nblks + *resbcountp)) { | 674 | hardlimit <= nblks + *resbcountp) { |
671 | error = xfs_quota_error(flags); | 675 | xfs_quota_warn(mp, dqp, QUOTA_NL_BHARDWARN); |
672 | goto error_return; | 676 | goto error_return; |
673 | } | 677 | } |
674 | |||
675 | if (softlimit > 0ULL && | 678 | if (softlimit > 0ULL && |
676 | (softlimit <= nblks + *resbcountp)) { | 679 | softlimit <= nblks + *resbcountp) { |
677 | if ((timer != 0 && get_seconds() > timer) || | 680 | if ((timer != 0 && get_seconds() > timer) || |
678 | (warns != 0 && warns >= warnlimit)) { | 681 | (warns != 0 && warns >= warnlimit)) { |
679 | error = xfs_quota_error(flags); | 682 | xfs_quota_warn(mp, dqp, |
683 | QUOTA_NL_BSOFTLONGWARN); | ||
680 | goto error_return; | 684 | goto error_return; |
681 | } | 685 | } |
686 | |||
687 | xfs_quota_warn(mp, dqp, QUOTA_NL_BSOFTWARN); | ||
682 | } | 688 | } |
683 | } | 689 | } |
684 | if (ninos > 0) { | 690 | if (ninos > 0) { |
@@ -692,15 +698,19 @@ xfs_trans_dqresv( | |||
692 | softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit); | 698 | softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit); |
693 | if (!softlimit) | 699 | if (!softlimit) |
694 | softlimit = q->qi_isoftlimit; | 700 | softlimit = q->qi_isoftlimit; |
701 | |||
695 | if (hardlimit > 0ULL && count >= hardlimit) { | 702 | if (hardlimit > 0ULL && count >= hardlimit) { |
696 | error = xfs_quota_error(flags); | 703 | xfs_quota_warn(mp, dqp, QUOTA_NL_IHARDWARN); |
697 | goto error_return; | 704 | goto error_return; |
698 | } else if (softlimit > 0ULL && count >= softlimit) { | 705 | } |
699 | if ((timer != 0 && get_seconds() > timer) || | 706 | if (softlimit > 0ULL && count >= softlimit) { |
707 | if ((timer != 0 && get_seconds() > timer) || | ||
700 | (warns != 0 && warns >= warnlimit)) { | 708 | (warns != 0 && warns >= warnlimit)) { |
701 | error = xfs_quota_error(flags); | 709 | xfs_quota_warn(mp, dqp, |
710 | QUOTA_NL_ISOFTLONGWARN); | ||
702 | goto error_return; | 711 | goto error_return; |
703 | } | 712 | } |
713 | xfs_quota_warn(mp, dqp, QUOTA_NL_ISOFTWARN); | ||
704 | } | 714 | } |
705 | } | 715 | } |
706 | } | 716 | } |
@@ -736,9 +746,14 @@ xfs_trans_dqresv( | |||
736 | ASSERT(dqp->q_res_rtbcount >= be64_to_cpu(dqp->q_core.d_rtbcount)); | 746 | ASSERT(dqp->q_res_rtbcount >= be64_to_cpu(dqp->q_core.d_rtbcount)); |
737 | ASSERT(dqp->q_res_icount >= be64_to_cpu(dqp->q_core.d_icount)); | 747 | ASSERT(dqp->q_res_icount >= be64_to_cpu(dqp->q_core.d_icount)); |
738 | 748 | ||
749 | xfs_dqunlock(dqp); | ||
750 | return 0; | ||
751 | |||
739 | error_return: | 752 | error_return: |
740 | xfs_dqunlock(dqp); | 753 | xfs_dqunlock(dqp); |
741 | return error; | 754 | if (flags & XFS_QMOPT_ENOSPC) |
755 | return ENOSPC; | ||
756 | return EDQUOT; | ||
742 | } | 757 | } |
743 | 758 | ||
744 | 759 | ||