diff options
Diffstat (limited to 'fs/xfs/xfs_log.c')
-rw-r--r-- | fs/xfs/xfs_log.c | 64 |
1 files changed, 49 insertions, 15 deletions
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 19d0c5f73e24..027ebfe20677 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -54,9 +54,6 @@ STATIC xlog_t * xlog_alloc_log(xfs_mount_t *mp, | |||
54 | STATIC int xlog_space_left(xlog_t *log, int cycle, int bytes); | 54 | STATIC int xlog_space_left(xlog_t *log, int cycle, int bytes); |
55 | STATIC int xlog_sync(xlog_t *log, xlog_in_core_t *iclog); | 55 | STATIC int xlog_sync(xlog_t *log, xlog_in_core_t *iclog); |
56 | STATIC void xlog_dealloc_log(xlog_t *log); | 56 | STATIC void xlog_dealloc_log(xlog_t *log); |
57 | STATIC int xlog_write(struct log *log, struct xfs_log_vec *log_vector, | ||
58 | struct xlog_ticket *tic, xfs_lsn_t *start_lsn, | ||
59 | xlog_in_core_t **commit_iclog, uint flags); | ||
60 | 57 | ||
61 | /* local state machine functions */ | 58 | /* local state machine functions */ |
62 | STATIC void xlog_state_done_syncing(xlog_in_core_t *iclog, int); | 59 | STATIC void xlog_state_done_syncing(xlog_in_core_t *iclog, int); |
@@ -86,12 +83,6 @@ STATIC int xlog_regrant_write_log_space(xlog_t *log, | |||
86 | STATIC void xlog_ungrant_log_space(xlog_t *log, | 83 | STATIC void xlog_ungrant_log_space(xlog_t *log, |
87 | xlog_ticket_t *ticket); | 84 | xlog_ticket_t *ticket); |
88 | 85 | ||
89 | |||
90 | /* local ticket functions */ | ||
91 | STATIC xlog_ticket_t *xlog_ticket_alloc(xlog_t *log, int unit_bytes, int count, | ||
92 | char clientid, uint flags, | ||
93 | int alloc_flags); | ||
94 | |||
95 | #if defined(DEBUG) | 86 | #if defined(DEBUG) |
96 | STATIC void xlog_verify_dest_ptr(xlog_t *log, char *ptr); | 87 | STATIC void xlog_verify_dest_ptr(xlog_t *log, char *ptr); |
97 | STATIC void xlog_verify_grant_head(xlog_t *log, int equals); | 88 | STATIC void xlog_verify_grant_head(xlog_t *log, int equals); |
@@ -460,6 +451,13 @@ xfs_log_mount( | |||
460 | /* Normal transactions can now occur */ | 451 | /* Normal transactions can now occur */ |
461 | mp->m_log->l_flags &= ~XLOG_ACTIVE_RECOVERY; | 452 | mp->m_log->l_flags &= ~XLOG_ACTIVE_RECOVERY; |
462 | 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 | |||
463 | return 0; | 461 | return 0; |
464 | 462 | ||
465 | out_destroy_ail: | 463 | out_destroy_ail: |
@@ -666,6 +664,10 @@ xfs_log_item_init( | |||
666 | item->li_ailp = mp->m_ail; | 664 | item->li_ailp = mp->m_ail; |
667 | item->li_type = type; | 665 | item->li_type = type; |
668 | item->li_ops = ops; | 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); | ||
669 | } | 671 | } |
670 | 672 | ||
671 | /* | 673 | /* |
@@ -1176,6 +1178,9 @@ xlog_alloc_log(xfs_mount_t *mp, | |||
1176 | *iclogp = log->l_iclog; /* complete ring */ | 1178 | *iclogp = log->l_iclog; /* complete ring */ |
1177 | 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 */ |
1178 | 1180 | ||
1181 | error = xlog_cil_init(log); | ||
1182 | if (error) | ||
1183 | goto out_free_iclog; | ||
1179 | return log; | 1184 | return log; |
1180 | 1185 | ||
1181 | out_free_iclog: | 1186 | out_free_iclog: |
@@ -1502,6 +1507,8 @@ xlog_dealloc_log(xlog_t *log) | |||
1502 | xlog_in_core_t *iclog, *next_iclog; | 1507 | xlog_in_core_t *iclog, *next_iclog; |
1503 | int i; | 1508 | int i; |
1504 | 1509 | ||
1510 | xlog_cil_destroy(log); | ||
1511 | |||
1505 | iclog = log->l_iclog; | 1512 | iclog = log->l_iclog; |
1506 | for (i=0; i<log->l_iclog_bufs; i++) { | 1513 | for (i=0; i<log->l_iclog_bufs; i++) { |
1507 | sv_destroy(&iclog->ic_force_wait); | 1514 | sv_destroy(&iclog->ic_force_wait); |
@@ -1544,8 +1551,10 @@ xlog_state_finish_copy(xlog_t *log, | |||
1544 | * print out info relating to regions written which consume | 1551 | * print out info relating to regions written which consume |
1545 | * the reservation | 1552 | * the reservation |
1546 | */ | 1553 | */ |
1547 | STATIC void | 1554 | void |
1548 | xlog_print_tic_res(xfs_mount_t *mp, xlog_ticket_t *ticket) | 1555 | xlog_print_tic_res( |
1556 | struct xfs_mount *mp, | ||
1557 | struct xlog_ticket *ticket) | ||
1549 | { | 1558 | { |
1550 | uint i; | 1559 | uint i; |
1551 | 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); |
@@ -1877,7 +1886,7 @@ xlog_write_copy_finish( | |||
1877 | * 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 |
1878 | * bytes have been written out. | 1887 | * bytes have been written out. |
1879 | */ | 1888 | */ |
1880 | STATIC int | 1889 | int |
1881 | xlog_write( | 1890 | xlog_write( |
1882 | struct log *log, | 1891 | struct log *log, |
1883 | struct xfs_log_vec *log_vector, | 1892 | struct xfs_log_vec *log_vector, |
@@ -1901,9 +1910,26 @@ xlog_write( | |||
1901 | *start_lsn = 0; | 1910 | *start_lsn = 0; |
1902 | 1911 | ||
1903 | len = xlog_write_calc_vec_length(ticket, log_vector); | 1912 | len = xlog_write_calc_vec_length(ticket, log_vector); |
1904 | if (ticket->t_curr_res < len) | 1913 | if (log->l_cilp) { |
1914 | /* | ||
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); | ||
1921 | |||
1922 | /* | ||
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) | ||
1905 | xlog_print_tic_res(log->l_mp, ticket); | 1932 | xlog_print_tic_res(log->l_mp, ticket); |
1906 | ticket->t_curr_res -= len; | ||
1907 | 1933 | ||
1908 | index = 0; | 1934 | index = 0; |
1909 | lv = log_vector; | 1935 | lv = log_vector; |
@@ -2999,6 +3025,8 @@ _xfs_log_force( | |||
2999 | 3025 | ||
3000 | XFS_STATS_INC(xs_log_force); | 3026 | XFS_STATS_INC(xs_log_force); |
3001 | 3027 | ||
3028 | xlog_cil_push(log, 1); | ||
3029 | |||
3002 | spin_lock(&log->l_icloglock); | 3030 | spin_lock(&log->l_icloglock); |
3003 | 3031 | ||
3004 | iclog = log->l_iclog; | 3032 | iclog = log->l_iclog; |
@@ -3148,6 +3176,12 @@ _xfs_log_force_lsn( | |||
3148 | 3176 | ||
3149 | XFS_STATS_INC(xs_log_force); | 3177 | XFS_STATS_INC(xs_log_force); |
3150 | 3178 | ||
3179 | if (log->l_cilp) { | ||
3180 | lsn = xlog_cil_push_lsn(log, lsn); | ||
3181 | if (lsn == NULLCOMMITLSN) | ||
3182 | return 0; | ||
3183 | } | ||
3184 | |||
3151 | try_again: | 3185 | try_again: |
3152 | spin_lock(&log->l_icloglock); | 3186 | spin_lock(&log->l_icloglock); |
3153 | iclog = log->l_iclog; | 3187 | iclog = log->l_iclog; |
@@ -3322,7 +3356,7 @@ xfs_log_get_trans_ident( | |||
3322 | /* | 3356 | /* |
3323 | * Allocate and initialise a new log ticket. | 3357 | * Allocate and initialise a new log ticket. |
3324 | */ | 3358 | */ |
3325 | STATIC xlog_ticket_t * | 3359 | xlog_ticket_t * |
3326 | xlog_ticket_alloc( | 3360 | xlog_ticket_alloc( |
3327 | struct log *log, | 3361 | struct log *log, |
3328 | int unit_bytes, | 3362 | int unit_bytes, |