This source file includes following definitions.
- xfs_trans_buf_item_match
- _xfs_trans_bjoin
- xfs_trans_bjoin
- xfs_trans_get_buf_map
- xfs_trans_getsb
- xfs_trans_read_buf_map
- xfs_trans_buf_is_dirty
- xfs_trans_brelse
- xfs_trans_bhold
- xfs_trans_bhold_release
- xfs_trans_dirty_buf
- xfs_trans_log_buf
- xfs_trans_binval
- xfs_trans_inode_buf
- xfs_trans_stale_inode_buf
- xfs_trans_inode_alloc_buf
- xfs_trans_ordered_buf
- xfs_trans_buf_set_type
- xfs_trans_buf_copy_type
- xfs_trans_dquot_buf
1
2
3
4
5
6 #include "xfs.h"
7 #include "xfs_fs.h"
8 #include "xfs_shared.h"
9 #include "xfs_format.h"
10 #include "xfs_log_format.h"
11 #include "xfs_trans_resv.h"
12 #include "xfs_mount.h"
13 #include "xfs_trans.h"
14 #include "xfs_buf_item.h"
15 #include "xfs_trans_priv.h"
16 #include "xfs_trace.h"
17
18
19
20
21
22 STATIC struct xfs_buf *
23 xfs_trans_buf_item_match(
24 struct xfs_trans *tp,
25 struct xfs_buftarg *target,
26 struct xfs_buf_map *map,
27 int nmaps)
28 {
29 struct xfs_log_item *lip;
30 struct xfs_buf_log_item *blip;
31 int len = 0;
32 int i;
33
34 for (i = 0; i < nmaps; i++)
35 len += map[i].bm_len;
36
37 list_for_each_entry(lip, &tp->t_items, li_trans) {
38 blip = (struct xfs_buf_log_item *)lip;
39 if (blip->bli_item.li_type == XFS_LI_BUF &&
40 blip->bli_buf->b_target == target &&
41 XFS_BUF_ADDR(blip->bli_buf) == map[0].bm_bn &&
42 blip->bli_buf->b_length == len) {
43 ASSERT(blip->bli_buf->b_map_count == nmaps);
44 return blip->bli_buf;
45 }
46 }
47
48 return NULL;
49 }
50
51
52
53
54
55
56
57
58
59
60 STATIC void
61 _xfs_trans_bjoin(
62 struct xfs_trans *tp,
63 struct xfs_buf *bp,
64 int reset_recur)
65 {
66 struct xfs_buf_log_item *bip;
67
68 ASSERT(bp->b_transp == NULL);
69
70
71
72
73
74
75 xfs_buf_item_init(bp, tp->t_mountp);
76 bip = bp->b_log_item;
77 ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
78 ASSERT(!(bip->__bli_format.blf_flags & XFS_BLF_CANCEL));
79 ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
80 if (reset_recur)
81 bip->bli_recur = 0;
82
83
84
85
86 atomic_inc(&bip->bli_refcount);
87
88
89
90
91
92 xfs_trans_add_item(tp, &bip->bli_item);
93 bp->b_transp = tp;
94
95 }
96
97 void
98 xfs_trans_bjoin(
99 struct xfs_trans *tp,
100 struct xfs_buf *bp)
101 {
102 _xfs_trans_bjoin(tp, bp, 0);
103 trace_xfs_trans_bjoin(bp->b_log_item);
104 }
105
106
107
108
109
110
111
112
113
114
115 struct xfs_buf *
116 xfs_trans_get_buf_map(
117 struct xfs_trans *tp,
118 struct xfs_buftarg *target,
119 struct xfs_buf_map *map,
120 int nmaps,
121 xfs_buf_flags_t flags)
122 {
123 xfs_buf_t *bp;
124 struct xfs_buf_log_item *bip;
125
126 if (!tp)
127 return xfs_buf_get_map(target, map, nmaps, flags);
128
129
130
131
132
133
134
135 bp = xfs_trans_buf_item_match(tp, target, map, nmaps);
136 if (bp != NULL) {
137 ASSERT(xfs_buf_islocked(bp));
138 if (XFS_FORCED_SHUTDOWN(tp->t_mountp)) {
139 xfs_buf_stale(bp);
140 bp->b_flags |= XBF_DONE;
141 }
142
143 ASSERT(bp->b_transp == tp);
144 bip = bp->b_log_item;
145 ASSERT(bip != NULL);
146 ASSERT(atomic_read(&bip->bli_refcount) > 0);
147 bip->bli_recur++;
148 trace_xfs_trans_get_buf_recur(bip);
149 return bp;
150 }
151
152 bp = xfs_buf_get_map(target, map, nmaps, flags);
153 if (bp == NULL) {
154 return NULL;
155 }
156
157 ASSERT(!bp->b_error);
158
159 _xfs_trans_bjoin(tp, bp, 1);
160 trace_xfs_trans_get_buf(bp->b_log_item);
161 return bp;
162 }
163
164
165
166
167
168
169
170
171
172 xfs_buf_t *
173 xfs_trans_getsb(
174 xfs_trans_t *tp,
175 struct xfs_mount *mp)
176 {
177 xfs_buf_t *bp;
178 struct xfs_buf_log_item *bip;
179
180
181
182
183
184 if (tp == NULL)
185 return xfs_getsb(mp);
186
187
188
189
190
191
192
193 bp = mp->m_sb_bp;
194 if (bp->b_transp == tp) {
195 bip = bp->b_log_item;
196 ASSERT(bip != NULL);
197 ASSERT(atomic_read(&bip->bli_refcount) > 0);
198 bip->bli_recur++;
199 trace_xfs_trans_getsb_recur(bip);
200 return bp;
201 }
202
203 bp = xfs_getsb(mp);
204 if (bp == NULL)
205 return NULL;
206
207 _xfs_trans_bjoin(tp, bp, 1);
208 trace_xfs_trans_getsb(bp->b_log_item);
209 return bp;
210 }
211
212
213
214
215
216
217
218
219
220
221
222 int
223 xfs_trans_read_buf_map(
224 struct xfs_mount *mp,
225 struct xfs_trans *tp,
226 struct xfs_buftarg *target,
227 struct xfs_buf_map *map,
228 int nmaps,
229 xfs_buf_flags_t flags,
230 struct xfs_buf **bpp,
231 const struct xfs_buf_ops *ops)
232 {
233 struct xfs_buf *bp = NULL;
234 struct xfs_buf_log_item *bip;
235 int error;
236
237 *bpp = NULL;
238
239
240
241
242
243
244
245
246 if (tp)
247 bp = xfs_trans_buf_item_match(tp, target, map, nmaps);
248 if (bp) {
249 ASSERT(xfs_buf_islocked(bp));
250 ASSERT(bp->b_transp == tp);
251 ASSERT(bp->b_log_item != NULL);
252 ASSERT(!bp->b_error);
253 ASSERT(bp->b_flags & XBF_DONE);
254
255
256
257
258
259 if (XFS_FORCED_SHUTDOWN(mp)) {
260 trace_xfs_trans_read_buf_shut(bp, _RET_IP_);
261 return -EIO;
262 }
263
264
265
266
267
268
269
270
271
272
273
274
275
276 ASSERT(bp->b_ops != NULL);
277 error = xfs_buf_reverify(bp, ops);
278 if (error) {
279 xfs_buf_ioerror_alert(bp, __func__);
280
281 if (tp->t_flags & XFS_TRANS_DIRTY)
282 xfs_force_shutdown(tp->t_mountp,
283 SHUTDOWN_META_IO_ERROR);
284
285
286 if (error == -EFSBADCRC)
287 error = -EFSCORRUPTED;
288 return error;
289 }
290
291 bip = bp->b_log_item;
292 bip->bli_recur++;
293
294 ASSERT(atomic_read(&bip->bli_refcount) > 0);
295 trace_xfs_trans_read_buf_recur(bip);
296 ASSERT(bp->b_ops != NULL || ops == NULL);
297 *bpp = bp;
298 return 0;
299 }
300
301 bp = xfs_buf_read_map(target, map, nmaps, flags, ops);
302 if (!bp) {
303 if (!(flags & XBF_TRYLOCK))
304 return -ENOMEM;
305 return tp ? 0 : -EAGAIN;
306 }
307
308
309
310
311
312
313
314
315
316
317 if (bp->b_error) {
318 error = bp->b_error;
319 if (!XFS_FORCED_SHUTDOWN(mp))
320 xfs_buf_ioerror_alert(bp, __func__);
321 bp->b_flags &= ~XBF_DONE;
322 xfs_buf_stale(bp);
323
324 if (tp && (tp->t_flags & XFS_TRANS_DIRTY))
325 xfs_force_shutdown(tp->t_mountp, SHUTDOWN_META_IO_ERROR);
326 xfs_buf_relse(bp);
327
328
329 if (error == -EFSBADCRC)
330 error = -EFSCORRUPTED;
331 return error;
332 }
333
334 if (XFS_FORCED_SHUTDOWN(mp)) {
335 xfs_buf_relse(bp);
336 trace_xfs_trans_read_buf_shut(bp, _RET_IP_);
337 return -EIO;
338 }
339
340 if (tp) {
341 _xfs_trans_bjoin(tp, bp, 1);
342 trace_xfs_trans_read_buf(bp->b_log_item);
343 }
344 ASSERT(bp->b_ops != NULL || ops == NULL);
345 *bpp = bp;
346 return 0;
347
348 }
349
350
351 bool
352 xfs_trans_buf_is_dirty(
353 struct xfs_buf *bp)
354 {
355 struct xfs_buf_log_item *bip = bp->b_log_item;
356
357 if (!bip)
358 return false;
359 ASSERT(bip->bli_item.li_type == XFS_LI_BUF);
360 return test_bit(XFS_LI_DIRTY, &bip->bli_item.li_flags);
361 }
362
363
364
365
366
367
368
369
370
371
372
373
374
375 void
376 xfs_trans_brelse(
377 struct xfs_trans *tp,
378 struct xfs_buf *bp)
379 {
380 struct xfs_buf_log_item *bip = bp->b_log_item;
381
382 ASSERT(bp->b_transp == tp);
383
384 if (!tp) {
385 xfs_buf_relse(bp);
386 return;
387 }
388
389 trace_xfs_trans_brelse(bip);
390 ASSERT(bip->bli_item.li_type == XFS_LI_BUF);
391 ASSERT(atomic_read(&bip->bli_refcount) > 0);
392
393
394
395
396
397 if (bip->bli_recur > 0) {
398 bip->bli_recur--;
399 return;
400 }
401
402
403
404
405
406 if (test_bit(XFS_LI_DIRTY, &bip->bli_item.li_flags))
407 return;
408 if (bip->bli_flags & XFS_BLI_STALE)
409 return;
410
411
412
413
414
415 ASSERT(!(bip->bli_flags & XFS_BLI_LOGGED));
416 xfs_trans_del_item(&bip->bli_item);
417 bip->bli_flags &= ~XFS_BLI_HOLD;
418
419
420 xfs_buf_item_put(bip);
421
422 bp->b_transp = NULL;
423 xfs_buf_relse(bp);
424 }
425
426
427
428
429
430
431
432 void
433 xfs_trans_bhold(
434 xfs_trans_t *tp,
435 xfs_buf_t *bp)
436 {
437 struct xfs_buf_log_item *bip = bp->b_log_item;
438
439 ASSERT(bp->b_transp == tp);
440 ASSERT(bip != NULL);
441 ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
442 ASSERT(!(bip->__bli_format.blf_flags & XFS_BLF_CANCEL));
443 ASSERT(atomic_read(&bip->bli_refcount) > 0);
444
445 bip->bli_flags |= XFS_BLI_HOLD;
446 trace_xfs_trans_bhold(bip);
447 }
448
449
450
451
452
453 void
454 xfs_trans_bhold_release(
455 xfs_trans_t *tp,
456 xfs_buf_t *bp)
457 {
458 struct xfs_buf_log_item *bip = bp->b_log_item;
459
460 ASSERT(bp->b_transp == tp);
461 ASSERT(bip != NULL);
462 ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
463 ASSERT(!(bip->__bli_format.blf_flags & XFS_BLF_CANCEL));
464 ASSERT(atomic_read(&bip->bli_refcount) > 0);
465 ASSERT(bip->bli_flags & XFS_BLI_HOLD);
466
467 bip->bli_flags &= ~XFS_BLI_HOLD;
468 trace_xfs_trans_bhold_release(bip);
469 }
470
471
472
473
474 void
475 xfs_trans_dirty_buf(
476 struct xfs_trans *tp,
477 struct xfs_buf *bp)
478 {
479 struct xfs_buf_log_item *bip = bp->b_log_item;
480
481 ASSERT(bp->b_transp == tp);
482 ASSERT(bip != NULL);
483 ASSERT(bp->b_iodone == NULL ||
484 bp->b_iodone == xfs_buf_iodone_callbacks);
485
486
487
488
489
490
491
492
493
494
495
496 bp->b_flags |= XBF_DONE;
497
498 ASSERT(atomic_read(&bip->bli_refcount) > 0);
499 bp->b_iodone = xfs_buf_iodone_callbacks;
500 bip->bli_item.li_cb = xfs_buf_iodone;
501
502
503
504
505
506
507
508 if (bip->bli_flags & XFS_BLI_STALE) {
509 bip->bli_flags &= ~XFS_BLI_STALE;
510 ASSERT(bp->b_flags & XBF_STALE);
511 bp->b_flags &= ~XBF_STALE;
512 bip->__bli_format.blf_flags &= ~XFS_BLF_CANCEL;
513 }
514 bip->bli_flags |= XFS_BLI_DIRTY | XFS_BLI_LOGGED;
515
516 tp->t_flags |= XFS_TRANS_DIRTY;
517 set_bit(XFS_LI_DIRTY, &bip->bli_item.li_flags);
518 }
519
520
521
522
523
524
525
526
527
528
529 void
530 xfs_trans_log_buf(
531 struct xfs_trans *tp,
532 struct xfs_buf *bp,
533 uint first,
534 uint last)
535 {
536 struct xfs_buf_log_item *bip = bp->b_log_item;
537
538 ASSERT(first <= last && last < BBTOB(bp->b_length));
539 ASSERT(!(bip->bli_flags & XFS_BLI_ORDERED));
540
541 xfs_trans_dirty_buf(tp, bp);
542
543 trace_xfs_trans_log_buf(bip);
544 xfs_buf_item_log(bip, first, last);
545 }
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577 void
578 xfs_trans_binval(
579 xfs_trans_t *tp,
580 xfs_buf_t *bp)
581 {
582 struct xfs_buf_log_item *bip = bp->b_log_item;
583 int i;
584
585 ASSERT(bp->b_transp == tp);
586 ASSERT(bip != NULL);
587 ASSERT(atomic_read(&bip->bli_refcount) > 0);
588
589 trace_xfs_trans_binval(bip);
590
591 if (bip->bli_flags & XFS_BLI_STALE) {
592
593
594
595
596 ASSERT(bp->b_flags & XBF_STALE);
597 ASSERT(!(bip->bli_flags & (XFS_BLI_LOGGED | XFS_BLI_DIRTY)));
598 ASSERT(!(bip->__bli_format.blf_flags & XFS_BLF_INODE_BUF));
599 ASSERT(!(bip->__bli_format.blf_flags & XFS_BLFT_MASK));
600 ASSERT(bip->__bli_format.blf_flags & XFS_BLF_CANCEL);
601 ASSERT(test_bit(XFS_LI_DIRTY, &bip->bli_item.li_flags));
602 ASSERT(tp->t_flags & XFS_TRANS_DIRTY);
603 return;
604 }
605
606 xfs_buf_stale(bp);
607
608 bip->bli_flags |= XFS_BLI_STALE;
609 bip->bli_flags &= ~(XFS_BLI_INODE_BUF | XFS_BLI_LOGGED | XFS_BLI_DIRTY);
610 bip->__bli_format.blf_flags &= ~XFS_BLF_INODE_BUF;
611 bip->__bli_format.blf_flags |= XFS_BLF_CANCEL;
612 bip->__bli_format.blf_flags &= ~XFS_BLFT_MASK;
613 for (i = 0; i < bip->bli_format_count; i++) {
614 memset(bip->bli_formats[i].blf_data_map, 0,
615 (bip->bli_formats[i].blf_map_size * sizeof(uint)));
616 }
617 set_bit(XFS_LI_DIRTY, &bip->bli_item.li_flags);
618 tp->t_flags |= XFS_TRANS_DIRTY;
619 }
620
621
622
623
624
625
626
627
628
629
630
631
632 void
633 xfs_trans_inode_buf(
634 xfs_trans_t *tp,
635 xfs_buf_t *bp)
636 {
637 struct xfs_buf_log_item *bip = bp->b_log_item;
638
639 ASSERT(bp->b_transp == tp);
640 ASSERT(bip != NULL);
641 ASSERT(atomic_read(&bip->bli_refcount) > 0);
642
643 bip->bli_flags |= XFS_BLI_INODE_BUF;
644 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DINO_BUF);
645 }
646
647
648
649
650
651
652
653
654
655
656 void
657 xfs_trans_stale_inode_buf(
658 xfs_trans_t *tp,
659 xfs_buf_t *bp)
660 {
661 struct xfs_buf_log_item *bip = bp->b_log_item;
662
663 ASSERT(bp->b_transp == tp);
664 ASSERT(bip != NULL);
665 ASSERT(atomic_read(&bip->bli_refcount) > 0);
666
667 bip->bli_flags |= XFS_BLI_STALE_INODE;
668 bip->bli_item.li_cb = xfs_buf_iodone;
669 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DINO_BUF);
670 }
671
672
673
674
675
676
677
678
679
680
681 void
682 xfs_trans_inode_alloc_buf(
683 xfs_trans_t *tp,
684 xfs_buf_t *bp)
685 {
686 struct xfs_buf_log_item *bip = bp->b_log_item;
687
688 ASSERT(bp->b_transp == tp);
689 ASSERT(bip != NULL);
690 ASSERT(atomic_read(&bip->bli_refcount) > 0);
691
692 bip->bli_flags |= XFS_BLI_INODE_ALLOC_BUF;
693 xfs_trans_buf_set_type(tp, bp, XFS_BLFT_DINO_BUF);
694 }
695
696
697
698
699
700
701
702
703 bool
704 xfs_trans_ordered_buf(
705 struct xfs_trans *tp,
706 struct xfs_buf *bp)
707 {
708 struct xfs_buf_log_item *bip = bp->b_log_item;
709
710 ASSERT(bp->b_transp == tp);
711 ASSERT(bip != NULL);
712 ASSERT(atomic_read(&bip->bli_refcount) > 0);
713
714 if (xfs_buf_item_dirty_format(bip))
715 return false;
716
717 bip->bli_flags |= XFS_BLI_ORDERED;
718 trace_xfs_buf_item_ordered(bip);
719
720
721
722
723
724 xfs_trans_dirty_buf(tp, bp);
725 return true;
726 }
727
728
729
730
731
732 void
733 xfs_trans_buf_set_type(
734 struct xfs_trans *tp,
735 struct xfs_buf *bp,
736 enum xfs_blft type)
737 {
738 struct xfs_buf_log_item *bip = bp->b_log_item;
739
740 if (!tp)
741 return;
742
743 ASSERT(bp->b_transp == tp);
744 ASSERT(bip != NULL);
745 ASSERT(atomic_read(&bip->bli_refcount) > 0);
746
747 xfs_blft_to_flags(&bip->__bli_format, type);
748 }
749
750 void
751 xfs_trans_buf_copy_type(
752 struct xfs_buf *dst_bp,
753 struct xfs_buf *src_bp)
754 {
755 struct xfs_buf_log_item *sbip = src_bp->b_log_item;
756 struct xfs_buf_log_item *dbip = dst_bp->b_log_item;
757 enum xfs_blft type;
758
759 type = xfs_blft_from_flags(&sbip->__bli_format);
760 xfs_blft_to_flags(&dbip->__bli_format, type);
761 }
762
763
764
765
766
767
768
769
770
771
772
773
774 void
775 xfs_trans_dquot_buf(
776 xfs_trans_t *tp,
777 xfs_buf_t *bp,
778 uint type)
779 {
780 struct xfs_buf_log_item *bip = bp->b_log_item;
781
782 ASSERT(type == XFS_BLF_UDQUOT_BUF ||
783 type == XFS_BLF_PDQUOT_BUF ||
784 type == XFS_BLF_GDQUOT_BUF);
785
786 bip->__bli_format.blf_flags |= type;
787
788 switch (type) {
789 case XFS_BLF_UDQUOT_BUF:
790 type = XFS_BLFT_UDQUOT_BUF;
791 break;
792 case XFS_BLF_PDQUOT_BUF:
793 type = XFS_BLFT_PDQUOT_BUF;
794 break;
795 case XFS_BLF_GDQUOT_BUF:
796 type = XFS_BLFT_GDQUOT_BUF;
797 break;
798 default:
799 type = XFS_BLFT_UNKNOWN_BUF;
800 break;
801 }
802
803 xfs_trans_buf_set_type(tp, bp, type);
804 }