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_mount.h"
28#include "xfs_error.h"
29#include "xfs_log_priv.h"
30#include "xfs_buf_item.h"
31#include "xfs_bmap_btree.h"
32#include "xfs_alloc_btree.h"
33#include "xfs_ialloc_btree.h"
34#include "xfs_log_recover.h"
35#include "xfs_trans_priv.h"
36#include "xfs_dinode.h"
37#include "xfs_inode.h"
38#include "xfs_rw.h"
39#include "xfs_trace.h"
40
41kmem_zone_t *xfs_log_ticket_zone;
42
43
44STATIC int xlog_commit_record(struct log *log, struct xlog_ticket *ticket,
45 xlog_in_core_t **, xfs_lsn_t *);
46STATIC xlog_t * xlog_alloc_log(xfs_mount_t *mp,
47 xfs_buftarg_t *log_target,
48 xfs_daddr_t blk_offset,
49 int num_bblks);
50STATIC int xlog_space_left(struct log *log, atomic64_t *head);
51STATIC int xlog_sync(xlog_t *log, xlog_in_core_t *iclog);
52STATIC void xlog_dealloc_log(xlog_t *log);
53
54
55STATIC void xlog_state_done_syncing(xlog_in_core_t *iclog, int);
56STATIC void xlog_state_do_callback(xlog_t *log,int aborted, xlog_in_core_t *iclog);
57STATIC int xlog_state_get_iclog_space(xlog_t *log,
58 int len,
59 xlog_in_core_t **iclog,
60 xlog_ticket_t *ticket,
61 int *continued_write,
62 int *logoffsetp);
63STATIC int xlog_state_release_iclog(xlog_t *log,
64 xlog_in_core_t *iclog);
65STATIC void xlog_state_switch_iclogs(xlog_t *log,
66 xlog_in_core_t *iclog,
67 int eventual_size);
68STATIC void xlog_state_want_sync(xlog_t *log, xlog_in_core_t *iclog);
69
70
71STATIC int xlog_grant_log_space(xlog_t *log,
72 xlog_ticket_t *xtic);
73STATIC void xlog_grant_push_ail(struct log *log,
74 int need_bytes);
75STATIC void xlog_regrant_reserve_log_space(xlog_t *log,
76 xlog_ticket_t *ticket);
77STATIC int xlog_regrant_write_log_space(xlog_t *log,
78 xlog_ticket_t *ticket);
79STATIC void xlog_ungrant_log_space(xlog_t *log,
80 xlog_ticket_t *ticket);
81
82#if defined(DEBUG)
83STATIC void xlog_verify_dest_ptr(xlog_t *log, char *ptr);
84STATIC void xlog_verify_grant_tail(struct log *log);
85STATIC void xlog_verify_iclog(xlog_t *log, xlog_in_core_t *iclog,
86 int count, boolean_t syncing);
87STATIC void xlog_verify_tail_lsn(xlog_t *log, xlog_in_core_t *iclog,
88 xfs_lsn_t tail_lsn);
89#else
90#define xlog_verify_dest_ptr(a,b)
91#define xlog_verify_grant_tail(a)
92#define xlog_verify_iclog(a,b,c,d)
93#define xlog_verify_tail_lsn(a,b,c)
94#endif
95
96STATIC int xlog_iclogs_empty(xlog_t *log);
97
98static void
99xlog_grant_sub_space(
100 struct log *log,
101 atomic64_t *head,
102 int bytes)
103{
104 int64_t head_val = atomic64_read(head);
105 int64_t new, old;
106
107 do {
108 int cycle, space;
109
110 xlog_crack_grant_head_val(head_val, &cycle, &space);
111
112 space -= bytes;
113 if (space < 0) {
114 space += log->l_logsize;
115 cycle--;
116 }
117
118 old = head_val;
119 new = xlog_assign_grant_head_val(cycle, space);
120 head_val = atomic64_cmpxchg(head, old, new);
121 } while (head_val != old);
122}
123
124static void
125xlog_grant_add_space(
126 struct log *log,
127 atomic64_t *head,
128 int bytes)
129{
130 int64_t head_val = atomic64_read(head);
131 int64_t new, old;
132
133 do {
134 int tmp;
135 int cycle, space;
136
137 xlog_crack_grant_head_val(head_val, &cycle, &space);
138
139 tmp = log->l_logsize - space;
140 if (tmp > bytes)
141 space += bytes;
142 else {
143 space = bytes - tmp;
144 cycle++;
145 }
146
147 old = head_val;
148 new = xlog_assign_grant_head_val(cycle, space);
149 head_val = atomic64_cmpxchg(head, old, new);
150 } while (head_val != old);
151}
152
153static void
154xlog_tic_reset_res(xlog_ticket_t *tic)
155{
156 tic->t_res_num = 0;
157 tic->t_res_arr_sum = 0;
158 tic->t_res_num_ophdrs = 0;
159}
160
161static void
162xlog_tic_add_region(xlog_ticket_t *tic, uint len, uint type)
163{
164 if (tic->t_res_num == XLOG_TIC_LEN_MAX) {
165
166 tic->t_res_o_flow += tic->t_res_arr_sum;
167 tic->t_res_num = 0;
168 tic->t_res_arr_sum = 0;
169 }
170
171 tic->t_res_arr[tic->t_res_num].r_len = len;
172 tic->t_res_arr[tic->t_res_num].r_type = type;
173 tic->t_res_arr_sum += len;
174 tic->t_res_num++;
175}
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198xfs_lsn_t
199xfs_log_done(
200 struct xfs_mount *mp,
201 struct xlog_ticket *ticket,
202 struct xlog_in_core **iclog,
203 uint flags)
204{
205 struct log *log = mp->m_log;
206 xfs_lsn_t lsn = 0;
207
208 if (XLOG_FORCED_SHUTDOWN(log) ||
209
210
211
212
213 (((ticket->t_flags & XLOG_TIC_INITED) == 0) &&
214 (xlog_commit_record(log, ticket, iclog, &lsn)))) {
215 lsn = (xfs_lsn_t) -1;
216 if (ticket->t_flags & XLOG_TIC_PERM_RESERV) {
217 flags |= XFS_LOG_REL_PERM_RESERV;
218 }
219 }
220
221
222 if ((ticket->t_flags & XLOG_TIC_PERM_RESERV) == 0 ||
223 (flags & XFS_LOG_REL_PERM_RESERV)) {
224 trace_xfs_log_done_nonperm(log, ticket);
225
226
227
228
229
230 xlog_ungrant_log_space(log, ticket);
231 xfs_log_ticket_put(ticket);
232 } else {
233 trace_xfs_log_done_perm(log, ticket);
234
235 xlog_regrant_reserve_log_space(log, ticket);
236
237
238
239
240 ticket->t_flags |= XLOG_TIC_INITED;
241 }
242
243 return lsn;
244}
245
246
247
248
249
250
251
252int
253xfs_log_notify(
254 struct xfs_mount *mp,
255 struct xlog_in_core *iclog,
256 xfs_log_callback_t *cb)
257{
258 int abortflg;
259
260 spin_lock(&iclog->ic_callback_lock);
261 abortflg = (iclog->ic_state & XLOG_STATE_IOERROR);
262 if (!abortflg) {
263 ASSERT_ALWAYS((iclog->ic_state == XLOG_STATE_ACTIVE) ||
264 (iclog->ic_state == XLOG_STATE_WANT_SYNC));
265 cb->cb_next = NULL;
266 *(iclog->ic_callback_tail) = cb;
267 iclog->ic_callback_tail = &(cb->cb_next);
268 }
269 spin_unlock(&iclog->ic_callback_lock);
270 return abortflg;
271}
272
273int
274xfs_log_release_iclog(
275 struct xfs_mount *mp,
276 struct xlog_in_core *iclog)
277{
278 if (xlog_state_release_iclog(mp->m_log, iclog)) {
279 xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
280 return EIO;
281 }
282
283 return 0;
284}
285
286
287
288
289
290
291
292
293
294
295
296int
297xfs_log_reserve(
298 struct xfs_mount *mp,
299 int unit_bytes,
300 int cnt,
301 struct xlog_ticket **ticket,
302 __uint8_t client,
303 uint flags,
304 uint t_type)
305{
306 struct log *log = mp->m_log;
307 struct xlog_ticket *internal_ticket;
308 int retval = 0;
309
310 ASSERT(client == XFS_TRANSACTION || client == XFS_LOG);
311
312 if (XLOG_FORCED_SHUTDOWN(log))
313 return XFS_ERROR(EIO);
314
315 XFS_STATS_INC(xs_try_logspace);
316
317
318 if (*ticket != NULL) {
319 ASSERT(flags & XFS_LOG_PERM_RESERV);
320 internal_ticket = *ticket;
321
322
323
324
325
326
327
328
329 internal_ticket->t_tid++;
330
331 trace_xfs_log_reserve(log, internal_ticket);
332
333 xlog_grant_push_ail(log, internal_ticket->t_unit_res);
334 retval = xlog_regrant_write_log_space(log, internal_ticket);
335 } else {
336
337 internal_ticket = xlog_ticket_alloc(log, unit_bytes, cnt,
338 client, flags,
339 KM_SLEEP|KM_MAYFAIL);
340 if (!internal_ticket)
341 return XFS_ERROR(ENOMEM);
342 internal_ticket->t_trans_type = t_type;
343 *ticket = internal_ticket;
344
345 trace_xfs_log_reserve(log, internal_ticket);
346
347 xlog_grant_push_ail(log,
348 (internal_ticket->t_unit_res *
349 internal_ticket->t_cnt));
350 retval = xlog_grant_log_space(log, internal_ticket);
351 }
352
353 return retval;
354}
355
356
357
358
359
360
361
362
363
364
365
366
367int
368xfs_log_mount(
369 xfs_mount_t *mp,
370 xfs_buftarg_t *log_target,
371 xfs_daddr_t blk_offset,
372 int num_bblks)
373{
374 int error;
375
376 if (!(mp->m_flags & XFS_MOUNT_NORECOVERY))
377 cmn_err(CE_NOTE, "XFS mounting filesystem %s", mp->m_fsname);
378 else {
379 cmn_err(CE_NOTE,
380 "Mounting filesystem \"%s\" in no-recovery mode. Filesystem will be inconsistent.",
381 mp->m_fsname);
382 ASSERT(mp->m_flags & XFS_MOUNT_RDONLY);
383 }
384
385 mp->m_log = xlog_alloc_log(mp, log_target, blk_offset, num_bblks);
386 if (IS_ERR(mp->m_log)) {
387 error = -PTR_ERR(mp->m_log);
388 goto out;
389 }
390
391
392
393
394 error = xfs_trans_ail_init(mp);
395 if (error) {
396 cmn_err(CE_WARN, "XFS: AIL initialisation failed: error %d", error);
397 goto out_free_log;
398 }
399 mp->m_log->l_ailp = mp->m_ail;
400
401
402
403
404
405 if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) {
406 int readonly = (mp->m_flags & XFS_MOUNT_RDONLY);
407
408 if (readonly)
409 mp->m_flags &= ~XFS_MOUNT_RDONLY;
410
411 error = xlog_recover(mp->m_log);
412
413 if (readonly)
414 mp->m_flags |= XFS_MOUNT_RDONLY;
415 if (error) {
416 cmn_err(CE_WARN, "XFS: log mount/recovery failed: error %d", error);
417 goto out_destroy_ail;
418 }
419 }
420
421
422 mp->m_log->l_flags &= ~XLOG_ACTIVE_RECOVERY;
423
424
425
426
427
428
429 xlog_cil_init_post_recovery(mp->m_log);
430
431 return 0;
432
433out_destroy_ail:
434 xfs_trans_ail_destroy(mp);
435out_free_log:
436 xlog_dealloc_log(mp->m_log);
437out:
438 return error;
439}
440
441
442
443
444
445
446
447
448
449int
450xfs_log_mount_finish(xfs_mount_t *mp)
451{
452 int error;
453
454 if (!(mp->m_flags & XFS_MOUNT_NORECOVERY))
455 error = xlog_recover_finish(mp->m_log);
456 else {
457 error = 0;
458 ASSERT(mp->m_flags & XFS_MOUNT_RDONLY);
459 }
460
461 return error;
462}
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480int
481xfs_log_unmount_write(xfs_mount_t *mp)
482{
483 xlog_t *log = mp->m_log;
484 xlog_in_core_t *iclog;
485#ifdef DEBUG
486 xlog_in_core_t *first_iclog;
487#endif
488 xlog_ticket_t *tic = NULL;
489 xfs_lsn_t lsn;
490 int error;
491
492
493
494
495
496 if (mp->m_flags & XFS_MOUNT_RDONLY)
497 return 0;
498
499 error = _xfs_log_force(mp, XFS_LOG_SYNC, NULL);
500 ASSERT(error || !(XLOG_FORCED_SHUTDOWN(log)));
501
502#ifdef DEBUG
503 first_iclog = iclog = log->l_iclog;
504 do {
505 if (!(iclog->ic_state & XLOG_STATE_IOERROR)) {
506 ASSERT(iclog->ic_state & XLOG_STATE_ACTIVE);
507 ASSERT(iclog->ic_offset == 0);
508 }
509 iclog = iclog->ic_next;
510 } while (iclog != first_iclog);
511#endif
512 if (! (XLOG_FORCED_SHUTDOWN(log))) {
513 error = xfs_log_reserve(mp, 600, 1, &tic,
514 XFS_LOG, 0, XLOG_UNMOUNT_REC_TYPE);
515 if (!error) {
516
517 struct {
518 __uint16_t magic;
519 __uint16_t pad1;
520 __uint32_t pad2;
521 } magic = {
522 .magic = XLOG_UNMOUNT_TYPE,
523 };
524 struct xfs_log_iovec reg = {
525 .i_addr = &magic,
526 .i_len = sizeof(magic),
527 .i_type = XLOG_REG_TYPE_UNMOUNT,
528 };
529 struct xfs_log_vec vec = {
530 .lv_niovecs = 1,
531 .lv_iovecp = ®,
532 };
533
534
535 tic->t_flags = 0;
536 error = xlog_write(log, &vec, tic, &lsn,
537 NULL, XLOG_UNMOUNT_TRANS);
538
539
540
541
542
543 }
544
545 if (error) {
546 xfs_fs_cmn_err(CE_ALERT, mp,
547 "xfs_log_unmount: unmount record failed");
548 }
549
550
551 spin_lock(&log->l_icloglock);
552 iclog = log->l_iclog;
553 atomic_inc(&iclog->ic_refcnt);
554 xlog_state_want_sync(log, iclog);
555 spin_unlock(&log->l_icloglock);
556 error = xlog_state_release_iclog(log, iclog);
557
558 spin_lock(&log->l_icloglock);
559 if (!(iclog->ic_state == XLOG_STATE_ACTIVE ||
560 iclog->ic_state == XLOG_STATE_DIRTY)) {
561 if (!XLOG_FORCED_SHUTDOWN(log)) {
562 xlog_wait(&iclog->ic_force_wait,
563 &log->l_icloglock);
564 } else {
565 spin_unlock(&log->l_icloglock);
566 }
567 } else {
568 spin_unlock(&log->l_icloglock);
569 }
570 if (tic) {
571 trace_xfs_log_umount_write(log, tic);
572 xlog_ungrant_log_space(log, tic);
573 xfs_log_ticket_put(tic);
574 }
575 } else {
576
577
578
579
580
581
582
583
584
585
586
587
588
589 spin_lock(&log->l_icloglock);
590 iclog = log->l_iclog;
591 atomic_inc(&iclog->ic_refcnt);
592
593 xlog_state_want_sync(log, iclog);
594 spin_unlock(&log->l_icloglock);
595 error = xlog_state_release_iclog(log, iclog);
596
597 spin_lock(&log->l_icloglock);
598
599 if ( ! ( iclog->ic_state == XLOG_STATE_ACTIVE
600 || iclog->ic_state == XLOG_STATE_DIRTY
601 || iclog->ic_state == XLOG_STATE_IOERROR) ) {
602
603 xlog_wait(&iclog->ic_force_wait,
604 &log->l_icloglock);
605 } else {
606 spin_unlock(&log->l_icloglock);
607 }
608 }
609
610 return error;
611}
612
613
614
615
616
617
618
619void
620xfs_log_unmount(xfs_mount_t *mp)
621{
622 xfs_trans_ail_destroy(mp);
623 xlog_dealloc_log(mp->m_log);
624}
625
626void
627xfs_log_item_init(
628 struct xfs_mount *mp,
629 struct xfs_log_item *item,
630 int type,
631 struct xfs_item_ops *ops)
632{
633 item->li_mountp = mp;
634 item->li_ailp = mp->m_ail;
635 item->li_type = type;
636 item->li_ops = ops;
637 item->li_lv = NULL;
638
639 INIT_LIST_HEAD(&item->li_ail);
640 INIT_LIST_HEAD(&item->li_cil);
641}
642
643
644
645
646
647
648
649
650
651int
652xfs_log_write(
653 struct xfs_mount *mp,
654 struct xfs_log_iovec reg[],
655 int nentries,
656 struct xlog_ticket *tic,
657 xfs_lsn_t *start_lsn)
658{
659 struct log *log = mp->m_log;
660 int error;
661 struct xfs_log_vec vec = {
662 .lv_niovecs = nentries,
663 .lv_iovecp = reg,
664 };
665
666 if (XLOG_FORCED_SHUTDOWN(log))
667 return XFS_ERROR(EIO);
668
669 error = xlog_write(log, &vec, tic, start_lsn, NULL, 0);
670 if (error)
671 xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
672 return error;
673}
674
675void
676xfs_log_move_tail(xfs_mount_t *mp,
677 xfs_lsn_t tail_lsn)
678{
679 xlog_ticket_t *tic;
680 xlog_t *log = mp->m_log;
681 int need_bytes, free_bytes;
682
683 if (XLOG_FORCED_SHUTDOWN(log))
684 return;
685
686 if (tail_lsn == 0)
687 tail_lsn = atomic64_read(&log->l_last_sync_lsn);
688
689
690 if (tail_lsn != 1)
691 atomic64_set(&log->l_tail_lsn, tail_lsn);
692
693 if (!list_empty_careful(&log->l_writeq)) {
694#ifdef DEBUG
695 if (log->l_flags & XLOG_ACTIVE_RECOVERY)
696 panic("Recovery problem");
697#endif
698 spin_lock(&log->l_grant_write_lock);
699 free_bytes = xlog_space_left(log, &log->l_grant_write_head);
700 list_for_each_entry(tic, &log->l_writeq, t_queue) {
701 ASSERT(tic->t_flags & XLOG_TIC_PERM_RESERV);
702
703 if (free_bytes < tic->t_unit_res && tail_lsn != 1)
704 break;
705 tail_lsn = 0;
706 free_bytes -= tic->t_unit_res;
707 trace_xfs_log_regrant_write_wake_up(log, tic);
708 wake_up(&tic->t_wait);
709 }
710 spin_unlock(&log->l_grant_write_lock);
711 }
712
713 if (!list_empty_careful(&log->l_reserveq)) {
714#ifdef DEBUG
715 if (log->l_flags & XLOG_ACTIVE_RECOVERY)
716 panic("Recovery problem");
717#endif
718 spin_lock(&log->l_grant_reserve_lock);
719 free_bytes = xlog_space_left(log, &log->l_grant_reserve_head);
720 list_for_each_entry(tic, &log->l_reserveq, t_queue) {
721 if (tic->t_flags & XLOG_TIC_PERM_RESERV)
722 need_bytes = tic->t_unit_res*tic->t_cnt;
723 else
724 need_bytes = tic->t_unit_res;
725 if (free_bytes < need_bytes && tail_lsn != 1)
726 break;
727 tail_lsn = 0;
728 free_bytes -= need_bytes;
729 trace_xfs_log_grant_wake_up(log, tic);
730 wake_up(&tic->t_wait);
731 }
732 spin_unlock(&log->l_grant_reserve_lock);
733 }
734}
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749int
750xfs_log_need_covered(xfs_mount_t *mp)
751{
752 int needed = 0;
753 xlog_t *log = mp->m_log;
754
755 if (!xfs_fs_writable(mp))
756 return 0;
757
758 spin_lock(&log->l_icloglock);
759 switch (log->l_covered_state) {
760 case XLOG_STATE_COVER_DONE:
761 case XLOG_STATE_COVER_DONE2:
762 case XLOG_STATE_COVER_IDLE:
763 break;
764 case XLOG_STATE_COVER_NEED:
765 case XLOG_STATE_COVER_NEED2:
766 if (!xfs_trans_ail_tail(log->l_ailp) &&
767 xlog_iclogs_empty(log)) {
768 if (log->l_covered_state == XLOG_STATE_COVER_NEED)
769 log->l_covered_state = XLOG_STATE_COVER_DONE;
770 else
771 log->l_covered_state = XLOG_STATE_COVER_DONE2;
772 }
773
774 default:
775 needed = 1;
776 break;
777 }
778 spin_unlock(&log->l_icloglock);
779 return needed;
780}
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799xfs_lsn_t
800xlog_assign_tail_lsn(
801 struct xfs_mount *mp)
802{
803 xfs_lsn_t tail_lsn;
804 struct log *log = mp->m_log;
805
806 tail_lsn = xfs_trans_ail_tail(mp->m_ail);
807 if (!tail_lsn)
808 tail_lsn = atomic64_read(&log->l_last_sync_lsn);
809
810 atomic64_set(&log->l_tail_lsn, tail_lsn);
811 return tail_lsn;
812}
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828STATIC int
829xlog_space_left(
830 struct log *log,
831 atomic64_t *head)
832{
833 int free_bytes;
834 int tail_bytes;
835 int tail_cycle;
836 int head_cycle;
837 int head_bytes;
838
839 xlog_crack_grant_head(head, &head_cycle, &head_bytes);
840 xlog_crack_atomic_lsn(&log->l_tail_lsn, &tail_cycle, &tail_bytes);
841 tail_bytes = BBTOB(tail_bytes);
842 if (tail_cycle == head_cycle && head_bytes >= tail_bytes)
843 free_bytes = log->l_logsize - (head_bytes - tail_bytes);
844 else if (tail_cycle + 1 < head_cycle)
845 return 0;
846 else if (tail_cycle < head_cycle) {
847 ASSERT(tail_cycle == (head_cycle - 1));
848 free_bytes = tail_bytes - head_bytes;
849 } else {
850
851
852
853
854
855 xfs_fs_cmn_err(CE_ALERT, log->l_mp,
856 "xlog_space_left: head behind tail\n"
857 " tail_cycle = %d, tail_bytes = %d\n"
858 " GH cycle = %d, GH bytes = %d",
859 tail_cycle, tail_bytes, head_cycle, head_bytes);
860 ASSERT(0);
861 free_bytes = log->l_logsize;
862 }
863 return free_bytes;
864}
865
866
867
868
869
870
871
872
873void
874xlog_iodone(xfs_buf_t *bp)
875{
876 xlog_in_core_t *iclog;
877 xlog_t *l;
878 int aborted;
879
880 iclog = XFS_BUF_FSPRIVATE(bp, xlog_in_core_t *);
881 ASSERT(XFS_BUF_FSPRIVATE2(bp, unsigned long) == (unsigned long) 2);
882 XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)1);
883 aborted = 0;
884 l = iclog->ic_log;
885
886
887
888
889 if (XFS_TEST_ERROR((XFS_BUF_GETERROR(bp)), l->l_mp,
890 XFS_ERRTAG_IODONE_IOERR, XFS_RANDOM_IODONE_IOERR)) {
891 xfs_ioerror_alert("xlog_iodone", l->l_mp, bp, XFS_BUF_ADDR(bp));
892 XFS_BUF_STALE(bp);
893 xfs_force_shutdown(l->l_mp, SHUTDOWN_LOG_IO_ERROR);
894
895
896
897
898
899 aborted = XFS_LI_ABORTED;
900 } else if (iclog->ic_state & XLOG_STATE_IOERROR) {
901 aborted = XFS_LI_ABORTED;
902 }
903
904
905 ASSERT(XFS_BUF_ISASYNC(bp));
906 xlog_state_done_syncing(iclog, aborted);
907
908
909
910
911
912
913}
914
915
916
917
918
919
920
921
922
923
924STATIC void
925xlog_get_iclog_buffer_size(xfs_mount_t *mp,
926 xlog_t *log)
927{
928 int size;
929 int xhdrs;
930
931 if (mp->m_logbufs <= 0)
932 log->l_iclog_bufs = XLOG_MAX_ICLOGS;
933 else
934 log->l_iclog_bufs = mp->m_logbufs;
935
936
937
938
939 if (mp->m_logbsize > 0) {
940 size = log->l_iclog_size = mp->m_logbsize;
941 log->l_iclog_size_log = 0;
942 while (size != 1) {
943 log->l_iclog_size_log++;
944 size >>= 1;
945 }
946
947 if (xfs_sb_version_haslogv2(&mp->m_sb)) {
948
949
950
951
952 xhdrs = mp->m_logbsize / XLOG_HEADER_CYCLE_SIZE;
953 if (mp->m_logbsize % XLOG_HEADER_CYCLE_SIZE)
954 xhdrs++;
955 log->l_iclog_hsize = xhdrs << BBSHIFT;
956 log->l_iclog_heads = xhdrs;
957 } else {
958 ASSERT(mp->m_logbsize <= XLOG_BIG_RECORD_BSIZE);
959 log->l_iclog_hsize = BBSIZE;
960 log->l_iclog_heads = 1;
961 }
962 goto done;
963 }
964
965
966 log->l_iclog_size = XLOG_BIG_RECORD_BSIZE;
967 log->l_iclog_size_log = XLOG_BIG_RECORD_BSHIFT;
968
969
970 log->l_iclog_hsize = BBSIZE;
971 log->l_iclog_heads = 1;
972
973done:
974
975 if (mp->m_logbufs == 0)
976 mp->m_logbufs = log->l_iclog_bufs;
977 if (mp->m_logbsize == 0)
978 mp->m_logbsize = log->l_iclog_size;
979}
980
981
982
983
984
985
986
987STATIC xlog_t *
988xlog_alloc_log(xfs_mount_t *mp,
989 xfs_buftarg_t *log_target,
990 xfs_daddr_t blk_offset,
991 int num_bblks)
992{
993 xlog_t *log;
994 xlog_rec_header_t *head;
995 xlog_in_core_t **iclogp;
996 xlog_in_core_t *iclog, *prev_iclog=NULL;
997 xfs_buf_t *bp;
998 int i;
999 int error = ENOMEM;
1000 uint log2_size = 0;
1001
1002 log = kmem_zalloc(sizeof(xlog_t), KM_MAYFAIL);
1003 if (!log) {
1004 xlog_warn("XFS: Log allocation failed: No memory!");
1005 goto out;
1006 }
1007
1008 log->l_mp = mp;
1009 log->l_targ = log_target;
1010 log->l_logsize = BBTOB(num_bblks);
1011 log->l_logBBstart = blk_offset;
1012 log->l_logBBsize = num_bblks;
1013 log->l_covered_state = XLOG_STATE_COVER_IDLE;
1014 log->l_flags |= XLOG_ACTIVE_RECOVERY;
1015
1016 log->l_prev_block = -1;
1017
1018 xlog_assign_atomic_lsn(&log->l_tail_lsn, 1, 0);
1019 xlog_assign_atomic_lsn(&log->l_last_sync_lsn, 1, 0);
1020 log->l_curr_cycle = 1;
1021 xlog_assign_grant_head(&log->l_grant_reserve_head, 1, 0);
1022 xlog_assign_grant_head(&log->l_grant_write_head, 1, 0);
1023 INIT_LIST_HEAD(&log->l_reserveq);
1024 INIT_LIST_HEAD(&log->l_writeq);
1025 spin_lock_init(&log->l_grant_reserve_lock);
1026 spin_lock_init(&log->l_grant_write_lock);
1027
1028 error = EFSCORRUPTED;
1029 if (xfs_sb_version_hassector(&mp->m_sb)) {
1030 log2_size = mp->m_sb.sb_logsectlog;
1031 if (log2_size < BBSHIFT) {
1032 xlog_warn("XFS: Log sector size too small "
1033 "(0x%x < 0x%x)", log2_size, BBSHIFT);
1034 goto out_free_log;
1035 }
1036
1037 log2_size -= BBSHIFT;
1038 if (log2_size > mp->m_sectbb_log) {
1039 xlog_warn("XFS: Log sector size too large "
1040 "(0x%x > 0x%x)", log2_size, mp->m_sectbb_log);
1041 goto out_free_log;
1042 }
1043
1044
1045 if (log2_size && log->l_logBBstart > 0 &&
1046 !xfs_sb_version_haslogv2(&mp->m_sb)) {
1047
1048 xlog_warn("XFS: log sector size (0x%x) invalid "
1049 "for configuration.", log2_size);
1050 goto out_free_log;
1051 }
1052 }
1053 log->l_sectBBsize = 1 << log2_size;
1054
1055 xlog_get_iclog_buffer_size(mp, log);
1056
1057 error = ENOMEM;
1058 bp = xfs_buf_get_empty(log->l_iclog_size, mp->m_logdev_targp);
1059 if (!bp)
1060 goto out_free_log;
1061 XFS_BUF_SET_IODONE_FUNC(bp, xlog_iodone);
1062 XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)1);
1063 ASSERT(XFS_BUF_ISBUSY(bp));
1064 ASSERT(XFS_BUF_VALUSEMA(bp) <= 0);
1065 log->l_xbuf = bp;
1066
1067 spin_lock_init(&log->l_icloglock);
1068 init_waitqueue_head(&log->l_flush_wait);
1069
1070
1071 ASSERT((XFS_BUF_SIZE(bp) & BBMASK) == 0);
1072
1073 iclogp = &log->l_iclog;
1074
1075
1076
1077
1078
1079
1080
1081 ASSERT(log->l_iclog_size >= 4096);
1082 for (i=0; i < log->l_iclog_bufs; i++) {
1083 *iclogp = kmem_zalloc(sizeof(xlog_in_core_t), KM_MAYFAIL);
1084 if (!*iclogp)
1085 goto out_free_iclog;
1086
1087 iclog = *iclogp;
1088 iclog->ic_prev = prev_iclog;
1089 prev_iclog = iclog;
1090
1091 bp = xfs_buf_get_uncached(mp->m_logdev_targp,
1092 log->l_iclog_size, 0);
1093 if (!bp)
1094 goto out_free_iclog;
1095 if (!XFS_BUF_CPSEMA(bp))
1096 ASSERT(0);
1097 XFS_BUF_SET_IODONE_FUNC(bp, xlog_iodone);
1098 XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)1);
1099 iclog->ic_bp = bp;
1100 iclog->ic_data = bp->b_addr;
1101#ifdef DEBUG
1102 log->l_iclog_bak[i] = (xfs_caddr_t)&(iclog->ic_header);
1103#endif
1104 head = &iclog->ic_header;
1105 memset(head, 0, sizeof(xlog_rec_header_t));
1106 head->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM);
1107 head->h_version = cpu_to_be32(
1108 xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? 2 : 1);
1109 head->h_size = cpu_to_be32(log->l_iclog_size);
1110
1111 head->h_fmt = cpu_to_be32(XLOG_FMT);
1112 memcpy(&head->h_fs_uuid, &mp->m_sb.sb_uuid, sizeof(uuid_t));
1113
1114 iclog->ic_size = XFS_BUF_SIZE(bp) - log->l_iclog_hsize;
1115 iclog->ic_state = XLOG_STATE_ACTIVE;
1116 iclog->ic_log = log;
1117 atomic_set(&iclog->ic_refcnt, 0);
1118 spin_lock_init(&iclog->ic_callback_lock);
1119 iclog->ic_callback_tail = &(iclog->ic_callback);
1120 iclog->ic_datap = (char *)iclog->ic_data + log->l_iclog_hsize;
1121
1122 ASSERT(XFS_BUF_ISBUSY(iclog->ic_bp));
1123 ASSERT(XFS_BUF_VALUSEMA(iclog->ic_bp) <= 0);
1124 init_waitqueue_head(&iclog->ic_force_wait);
1125 init_waitqueue_head(&iclog->ic_write_wait);
1126
1127 iclogp = &iclog->ic_next;
1128 }
1129 *iclogp = log->l_iclog;
1130 log->l_iclog->ic_prev = prev_iclog;
1131
1132 error = xlog_cil_init(log);
1133 if (error)
1134 goto out_free_iclog;
1135 return log;
1136
1137out_free_iclog:
1138 for (iclog = log->l_iclog; iclog; iclog = prev_iclog) {
1139 prev_iclog = iclog->ic_next;
1140 if (iclog->ic_bp)
1141 xfs_buf_free(iclog->ic_bp);
1142 kmem_free(iclog);
1143 }
1144 spinlock_destroy(&log->l_icloglock);
1145 xfs_buf_free(log->l_xbuf);
1146out_free_log:
1147 kmem_free(log);
1148out:
1149 return ERR_PTR(-error);
1150}
1151
1152
1153
1154
1155
1156
1157STATIC int
1158xlog_commit_record(
1159 struct log *log,
1160 struct xlog_ticket *ticket,
1161 struct xlog_in_core **iclog,
1162 xfs_lsn_t *commitlsnp)
1163{
1164 struct xfs_mount *mp = log->l_mp;
1165 int error;
1166 struct xfs_log_iovec reg = {
1167 .i_addr = NULL,
1168 .i_len = 0,
1169 .i_type = XLOG_REG_TYPE_COMMIT,
1170 };
1171 struct xfs_log_vec vec = {
1172 .lv_niovecs = 1,
1173 .lv_iovecp = ®,
1174 };
1175
1176 ASSERT_ALWAYS(iclog);
1177 error = xlog_write(log, &vec, ticket, commitlsnp, iclog,
1178 XLOG_COMMIT_TRANS);
1179 if (error)
1180 xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
1181 return error;
1182}
1183
1184
1185
1186
1187
1188
1189
1190
1191STATIC void
1192xlog_grant_push_ail(
1193 struct log *log,
1194 int need_bytes)
1195{
1196 xfs_lsn_t threshold_lsn = 0;
1197 xfs_lsn_t last_sync_lsn;
1198 int free_blocks;
1199 int free_bytes;
1200 int threshold_block;
1201 int threshold_cycle;
1202 int free_threshold;
1203
1204 ASSERT(BTOBB(need_bytes) < log->l_logBBsize);
1205
1206 free_bytes = xlog_space_left(log, &log->l_grant_reserve_head);
1207 free_blocks = BTOBBT(free_bytes);
1208
1209
1210
1211
1212
1213
1214 free_threshold = BTOBB(need_bytes);
1215 free_threshold = MAX(free_threshold, (log->l_logBBsize >> 2));
1216 free_threshold = MAX(free_threshold, 256);
1217 if (free_blocks >= free_threshold)
1218 return;
1219
1220 xlog_crack_atomic_lsn(&log->l_tail_lsn, &threshold_cycle,
1221 &threshold_block);
1222 threshold_block += free_threshold;
1223 if (threshold_block >= log->l_logBBsize) {
1224 threshold_block -= log->l_logBBsize;
1225 threshold_cycle += 1;
1226 }
1227 threshold_lsn = xlog_assign_lsn(threshold_cycle,
1228 threshold_block);
1229
1230
1231
1232
1233
1234 last_sync_lsn = atomic64_read(&log->l_last_sync_lsn);
1235 if (XFS_LSN_CMP(threshold_lsn, last_sync_lsn) > 0)
1236 threshold_lsn = last_sync_lsn;
1237
1238
1239
1240
1241
1242
1243 if (!XLOG_FORCED_SHUTDOWN(log))
1244 xfs_trans_ail_push(log->l_ailp, threshold_lsn);
1245}
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255STATIC int
1256xlog_bdstrat(
1257 struct xfs_buf *bp)
1258{
1259 struct xlog_in_core *iclog;
1260
1261 iclog = XFS_BUF_FSPRIVATE(bp, xlog_in_core_t *);
1262 if (iclog->ic_state & XLOG_STATE_IOERROR) {
1263 XFS_BUF_ERROR(bp, EIO);
1264 XFS_BUF_STALE(bp);
1265 xfs_buf_ioend(bp, 0);
1266
1267
1268
1269
1270
1271 return 0;
1272 }
1273
1274 bp->b_flags |= _XBF_RUN_QUEUES;
1275 xfs_buf_iorequest(bp);
1276 return 0;
1277}
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304STATIC int
1305xlog_sync(xlog_t *log,
1306 xlog_in_core_t *iclog)
1307{
1308 xfs_caddr_t dptr;
1309 xfs_buf_t *bp;
1310 int i;
1311 uint count;
1312 uint count_init;
1313 int roundoff;
1314 int split = 0;
1315 int error;
1316 int v2 = xfs_sb_version_haslogv2(&log->l_mp->m_sb);
1317
1318 XFS_STATS_INC(xs_log_writes);
1319 ASSERT(atomic_read(&iclog->ic_refcnt) == 0);
1320
1321
1322 count_init = log->l_iclog_hsize + iclog->ic_offset;
1323
1324
1325 if (v2 && log->l_mp->m_sb.sb_logsunit > 1) {
1326
1327 count = XLOG_LSUNITTOB(log, XLOG_BTOLSUNIT(log, count_init));
1328 } else {
1329 count = BBTOB(BTOBB(count_init));
1330 }
1331 roundoff = count - count_init;
1332 ASSERT(roundoff >= 0);
1333 ASSERT((v2 && log->l_mp->m_sb.sb_logsunit > 1 &&
1334 roundoff < log->l_mp->m_sb.sb_logsunit)
1335 ||
1336 (log->l_mp->m_sb.sb_logsunit <= 1 &&
1337 roundoff < BBTOB(1)));
1338
1339
1340 xlog_grant_add_space(log, &log->l_grant_reserve_head, roundoff);
1341 xlog_grant_add_space(log, &log->l_grant_write_head, roundoff);
1342
1343
1344 xlog_pack_data(log, iclog, roundoff);
1345
1346
1347 if (v2) {
1348 iclog->ic_header.h_len =
1349 cpu_to_be32(iclog->ic_offset + roundoff);
1350 } else {
1351 iclog->ic_header.h_len =
1352 cpu_to_be32(iclog->ic_offset);
1353 }
1354
1355 bp = iclog->ic_bp;
1356 ASSERT(XFS_BUF_FSPRIVATE2(bp, unsigned long) == (unsigned long)1);
1357 XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)2);
1358 XFS_BUF_SET_ADDR(bp, BLOCK_LSN(be64_to_cpu(iclog->ic_header.h_lsn)));
1359
1360 XFS_STATS_ADD(xs_log_blocks, BTOBB(count));
1361
1362
1363 if (XFS_BUF_ADDR(bp) + BTOBB(count) > log->l_logBBsize) {
1364 split = count - (BBTOB(log->l_logBBsize - XFS_BUF_ADDR(bp)));
1365 count = BBTOB(log->l_logBBsize - XFS_BUF_ADDR(bp));
1366 iclog->ic_bwritecnt = 2;
1367 } else {
1368 iclog->ic_bwritecnt = 1;
1369 }
1370 XFS_BUF_SET_COUNT(bp, count);
1371 XFS_BUF_SET_FSPRIVATE(bp, iclog);
1372 XFS_BUF_ZEROFLAGS(bp);
1373 XFS_BUF_BUSY(bp);
1374 XFS_BUF_ASYNC(bp);
1375 bp->b_flags |= XBF_LOG_BUFFER;
1376
1377 if (log->l_mp->m_flags & XFS_MOUNT_BARRIER)
1378 XFS_BUF_ORDERED(bp);
1379
1380 ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1);
1381 ASSERT(XFS_BUF_ADDR(bp) + BTOBB(count) <= log->l_logBBsize);
1382
1383 xlog_verify_iclog(log, iclog, count, B_TRUE);
1384
1385
1386 XFS_BUF_SET_ADDR(bp, XFS_BUF_ADDR(bp) + log->l_logBBstart);
1387
1388
1389
1390
1391 XFS_BUF_WRITE(bp);
1392
1393 if ((error = xlog_bdstrat(bp))) {
1394 xfs_ioerror_alert("xlog_sync", log->l_mp, bp,
1395 XFS_BUF_ADDR(bp));
1396 return error;
1397 }
1398 if (split) {
1399 bp = iclog->ic_log->l_xbuf;
1400 ASSERT(XFS_BUF_FSPRIVATE2(bp, unsigned long) ==
1401 (unsigned long)1);
1402 XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)2);
1403 XFS_BUF_SET_ADDR(bp, 0);
1404 XFS_BUF_SET_PTR(bp, (xfs_caddr_t)((__psint_t)&(iclog->ic_header)+
1405 (__psint_t)count), split);
1406 XFS_BUF_SET_FSPRIVATE(bp, iclog);
1407 XFS_BUF_ZEROFLAGS(bp);
1408 XFS_BUF_BUSY(bp);
1409 XFS_BUF_ASYNC(bp);
1410 bp->b_flags |= XBF_LOG_BUFFER;
1411 if (log->l_mp->m_flags & XFS_MOUNT_BARRIER)
1412 XFS_BUF_ORDERED(bp);
1413 dptr = XFS_BUF_PTR(bp);
1414
1415
1416
1417
1418
1419
1420 for (i = 0; i < split; i += BBSIZE) {
1421 be32_add_cpu((__be32 *)dptr, 1);
1422 if (be32_to_cpu(*(__be32 *)dptr) == XLOG_HEADER_MAGIC_NUM)
1423 be32_add_cpu((__be32 *)dptr, 1);
1424 dptr += BBSIZE;
1425 }
1426
1427 ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1);
1428 ASSERT(XFS_BUF_ADDR(bp) + BTOBB(count) <= log->l_logBBsize);
1429
1430
1431 XFS_BUF_SET_ADDR(bp, XFS_BUF_ADDR(bp) + log->l_logBBstart);
1432 XFS_BUF_WRITE(bp);
1433 if ((error = xlog_bdstrat(bp))) {
1434 xfs_ioerror_alert("xlog_sync (split)", log->l_mp,
1435 bp, XFS_BUF_ADDR(bp));
1436 return error;
1437 }
1438 }
1439 return 0;
1440}
1441
1442
1443
1444
1445
1446STATIC void
1447xlog_dealloc_log(xlog_t *log)
1448{
1449 xlog_in_core_t *iclog, *next_iclog;
1450 int i;
1451
1452 xlog_cil_destroy(log);
1453
1454 iclog = log->l_iclog;
1455 for (i=0; i<log->l_iclog_bufs; i++) {
1456 xfs_buf_free(iclog->ic_bp);
1457 next_iclog = iclog->ic_next;
1458 kmem_free(iclog);
1459 iclog = next_iclog;
1460 }
1461 spinlock_destroy(&log->l_icloglock);
1462
1463 xfs_buf_free(log->l_xbuf);
1464 log->l_mp->m_log = NULL;
1465 kmem_free(log);
1466}
1467
1468
1469
1470
1471
1472static inline void
1473xlog_state_finish_copy(xlog_t *log,
1474 xlog_in_core_t *iclog,
1475 int record_cnt,
1476 int copy_bytes)
1477{
1478 spin_lock(&log->l_icloglock);
1479
1480 be32_add_cpu(&iclog->ic_header.h_num_logops, record_cnt);
1481 iclog->ic_offset += copy_bytes;
1482
1483 spin_unlock(&log->l_icloglock);
1484}
1485
1486
1487
1488
1489
1490
1491
1492
1493void
1494xlog_print_tic_res(
1495 struct xfs_mount *mp,
1496 struct xlog_ticket *ticket)
1497{
1498 uint i;
1499 uint ophdr_spc = ticket->t_res_num_ophdrs * (uint)sizeof(xlog_op_header_t);
1500
1501
1502 static char *res_type_str[XLOG_REG_TYPE_MAX] = {
1503 "bformat",
1504 "bchunk",
1505 "efi_format",
1506 "efd_format",
1507 "iformat",
1508 "icore",
1509 "iext",
1510 "ibroot",
1511 "ilocal",
1512 "iattr_ext",
1513 "iattr_broot",
1514 "iattr_local",
1515 "qformat",
1516 "dquot",
1517 "quotaoff",
1518 "LR header",
1519 "unmount",
1520 "commit",
1521 "trans header"
1522 };
1523 static char *trans_type_str[XFS_TRANS_TYPE_MAX] = {
1524 "SETATTR_NOT_SIZE",
1525 "SETATTR_SIZE",
1526 "INACTIVE",
1527 "CREATE",
1528 "CREATE_TRUNC",
1529 "TRUNCATE_FILE",
1530 "REMOVE",
1531 "LINK",
1532 "RENAME",
1533 "MKDIR",
1534 "RMDIR",
1535 "SYMLINK",
1536 "SET_DMATTRS",
1537 "GROWFS",
1538 "STRAT_WRITE",
1539 "DIOSTRAT",
1540 "WRITE_SYNC",
1541 "WRITEID",
1542 "ADDAFORK",
1543 "ATTRINVAL",
1544 "ATRUNCATE",
1545 "ATTR_SET",
1546 "ATTR_RM",
1547 "ATTR_FLAG",
1548 "CLEAR_AGI_BUCKET",
1549 "QM_SBCHANGE",
1550 "DUMMY1",
1551 "DUMMY2",
1552 "QM_QUOTAOFF",
1553 "QM_DQALLOC",
1554 "QM_SETQLIM",
1555 "QM_DQCLUSTER",
1556 "QM_QINOCREATE",
1557 "QM_QUOTAOFF_END",
1558 "SB_UNIT",
1559 "FSYNC_TS",
1560 "GROWFSRT_ALLOC",
1561 "GROWFSRT_ZERO",
1562 "GROWFSRT_FREE",
1563 "SWAPEXT"
1564 };
1565
1566 xfs_fs_cmn_err(CE_WARN, mp,
1567 "xfs_log_write: reservation summary:\n"
1568 " trans type = %s (%u)\n"
1569 " unit res = %d bytes\n"
1570 " current res = %d bytes\n"
1571 " total reg = %u bytes (o/flow = %u bytes)\n"
1572 " ophdrs = %u (ophdr space = %u bytes)\n"
1573 " ophdr + reg = %u bytes\n"
1574 " num regions = %u\n",
1575 ((ticket->t_trans_type <= 0 ||
1576 ticket->t_trans_type > XFS_TRANS_TYPE_MAX) ?
1577 "bad-trans-type" : trans_type_str[ticket->t_trans_type-1]),
1578 ticket->t_trans_type,
1579 ticket->t_unit_res,
1580 ticket->t_curr_res,
1581 ticket->t_res_arr_sum, ticket->t_res_o_flow,
1582 ticket->t_res_num_ophdrs, ophdr_spc,
1583 ticket->t_res_arr_sum +
1584 ticket->t_res_o_flow + ophdr_spc,
1585 ticket->t_res_num);
1586
1587 for (i = 0; i < ticket->t_res_num; i++) {
1588 uint r_type = ticket->t_res_arr[i].r_type;
1589 cmn_err(CE_WARN,
1590 "region[%u]: %s - %u bytes\n",
1591 i,
1592 ((r_type <= 0 || r_type > XLOG_REG_TYPE_MAX) ?
1593 "bad-rtype" : res_type_str[r_type-1]),
1594 ticket->t_res_arr[i].r_len);
1595 }
1596
1597 xfs_cmn_err(XFS_PTAG_LOGRES, CE_ALERT, mp,
1598 "xfs_log_write: reservation ran out. Need to up reservation");
1599 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
1600}
1601
1602
1603
1604
1605
1606static int
1607xlog_write_calc_vec_length(
1608 struct xlog_ticket *ticket,
1609 struct xfs_log_vec *log_vector)
1610{
1611 struct xfs_log_vec *lv;
1612 int headers = 0;
1613 int len = 0;
1614 int i;
1615
1616
1617 if (ticket->t_flags & XLOG_TIC_INITED)
1618 headers++;
1619
1620 for (lv = log_vector; lv; lv = lv->lv_next) {
1621 headers += lv->lv_niovecs;
1622
1623 for (i = 0; i < lv->lv_niovecs; i++) {
1624 struct xfs_log_iovec *vecp = &lv->lv_iovecp[i];
1625
1626 len += vecp->i_len;
1627 xlog_tic_add_region(ticket, vecp->i_len, vecp->i_type);
1628 }
1629 }
1630
1631 ticket->t_res_num_ophdrs += headers;
1632 len += headers * sizeof(struct xlog_op_header);
1633
1634 return len;
1635}
1636
1637
1638
1639
1640
1641static int
1642xlog_write_start_rec(
1643 struct xlog_op_header *ophdr,
1644 struct xlog_ticket *ticket)
1645{
1646 if (!(ticket->t_flags & XLOG_TIC_INITED))
1647 return 0;
1648
1649 ophdr->oh_tid = cpu_to_be32(ticket->t_tid);
1650 ophdr->oh_clientid = ticket->t_clientid;
1651 ophdr->oh_len = 0;
1652 ophdr->oh_flags = XLOG_START_TRANS;
1653 ophdr->oh_res2 = 0;
1654
1655 ticket->t_flags &= ~XLOG_TIC_INITED;
1656
1657 return sizeof(struct xlog_op_header);
1658}
1659
1660static xlog_op_header_t *
1661xlog_write_setup_ophdr(
1662 struct log *log,
1663 struct xlog_op_header *ophdr,
1664 struct xlog_ticket *ticket,
1665 uint flags)
1666{
1667 ophdr->oh_tid = cpu_to_be32(ticket->t_tid);
1668 ophdr->oh_clientid = ticket->t_clientid;
1669 ophdr->oh_res2 = 0;
1670
1671
1672 ophdr->oh_flags = flags;
1673
1674
1675
1676
1677
1678
1679 switch (ophdr->oh_clientid) {
1680 case XFS_TRANSACTION:
1681 case XFS_VOLUME:
1682 case XFS_LOG:
1683 break;
1684 default:
1685 xfs_fs_cmn_err(CE_WARN, log->l_mp,
1686 "Bad XFS transaction clientid 0x%x in ticket 0x%p",
1687 ophdr->oh_clientid, ticket);
1688 return NULL;
1689 }
1690
1691 return ophdr;
1692}
1693
1694
1695
1696
1697
1698
1699
1700static int
1701xlog_write_setup_copy(
1702 struct xlog_ticket *ticket,
1703 struct xlog_op_header *ophdr,
1704 int space_available,
1705 int space_required,
1706 int *copy_off,
1707 int *copy_len,
1708 int *last_was_partial_copy,
1709 int *bytes_consumed)
1710{
1711 int still_to_copy;
1712
1713 still_to_copy = space_required - *bytes_consumed;
1714 *copy_off = *bytes_consumed;
1715
1716 if (still_to_copy <= space_available) {
1717
1718 *copy_len = still_to_copy;
1719 ophdr->oh_len = cpu_to_be32(*copy_len);
1720 if (*last_was_partial_copy)
1721 ophdr->oh_flags |= (XLOG_END_TRANS|XLOG_WAS_CONT_TRANS);
1722 *last_was_partial_copy = 0;
1723 *bytes_consumed = 0;
1724 return 0;
1725 }
1726
1727
1728 *copy_len = space_available;
1729 ophdr->oh_len = cpu_to_be32(*copy_len);
1730 ophdr->oh_flags |= XLOG_CONTINUE_TRANS;
1731 if (*last_was_partial_copy)
1732 ophdr->oh_flags |= XLOG_WAS_CONT_TRANS;
1733 *bytes_consumed += *copy_len;
1734 (*last_was_partial_copy)++;
1735
1736
1737 ticket->t_curr_res -= sizeof(struct xlog_op_header);
1738 ticket->t_res_num_ophdrs++;
1739
1740 return sizeof(struct xlog_op_header);
1741}
1742
1743static int
1744xlog_write_copy_finish(
1745 struct log *log,
1746 struct xlog_in_core *iclog,
1747 uint flags,
1748 int *record_cnt,
1749 int *data_cnt,
1750 int *partial_copy,
1751 int *partial_copy_len,
1752 int log_offset,
1753 struct xlog_in_core **commit_iclog)
1754{
1755 if (*partial_copy) {
1756
1757
1758
1759
1760 xlog_state_finish_copy(log, iclog, *record_cnt, *data_cnt);
1761 *record_cnt = 0;
1762 *data_cnt = 0;
1763 return xlog_state_release_iclog(log, iclog);
1764 }
1765
1766 *partial_copy = 0;
1767 *partial_copy_len = 0;
1768
1769 if (iclog->ic_size - log_offset <= sizeof(xlog_op_header_t)) {
1770
1771 xlog_state_finish_copy(log, iclog, *record_cnt, *data_cnt);
1772 *record_cnt = 0;
1773 *data_cnt = 0;
1774
1775 spin_lock(&log->l_icloglock);
1776 xlog_state_want_sync(log, iclog);
1777 spin_unlock(&log->l_icloglock);
1778
1779 if (!commit_iclog)
1780 return xlog_state_release_iclog(log, iclog);
1781 ASSERT(flags & XLOG_COMMIT_TRANS);
1782 *commit_iclog = iclog;
1783 }
1784
1785 return 0;
1786}
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828int
1829xlog_write(
1830 struct log *log,
1831 struct xfs_log_vec *log_vector,
1832 struct xlog_ticket *ticket,
1833 xfs_lsn_t *start_lsn,
1834 struct xlog_in_core **commit_iclog,
1835 uint flags)
1836{
1837 struct xlog_in_core *iclog = NULL;
1838 struct xfs_log_iovec *vecp;
1839 struct xfs_log_vec *lv;
1840 int len;
1841 int index;
1842 int partial_copy = 0;
1843 int partial_copy_len = 0;
1844 int contwr = 0;
1845 int record_cnt = 0;
1846 int data_cnt = 0;
1847 int error;
1848
1849 *start_lsn = 0;
1850
1851 len = xlog_write_calc_vec_length(ticket, log_vector);
1852 if (log->l_cilp) {
1853
1854
1855
1856
1857
1858 if (ticket->t_flags & XLOG_TIC_INITED)
1859 ticket->t_curr_res -= sizeof(xlog_op_header_t);
1860
1861
1862
1863
1864
1865 if (flags & (XLOG_COMMIT_TRANS | XLOG_UNMOUNT_TRANS))
1866 ticket->t_curr_res -= sizeof(xlog_op_header_t);
1867 } else
1868 ticket->t_curr_res -= len;
1869
1870 if (ticket->t_curr_res < 0)
1871 xlog_print_tic_res(log->l_mp, ticket);
1872
1873 index = 0;
1874 lv = log_vector;
1875 vecp = lv->lv_iovecp;
1876 while (lv && index < lv->lv_niovecs) {
1877 void *ptr;
1878 int log_offset;
1879
1880 error = xlog_state_get_iclog_space(log, len, &iclog, ticket,
1881 &contwr, &log_offset);
1882 if (error)
1883 return error;
1884
1885 ASSERT(log_offset <= iclog->ic_size - 1);
1886 ptr = iclog->ic_datap + log_offset;
1887
1888
1889 if (!*start_lsn)
1890 *start_lsn = be64_to_cpu(iclog->ic_header.h_lsn);
1891
1892
1893
1894
1895
1896 while (lv && index < lv->lv_niovecs) {
1897 struct xfs_log_iovec *reg = &vecp[index];
1898 struct xlog_op_header *ophdr;
1899 int start_rec_copy;
1900 int copy_len;
1901 int copy_off;
1902
1903 ASSERT(reg->i_len % sizeof(__int32_t) == 0);
1904 ASSERT((unsigned long)ptr % sizeof(__int32_t) == 0);
1905
1906 start_rec_copy = xlog_write_start_rec(ptr, ticket);
1907 if (start_rec_copy) {
1908 record_cnt++;
1909 xlog_write_adv_cnt(&ptr, &len, &log_offset,
1910 start_rec_copy);
1911 }
1912
1913 ophdr = xlog_write_setup_ophdr(log, ptr, ticket, flags);
1914 if (!ophdr)
1915 return XFS_ERROR(EIO);
1916
1917 xlog_write_adv_cnt(&ptr, &len, &log_offset,
1918 sizeof(struct xlog_op_header));
1919
1920 len += xlog_write_setup_copy(ticket, ophdr,
1921 iclog->ic_size-log_offset,
1922 reg->i_len,
1923 ©_off, ©_len,
1924 &partial_copy,
1925 &partial_copy_len);
1926 xlog_verify_dest_ptr(log, ptr);
1927
1928
1929 ASSERT(copy_len >= 0);
1930 memcpy(ptr, reg->i_addr + copy_off, copy_len);
1931 xlog_write_adv_cnt(&ptr, &len, &log_offset, copy_len);
1932
1933 copy_len += start_rec_copy + sizeof(xlog_op_header_t);
1934 record_cnt++;
1935 data_cnt += contwr ? copy_len : 0;
1936
1937 error = xlog_write_copy_finish(log, iclog, flags,
1938 &record_cnt, &data_cnt,
1939 &partial_copy,
1940 &partial_copy_len,
1941 log_offset,
1942 commit_iclog);
1943 if (error)
1944 return error;
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958 if (partial_copy)
1959 break;
1960
1961 if (++index == lv->lv_niovecs) {
1962 lv = lv->lv_next;
1963 index = 0;
1964 if (lv)
1965 vecp = lv->lv_iovecp;
1966 }
1967 if (record_cnt == 0) {
1968 if (!lv)
1969 return 0;
1970 break;
1971 }
1972 }
1973 }
1974
1975 ASSERT(len == 0);
1976
1977 xlog_state_finish_copy(log, iclog, record_cnt, data_cnt);
1978 if (!commit_iclog)
1979 return xlog_state_release_iclog(log, iclog);
1980
1981 ASSERT(flags & XLOG_COMMIT_TRANS);
1982 *commit_iclog = iclog;
1983 return 0;
1984}
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002STATIC void
2003xlog_state_clean_log(xlog_t *log)
2004{
2005 xlog_in_core_t *iclog;
2006 int changed = 0;
2007
2008 iclog = log->l_iclog;
2009 do {
2010 if (iclog->ic_state == XLOG_STATE_DIRTY) {
2011 iclog->ic_state = XLOG_STATE_ACTIVE;
2012 iclog->ic_offset = 0;
2013 ASSERT(iclog->ic_callback == NULL);
2014
2015
2016
2017
2018
2019
2020
2021
2022 if (!changed &&
2023 (be32_to_cpu(iclog->ic_header.h_num_logops) ==
2024 XLOG_COVER_OPS)) {
2025 changed = 1;
2026 } else {
2027
2028
2029
2030
2031
2032 changed = 2;
2033 }
2034 iclog->ic_header.h_num_logops = 0;
2035 memset(iclog->ic_header.h_cycle_data, 0,
2036 sizeof(iclog->ic_header.h_cycle_data));
2037 iclog->ic_header.h_lsn = 0;
2038 } else if (iclog->ic_state == XLOG_STATE_ACTIVE)
2039 ;
2040 else
2041 break;
2042 iclog = iclog->ic_next;
2043 } while (iclog != log->l_iclog);
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053 if (changed) {
2054 switch (log->l_covered_state) {
2055 case XLOG_STATE_COVER_IDLE:
2056 case XLOG_STATE_COVER_NEED:
2057 case XLOG_STATE_COVER_NEED2:
2058 log->l_covered_state = XLOG_STATE_COVER_NEED;
2059 break;
2060
2061 case XLOG_STATE_COVER_DONE:
2062 if (changed == 1)
2063 log->l_covered_state = XLOG_STATE_COVER_NEED2;
2064 else
2065 log->l_covered_state = XLOG_STATE_COVER_NEED;
2066 break;
2067
2068 case XLOG_STATE_COVER_DONE2:
2069 if (changed == 1)
2070 log->l_covered_state = XLOG_STATE_COVER_IDLE;
2071 else
2072 log->l_covered_state = XLOG_STATE_COVER_NEED;
2073 break;
2074
2075 default:
2076 ASSERT(0);
2077 }
2078 }
2079}
2080
2081STATIC xfs_lsn_t
2082xlog_get_lowest_lsn(
2083 xlog_t *log)
2084{
2085 xlog_in_core_t *lsn_log;
2086 xfs_lsn_t lowest_lsn, lsn;
2087
2088 lsn_log = log->l_iclog;
2089 lowest_lsn = 0;
2090 do {
2091 if (!(lsn_log->ic_state & (XLOG_STATE_ACTIVE|XLOG_STATE_DIRTY))) {
2092 lsn = be64_to_cpu(lsn_log->ic_header.h_lsn);
2093 if ((lsn && !lowest_lsn) ||
2094 (XFS_LSN_CMP(lsn, lowest_lsn) < 0)) {
2095 lowest_lsn = lsn;
2096 }
2097 }
2098 lsn_log = lsn_log->ic_next;
2099 } while (lsn_log != log->l_iclog);
2100 return lowest_lsn;
2101}
2102
2103
2104STATIC void
2105xlog_state_do_callback(
2106 xlog_t *log,
2107 int aborted,
2108 xlog_in_core_t *ciclog)
2109{
2110 xlog_in_core_t *iclog;
2111 xlog_in_core_t *first_iclog;
2112
2113 xfs_log_callback_t *cb, *cb_next;
2114 int flushcnt = 0;
2115 xfs_lsn_t lowest_lsn;
2116 int ioerrors;
2117 int loopdidcallbacks;
2118 int funcdidcallbacks;
2119 int repeats;
2120
2121 int wake = 0;
2122
2123 spin_lock(&log->l_icloglock);
2124 first_iclog = iclog = log->l_iclog;
2125 ioerrors = 0;
2126 funcdidcallbacks = 0;
2127 repeats = 0;
2128
2129 do {
2130
2131
2132
2133
2134
2135
2136
2137
2138 first_iclog = log->l_iclog;
2139 iclog = log->l_iclog;
2140 loopdidcallbacks = 0;
2141 repeats++;
2142
2143 do {
2144
2145
2146 if (iclog->ic_state &
2147 (XLOG_STATE_ACTIVE|XLOG_STATE_DIRTY)) {
2148 iclog = iclog->ic_next;
2149 continue;
2150 }
2151
2152
2153
2154
2155
2156
2157
2158
2159 if (!(iclog->ic_state & XLOG_STATE_IOERROR)) {
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170 if (!(iclog->ic_state &
2171 (XLOG_STATE_DONE_SYNC |
2172 XLOG_STATE_DO_CALLBACK))) {
2173 if (ciclog && (ciclog->ic_state ==
2174 XLOG_STATE_DONE_SYNC)) {
2175 ciclog->ic_state = XLOG_STATE_DO_CALLBACK;
2176 }
2177 break;
2178 }
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193 lowest_lsn = xlog_get_lowest_lsn(log);
2194 if (lowest_lsn &&
2195 XFS_LSN_CMP(lowest_lsn,
2196 be64_to_cpu(iclog->ic_header.h_lsn)) < 0) {
2197 iclog = iclog->ic_next;
2198 continue;
2199
2200 }
2201
2202 iclog->ic_state = XLOG_STATE_CALLBACK;
2203
2204
2205
2206
2207
2208
2209
2210 ASSERT(XFS_LSN_CMP(atomic64_read(&log->l_last_sync_lsn),
2211 be64_to_cpu(iclog->ic_header.h_lsn)) <= 0);
2212 atomic64_set(&log->l_last_sync_lsn,
2213 be64_to_cpu(iclog->ic_header.h_lsn));
2214
2215 } else
2216 ioerrors++;
2217
2218 spin_unlock(&log->l_icloglock);
2219
2220
2221
2222
2223
2224
2225
2226
2227 spin_lock(&iclog->ic_callback_lock);
2228 cb = iclog->ic_callback;
2229 while (cb) {
2230 iclog->ic_callback_tail = &(iclog->ic_callback);
2231 iclog->ic_callback = NULL;
2232 spin_unlock(&iclog->ic_callback_lock);
2233
2234
2235 for (; cb; cb = cb_next) {
2236 cb_next = cb->cb_next;
2237 cb->cb_func(cb->cb_arg, aborted);
2238 }
2239 spin_lock(&iclog->ic_callback_lock);
2240 cb = iclog->ic_callback;
2241 }
2242
2243 loopdidcallbacks++;
2244 funcdidcallbacks++;
2245
2246 spin_lock(&log->l_icloglock);
2247 ASSERT(iclog->ic_callback == NULL);
2248 spin_unlock(&iclog->ic_callback_lock);
2249 if (!(iclog->ic_state & XLOG_STATE_IOERROR))
2250 iclog->ic_state = XLOG_STATE_DIRTY;
2251
2252
2253
2254
2255
2256 xlog_state_clean_log(log);
2257
2258
2259 wake_up_all(&iclog->ic_force_wait);
2260
2261 iclog = iclog->ic_next;
2262 } while (first_iclog != iclog);
2263
2264 if (repeats > 5000) {
2265 flushcnt += repeats;
2266 repeats = 0;
2267 xfs_fs_cmn_err(CE_WARN, log->l_mp,
2268 "%s: possible infinite loop (%d iterations)",
2269 __func__, flushcnt);
2270 }
2271 } while (!ioerrors && loopdidcallbacks);
2272
2273
2274
2275
2276
2277#ifdef DEBUG
2278 if (funcdidcallbacks) {
2279 first_iclog = iclog = log->l_iclog;
2280 do {
2281 ASSERT(iclog->ic_state != XLOG_STATE_DO_CALLBACK);
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291 if (iclog->ic_state == XLOG_STATE_WANT_SYNC ||
2292 iclog->ic_state == XLOG_STATE_SYNCING ||
2293 iclog->ic_state == XLOG_STATE_DONE_SYNC ||
2294 iclog->ic_state == XLOG_STATE_IOERROR )
2295 break;
2296 iclog = iclog->ic_next;
2297 } while (first_iclog != iclog);
2298 }
2299#endif
2300
2301 if (log->l_iclog->ic_state & (XLOG_STATE_ACTIVE|XLOG_STATE_IOERROR))
2302 wake = 1;
2303 spin_unlock(&log->l_icloglock);
2304
2305 if (wake)
2306 wake_up_all(&log->l_flush_wait);
2307}
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323STATIC void
2324xlog_state_done_syncing(
2325 xlog_in_core_t *iclog,
2326 int aborted)
2327{
2328 xlog_t *log = iclog->ic_log;
2329
2330 spin_lock(&log->l_icloglock);
2331
2332 ASSERT(iclog->ic_state == XLOG_STATE_SYNCING ||
2333 iclog->ic_state == XLOG_STATE_IOERROR);
2334 ASSERT(atomic_read(&iclog->ic_refcnt) == 0);
2335 ASSERT(iclog->ic_bwritecnt == 1 || iclog->ic_bwritecnt == 2);
2336
2337
2338
2339
2340
2341
2342
2343
2344 if (iclog->ic_state != XLOG_STATE_IOERROR) {
2345 if (--iclog->ic_bwritecnt == 1) {
2346 spin_unlock(&log->l_icloglock);
2347 return;
2348 }
2349 iclog->ic_state = XLOG_STATE_DONE_SYNC;
2350 }
2351
2352
2353
2354
2355
2356
2357 wake_up_all(&iclog->ic_write_wait);
2358 spin_unlock(&log->l_icloglock);
2359 xlog_state_do_callback(log, aborted, iclog);
2360}
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381STATIC int
2382xlog_state_get_iclog_space(xlog_t *log,
2383 int len,
2384 xlog_in_core_t **iclogp,
2385 xlog_ticket_t *ticket,
2386 int *continued_write,
2387 int *logoffsetp)
2388{
2389 int log_offset;
2390 xlog_rec_header_t *head;
2391 xlog_in_core_t *iclog;
2392 int error;
2393
2394restart:
2395 spin_lock(&log->l_icloglock);
2396 if (XLOG_FORCED_SHUTDOWN(log)) {
2397 spin_unlock(&log->l_icloglock);
2398 return XFS_ERROR(EIO);
2399 }
2400
2401 iclog = log->l_iclog;
2402 if (iclog->ic_state != XLOG_STATE_ACTIVE) {
2403 XFS_STATS_INC(xs_log_noiclogs);
2404
2405
2406 xlog_wait(&log->l_flush_wait, &log->l_icloglock);
2407 goto restart;
2408 }
2409
2410 head = &iclog->ic_header;
2411
2412 atomic_inc(&iclog->ic_refcnt);
2413 log_offset = iclog->ic_offset;
2414
2415
2416
2417
2418
2419
2420 if (log_offset == 0) {
2421 ticket->t_curr_res -= log->l_iclog_hsize;
2422 xlog_tic_add_region(ticket,
2423 log->l_iclog_hsize,
2424 XLOG_REG_TYPE_LRHEADER);
2425 head->h_cycle = cpu_to_be32(log->l_curr_cycle);
2426 head->h_lsn = cpu_to_be64(
2427 xlog_assign_lsn(log->l_curr_cycle, log->l_curr_block));
2428 ASSERT(log->l_curr_block >= 0);
2429 }
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440 if (iclog->ic_size - iclog->ic_offset < 2*sizeof(xlog_op_header_t)) {
2441 xlog_state_switch_iclogs(log, iclog, iclog->ic_size);
2442
2443
2444
2445
2446
2447
2448
2449
2450 if (!atomic_add_unless(&iclog->ic_refcnt, -1, 1)) {
2451
2452 spin_unlock(&log->l_icloglock);
2453 error = xlog_state_release_iclog(log, iclog);
2454 if (error)
2455 return error;
2456 } else {
2457 spin_unlock(&log->l_icloglock);
2458 }
2459 goto restart;
2460 }
2461
2462
2463
2464
2465
2466
2467
2468 if (len <= iclog->ic_size - iclog->ic_offset) {
2469 *continued_write = 0;
2470 iclog->ic_offset += len;
2471 } else {
2472 *continued_write = 1;
2473 xlog_state_switch_iclogs(log, iclog, iclog->ic_size);
2474 }
2475 *iclogp = iclog;
2476
2477 ASSERT(iclog->ic_offset <= iclog->ic_size);
2478 spin_unlock(&log->l_icloglock);
2479
2480 *logoffsetp = log_offset;
2481 return 0;
2482}
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502STATIC int
2503xlog_grant_log_space(xlog_t *log,
2504 xlog_ticket_t *tic)
2505{
2506 int free_bytes;
2507 int need_bytes;
2508
2509#ifdef DEBUG
2510 if (log->l_flags & XLOG_ACTIVE_RECOVERY)
2511 panic("grant Recovery problem");
2512#endif
2513
2514 trace_xfs_log_grant_enter(log, tic);
2515
2516 need_bytes = tic->t_unit_res;
2517 if (tic->t_flags & XFS_LOG_PERM_RESERV)
2518 need_bytes *= tic->t_ocnt;
2519
2520
2521 if (!list_empty_careful(&log->l_reserveq)) {
2522 spin_lock(&log->l_grant_reserve_lock);
2523
2524 if (list_empty(&log->l_reserveq)) {
2525 spin_unlock(&log->l_grant_reserve_lock);
2526 goto redo;
2527 }
2528 list_add_tail(&tic->t_queue, &log->l_reserveq);
2529
2530 trace_xfs_log_grant_sleep1(log, tic);
2531
2532
2533
2534
2535
2536 if (XLOG_FORCED_SHUTDOWN(log))
2537 goto error_return;
2538
2539 XFS_STATS_INC(xs_sleep_logspace);
2540 xlog_wait(&tic->t_wait, &log->l_grant_reserve_lock);
2541
2542
2543
2544
2545
2546 trace_xfs_log_grant_wake1(log, tic);
2547 }
2548
2549redo:
2550 if (XLOG_FORCED_SHUTDOWN(log))
2551 goto error_return_unlocked;
2552
2553 free_bytes = xlog_space_left(log, &log->l_grant_reserve_head);
2554 if (free_bytes < need_bytes) {
2555 spin_lock(&log->l_grant_reserve_lock);
2556 if (list_empty(&tic->t_queue))
2557 list_add_tail(&tic->t_queue, &log->l_reserveq);
2558
2559 trace_xfs_log_grant_sleep2(log, tic);
2560
2561 if (XLOG_FORCED_SHUTDOWN(log))
2562 goto error_return;
2563
2564 xlog_grant_push_ail(log, need_bytes);
2565
2566 XFS_STATS_INC(xs_sleep_logspace);
2567 xlog_wait(&tic->t_wait, &log->l_grant_reserve_lock);
2568
2569 trace_xfs_log_grant_wake2(log, tic);
2570 goto redo;
2571 }
2572
2573 if (!list_empty(&tic->t_queue)) {
2574 spin_lock(&log->l_grant_reserve_lock);
2575 list_del_init(&tic->t_queue);
2576 spin_unlock(&log->l_grant_reserve_lock);
2577 }
2578
2579
2580 xlog_grant_add_space(log, &log->l_grant_reserve_head, need_bytes);
2581 xlog_grant_add_space(log, &log->l_grant_write_head, need_bytes);
2582 trace_xfs_log_grant_exit(log, tic);
2583 xlog_verify_grant_tail(log);
2584 return 0;
2585
2586error_return_unlocked:
2587 spin_lock(&log->l_grant_reserve_lock);
2588error_return:
2589 list_del_init(&tic->t_queue);
2590 spin_unlock(&log->l_grant_reserve_lock);
2591 trace_xfs_log_grant_error(log, tic);
2592
2593
2594
2595
2596
2597
2598 tic->t_curr_res = 0;
2599 tic->t_cnt = 0;
2600 return XFS_ERROR(EIO);
2601}
2602
2603
2604
2605
2606
2607
2608
2609
2610STATIC int
2611xlog_regrant_write_log_space(xlog_t *log,
2612 xlog_ticket_t *tic)
2613{
2614 int free_bytes, need_bytes;
2615
2616 tic->t_curr_res = tic->t_unit_res;
2617 xlog_tic_reset_res(tic);
2618
2619 if (tic->t_cnt > 0)
2620 return 0;
2621
2622#ifdef DEBUG
2623 if (log->l_flags & XLOG_ACTIVE_RECOVERY)
2624 panic("regrant Recovery problem");
2625#endif
2626
2627 trace_xfs_log_regrant_write_enter(log, tic);
2628 if (XLOG_FORCED_SHUTDOWN(log))
2629 goto error_return_unlocked;
2630
2631
2632
2633
2634
2635
2636
2637 need_bytes = tic->t_unit_res;
2638 if (!list_empty_careful(&log->l_writeq)) {
2639 struct xlog_ticket *ntic;
2640
2641 spin_lock(&log->l_grant_write_lock);
2642 free_bytes = xlog_space_left(log, &log->l_grant_write_head);
2643 list_for_each_entry(ntic, &log->l_writeq, t_queue) {
2644 ASSERT(ntic->t_flags & XLOG_TIC_PERM_RESERV);
2645
2646 if (free_bytes < ntic->t_unit_res)
2647 break;
2648 free_bytes -= ntic->t_unit_res;
2649 wake_up(&ntic->t_wait);
2650 }
2651
2652 if (ntic != list_first_entry(&log->l_writeq,
2653 struct xlog_ticket, t_queue)) {
2654 if (list_empty(&tic->t_queue))
2655 list_add_tail(&tic->t_queue, &log->l_writeq);
2656 trace_xfs_log_regrant_write_sleep1(log, tic);
2657
2658 xlog_grant_push_ail(log, need_bytes);
2659
2660 XFS_STATS_INC(xs_sleep_logspace);
2661 xlog_wait(&tic->t_wait, &log->l_grant_write_lock);
2662 trace_xfs_log_regrant_write_wake1(log, tic);
2663 } else
2664 spin_unlock(&log->l_grant_write_lock);
2665 }
2666
2667redo:
2668 if (XLOG_FORCED_SHUTDOWN(log))
2669 goto error_return_unlocked;
2670
2671 free_bytes = xlog_space_left(log, &log->l_grant_write_head);
2672 if (free_bytes < need_bytes) {
2673 spin_lock(&log->l_grant_write_lock);
2674 if (list_empty(&tic->t_queue))
2675 list_add_tail(&tic->t_queue, &log->l_writeq);
2676
2677 if (XLOG_FORCED_SHUTDOWN(log))
2678 goto error_return;
2679
2680 xlog_grant_push_ail(log, need_bytes);
2681
2682 XFS_STATS_INC(xs_sleep_logspace);
2683 trace_xfs_log_regrant_write_sleep2(log, tic);
2684 xlog_wait(&tic->t_wait, &log->l_grant_write_lock);
2685
2686 trace_xfs_log_regrant_write_wake2(log, tic);
2687 goto redo;
2688 }
2689
2690 if (!list_empty(&tic->t_queue)) {
2691 spin_lock(&log->l_grant_write_lock);
2692 list_del_init(&tic->t_queue);
2693 spin_unlock(&log->l_grant_write_lock);
2694 }
2695
2696
2697 xlog_grant_add_space(log, &log->l_grant_write_head, need_bytes);
2698 trace_xfs_log_regrant_write_exit(log, tic);
2699 xlog_verify_grant_tail(log);
2700 return 0;
2701
2702
2703 error_return_unlocked:
2704 spin_lock(&log->l_grant_write_lock);
2705 error_return:
2706 list_del_init(&tic->t_queue);
2707 spin_unlock(&log->l_grant_write_lock);
2708 trace_xfs_log_regrant_write_error(log, tic);
2709
2710
2711
2712
2713
2714
2715 tic->t_curr_res = 0;
2716 tic->t_cnt = 0;
2717 return XFS_ERROR(EIO);
2718}
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728STATIC void
2729xlog_regrant_reserve_log_space(xlog_t *log,
2730 xlog_ticket_t *ticket)
2731{
2732 trace_xfs_log_regrant_reserve_enter(log, ticket);
2733
2734 if (ticket->t_cnt > 0)
2735 ticket->t_cnt--;
2736
2737 xlog_grant_sub_space(log, &log->l_grant_reserve_head,
2738 ticket->t_curr_res);
2739 xlog_grant_sub_space(log, &log->l_grant_write_head,
2740 ticket->t_curr_res);
2741 ticket->t_curr_res = ticket->t_unit_res;
2742 xlog_tic_reset_res(ticket);
2743
2744 trace_xfs_log_regrant_reserve_sub(log, ticket);
2745
2746
2747 if (ticket->t_cnt > 0)
2748 return;
2749
2750 xlog_grant_add_space(log, &log->l_grant_reserve_head,
2751 ticket->t_unit_res);
2752
2753 trace_xfs_log_regrant_reserve_exit(log, ticket);
2754
2755 ticket->t_curr_res = ticket->t_unit_res;
2756 xlog_tic_reset_res(ticket);
2757}
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774STATIC void
2775xlog_ungrant_log_space(xlog_t *log,
2776 xlog_ticket_t *ticket)
2777{
2778 int bytes;
2779
2780 if (ticket->t_cnt > 0)
2781 ticket->t_cnt--;
2782
2783 trace_xfs_log_ungrant_enter(log, ticket);
2784 trace_xfs_log_ungrant_sub(log, ticket);
2785
2786
2787
2788
2789
2790 bytes = ticket->t_curr_res;
2791 if (ticket->t_cnt > 0) {
2792 ASSERT(ticket->t_flags & XLOG_TIC_PERM_RESERV);
2793 bytes += ticket->t_unit_res*ticket->t_cnt;
2794 }
2795
2796 xlog_grant_sub_space(log, &log->l_grant_reserve_head, bytes);
2797 xlog_grant_sub_space(log, &log->l_grant_write_head, bytes);
2798
2799 trace_xfs_log_ungrant_exit(log, ticket);
2800
2801 xfs_log_move_tail(log->l_mp, 1);
2802}
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814STATIC int
2815xlog_state_release_iclog(
2816 xlog_t *log,
2817 xlog_in_core_t *iclog)
2818{
2819 int sync = 0;
2820
2821 if (iclog->ic_state & XLOG_STATE_IOERROR)
2822 return XFS_ERROR(EIO);
2823
2824 ASSERT(atomic_read(&iclog->ic_refcnt) > 0);
2825 if (!atomic_dec_and_lock(&iclog->ic_refcnt, &log->l_icloglock))
2826 return 0;
2827
2828 if (iclog->ic_state & XLOG_STATE_IOERROR) {
2829 spin_unlock(&log->l_icloglock);
2830 return XFS_ERROR(EIO);
2831 }
2832 ASSERT(iclog->ic_state == XLOG_STATE_ACTIVE ||
2833 iclog->ic_state == XLOG_STATE_WANT_SYNC);
2834
2835 if (iclog->ic_state == XLOG_STATE_WANT_SYNC) {
2836
2837 xfs_lsn_t tail_lsn = xlog_assign_tail_lsn(log->l_mp);
2838 sync++;
2839 iclog->ic_state = XLOG_STATE_SYNCING;
2840 iclog->ic_header.h_tail_lsn = cpu_to_be64(tail_lsn);
2841 xlog_verify_tail_lsn(log, iclog, tail_lsn);
2842
2843 }
2844 spin_unlock(&log->l_icloglock);
2845
2846
2847
2848
2849
2850
2851
2852
2853 if (sync)
2854 return xlog_sync(log, iclog);
2855 return 0;
2856}
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866STATIC void
2867xlog_state_switch_iclogs(xlog_t *log,
2868 xlog_in_core_t *iclog,
2869 int eventual_size)
2870{
2871 ASSERT(iclog->ic_state == XLOG_STATE_ACTIVE);
2872 if (!eventual_size)
2873 eventual_size = iclog->ic_offset;
2874 iclog->ic_state = XLOG_STATE_WANT_SYNC;
2875 iclog->ic_header.h_prev_block = cpu_to_be32(log->l_prev_block);
2876 log->l_prev_block = log->l_curr_block;
2877 log->l_prev_cycle = log->l_curr_cycle;
2878
2879
2880 log->l_curr_block += BTOBB(eventual_size)+BTOBB(log->l_iclog_hsize);
2881
2882
2883 if (xfs_sb_version_haslogv2(&log->l_mp->m_sb) &&
2884 log->l_mp->m_sb.sb_logsunit > 1) {
2885 __uint32_t sunit_bb = BTOBB(log->l_mp->m_sb.sb_logsunit);
2886 log->l_curr_block = roundup(log->l_curr_block, sunit_bb);
2887 }
2888
2889 if (log->l_curr_block >= log->l_logBBsize) {
2890 log->l_curr_cycle++;
2891 if (log->l_curr_cycle == XLOG_HEADER_MAGIC_NUM)
2892 log->l_curr_cycle++;
2893 log->l_curr_block -= log->l_logBBsize;
2894 ASSERT(log->l_curr_block >= 0);
2895 }
2896 ASSERT(iclog == log->l_iclog);
2897 log->l_iclog = iclog->ic_next;
2898}
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927int
2928_xfs_log_force(
2929 struct xfs_mount *mp,
2930 uint flags,
2931 int *log_flushed)
2932{
2933 struct log *log = mp->m_log;
2934 struct xlog_in_core *iclog;
2935 xfs_lsn_t lsn;
2936
2937 XFS_STATS_INC(xs_log_force);
2938
2939 if (log->l_cilp)
2940 xlog_cil_force(log);
2941
2942 spin_lock(&log->l_icloglock);
2943
2944 iclog = log->l_iclog;
2945 if (iclog->ic_state & XLOG_STATE_IOERROR) {
2946 spin_unlock(&log->l_icloglock);
2947 return XFS_ERROR(EIO);
2948 }
2949
2950
2951
2952
2953 if (iclog->ic_state == XLOG_STATE_ACTIVE ||
2954 iclog->ic_state == XLOG_STATE_DIRTY) {
2955
2956
2957
2958
2959
2960
2961
2962 if (iclog->ic_state == XLOG_STATE_DIRTY ||
2963 (atomic_read(&iclog->ic_refcnt) == 0
2964 && iclog->ic_offset == 0)) {
2965 iclog = iclog->ic_prev;
2966 if (iclog->ic_state == XLOG_STATE_ACTIVE ||
2967 iclog->ic_state == XLOG_STATE_DIRTY)
2968 goto no_sleep;
2969 else
2970 goto maybe_sleep;
2971 } else {
2972 if (atomic_read(&iclog->ic_refcnt) == 0) {
2973
2974
2975
2976
2977
2978
2979 atomic_inc(&iclog->ic_refcnt);
2980 lsn = be64_to_cpu(iclog->ic_header.h_lsn);
2981 xlog_state_switch_iclogs(log, iclog, 0);
2982 spin_unlock(&log->l_icloglock);
2983
2984 if (xlog_state_release_iclog(log, iclog))
2985 return XFS_ERROR(EIO);
2986
2987 if (log_flushed)
2988 *log_flushed = 1;
2989 spin_lock(&log->l_icloglock);
2990 if (be64_to_cpu(iclog->ic_header.h_lsn) == lsn &&
2991 iclog->ic_state != XLOG_STATE_DIRTY)
2992 goto maybe_sleep;
2993 else
2994 goto no_sleep;
2995 } else {
2996
2997
2998
2999
3000
3001 xlog_state_switch_iclogs(log, iclog, 0);
3002 goto maybe_sleep;
3003 }
3004 }
3005 }
3006
3007
3008
3009
3010
3011maybe_sleep:
3012 if (flags & XFS_LOG_SYNC) {
3013
3014
3015
3016
3017
3018
3019 if (iclog->ic_state & XLOG_STATE_IOERROR) {
3020 spin_unlock(&log->l_icloglock);
3021 return XFS_ERROR(EIO);
3022 }
3023 XFS_STATS_INC(xs_log_force_sleep);
3024 xlog_wait(&iclog->ic_force_wait, &log->l_icloglock);
3025
3026
3027
3028
3029
3030 if (iclog->ic_state & XLOG_STATE_IOERROR)
3031 return XFS_ERROR(EIO);
3032 if (log_flushed)
3033 *log_flushed = 1;
3034 } else {
3035
3036no_sleep:
3037 spin_unlock(&log->l_icloglock);
3038 }
3039 return 0;
3040}
3041
3042
3043
3044
3045
3046
3047void
3048xfs_log_force(
3049 xfs_mount_t *mp,
3050 uint flags)
3051{
3052 int error;
3053
3054 error = _xfs_log_force(mp, flags, NULL);
3055 if (error) {
3056 xfs_fs_cmn_err(CE_WARN, mp, "xfs_log_force: "
3057 "error %d returned.", error);
3058 }
3059}
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076int
3077_xfs_log_force_lsn(
3078 struct xfs_mount *mp,
3079 xfs_lsn_t lsn,
3080 uint flags,
3081 int *log_flushed)
3082{
3083 struct log *log = mp->m_log;
3084 struct xlog_in_core *iclog;
3085 int already_slept = 0;
3086
3087 ASSERT(lsn != 0);
3088
3089 XFS_STATS_INC(xs_log_force);
3090
3091 if (log->l_cilp) {
3092 lsn = xlog_cil_force_lsn(log, lsn);
3093 if (lsn == NULLCOMMITLSN)
3094 return 0;
3095 }
3096
3097try_again:
3098 spin_lock(&log->l_icloglock);
3099 iclog = log->l_iclog;
3100 if (iclog->ic_state & XLOG_STATE_IOERROR) {
3101 spin_unlock(&log->l_icloglock);
3102 return XFS_ERROR(EIO);
3103 }
3104
3105 do {
3106 if (be64_to_cpu(iclog->ic_header.h_lsn) != lsn) {
3107 iclog = iclog->ic_next;
3108 continue;
3109 }
3110
3111 if (iclog->ic_state == XLOG_STATE_DIRTY) {
3112 spin_unlock(&log->l_icloglock);
3113 return 0;
3114 }
3115
3116 if (iclog->ic_state == XLOG_STATE_ACTIVE) {
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135 if (!already_slept &&
3136 (iclog->ic_prev->ic_state &
3137 (XLOG_STATE_WANT_SYNC | XLOG_STATE_SYNCING))) {
3138 ASSERT(!(iclog->ic_state & XLOG_STATE_IOERROR));
3139
3140 XFS_STATS_INC(xs_log_force_sleep);
3141
3142 xlog_wait(&iclog->ic_prev->ic_write_wait,
3143 &log->l_icloglock);
3144 if (log_flushed)
3145 *log_flushed = 1;
3146 already_slept = 1;
3147 goto try_again;
3148 }
3149 atomic_inc(&iclog->ic_refcnt);
3150 xlog_state_switch_iclogs(log, iclog, 0);
3151 spin_unlock(&log->l_icloglock);
3152 if (xlog_state_release_iclog(log, iclog))
3153 return XFS_ERROR(EIO);
3154 if (log_flushed)
3155 *log_flushed = 1;
3156 spin_lock(&log->l_icloglock);
3157 }
3158
3159 if ((flags & XFS_LOG_SYNC) &&
3160 !(iclog->ic_state &
3161 (XLOG_STATE_ACTIVE | XLOG_STATE_DIRTY))) {
3162
3163
3164
3165
3166 if (iclog->ic_state & XLOG_STATE_IOERROR) {
3167 spin_unlock(&log->l_icloglock);
3168 return XFS_ERROR(EIO);
3169 }
3170 XFS_STATS_INC(xs_log_force_sleep);
3171 xlog_wait(&iclog->ic_force_wait, &log->l_icloglock);
3172
3173
3174
3175
3176
3177 if (iclog->ic_state & XLOG_STATE_IOERROR)
3178 return XFS_ERROR(EIO);
3179
3180 if (log_flushed)
3181 *log_flushed = 1;
3182 } else {
3183 spin_unlock(&log->l_icloglock);
3184 }
3185
3186 return 0;
3187 } while (iclog != log->l_iclog);
3188
3189 spin_unlock(&log->l_icloglock);
3190 return 0;
3191}
3192
3193
3194
3195
3196
3197
3198void
3199xfs_log_force_lsn(
3200 xfs_mount_t *mp,
3201 xfs_lsn_t lsn,
3202 uint flags)
3203{
3204 int error;
3205
3206 error = _xfs_log_force_lsn(mp, lsn, flags, NULL);
3207 if (error) {
3208 xfs_fs_cmn_err(CE_WARN, mp, "xfs_log_force: "
3209 "error %d returned.", error);
3210 }
3211}
3212
3213
3214
3215
3216
3217STATIC void
3218xlog_state_want_sync(xlog_t *log, xlog_in_core_t *iclog)
3219{
3220 assert_spin_locked(&log->l_icloglock);
3221
3222 if (iclog->ic_state == XLOG_STATE_ACTIVE) {
3223 xlog_state_switch_iclogs(log, iclog, 0);
3224 } else {
3225 ASSERT(iclog->ic_state &
3226 (XLOG_STATE_WANT_SYNC|XLOG_STATE_IOERROR));
3227 }
3228}
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241void
3242xfs_log_ticket_put(
3243 xlog_ticket_t *ticket)
3244{
3245 ASSERT(atomic_read(&ticket->t_ref) > 0);
3246 if (atomic_dec_and_test(&ticket->t_ref))
3247 kmem_zone_free(xfs_log_ticket_zone, ticket);
3248}
3249
3250xlog_ticket_t *
3251xfs_log_ticket_get(
3252 xlog_ticket_t *ticket)
3253{
3254 ASSERT(atomic_read(&ticket->t_ref) > 0);
3255 atomic_inc(&ticket->t_ref);
3256 return ticket;
3257}
3258
3259xlog_tid_t
3260xfs_log_get_trans_ident(
3261 struct xfs_trans *tp)
3262{
3263 return tp->t_ticket->t_tid;
3264}
3265
3266
3267
3268
3269xlog_ticket_t *
3270xlog_ticket_alloc(
3271 struct log *log,
3272 int unit_bytes,
3273 int cnt,
3274 char client,
3275 uint xflags,
3276 int alloc_flags)
3277{
3278 struct xlog_ticket *tic;
3279 uint num_headers;
3280 int iclog_space;
3281
3282 tic = kmem_zone_zalloc(xfs_log_ticket_zone, alloc_flags);
3283 if (!tic)
3284 return NULL;
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318 unit_bytes += sizeof(xlog_op_header_t);
3319 unit_bytes += sizeof(xfs_trans_header_t);
3320
3321
3322 unit_bytes += sizeof(xlog_op_header_t);
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341 iclog_space = log->l_iclog_size - log->l_iclog_hsize;
3342 num_headers = howmany(unit_bytes, iclog_space);
3343
3344
3345 unit_bytes += sizeof(xlog_op_header_t) * num_headers;
3346
3347
3348 while (!num_headers ||
3349 howmany(unit_bytes, iclog_space) > num_headers) {
3350 unit_bytes += sizeof(xlog_op_header_t);
3351 num_headers++;
3352 }
3353 unit_bytes += log->l_iclog_hsize * num_headers;
3354
3355
3356 unit_bytes += log->l_iclog_hsize;
3357
3358
3359 if (xfs_sb_version_haslogv2(&log->l_mp->m_sb) &&
3360 log->l_mp->m_sb.sb_logsunit > 1) {
3361
3362 unit_bytes += 2*log->l_mp->m_sb.sb_logsunit;
3363 } else {
3364
3365 unit_bytes += 2*BBSIZE;
3366 }
3367
3368 atomic_set(&tic->t_ref, 1);
3369 INIT_LIST_HEAD(&tic->t_queue);
3370 tic->t_unit_res = unit_bytes;
3371 tic->t_curr_res = unit_bytes;
3372 tic->t_cnt = cnt;
3373 tic->t_ocnt = cnt;
3374 tic->t_tid = random32();
3375 tic->t_clientid = client;
3376 tic->t_flags = XLOG_TIC_INITED;
3377 tic->t_trans_type = 0;
3378 if (xflags & XFS_LOG_PERM_RESERV)
3379 tic->t_flags |= XLOG_TIC_PERM_RESERV;
3380 init_waitqueue_head(&tic->t_wait);
3381
3382 xlog_tic_reset_res(tic);
3383
3384 return tic;
3385}
3386
3387
3388
3389
3390
3391
3392
3393
3394#if defined(DEBUG)
3395
3396
3397
3398
3399
3400void
3401xlog_verify_dest_ptr(
3402 struct log *log,
3403 char *ptr)
3404{
3405 int i;
3406 int good_ptr = 0;
3407
3408 for (i = 0; i < log->l_iclog_bufs; i++) {
3409 if (ptr >= log->l_iclog_bak[i] &&
3410 ptr <= log->l_iclog_bak[i] + log->l_iclog_size)
3411 good_ptr++;
3412 }
3413
3414 if (!good_ptr)
3415 xlog_panic("xlog_verify_dest_ptr: invalid ptr");
3416}
3417
3418STATIC void
3419xlog_verify_grant_tail(
3420 struct log *log)
3421{
3422 int tail_cycle, tail_blocks;
3423 int cycle, space;
3424
3425
3426
3427
3428
3429
3430
3431 xlog_crack_grant_head(&log->l_grant_write_head, &cycle, &space);
3432 xlog_crack_atomic_lsn(&log->l_tail_lsn, &tail_cycle, &tail_blocks);
3433 if (tail_cycle != cycle) {
3434 ASSERT(cycle - 1 == tail_cycle);
3435 ASSERT(space <= BBTOB(tail_blocks));
3436 }
3437}
3438
3439
3440STATIC void
3441xlog_verify_tail_lsn(xlog_t *log,
3442 xlog_in_core_t *iclog,
3443 xfs_lsn_t tail_lsn)
3444{
3445 int blocks;
3446
3447 if (CYCLE_LSN(tail_lsn) == log->l_prev_cycle) {
3448 blocks =
3449 log->l_logBBsize - (log->l_prev_block - BLOCK_LSN(tail_lsn));
3450 if (blocks < BTOBB(iclog->ic_offset)+BTOBB(log->l_iclog_hsize))
3451 xlog_panic("xlog_verify_tail_lsn: ran out of log space");
3452 } else {
3453 ASSERT(CYCLE_LSN(tail_lsn)+1 == log->l_prev_cycle);
3454
3455 if (BLOCK_LSN(tail_lsn) == log->l_prev_block)
3456 xlog_panic("xlog_verify_tail_lsn: tail wrapped");
3457
3458 blocks = BLOCK_LSN(tail_lsn) - log->l_prev_block;
3459 if (blocks < BTOBB(iclog->ic_offset) + 1)
3460 xlog_panic("xlog_verify_tail_lsn: ran out of log space");
3461 }
3462}
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479STATIC void
3480xlog_verify_iclog(xlog_t *log,
3481 xlog_in_core_t *iclog,
3482 int count,
3483 boolean_t syncing)
3484{
3485 xlog_op_header_t *ophead;
3486 xlog_in_core_t *icptr;
3487 xlog_in_core_2_t *xhdr;
3488 xfs_caddr_t ptr;
3489 xfs_caddr_t base_ptr;
3490 __psint_t field_offset;
3491 __uint8_t clientid;
3492 int len, i, j, k, op_len;
3493 int idx;
3494
3495
3496 spin_lock(&log->l_icloglock);
3497 icptr = log->l_iclog;
3498 for (i=0; i < log->l_iclog_bufs; i++) {
3499 if (icptr == NULL)
3500 xlog_panic("xlog_verify_iclog: invalid ptr");
3501 icptr = icptr->ic_next;
3502 }
3503 if (icptr != log->l_iclog)
3504 xlog_panic("xlog_verify_iclog: corrupt iclog ring");
3505 spin_unlock(&log->l_icloglock);
3506
3507
3508 if (be32_to_cpu(iclog->ic_header.h_magicno) != XLOG_HEADER_MAGIC_NUM)
3509 xlog_panic("xlog_verify_iclog: invalid magic num");
3510
3511 ptr = (xfs_caddr_t) &iclog->ic_header;
3512 for (ptr += BBSIZE; ptr < ((xfs_caddr_t)&iclog->ic_header) + count;
3513 ptr += BBSIZE) {
3514 if (be32_to_cpu(*(__be32 *)ptr) == XLOG_HEADER_MAGIC_NUM)
3515 xlog_panic("xlog_verify_iclog: unexpected magic num");
3516 }
3517
3518
3519 len = be32_to_cpu(iclog->ic_header.h_num_logops);
3520 ptr = iclog->ic_datap;
3521 base_ptr = ptr;
3522 ophead = (xlog_op_header_t *)ptr;
3523 xhdr = iclog->ic_data;
3524 for (i = 0; i < len; i++) {
3525 ophead = (xlog_op_header_t *)ptr;
3526
3527
3528 field_offset = (__psint_t)
3529 ((xfs_caddr_t)&(ophead->oh_clientid) - base_ptr);
3530 if (syncing == B_FALSE || (field_offset & 0x1ff)) {
3531 clientid = ophead->oh_clientid;
3532 } else {
3533 idx = BTOBBT((xfs_caddr_t)&(ophead->oh_clientid) - iclog->ic_datap);
3534 if (idx >= (XLOG_HEADER_CYCLE_SIZE / BBSIZE)) {
3535 j = idx / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
3536 k = idx % (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
3537 clientid = xlog_get_client_id(
3538 xhdr[j].hic_xheader.xh_cycle_data[k]);
3539 } else {
3540 clientid = xlog_get_client_id(
3541 iclog->ic_header.h_cycle_data[idx]);
3542 }
3543 }
3544 if (clientid != XFS_TRANSACTION && clientid != XFS_LOG)
3545 cmn_err(CE_WARN, "xlog_verify_iclog: "
3546 "invalid clientid %d op 0x%p offset 0x%lx",
3547 clientid, ophead, (unsigned long)field_offset);
3548
3549
3550 field_offset = (__psint_t)
3551 ((xfs_caddr_t)&(ophead->oh_len) - base_ptr);
3552 if (syncing == B_FALSE || (field_offset & 0x1ff)) {
3553 op_len = be32_to_cpu(ophead->oh_len);
3554 } else {
3555 idx = BTOBBT((__psint_t)&ophead->oh_len -
3556 (__psint_t)iclog->ic_datap);
3557 if (idx >= (XLOG_HEADER_CYCLE_SIZE / BBSIZE)) {
3558 j = idx / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
3559 k = idx % (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
3560 op_len = be32_to_cpu(xhdr[j].hic_xheader.xh_cycle_data[k]);
3561 } else {
3562 op_len = be32_to_cpu(iclog->ic_header.h_cycle_data[idx]);
3563 }
3564 }
3565 ptr += sizeof(xlog_op_header_t) + op_len;
3566 }
3567}
3568#endif
3569
3570
3571
3572
3573STATIC int
3574xlog_state_ioerror(
3575 xlog_t *log)
3576{
3577 xlog_in_core_t *iclog, *ic;
3578
3579 iclog = log->l_iclog;
3580 if (! (iclog->ic_state & XLOG_STATE_IOERROR)) {
3581
3582
3583
3584
3585 ic = iclog;
3586 do {
3587 ic->ic_state = XLOG_STATE_IOERROR;
3588 ic = ic->ic_next;
3589 } while (ic != iclog);
3590 return 0;
3591 }
3592
3593
3594
3595 return 1;
3596}
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615int
3616xfs_log_force_umount(
3617 struct xfs_mount *mp,
3618 int logerror)
3619{
3620 xlog_ticket_t *tic;
3621 xlog_t *log;
3622 int retval;
3623
3624 log = mp->m_log;
3625
3626
3627
3628
3629
3630 if (!log ||
3631 log->l_flags & XLOG_ACTIVE_RECOVERY) {
3632 mp->m_flags |= XFS_MOUNT_FS_SHUTDOWN;
3633 if (mp->m_sb_bp)
3634 XFS_BUF_DONE(mp->m_sb_bp);
3635 return 0;
3636 }
3637
3638
3639
3640
3641
3642 if (logerror && log->l_iclog->ic_state & XLOG_STATE_IOERROR) {
3643 ASSERT(XLOG_FORCED_SHUTDOWN(log));
3644 return 1;
3645 }
3646 retval = 0;
3647
3648
3649
3650
3651
3652
3653
3654 if (!logerror && (mp->m_flags & XFS_MOUNT_DELAYLOG))
3655 xlog_cil_force(log);
3656
3657
3658
3659
3660
3661 spin_lock(&log->l_icloglock);
3662 mp->m_flags |= XFS_MOUNT_FS_SHUTDOWN;
3663 if (mp->m_sb_bp)
3664 XFS_BUF_DONE(mp->m_sb_bp);
3665
3666
3667
3668
3669
3670
3671 log->l_flags |= XLOG_IO_ERROR;
3672
3673
3674
3675
3676
3677 if (logerror)
3678 retval = xlog_state_ioerror(log);
3679 spin_unlock(&log->l_icloglock);
3680
3681
3682
3683
3684
3685
3686
3687
3688 spin_lock(&log->l_grant_reserve_lock);
3689 list_for_each_entry(tic, &log->l_reserveq, t_queue)
3690 wake_up(&tic->t_wait);
3691 spin_unlock(&log->l_grant_reserve_lock);
3692
3693 spin_lock(&log->l_grant_write_lock);
3694 list_for_each_entry(tic, &log->l_writeq, t_queue)
3695 wake_up(&tic->t_wait);
3696 spin_unlock(&log->l_grant_write_lock);
3697
3698 if (!(log->l_iclog->ic_state & XLOG_STATE_IOERROR)) {
3699 ASSERT(!logerror);
3700
3701
3702
3703
3704 _xfs_log_force(mp, XFS_LOG_SYNC, NULL);
3705
3706 spin_lock(&log->l_icloglock);
3707 retval = xlog_state_ioerror(log);
3708 spin_unlock(&log->l_icloglock);
3709 }
3710
3711
3712
3713
3714
3715 xlog_state_do_callback(log, XFS_LI_ABORTED, NULL);
3716
3717#ifdef XFSERRORDEBUG
3718 {
3719 xlog_in_core_t *iclog;
3720
3721 spin_lock(&log->l_icloglock);
3722 iclog = log->l_iclog;
3723 do {
3724 ASSERT(iclog->ic_callback == 0);
3725 iclog = iclog->ic_next;
3726 } while (iclog != log->l_iclog);
3727 spin_unlock(&log->l_icloglock);
3728 }
3729#endif
3730
3731 return retval;
3732}
3733
3734STATIC int
3735xlog_iclogs_empty(xlog_t *log)
3736{
3737 xlog_in_core_t *iclog;
3738
3739 iclog = log->l_iclog;
3740 do {
3741
3742
3743
3744 if (iclog->ic_header.h_num_logops)
3745 return 0;
3746 iclog = iclog->ic_next;
3747 } while (iclog != log->l_iclog);
3748 return 1;
3749}
3750