1 /*
2  * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of version 2 of the GNU General Public License as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it would be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  *
12  * Further, this software is distributed without any warranty that it is
13  * free of the rightful claim of any third person regarding infringement
14  * or the like.	 Any license provided herein, whether implied or
15  * otherwise, applies only to this software file.  Patent licenses, if
16  * any, provided herein do not apply to combinations of this program with
17  * other software, or any other product whatsoever.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write the Free Software Foundation, Inc., 59
21  * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22  *
23  * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24  * Mountain View, CA  94043, or:
25  *
26  * http://www.sgi.com
27  *
28  * For further information regarding this notice, see:
29  *
30  * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31  */
32 
33 #include "xfs.h"
34 #include "xfs_fs.h"
35 #include "xfs_inum.h"
36 #include "xfs_log.h"
37 #include "xfs_trans.h"
38 #include "xfs_sb.h"
39 #include "xfs_ag.h"
40 #include "xfs_dir.h"
41 #include "xfs_dir2.h"
42 #include "xfs_alloc.h"
43 #include "xfs_dmapi.h"
44 #include "xfs_quota.h"
45 #include "xfs_mount.h"
46 #include "xfs_alloc_btree.h"
47 #include "xfs_bmap_btree.h"
48 #include "xfs_ialloc_btree.h"
49 #include "xfs_btree.h"
50 #include "xfs_ialloc.h"
51 #include "xfs_attr_sf.h"
52 #include "xfs_dir_sf.h"
53 #include "xfs_dir2_sf.h"
54 #include "xfs_dinode.h"
55 #include "xfs_inode.h"
56 #include "xfs_bmap.h"
57 #include "xfs_bit.h"
58 #include "xfs_rtalloc.h"
59 #include "xfs_error.h"
60 #include "xfs_itable.h"
61 #include "xfs_rw.h"
62 #include "xfs_acl.h"
63 #include "xfs_cap.h"
64 #include "xfs_mac.h"
65 #include "xfs_attr.h"
66 #include "xfs_buf_item.h"
67 #include "xfs_trans_space.h"
68 #include "xfs_trans_priv.h"
69 
70 #include "xfs_qm.h"
71 
72 
73 /*
74    LOCK ORDER
75 
76    inode lock		    (ilock)
77    dquot hash-chain lock    (hashlock)
78    xqm dquot freelist lock  (freelistlock
79    mount's dquot list lock  (mplistlock)
80    user dquot lock - lock ordering among dquots is based on the uid or gid
81    group dquot lock - similar to udquots. Between the two dquots, the udquot
82 		      has to be locked first.
83    pin lock - the dquot lock must be held to take this lock.
84    flush lock - ditto.
85 */
86 
87 STATIC void		xfs_qm_dqflush_done(xfs_buf_t *, xfs_dq_logitem_t *);
88 
89 #ifdef DEBUG
90 xfs_buftarg_t *xfs_dqerror_target;
91 int xfs_do_dqerror;
92 int xfs_dqreq_num;
93 int xfs_dqerror_mod = 33;
94 #endif
95 
96 /*
97  * Allocate and initialize a dquot. We don't always allocate fresh memory;
98  * we try to reclaim a free dquot if the number of incore dquots are above
99  * a threshold.
100  * The only field inside the core that gets initialized at this point
101  * is the d_id field. The idea is to fill in the entire q_core
102  * when we read in the on disk dquot.
103  */
104 xfs_dquot_t *
xfs_qm_dqinit(xfs_mount_t * mp,xfs_dqid_t id,uint type)105 xfs_qm_dqinit(
106 	xfs_mount_t  *mp,
107 	xfs_dqid_t   id,
108 	uint	     type)
109 {
110 	xfs_dquot_t	*dqp;
111 	boolean_t	brandnewdquot;
112 
113 	brandnewdquot = xfs_qm_dqalloc_incore(&dqp);
114 	dqp->dq_flags = type;
115 	INT_SET(dqp->q_core.d_id, ARCH_CONVERT, id);
116 	dqp->q_mount = mp;
117 
118 	/*
119 	 * No need to re-initialize these if this is a reclaimed dquot.
120 	 */
121 	if (brandnewdquot) {
122 		dqp->dq_flnext = dqp->dq_flprev = dqp;
123 		mutex_init(&dqp->q_qlock,  MUTEX_DEFAULT, "xdq");
124 		initnsema(&dqp->q_flock, 1, "fdq");
125 		sv_init(&dqp->q_pinwait, SV_DEFAULT, "pdq");
126 
127 #ifdef XFS_DQUOT_TRACE
128 		dqp->q_trace = ktrace_alloc(DQUOT_TRACE_SIZE, KM_SLEEP);
129 		xfs_dqtrace_entry(dqp, "DQINIT");
130 #endif
131 	} else {
132 		/*
133 		 * Only the q_core portion was zeroed in dqreclaim_one().
134 		 * So, we need to reset others.
135 		 */
136 		 dqp->q_nrefs = 0;
137 		 dqp->q_blkno = 0;
138 		 dqp->MPL_NEXT = dqp->HL_NEXT = NULL;
139 		 dqp->HL_PREVP = dqp->MPL_PREVP = NULL;
140 		 dqp->q_bufoffset = 0;
141 		 dqp->q_fileoffset = 0;
142 		 dqp->q_transp = NULL;
143 		 dqp->q_gdquot = NULL;
144 		 dqp->q_res_bcount = 0;
145 		 dqp->q_res_icount = 0;
146 		 dqp->q_res_rtbcount = 0;
147 		 dqp->q_pincount = 0;
148 		 dqp->q_hash = NULL;
149 		 ASSERT(dqp->dq_flnext == dqp->dq_flprev);
150 
151 #ifdef XFS_DQUOT_TRACE
152 		 ASSERT(dqp->q_trace);
153 		 xfs_dqtrace_entry(dqp, "DQRECLAIMED_INIT");
154 #endif
155 	 }
156 
157 	/*
158 	 * log item gets initialized later
159 	 */
160 	return (dqp);
161 }
162 
163 /*
164  * This is called to free all the memory associated with a dquot
165  */
166 void
xfs_qm_dqdestroy(xfs_dquot_t * dqp)167 xfs_qm_dqdestroy(
168 	xfs_dquot_t	*dqp)
169 {
170 	ASSERT(! XFS_DQ_IS_ON_FREELIST(dqp));
171 
172 	mutex_destroy(&dqp->q_qlock);
173 	freesema(&dqp->q_flock);
174 	sv_destroy(&dqp->q_pinwait);
175 
176 #ifdef XFS_DQUOT_TRACE
177 	if (dqp->q_trace)
178 	     ktrace_free(dqp->q_trace);
179 	dqp->q_trace = NULL;
180 #endif
181 	kmem_zone_free(xfs_Gqm->qm_dqzone, dqp);
182 	atomic_dec(&xfs_Gqm->qm_totaldquots);
183 }
184 
185 /*
186  * This is what a 'fresh' dquot inside a dquot chunk looks like on disk.
187  */
188 STATIC void
xfs_qm_dqinit_core(xfs_dqid_t id,uint type,xfs_dqblk_t * d)189 xfs_qm_dqinit_core(
190 	xfs_dqid_t	id,
191 	uint		type,
192 	xfs_dqblk_t	*d)
193 {
194 	/*
195 	 * Caller has zero'd the entire dquot 'chunk' already.
196 	 */
197 	INT_SET(d->dd_diskdq.d_magic, ARCH_CONVERT, XFS_DQUOT_MAGIC);
198 	INT_SET(d->dd_diskdq.d_version, ARCH_CONVERT, XFS_DQUOT_VERSION);
199 	INT_SET(d->dd_diskdq.d_id, ARCH_CONVERT, id);
200 	INT_SET(d->dd_diskdq.d_flags, ARCH_CONVERT, type);
201 }
202 
203 
204 #ifdef XFS_DQUOT_TRACE
205 /*
206  * Dquot tracing for debugging.
207  */
208 /* ARGSUSED */
209 void
__xfs_dqtrace_entry(xfs_dquot_t * dqp,char * func,void * retaddr,xfs_inode_t * ip)210 __xfs_dqtrace_entry(
211 	xfs_dquot_t	*dqp,
212 	char		*func,
213 	void		*retaddr,
214 	xfs_inode_t	*ip)
215 {
216 	xfs_dquot_t	*udqp = NULL;
217 	xfs_ino_t	ino = 0;
218 
219 	ASSERT(dqp->q_trace);
220 	if (ip) {
221 		ino = ip->i_ino;
222 		udqp = ip->i_udquot;
223 	}
224 	ktrace_enter(dqp->q_trace,
225 		     (void *)(__psint_t)DQUOT_KTRACE_ENTRY,
226 		     (void *)func,
227 		     (void *)(__psint_t)dqp->q_nrefs,
228 		     (void *)(__psint_t)dqp->dq_flags,
229 		     (void *)(__psint_t)dqp->q_res_bcount,
230 		     (void *)(__psint_t)INT_GET(dqp->q_core.d_bcount,
231 						ARCH_CONVERT),
232 		     (void *)(__psint_t)INT_GET(dqp->q_core.d_icount,
233 						ARCH_CONVERT),
234 		     (void *)(__psint_t)INT_GET(dqp->q_core.d_blk_hardlimit,
235 						ARCH_CONVERT),
236 		     (void *)(__psint_t)INT_GET(dqp->q_core.d_blk_softlimit,
237 						ARCH_CONVERT),
238 		     (void *)(__psint_t)INT_GET(dqp->q_core.d_ino_hardlimit,
239 						ARCH_CONVERT),
240 		     (void *)(__psint_t)INT_GET(dqp->q_core.d_ino_softlimit,
241 						ARCH_CONVERT),
242 		     (void *)(__psint_t)INT_GET(dqp->q_core.d_id, ARCH_CONVERT),
243 		     (void *)(__psint_t)current_pid(),
244 		     (void *)(__psint_t)ino,
245 		     (void *)(__psint_t)retaddr,
246 		     (void *)(__psint_t)udqp);
247 	return;
248 }
249 #endif
250 
251 
252 /*
253  * If default limits are in force, push them into the dquot now.
254  * We overwrite the dquot limits only if they are zero and this
255  * is not the root dquot.
256  */
257 void
xfs_qm_adjust_dqlimits(xfs_mount_t * mp,xfs_disk_dquot_t * d)258 xfs_qm_adjust_dqlimits(
259 	xfs_mount_t		*mp,
260 	xfs_disk_dquot_t	*d)
261 {
262 	xfs_quotainfo_t		*q = mp->m_quotainfo;
263 
264 	ASSERT(!INT_ISZERO(d->d_id, ARCH_CONVERT));
265 
266 	if (q->qi_bsoftlimit && INT_ISZERO(d->d_blk_softlimit, ARCH_CONVERT))
267 		INT_SET(d->d_blk_softlimit, ARCH_CONVERT, q->qi_bsoftlimit);
268 	if (q->qi_bhardlimit && INT_ISZERO(d->d_blk_hardlimit, ARCH_CONVERT))
269 		INT_SET(d->d_blk_hardlimit, ARCH_CONVERT, q->qi_bhardlimit);
270 	if (q->qi_isoftlimit && INT_ISZERO(d->d_ino_softlimit, ARCH_CONVERT))
271 		INT_SET(d->d_ino_softlimit, ARCH_CONVERT, q->qi_isoftlimit);
272 	if (q->qi_ihardlimit && INT_ISZERO(d->d_ino_hardlimit, ARCH_CONVERT))
273 		INT_SET(d->d_ino_hardlimit, ARCH_CONVERT, q->qi_ihardlimit);
274 	if (q->qi_rtbsoftlimit &&
275 	    INT_ISZERO(d->d_rtb_softlimit, ARCH_CONVERT))
276 		INT_SET(d->d_rtb_softlimit, ARCH_CONVERT, q->qi_rtbsoftlimit);
277 	if (q->qi_rtbhardlimit &&
278 	    INT_ISZERO(d->d_rtb_hardlimit, ARCH_CONVERT))
279 		INT_SET(d->d_rtb_hardlimit, ARCH_CONVERT, q->qi_rtbhardlimit);
280 }
281 
282 /*
283  * Check the limits and timers of a dquot and start or reset timers
284  * if necessary.
285  * This gets called even when quota enforcement is OFF, which makes our
286  * life a little less complicated. (We just don't reject any quota
287  * reservations in that case, when enforcement is off).
288  * We also return 0 as the values of the timers in Q_GETQUOTA calls, when
289  * enforcement's off.
290  * In contrast, warnings are a little different in that they don't
291  * 'automatically' get started when limits get exceeded.
292  */
293 void
xfs_qm_adjust_dqtimers(xfs_mount_t * mp,xfs_disk_dquot_t * d)294 xfs_qm_adjust_dqtimers(
295 	xfs_mount_t		*mp,
296 	xfs_disk_dquot_t	*d)
297 {
298 	ASSERT(!INT_ISZERO(d->d_id, ARCH_CONVERT));
299 
300 #ifdef QUOTADEBUG
301 	if (INT_GET(d->d_blk_hardlimit, ARCH_CONVERT))
302 		ASSERT(INT_GET(d->d_blk_softlimit, ARCH_CONVERT) <=
303 			INT_GET(d->d_blk_hardlimit, ARCH_CONVERT));
304 	if (INT_GET(d->d_ino_hardlimit, ARCH_CONVERT))
305 		ASSERT(INT_GET(d->d_ino_softlimit, ARCH_CONVERT) <=
306 			INT_GET(d->d_ino_hardlimit, ARCH_CONVERT));
307 	if (INT_GET(d->d_rtb_hardlimit, ARCH_CONVERT))
308 		ASSERT(INT_GET(d->d_rtb_softlimit, ARCH_CONVERT) <=
309 			INT_GET(d->d_rtb_hardlimit, ARCH_CONVERT));
310 #endif
311 	if (INT_ISZERO(d->d_btimer, ARCH_CONVERT)) {
312 		if ((INT_GET(d->d_blk_softlimit, ARCH_CONVERT) &&
313 		    (INT_GET(d->d_bcount, ARCH_CONVERT) >=
314 				INT_GET(d->d_blk_softlimit, ARCH_CONVERT))) ||
315 		    (INT_GET(d->d_blk_hardlimit, ARCH_CONVERT) &&
316 		    (INT_GET(d->d_bcount, ARCH_CONVERT) >=
317 				INT_GET(d->d_blk_hardlimit, ARCH_CONVERT)))) {
318 			INT_SET(d->d_btimer, ARCH_CONVERT,
319 				get_seconds() + XFS_QI_BTIMELIMIT(mp));
320 		}
321 	} else {
322 		if ((INT_ISZERO(d->d_blk_softlimit, ARCH_CONVERT) ||
323 		    (INT_GET(d->d_bcount, ARCH_CONVERT) <
324 				INT_GET(d->d_blk_softlimit, ARCH_CONVERT))) &&
325 		    (INT_ISZERO(d->d_blk_hardlimit, ARCH_CONVERT) ||
326 		    (INT_GET(d->d_bcount, ARCH_CONVERT) <
327 				INT_GET(d->d_blk_hardlimit, ARCH_CONVERT)))) {
328 			INT_ZERO(d->d_btimer, ARCH_CONVERT);
329 		}
330 	}
331 
332 	if (INT_ISZERO(d->d_itimer, ARCH_CONVERT)) {
333 		if ((INT_GET(d->d_ino_softlimit, ARCH_CONVERT) &&
334 		    (INT_GET(d->d_icount, ARCH_CONVERT) >=
335 				INT_GET(d->d_ino_softlimit, ARCH_CONVERT))) ||
336 		    (INT_GET(d->d_ino_hardlimit, ARCH_CONVERT) &&
337 		    (INT_GET(d->d_icount, ARCH_CONVERT) >=
338 				INT_GET(d->d_ino_hardlimit, ARCH_CONVERT)))) {
339 			INT_SET(d->d_itimer, ARCH_CONVERT,
340 				get_seconds() + XFS_QI_ITIMELIMIT(mp));
341 		}
342 	} else {
343 		if ((INT_ISZERO(d->d_ino_softlimit, ARCH_CONVERT) ||
344 		    (INT_GET(d->d_icount, ARCH_CONVERT) <
345 				INT_GET(d->d_ino_softlimit, ARCH_CONVERT)))  &&
346 		    (INT_ISZERO(d->d_ino_hardlimit, ARCH_CONVERT) ||
347 		    (INT_GET(d->d_icount, ARCH_CONVERT) <
348 				INT_GET(d->d_ino_hardlimit, ARCH_CONVERT)))) {
349 			INT_ZERO(d->d_itimer, ARCH_CONVERT);
350 		}
351 	}
352 
353 	if (INT_ISZERO(d->d_rtbtimer, ARCH_CONVERT)) {
354 		if ((INT_GET(d->d_rtb_softlimit, ARCH_CONVERT) &&
355 		    (INT_GET(d->d_rtbcount, ARCH_CONVERT) >=
356 				INT_GET(d->d_rtb_softlimit, ARCH_CONVERT))) ||
357 		    (INT_GET(d->d_rtb_hardlimit, ARCH_CONVERT) &&
358 		    (INT_GET(d->d_rtbcount, ARCH_CONVERT) >=
359 				INT_GET(d->d_rtb_hardlimit, ARCH_CONVERT)))) {
360 			INT_SET(d->d_rtbtimer, ARCH_CONVERT,
361 				get_seconds() + XFS_QI_RTBTIMELIMIT(mp));
362 		}
363 	} else {
364 		if ((INT_ISZERO(d->d_rtb_softlimit, ARCH_CONVERT) ||
365 		    (INT_GET(d->d_rtbcount, ARCH_CONVERT) <
366 				INT_GET(d->d_rtb_softlimit, ARCH_CONVERT))) &&
367 		    (INT_ISZERO(d->d_rtb_hardlimit, ARCH_CONVERT) ||
368 		    (INT_GET(d->d_rtbcount, ARCH_CONVERT) <
369 				INT_GET(d->d_rtb_hardlimit, ARCH_CONVERT)))) {
370 			INT_ZERO(d->d_rtbtimer, ARCH_CONVERT);
371 		}
372 	}
373 }
374 
375 /*
376  * Increment or reset warnings of a given dquot.
377  */
378 int
xfs_qm_dqwarn(xfs_disk_dquot_t * d,uint flags)379 xfs_qm_dqwarn(
380 	xfs_disk_dquot_t	*d,
381 	uint			flags)
382 {
383 	int	warned;
384 
385 	/*
386 	 * root's limits are not real limits.
387 	 */
388 	if (INT_ISZERO(d->d_id, ARCH_CONVERT))
389 		return (0);
390 
391 	warned = 0;
392 	if (INT_GET(d->d_blk_softlimit, ARCH_CONVERT) &&
393 	    (INT_GET(d->d_bcount, ARCH_CONVERT) >=
394 	     INT_GET(d->d_blk_softlimit, ARCH_CONVERT))) {
395 		if (flags & XFS_QMOPT_DOWARN) {
396 			INT_MOD(d->d_bwarns, ARCH_CONVERT, +1);
397 			warned++;
398 		}
399 	} else {
400 		if (INT_ISZERO(d->d_blk_softlimit, ARCH_CONVERT) ||
401 		    (INT_GET(d->d_bcount, ARCH_CONVERT) <
402 		     INT_GET(d->d_blk_softlimit, ARCH_CONVERT))) {
403 			INT_ZERO(d->d_bwarns, ARCH_CONVERT);
404 		}
405 	}
406 
407 	if (INT_GET(d->d_ino_softlimit, ARCH_CONVERT) > 0 &&
408 	    (INT_GET(d->d_icount, ARCH_CONVERT) >=
409 	     INT_GET(d->d_ino_softlimit, ARCH_CONVERT))) {
410 		if (flags & XFS_QMOPT_DOWARN) {
411 			INT_MOD(d->d_iwarns, ARCH_CONVERT, +1);
412 			warned++;
413 		}
414 	} else {
415 		if ((INT_ISZERO(d->d_ino_softlimit, ARCH_CONVERT)) ||
416 		    (INT_GET(d->d_icount, ARCH_CONVERT) <
417 		     INT_GET(d->d_ino_softlimit, ARCH_CONVERT))) {
418 			INT_ZERO(d->d_iwarns, ARCH_CONVERT);
419 		}
420 	}
421 #ifdef QUOTADEBUG
422 	if (INT_GET(d->d_iwarns, ARCH_CONVERT))
423 		cmn_err(CE_DEBUG,
424 			"--------@@Inode warnings running : %Lu >= %Lu",
425 			INT_GET(d->d_icount, ARCH_CONVERT),
426 			INT_GET(d->d_ino_softlimit, ARCH_CONVERT));
427 	if (INT_GET(d->d_bwarns, ARCH_CONVERT))
428 		cmn_err(CE_DEBUG,
429 			"--------@@Blks warnings running : %Lu >= %Lu",
430 			INT_GET(d->d_bcount, ARCH_CONVERT),
431 			INT_GET(d->d_blk_softlimit, ARCH_CONVERT));
432 #endif
433 	return (warned);
434 }
435 
436 
437 /*
438  * initialize a buffer full of dquots and log the whole thing
439  */
440 STATIC void
xfs_qm_init_dquot_blk(xfs_trans_t * tp,xfs_mount_t * mp,xfs_dqid_t id,uint type,xfs_buf_t * bp)441 xfs_qm_init_dquot_blk(
442 	xfs_trans_t	*tp,
443 	xfs_mount_t	*mp,
444 	xfs_dqid_t	id,
445 	uint		type,
446 	xfs_buf_t	*bp)
447 {
448 	xfs_dqblk_t	*d;
449 	int		curid, i;
450 
451 	ASSERT(tp);
452 	ASSERT(XFS_BUF_ISBUSY(bp));
453 	ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);
454 
455 	d = (xfs_dqblk_t *)XFS_BUF_PTR(bp);
456 
457 	/*
458 	 * ID of the first dquot in the block - id's are zero based.
459 	 */
460 	curid = id - (id % XFS_QM_DQPERBLK(mp));
461 	ASSERT(curid >= 0);
462 	memset(d, 0, BBTOB(XFS_QI_DQCHUNKLEN(mp)));
463 	for (i = 0; i < XFS_QM_DQPERBLK(mp); i++, d++, curid++)
464 		xfs_qm_dqinit_core(curid, type, d);
465 	xfs_trans_dquot_buf(tp, bp,
466 			    type & XFS_DQ_USER ?
467 			    XFS_BLI_UDQUOT_BUF :
468 			    XFS_BLI_GDQUOT_BUF);
469 	xfs_trans_log_buf(tp, bp, 0, BBTOB(XFS_QI_DQCHUNKLEN(mp)) - 1);
470 }
471 
472 
473 
474 /*
475  * Allocate a block and fill it with dquots.
476  * This is called when the bmapi finds a hole.
477  */
478 STATIC int
xfs_qm_dqalloc(xfs_trans_t * tp,xfs_mount_t * mp,xfs_dquot_t * dqp,xfs_inode_t * quotip,xfs_fileoff_t offset_fsb,xfs_buf_t ** O_bpp)479 xfs_qm_dqalloc(
480 	xfs_trans_t	*tp,
481 	xfs_mount_t	*mp,
482 	xfs_dquot_t	*dqp,
483 	xfs_inode_t	*quotip,
484 	xfs_fileoff_t	offset_fsb,
485 	xfs_buf_t	**O_bpp)
486 {
487 	xfs_fsblock_t	firstblock;
488 	xfs_bmap_free_t flist;
489 	xfs_bmbt_irec_t map;
490 	int		nmaps, error, committed;
491 	xfs_buf_t	*bp;
492 
493 	ASSERT(tp != NULL);
494 	xfs_dqtrace_entry(dqp, "DQALLOC");
495 
496 	/*
497 	 * Initialize the bmap freelist prior to calling bmapi code.
498 	 */
499 	XFS_BMAP_INIT(&flist, &firstblock);
500 	xfs_ilock(quotip, XFS_ILOCK_EXCL);
501 	/*
502 	 * Return if this type of quotas is turned off while we didn't
503 	 * have an inode lock
504 	 */
505 	if (XFS_IS_THIS_QUOTA_OFF(dqp)) {
506 		xfs_iunlock(quotip, XFS_ILOCK_EXCL);
507 		return (ESRCH);
508 	}
509 
510 	/*
511 	 * xfs_trans_commit normally decrements the vnode ref count
512 	 * when it unlocks the inode. Since we want to keep the quota
513 	 * inode around, we bump the vnode ref count now.
514 	 */
515 	VN_HOLD(XFS_ITOV(quotip));
516 
517 	xfs_trans_ijoin(tp, quotip, XFS_ILOCK_EXCL);
518 	nmaps = 1;
519 	if ((error = xfs_bmapi(tp, quotip,
520 			      offset_fsb, XFS_DQUOT_CLUSTER_SIZE_FSB,
521 			      XFS_BMAPI_METADATA | XFS_BMAPI_WRITE,
522 			      &firstblock,
523 			      XFS_QM_DQALLOC_SPACE_RES(mp),
524 			      &map, &nmaps, &flist))) {
525 		goto error0;
526 	}
527 	ASSERT(map.br_blockcount == XFS_DQUOT_CLUSTER_SIZE_FSB);
528 	ASSERT(nmaps == 1);
529 	ASSERT((map.br_startblock != DELAYSTARTBLOCK) &&
530 	       (map.br_startblock != HOLESTARTBLOCK));
531 
532 	/*
533 	 * Keep track of the blkno to save a lookup later
534 	 */
535 	dqp->q_blkno = XFS_FSB_TO_DADDR(mp, map.br_startblock);
536 
537 	/* now we can just get the buffer (there's nothing to read yet) */
538 	bp = xfs_trans_get_buf(tp, mp->m_ddev_targp,
539 			       dqp->q_blkno,
540 			       XFS_QI_DQCHUNKLEN(mp),
541 			       0);
542 	if (!bp || (error = XFS_BUF_GETERROR(bp)))
543 		goto error1;
544 	/*
545 	 * Make a chunk of dquots out of this buffer and log
546 	 * the entire thing.
547 	 */
548 	xfs_qm_init_dquot_blk(tp, mp, INT_GET(dqp->q_core.d_id, ARCH_CONVERT),
549 			      dqp->dq_flags & (XFS_DQ_USER|XFS_DQ_GROUP),
550 			      bp);
551 
552 	if ((error = xfs_bmap_finish(&tp, &flist, firstblock, &committed))) {
553 		goto error1;
554 	}
555 
556 	*O_bpp = bp;
557 	return 0;
558 
559       error1:
560 	xfs_bmap_cancel(&flist);
561       error0:
562 	xfs_iunlock(quotip, XFS_ILOCK_EXCL);
563 
564 	return (error);
565 }
566 
567 /*
568  * Maps a dquot to the buffer containing its on-disk version.
569  * This returns a ptr to the buffer containing the on-disk dquot
570  * in the bpp param, and a ptr to the on-disk dquot within that buffer
571  */
572 STATIC int
xfs_qm_dqtobp(xfs_trans_t * tp,xfs_dquot_t * dqp,xfs_disk_dquot_t ** O_ddpp,xfs_buf_t ** O_bpp,uint flags)573 xfs_qm_dqtobp(
574 	xfs_trans_t		*tp,
575 	xfs_dquot_t		*dqp,
576 	xfs_disk_dquot_t	**O_ddpp,
577 	xfs_buf_t		**O_bpp,
578 	uint			flags)
579 {
580 	xfs_bmbt_irec_t map;
581 	int		nmaps, error;
582 	xfs_buf_t	*bp;
583 	xfs_inode_t	*quotip;
584 	xfs_mount_t	*mp;
585 	xfs_disk_dquot_t *ddq;
586 	xfs_dqid_t	id;
587 	boolean_t	newdquot;
588 
589 	mp = dqp->q_mount;
590 	id = INT_GET(dqp->q_core.d_id, ARCH_CONVERT);
591 	nmaps = 1;
592 	newdquot = B_FALSE;
593 
594 	/*
595 	 * If we don't know where the dquot lives, find out.
596 	 */
597 	if (dqp->q_blkno == (xfs_daddr_t) 0) {
598 		/* We use the id as an index */
599 		dqp->q_fileoffset = (xfs_fileoff_t) ((uint)id /
600 						     XFS_QM_DQPERBLK(mp));
601 		nmaps = 1;
602 		quotip = XFS_DQ_TO_QIP(dqp);
603 		xfs_ilock(quotip, XFS_ILOCK_SHARED);
604 		/*
605 		 * Return if this type of quotas is turned off while we didn't
606 		 * have an inode lock
607 		 */
608 		if (XFS_IS_THIS_QUOTA_OFF(dqp)) {
609 			xfs_iunlock(quotip, XFS_ILOCK_SHARED);
610 			return (ESRCH);
611 		}
612 		/*
613 		 * Find the block map; no allocations yet
614 		 */
615 		error = xfs_bmapi(NULL, quotip, dqp->q_fileoffset,
616 				  XFS_DQUOT_CLUSTER_SIZE_FSB,
617 				  XFS_BMAPI_METADATA,
618 				  NULL, 0, &map, &nmaps, NULL);
619 
620 		xfs_iunlock(quotip, XFS_ILOCK_SHARED);
621 		if (error)
622 			return (error);
623 		ASSERT(nmaps == 1);
624 		ASSERT(map.br_blockcount == 1);
625 
626 		/*
627 		 * offset of dquot in the (fixed sized) dquot chunk.
628 		 */
629 		dqp->q_bufoffset = (id % XFS_QM_DQPERBLK(mp)) *
630 			sizeof(xfs_dqblk_t);
631 		if (map.br_startblock == HOLESTARTBLOCK) {
632 			/*
633 			 * We don't allocate unless we're asked to
634 			 */
635 			if (!(flags & XFS_QMOPT_DQALLOC))
636 				return (ENOENT);
637 
638 			ASSERT(tp);
639 			if ((error = xfs_qm_dqalloc(tp, mp, dqp, quotip,
640 						dqp->q_fileoffset, &bp)))
641 				return (error);
642 			newdquot = B_TRUE;
643 		} else {
644 			/*
645 			 * store the blkno etc so that we don't have to do the
646 			 * mapping all the time
647 			 */
648 			dqp->q_blkno = XFS_FSB_TO_DADDR(mp, map.br_startblock);
649 		}
650 	}
651 	ASSERT(dqp->q_blkno != DELAYSTARTBLOCK);
652 	ASSERT(dqp->q_blkno != HOLESTARTBLOCK);
653 
654 	/*
655 	 * Read in the buffer, unless we've just done the allocation
656 	 * (in which case we already have the buf).
657 	 */
658 	if (! newdquot) {
659 		xfs_dqtrace_entry(dqp, "DQTOBP READBUF");
660 		if ((error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp,
661 					       dqp->q_blkno,
662 					       XFS_QI_DQCHUNKLEN(mp),
663 					       0, &bp))) {
664 			return (error);
665 		}
666 		if (error || !bp)
667 			return XFS_ERROR(error);
668 	}
669 	ASSERT(XFS_BUF_ISBUSY(bp));
670 	ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);
671 
672 	/*
673 	 * calculate the location of the dquot inside the buffer.
674 	 */
675 	ddq = (xfs_disk_dquot_t *)((char *)XFS_BUF_PTR(bp) + dqp->q_bufoffset);
676 
677 	/*
678 	 * A simple sanity check in case we got a corrupted dquot...
679 	 */
680 	if (xfs_qm_dqcheck(ddq, id,
681 			   dqp->dq_flags & (XFS_DQ_USER|XFS_DQ_GROUP),
682 			   flags & (XFS_QMOPT_DQREPAIR|XFS_QMOPT_DOWARN),
683 			   "dqtobp")) {
684 		if (!(flags & XFS_QMOPT_DQREPAIR)) {
685 			xfs_trans_brelse(tp, bp);
686 			return XFS_ERROR(EIO);
687 		}
688 		XFS_BUF_BUSY(bp); /* We dirtied this */
689 	}
690 
691 	*O_bpp = bp;
692 	*O_ddpp = ddq;
693 
694 	return (0);
695 }
696 
697 
698 /*
699  * Read in the ondisk dquot using dqtobp() then copy it to an incore version,
700  * and release the buffer immediately.
701  *
702  */
703 /* ARGSUSED */
704 STATIC int
xfs_qm_dqread(xfs_trans_t * tp,xfs_dqid_t id,xfs_dquot_t * dqp,uint flags)705 xfs_qm_dqread(
706 	xfs_trans_t	*tp,
707 	xfs_dqid_t	id,
708 	xfs_dquot_t	*dqp,	/* dquot to get filled in */
709 	uint		flags)
710 {
711 	xfs_disk_dquot_t *ddqp;
712 	xfs_buf_t	 *bp;
713 	int		 error;
714 
715 	/*
716 	 * get a pointer to the on-disk dquot and the buffer containing it
717 	 * dqp already knows its own type (GROUP/USER).
718 	 */
719 	xfs_dqtrace_entry(dqp, "DQREAD");
720 	if ((error = xfs_qm_dqtobp(tp, dqp, &ddqp, &bp, flags))) {
721 		return (error);
722 	}
723 
724 	/* copy everything from disk dquot to the incore dquot */
725 	memcpy(&dqp->q_core, ddqp, sizeof(xfs_disk_dquot_t));
726 	ASSERT(INT_GET(dqp->q_core.d_id, ARCH_CONVERT) == id);
727 	xfs_qm_dquot_logitem_init(dqp);
728 
729 	/*
730 	 * Reservation counters are defined as reservation plus current usage
731 	 * to avoid having to add everytime.
732 	 */
733 	dqp->q_res_bcount = INT_GET(ddqp->d_bcount, ARCH_CONVERT);
734 	dqp->q_res_icount = INT_GET(ddqp->d_icount, ARCH_CONVERT);
735 	dqp->q_res_rtbcount = INT_GET(ddqp->d_rtbcount, ARCH_CONVERT);
736 
737 	/* Mark the buf so that this will stay incore a little longer */
738 	XFS_BUF_SET_VTYPE_REF(bp, B_FS_DQUOT, XFS_DQUOT_REF);
739 
740 	/*
741 	 * We got the buffer with a xfs_trans_read_buf() (in dqtobp())
742 	 * So we need to release with xfs_trans_brelse().
743 	 * The strategy here is identical to that of inodes; we lock
744 	 * the dquot in xfs_qm_dqget() before making it accessible to
745 	 * others. This is because dquots, like inodes, need a good level of
746 	 * concurrency, and we don't want to take locks on the entire buffers
747 	 * for dquot accesses.
748 	 * Note also that the dquot buffer may even be dirty at this point, if
749 	 * this particular dquot was repaired. We still aren't afraid to
750 	 * brelse it because we have the changes incore.
751 	 */
752 	ASSERT(XFS_BUF_ISBUSY(bp));
753 	ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);
754 	xfs_trans_brelse(tp, bp);
755 
756 	return (error);
757 }
758 
759 
760 /*
761  * allocate an incore dquot from the kernel heap,
762  * and fill its core with quota information kept on disk.
763  * If XFS_QMOPT_DQALLOC is set, it'll allocate a dquot on disk
764  * if it wasn't already allocated.
765  */
766 STATIC int
xfs_qm_idtodq(xfs_mount_t * mp,xfs_dqid_t id,uint type,uint flags,xfs_dquot_t ** O_dqpp)767 xfs_qm_idtodq(
768 	xfs_mount_t	*mp,
769 	xfs_dqid_t	id,	 /* gid or uid, depending on type */
770 	uint		type,	 /* UDQUOT or GDQUOT */
771 	uint		flags,	 /* DQALLOC, DQREPAIR */
772 	xfs_dquot_t	**O_dqpp)/* OUT : incore dquot, not locked */
773 {
774 	xfs_dquot_t	*dqp;
775 	int		error;
776 	xfs_trans_t	*tp;
777 	int		cancelflags=0;
778 
779 	dqp = xfs_qm_dqinit(mp, id, type);
780 	tp = NULL;
781 	if (flags & XFS_QMOPT_DQALLOC) {
782 		tp = xfs_trans_alloc(mp, XFS_TRANS_QM_DQALLOC);
783 		if ((error = xfs_trans_reserve(tp,
784 				       XFS_QM_DQALLOC_SPACE_RES(mp),
785 				       XFS_WRITE_LOG_RES(mp) +
786 					      BBTOB(XFS_QI_DQCHUNKLEN(mp)) - 1 +
787 					      128,
788 				       0,
789 				       XFS_TRANS_PERM_LOG_RES,
790 				       XFS_WRITE_LOG_COUNT))) {
791 			cancelflags = 0;
792 			goto error0;
793 		}
794 		cancelflags = XFS_TRANS_RELEASE_LOG_RES;
795 	}
796 
797 	/*
798 	 * Read it from disk; xfs_dqread() takes care of
799 	 * all the necessary initialization of dquot's fields (locks, etc)
800 	 */
801 	if ((error = xfs_qm_dqread(tp, id, dqp, flags))) {
802 		/*
803 		 * This can happen if quotas got turned off (ESRCH),
804 		 * or if the dquot didn't exist on disk and we ask to
805 		 * allocate (ENOENT).
806 		 */
807 		xfs_dqtrace_entry(dqp, "DQREAD FAIL");
808 		cancelflags |= XFS_TRANS_ABORT;
809 		goto error0;
810 	}
811 	if (tp) {
812 		if ((error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES,
813 					     NULL)))
814 			goto error1;
815 	}
816 
817 	*O_dqpp = dqp;
818 	return (0);
819 
820  error0:
821 	ASSERT(error);
822 	if (tp)
823 		xfs_trans_cancel(tp, cancelflags);
824  error1:
825 	xfs_qm_dqdestroy(dqp);
826 	*O_dqpp = NULL;
827 	return (error);
828 }
829 
830 /*
831  * Lookup a dquot in the incore dquot hashtable. We keep two separate
832  * hashtables for user and group dquots; and, these are global tables
833  * inside the XQM, not per-filesystem tables.
834  * The hash chain must be locked by caller, and it is left locked
835  * on return. Returning dquot is locked.
836  */
837 STATIC int
xfs_qm_dqlookup(xfs_mount_t * mp,xfs_dqid_t id,xfs_dqhash_t * qh,xfs_dquot_t ** O_dqpp)838 xfs_qm_dqlookup(
839 	xfs_mount_t		*mp,
840 	xfs_dqid_t		id,
841 	xfs_dqhash_t		*qh,
842 	xfs_dquot_t		**O_dqpp)
843 {
844 	xfs_dquot_t		*dqp;
845 	uint			flist_locked;
846 	xfs_dquot_t		*d;
847 
848 	ASSERT(XFS_DQ_IS_HASH_LOCKED(qh));
849 
850 	flist_locked = B_FALSE;
851 
852 	/*
853 	 * Traverse the hashchain looking for a match
854 	 */
855 	for (dqp = qh->qh_next; dqp != NULL; dqp = dqp->HL_NEXT) {
856 		/*
857 		 * We already have the hashlock. We don't need the
858 		 * dqlock to look at the id field of the dquot, since the
859 		 * id can't be modified without the hashlock anyway.
860 		 */
861 		if (INT_GET(dqp->q_core.d_id, ARCH_CONVERT) == id && dqp->q_mount == mp) {
862 			xfs_dqtrace_entry(dqp, "DQFOUND BY LOOKUP");
863 			/*
864 			 * All in core dquots must be on the dqlist of mp
865 			 */
866 			ASSERT(dqp->MPL_PREVP != NULL);
867 
868 			xfs_dqlock(dqp);
869 			if (dqp->q_nrefs == 0) {
870 				ASSERT (XFS_DQ_IS_ON_FREELIST(dqp));
871 				if (! xfs_qm_freelist_lock_nowait(xfs_Gqm)) {
872 					xfs_dqtrace_entry(dqp, "DQLOOKUP: WANT");
873 
874 					/*
875 					 * We may have raced with dqreclaim_one()
876 					 * (and lost). So, flag that we don't
877 					 * want the dquot to be reclaimed.
878 					 */
879 					dqp->dq_flags |= XFS_DQ_WANT;
880 					xfs_dqunlock(dqp);
881 					xfs_qm_freelist_lock(xfs_Gqm);
882 					xfs_dqlock(dqp);
883 					dqp->dq_flags &= ~(XFS_DQ_WANT);
884 				}
885 				flist_locked = B_TRUE;
886 			}
887 
888 			/*
889 			 * id couldn't have changed; we had the hashlock all
890 			 * along
891 			 */
892 			ASSERT(INT_GET(dqp->q_core.d_id, ARCH_CONVERT) == id);
893 
894 			if (flist_locked) {
895 				if (dqp->q_nrefs != 0) {
896 					xfs_qm_freelist_unlock(xfs_Gqm);
897 					flist_locked = B_FALSE;
898 				} else {
899 					/*
900 					 * take it off the freelist
901 					 */
902 					xfs_dqtrace_entry(dqp,
903 							"DQLOOKUP: TAKEOFF FL");
904 					XQM_FREELIST_REMOVE(dqp);
905 					/* xfs_qm_freelist_print(&(xfs_Gqm->
906 							qm_dqfreelist),
907 							"after removal"); */
908 				}
909 			}
910 
911 			/*
912 			 * grab a reference
913 			 */
914 			XFS_DQHOLD(dqp);
915 
916 			if (flist_locked)
917 				xfs_qm_freelist_unlock(xfs_Gqm);
918 			/*
919 			 * move the dquot to the front of the hashchain
920 			 */
921 			ASSERT(XFS_DQ_IS_HASH_LOCKED(qh));
922 			if (dqp->HL_PREVP != &qh->qh_next) {
923 				xfs_dqtrace_entry(dqp,
924 						  "DQLOOKUP: HASH MOVETOFRONT");
925 				if ((d = dqp->HL_NEXT))
926 					d->HL_PREVP = dqp->HL_PREVP;
927 				*(dqp->HL_PREVP) = d;
928 				d = qh->qh_next;
929 				d->HL_PREVP = &dqp->HL_NEXT;
930 				dqp->HL_NEXT = d;
931 				dqp->HL_PREVP = &qh->qh_next;
932 				qh->qh_next = dqp;
933 			}
934 			xfs_dqtrace_entry(dqp, "LOOKUP END");
935 			*O_dqpp = dqp;
936 			ASSERT(XFS_DQ_IS_HASH_LOCKED(qh));
937 			return (0);
938 		}
939 	}
940 
941 	*O_dqpp = NULL;
942 	ASSERT(XFS_DQ_IS_HASH_LOCKED(qh));
943 	return (1);
944 }
945 
946 /*
947  * Given the file system, inode OR id, and type (UDQUOT/GDQUOT), return a
948  * a locked dquot, doing an allocation (if requested) as needed.
949  * When both an inode and an id are given, the inode's id takes precedence.
950  * That is, if the id changes while we don't hold the ilock inside this
951  * function, the new dquot is returned, not necessarily the one requested
952  * in the id argument.
953  */
954 int
xfs_qm_dqget(xfs_mount_t * mp,xfs_inode_t * ip,xfs_dqid_t id,uint type,uint flags,xfs_dquot_t ** O_dqpp)955 xfs_qm_dqget(
956 	xfs_mount_t	*mp,
957 	xfs_inode_t	*ip,	  /* locked inode (optional) */
958 	xfs_dqid_t	id,	  /* gid or uid, depending on type */
959 	uint		type,	  /* UDQUOT or GDQUOT */
960 	uint		flags,	  /* DQALLOC, DQSUSER, DQREPAIR, DOWARN */
961 	xfs_dquot_t	**O_dqpp) /* OUT : locked incore dquot */
962 {
963 	xfs_dquot_t	*dqp;
964 	xfs_dqhash_t	*h;
965 	uint		version;
966 	int		error;
967 
968 	ASSERT(XFS_IS_QUOTA_RUNNING(mp));
969 	if ((! XFS_IS_UQUOTA_ON(mp) && type == XFS_DQ_USER) ||
970 	    (! XFS_IS_GQUOTA_ON(mp) && type == XFS_DQ_GROUP)) {
971 		return (ESRCH);
972 	}
973 	h = XFS_DQ_HASH(mp, id, type);
974 
975 #ifdef DEBUG
976 	if (xfs_do_dqerror) {
977 		if ((xfs_dqerror_target == mp->m_ddev_targp) &&
978 		    (xfs_dqreq_num++ % xfs_dqerror_mod) == 0) {
979 			cmn_err(CE_DEBUG, "Returning error in dqget");
980 			return (EIO);
981 		}
982 	}
983 #endif
984 
985  again:
986 
987 #ifdef DEBUG
988 	ASSERT(type == XFS_DQ_USER || type == XFS_DQ_GROUP);
989 	if (ip) {
990 		ASSERT(XFS_ISLOCKED_INODE_EXCL(ip));
991 		if (type == XFS_DQ_USER)
992 			ASSERT(ip->i_udquot == NULL);
993 		else
994 			ASSERT(ip->i_gdquot == NULL);
995 	}
996 #endif
997 	XFS_DQ_HASH_LOCK(h);
998 
999 	/*
1000 	 * Look in the cache (hashtable).
1001 	 * The chain is kept locked during lookup.
1002 	 */
1003 	if (xfs_qm_dqlookup(mp, id, h, O_dqpp) == 0) {
1004 		XQM_STATS_INC(xqmstats.xs_qm_dqcachehits);
1005 		/*
1006 		 * The dquot was found, moved to the front of the chain,
1007 		 * taken off the freelist if it was on it, and locked
1008 		 * at this point. Just unlock the hashchain and return.
1009 		 */
1010 		ASSERT(*O_dqpp);
1011 		ASSERT(XFS_DQ_IS_LOCKED(*O_dqpp));
1012 		XFS_DQ_HASH_UNLOCK(h);
1013 		xfs_dqtrace_entry(*O_dqpp, "DQGET DONE (FROM CACHE)");
1014 		return (0);	/* success */
1015 	}
1016 	XQM_STATS_INC(xqmstats.xs_qm_dqcachemisses);
1017 
1018 	/*
1019 	 * Dquot cache miss. We don't want to keep the inode lock across
1020 	 * a (potential) disk read. Also we don't want to deal with the lock
1021 	 * ordering between quotainode and this inode. OTOH, dropping the inode
1022 	 * lock here means dealing with a chown that can happen before
1023 	 * we re-acquire the lock.
1024 	 */
1025 	if (ip)
1026 		xfs_iunlock(ip, XFS_ILOCK_EXCL);
1027 	/*
1028 	 * Save the hashchain version stamp, and unlock the chain, so that
1029 	 * we don't keep the lock across a disk read
1030 	 */
1031 	version = h->qh_version;
1032 	XFS_DQ_HASH_UNLOCK(h);
1033 
1034 	/*
1035 	 * Allocate the dquot on the kernel heap, and read the ondisk
1036 	 * portion off the disk. Also, do all the necessary initialization
1037 	 * This can return ENOENT if dquot didn't exist on disk and we didn't
1038 	 * ask it to allocate; ESRCH if quotas got turned off suddenly.
1039 	 */
1040 	if ((error = xfs_qm_idtodq(mp, id, type,
1041 				  flags & (XFS_QMOPT_DQALLOC|XFS_QMOPT_DQREPAIR|
1042 					   XFS_QMOPT_DOWARN),
1043 				  &dqp))) {
1044 		if (ip)
1045 			xfs_ilock(ip, XFS_ILOCK_EXCL);
1046 		return (error);
1047 	}
1048 
1049 	/*
1050 	 * See if this is mount code calling to look at the overall quota limits
1051 	 * which are stored in the id == 0 user or group's dquot.
1052 	 * Since we may not have done a quotacheck by this point, just return
1053 	 * the dquot without attaching it to any hashtables, lists, etc, or even
1054 	 * taking a reference.
1055 	 * The caller must dqdestroy this once done.
1056 	 */
1057 	if (flags & XFS_QMOPT_DQSUSER) {
1058 		ASSERT(id == 0);
1059 		ASSERT(! ip);
1060 		goto dqret;
1061 	}
1062 
1063 	/*
1064 	 * Dquot lock comes after hashlock in the lock ordering
1065 	 */
1066 	if (ip) {
1067 		xfs_ilock(ip, XFS_ILOCK_EXCL);
1068 		if (! XFS_IS_DQTYPE_ON(mp, type)) {
1069 			/* inode stays locked on return */
1070 			xfs_qm_dqdestroy(dqp);
1071 			return XFS_ERROR(ESRCH);
1072 		}
1073 		/*
1074 		 * A dquot could be attached to this inode by now, since
1075 		 * we had dropped the ilock.
1076 		 */
1077 		if (type == XFS_DQ_USER) {
1078 			if (ip->i_udquot) {
1079 				xfs_qm_dqdestroy(dqp);
1080 				dqp = ip->i_udquot;
1081 				xfs_dqlock(dqp);
1082 				goto dqret;
1083 			}
1084 		} else {
1085 			if (ip->i_gdquot) {
1086 				xfs_qm_dqdestroy(dqp);
1087 				dqp = ip->i_gdquot;
1088 				xfs_dqlock(dqp);
1089 				goto dqret;
1090 			}
1091 		}
1092 	}
1093 
1094 	/*
1095 	 * Hashlock comes after ilock in lock order
1096 	 */
1097 	XFS_DQ_HASH_LOCK(h);
1098 	if (version != h->qh_version) {
1099 		xfs_dquot_t *tmpdqp;
1100 		/*
1101 		 * Now, see if somebody else put the dquot in the
1102 		 * hashtable before us. This can happen because we didn't
1103 		 * keep the hashchain lock. We don't have to worry about
1104 		 * lock order between the two dquots here since dqp isn't
1105 		 * on any findable lists yet.
1106 		 */
1107 		if (xfs_qm_dqlookup(mp, id, h, &tmpdqp) == 0) {
1108 			/*
1109 			 * Duplicate found. Just throw away the new dquot
1110 			 * and start over.
1111 			 */
1112 			xfs_qm_dqput(tmpdqp);
1113 			XFS_DQ_HASH_UNLOCK(h);
1114 			xfs_qm_dqdestroy(dqp);
1115 			XQM_STATS_INC(xqmstats.xs_qm_dquot_dups);
1116 			goto again;
1117 		}
1118 	}
1119 
1120 	/*
1121 	 * Put the dquot at the beginning of the hash-chain and mp's list
1122 	 * LOCK ORDER: hashlock, freelistlock, mplistlock, udqlock, gdqlock ..
1123 	 */
1124 	ASSERT(XFS_DQ_IS_HASH_LOCKED(h));
1125 	dqp->q_hash = h;
1126 	XQM_HASHLIST_INSERT(h, dqp);
1127 
1128 	/*
1129 	 * Attach this dquot to this filesystem's list of all dquots,
1130 	 * kept inside the mount structure in m_quotainfo field
1131 	 */
1132 	xfs_qm_mplist_lock(mp);
1133 
1134 	/*
1135 	 * We return a locked dquot to the caller, with a reference taken
1136 	 */
1137 	xfs_dqlock(dqp);
1138 	dqp->q_nrefs = 1;
1139 
1140 	XQM_MPLIST_INSERT(&(XFS_QI_MPL_LIST(mp)), dqp);
1141 
1142 	xfs_qm_mplist_unlock(mp);
1143 	XFS_DQ_HASH_UNLOCK(h);
1144  dqret:
1145 	ASSERT((ip == NULL) || XFS_ISLOCKED_INODE_EXCL(ip));
1146 	xfs_dqtrace_entry(dqp, "DQGET DONE");
1147 	*O_dqpp = dqp;
1148 	return (0);
1149 }
1150 
1151 
1152 /*
1153  * Release a reference to the dquot (decrement ref-count)
1154  * and unlock it. If there is a group quota attached to this
1155  * dquot, carefully release that too without tripping over
1156  * deadlocks'n'stuff.
1157  */
1158 void
xfs_qm_dqput(xfs_dquot_t * dqp)1159 xfs_qm_dqput(
1160 	xfs_dquot_t	*dqp)
1161 {
1162 	xfs_dquot_t	*gdqp;
1163 
1164 	ASSERT(dqp->q_nrefs > 0);
1165 	ASSERT(XFS_DQ_IS_LOCKED(dqp));
1166 	xfs_dqtrace_entry(dqp, "DQPUT");
1167 
1168 	if (dqp->q_nrefs != 1) {
1169 		dqp->q_nrefs--;
1170 		xfs_dqunlock(dqp);
1171 		return;
1172 	}
1173 
1174 	/*
1175 	 * drop the dqlock and acquire the freelist and dqlock
1176 	 * in the right order; but try to get it out-of-order first
1177 	 */
1178 	if (! xfs_qm_freelist_lock_nowait(xfs_Gqm)) {
1179 		xfs_dqtrace_entry(dqp, "DQPUT: FLLOCK-WAIT");
1180 		xfs_dqunlock(dqp);
1181 		xfs_qm_freelist_lock(xfs_Gqm);
1182 		xfs_dqlock(dqp);
1183 	}
1184 
1185 	while (1) {
1186 		gdqp = NULL;
1187 
1188 		/* We can't depend on nrefs being == 1 here */
1189 		if (--dqp->q_nrefs == 0) {
1190 			xfs_dqtrace_entry(dqp, "DQPUT: ON FREELIST");
1191 			/*
1192 			 * insert at end of the freelist.
1193 			 */
1194 			XQM_FREELIST_INSERT(&(xfs_Gqm->qm_dqfreelist), dqp);
1195 
1196 			/*
1197 			 * If we just added a udquot to the freelist, then
1198 			 * we want to release the gdquot reference that
1199 			 * it (probably) has. Otherwise it'll keep the
1200 			 * gdquot from getting reclaimed.
1201 			 */
1202 			if ((gdqp = dqp->q_gdquot)) {
1203 				/*
1204 				 * Avoid a recursive dqput call
1205 				 */
1206 				xfs_dqlock(gdqp);
1207 				dqp->q_gdquot = NULL;
1208 			}
1209 
1210 			/* xfs_qm_freelist_print(&(xfs_Gqm->qm_dqfreelist),
1211 			   "@@@@@++ Free list (after append) @@@@@+");
1212 			   */
1213 		}
1214 		xfs_dqunlock(dqp);
1215 
1216 		/*
1217 		 * If we had a group quota inside the user quota as a hint,
1218 		 * release it now.
1219 		 */
1220 		if (! gdqp)
1221 			break;
1222 		dqp = gdqp;
1223 	}
1224 	xfs_qm_freelist_unlock(xfs_Gqm);
1225 }
1226 
1227 /*
1228  * Release a dquot. Flush it if dirty, then dqput() it.
1229  * dquot must not be locked.
1230  */
1231 void
xfs_qm_dqrele(xfs_dquot_t * dqp)1232 xfs_qm_dqrele(
1233 	xfs_dquot_t	*dqp)
1234 {
1235 	ASSERT(dqp);
1236 	xfs_dqtrace_entry(dqp, "DQRELE");
1237 
1238 	xfs_dqlock(dqp);
1239 	/*
1240 	 * We don't care to flush it if the dquot is dirty here.
1241 	 * That will create stutters that we want to avoid.
1242 	 * Instead we do a delayed write when we try to reclaim
1243 	 * a dirty dquot. Also xfs_sync will take part of the burden...
1244 	 */
1245 	xfs_qm_dqput(dqp);
1246 }
1247 
1248 
1249 /*
1250  * Write a modified dquot to disk.
1251  * The dquot must be locked and the flush lock too taken by caller.
1252  * The flush lock will not be unlocked until the dquot reaches the disk,
1253  * but the dquot is free to be unlocked and modified by the caller
1254  * in the interim. Dquot is still locked on return. This behavior is
1255  * identical to that of inodes.
1256  */
1257 int
xfs_qm_dqflush(xfs_dquot_t * dqp,uint flags)1258 xfs_qm_dqflush(
1259 	xfs_dquot_t		*dqp,
1260 	uint			flags)
1261 {
1262 	xfs_mount_t		*mp;
1263 	xfs_buf_t		*bp;
1264 	xfs_disk_dquot_t	*ddqp;
1265 	int			error;
1266 	SPLDECL(s);
1267 
1268 	ASSERT(XFS_DQ_IS_LOCKED(dqp));
1269 	ASSERT(XFS_DQ_IS_FLUSH_LOCKED(dqp));
1270 	xfs_dqtrace_entry(dqp, "DQFLUSH");
1271 
1272 	/*
1273 	 * If not dirty, nada.
1274 	 */
1275 	if (!XFS_DQ_IS_DIRTY(dqp)) {
1276 		xfs_dqfunlock(dqp);
1277 		return (0);
1278 	}
1279 
1280 	/*
1281 	 * Cant flush a pinned dquot. Wait for it.
1282 	 */
1283 	xfs_qm_dqunpin_wait(dqp);
1284 
1285 	/*
1286 	 * This may have been unpinned because the filesystem is shutting
1287 	 * down forcibly. If that's the case we must not write this dquot
1288 	 * to disk, because the log record didn't make it to disk!
1289 	 */
1290 	if (XFS_FORCED_SHUTDOWN(dqp->q_mount)) {
1291 		dqp->dq_flags &= ~(XFS_DQ_DIRTY);
1292 		xfs_dqfunlock(dqp);
1293 		return XFS_ERROR(EIO);
1294 	}
1295 
1296 	/*
1297 	 * Get the buffer containing the on-disk dquot
1298 	 * We don't need a transaction envelope because we know that the
1299 	 * the ondisk-dquot has already been allocated for.
1300 	 */
1301 	if ((error = xfs_qm_dqtobp(NULL, dqp, &ddqp, &bp, XFS_QMOPT_DOWARN))) {
1302 		xfs_dqtrace_entry(dqp, "DQTOBP FAIL");
1303 		ASSERT(error != ENOENT);
1304 		/*
1305 		 * Quotas could have gotten turned off (ESRCH)
1306 		 */
1307 		xfs_dqfunlock(dqp);
1308 		return (error);
1309 	}
1310 
1311 	if (xfs_qm_dqcheck(&dqp->q_core, INT_GET(ddqp->d_id, ARCH_CONVERT), 0, XFS_QMOPT_DOWARN,
1312 			   "dqflush (incore copy)")) {
1313 		xfs_force_shutdown(dqp->q_mount, XFS_CORRUPT_INCORE);
1314 		return XFS_ERROR(EIO);
1315 	}
1316 
1317 	/* This is the only portion of data that needs to persist */
1318 	memcpy(ddqp, &(dqp->q_core), sizeof(xfs_disk_dquot_t));
1319 
1320 	/*
1321 	 * Clear the dirty field and remember the flush lsn for later use.
1322 	 */
1323 	dqp->dq_flags &= ~(XFS_DQ_DIRTY);
1324 	mp = dqp->q_mount;
1325 
1326 	/* lsn is 64 bits */
1327 	AIL_LOCK(mp, s);
1328 	dqp->q_logitem.qli_flush_lsn = dqp->q_logitem.qli_item.li_lsn;
1329 	AIL_UNLOCK(mp, s);
1330 
1331 	/*
1332 	 * Attach an iodone routine so that we can remove this dquot from the
1333 	 * AIL and release the flush lock once the dquot is synced to disk.
1334 	 */
1335 	xfs_buf_attach_iodone(bp, (void(*)(xfs_buf_t *, xfs_log_item_t *))
1336 			      xfs_qm_dqflush_done, &(dqp->q_logitem.qli_item));
1337 	/*
1338 	 * If the buffer is pinned then push on the log so we won't
1339 	 * get stuck waiting in the write for too long.
1340 	 */
1341 	if (XFS_BUF_ISPINNED(bp)) {
1342 		xfs_dqtrace_entry(dqp, "DQFLUSH LOG FORCE");
1343 		xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE);
1344 	}
1345 
1346 	if (flags & XFS_QMOPT_DELWRI) {
1347 		xfs_bdwrite(mp, bp);
1348 	} else if (flags & XFS_QMOPT_ASYNC) {
1349 		xfs_bawrite(mp, bp);
1350 	} else {
1351 		error = xfs_bwrite(mp, bp);
1352 	}
1353 	xfs_dqtrace_entry(dqp, "DQFLUSH END");
1354 	/*
1355 	 * dqp is still locked, but caller is free to unlock it now.
1356 	 */
1357 	return (error);
1358 
1359 }
1360 
1361 /*
1362  * This is the dquot flushing I/O completion routine.  It is called
1363  * from interrupt level when the buffer containing the dquot is
1364  * flushed to disk.  It is responsible for removing the dquot logitem
1365  * from the AIL if it has not been re-logged, and unlocking the dquot's
1366  * flush lock. This behavior is very similar to that of inodes..
1367  */
1368 /*ARGSUSED*/
1369 STATIC void
xfs_qm_dqflush_done(xfs_buf_t * bp,xfs_dq_logitem_t * qip)1370 xfs_qm_dqflush_done(
1371 	xfs_buf_t		*bp,
1372 	xfs_dq_logitem_t	*qip)
1373 {
1374 	xfs_dquot_t		*dqp;
1375 	SPLDECL(s);
1376 
1377 	dqp = qip->qli_dquot;
1378 
1379 	/*
1380 	 * We only want to pull the item from the AIL if its
1381 	 * location in the log has not changed since we started the flush.
1382 	 * Thus, we only bother if the dquot's lsn has
1383 	 * not changed. First we check the lsn outside the lock
1384 	 * since it's cheaper, and then we recheck while
1385 	 * holding the lock before removing the dquot from the AIL.
1386 	 */
1387 	if ((qip->qli_item.li_flags & XFS_LI_IN_AIL) &&
1388 	    qip->qli_item.li_lsn == qip->qli_flush_lsn) {
1389 
1390 		AIL_LOCK(dqp->q_mount, s);
1391 		/*
1392 		 * xfs_trans_delete_ail() drops the AIL lock.
1393 		 */
1394 		if (qip->qli_item.li_lsn == qip->qli_flush_lsn)
1395 			xfs_trans_delete_ail(dqp->q_mount,
1396 					     (xfs_log_item_t*)qip, s);
1397 		else
1398 			AIL_UNLOCK(dqp->q_mount, s);
1399 	}
1400 
1401 	/*
1402 	 * Release the dq's flush lock since we're done with it.
1403 	 */
1404 	xfs_dqfunlock(dqp);
1405 }
1406 
1407 
1408 int
xfs_qm_dqflock_nowait(xfs_dquot_t * dqp)1409 xfs_qm_dqflock_nowait(
1410 	xfs_dquot_t *dqp)
1411 {
1412 	int locked;
1413 
1414 	locked = cpsema(&((dqp)->q_flock));
1415 
1416 	/* XXX ifdef these out */
1417 	if (locked)
1418 		(dqp)->dq_flags |= XFS_DQ_FLOCKED;
1419 	return (locked);
1420 }
1421 
1422 
1423 int
xfs_qm_dqlock_nowait(xfs_dquot_t * dqp)1424 xfs_qm_dqlock_nowait(
1425 	xfs_dquot_t *dqp)
1426 {
1427 	return (mutex_trylock(&((dqp)->q_qlock)));
1428 }
1429 
1430 void
xfs_dqlock(xfs_dquot_t * dqp)1431 xfs_dqlock(
1432 	xfs_dquot_t *dqp)
1433 {
1434 	mutex_lock(&(dqp->q_qlock), PINOD);
1435 }
1436 
1437 void
xfs_dqunlock(xfs_dquot_t * dqp)1438 xfs_dqunlock(
1439 	xfs_dquot_t *dqp)
1440 {
1441 	mutex_unlock(&(dqp->q_qlock));
1442 	if (dqp->q_logitem.qli_dquot == dqp) {
1443 		/* Once was dqp->q_mount, but might just have been cleared */
1444 		xfs_trans_unlocked_item(dqp->q_logitem.qli_item.li_mountp,
1445 					(xfs_log_item_t*)&(dqp->q_logitem));
1446 	}
1447 }
1448 
1449 
1450 void
xfs_dqunlock_nonotify(xfs_dquot_t * dqp)1451 xfs_dqunlock_nonotify(
1452 	xfs_dquot_t *dqp)
1453 {
1454 	mutex_unlock(&(dqp->q_qlock));
1455 }
1456 
1457 void
xfs_dqlock2(xfs_dquot_t * d1,xfs_dquot_t * d2)1458 xfs_dqlock2(
1459 	xfs_dquot_t	*d1,
1460 	xfs_dquot_t	*d2)
1461 {
1462 	if (d1 && d2) {
1463 		ASSERT(d1 != d2);
1464 		if (INT_GET(d1->q_core.d_id, ARCH_CONVERT) > INT_GET(d2->q_core.d_id, ARCH_CONVERT)) {
1465 			xfs_dqlock(d2);
1466 			xfs_dqlock(d1);
1467 		} else {
1468 			xfs_dqlock(d1);
1469 			xfs_dqlock(d2);
1470 		}
1471 	} else {
1472 		if (d1) {
1473 			xfs_dqlock(d1);
1474 		} else if (d2) {
1475 			xfs_dqlock(d2);
1476 		}
1477 	}
1478 }
1479 
1480 
1481 /*
1482  * Take a dquot out of the mount's dqlist as well as the hashlist.
1483  * This is called via unmount as well as quotaoff, and the purge
1484  * will always succeed unless there are soft (temp) references
1485  * outstanding.
1486  *
1487  * This returns 0 if it was purged, 1 if it wasn't. It's not an error code
1488  * that we're returning! XXXsup - not cool.
1489  */
1490 /* ARGSUSED */
1491 int
xfs_qm_dqpurge(xfs_dquot_t * dqp,uint flags)1492 xfs_qm_dqpurge(
1493 	xfs_dquot_t	*dqp,
1494 	uint		flags)
1495 {
1496 	xfs_dqhash_t	*thishash;
1497 	xfs_mount_t	*mp;
1498 
1499 	mp = dqp->q_mount;
1500 
1501 	ASSERT(XFS_QM_IS_MPLIST_LOCKED(mp));
1502 	ASSERT(XFS_DQ_IS_HASH_LOCKED(dqp->q_hash));
1503 
1504 	xfs_dqlock(dqp);
1505 	/*
1506 	 * We really can't afford to purge a dquot that is
1507 	 * referenced, because these are hard refs.
1508 	 * It shouldn't happen in general because we went thru _all_ inodes in
1509 	 * dqrele_all_inodes before calling this and didn't let the mountlock go.
1510 	 * However it is possible that we have dquots with temporary
1511 	 * references that are not attached to an inode. e.g. see xfs_setattr().
1512 	 */
1513 	if (dqp->q_nrefs != 0) {
1514 		xfs_dqunlock(dqp);
1515 		XFS_DQ_HASH_UNLOCK(dqp->q_hash);
1516 		return (1);
1517 	}
1518 
1519 	ASSERT(XFS_DQ_IS_ON_FREELIST(dqp));
1520 
1521 	/*
1522 	 * If we're turning off quotas, we have to make sure that, for
1523 	 * example, we don't delete quota disk blocks while dquots are
1524 	 * in the process of getting written to those disk blocks.
1525 	 * This dquot might well be on AIL, and we can't leave it there
1526 	 * if we're turning off quotas. Basically, we need this flush
1527 	 * lock, and are willing to block on it.
1528 	 */
1529 	if (! xfs_qm_dqflock_nowait(dqp)) {
1530 		/*
1531 		 * Block on the flush lock after nudging dquot buffer,
1532 		 * if it is incore.
1533 		 */
1534 		xfs_qm_dqflock_pushbuf_wait(dqp);
1535 	}
1536 
1537 	/*
1538 	 * XXXIf we're turning this type of quotas off, we don't care
1539 	 * about the dirty metadata sitting in this dquot. OTOH, if
1540 	 * we're unmounting, we do care, so we flush it and wait.
1541 	 */
1542 	if (XFS_DQ_IS_DIRTY(dqp)) {
1543 		xfs_dqtrace_entry(dqp, "DQPURGE ->DQFLUSH: DQDIRTY");
1544 		/* dqflush unlocks dqflock */
1545 		/*
1546 		 * Given that dqpurge is a very rare occurrence, it is OK
1547 		 * that we're holding the hashlist and mplist locks
1548 		 * across the disk write. But, ... XXXsup
1549 		 *
1550 		 * We don't care about getting disk errors here. We need
1551 		 * to purge this dquot anyway, so we go ahead regardless.
1552 		 */
1553 		(void) xfs_qm_dqflush(dqp, XFS_QMOPT_SYNC);
1554 		xfs_dqflock(dqp);
1555 	}
1556 	ASSERT(dqp->q_pincount == 0);
1557 	ASSERT(XFS_FORCED_SHUTDOWN(mp) ||
1558 	       !(dqp->q_logitem.qli_item.li_flags & XFS_LI_IN_AIL));
1559 
1560 	thishash = dqp->q_hash;
1561 	XQM_HASHLIST_REMOVE(thishash, dqp);
1562 	XQM_MPLIST_REMOVE(&(XFS_QI_MPL_LIST(mp)), dqp);
1563 	/*
1564 	 * XXX Move this to the front of the freelist, if we can get the
1565 	 * freelist lock.
1566 	 */
1567 	ASSERT(XFS_DQ_IS_ON_FREELIST(dqp));
1568 
1569 	dqp->q_mount = NULL;
1570 	dqp->q_hash = NULL;
1571 	dqp->dq_flags = XFS_DQ_INACTIVE;
1572 	memset(&dqp->q_core, 0, sizeof(dqp->q_core));
1573 	xfs_dqfunlock(dqp);
1574 	xfs_dqunlock(dqp);
1575 	XFS_DQ_HASH_UNLOCK(thishash);
1576 	return (0);
1577 }
1578 
1579 
1580 #ifdef QUOTADEBUG
1581 void
xfs_qm_dqprint(xfs_dquot_t * dqp)1582 xfs_qm_dqprint(xfs_dquot_t *dqp)
1583 {
1584 	cmn_err(CE_DEBUG, "-----------KERNEL DQUOT----------------");
1585 	cmn_err(CE_DEBUG, "---- dquotID =  %d",
1586 		(int)INT_GET(dqp->q_core.d_id, ARCH_CONVERT));
1587 	cmn_err(CE_DEBUG, "---- type    =  %s",
1588 		XFS_QM_ISUDQ(dqp) ? "USR" : "GRP");
1589 	cmn_err(CE_DEBUG, "---- fs      =  0x%p", dqp->q_mount);
1590 	cmn_err(CE_DEBUG, "---- blkno   =  0x%x", (int) dqp->q_blkno);
1591 	cmn_err(CE_DEBUG, "---- boffset =  0x%x", (int) dqp->q_bufoffset);
1592 	cmn_err(CE_DEBUG, "---- blkhlimit =  %Lu (0x%x)",
1593 		INT_GET(dqp->q_core.d_blk_hardlimit, ARCH_CONVERT),
1594 		(int) INT_GET(dqp->q_core.d_blk_hardlimit, ARCH_CONVERT));
1595 	cmn_err(CE_DEBUG, "---- blkslimit =  %Lu (0x%x)",
1596 		INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT),
1597 		(int)INT_GET(dqp->q_core.d_blk_softlimit, ARCH_CONVERT));
1598 	cmn_err(CE_DEBUG, "---- inohlimit =  %Lu (0x%x)",
1599 		INT_GET(dqp->q_core.d_ino_hardlimit, ARCH_CONVERT),
1600 		(int)INT_GET(dqp->q_core.d_ino_hardlimit, ARCH_CONVERT));
1601 	cmn_err(CE_DEBUG, "---- inoslimit =  %Lu (0x%x)",
1602 		INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT),
1603 		(int)INT_GET(dqp->q_core.d_ino_softlimit, ARCH_CONVERT));
1604 	cmn_err(CE_DEBUG, "---- bcount  =  %Lu (0x%x)",
1605 		INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT),
1606 		(int)INT_GET(dqp->q_core.d_bcount, ARCH_CONVERT));
1607 	cmn_err(CE_DEBUG, "---- icount  =  %Lu (0x%x)",
1608 		INT_GET(dqp->q_core.d_icount, ARCH_CONVERT),
1609 		(int)INT_GET(dqp->q_core.d_icount, ARCH_CONVERT));
1610 	cmn_err(CE_DEBUG, "---- btimer  =  %d",
1611 		(int)INT_GET(dqp->q_core.d_btimer, ARCH_CONVERT));
1612 	cmn_err(CE_DEBUG, "---- itimer  =  %d",
1613 		(int)INT_GET(dqp->q_core.d_itimer, ARCH_CONVERT));
1614 	cmn_err(CE_DEBUG, "---------------------------");
1615 }
1616 #endif
1617 
1618 /*
1619  * Give the buffer a little push if it is incore and
1620  * wait on the flush lock.
1621  */
1622 void
xfs_qm_dqflock_pushbuf_wait(xfs_dquot_t * dqp)1623 xfs_qm_dqflock_pushbuf_wait(
1624 	xfs_dquot_t	*dqp)
1625 {
1626 	xfs_buf_t	*bp;
1627 
1628 	/*
1629 	 * Check to see if the dquot has been flushed delayed
1630 	 * write.  If so, grab its buffer and send it
1631 	 * out immediately.  We'll be able to acquire
1632 	 * the flush lock when the I/O completes.
1633 	 */
1634 	bp = xfs_incore(dqp->q_mount->m_ddev_targp, dqp->q_blkno,
1635 		    XFS_QI_DQCHUNKLEN(dqp->q_mount),
1636 		    XFS_INCORE_TRYLOCK);
1637 	if (bp != NULL) {
1638 		if (XFS_BUF_ISDELAYWRITE(bp)) {
1639 			if (XFS_BUF_ISPINNED(bp)) {
1640 				xfs_log_force(dqp->q_mount,
1641 					      (xfs_lsn_t)0,
1642 					      XFS_LOG_FORCE);
1643 			}
1644 			xfs_bawrite(dqp->q_mount, bp);
1645 		} else {
1646 			xfs_buf_relse(bp);
1647 		}
1648 	}
1649 	xfs_dqflock(dqp);
1650 }
1651