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