1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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
75
76
77
78
79
80
81
82
83
84
85
86
87STATIC void xfs_qm_dqflush_done(xfs_buf_t *, xfs_dq_logitem_t *);
88
89#ifdef DEBUG
90xfs_buftarg_t *xfs_dqerror_target;
91int xfs_do_dqerror;
92int xfs_dqreq_num;
93int xfs_dqerror_mod = 33;
94#endif
95
96
97
98
99
100
101
102
103
104xfs_dquot_t *
105xfs_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
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
134
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
159
160 return (dqp);
161}
162
163
164
165
166void
167xfs_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
187
188STATIC void
189xfs_qm_dqinit_core(
190 xfs_dqid_t id,
191 uint type,
192 xfs_dqblk_t *d)
193{
194
195
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
207
208
209void
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
254
255
256
257void
258xfs_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
284
285
286
287
288
289
290
291
292
293void
294xfs_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
377
378int
379xfs_qm_dqwarn(
380 xfs_disk_dquot_t *d,
381 uint flags)
382{
383 int warned;
384
385
386
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
439
440STATIC void
441xfs_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
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
476
477
478STATIC int
479xfs_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
498
499 XFS_BMAP_INIT(&flist, &firstblock);
500 xfs_ilock(quotip, XFS_ILOCK_EXCL);
501
502
503
504
505 if (XFS_IS_THIS_QUOTA_OFF(dqp)) {
506 xfs_iunlock(quotip, XFS_ILOCK_EXCL);
507 return (ESRCH);
508 }
509
510
511
512
513
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
534
535 dqp->q_blkno = XFS_FSB_TO_DADDR(mp, map.br_startblock);
536
537
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
546
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
569
570
571
572STATIC int
573xfs_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
596
597 if (dqp->q_blkno == (xfs_daddr_t) 0) {
598
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
606
607
608 if (XFS_IS_THIS_QUOTA_OFF(dqp)) {
609 xfs_iunlock(quotip, XFS_ILOCK_SHARED);
610 return (ESRCH);
611 }
612
613
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
628
629 dqp->q_bufoffset = (id % XFS_QM_DQPERBLK(mp)) *
630 sizeof(xfs_dqblk_t);
631 if (map.br_startblock == HOLESTARTBLOCK) {
632
633
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
646
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
656
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
674
675 ddq = (xfs_disk_dquot_t *)((char *)XFS_BUF_PTR(bp) + dqp->q_bufoffset);
676
677
678
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);
689 }
690
691 *O_bpp = bp;
692 *O_ddpp = ddq;
693
694 return (0);
695}
696
697
698
699
700
701
702
703
704STATIC int
705xfs_qm_dqread(
706 xfs_trans_t *tp,
707 xfs_dqid_t id,
708 xfs_dquot_t *dqp,
709 uint flags)
710{
711 xfs_disk_dquot_t *ddqp;
712 xfs_buf_t *bp;
713 int error;
714
715
716
717
718
719 xfs_dqtrace_entry(dqp, "DQREAD");
720 if ((error = xfs_qm_dqtobp(tp, dqp, &ddqp, &bp, flags))) {
721 return (error);
722 }
723
724
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
731
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
738 XFS_BUF_SET_VTYPE_REF(bp, B_FS_DQUOT, XFS_DQUOT_REF);
739
740
741
742
743
744
745
746
747
748
749
750
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
762
763
764
765
766STATIC int
767xfs_qm_idtodq(
768 xfs_mount_t *mp,
769 xfs_dqid_t id,
770 uint type,
771 uint flags,
772 xfs_dquot_t **O_dqpp)
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
799
800
801 if ((error = xfs_qm_dqread(tp, id, dqp, flags))) {
802
803
804
805
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
832
833
834
835
836
837STATIC int
838xfs_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
854
855 for (dqp = qh->qh_next; dqp != NULL; dqp = dqp->HL_NEXT) {
856
857
858
859
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
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
876
877
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
890
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
901
902 xfs_dqtrace_entry(dqp,
903 "DQLOOKUP: TAKEOFF FL");
904 XQM_FREELIST_REMOVE(dqp);
905
906
907
908 }
909 }
910
911
912
913
914 XFS_DQHOLD(dqp);
915
916 if (flist_locked)
917 xfs_qm_freelist_unlock(xfs_Gqm);
918
919
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
948
949
950
951
952
953
954int
955xfs_qm_dqget(
956 xfs_mount_t *mp,
957 xfs_inode_t *ip,
958 xfs_dqid_t id,
959 uint type,
960 uint flags,
961 xfs_dquot_t **O_dqpp)
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
1001
1002
1003 if (xfs_qm_dqlookup(mp, id, h, O_dqpp) == 0) {
1004 XQM_STATS_INC(xqmstats.xs_qm_dqcachehits);
1005
1006
1007
1008
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);
1015 }
1016 XQM_STATS_INC(xqmstats.xs_qm_dqcachemisses);
1017
1018
1019
1020
1021
1022
1023
1024
1025 if (ip)
1026 xfs_iunlock(ip, XFS_ILOCK_EXCL);
1027
1028
1029
1030
1031 version = h->qh_version;
1032 XFS_DQ_HASH_UNLOCK(h);
1033
1034
1035
1036
1037
1038
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
1051
1052
1053
1054
1055
1056
1057 if (flags & XFS_QMOPT_DQSUSER) {
1058 ASSERT(id == 0);
1059 ASSERT(! ip);
1060 goto dqret;
1061 }
1062
1063
1064
1065
1066 if (ip) {
1067 xfs_ilock(ip, XFS_ILOCK_EXCL);
1068 if (! XFS_IS_DQTYPE_ON(mp, type)) {
1069
1070 xfs_qm_dqdestroy(dqp);
1071 return XFS_ERROR(ESRCH);
1072 }
1073
1074
1075
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
1096
1097 XFS_DQ_HASH_LOCK(h);
1098 if (version != h->qh_version) {
1099 xfs_dquot_t *tmpdqp;
1100
1101
1102
1103
1104
1105
1106
1107 if (xfs_qm_dqlookup(mp, id, h, &tmpdqp) == 0) {
1108
1109
1110
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
1122
1123
1124 ASSERT(XFS_DQ_IS_HASH_LOCKED(h));
1125 dqp->q_hash = h;
1126 XQM_HASHLIST_INSERT(h, dqp);
1127
1128
1129
1130
1131
1132 xfs_qm_mplist_lock(mp);
1133
1134
1135
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
1154
1155
1156
1157
1158void
1159xfs_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
1176
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
1189 if (--dqp->q_nrefs == 0) {
1190 xfs_dqtrace_entry(dqp, "DQPUT: ON FREELIST");
1191
1192
1193
1194 XQM_FREELIST_INSERT(&(xfs_Gqm->qm_dqfreelist), dqp);
1195
1196
1197
1198
1199
1200
1201
1202 if ((gdqp = dqp->q_gdquot)) {
1203
1204
1205
1206 xfs_dqlock(gdqp);
1207 dqp->q_gdquot = NULL;
1208 }
1209
1210
1211
1212
1213 }
1214 xfs_dqunlock(dqp);
1215
1216
1217
1218
1219
1220 if (! gdqp)
1221 break;
1222 dqp = gdqp;
1223 }
1224 xfs_qm_freelist_unlock(xfs_Gqm);
1225}
1226
1227
1228
1229
1230
1231void
1232xfs_qm_dqrele(
1233 xfs_dquot_t *dqp)
1234{
1235 ASSERT(dqp);
1236 xfs_dqtrace_entry(dqp, "DQRELE");
1237
1238 xfs_dqlock(dqp);
1239
1240
1241
1242
1243
1244
1245 xfs_qm_dqput(dqp);
1246}
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257int
1258xfs_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
1274
1275 if (!XFS_DQ_IS_DIRTY(dqp)) {
1276 xfs_dqfunlock(dqp);
1277 return (0);
1278 }
1279
1280
1281
1282
1283 xfs_qm_dqunpin_wait(dqp);
1284
1285
1286
1287
1288
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
1298
1299
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
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
1318 memcpy(ddqp, &(dqp->q_core), sizeof(xfs_disk_dquot_t));
1319
1320
1321
1322
1323 dqp->dq_flags &= ~(XFS_DQ_DIRTY);
1324 mp = dqp->q_mount;
1325
1326
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
1333
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
1339
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
1356
1357 return (error);
1358
1359}
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369STATIC void
1370xfs_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
1381
1382
1383
1384
1385
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
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
1403
1404 xfs_dqfunlock(dqp);
1405}
1406
1407
1408int
1409xfs_qm_dqflock_nowait(
1410 xfs_dquot_t *dqp)
1411{
1412 int locked;
1413
1414 locked = cpsema(&((dqp)->q_flock));
1415
1416
1417 if (locked)
1418 (dqp)->dq_flags |= XFS_DQ_FLOCKED;
1419 return (locked);
1420}
1421
1422
1423int
1424xfs_qm_dqlock_nowait(
1425 xfs_dquot_t *dqp)
1426{
1427 return (mutex_trylock(&((dqp)->q_qlock)));
1428}
1429
1430void
1431xfs_dqlock(
1432 xfs_dquot_t *dqp)
1433{
1434 mutex_lock(&(dqp->q_qlock), PINOD);
1435}
1436
1437void
1438xfs_dqunlock(
1439 xfs_dquot_t *dqp)
1440{
1441 mutex_unlock(&(dqp->q_qlock));
1442 if (dqp->q_logitem.qli_dquot == dqp) {
1443
1444 xfs_trans_unlocked_item(dqp->q_logitem.qli_item.li_mountp,
1445 (xfs_log_item_t*)&(dqp->q_logitem));
1446 }
1447}
1448
1449
1450void
1451xfs_dqunlock_nonotify(
1452 xfs_dquot_t *dqp)
1453{
1454 mutex_unlock(&(dqp->q_qlock));
1455}
1456
1457void
1458xfs_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
1483
1484
1485
1486
1487
1488
1489
1490
1491int
1492xfs_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
1507
1508
1509
1510
1511
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
1523
1524
1525
1526
1527
1528
1529 if (! xfs_qm_dqflock_nowait(dqp)) {
1530
1531
1532
1533
1534 xfs_qm_dqflock_pushbuf_wait(dqp);
1535 }
1536
1537
1538
1539
1540
1541
1542 if (XFS_DQ_IS_DIRTY(dqp)) {
1543 xfs_dqtrace_entry(dqp, "DQPURGE ->DQFLUSH: DQDIRTY");
1544
1545
1546
1547
1548
1549
1550
1551
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
1565
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
1581void
1582xfs_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
1620
1621
1622void
1623xfs_qm_dqflock_pushbuf_wait(
1624 xfs_dquot_t *dqp)
1625{
1626 xfs_buf_t *bp;
1627
1628
1629
1630
1631
1632
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