aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_log.c
diff options
context:
space:
mode:
authorMark Brown <broonie@opensource.wolfsonmicro.com>2010-05-31 06:07:15 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2010-05-31 06:07:15 -0400
commite37c83c06c2690157a989df40dc99a6b61c9ea15 (patch)
tree024dfb8b2c9abeec9ca7cb0c0136c276d9aacc91 /fs/xfs/xfs_log.c
parentce1f7d30766f6549db6fa0b9e595e0d26a5b7d9a (diff)
parent67a3e12b05e055c0415c556a315a3d3eb637e29e (diff)
Merge commit 'v2.6.35-rc1' into for-2.6.36
Diffstat (limited to 'fs/xfs/xfs_log.c')
-rw-r--r--fs/xfs/xfs_log.c834
1 files changed, 546 insertions, 288 deletions
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index e8fba92d7cd9..5215abc8023a 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -44,13 +44,8 @@
44 44
45kmem_zone_t *xfs_log_ticket_zone; 45kmem_zone_t *xfs_log_ticket_zone;
46 46
47#define xlog_write_adv_cnt(ptr, len, off, bytes) \
48 { (ptr) += (bytes); \
49 (len) -= (bytes); \
50 (off) += (bytes);}
51
52/* Local miscellaneous function prototypes */ 47/* Local miscellaneous function prototypes */
53STATIC int xlog_commit_record(xfs_mount_t *mp, xlog_ticket_t *ticket, 48STATIC int xlog_commit_record(struct log *log, struct xlog_ticket *ticket,
54 xlog_in_core_t **, xfs_lsn_t *); 49 xlog_in_core_t **, xfs_lsn_t *);
55STATIC xlog_t * xlog_alloc_log(xfs_mount_t *mp, 50STATIC xlog_t * xlog_alloc_log(xfs_mount_t *mp,
56 xfs_buftarg_t *log_target, 51 xfs_buftarg_t *log_target,
@@ -59,11 +54,6 @@ STATIC xlog_t * xlog_alloc_log(xfs_mount_t *mp,
59STATIC int xlog_space_left(xlog_t *log, int cycle, int bytes); 54STATIC int xlog_space_left(xlog_t *log, int cycle, int bytes);
60STATIC int xlog_sync(xlog_t *log, xlog_in_core_t *iclog); 55STATIC int xlog_sync(xlog_t *log, xlog_in_core_t *iclog);
61STATIC void xlog_dealloc_log(xlog_t *log); 56STATIC 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 57
68/* local state machine functions */ 58/* local state machine functions */
69STATIC void xlog_state_done_syncing(xlog_in_core_t *iclog, int); 59STATIC void xlog_state_done_syncing(xlog_in_core_t *iclog, int);
@@ -93,16 +83,8 @@ STATIC int xlog_regrant_write_log_space(xlog_t *log,
93STATIC void xlog_ungrant_log_space(xlog_t *log, 83STATIC void xlog_ungrant_log_space(xlog_t *log,
94 xlog_ticket_t *ticket); 84 xlog_ticket_t *ticket);
95 85
96
97/* local ticket functions */
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) 86#if defined(DEBUG)
105STATIC void xlog_verify_dest_ptr(xlog_t *log, __psint_t ptr); 87STATIC void xlog_verify_dest_ptr(xlog_t *log, char *ptr);
106STATIC void xlog_verify_grant_head(xlog_t *log, int equals); 88STATIC void xlog_verify_grant_head(xlog_t *log, int equals);
107STATIC void xlog_verify_iclog(xlog_t *log, xlog_in_core_t *iclog, 89STATIC void xlog_verify_iclog(xlog_t *log, xlog_in_core_t *iclog,
108 int count, boolean_t syncing); 90 int count, boolean_t syncing);
@@ -258,7 +240,7 @@ xfs_log_done(
258 * If we get an error, just continue and give back the log ticket. 240 * If we get an error, just continue and give back the log ticket.
259 */ 241 */
260 (((ticket->t_flags & XLOG_TIC_INITED) == 0) && 242 (((ticket->t_flags & XLOG_TIC_INITED) == 0) &&
261 (xlog_commit_record(mp, ticket, iclog, &lsn)))) { 243 (xlog_commit_record(log, ticket, iclog, &lsn)))) {
262 lsn = (xfs_lsn_t) -1; 244 lsn = (xfs_lsn_t) -1;
263 if (ticket->t_flags & XLOG_TIC_PERM_RESERV) { 245 if (ticket->t_flags & XLOG_TIC_PERM_RESERV) {
264 flags |= XFS_LOG_REL_PERM_RESERV; 246 flags |= XFS_LOG_REL_PERM_RESERV;
@@ -367,6 +349,15 @@ xfs_log_reserve(
367 ASSERT(flags & XFS_LOG_PERM_RESERV); 349 ASSERT(flags & XFS_LOG_PERM_RESERV);
368 internal_ticket = *ticket; 350 internal_ticket = *ticket;
369 351
352 /*
353 * this is a new transaction on the ticket, so we need to
354 * change the transaction ID so that the next transaction has a
355 * different TID in the log. Just add one to the existing tid
356 * so that we can see chains of rolling transactions in the log
357 * easily.
358 */
359 internal_ticket->t_tid++;
360
370 trace_xfs_log_reserve(log, internal_ticket); 361 trace_xfs_log_reserve(log, internal_ticket);
371 362
372 xlog_grant_push_ail(mp, internal_ticket->t_unit_res); 363 xlog_grant_push_ail(mp, internal_ticket->t_unit_res);
@@ -374,7 +365,8 @@ xfs_log_reserve(
374 } else { 365 } else {
375 /* may sleep if need to allocate more tickets */ 366 /* may sleep if need to allocate more tickets */
376 internal_ticket = xlog_ticket_alloc(log, unit_bytes, cnt, 367 internal_ticket = xlog_ticket_alloc(log, unit_bytes, cnt,
377 client, flags); 368 client, flags,
369 KM_SLEEP|KM_MAYFAIL);
378 if (!internal_ticket) 370 if (!internal_ticket)
379 return XFS_ERROR(ENOMEM); 371 return XFS_ERROR(ENOMEM);
380 internal_ticket->t_trans_type = t_type; 372 internal_ticket->t_trans_type = t_type;
@@ -459,6 +451,13 @@ xfs_log_mount(
459 /* Normal transactions can now occur */ 451 /* Normal transactions can now occur */
460 mp->m_log->l_flags &= ~XLOG_ACTIVE_RECOVERY; 452 mp->m_log->l_flags &= ~XLOG_ACTIVE_RECOVERY;
461 453
454 /*
455 * Now the log has been fully initialised and we know were our
456 * space grant counters are, we can initialise the permanent ticket
457 * needed for delayed logging to work.
458 */
459 xlog_cil_init_post_recovery(mp->m_log);
460
462 return 0; 461 return 0;
463 462
464out_destroy_ail: 463out_destroy_ail:
@@ -516,18 +515,10 @@ xfs_log_unmount_write(xfs_mount_t *mp)
516#ifdef DEBUG 515#ifdef DEBUG
517 xlog_in_core_t *first_iclog; 516 xlog_in_core_t *first_iclog;
518#endif 517#endif
519 xfs_log_iovec_t reg[1];
520 xlog_ticket_t *tic = NULL; 518 xlog_ticket_t *tic = NULL;
521 xfs_lsn_t lsn; 519 xfs_lsn_t lsn;
522 int error; 520 int error;
523 521
524 /* the data section must be 32 bit size aligned */
525 struct {
526 __uint16_t magic;
527 __uint16_t pad1;
528 __uint32_t pad2; /* may as well make it 64 bits */
529 } magic = { XLOG_UNMOUNT_TYPE, 0, 0 };
530
531 /* 522 /*
532 * Don't write out unmount record on read-only mounts. 523 * Don't write out unmount record on read-only mounts.
533 * Or, if we are doing a forced umount (typically because of IO errors). 524 * Or, if we are doing a forced umount (typically because of IO errors).
@@ -549,16 +540,30 @@ xfs_log_unmount_write(xfs_mount_t *mp)
549 } while (iclog != first_iclog); 540 } while (iclog != first_iclog);
550#endif 541#endif
551 if (! (XLOG_FORCED_SHUTDOWN(log))) { 542 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, 543 error = xfs_log_reserve(mp, 600, 1, &tic,
557 XFS_LOG, 0, XLOG_UNMOUNT_REC_TYPE); 544 XFS_LOG, 0, XLOG_UNMOUNT_REC_TYPE);
558 if (!error) { 545 if (!error) {
546 /* the data section must be 32 bit size aligned */
547 struct {
548 __uint16_t magic;
549 __uint16_t pad1;
550 __uint32_t pad2; /* may as well make it 64 bits */
551 } magic = {
552 .magic = XLOG_UNMOUNT_TYPE,
553 };
554 struct xfs_log_iovec reg = {
555 .i_addr = (void *)&magic,
556 .i_len = sizeof(magic),
557 .i_type = XLOG_REG_TYPE_UNMOUNT,
558 };
559 struct xfs_log_vec vec = {
560 .lv_niovecs = 1,
561 .lv_iovecp = &reg,
562 };
563
559 /* remove inited flag */ 564 /* remove inited flag */
560 ((xlog_ticket_t *)tic)->t_flags = 0; 565 tic->t_flags = 0;
561 error = xlog_write(mp, reg, 1, tic, &lsn, 566 error = xlog_write(log, &vec, tic, &lsn,
562 NULL, XLOG_UNMOUNT_TRANS); 567 NULL, XLOG_UNMOUNT_TRANS);
563 /* 568 /*
564 * At this point, we're umounting anyway, 569 * At this point, we're umounting anyway,
@@ -648,10 +653,30 @@ xfs_log_unmount(xfs_mount_t *mp)
648 xlog_dealloc_log(mp->m_log); 653 xlog_dealloc_log(mp->m_log);
649} 654}
650 655
656void
657xfs_log_item_init(
658 struct xfs_mount *mp,
659 struct xfs_log_item *item,
660 int type,
661 struct xfs_item_ops *ops)
662{
663 item->li_mountp = mp;
664 item->li_ailp = mp->m_ail;
665 item->li_type = type;
666 item->li_ops = ops;
667 item->li_lv = NULL;
668
669 INIT_LIST_HEAD(&item->li_ail);
670 INIT_LIST_HEAD(&item->li_cil);
671}
672
651/* 673/*
652 * Write region vectors to log. The write happens using the space reservation 674 * Write region vectors to log. The write happens using the space reservation
653 * of the ticket (tic). It is not a requirement that all writes for a given 675 * of the ticket (tic). It is not a requirement that all writes for a given
654 * transaction occur with one call to xfs_log_write(). 676 * transaction occur with one call to xfs_log_write(). However, it is important
677 * to note that the transaction reservation code makes an assumption about the
678 * number of log headers a transaction requires that may be violated if you
679 * don't pass all the transaction vectors in one call....
655 */ 680 */
656int 681int
657xfs_log_write( 682xfs_log_write(
@@ -663,11 +688,15 @@ xfs_log_write(
663{ 688{
664 struct log *log = mp->m_log; 689 struct log *log = mp->m_log;
665 int error; 690 int error;
691 struct xfs_log_vec vec = {
692 .lv_niovecs = nentries,
693 .lv_iovecp = reg,
694 };
666 695
667 if (XLOG_FORCED_SHUTDOWN(log)) 696 if (XLOG_FORCED_SHUTDOWN(log))
668 return XFS_ERROR(EIO); 697 return XFS_ERROR(EIO);
669 698
670 error = xlog_write(mp, reg, nentries, tic, start_lsn, NULL, 0); 699 error = xlog_write(log, &vec, tic, start_lsn, NULL, 0);
671 if (error) 700 if (error)
672 xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR); 701 xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
673 return error; 702 return error;
@@ -745,9 +774,16 @@ xfs_log_move_tail(xfs_mount_t *mp,
745 774
746/* 775/*
747 * Determine if we have a transaction that has gone to disk 776 * Determine if we have a transaction that has gone to disk
748 * that needs to be covered. Log activity needs to be idle (no AIL and 777 * that needs to be covered. To begin the transition to the idle state
749 * nothing in the iclogs). And, we need to be in the right state indicating 778 * firstly the log needs to be idle (no AIL and nothing in the iclogs).
750 * something has gone out. 779 * If we are then in a state where covering is needed, the caller is informed
780 * that dummy transactions are required to move the log into the idle state.
781 *
782 * Because this is called as part of the sync process, we should also indicate
783 * that dummy transactions should be issued in anything but the covered or
784 * idle states. This ensures that the log tail is accurately reflected in
785 * the log at the end of the sync, hence if a crash occurrs avoids replay
786 * of transactions where the metadata is already on disk.
751 */ 787 */
752int 788int
753xfs_log_need_covered(xfs_mount_t *mp) 789xfs_log_need_covered(xfs_mount_t *mp)
@@ -759,17 +795,24 @@ xfs_log_need_covered(xfs_mount_t *mp)
759 return 0; 795 return 0;
760 796
761 spin_lock(&log->l_icloglock); 797 spin_lock(&log->l_icloglock);
762 if (((log->l_covered_state == XLOG_STATE_COVER_NEED) || 798 switch (log->l_covered_state) {
763 (log->l_covered_state == XLOG_STATE_COVER_NEED2)) 799 case XLOG_STATE_COVER_DONE:
764 && !xfs_trans_ail_tail(log->l_ailp) 800 case XLOG_STATE_COVER_DONE2:
765 && xlog_iclogs_empty(log)) { 801 case XLOG_STATE_COVER_IDLE:
766 if (log->l_covered_state == XLOG_STATE_COVER_NEED) 802 break;
767 log->l_covered_state = XLOG_STATE_COVER_DONE; 803 case XLOG_STATE_COVER_NEED:
768 else { 804 case XLOG_STATE_COVER_NEED2:
769 ASSERT(log->l_covered_state == XLOG_STATE_COVER_NEED2); 805 if (!xfs_trans_ail_tail(log->l_ailp) &&
770 log->l_covered_state = XLOG_STATE_COVER_DONE2; 806 xlog_iclogs_empty(log)) {
807 if (log->l_covered_state == XLOG_STATE_COVER_NEED)
808 log->l_covered_state = XLOG_STATE_COVER_DONE;
809 else
810 log->l_covered_state = XLOG_STATE_COVER_DONE2;
771 } 811 }
812 /* FALLTHRU */
813 default:
772 needed = 1; 814 needed = 1;
815 break;
773 } 816 }
774 spin_unlock(&log->l_icloglock); 817 spin_unlock(&log->l_icloglock);
775 return needed; 818 return needed;
@@ -1006,6 +1049,7 @@ xlog_alloc_log(xfs_mount_t *mp,
1006 int i; 1049 int i;
1007 int iclogsize; 1050 int iclogsize;
1008 int error = ENOMEM; 1051 int error = ENOMEM;
1052 uint log2_size = 0;
1009 1053
1010 log = kmem_zalloc(sizeof(xlog_t), KM_MAYFAIL); 1054 log = kmem_zalloc(sizeof(xlog_t), KM_MAYFAIL);
1011 if (!log) { 1055 if (!log) {
@@ -1031,29 +1075,30 @@ xlog_alloc_log(xfs_mount_t *mp,
1031 1075
1032 error = EFSCORRUPTED; 1076 error = EFSCORRUPTED;
1033 if (xfs_sb_version_hassector(&mp->m_sb)) { 1077 if (xfs_sb_version_hassector(&mp->m_sb)) {
1034 log->l_sectbb_log = mp->m_sb.sb_logsectlog - BBSHIFT; 1078 log2_size = mp->m_sb.sb_logsectlog;
1035 if (log->l_sectbb_log < 0 || 1079 if (log2_size < BBSHIFT) {
1036 log->l_sectbb_log > mp->m_sectbb_log) { 1080 xlog_warn("XFS: Log sector size too small "
1037 xlog_warn("XFS: Log sector size (0x%x) out of range.", 1081 "(0x%x < 0x%x)", log2_size, BBSHIFT);
1038 log->l_sectbb_log);
1039 goto out_free_log; 1082 goto out_free_log;
1040 } 1083 }
1041 1084
1042 /* for larger sector sizes, must have v2 or external log */ 1085 log2_size -= BBSHIFT;
1043 if (log->l_sectbb_log != 0 && 1086 if (log2_size > mp->m_sectbb_log) {
1044 (log->l_logBBstart != 0 && 1087 xlog_warn("XFS: Log sector size too large "
1045 !xfs_sb_version_haslogv2(&mp->m_sb))) { 1088 "(0x%x > 0x%x)", log2_size, mp->m_sectbb_log);
1046 xlog_warn("XFS: log sector size (0x%x) invalid "
1047 "for configuration.", log->l_sectbb_log);
1048 goto out_free_log; 1089 goto out_free_log;
1049 } 1090 }
1050 if (mp->m_sb.sb_logsectlog < BBSHIFT) { 1091
1051 xlog_warn("XFS: Log sector log (0x%x) too small.", 1092 /* for larger sector sizes, must have v2 or external log */
1052 mp->m_sb.sb_logsectlog); 1093 if (log2_size && log->l_logBBstart > 0 &&
1094 !xfs_sb_version_haslogv2(&mp->m_sb)) {
1095
1096 xlog_warn("XFS: log sector size (0x%x) invalid "
1097 "for configuration.", log2_size);
1053 goto out_free_log; 1098 goto out_free_log;
1054 } 1099 }
1055 } 1100 }
1056 log->l_sectbb_mask = (1 << log->l_sectbb_log) - 1; 1101 log->l_sectBBsize = 1 << log2_size;
1057 1102
1058 xlog_get_iclog_buffer_size(mp, log); 1103 xlog_get_iclog_buffer_size(mp, log);
1059 1104
@@ -1133,6 +1178,9 @@ xlog_alloc_log(xfs_mount_t *mp,
1133 *iclogp = log->l_iclog; /* complete ring */ 1178 *iclogp = log->l_iclog; /* complete ring */
1134 log->l_iclog->ic_prev = prev_iclog; /* re-write 1st prev ptr */ 1179 log->l_iclog->ic_prev = prev_iclog; /* re-write 1st prev ptr */
1135 1180
1181 error = xlog_cil_init(log);
1182 if (error)
1183 goto out_free_iclog;
1136 return log; 1184 return log;
1137 1185
1138out_free_iclog: 1186out_free_iclog:
@@ -1160,26 +1208,31 @@ out:
1160 * ticket. Return the lsn of the commit record. 1208 * ticket. Return the lsn of the commit record.
1161 */ 1209 */
1162STATIC int 1210STATIC int
1163xlog_commit_record(xfs_mount_t *mp, 1211xlog_commit_record(
1164 xlog_ticket_t *ticket, 1212 struct log *log,
1165 xlog_in_core_t **iclog, 1213 struct xlog_ticket *ticket,
1166 xfs_lsn_t *commitlsnp) 1214 struct xlog_in_core **iclog,
1215 xfs_lsn_t *commitlsnp)
1167{ 1216{
1168 int error; 1217 struct xfs_mount *mp = log->l_mp;
1169 xfs_log_iovec_t reg[1]; 1218 int error;
1170 1219 struct xfs_log_iovec reg = {
1171 reg[0].i_addr = NULL; 1220 .i_addr = NULL,
1172 reg[0].i_len = 0; 1221 .i_len = 0,
1173 reg[0].i_type = XLOG_REG_TYPE_COMMIT; 1222 .i_type = XLOG_REG_TYPE_COMMIT,
1223 };
1224 struct xfs_log_vec vec = {
1225 .lv_niovecs = 1,
1226 .lv_iovecp = &reg,
1227 };
1174 1228
1175 ASSERT_ALWAYS(iclog); 1229 ASSERT_ALWAYS(iclog);
1176 if ((error = xlog_write(mp, reg, 1, ticket, commitlsnp, 1230 error = xlog_write(log, &vec, ticket, commitlsnp, iclog,
1177 iclog, XLOG_COMMIT_TRANS))) { 1231 XLOG_COMMIT_TRANS);
1232 if (error)
1178 xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR); 1233 xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
1179 }
1180 return error; 1234 return error;
1181} /* xlog_commit_record */ 1235}
1182
1183 1236
1184/* 1237/*
1185 * Push on the buffer cache code if we ever use more than 75% of the on-disk 1238 * Push on the buffer cache code if we ever use more than 75% of the on-disk
@@ -1454,6 +1507,8 @@ xlog_dealloc_log(xlog_t *log)
1454 xlog_in_core_t *iclog, *next_iclog; 1507 xlog_in_core_t *iclog, *next_iclog;
1455 int i; 1508 int i;
1456 1509
1510 xlog_cil_destroy(log);
1511
1457 iclog = log->l_iclog; 1512 iclog = log->l_iclog;
1458 for (i=0; i<log->l_iclog_bufs; i++) { 1513 for (i=0; i<log->l_iclog_bufs; i++) {
1459 sv_destroy(&iclog->ic_force_wait); 1514 sv_destroy(&iclog->ic_force_wait);
@@ -1496,8 +1551,10 @@ xlog_state_finish_copy(xlog_t *log,
1496 * print out info relating to regions written which consume 1551 * print out info relating to regions written which consume
1497 * the reservation 1552 * the reservation
1498 */ 1553 */
1499STATIC void 1554void
1500xlog_print_tic_res(xfs_mount_t *mp, xlog_ticket_t *ticket) 1555xlog_print_tic_res(
1556 struct xfs_mount *mp,
1557 struct xlog_ticket *ticket)
1501{ 1558{
1502 uint i; 1559 uint i;
1503 uint ophdr_spc = ticket->t_res_num_ophdrs * (uint)sizeof(xlog_op_header_t); 1560 uint ophdr_spc = ticket->t_res_num_ophdrs * (uint)sizeof(xlog_op_header_t);
@@ -1597,6 +1654,196 @@ xlog_print_tic_res(xfs_mount_t *mp, xlog_ticket_t *ticket)
1597 "bad-rtype" : res_type_str[r_type-1]), 1654 "bad-rtype" : res_type_str[r_type-1]),
1598 ticket->t_res_arr[i].r_len); 1655 ticket->t_res_arr[i].r_len);
1599 } 1656 }
1657
1658 xfs_cmn_err(XFS_PTAG_LOGRES, CE_ALERT, mp,
1659 "xfs_log_write: reservation ran out. Need to up reservation");
1660 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
1661}
1662
1663/*
1664 * Calculate the potential space needed by the log vector. Each region gets
1665 * its own xlog_op_header_t and may need to be double word aligned.
1666 */
1667static int
1668xlog_write_calc_vec_length(
1669 struct xlog_ticket *ticket,
1670 struct xfs_log_vec *log_vector)
1671{
1672 struct xfs_log_vec *lv;
1673 int headers = 0;
1674 int len = 0;
1675 int i;
1676
1677 /* acct for start rec of xact */
1678 if (ticket->t_flags & XLOG_TIC_INITED)
1679 headers++;
1680
1681 for (lv = log_vector; lv; lv = lv->lv_next) {
1682 headers += lv->lv_niovecs;
1683
1684 for (i = 0; i < lv->lv_niovecs; i++) {
1685 struct xfs_log_iovec *vecp = &lv->lv_iovecp[i];
1686
1687 len += vecp->i_len;
1688 xlog_tic_add_region(ticket, vecp->i_len, vecp->i_type);
1689 }
1690 }
1691
1692 ticket->t_res_num_ophdrs += headers;
1693 len += headers * sizeof(struct xlog_op_header);
1694
1695 return len;
1696}
1697
1698/*
1699 * If first write for transaction, insert start record We can't be trying to
1700 * commit if we are inited. We can't have any "partial_copy" if we are inited.
1701 */
1702static int
1703xlog_write_start_rec(
1704 struct xlog_op_header *ophdr,
1705 struct xlog_ticket *ticket)
1706{
1707 if (!(ticket->t_flags & XLOG_TIC_INITED))
1708 return 0;
1709
1710 ophdr->oh_tid = cpu_to_be32(ticket->t_tid);
1711 ophdr->oh_clientid = ticket->t_clientid;
1712 ophdr->oh_len = 0;
1713 ophdr->oh_flags = XLOG_START_TRANS;
1714 ophdr->oh_res2 = 0;
1715
1716 ticket->t_flags &= ~XLOG_TIC_INITED;
1717
1718 return sizeof(struct xlog_op_header);
1719}
1720
1721static xlog_op_header_t *
1722xlog_write_setup_ophdr(
1723 struct log *log,
1724 struct xlog_op_header *ophdr,
1725 struct xlog_ticket *ticket,
1726 uint flags)
1727{
1728 ophdr->oh_tid = cpu_to_be32(ticket->t_tid);
1729 ophdr->oh_clientid = ticket->t_clientid;
1730 ophdr->oh_res2 = 0;
1731
1732 /* are we copying a commit or unmount record? */
1733 ophdr->oh_flags = flags;
1734
1735 /*
1736 * We've seen logs corrupted with bad transaction client ids. This
1737 * makes sure that XFS doesn't generate them on. Turn this into an EIO
1738 * and shut down the filesystem.
1739 */
1740 switch (ophdr->oh_clientid) {
1741 case XFS_TRANSACTION:
1742 case XFS_VOLUME:
1743 case XFS_LOG:
1744 break;
1745 default:
1746 xfs_fs_cmn_err(CE_WARN, log->l_mp,
1747 "Bad XFS transaction clientid 0x%x in ticket 0x%p",
1748 ophdr->oh_clientid, ticket);
1749 return NULL;
1750 }
1751
1752 return ophdr;
1753}
1754
1755/*
1756 * Set up the parameters of the region copy into the log. This has
1757 * to handle region write split across multiple log buffers - this
1758 * state is kept external to this function so that this code can
1759 * can be written in an obvious, self documenting manner.
1760 */
1761static int
1762xlog_write_setup_copy(
1763 struct xlog_ticket *ticket,
1764 struct xlog_op_header *ophdr,
1765 int space_available,
1766 int space_required,
1767 int *copy_off,
1768 int *copy_len,
1769 int *last_was_partial_copy,
1770 int *bytes_consumed)
1771{
1772 int still_to_copy;
1773
1774 still_to_copy = space_required - *bytes_consumed;
1775 *copy_off = *bytes_consumed;
1776
1777 if (still_to_copy <= space_available) {
1778 /* write of region completes here */
1779 *copy_len = still_to_copy;
1780 ophdr->oh_len = cpu_to_be32(*copy_len);
1781 if (*last_was_partial_copy)
1782 ophdr->oh_flags |= (XLOG_END_TRANS|XLOG_WAS_CONT_TRANS);
1783 *last_was_partial_copy = 0;
1784 *bytes_consumed = 0;
1785 return 0;
1786 }
1787
1788 /* partial write of region, needs extra log op header reservation */
1789 *copy_len = space_available;
1790 ophdr->oh_len = cpu_to_be32(*copy_len);
1791 ophdr->oh_flags |= XLOG_CONTINUE_TRANS;
1792 if (*last_was_partial_copy)
1793 ophdr->oh_flags |= XLOG_WAS_CONT_TRANS;
1794 *bytes_consumed += *copy_len;
1795 (*last_was_partial_copy)++;
1796
1797 /* account for new log op header */
1798 ticket->t_curr_res -= sizeof(struct xlog_op_header);
1799 ticket->t_res_num_ophdrs++;
1800
1801 return sizeof(struct xlog_op_header);
1802}
1803
1804static int
1805xlog_write_copy_finish(
1806 struct log *log,
1807 struct xlog_in_core *iclog,
1808 uint flags,
1809 int *record_cnt,
1810 int *data_cnt,
1811 int *partial_copy,
1812 int *partial_copy_len,
1813 int log_offset,
1814 struct xlog_in_core **commit_iclog)
1815{
1816 if (*partial_copy) {
1817 /*
1818 * This iclog has already been marked WANT_SYNC by
1819 * xlog_state_get_iclog_space.
1820 */
1821 xlog_state_finish_copy(log, iclog, *record_cnt, *data_cnt);
1822 *record_cnt = 0;
1823 *data_cnt = 0;
1824 return xlog_state_release_iclog(log, iclog);
1825 }
1826
1827 *partial_copy = 0;
1828 *partial_copy_len = 0;
1829
1830 if (iclog->ic_size - log_offset <= sizeof(xlog_op_header_t)) {
1831 /* no more space in this iclog - push it. */
1832 xlog_state_finish_copy(log, iclog, *record_cnt, *data_cnt);
1833 *record_cnt = 0;
1834 *data_cnt = 0;
1835
1836 spin_lock(&log->l_icloglock);
1837 xlog_state_want_sync(log, iclog);
1838 spin_unlock(&log->l_icloglock);
1839
1840 if (!commit_iclog)
1841 return xlog_state_release_iclog(log, iclog);
1842 ASSERT(flags & XLOG_COMMIT_TRANS);
1843 *commit_iclog = iclog;
1844 }
1845
1846 return 0;
1600} 1847}
1601 1848
1602/* 1849/*
@@ -1639,211 +1886,163 @@ xlog_print_tic_res(xfs_mount_t *mp, xlog_ticket_t *ticket)
1639 * we don't update ic_offset until the end when we know exactly how many 1886 * we don't update ic_offset until the end when we know exactly how many
1640 * bytes have been written out. 1887 * bytes have been written out.
1641 */ 1888 */
1642STATIC int 1889int
1643xlog_write( 1890xlog_write(
1644 struct xfs_mount *mp, 1891 struct log *log,
1645 struct xfs_log_iovec reg[], 1892 struct xfs_log_vec *log_vector,
1646 int nentries,
1647 struct xlog_ticket *ticket, 1893 struct xlog_ticket *ticket,
1648 xfs_lsn_t *start_lsn, 1894 xfs_lsn_t *start_lsn,
1649 struct xlog_in_core **commit_iclog, 1895 struct xlog_in_core **commit_iclog,
1650 uint flags) 1896 uint flags)
1651{ 1897{
1652 xlog_t *log = mp->m_log; 1898 struct xlog_in_core *iclog = NULL;
1653 xlog_in_core_t *iclog = NULL; /* ptr to current in-core log */ 1899 struct xfs_log_iovec *vecp;
1654 xlog_op_header_t *logop_head; /* ptr to log operation header */ 1900 struct xfs_log_vec *lv;
1655 __psint_t ptr; /* copy address into data region */ 1901 int len;
1656 int len; /* # xlog_write() bytes 2 still copy */ 1902 int index;
1657 int index; /* region index currently copying */ 1903 int partial_copy = 0;
1658 int log_offset; /* offset (from 0) into data region */ 1904 int partial_copy_len = 0;
1659 int start_rec_copy; /* # bytes to copy for start record */ 1905 int contwr = 0;
1660 int partial_copy; /* did we split a region? */ 1906 int record_cnt = 0;
1661 int partial_copy_len;/* # bytes copied if split region */ 1907 int data_cnt = 0;
1662 int need_copy; /* # bytes need to memcpy this region */ 1908 int error;
1663 int copy_len; /* # bytes actually memcpy'ing */
1664 int copy_off; /* # bytes from entry start */
1665 int contwr; /* continued write of in-core log? */
1666 int error;
1667 int record_cnt = 0, data_cnt = 0;
1668
1669 partial_copy_len = partial_copy = 0;
1670
1671 /* Calculate potential maximum space. Each region gets its own
1672 * xlog_op_header_t and may need to be double word aligned.
1673 */
1674 len = 0;
1675 if (ticket->t_flags & XLOG_TIC_INITED) { /* acct for start rec of xact */
1676 len += sizeof(xlog_op_header_t);
1677 ticket->t_res_num_ophdrs++;
1678 }
1679
1680 for (index = 0; index < nentries; index++) {
1681 len += sizeof(xlog_op_header_t); /* each region gets >= 1 */
1682 ticket->t_res_num_ophdrs++;
1683 len += reg[index].i_len;
1684 xlog_tic_add_region(ticket, reg[index].i_len, reg[index].i_type);
1685 }
1686 contwr = *start_lsn = 0;
1687 1909
1688 if (ticket->t_curr_res < len) { 1910 *start_lsn = 0;
1689 xlog_print_tic_res(mp, ticket);
1690#ifdef DEBUG
1691 xlog_panic(
1692 "xfs_log_write: reservation ran out. Need to up reservation");
1693#else
1694 /* Customer configurable panic */
1695 xfs_cmn_err(XFS_PTAG_LOGRES, CE_ALERT, mp,
1696 "xfs_log_write: reservation ran out. Need to up reservation");
1697 /* If we did not panic, shutdown the filesystem */
1698 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
1699#endif
1700 } else
1701 ticket->t_curr_res -= len;
1702 1911
1703 for (index = 0; index < nentries; ) { 1912 len = xlog_write_calc_vec_length(ticket, log_vector);
1704 if ((error = xlog_state_get_iclog_space(log, len, &iclog, ticket, 1913 if (log->l_cilp) {
1705 &contwr, &log_offset))) 1914 /*
1706 return error; 1915 * Region headers and bytes are already accounted for.
1916 * We only need to take into account start records and
1917 * split regions in this function.
1918 */
1919 if (ticket->t_flags & XLOG_TIC_INITED)
1920 ticket->t_curr_res -= sizeof(xlog_op_header_t);
1707 1921
1708 ASSERT(log_offset <= iclog->ic_size - 1); 1922 /*
1709 ptr = (__psint_t) ((char *)iclog->ic_datap+log_offset); 1923 * Commit record headers need to be accounted for. These
1924 * come in as separate writes so are easy to detect.
1925 */
1926 if (flags & (XLOG_COMMIT_TRANS | XLOG_UNMOUNT_TRANS))
1927 ticket->t_curr_res -= sizeof(xlog_op_header_t);
1928 } else
1929 ticket->t_curr_res -= len;
1930
1931 if (ticket->t_curr_res < 0)
1932 xlog_print_tic_res(log->l_mp, ticket);
1933
1934 index = 0;
1935 lv = log_vector;
1936 vecp = lv->lv_iovecp;
1937 while (lv && index < lv->lv_niovecs) {
1938 void *ptr;
1939 int log_offset;
1940
1941 error = xlog_state_get_iclog_space(log, len, &iclog, ticket,
1942 &contwr, &log_offset);
1943 if (error)
1944 return error;
1710 1945
1711 /* start_lsn is the first lsn written to. That's all we need. */ 1946 ASSERT(log_offset <= iclog->ic_size - 1);
1712 if (! *start_lsn) 1947 ptr = iclog->ic_datap + log_offset;
1713 *start_lsn = be64_to_cpu(iclog->ic_header.h_lsn);
1714 1948
1715 /* This loop writes out as many regions as can fit in the amount 1949 /* start_lsn is the first lsn written to. That's all we need. */
1716 * of space which was allocated by xlog_state_get_iclog_space(). 1950 if (!*start_lsn)
1717 */ 1951 *start_lsn = be64_to_cpu(iclog->ic_header.h_lsn);
1718 while (index < nentries) {
1719 ASSERT(reg[index].i_len % sizeof(__int32_t) == 0);
1720 ASSERT((__psint_t)ptr % sizeof(__int32_t) == 0);
1721 start_rec_copy = 0;
1722
1723 /* If first write for transaction, insert start record.
1724 * We can't be trying to commit if we are inited. We can't
1725 * have any "partial_copy" if we are inited.
1726 */
1727 if (ticket->t_flags & XLOG_TIC_INITED) {
1728 logop_head = (xlog_op_header_t *)ptr;
1729 logop_head->oh_tid = cpu_to_be32(ticket->t_tid);
1730 logop_head->oh_clientid = ticket->t_clientid;
1731 logop_head->oh_len = 0;
1732 logop_head->oh_flags = XLOG_START_TRANS;
1733 logop_head->oh_res2 = 0;
1734 ticket->t_flags &= ~XLOG_TIC_INITED; /* clear bit */
1735 record_cnt++;
1736
1737 start_rec_copy = sizeof(xlog_op_header_t);
1738 xlog_write_adv_cnt(ptr, len, log_offset, start_rec_copy);
1739 }
1740 1952
1741 /* Copy log operation header directly into data section */ 1953 /*
1742 logop_head = (xlog_op_header_t *)ptr; 1954 * This loop writes out as many regions as can fit in the amount
1743 logop_head->oh_tid = cpu_to_be32(ticket->t_tid); 1955 * of space which was allocated by xlog_state_get_iclog_space().
1744 logop_head->oh_clientid = ticket->t_clientid; 1956 */
1745 logop_head->oh_res2 = 0; 1957 while (lv && index < lv->lv_niovecs) {
1958 struct xfs_log_iovec *reg = &vecp[index];
1959 struct xlog_op_header *ophdr;
1960 int start_rec_copy;
1961 int copy_len;
1962 int copy_off;
1963
1964 ASSERT(reg->i_len % sizeof(__int32_t) == 0);
1965 ASSERT((unsigned long)ptr % sizeof(__int32_t) == 0);
1966
1967 start_rec_copy = xlog_write_start_rec(ptr, ticket);
1968 if (start_rec_copy) {
1969 record_cnt++;
1970 xlog_write_adv_cnt(&ptr, &len, &log_offset,
1971 start_rec_copy);
1972 }
1746 1973
1747 /* header copied directly */ 1974 ophdr = xlog_write_setup_ophdr(log, ptr, ticket, flags);
1748 xlog_write_adv_cnt(ptr, len, log_offset, sizeof(xlog_op_header_t)); 1975 if (!ophdr)
1976 return XFS_ERROR(EIO);
1749 1977
1750 /* are we copying a commit or unmount record? */ 1978 xlog_write_adv_cnt(&ptr, &len, &log_offset,
1751 logop_head->oh_flags = flags; 1979 sizeof(struct xlog_op_header));
1980
1981 len += xlog_write_setup_copy(ticket, ophdr,
1982 iclog->ic_size-log_offset,
1983 reg->i_len,
1984 &copy_off, &copy_len,
1985 &partial_copy,
1986 &partial_copy_len);
1987 xlog_verify_dest_ptr(log, ptr);
1988
1989 /* copy region */
1990 ASSERT(copy_len >= 0);
1991 memcpy(ptr, reg->i_addr + copy_off, copy_len);
1992 xlog_write_adv_cnt(&ptr, &len, &log_offset, copy_len);
1993
1994 copy_len += start_rec_copy + sizeof(xlog_op_header_t);
1995 record_cnt++;
1996 data_cnt += contwr ? copy_len : 0;
1997
1998 error = xlog_write_copy_finish(log, iclog, flags,
1999 &record_cnt, &data_cnt,
2000 &partial_copy,
2001 &partial_copy_len,
2002 log_offset,
2003 commit_iclog);
2004 if (error)
2005 return error;
1752 2006
1753 /* 2007 /*
1754 * We've seen logs corrupted with bad transaction client 2008 * if we had a partial copy, we need to get more iclog
1755 * ids. This makes sure that XFS doesn't generate them on. 2009 * space but we don't want to increment the region
1756 * Turn this into an EIO and shut down the filesystem. 2010 * index because there is still more is this region to
1757 */ 2011 * write.
1758 switch (logop_head->oh_clientid) { 2012 *
1759 case XFS_TRANSACTION: 2013 * If we completed writing this region, and we flushed
1760 case XFS_VOLUME: 2014 * the iclog (indicated by resetting of the record
1761 case XFS_LOG: 2015 * count), then we also need to get more log space. If
1762 break; 2016 * this was the last record, though, we are done and
1763 default: 2017 * can just return.
1764 xfs_fs_cmn_err(CE_WARN, mp, 2018 */
1765 "Bad XFS transaction clientid 0x%x in ticket 0x%p", 2019 if (partial_copy)
1766 logop_head->oh_clientid, ticket); 2020 break;
1767 return XFS_ERROR(EIO);
1768 }
1769 2021
1770 /* Partial write last time? => (partial_copy != 0) 2022 if (++index == lv->lv_niovecs) {
1771 * need_copy is the amount we'd like to copy if everything could 2023 lv = lv->lv_next;
1772 * fit in the current memcpy. 2024 index = 0;
1773 */ 2025 if (lv)
1774 need_copy = reg[index].i_len - partial_copy_len; 2026 vecp = lv->lv_iovecp;
1775 2027 }
1776 copy_off = partial_copy_len; 2028 if (record_cnt == 0) {
1777 if (need_copy <= iclog->ic_size - log_offset) { /*complete write */ 2029 if (!lv)
1778 copy_len = need_copy; 2030 return 0;
1779 logop_head->oh_len = cpu_to_be32(copy_len); 2031 break;
1780 if (partial_copy) 2032 }
1781 logop_head->oh_flags|= (XLOG_END_TRANS|XLOG_WAS_CONT_TRANS);
1782 partial_copy_len = partial_copy = 0;
1783 } else { /* partial write */
1784 copy_len = iclog->ic_size - log_offset;
1785 logop_head->oh_len = cpu_to_be32(copy_len);
1786 logop_head->oh_flags |= XLOG_CONTINUE_TRANS;
1787 if (partial_copy)
1788 logop_head->oh_flags |= XLOG_WAS_CONT_TRANS;
1789 partial_copy_len += copy_len;
1790 partial_copy++;
1791 len += sizeof(xlog_op_header_t); /* from splitting of region */
1792 /* account for new log op header */
1793 ticket->t_curr_res -= sizeof(xlog_op_header_t);
1794 ticket->t_res_num_ophdrs++;
1795 }
1796 xlog_verify_dest_ptr(log, ptr);
1797
1798 /* copy region */
1799 ASSERT(copy_len >= 0);
1800 memcpy((xfs_caddr_t)ptr, reg[index].i_addr + copy_off, copy_len);
1801 xlog_write_adv_cnt(ptr, len, log_offset, copy_len);
1802
1803 /* make copy_len total bytes copied, including headers */
1804 copy_len += start_rec_copy + sizeof(xlog_op_header_t);
1805 record_cnt++;
1806 data_cnt += contwr ? copy_len : 0;
1807 if (partial_copy) { /* copied partial region */
1808 /* already marked WANT_SYNC by xlog_state_get_iclog_space */
1809 xlog_state_finish_copy(log, iclog, record_cnt, data_cnt);
1810 record_cnt = data_cnt = 0;
1811 if ((error = xlog_state_release_iclog(log, iclog)))
1812 return error;
1813 break; /* don't increment index */
1814 } else { /* copied entire region */
1815 index++;
1816 partial_copy_len = partial_copy = 0;
1817
1818 if (iclog->ic_size - log_offset <= sizeof(xlog_op_header_t)) {
1819 xlog_state_finish_copy(log, iclog, record_cnt, data_cnt);
1820 record_cnt = data_cnt = 0;
1821 spin_lock(&log->l_icloglock);
1822 xlog_state_want_sync(log, iclog);
1823 spin_unlock(&log->l_icloglock);
1824 if (commit_iclog) {
1825 ASSERT(flags & XLOG_COMMIT_TRANS);
1826 *commit_iclog = iclog;
1827 } else if ((error = xlog_state_release_iclog(log, iclog)))
1828 return error;
1829 if (index == nentries)
1830 return 0; /* we are done */
1831 else
1832 break;
1833 } 2033 }
1834 } /* if (partial_copy) */ 2034 }
1835 } /* while (index < nentries) */ 2035
1836 } /* for (index = 0; index < nentries; ) */ 2036 ASSERT(len == 0);
1837 ASSERT(len == 0); 2037
2038 xlog_state_finish_copy(log, iclog, record_cnt, data_cnt);
2039 if (!commit_iclog)
2040 return xlog_state_release_iclog(log, iclog);
1838 2041
1839 xlog_state_finish_copy(log, iclog, record_cnt, data_cnt);
1840 if (commit_iclog) {
1841 ASSERT(flags & XLOG_COMMIT_TRANS); 2042 ASSERT(flags & XLOG_COMMIT_TRANS);
1842 *commit_iclog = iclog; 2043 *commit_iclog = iclog;
1843 return 0; 2044 return 0;
1844 } 2045}
1845 return xlog_state_release_iclog(log, iclog);
1846} /* xlog_write */
1847 2046
1848 2047
1849/***************************************************************************** 2048/*****************************************************************************
@@ -2826,6 +3025,8 @@ _xfs_log_force(
2826 3025
2827 XFS_STATS_INC(xs_log_force); 3026 XFS_STATS_INC(xs_log_force);
2828 3027
3028 xlog_cil_push(log, 1);
3029
2829 spin_lock(&log->l_icloglock); 3030 spin_lock(&log->l_icloglock);
2830 3031
2831 iclog = log->l_iclog; 3032 iclog = log->l_iclog;
@@ -2975,6 +3176,12 @@ _xfs_log_force_lsn(
2975 3176
2976 XFS_STATS_INC(xs_log_force); 3177 XFS_STATS_INC(xs_log_force);
2977 3178
3179 if (log->l_cilp) {
3180 lsn = xlog_cil_push_lsn(log, lsn);
3181 if (lsn == NULLCOMMITLSN)
3182 return 0;
3183 }
3184
2978try_again: 3185try_again:
2979 spin_lock(&log->l_icloglock); 3186 spin_lock(&log->l_icloglock);
2980 iclog = log->l_iclog; 3187 iclog = log->l_iclog;
@@ -3139,20 +3346,30 @@ xfs_log_ticket_get(
3139 return ticket; 3346 return ticket;
3140} 3347}
3141 3348
3349xlog_tid_t
3350xfs_log_get_trans_ident(
3351 struct xfs_trans *tp)
3352{
3353 return tp->t_ticket->t_tid;
3354}
3355
3142/* 3356/*
3143 * Allocate and initialise a new log ticket. 3357 * Allocate and initialise a new log ticket.
3144 */ 3358 */
3145STATIC xlog_ticket_t * 3359xlog_ticket_t *
3146xlog_ticket_alloc(xlog_t *log, 3360xlog_ticket_alloc(
3147 int unit_bytes, 3361 struct log *log,
3148 int cnt, 3362 int unit_bytes,
3149 char client, 3363 int cnt,
3150 uint xflags) 3364 char client,
3365 uint xflags,
3366 int alloc_flags)
3151{ 3367{
3152 xlog_ticket_t *tic; 3368 struct xlog_ticket *tic;
3153 uint num_headers; 3369 uint num_headers;
3370 int iclog_space;
3154 3371
3155 tic = kmem_zone_zalloc(xfs_log_ticket_zone, KM_SLEEP|KM_MAYFAIL); 3372 tic = kmem_zone_zalloc(xfs_log_ticket_zone, alloc_flags);
3156 if (!tic) 3373 if (!tic)
3157 return NULL; 3374 return NULL;
3158 3375
@@ -3194,16 +3411,40 @@ xlog_ticket_alloc(xlog_t *log,
3194 /* for start-rec */ 3411 /* for start-rec */
3195 unit_bytes += sizeof(xlog_op_header_t); 3412 unit_bytes += sizeof(xlog_op_header_t);
3196 3413
3197 /* for LR headers */ 3414 /*
3198 num_headers = ((unit_bytes + log->l_iclog_size-1) >> log->l_iclog_size_log); 3415 * for LR headers - the space for data in an iclog is the size minus
3416 * the space used for the headers. If we use the iclog size, then we
3417 * undercalculate the number of headers required.
3418 *
3419 * Furthermore - the addition of op headers for split-recs might
3420 * increase the space required enough to require more log and op
3421 * headers, so take that into account too.
3422 *
3423 * IMPORTANT: This reservation makes the assumption that if this
3424 * transaction is the first in an iclog and hence has the LR headers
3425 * accounted to it, then the remaining space in the iclog is
3426 * exclusively for this transaction. i.e. if the transaction is larger
3427 * than the iclog, it will be the only thing in that iclog.
3428 * Fundamentally, this means we must pass the entire log vector to
3429 * xlog_write to guarantee this.
3430 */
3431 iclog_space = log->l_iclog_size - log->l_iclog_hsize;
3432 num_headers = howmany(unit_bytes, iclog_space);
3433
3434 /* for split-recs - ophdrs added when data split over LRs */
3435 unit_bytes += sizeof(xlog_op_header_t) * num_headers;
3436
3437 /* add extra header reservations if we overrun */
3438 while (!num_headers ||
3439 howmany(unit_bytes, iclog_space) > num_headers) {
3440 unit_bytes += sizeof(xlog_op_header_t);
3441 num_headers++;
3442 }
3199 unit_bytes += log->l_iclog_hsize * num_headers; 3443 unit_bytes += log->l_iclog_hsize * num_headers;
3200 3444
3201 /* for commit-rec LR header - note: padding will subsume the ophdr */ 3445 /* for commit-rec LR header - note: padding will subsume the ophdr */
3202 unit_bytes += log->l_iclog_hsize; 3446 unit_bytes += log->l_iclog_hsize;
3203 3447
3204 /* for split-recs - ophdrs added when data split over LRs */
3205 unit_bytes += sizeof(xlog_op_header_t) * num_headers;
3206
3207 /* for roundoff padding for transaction data and one for commit record */ 3448 /* for roundoff padding for transaction data and one for commit record */
3208 if (xfs_sb_version_haslogv2(&log->l_mp->m_sb) && 3449 if (xfs_sb_version_haslogv2(&log->l_mp->m_sb) &&
3209 log->l_mp->m_sb.sb_logsunit > 1) { 3450 log->l_mp->m_sb.sb_logsunit > 1) {
@@ -3219,13 +3460,13 @@ xlog_ticket_alloc(xlog_t *log,
3219 tic->t_curr_res = unit_bytes; 3460 tic->t_curr_res = unit_bytes;
3220 tic->t_cnt = cnt; 3461 tic->t_cnt = cnt;
3221 tic->t_ocnt = cnt; 3462 tic->t_ocnt = cnt;
3222 tic->t_tid = (xlog_tid_t)((__psint_t)tic & 0xffffffff); 3463 tic->t_tid = random32();
3223 tic->t_clientid = client; 3464 tic->t_clientid = client;
3224 tic->t_flags = XLOG_TIC_INITED; 3465 tic->t_flags = XLOG_TIC_INITED;
3225 tic->t_trans_type = 0; 3466 tic->t_trans_type = 0;
3226 if (xflags & XFS_LOG_PERM_RESERV) 3467 if (xflags & XFS_LOG_PERM_RESERV)
3227 tic->t_flags |= XLOG_TIC_PERM_RESERV; 3468 tic->t_flags |= XLOG_TIC_PERM_RESERV;
3228 sv_init(&(tic->t_wait), SV_DEFAULT, "logtick"); 3469 sv_init(&tic->t_wait, SV_DEFAULT, "logtick");
3229 3470
3230 xlog_tic_reset_res(tic); 3471 xlog_tic_reset_res(tic);
3231 3472
@@ -3246,20 +3487,22 @@ xlog_ticket_alloc(xlog_t *log,
3246 * part of the log in case we trash the log structure. 3487 * part of the log in case we trash the log structure.
3247 */ 3488 */
3248void 3489void
3249xlog_verify_dest_ptr(xlog_t *log, 3490xlog_verify_dest_ptr(
3250 __psint_t ptr) 3491 struct log *log,
3492 char *ptr)
3251{ 3493{
3252 int i; 3494 int i;
3253 int good_ptr = 0; 3495 int good_ptr = 0;
3254 3496
3255 for (i=0; i < log->l_iclog_bufs; i++) { 3497 for (i = 0; i < log->l_iclog_bufs; i++) {
3256 if (ptr >= (__psint_t)log->l_iclog_bak[i] && 3498 if (ptr >= log->l_iclog_bak[i] &&
3257 ptr <= (__psint_t)log->l_iclog_bak[i]+log->l_iclog_size) 3499 ptr <= log->l_iclog_bak[i] + log->l_iclog_size)
3258 good_ptr++; 3500 good_ptr++;
3259 } 3501 }
3260 if (! good_ptr) 3502
3503 if (!good_ptr)
3261 xlog_panic("xlog_verify_dest_ptr: invalid ptr"); 3504 xlog_panic("xlog_verify_dest_ptr: invalid ptr");
3262} /* xlog_verify_dest_ptr */ 3505}
3263 3506
3264STATIC void 3507STATIC void
3265xlog_verify_grant_head(xlog_t *log, int equals) 3508xlog_verify_grant_head(xlog_t *log, int equals)
@@ -3445,6 +3688,11 @@ xlog_state_ioerror(
3445 * c. nothing new gets queued up after (a) and (b) are done. 3688 * c. nothing new gets queued up after (a) and (b) are done.
3446 * d. if !logerror, flush the iclogs to disk, then seal them off 3689 * d. if !logerror, flush the iclogs to disk, then seal them off
3447 * for business. 3690 * for business.
3691 *
3692 * Note: for delayed logging the !logerror case needs to flush the regions
3693 * held in memory out to the iclogs before flushing them to disk. This needs
3694 * to be done before the log is marked as shutdown, otherwise the flush to the
3695 * iclogs will fail.
3448 */ 3696 */
3449int 3697int
3450xfs_log_force_umount( 3698xfs_log_force_umount(
@@ -3478,6 +3726,16 @@ xfs_log_force_umount(
3478 return 1; 3726 return 1;
3479 } 3727 }
3480 retval = 0; 3728 retval = 0;
3729
3730 /*
3731 * Flush the in memory commit item list before marking the log as
3732 * being shut down. We need to do it in this order to ensure all the
3733 * completed transactions are flushed to disk with the xfs_log_force()
3734 * call below.
3735 */
3736 if (!logerror && (mp->m_flags & XFS_MOUNT_DELAYLOG))
3737 xlog_cil_push(log, 1);
3738
3481 /* 3739 /*
3482 * We must hold both the GRANT lock and the LOG lock, 3740 * We must hold both the GRANT lock and the LOG lock,
3483 * before we mark the filesystem SHUTDOWN and wake 3741 * before we mark the filesystem SHUTDOWN and wake