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