diff options
Diffstat (limited to 'fs/xfs/xfs_log.c')
-rw-r--r-- | fs/xfs/xfs_log.c | 100 |
1 files changed, 58 insertions, 42 deletions
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 9bfb69e1e885..77c12715a7d0 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -252,6 +252,29 @@ xlog_grant_add_space(struct log *log, int bytes) | |||
252 | xlog_grant_add_space_reserve(log, bytes); | 252 | xlog_grant_add_space_reserve(log, bytes); |
253 | } | 253 | } |
254 | 254 | ||
255 | static void | ||
256 | xlog_tic_reset_res(xlog_ticket_t *tic) | ||
257 | { | ||
258 | tic->t_res_num = 0; | ||
259 | tic->t_res_arr_sum = 0; | ||
260 | tic->t_res_num_ophdrs = 0; | ||
261 | } | ||
262 | |||
263 | static void | ||
264 | xlog_tic_add_region(xlog_ticket_t *tic, uint len, uint type) | ||
265 | { | ||
266 | if (tic->t_res_num == XLOG_TIC_LEN_MAX) { | ||
267 | /* add to overflow and start again */ | ||
268 | tic->t_res_o_flow += tic->t_res_arr_sum; | ||
269 | tic->t_res_num = 0; | ||
270 | tic->t_res_arr_sum = 0; | ||
271 | } | ||
272 | |||
273 | tic->t_res_arr[tic->t_res_num].r_len = len; | ||
274 | tic->t_res_arr[tic->t_res_num].r_type = type; | ||
275 | tic->t_res_arr_sum += len; | ||
276 | tic->t_res_num++; | ||
277 | } | ||
255 | 278 | ||
256 | /* | 279 | /* |
257 | * NOTES: | 280 | * NOTES: |
@@ -486,7 +509,7 @@ xfs_log_mount(xfs_mount_t *mp, | |||
486 | cmn_err(CE_NOTE, | 509 | cmn_err(CE_NOTE, |
487 | "!Mounting filesystem \"%s\" in no-recovery mode. Filesystem will be inconsistent.", | 510 | "!Mounting filesystem \"%s\" in no-recovery mode. Filesystem will be inconsistent.", |
488 | mp->m_fsname); | 511 | mp->m_fsname); |
489 | ASSERT(XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY); | 512 | ASSERT(mp->m_flags & XFS_MOUNT_RDONLY); |
490 | } | 513 | } |
491 | 514 | ||
492 | mp->m_log = xlog_alloc_log(mp, log_target, blk_offset, num_bblks); | 515 | mp->m_log = xlog_alloc_log(mp, log_target, blk_offset, num_bblks); |
@@ -496,16 +519,15 @@ xfs_log_mount(xfs_mount_t *mp, | |||
496 | * just worked. | 519 | * just worked. |
497 | */ | 520 | */ |
498 | if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) { | 521 | if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) { |
499 | bhv_vfs_t *vfsp = XFS_MTOVFS(mp); | 522 | int error, readonly = (mp->m_flags & XFS_MOUNT_RDONLY); |
500 | int error, readonly = (vfsp->vfs_flag & VFS_RDONLY); | ||
501 | 523 | ||
502 | if (readonly) | 524 | if (readonly) |
503 | vfsp->vfs_flag &= ~VFS_RDONLY; | 525 | mp->m_flags &= ~XFS_MOUNT_RDONLY; |
504 | 526 | ||
505 | error = xlog_recover(mp->m_log); | 527 | error = xlog_recover(mp->m_log); |
506 | 528 | ||
507 | if (readonly) | 529 | if (readonly) |
508 | vfsp->vfs_flag |= VFS_RDONLY; | 530 | mp->m_flags |= XFS_MOUNT_RDONLY; |
509 | if (error) { | 531 | if (error) { |
510 | cmn_err(CE_WARN, "XFS: log mount/recovery failed: error %d", error); | 532 | cmn_err(CE_WARN, "XFS: log mount/recovery failed: error %d", error); |
511 | xlog_dealloc_log(mp->m_log); | 533 | xlog_dealloc_log(mp->m_log); |
@@ -537,7 +559,7 @@ xfs_log_mount_finish(xfs_mount_t *mp, int mfsi_flags) | |||
537 | error = xlog_recover_finish(mp->m_log, mfsi_flags); | 559 | error = xlog_recover_finish(mp->m_log, mfsi_flags); |
538 | else { | 560 | else { |
539 | error = 0; | 561 | error = 0; |
540 | ASSERT(XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY); | 562 | ASSERT(mp->m_flags & XFS_MOUNT_RDONLY); |
541 | } | 563 | } |
542 | 564 | ||
543 | return error; | 565 | return error; |
@@ -597,7 +619,7 @@ xfs_log_unmount_write(xfs_mount_t *mp) | |||
597 | * Don't write out unmount record on read-only mounts. | 619 | * Don't write out unmount record on read-only mounts. |
598 | * Or, if we are doing a forced umount (typically because of IO errors). | 620 | * Or, if we are doing a forced umount (typically because of IO errors). |
599 | */ | 621 | */ |
600 | if (XFS_MTOVFS(mp)->vfs_flag & VFS_RDONLY) | 622 | if (mp->m_flags & XFS_MOUNT_RDONLY) |
601 | return 0; | 623 | return 0; |
602 | 624 | ||
603 | xfs_log_force(mp, 0, XFS_LOG_FORCE|XFS_LOG_SYNC); | 625 | xfs_log_force(mp, 0, XFS_LOG_FORCE|XFS_LOG_SYNC); |
@@ -949,6 +971,19 @@ xlog_iodone(xfs_buf_t *bp) | |||
949 | l = iclog->ic_log; | 971 | l = iclog->ic_log; |
950 | 972 | ||
951 | /* | 973 | /* |
974 | * If the ordered flag has been removed by a lower | ||
975 | * layer, it means the underlyin device no longer supports | ||
976 | * barrier I/O. Warn loudly and turn off barriers. | ||
977 | */ | ||
978 | if ((l->l_mp->m_flags & XFS_MOUNT_BARRIER) && !XFS_BUF_ORDERED(bp)) { | ||
979 | l->l_mp->m_flags &= ~XFS_MOUNT_BARRIER; | ||
980 | xfs_fs_cmn_err(CE_WARN, l->l_mp, | ||
981 | "xlog_iodone: Barriers are no longer supported" | ||
982 | " by device. Disabling barriers\n"); | ||
983 | xfs_buftrace("XLOG_IODONE BARRIERS OFF", bp); | ||
984 | } | ||
985 | |||
986 | /* | ||
952 | * Race to shutdown the filesystem if we see an error. | 987 | * Race to shutdown the filesystem if we see an error. |
953 | */ | 988 | */ |
954 | if (XFS_TEST_ERROR((XFS_BUF_GETERROR(bp)), l->l_mp, | 989 | if (XFS_TEST_ERROR((XFS_BUF_GETERROR(bp)), l->l_mp, |
@@ -1012,10 +1047,7 @@ xlog_bdstrat_cb(struct xfs_buf *bp) | |||
1012 | /* | 1047 | /* |
1013 | * Return size of each in-core log record buffer. | 1048 | * Return size of each in-core log record buffer. |
1014 | * | 1049 | * |
1015 | * Low memory machines only get 2 16KB buffers. We don't want to waste | 1050 | * All machines get 8 x 32KB buffers by default, unless tuned otherwise. |
1016 | * memory here. However, all other machines get at least 2 32KB buffers. | ||
1017 | * The number is hard coded because we don't care about the minimum | ||
1018 | * memory size, just 32MB systems. | ||
1019 | * | 1051 | * |
1020 | * If the filesystem blocksize is too large, we may need to choose a | 1052 | * If the filesystem blocksize is too large, we may need to choose a |
1021 | * larger size since the directory code currently logs entire blocks. | 1053 | * larger size since the directory code currently logs entire blocks. |
@@ -1028,17 +1060,10 @@ xlog_get_iclog_buffer_size(xfs_mount_t *mp, | |||
1028 | int size; | 1060 | int size; |
1029 | int xhdrs; | 1061 | int xhdrs; |
1030 | 1062 | ||
1031 | if (mp->m_logbufs <= 0) { | 1063 | if (mp->m_logbufs <= 0) |
1032 | if (xfs_physmem <= btoc(128*1024*1024)) { | 1064 | log->l_iclog_bufs = XLOG_MAX_ICLOGS; |
1033 | log->l_iclog_bufs = XLOG_MIN_ICLOGS; | 1065 | else |
1034 | } else if (xfs_physmem <= btoc(400*1024*1024)) { | ||
1035 | log->l_iclog_bufs = XLOG_MED_ICLOGS; | ||
1036 | } else { /* 256K with 32K bufs */ | ||
1037 | log->l_iclog_bufs = XLOG_MAX_ICLOGS; | ||
1038 | } | ||
1039 | } else { | ||
1040 | log->l_iclog_bufs = mp->m_logbufs; | 1066 | log->l_iclog_bufs = mp->m_logbufs; |
1041 | } | ||
1042 | 1067 | ||
1043 | /* | 1068 | /* |
1044 | * Buffer size passed in from mount system call. | 1069 | * Buffer size passed in from mount system call. |
@@ -1069,18 +1094,9 @@ xlog_get_iclog_buffer_size(xfs_mount_t *mp, | |||
1069 | goto done; | 1094 | goto done; |
1070 | } | 1095 | } |
1071 | 1096 | ||
1072 | /* | 1097 | /* All machines use 32KB buffers by default. */ |
1073 | * Special case machines that have less than 32MB of memory. | 1098 | log->l_iclog_size = XLOG_BIG_RECORD_BSIZE; |
1074 | * All machines with more memory use 32KB buffers. | 1099 | log->l_iclog_size_log = XLOG_BIG_RECORD_BSHIFT; |
1075 | */ | ||
1076 | if (xfs_physmem <= btoc(32*1024*1024)) { | ||
1077 | /* Don't change; min configuration */ | ||
1078 | log->l_iclog_size = XLOG_RECORD_BSIZE; /* 16k */ | ||
1079 | log->l_iclog_size_log = XLOG_RECORD_BSHIFT; | ||
1080 | } else { | ||
1081 | log->l_iclog_size = XLOG_BIG_RECORD_BSIZE; /* 32k */ | ||
1082 | log->l_iclog_size_log = XLOG_BIG_RECORD_BSHIFT; | ||
1083 | } | ||
1084 | 1100 | ||
1085 | /* the default log size is 16k or 32k which is one header sector */ | 1101 | /* the default log size is 16k or 32k which is one header sector */ |
1086 | log->l_iclog_hsize = BBSIZE; | 1102 | log->l_iclog_hsize = BBSIZE; |
@@ -1771,14 +1787,14 @@ xlog_write(xfs_mount_t * mp, | |||
1771 | len = 0; | 1787 | len = 0; |
1772 | if (ticket->t_flags & XLOG_TIC_INITED) { /* acct for start rec of xact */ | 1788 | if (ticket->t_flags & XLOG_TIC_INITED) { /* acct for start rec of xact */ |
1773 | len += sizeof(xlog_op_header_t); | 1789 | len += sizeof(xlog_op_header_t); |
1774 | XLOG_TIC_ADD_OPHDR(ticket); | 1790 | ticket->t_res_num_ophdrs++; |
1775 | } | 1791 | } |
1776 | 1792 | ||
1777 | for (index = 0; index < nentries; index++) { | 1793 | for (index = 0; index < nentries; index++) { |
1778 | len += sizeof(xlog_op_header_t); /* each region gets >= 1 */ | 1794 | len += sizeof(xlog_op_header_t); /* each region gets >= 1 */ |
1779 | XLOG_TIC_ADD_OPHDR(ticket); | 1795 | ticket->t_res_num_ophdrs++; |
1780 | len += reg[index].i_len; | 1796 | len += reg[index].i_len; |
1781 | XLOG_TIC_ADD_REGION(ticket, reg[index].i_len, reg[index].i_type); | 1797 | xlog_tic_add_region(ticket, reg[index].i_len, reg[index].i_type); |
1782 | } | 1798 | } |
1783 | contwr = *start_lsn = 0; | 1799 | contwr = *start_lsn = 0; |
1784 | 1800 | ||
@@ -1887,7 +1903,7 @@ xlog_write(xfs_mount_t * mp, | |||
1887 | len += sizeof(xlog_op_header_t); /* from splitting of region */ | 1903 | len += sizeof(xlog_op_header_t); /* from splitting of region */ |
1888 | /* account for new log op header */ | 1904 | /* account for new log op header */ |
1889 | ticket->t_curr_res -= sizeof(xlog_op_header_t); | 1905 | ticket->t_curr_res -= sizeof(xlog_op_header_t); |
1890 | XLOG_TIC_ADD_OPHDR(ticket); | 1906 | ticket->t_res_num_ophdrs++; |
1891 | } | 1907 | } |
1892 | xlog_verify_dest_ptr(log, ptr); | 1908 | xlog_verify_dest_ptr(log, ptr); |
1893 | 1909 | ||
@@ -2385,7 +2401,7 @@ restart: | |||
2385 | */ | 2401 | */ |
2386 | if (log_offset == 0) { | 2402 | if (log_offset == 0) { |
2387 | ticket->t_curr_res -= log->l_iclog_hsize; | 2403 | ticket->t_curr_res -= log->l_iclog_hsize; |
2388 | XLOG_TIC_ADD_REGION(ticket, | 2404 | xlog_tic_add_region(ticket, |
2389 | log->l_iclog_hsize, | 2405 | log->l_iclog_hsize, |
2390 | XLOG_REG_TYPE_LRHEADER); | 2406 | XLOG_REG_TYPE_LRHEADER); |
2391 | INT_SET(head->h_cycle, ARCH_CONVERT, log->l_curr_cycle); | 2407 | INT_SET(head->h_cycle, ARCH_CONVERT, log->l_curr_cycle); |
@@ -2573,7 +2589,7 @@ xlog_regrant_write_log_space(xlog_t *log, | |||
2573 | #endif | 2589 | #endif |
2574 | 2590 | ||
2575 | tic->t_curr_res = tic->t_unit_res; | 2591 | tic->t_curr_res = tic->t_unit_res; |
2576 | XLOG_TIC_RESET_RES(tic); | 2592 | xlog_tic_reset_res(tic); |
2577 | 2593 | ||
2578 | if (tic->t_cnt > 0) | 2594 | if (tic->t_cnt > 0) |
2579 | return 0; | 2595 | return 0; |
@@ -2714,7 +2730,7 @@ xlog_regrant_reserve_log_space(xlog_t *log, | |||
2714 | s = GRANT_LOCK(log); | 2730 | s = GRANT_LOCK(log); |
2715 | xlog_grant_sub_space(log, ticket->t_curr_res); | 2731 | xlog_grant_sub_space(log, ticket->t_curr_res); |
2716 | ticket->t_curr_res = ticket->t_unit_res; | 2732 | ticket->t_curr_res = ticket->t_unit_res; |
2717 | XLOG_TIC_RESET_RES(ticket); | 2733 | xlog_tic_reset_res(ticket); |
2718 | xlog_trace_loggrant(log, ticket, | 2734 | xlog_trace_loggrant(log, ticket, |
2719 | "xlog_regrant_reserve_log_space: sub current res"); | 2735 | "xlog_regrant_reserve_log_space: sub current res"); |
2720 | xlog_verify_grant_head(log, 1); | 2736 | xlog_verify_grant_head(log, 1); |
@@ -2731,7 +2747,7 @@ xlog_regrant_reserve_log_space(xlog_t *log, | |||
2731 | xlog_verify_grant_head(log, 0); | 2747 | xlog_verify_grant_head(log, 0); |
2732 | GRANT_UNLOCK(log, s); | 2748 | GRANT_UNLOCK(log, s); |
2733 | ticket->t_curr_res = ticket->t_unit_res; | 2749 | ticket->t_curr_res = ticket->t_unit_res; |
2734 | XLOG_TIC_RESET_RES(ticket); | 2750 | xlog_tic_reset_res(ticket); |
2735 | } /* xlog_regrant_reserve_log_space */ | 2751 | } /* xlog_regrant_reserve_log_space */ |
2736 | 2752 | ||
2737 | 2753 | ||
@@ -3354,7 +3370,7 @@ xlog_ticket_get(xlog_t *log, | |||
3354 | tic->t_flags |= XLOG_TIC_PERM_RESERV; | 3370 | tic->t_flags |= XLOG_TIC_PERM_RESERV; |
3355 | sv_init(&(tic->t_sema), SV_DEFAULT, "logtick"); | 3371 | sv_init(&(tic->t_sema), SV_DEFAULT, "logtick"); |
3356 | 3372 | ||
3357 | XLOG_TIC_RESET_RES(tic); | 3373 | xlog_tic_reset_res(tic); |
3358 | 3374 | ||
3359 | return tic; | 3375 | return tic; |
3360 | } /* xlog_ticket_get */ | 3376 | } /* xlog_ticket_get */ |