1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include "xfs.h"
19#include "xfs_fs.h"
20#include "xfs_bit.h"
21#include "xfs_log.h"
22#include "xfs_inum.h"
23#include "xfs_trans.h"
24#include "xfs_sb.h"
25#include "xfs_ag.h"
26#include "xfs_dir2.h"
27#include "xfs_alloc.h"
28#include "xfs_dmapi.h"
29#include "xfs_quota.h"
30#include "xfs_mount.h"
31#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h"
34#include "xfs_dir2_sf.h"
35#include "xfs_attr_sf.h"
36#include "xfs_dinode.h"
37#include "xfs_inode.h"
38#include "xfs_bmap.h"
39#include "xfs_btree.h"
40#include "xfs_ialloc.h"
41#include "xfs_rtalloc.h"
42#include "xfs_error.h"
43#include "xfs_itable.h"
44#include "xfs_rw.h"
45#include "xfs_acl.h"
46#include "xfs_attr.h"
47#include "xfs_buf_item.h"
48#include "xfs_trans_priv.h"
49#include "xfs_qm.h"
50
51
52
53
54
55STATIC uint
56xfs_qm_dquot_logitem_size(
57 xfs_dq_logitem_t *logitem)
58{
59
60
61
62 return (2);
63}
64
65
66
67
68STATIC void
69xfs_qm_dquot_logitem_format(
70 xfs_dq_logitem_t *logitem,
71 xfs_log_iovec_t *logvec)
72{
73 ASSERT(logitem);
74 ASSERT(logitem->qli_dquot);
75
76 logvec->i_addr = (xfs_caddr_t)&logitem->qli_format;
77 logvec->i_len = sizeof(xfs_dq_logformat_t);
78 XLOG_VEC_SET_TYPE(logvec, XLOG_REG_TYPE_QFORMAT);
79 logvec++;
80 logvec->i_addr = (xfs_caddr_t)&logitem->qli_dquot->q_core;
81 logvec->i_len = sizeof(xfs_disk_dquot_t);
82 XLOG_VEC_SET_TYPE(logvec, XLOG_REG_TYPE_DQUOT);
83
84 ASSERT(2 == logitem->qli_item.li_desc->lid_size);
85 logitem->qli_format.qlf_size = 2;
86
87}
88
89
90
91
92
93STATIC void
94xfs_qm_dquot_logitem_pin(
95 xfs_dq_logitem_t *logitem)
96{
97 xfs_dquot_t *dqp;
98
99 dqp = logitem->qli_dquot;
100 ASSERT(XFS_DQ_IS_LOCKED(dqp));
101 spin_lock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock));
102 dqp->q_pincount++;
103 spin_unlock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock));
104}
105
106
107
108
109
110
111
112STATIC void
113xfs_qm_dquot_logitem_unpin(
114 xfs_dq_logitem_t *logitem,
115 int stale)
116{
117 xfs_dquot_t *dqp;
118
119 dqp = logitem->qli_dquot;
120 ASSERT(dqp->q_pincount > 0);
121 spin_lock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock));
122 dqp->q_pincount--;
123 if (dqp->q_pincount == 0) {
124 sv_broadcast(&dqp->q_pinwait);
125 }
126 spin_unlock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock));
127}
128
129
130STATIC void
131xfs_qm_dquot_logitem_unpin_remove(
132 xfs_dq_logitem_t *logitem,
133 xfs_trans_t *tp)
134{
135 xfs_qm_dquot_logitem_unpin(logitem, 0);
136}
137
138
139
140
141
142
143
144STATIC void
145xfs_qm_dquot_logitem_push(
146 xfs_dq_logitem_t *logitem)
147{
148 xfs_dquot_t *dqp;
149 int error;
150
151 dqp = logitem->qli_dquot;
152
153 ASSERT(XFS_DQ_IS_LOCKED(dqp));
154 ASSERT(!completion_done(&dqp->q_flush));
155
156
157
158
159
160
161
162
163
164
165 error = xfs_qm_dqflush(dqp, XFS_QMOPT_DELWRI);
166 if (error)
167 xfs_fs_cmn_err(CE_WARN, dqp->q_mount,
168 "xfs_qm_dquot_logitem_push: push error %d on dqp %p",
169 error, dqp);
170 xfs_dqunlock(dqp);
171}
172
173
174STATIC xfs_lsn_t
175xfs_qm_dquot_logitem_committed(
176 xfs_dq_logitem_t *l,
177 xfs_lsn_t lsn)
178{
179
180
181
182
183 return (lsn);
184}
185
186
187
188
189
190
191void
192xfs_qm_dqunpin_wait(
193 xfs_dquot_t *dqp)
194{
195 ASSERT(XFS_DQ_IS_LOCKED(dqp));
196 if (dqp->q_pincount == 0) {
197 return;
198 }
199
200
201
202
203 xfs_log_force(dqp->q_mount, (xfs_lsn_t)0, XFS_LOG_FORCE);
204 spin_lock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock));
205 if (dqp->q_pincount == 0) {
206 spin_unlock(&(XFS_DQ_TO_QINF(dqp)->qi_pinlock));
207 return;
208 }
209 sv_wait(&(dqp->q_pinwait), PINOD,
210 &(XFS_DQ_TO_QINF(dqp)->qi_pinlock), s);
211}
212
213
214
215
216
217
218
219
220
221
222
223
224STATIC void
225xfs_qm_dquot_logitem_pushbuf(
226 xfs_dq_logitem_t *qip)
227{
228 xfs_dquot_t *dqp;
229 xfs_mount_t *mp;
230 xfs_buf_t *bp;
231 uint dopush;
232
233 dqp = qip->qli_dquot;
234 ASSERT(XFS_DQ_IS_LOCKED(dqp));
235
236
237
238
239
240 ASSERT(qip->qli_pushbuf_flag != 0);
241 ASSERT(qip->qli_push_owner == current_pid());
242
243
244
245
246
247
248 if (completion_done(&dqp->q_flush) ||
249 ((qip->qli_item.li_flags & XFS_LI_IN_AIL) == 0)) {
250 qip->qli_pushbuf_flag = 0;
251 xfs_dqunlock(dqp);
252 return;
253 }
254 mp = dqp->q_mount;
255 bp = xfs_incore(mp->m_ddev_targp, qip->qli_format.qlf_blkno,
256 XFS_QI_DQCHUNKLEN(mp),
257 XFS_INCORE_TRYLOCK);
258 if (bp != NULL) {
259 if (XFS_BUF_ISDELAYWRITE(bp)) {
260 dopush = ((qip->qli_item.li_flags & XFS_LI_IN_AIL) &&
261 !completion_done(&dqp->q_flush));
262 qip->qli_pushbuf_flag = 0;
263 xfs_dqunlock(dqp);
264
265 if (XFS_BUF_ISPINNED(bp)) {
266 xfs_log_force(mp, (xfs_lsn_t)0,
267 XFS_LOG_FORCE);
268 }
269 if (dopush) {
270 int error;
271#ifdef XFSRACEDEBUG
272 delay_for_intr();
273 delay(300);
274#endif
275 error = xfs_bawrite(mp, bp);
276 if (error)
277 xfs_fs_cmn_err(CE_WARN, mp,
278 "xfs_qm_dquot_logitem_pushbuf: pushbuf error %d on qip %p, bp %p",
279 error, qip, bp);
280 } else {
281 xfs_buf_relse(bp);
282 }
283 } else {
284 qip->qli_pushbuf_flag = 0;
285 xfs_dqunlock(dqp);
286 xfs_buf_relse(bp);
287 }
288 return;
289 }
290
291 qip->qli_pushbuf_flag = 0;
292 xfs_dqunlock(dqp);
293}
294
295
296
297
298
299
300
301
302
303
304
305STATIC uint
306xfs_qm_dquot_logitem_trylock(
307 xfs_dq_logitem_t *qip)
308{
309 xfs_dquot_t *dqp;
310 uint retval;
311
312 dqp = qip->qli_dquot;
313 if (dqp->q_pincount > 0)
314 return (XFS_ITEM_PINNED);
315
316 if (! xfs_qm_dqlock_nowait(dqp))
317 return (XFS_ITEM_LOCKED);
318
319 retval = XFS_ITEM_SUCCESS;
320 if (!xfs_dqflock_nowait(dqp)) {
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336 if (qip->qli_pushbuf_flag == 0) {
337 qip->qli_pushbuf_flag = 1;
338 ASSERT(qip->qli_format.qlf_blkno == dqp->q_blkno);
339#ifdef DEBUG
340 qip->qli_push_owner = current_pid();
341#endif
342
343
344
345 retval = XFS_ITEM_PUSHBUF;
346 } else {
347 retval = XFS_ITEM_FLUSHING;
348 xfs_dqunlock_nonotify(dqp);
349 }
350 }
351
352 ASSERT(qip->qli_item.li_flags & XFS_LI_IN_AIL);
353 return (retval);
354}
355
356
357
358
359
360
361
362
363STATIC void
364xfs_qm_dquot_logitem_unlock(
365 xfs_dq_logitem_t *ql)
366{
367 xfs_dquot_t *dqp;
368
369 ASSERT(ql != NULL);
370 dqp = ql->qli_dquot;
371 ASSERT(XFS_DQ_IS_LOCKED(dqp));
372
373
374
375
376 dqp->q_transp = NULL;
377
378
379
380
381
382
383
384 xfs_dqunlock(dqp);
385}
386
387
388
389
390
391
392
393
394STATIC void
395xfs_qm_dquot_logitem_committing(
396 xfs_dq_logitem_t *l,
397 xfs_lsn_t lsn)
398{
399 return;
400}
401
402
403
404
405
406static struct xfs_item_ops xfs_dquot_item_ops = {
407 .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_size,
408 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
409 xfs_qm_dquot_logitem_format,
410 .iop_pin = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_pin,
411 .iop_unpin = (void(*)(xfs_log_item_t*, int))
412 xfs_qm_dquot_logitem_unpin,
413 .iop_unpin_remove = (void(*)(xfs_log_item_t*, xfs_trans_t*))
414 xfs_qm_dquot_logitem_unpin_remove,
415 .iop_trylock = (uint(*)(xfs_log_item_t*))
416 xfs_qm_dquot_logitem_trylock,
417 .iop_unlock = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_unlock,
418 .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
419 xfs_qm_dquot_logitem_committed,
420 .iop_push = (void(*)(xfs_log_item_t*))xfs_qm_dquot_logitem_push,
421 .iop_pushbuf = (void(*)(xfs_log_item_t*))
422 xfs_qm_dquot_logitem_pushbuf,
423 .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
424 xfs_qm_dquot_logitem_committing
425};
426
427
428
429
430
431
432void
433xfs_qm_dquot_logitem_init(
434 struct xfs_dquot *dqp)
435{
436 xfs_dq_logitem_t *lp;
437 lp = &dqp->q_logitem;
438
439 lp->qli_item.li_type = XFS_LI_DQUOT;
440 lp->qli_item.li_ops = &xfs_dquot_item_ops;
441 lp->qli_item.li_mountp = dqp->q_mount;
442 lp->qli_dquot = dqp;
443 lp->qli_format.qlf_type = XFS_LI_DQUOT;
444 lp->qli_format.qlf_id = be32_to_cpu(dqp->q_core.d_id);
445 lp->qli_format.qlf_blkno = dqp->q_blkno;
446 lp->qli_format.qlf_len = 1;
447
448
449
450
451
452
453
454 lp->qli_format.qlf_boffset = (__uint32_t)dqp->q_bufoffset;
455}
456
457
458
459
460
461
462
463
464
465STATIC uint
466xfs_qm_qoff_logitem_size(xfs_qoff_logitem_t *qf)
467{
468 return (1);
469}
470
471
472
473
474
475
476
477
478STATIC void
479xfs_qm_qoff_logitem_format(xfs_qoff_logitem_t *qf,
480 xfs_log_iovec_t *log_vector)
481{
482 ASSERT(qf->qql_format.qf_type == XFS_LI_QUOTAOFF);
483
484 log_vector->i_addr = (xfs_caddr_t)&(qf->qql_format);
485 log_vector->i_len = sizeof(xfs_qoff_logitem_t);
486 XLOG_VEC_SET_TYPE(log_vector, XLOG_REG_TYPE_QUOTAOFF);
487 qf->qql_format.qf_size = 1;
488}
489
490
491
492
493
494
495STATIC void
496xfs_qm_qoff_logitem_pin(xfs_qoff_logitem_t *qf)
497{
498 return;
499}
500
501
502
503
504
505
506
507STATIC void
508xfs_qm_qoff_logitem_unpin(xfs_qoff_logitem_t *qf, int stale)
509{
510 return;
511}
512
513
514STATIC void
515xfs_qm_qoff_logitem_unpin_remove(xfs_qoff_logitem_t *qf, xfs_trans_t *tp)
516{
517 return;
518}
519
520
521
522
523
524STATIC uint
525xfs_qm_qoff_logitem_trylock(xfs_qoff_logitem_t *qf)
526{
527 return XFS_ITEM_LOCKED;
528}
529
530
531
532
533
534
535STATIC void
536xfs_qm_qoff_logitem_unlock(xfs_qoff_logitem_t *qf)
537{
538 return;
539}
540
541
542
543
544
545
546STATIC xfs_lsn_t
547xfs_qm_qoff_logitem_committed(xfs_qoff_logitem_t *qf, xfs_lsn_t lsn)
548{
549 return (lsn);
550}
551
552
553
554
555
556
557STATIC void
558xfs_qm_qoff_logitem_push(xfs_qoff_logitem_t *qf)
559{
560 return;
561}
562
563
564
565STATIC xfs_lsn_t
566xfs_qm_qoffend_logitem_committed(
567 xfs_qoff_logitem_t *qfe,
568 xfs_lsn_t lsn)
569{
570 xfs_qoff_logitem_t *qfs;
571
572 qfs = qfe->qql_start_lip;
573 spin_lock(&qfs->qql_item.li_mountp->m_ail_lock);
574
575
576
577
578 xfs_trans_delete_ail(qfs->qql_item.li_mountp, (xfs_log_item_t *)qfs);
579 kmem_free(qfs);
580 kmem_free(qfe);
581 return (xfs_lsn_t)-1;
582}
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599STATIC void
600xfs_qm_qoff_logitem_committing(xfs_qoff_logitem_t *qip, xfs_lsn_t commit_lsn)
601{
602 return;
603}
604
605
606STATIC void
607xfs_qm_qoffend_logitem_committing(xfs_qoff_logitem_t *qip, xfs_lsn_t commit_lsn)
608{
609 return;
610}
611
612static struct xfs_item_ops xfs_qm_qoffend_logitem_ops = {
613 .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_size,
614 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
615 xfs_qm_qoff_logitem_format,
616 .iop_pin = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_pin,
617 .iop_unpin = (void(*)(xfs_log_item_t* ,int))
618 xfs_qm_qoff_logitem_unpin,
619 .iop_unpin_remove = (void(*)(xfs_log_item_t*,xfs_trans_t*))
620 xfs_qm_qoff_logitem_unpin_remove,
621 .iop_trylock = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_trylock,
622 .iop_unlock = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_unlock,
623 .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
624 xfs_qm_qoffend_logitem_committed,
625 .iop_push = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_push,
626 .iop_pushbuf = NULL,
627 .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
628 xfs_qm_qoffend_logitem_committing
629};
630
631
632
633
634static struct xfs_item_ops xfs_qm_qoff_logitem_ops = {
635 .iop_size = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_size,
636 .iop_format = (void(*)(xfs_log_item_t*, xfs_log_iovec_t*))
637 xfs_qm_qoff_logitem_format,
638 .iop_pin = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_pin,
639 .iop_unpin = (void(*)(xfs_log_item_t*, int))
640 xfs_qm_qoff_logitem_unpin,
641 .iop_unpin_remove = (void(*)(xfs_log_item_t*,xfs_trans_t*))
642 xfs_qm_qoff_logitem_unpin_remove,
643 .iop_trylock = (uint(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_trylock,
644 .iop_unlock = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_unlock,
645 .iop_committed = (xfs_lsn_t(*)(xfs_log_item_t*, xfs_lsn_t))
646 xfs_qm_qoff_logitem_committed,
647 .iop_push = (void(*)(xfs_log_item_t*))xfs_qm_qoff_logitem_push,
648 .iop_pushbuf = NULL,
649 .iop_committing = (void(*)(xfs_log_item_t*, xfs_lsn_t))
650 xfs_qm_qoff_logitem_committing
651};
652
653
654
655
656xfs_qoff_logitem_t *
657xfs_qm_qoff_logitem_init(
658 struct xfs_mount *mp,
659 xfs_qoff_logitem_t *start,
660 uint flags)
661{
662 xfs_qoff_logitem_t *qf;
663
664 qf = (xfs_qoff_logitem_t*) kmem_zalloc(sizeof(xfs_qoff_logitem_t), KM_SLEEP);
665
666 qf->qql_item.li_type = XFS_LI_QUOTAOFF;
667 if (start)
668 qf->qql_item.li_ops = &xfs_qm_qoffend_logitem_ops;
669 else
670 qf->qql_item.li_ops = &xfs_qm_qoff_logitem_ops;
671 qf->qql_item.li_mountp = mp;
672 qf->qql_format.qf_type = XFS_LI_QUOTAOFF;
673 qf->qql_format.qf_flags = flags;
674 qf->qql_start_lip = start;
675 return (qf);
676}