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_trans.h"
24#include "xfs_sb.h"
25#include "xfs_ag.h"
26#include "xfs_mount.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
33kmem_zone_t *xfs_buf_item_zone;
34
35static inline struct xfs_buf_log_item *BUF_ITEM(struct xfs_log_item *lip)
36{
37 return container_of(lip, struct xfs_buf_log_item, bli_item);
38}
39
40
41#ifdef XFS_TRANS_DEBUG
42
43
44
45
46
47
48
49
50
51STATIC void
52xfs_buf_item_log_debug(
53 xfs_buf_log_item_t *bip,
54 uint first,
55 uint last)
56{
57 uint x;
58 uint byte;
59 uint nbytes;
60 uint chunk_num;
61 uint word_num;
62 uint bit_num;
63 uint bit_set;
64 uint *wordp;
65
66 ASSERT(bip->bli_logged != NULL);
67 byte = first;
68 nbytes = last - first + 1;
69 bfset(bip->bli_logged, first, nbytes);
70 for (x = 0; x < nbytes; x++) {
71 chunk_num = byte >> XFS_BLF_SHIFT;
72 word_num = chunk_num >> BIT_TO_WORD_SHIFT;
73 bit_num = chunk_num & (NBWORD - 1);
74 wordp = &(bip->bli_format.blf_data_map[word_num]);
75 bit_set = *wordp & (1 << bit_num);
76 ASSERT(bit_set);
77 byte++;
78 }
79}
80
81
82
83
84
85
86void
87xfs_buf_item_flush_log_debug(
88 xfs_buf_t *bp,
89 uint first,
90 uint last)
91{
92 xfs_buf_log_item_t *bip = bp->b_fspriv;
93 uint nbytes;
94
95 if (bip == NULL || (bip->bli_item.li_type != XFS_LI_BUF))
96 return;
97
98 ASSERT(bip->bli_logged != NULL);
99 nbytes = last - first + 1;
100 bfset(bip->bli_logged, first, nbytes);
101}
102
103
104
105
106
107
108
109
110
111
112STATIC void
113xfs_buf_item_log_check(
114 xfs_buf_log_item_t *bip)
115{
116 char *orig;
117 char *buffer;
118 int x;
119 xfs_buf_t *bp;
120
121 ASSERT(bip->bli_orig != NULL);
122 ASSERT(bip->bli_logged != NULL);
123
124 bp = bip->bli_buf;
125 ASSERT(bp->b_length > 0);
126 ASSERT(bp->b_addr != NULL);
127 orig = bip->bli_orig;
128 buffer = bp->b_addr;
129 for (x = 0; x < BBTOB(bp->b_length); x++) {
130 if (orig[x] != buffer[x] && !btst(bip->bli_logged, x)) {
131 xfs_emerg(bp->b_mount,
132 "%s: bip %x buffer %x orig %x index %d",
133 __func__, bip, bp, orig, x);
134 ASSERT(0);
135 }
136 }
137}
138#else
139#define xfs_buf_item_log_debug(x,y,z)
140#define xfs_buf_item_log_check(x)
141#endif
142
143STATIC void xfs_buf_do_callbacks(struct xfs_buf *bp);
144
145
146
147
148
149
150
151
152
153
154
155STATIC uint
156xfs_buf_item_size_segment(
157 struct xfs_buf_log_item *bip,
158 struct xfs_buf_log_format *blfp)
159{
160 struct xfs_buf *bp = bip->bli_buf;
161 uint nvecs;
162 int next_bit;
163 int last_bit;
164
165 last_bit = xfs_next_bit(blfp->blf_data_map, blfp->blf_map_size, 0);
166 if (last_bit == -1)
167 return 0;
168
169
170
171
172
173 nvecs = 2;
174
175 while (last_bit != -1) {
176
177
178
179
180
181
182 next_bit = xfs_next_bit(blfp->blf_data_map, blfp->blf_map_size,
183 last_bit + 1);
184
185
186
187
188
189 if (next_bit == -1) {
190 break;
191 } else if (next_bit != last_bit + 1) {
192 last_bit = next_bit;
193 nvecs++;
194 } else if (xfs_buf_offset(bp, next_bit * XFS_BLF_CHUNK) !=
195 (xfs_buf_offset(bp, last_bit * XFS_BLF_CHUNK) +
196 XFS_BLF_CHUNK)) {
197 last_bit = next_bit;
198 nvecs++;
199 } else {
200 last_bit++;
201 }
202 }
203
204 return nvecs;
205}
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224STATIC uint
225xfs_buf_item_size(
226 struct xfs_log_item *lip)
227{
228 struct xfs_buf_log_item *bip = BUF_ITEM(lip);
229 uint nvecs;
230 int i;
231
232 ASSERT(atomic_read(&bip->bli_refcount) > 0);
233 if (bip->bli_flags & XFS_BLI_STALE) {
234
235
236
237
238
239 trace_xfs_buf_item_size_stale(bip);
240 ASSERT(bip->bli_format.blf_flags & XFS_BLF_CANCEL);
241 return bip->bli_format_count;
242 }
243
244 ASSERT(bip->bli_flags & XFS_BLI_LOGGED);
245
246
247
248
249
250
251
252
253
254
255 nvecs = 0;
256 for (i = 0; i < bip->bli_format_count; i++) {
257 nvecs += xfs_buf_item_size_segment(bip, &bip->bli_formats[i]);
258 }
259
260 trace_xfs_buf_item_size(bip);
261 return nvecs;
262}
263
264static struct xfs_log_iovec *
265xfs_buf_item_format_segment(
266 struct xfs_buf_log_item *bip,
267 struct xfs_log_iovec *vecp,
268 uint offset,
269 struct xfs_buf_log_format *blfp)
270{
271 struct xfs_buf *bp = bip->bli_buf;
272 uint base_size;
273 uint nvecs;
274 int first_bit;
275 int last_bit;
276 int next_bit;
277 uint nbits;
278 uint buffer_offset;
279
280
281 blfp->blf_flags = bip->bli_format.blf_flags;
282
283
284
285
286
287
288 base_size = offsetof(struct xfs_buf_log_format, blf_data_map) +
289 (blfp->blf_map_size * sizeof(blfp->blf_data_map[0]));
290 vecp->i_addr = blfp;
291 vecp->i_len = base_size;
292 vecp->i_type = XLOG_REG_TYPE_BFORMAT;
293 vecp++;
294 nvecs = 1;
295
296 if (bip->bli_flags & XFS_BLI_STALE) {
297
298
299
300
301
302 trace_xfs_buf_item_format_stale(bip);
303 ASSERT(blfp->blf_flags & XFS_BLF_CANCEL);
304 blfp->blf_size = nvecs;
305 return vecp;
306 }
307
308
309
310
311 first_bit = xfs_next_bit(blfp->blf_data_map, blfp->blf_map_size, 0);
312 ASSERT(first_bit != -1);
313 last_bit = first_bit;
314 nbits = 1;
315 for (;;) {
316
317
318
319
320
321
322 next_bit = xfs_next_bit(blfp->blf_data_map, blfp->blf_map_size,
323 (uint)last_bit + 1);
324
325
326
327
328
329
330
331
332
333 if (next_bit == -1) {
334 buffer_offset = offset + first_bit * XFS_BLF_CHUNK;
335 vecp->i_addr = xfs_buf_offset(bp, buffer_offset);
336 vecp->i_len = nbits * XFS_BLF_CHUNK;
337 vecp->i_type = XLOG_REG_TYPE_BCHUNK;
338 nvecs++;
339 break;
340 } else if (next_bit != last_bit + 1) {
341 buffer_offset = offset + first_bit * XFS_BLF_CHUNK;
342 vecp->i_addr = xfs_buf_offset(bp, buffer_offset);
343 vecp->i_len = nbits * XFS_BLF_CHUNK;
344 vecp->i_type = XLOG_REG_TYPE_BCHUNK;
345 nvecs++;
346 vecp++;
347 first_bit = next_bit;
348 last_bit = next_bit;
349 nbits = 1;
350 } else if (xfs_buf_offset(bp, offset +
351 (next_bit << XFS_BLF_SHIFT)) !=
352 (xfs_buf_offset(bp, offset +
353 (last_bit << XFS_BLF_SHIFT)) +
354 XFS_BLF_CHUNK)) {
355 buffer_offset = offset + first_bit * XFS_BLF_CHUNK;
356 vecp->i_addr = xfs_buf_offset(bp, buffer_offset);
357 vecp->i_len = nbits * XFS_BLF_CHUNK;
358 vecp->i_type = XLOG_REG_TYPE_BCHUNK;
359
360
361
362
363
364
365 vecp++;
366 first_bit = next_bit;
367 last_bit = next_bit;
368 nbits = 1;
369 } else {
370 last_bit++;
371 nbits++;
372 }
373 }
374 bip->bli_format.blf_size = nvecs;
375 return vecp;
376}
377
378
379
380
381
382
383
384STATIC void
385xfs_buf_item_format(
386 struct xfs_log_item *lip,
387 struct xfs_log_iovec *vecp)
388{
389 struct xfs_buf_log_item *bip = BUF_ITEM(lip);
390 struct xfs_buf *bp = bip->bli_buf;
391 uint offset = 0;
392 int i;
393
394 ASSERT(atomic_read(&bip->bli_refcount) > 0);
395 ASSERT((bip->bli_flags & XFS_BLI_LOGGED) ||
396 (bip->bli_flags & XFS_BLI_STALE));
397
398
399
400
401
402
403
404
405 if (bip->bli_flags & XFS_BLI_INODE_BUF) {
406 if (!((bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF) &&
407 xfs_log_item_in_current_chkpt(lip)))
408 bip->bli_format.blf_flags |= XFS_BLF_INODE_BUF;
409 bip->bli_flags &= ~XFS_BLI_INODE_BUF;
410 }
411
412 for (i = 0; i < bip->bli_format_count; i++) {
413 vecp = xfs_buf_item_format_segment(bip, vecp, offset,
414 &bip->bli_formats[i]);
415 offset += bp->b_maps[i].bm_len;
416 }
417
418
419
420
421 trace_xfs_buf_item_format(bip);
422 xfs_buf_item_log_check(bip);
423}
424
425
426
427
428
429
430
431
432
433
434STATIC void
435xfs_buf_item_pin(
436 struct xfs_log_item *lip)
437{
438 struct xfs_buf_log_item *bip = BUF_ITEM(lip);
439
440 ASSERT(atomic_read(&bip->bli_refcount) > 0);
441 ASSERT((bip->bli_flags & XFS_BLI_LOGGED) ||
442 (bip->bli_flags & XFS_BLI_STALE));
443
444 trace_xfs_buf_item_pin(bip);
445
446 atomic_inc(&bip->bli_refcount);
447 atomic_inc(&bip->bli_buf->b_pin_count);
448}
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463STATIC void
464xfs_buf_item_unpin(
465 struct xfs_log_item *lip,
466 int remove)
467{
468 struct xfs_buf_log_item *bip = BUF_ITEM(lip);
469 xfs_buf_t *bp = bip->bli_buf;
470 struct xfs_ail *ailp = lip->li_ailp;
471 int stale = bip->bli_flags & XFS_BLI_STALE;
472 int freed;
473
474 ASSERT(bp->b_fspriv == bip);
475 ASSERT(atomic_read(&bip->bli_refcount) > 0);
476
477 trace_xfs_buf_item_unpin(bip);
478
479 freed = atomic_dec_and_test(&bip->bli_refcount);
480
481 if (atomic_dec_and_test(&bp->b_pin_count))
482 wake_up_all(&bp->b_waiters);
483
484 if (freed && stale) {
485 ASSERT(bip->bli_flags & XFS_BLI_STALE);
486 ASSERT(xfs_buf_islocked(bp));
487 ASSERT(XFS_BUF_ISSTALE(bp));
488 ASSERT(bip->bli_format.blf_flags & XFS_BLF_CANCEL);
489
490 trace_xfs_buf_item_unpin_stale(bip);
491
492 if (remove) {
493
494
495
496
497
498
499
500
501 if (lip->li_desc)
502 xfs_trans_del_item(lip);
503
504
505
506
507
508 bp->b_transp = NULL;
509 }
510
511
512
513
514
515
516
517 if (bip->bli_flags & XFS_BLI_STALE_INODE) {
518 xfs_buf_do_callbacks(bp);
519 bp->b_fspriv = NULL;
520 bp->b_iodone = NULL;
521 } else {
522 spin_lock(&ailp->xa_lock);
523 xfs_trans_ail_delete(ailp, lip, SHUTDOWN_LOG_IO_ERROR);
524 xfs_buf_item_relse(bp);
525 ASSERT(bp->b_fspriv == NULL);
526 }
527 xfs_buf_relse(bp);
528 } else if (freed && remove) {
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545 xfs_buf_lock(bp);
546 xfs_buf_hold(bp);
547 bp->b_flags |= XBF_ASYNC;
548 xfs_buf_ioerror(bp, EIO);
549 XFS_BUF_UNDONE(bp);
550 xfs_buf_stale(bp);
551 xfs_buf_ioend(bp, 0);
552 }
553}
554
555STATIC uint
556xfs_buf_item_push(
557 struct xfs_log_item *lip,
558 struct list_head *buffer_list)
559{
560 struct xfs_buf_log_item *bip = BUF_ITEM(lip);
561 struct xfs_buf *bp = bip->bli_buf;
562 uint rval = XFS_ITEM_SUCCESS;
563
564 if (xfs_buf_ispinned(bp))
565 return XFS_ITEM_PINNED;
566 if (!xfs_buf_trylock(bp))
567 return XFS_ITEM_LOCKED;
568
569 ASSERT(!(bip->bli_flags & XFS_BLI_STALE));
570
571 trace_xfs_buf_item_push(bip);
572
573 if (!xfs_buf_delwri_queue(bp, buffer_list))
574 rval = XFS_ITEM_FLUSHING;
575 xfs_buf_unlock(bp);
576 return rval;
577}
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598STATIC void
599xfs_buf_item_unlock(
600 struct xfs_log_item *lip)
601{
602 struct xfs_buf_log_item *bip = BUF_ITEM(lip);
603 struct xfs_buf *bp = bip->bli_buf;
604 int aborted;
605 uint hold;
606
607
608 bp->b_transp = NULL;
609
610
611
612
613
614
615
616 aborted = (lip->li_flags & XFS_LI_ABORTED) != 0;
617
618
619
620
621
622 hold = bip->bli_flags & XFS_BLI_HOLD;
623
624
625 bip->bli_flags &= ~(XFS_BLI_LOGGED | XFS_BLI_HOLD);
626
627
628
629
630
631
632 if (bip->bli_flags & XFS_BLI_STALE) {
633 trace_xfs_buf_item_unlock_stale(bip);
634 ASSERT(bip->bli_format.blf_flags & XFS_BLF_CANCEL);
635 if (!aborted) {
636 atomic_dec(&bip->bli_refcount);
637 return;
638 }
639 }
640
641 trace_xfs_buf_item_unlock(bip);
642
643
644
645
646
647 if (xfs_bitmap_empty(bip->bli_format.blf_data_map,
648 bip->bli_format.blf_map_size))
649 xfs_buf_item_relse(bp);
650 else
651 atomic_dec(&bip->bli_refcount);
652
653 if (!hold)
654 xfs_buf_relse(bp);
655}
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675STATIC xfs_lsn_t
676xfs_buf_item_committed(
677 struct xfs_log_item *lip,
678 xfs_lsn_t lsn)
679{
680 struct xfs_buf_log_item *bip = BUF_ITEM(lip);
681
682 trace_xfs_buf_item_committed(bip);
683
684 if ((bip->bli_flags & XFS_BLI_INODE_ALLOC_BUF) && lip->li_lsn != 0)
685 return lip->li_lsn;
686 return lsn;
687}
688
689STATIC void
690xfs_buf_item_committing(
691 struct xfs_log_item *lip,
692 xfs_lsn_t commit_lsn)
693{
694}
695
696
697
698
699static const struct xfs_item_ops xfs_buf_item_ops = {
700 .iop_size = xfs_buf_item_size,
701 .iop_format = xfs_buf_item_format,
702 .iop_pin = xfs_buf_item_pin,
703 .iop_unpin = xfs_buf_item_unpin,
704 .iop_unlock = xfs_buf_item_unlock,
705 .iop_committed = xfs_buf_item_committed,
706 .iop_push = xfs_buf_item_push,
707 .iop_committing = xfs_buf_item_committing
708};
709
710STATIC int
711xfs_buf_item_get_format(
712 struct xfs_buf_log_item *bip,
713 int count)
714{
715 ASSERT(bip->bli_formats == NULL);
716 bip->bli_format_count = count;
717
718 if (count == 1) {
719 bip->bli_formats = &bip->bli_format;
720 return 0;
721 }
722
723 bip->bli_formats = kmem_zalloc(count * sizeof(struct xfs_buf_log_format),
724 KM_SLEEP);
725 if (!bip->bli_formats)
726 return ENOMEM;
727 return 0;
728}
729
730STATIC void
731xfs_buf_item_free_format(
732 struct xfs_buf_log_item *bip)
733{
734 if (bip->bli_formats != &bip->bli_format) {
735 kmem_free(bip->bli_formats);
736 bip->bli_formats = NULL;
737 }
738}
739
740
741
742
743
744
745
746
747void
748xfs_buf_item_init(
749 xfs_buf_t *bp,
750 xfs_mount_t *mp)
751{
752 xfs_log_item_t *lip = bp->b_fspriv;
753 xfs_buf_log_item_t *bip;
754 int chunks;
755 int map_size;
756 int error;
757 int i;
758
759
760
761
762
763
764
765 ASSERT(bp->b_target->bt_mount == mp);
766 if (lip != NULL && lip->li_type == XFS_LI_BUF)
767 return;
768
769 bip = kmem_zone_zalloc(xfs_buf_item_zone, KM_SLEEP);
770 xfs_log_item_init(mp, &bip->bli_item, XFS_LI_BUF, &xfs_buf_item_ops);
771 bip->bli_buf = bp;
772 xfs_buf_hold(bp);
773
774
775
776
777
778
779
780
781
782
783 error = xfs_buf_item_get_format(bip, bp->b_map_count);
784 ASSERT(error == 0);
785
786 for (i = 0; i < bip->bli_format_count; i++) {
787 chunks = DIV_ROUND_UP(BBTOB(bp->b_maps[i].bm_len),
788 XFS_BLF_CHUNK);
789 map_size = DIV_ROUND_UP(chunks, NBWORD);
790
791 bip->bli_formats[i].blf_type = XFS_LI_BUF;
792 bip->bli_formats[i].blf_blkno = bp->b_maps[i].bm_bn;
793 bip->bli_formats[i].blf_len = bp->b_maps[i].bm_len;
794 bip->bli_formats[i].blf_map_size = map_size;
795 }
796
797#ifdef XFS_TRANS_DEBUG
798
799
800
801
802
803
804
805
806 bip->bli_orig = kmem_alloc(BBTOB(bp->b_length), KM_SLEEP);
807 memcpy(bip->bli_orig, bp->b_addr, BBTOB(bp->b_length));
808 bip->bli_logged = kmem_zalloc(BBTOB(bp->b_length) / NBBY, KM_SLEEP);
809#endif
810
811
812
813
814
815 if (bp->b_fspriv)
816 bip->bli_item.li_bio_list = bp->b_fspriv;
817 bp->b_fspriv = bip;
818}
819
820
821
822
823
824
825void
826xfs_buf_item_log_segment(
827 struct xfs_buf_log_item *bip,
828 uint first,
829 uint last,
830 uint *map)
831{
832 uint first_bit;
833 uint last_bit;
834 uint bits_to_set;
835 uint bits_set;
836 uint word_num;
837 uint *wordp;
838 uint bit;
839 uint end_bit;
840 uint mask;
841
842
843
844
845 first_bit = first >> XFS_BLF_SHIFT;
846 last_bit = last >> XFS_BLF_SHIFT;
847
848
849
850
851 bits_to_set = last_bit - first_bit + 1;
852
853
854
855
856
857 word_num = first_bit >> BIT_TO_WORD_SHIFT;
858 wordp = &map[word_num];
859
860
861
862
863 bit = first_bit & (uint)(NBWORD - 1);
864
865
866
867
868
869
870
871
872
873 if (bit) {
874 end_bit = MIN(bit + bits_to_set, (uint)NBWORD);
875 mask = ((1 << (end_bit - bit)) - 1) << bit;
876 *wordp |= mask;
877 wordp++;
878 bits_set = end_bit - bit;
879 } else {
880 bits_set = 0;
881 }
882
883
884
885
886
887 while ((bits_to_set - bits_set) >= NBWORD) {
888 *wordp |= 0xffffffff;
889 bits_set += NBWORD;
890 wordp++;
891 }
892
893
894
895
896 end_bit = bits_to_set - bits_set;
897 if (end_bit) {
898 mask = (1 << end_bit) - 1;
899 *wordp |= mask;
900 }
901
902 xfs_buf_item_log_debug(bip, first, last);
903}
904
905
906
907
908
909void
910xfs_buf_item_log(
911 xfs_buf_log_item_t *bip,
912 uint first,
913 uint last)
914{
915 int i;
916 uint start;
917 uint end;
918 struct xfs_buf *bp = bip->bli_buf;
919
920
921
922
923
924 bip->bli_flags |= XFS_BLI_DIRTY;
925
926
927
928
929 start = 0;
930 for (i = 0; i < bip->bli_format_count; i++) {
931 if (start > last)
932 break;
933 end = start + BBTOB(bp->b_maps[i].bm_len);
934 if (first > end) {
935 start += BBTOB(bp->b_maps[i].bm_len);
936 continue;
937 }
938 if (first < start)
939 first = start;
940 if (end > last)
941 end = last;
942
943 xfs_buf_item_log_segment(bip, first, end,
944 &bip->bli_formats[i].blf_data_map[0]);
945
946 start += bp->b_maps[i].bm_len;
947 }
948}
949
950
951
952
953
954
955uint
956xfs_buf_item_dirty(
957 xfs_buf_log_item_t *bip)
958{
959 return (bip->bli_flags & XFS_BLI_DIRTY);
960}
961
962STATIC void
963xfs_buf_item_free(
964 xfs_buf_log_item_t *bip)
965{
966#ifdef XFS_TRANS_DEBUG
967 kmem_free(bip->bli_orig);
968 kmem_free(bip->bli_logged);
969#endif
970
971 xfs_buf_item_free_format(bip);
972 kmem_zone_free(xfs_buf_item_zone, bip);
973}
974
975
976
977
978
979
980
981
982void
983xfs_buf_item_relse(
984 xfs_buf_t *bp)
985{
986 xfs_buf_log_item_t *bip;
987
988 trace_xfs_buf_item_relse(bp, _RET_IP_);
989
990 bip = bp->b_fspriv;
991 bp->b_fspriv = bip->bli_item.li_bio_list;
992 if (bp->b_fspriv == NULL)
993 bp->b_iodone = NULL;
994
995 xfs_buf_rele(bp);
996 xfs_buf_item_free(bip);
997}
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009void
1010xfs_buf_attach_iodone(
1011 xfs_buf_t *bp,
1012 void (*cb)(xfs_buf_t *, xfs_log_item_t *),
1013 xfs_log_item_t *lip)
1014{
1015 xfs_log_item_t *head_lip;
1016
1017 ASSERT(xfs_buf_islocked(bp));
1018
1019 lip->li_cb = cb;
1020 head_lip = bp->b_fspriv;
1021 if (head_lip) {
1022 lip->li_bio_list = head_lip->li_bio_list;
1023 head_lip->li_bio_list = lip;
1024 } else {
1025 bp->b_fspriv = lip;
1026 }
1027
1028 ASSERT(bp->b_iodone == NULL ||
1029 bp->b_iodone == xfs_buf_iodone_callbacks);
1030 bp->b_iodone = xfs_buf_iodone_callbacks;
1031}
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045STATIC void
1046xfs_buf_do_callbacks(
1047 struct xfs_buf *bp)
1048{
1049 struct xfs_log_item *lip;
1050
1051 while ((lip = bp->b_fspriv) != NULL) {
1052 bp->b_fspriv = lip->li_bio_list;
1053 ASSERT(lip->li_cb != NULL);
1054
1055
1056
1057
1058
1059
1060 lip->li_bio_list = NULL;
1061 lip->li_cb(bp, lip);
1062 }
1063}
1064
1065
1066
1067
1068
1069
1070
1071
1072void
1073xfs_buf_iodone_callbacks(
1074 struct xfs_buf *bp)
1075{
1076 struct xfs_log_item *lip = bp->b_fspriv;
1077 struct xfs_mount *mp = lip->li_mountp;
1078 static ulong lasttime;
1079 static xfs_buftarg_t *lasttarg;
1080
1081 if (likely(!xfs_buf_geterror(bp)))
1082 goto do_callbacks;
1083
1084
1085
1086
1087
1088 if (XFS_FORCED_SHUTDOWN(mp)) {
1089 xfs_buf_stale(bp);
1090 XFS_BUF_DONE(bp);
1091 trace_xfs_buf_item_iodone(bp, _RET_IP_);
1092 goto do_callbacks;
1093 }
1094
1095 if (bp->b_target != lasttarg ||
1096 time_after(jiffies, (lasttime + 5*HZ))) {
1097 lasttime = jiffies;
1098 xfs_buf_ioerror_alert(bp, __func__);
1099 }
1100 lasttarg = bp->b_target;
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113 if (XFS_BUF_ISASYNC(bp)) {
1114 ASSERT(bp->b_iodone != NULL);
1115
1116 trace_xfs_buf_item_iodone_async(bp, _RET_IP_);
1117
1118 xfs_buf_ioerror(bp, 0);
1119
1120 if (!XFS_BUF_ISSTALE(bp)) {
1121 bp->b_flags |= XBF_WRITE | XBF_ASYNC | XBF_DONE;
1122 xfs_buf_iorequest(bp);
1123 } else {
1124 xfs_buf_relse(bp);
1125 }
1126
1127 return;
1128 }
1129
1130
1131
1132
1133
1134 xfs_buf_stale(bp);
1135 XFS_BUF_DONE(bp);
1136
1137 trace_xfs_buf_error_relse(bp, _RET_IP_);
1138
1139do_callbacks:
1140 xfs_buf_do_callbacks(bp);
1141 bp->b_fspriv = NULL;
1142 bp->b_iodone = NULL;
1143 xfs_buf_ioend(bp, 0);
1144}
1145
1146
1147
1148
1149
1150
1151
1152
1153void
1154xfs_buf_iodone(
1155 struct xfs_buf *bp,
1156 struct xfs_log_item *lip)
1157{
1158 struct xfs_ail *ailp = lip->li_ailp;
1159
1160 ASSERT(BUF_ITEM(lip)->bli_buf == bp);
1161
1162 xfs_buf_rele(bp);
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173 spin_lock(&ailp->xa_lock);
1174 xfs_trans_ail_delete(ailp, lip, SHUTDOWN_CORRUPT_INCORE);
1175 xfs_buf_item_free(BUF_ITEM(lip));
1176}
1177