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_types.h"
21#include "xfs_bit.h"
22#include "xfs_log.h"
23#include "xfs_inum.h"
24#include "xfs_trans.h"
25#include "xfs_sb.h"
26#include "xfs_ag.h"
27#include "xfs_dir2.h"
28#include "xfs_dmapi.h"
29#include "xfs_mount.h"
30#include "xfs_bmap_btree.h"
31#include "xfs_alloc_btree.h"
32#include "xfs_ialloc_btree.h"
33#include "xfs_dir2_sf.h"
34#include "xfs_attr_sf.h"
35#include "xfs_dinode.h"
36#include "xfs_inode.h"
37#include "xfs_buf_item.h"
38#include "xfs_trans_priv.h"
39#include "xfs_error.h"
40#include "xfs_rw.h"
41
42
43STATIC xfs_buf_t *xfs_trans_buf_item_match(xfs_trans_t *, xfs_buftarg_t *,
44 xfs_daddr_t, int);
45STATIC xfs_buf_t *xfs_trans_buf_item_match_all(xfs_trans_t *, xfs_buftarg_t *,
46 xfs_daddr_t, int);
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66xfs_buf_t *
67xfs_trans_get_buf(xfs_trans_t *tp,
68 xfs_buftarg_t *target_dev,
69 xfs_daddr_t blkno,
70 int len,
71 uint flags)
72{
73 xfs_buf_t *bp;
74 xfs_buf_log_item_t *bip;
75
76 if (flags == 0)
77 flags = XFS_BUF_LOCK | XFS_BUF_MAPPED;
78
79
80
81
82 if (tp == NULL) {
83 bp = xfs_buf_get_flags(target_dev, blkno, len,
84 flags | BUF_BUSY);
85 return(bp);
86 }
87
88
89
90
91
92
93
94 if (tp->t_items.lic_next == NULL) {
95 bp = xfs_trans_buf_item_match(tp, target_dev, blkno, len);
96 } else {
97 bp = xfs_trans_buf_item_match_all(tp, target_dev, blkno, len);
98 }
99 if (bp != NULL) {
100 ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);
101 if (XFS_FORCED_SHUTDOWN(tp->t_mountp)) {
102 xfs_buftrace("TRANS GET RECUR SHUT", bp);
103 XFS_BUF_SUPER_STALE(bp);
104 }
105
106
107
108
109
110 else if (XFS_BUF_ISSTALE(bp)) {
111 xfs_buftrace("TRANS GET RECUR STALE", bp);
112 ASSERT(!XFS_BUF_ISDELAYWRITE(bp));
113 }
114 ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
115 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
116 ASSERT(bip != NULL);
117 ASSERT(atomic_read(&bip->bli_refcount) > 0);
118 bip->bli_recur++;
119 xfs_buftrace("TRANS GET RECUR", bp);
120 xfs_buf_item_trace("GET RECUR", bip);
121 return (bp);
122 }
123
124
125
126
127
128
129
130
131
132 bp = xfs_buf_get_flags(target_dev, blkno, len, flags | BUF_BUSY);
133 if (bp == NULL) {
134 return NULL;
135 }
136
137 ASSERT(!XFS_BUF_GETERROR(bp));
138
139
140
141
142
143
144 xfs_buf_item_init(bp, tp->t_mountp);
145
146
147
148
149
150 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t*);
151 ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
152 ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL));
153 ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
154 bip->bli_recur = 0;
155
156
157
158
159 atomic_inc(&bip->bli_refcount);
160
161
162
163
164 (void) xfs_trans_add_item(tp, (xfs_log_item_t*)bip);
165
166
167
168
169
170 XFS_BUF_SET_FSPRIVATE2(bp, tp);
171
172 xfs_buftrace("TRANS GET", bp);
173 xfs_buf_item_trace("GET", bip);
174 return (bp);
175}
176
177
178
179
180
181
182
183
184
185xfs_buf_t *
186xfs_trans_getsb(xfs_trans_t *tp,
187 struct xfs_mount *mp,
188 int flags)
189{
190 xfs_buf_t *bp;
191 xfs_buf_log_item_t *bip;
192
193
194
195
196
197 if (tp == NULL) {
198 return (xfs_getsb(mp, flags));
199 }
200
201
202
203
204
205
206
207 bp = mp->m_sb_bp;
208 if (XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp) {
209 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t*);
210 ASSERT(bip != NULL);
211 ASSERT(atomic_read(&bip->bli_refcount) > 0);
212 bip->bli_recur++;
213 xfs_buf_item_trace("GETSB RECUR", bip);
214 return (bp);
215 }
216
217 bp = xfs_getsb(mp, flags);
218 if (bp == NULL) {
219 return NULL;
220 }
221
222
223
224
225
226
227 xfs_buf_item_init(bp, mp);
228
229
230
231
232
233 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t*);
234 ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
235 ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL));
236 ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
237 bip->bli_recur = 0;
238
239
240
241
242 atomic_inc(&bip->bli_refcount);
243
244
245
246
247 (void) xfs_trans_add_item(tp, (xfs_log_item_t*)bip);
248
249
250
251
252
253 XFS_BUF_SET_FSPRIVATE2(bp, tp);
254
255 xfs_buf_item_trace("GETSB", bip);
256 return (bp);
257}
258
259#ifdef DEBUG
260xfs_buftarg_t *xfs_error_target;
261int xfs_do_error;
262int xfs_req_num;
263int xfs_error_mod = 33;
264#endif
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284int
285xfs_trans_read_buf(
286 xfs_mount_t *mp,
287 xfs_trans_t *tp,
288 xfs_buftarg_t *target,
289 xfs_daddr_t blkno,
290 int len,
291 uint flags,
292 xfs_buf_t **bpp)
293{
294 xfs_buf_t *bp;
295 xfs_buf_log_item_t *bip;
296 int error;
297
298 if (flags == 0)
299 flags = XFS_BUF_LOCK | XFS_BUF_MAPPED;
300
301
302
303
304 if (tp == NULL) {
305 bp = xfs_buf_read_flags(target, blkno, len, flags | BUF_BUSY);
306 if (!bp)
307 return (flags & XFS_BUF_TRYLOCK) ?
308 EAGAIN : XFS_ERROR(ENOMEM);
309
310 if ((bp != NULL) && (XFS_BUF_GETERROR(bp) != 0)) {
311 xfs_ioerror_alert("xfs_trans_read_buf", mp,
312 bp, blkno);
313 error = XFS_BUF_GETERROR(bp);
314 xfs_buf_relse(bp);
315 return error;
316 }
317#ifdef DEBUG
318 if (xfs_do_error && (bp != NULL)) {
319 if (xfs_error_target == target) {
320 if (((xfs_req_num++) % xfs_error_mod) == 0) {
321 xfs_buf_relse(bp);
322 cmn_err(CE_DEBUG, "Returning error!\n");
323 return XFS_ERROR(EIO);
324 }
325 }
326 }
327#endif
328 if (XFS_FORCED_SHUTDOWN(mp))
329 goto shutdown_abort;
330 *bpp = bp;
331 return 0;
332 }
333
334
335
336
337
338
339
340
341
342 if (tp->t_items.lic_next == NULL) {
343 bp = xfs_trans_buf_item_match(tp, target, blkno, len);
344 } else {
345 bp = xfs_trans_buf_item_match_all(tp, target, blkno, len);
346 }
347 if (bp != NULL) {
348 ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);
349 ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
350 ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
351 ASSERT((XFS_BUF_ISERROR(bp)) == 0);
352 if (!(XFS_BUF_ISDONE(bp))) {
353 xfs_buftrace("READ_BUF_INCORE !DONE", bp);
354 ASSERT(!XFS_BUF_ISASYNC(bp));
355 XFS_BUF_READ(bp);
356 xfsbdstrat(tp->t_mountp, bp);
357 error = xfs_iowait(bp);
358 if (error) {
359 xfs_ioerror_alert("xfs_trans_read_buf", mp,
360 bp, blkno);
361 xfs_buf_relse(bp);
362
363
364
365
366
367 if (tp->t_flags & XFS_TRANS_DIRTY)
368 xfs_force_shutdown(tp->t_mountp,
369 SHUTDOWN_META_IO_ERROR);
370 return error;
371 }
372 }
373
374
375
376
377 if (XFS_FORCED_SHUTDOWN(mp)) {
378 xfs_buftrace("READ_BUF_INCORE XFSSHUTDN", bp);
379 *bpp = NULL;
380 return XFS_ERROR(EIO);
381 }
382
383
384 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t*);
385 bip->bli_recur++;
386
387 ASSERT(atomic_read(&bip->bli_refcount) > 0);
388 xfs_buf_item_trace("READ RECUR", bip);
389 *bpp = bp;
390 return 0;
391 }
392
393
394
395
396
397
398
399
400
401 bp = xfs_buf_read_flags(target, blkno, len, flags | BUF_BUSY);
402 if (bp == NULL) {
403 *bpp = NULL;
404 return 0;
405 }
406 if (XFS_BUF_GETERROR(bp) != 0) {
407 XFS_BUF_SUPER_STALE(bp);
408 xfs_buftrace("READ ERROR", bp);
409 error = XFS_BUF_GETERROR(bp);
410
411 xfs_ioerror_alert("xfs_trans_read_buf", mp,
412 bp, blkno);
413 if (tp->t_flags & XFS_TRANS_DIRTY)
414 xfs_force_shutdown(tp->t_mountp, SHUTDOWN_META_IO_ERROR);
415 xfs_buf_relse(bp);
416 return error;
417 }
418#ifdef DEBUG
419 if (xfs_do_error && !(tp->t_flags & XFS_TRANS_DIRTY)) {
420 if (xfs_error_target == target) {
421 if (((xfs_req_num++) % xfs_error_mod) == 0) {
422 xfs_force_shutdown(tp->t_mountp,
423 SHUTDOWN_META_IO_ERROR);
424 xfs_buf_relse(bp);
425 cmn_err(CE_DEBUG, "Returning trans error!\n");
426 return XFS_ERROR(EIO);
427 }
428 }
429 }
430#endif
431 if (XFS_FORCED_SHUTDOWN(mp))
432 goto shutdown_abort;
433
434
435
436
437
438
439 xfs_buf_item_init(bp, tp->t_mountp);
440
441
442
443
444
445 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t*);
446 ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
447 ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL));
448 ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
449 bip->bli_recur = 0;
450
451
452
453
454 atomic_inc(&bip->bli_refcount);
455
456
457
458
459 (void) xfs_trans_add_item(tp, (xfs_log_item_t*)bip);
460
461
462
463
464
465 XFS_BUF_SET_FSPRIVATE2(bp, tp);
466
467 xfs_buftrace("TRANS READ", bp);
468 xfs_buf_item_trace("READ", bip);
469 *bpp = bp;
470 return 0;
471
472shutdown_abort:
473
474
475
476
477
478
479#if defined(DEBUG)
480 if (XFS_BUF_ISSTALE(bp) && XFS_BUF_ISDELAYWRITE(bp))
481 cmn_err(CE_NOTE, "about to pop assert, bp == 0x%p", bp);
482#endif
483 ASSERT((XFS_BUF_BFLAGS(bp) & (XFS_B_STALE|XFS_B_DELWRI)) !=
484 (XFS_B_STALE|XFS_B_DELWRI));
485
486 xfs_buftrace("READ_BUF XFSSHUTDN", bp);
487 xfs_buf_relse(bp);
488 *bpp = NULL;
489 return XFS_ERROR(EIO);
490}
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508void
509xfs_trans_brelse(xfs_trans_t *tp,
510 xfs_buf_t *bp)
511{
512 xfs_buf_log_item_t *bip;
513 xfs_log_item_t *lip;
514 xfs_log_item_desc_t *lidp;
515
516
517
518
519 if (tp == NULL) {
520 ASSERT(XFS_BUF_FSPRIVATE2(bp, void *) == NULL);
521
522
523
524
525
526 if (XFS_BUF_FSPRIVATE(bp, void *) != NULL) {
527 lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *);
528 if (lip->li_type == XFS_LI_BUF) {
529 bip = XFS_BUF_FSPRIVATE(bp,xfs_buf_log_item_t*);
530 xfs_trans_unlocked_item(
531 bip->bli_item.li_mountp,
532 lip);
533 }
534 }
535 xfs_buf_relse(bp);
536 return;
537 }
538
539 ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
540 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
541 ASSERT(bip->bli_item.li_type == XFS_LI_BUF);
542 ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
543 ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL));
544 ASSERT(atomic_read(&bip->bli_refcount) > 0);
545
546
547
548
549
550 lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)bip);
551 ASSERT(lidp != NULL);
552
553
554
555
556
557 if (bip->bli_recur > 0) {
558 bip->bli_recur--;
559 xfs_buf_item_trace("RELSE RECUR", bip);
560 return;
561 }
562
563
564
565
566
567 if (lidp->lid_flags & XFS_LID_DIRTY) {
568 xfs_buf_item_trace("RELSE DIRTY", bip);
569 return;
570 }
571
572
573
574
575
576
577
578 if (bip->bli_flags & XFS_BLI_STALE) {
579 xfs_buf_item_trace("RELSE STALE", bip);
580 return;
581 }
582
583 ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
584 xfs_buf_item_trace("RELSE", bip);
585
586
587
588
589 xfs_trans_free_item(tp, lidp);
590
591
592
593
594
595
596 if (bip->bli_flags & XFS_BLI_HOLD) {
597 bip->bli_flags &= ~XFS_BLI_HOLD;
598 }
599
600
601
602
603 atomic_dec(&bip->bli_refcount);
604
605
606
607
608
609
610
611
612 if (!xfs_buf_item_dirty(bip)) {
613
614
615
616 ASSERT(atomic_read(&bip->bli_refcount) == 0);
617 ASSERT(!(bip->bli_item.li_flags & XFS_LI_IN_AIL));
618 ASSERT(!(bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF));
619 xfs_buf_item_relse(bp);
620 bip = NULL;
621 }
622 XFS_BUF_SET_FSPRIVATE2(bp, NULL);
623
624
625
626
627
628 if (bip != NULL) {
629 xfs_trans_unlocked_item(bip->bli_item.li_mountp,
630 (xfs_log_item_t*)bip);
631 }
632
633 xfs_buf_relse(bp);
634 return;
635}
636
637
638
639
640
641
642
643
644
645void
646xfs_trans_bjoin(xfs_trans_t *tp,
647 xfs_buf_t *bp)
648{
649 xfs_buf_log_item_t *bip;
650
651 ASSERT(XFS_BUF_ISBUSY(bp));
652 ASSERT(XFS_BUF_FSPRIVATE2(bp, void *) == NULL);
653
654
655
656
657
658
659 xfs_buf_item_init(bp, tp->t_mountp);
660 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
661 ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
662 ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL));
663 ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
664
665
666
667
668 atomic_inc(&bip->bli_refcount);
669
670
671
672
673 (void) xfs_trans_add_item(tp, (xfs_log_item_t *)bip);
674
675
676
677
678
679 XFS_BUF_SET_FSPRIVATE2(bp, tp);
680
681 xfs_buf_item_trace("BJOIN", bip);
682}
683
684
685
686
687
688
689
690void
691xfs_trans_bhold(xfs_trans_t *tp,
692 xfs_buf_t *bp)
693{
694 xfs_buf_log_item_t *bip;
695
696 ASSERT(XFS_BUF_ISBUSY(bp));
697 ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
698 ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
699
700 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
701 ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
702 ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL));
703 ASSERT(atomic_read(&bip->bli_refcount) > 0);
704 bip->bli_flags |= XFS_BLI_HOLD;
705 xfs_buf_item_trace("BHOLD", bip);
706}
707
708
709
710
711
712void
713xfs_trans_bhold_release(xfs_trans_t *tp,
714 xfs_buf_t *bp)
715{
716 xfs_buf_log_item_t *bip;
717
718 ASSERT(XFS_BUF_ISBUSY(bp));
719 ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
720 ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
721
722 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
723 ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
724 ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_CANCEL));
725 ASSERT(atomic_read(&bip->bli_refcount) > 0);
726 ASSERT(bip->bli_flags & XFS_BLI_HOLD);
727 bip->bli_flags &= ~XFS_BLI_HOLD;
728 xfs_buf_item_trace("BHOLD RELEASE", bip);
729}
730
731
732
733
734
735
736
737
738
739
740void
741xfs_trans_log_buf(xfs_trans_t *tp,
742 xfs_buf_t *bp,
743 uint first,
744 uint last)
745{
746 xfs_buf_log_item_t *bip;
747 xfs_log_item_desc_t *lidp;
748
749 ASSERT(XFS_BUF_ISBUSY(bp));
750 ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
751 ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
752 ASSERT((first <= last) && (last < XFS_BUF_COUNT(bp)));
753 ASSERT((XFS_BUF_IODONE_FUNC(bp) == NULL) ||
754 (XFS_BUF_IODONE_FUNC(bp) == xfs_buf_iodone_callbacks));
755
756
757
758
759
760
761
762
763
764
765
766 XFS_BUF_DELAYWRITE(bp);
767 XFS_BUF_DONE(bp);
768
769 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
770 ASSERT(atomic_read(&bip->bli_refcount) > 0);
771 XFS_BUF_SET_IODONE_FUNC(bp, xfs_buf_iodone_callbacks);
772 bip->bli_item.li_cb = (void(*)(xfs_buf_t*,xfs_log_item_t*))xfs_buf_iodone;
773
774
775
776
777
778
779
780 if (bip->bli_flags & XFS_BLI_STALE) {
781 xfs_buf_item_trace("BLOG UNSTALE", bip);
782 bip->bli_flags &= ~XFS_BLI_STALE;
783 ASSERT(XFS_BUF_ISSTALE(bp));
784 XFS_BUF_UNSTALE(bp);
785 bip->bli_format.blf_flags &= ~XFS_BLI_CANCEL;
786 }
787
788 lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)bip);
789 ASSERT(lidp != NULL);
790
791 tp->t_flags |= XFS_TRANS_DIRTY;
792 lidp->lid_flags |= XFS_LID_DIRTY;
793 lidp->lid_flags &= ~XFS_LID_BUF_STALE;
794 bip->bli_flags |= XFS_BLI_LOGGED;
795 xfs_buf_item_log(bip, first, last);
796 xfs_buf_item_trace("BLOG", bip);
797}
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818void
819xfs_trans_binval(
820 xfs_trans_t *tp,
821 xfs_buf_t *bp)
822{
823 xfs_log_item_desc_t *lidp;
824 xfs_buf_log_item_t *bip;
825
826 ASSERT(XFS_BUF_ISBUSY(bp));
827 ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
828 ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
829
830 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
831 lidp = xfs_trans_find_item(tp, (xfs_log_item_t*)bip);
832 ASSERT(lidp != NULL);
833 ASSERT(atomic_read(&bip->bli_refcount) > 0);
834
835 if (bip->bli_flags & XFS_BLI_STALE) {
836
837
838
839
840 ASSERT(!(XFS_BUF_ISDELAYWRITE(bp)));
841 ASSERT(XFS_BUF_ISSTALE(bp));
842 ASSERT(!(bip->bli_flags & (XFS_BLI_LOGGED | XFS_BLI_DIRTY)));
843 ASSERT(!(bip->bli_format.blf_flags & XFS_BLI_INODE_BUF));
844 ASSERT(bip->bli_format.blf_flags & XFS_BLI_CANCEL);
845 ASSERT(lidp->lid_flags & XFS_LID_DIRTY);
846 ASSERT(tp->t_flags & XFS_TRANS_DIRTY);
847 xfs_buftrace("XFS_BINVAL RECUR", bp);
848 xfs_buf_item_trace("BINVAL RECUR", bip);
849 return;
850 }
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872 XFS_BUF_UNDELAYWRITE(bp);
873 XFS_BUF_STALE(bp);
874 bip->bli_flags |= XFS_BLI_STALE;
875 bip->bli_flags &= ~(XFS_BLI_LOGGED | XFS_BLI_DIRTY);
876 bip->bli_format.blf_flags &= ~XFS_BLI_INODE_BUF;
877 bip->bli_format.blf_flags |= XFS_BLI_CANCEL;
878 memset((char *)(bip->bli_format.blf_data_map), 0,
879 (bip->bli_format.blf_map_size * sizeof(uint)));
880 lidp->lid_flags |= XFS_LID_DIRTY|XFS_LID_BUF_STALE;
881 tp->t_flags |= XFS_TRANS_DIRTY;
882 xfs_buftrace("XFS_BINVAL", bp);
883 xfs_buf_item_trace("BINVAL", bip);
884}
885
886
887
888
889
890
891
892
893
894
895
896
897void
898xfs_trans_inode_buf(
899 xfs_trans_t *tp,
900 xfs_buf_t *bp)
901{
902 xfs_buf_log_item_t *bip;
903
904 ASSERT(XFS_BUF_ISBUSY(bp));
905 ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
906 ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
907
908 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
909 ASSERT(atomic_read(&bip->bli_refcount) > 0);
910
911 bip->bli_format.blf_flags |= XFS_BLI_INODE_BUF;
912}
913
914
915
916
917
918
919
920
921
922
923void
924xfs_trans_stale_inode_buf(
925 xfs_trans_t *tp,
926 xfs_buf_t *bp)
927{
928 xfs_buf_log_item_t *bip;
929
930 ASSERT(XFS_BUF_ISBUSY(bp));
931 ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
932 ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
933
934 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
935 ASSERT(atomic_read(&bip->bli_refcount) > 0);
936
937 bip->bli_flags |= XFS_BLI_STALE_INODE;
938 bip->bli_item.li_cb = (void(*)(xfs_buf_t*,xfs_log_item_t*))
939 xfs_buf_iodone;
940}
941
942
943
944
945
946
947
948
949
950
951
952
953void
954xfs_trans_inode_alloc_buf(
955 xfs_trans_t *tp,
956 xfs_buf_t *bp)
957{
958 xfs_buf_log_item_t *bip;
959
960 ASSERT(XFS_BUF_ISBUSY(bp));
961 ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
962 ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
963
964 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
965 ASSERT(atomic_read(&bip->bli_refcount) > 0);
966
967 bip->bli_flags |= XFS_BLI_INODE_ALLOC_BUF;
968}
969
970
971
972
973
974
975
976
977
978
979
980
981
982void
983xfs_trans_dquot_buf(
984 xfs_trans_t *tp,
985 xfs_buf_t *bp,
986 uint type)
987{
988 xfs_buf_log_item_t *bip;
989
990 ASSERT(XFS_BUF_ISBUSY(bp));
991 ASSERT(XFS_BUF_FSPRIVATE2(bp, xfs_trans_t *) == tp);
992 ASSERT(XFS_BUF_FSPRIVATE(bp, void *) != NULL);
993 ASSERT(type == XFS_BLI_UDQUOT_BUF ||
994 type == XFS_BLI_PDQUOT_BUF ||
995 type == XFS_BLI_GDQUOT_BUF);
996
997 bip = XFS_BUF_FSPRIVATE(bp, xfs_buf_log_item_t *);
998 ASSERT(atomic_read(&bip->bli_refcount) > 0);
999
1000 bip->bli_format.blf_flags |= type;
1001}
1002
1003
1004
1005
1006
1007
1008STATIC xfs_buf_t *
1009xfs_trans_buf_item_match(
1010 xfs_trans_t *tp,
1011 xfs_buftarg_t *target,
1012 xfs_daddr_t blkno,
1013 int len)
1014{
1015 xfs_log_item_chunk_t *licp;
1016 xfs_log_item_desc_t *lidp;
1017 xfs_buf_log_item_t *blip;
1018 xfs_buf_t *bp;
1019 int i;
1020
1021 bp = NULL;
1022 len = BBTOB(len);
1023 licp = &tp->t_items;
1024 if (!xfs_lic_are_all_free(licp)) {
1025 for (i = 0; i < licp->lic_unused; i++) {
1026
1027
1028
1029 if (xfs_lic_isfree(licp, i)) {
1030 continue;
1031 }
1032
1033 lidp = xfs_lic_slot(licp, i);
1034 blip = (xfs_buf_log_item_t *)lidp->lid_item;
1035 if (blip->bli_item.li_type != XFS_LI_BUF) {
1036 continue;
1037 }
1038
1039 bp = blip->bli_buf;
1040 if ((XFS_BUF_TARGET(bp) == target) &&
1041 (XFS_BUF_ADDR(bp) == blkno) &&
1042 (XFS_BUF_COUNT(bp) == len)) {
1043
1044
1045
1046
1047 break;
1048 } else {
1049 bp = NULL;
1050 }
1051 }
1052 }
1053 return bp;
1054}
1055
1056
1057
1058
1059
1060
1061STATIC xfs_buf_t *
1062xfs_trans_buf_item_match_all(
1063 xfs_trans_t *tp,
1064 xfs_buftarg_t *target,
1065 xfs_daddr_t blkno,
1066 int len)
1067{
1068 xfs_log_item_chunk_t *licp;
1069 xfs_log_item_desc_t *lidp;
1070 xfs_buf_log_item_t *blip;
1071 xfs_buf_t *bp;
1072 int i;
1073
1074 bp = NULL;
1075 len = BBTOB(len);
1076 for (licp = &tp->t_items; licp != NULL; licp = licp->lic_next) {
1077 if (xfs_lic_are_all_free(licp)) {
1078 ASSERT(licp == &tp->t_items);
1079 ASSERT(licp->lic_next == NULL);
1080 return NULL;
1081 }
1082 for (i = 0; i < licp->lic_unused; i++) {
1083
1084
1085
1086 if (xfs_lic_isfree(licp, i)) {
1087 continue;
1088 }
1089
1090 lidp = xfs_lic_slot(licp, i);
1091 blip = (xfs_buf_log_item_t *)lidp->lid_item;
1092 if (blip->bli_item.li_type != XFS_LI_BUF) {
1093 continue;
1094 }
1095
1096 bp = blip->bli_buf;
1097 if ((XFS_BUF_TARGET(bp) == target) &&
1098 (XFS_BUF_ADDR(bp) == blkno) &&
1099 (XFS_BUF_COUNT(bp) == len)) {
1100
1101
1102
1103
1104 return bp;
1105 }
1106 }
1107 }
1108 return NULL;
1109}
1110