aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_log.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_log.c')
-rw-r--r--fs/xfs/xfs_log.c81
1 files changed, 44 insertions, 37 deletions
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 3608a0f0a5f6..f4726f702a9e 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -100,12 +100,11 @@ STATIC void xlog_ungrant_log_space(xlog_t *log,
100 100
101 101
102/* local ticket functions */ 102/* local ticket functions */
103STATIC xlog_ticket_t *xlog_ticket_get(xlog_t *log, 103STATIC xlog_ticket_t *xlog_ticket_alloc(xlog_t *log,
104 int unit_bytes, 104 int unit_bytes,
105 int count, 105 int count,
106 char clientid, 106 char clientid,
107 uint flags); 107 uint flags);
108STATIC void xlog_ticket_put(xlog_t *log, xlog_ticket_t *ticket);
109 108
110#if defined(DEBUG) 109#if defined(DEBUG)
111STATIC void xlog_verify_dest_ptr(xlog_t *log, __psint_t ptr); 110STATIC void xlog_verify_dest_ptr(xlog_t *log, __psint_t ptr);
@@ -360,7 +359,7 @@ xfs_log_done(xfs_mount_t *mp,
360 */ 359 */
361 xlog_trace_loggrant(log, ticket, "xfs_log_done: (non-permanent)"); 360 xlog_trace_loggrant(log, ticket, "xfs_log_done: (non-permanent)");
362 xlog_ungrant_log_space(log, ticket); 361 xlog_ungrant_log_space(log, ticket);
363 xlog_ticket_put(log, ticket); 362 xfs_log_ticket_put(ticket);
364 } else { 363 } else {
365 xlog_trace_loggrant(log, ticket, "xfs_log_done: (permanent)"); 364 xlog_trace_loggrant(log, ticket, "xfs_log_done: (permanent)");
366 xlog_regrant_reserve_log_space(log, ticket); 365 xlog_regrant_reserve_log_space(log, ticket);
@@ -514,7 +513,7 @@ xfs_log_reserve(xfs_mount_t *mp,
514 retval = xlog_regrant_write_log_space(log, internal_ticket); 513 retval = xlog_regrant_write_log_space(log, internal_ticket);
515 } else { 514 } else {
516 /* may sleep if need to allocate more tickets */ 515 /* may sleep if need to allocate more tickets */
517 internal_ticket = xlog_ticket_get(log, unit_bytes, cnt, 516 internal_ticket = xlog_ticket_alloc(log, unit_bytes, cnt,
518 client, flags); 517 client, flags);
519 if (!internal_ticket) 518 if (!internal_ticket)
520 return XFS_ERROR(ENOMEM); 519 return XFS_ERROR(ENOMEM);
@@ -572,12 +571,12 @@ xfs_log_mount(
572 /* 571 /*
573 * Initialize the AIL now we have a log. 572 * Initialize the AIL now we have a log.
574 */ 573 */
575 spin_lock_init(&mp->m_ail_lock);
576 error = xfs_trans_ail_init(mp); 574 error = xfs_trans_ail_init(mp);
577 if (error) { 575 if (error) {
578 cmn_err(CE_WARN, "XFS: AIL initialisation failed: error %d", error); 576 cmn_err(CE_WARN, "XFS: AIL initialisation failed: error %d", error);
579 goto error; 577 goto error;
580 } 578 }
579 mp->m_log->l_ailp = mp->m_ail;
581 580
582 /* 581 /*
583 * skip log recovery on a norecovery mount. pretend it all 582 * skip log recovery on a norecovery mount. pretend it all
@@ -730,8 +729,8 @@ xfs_log_unmount_write(xfs_mount_t *mp)
730 spin_lock(&log->l_icloglock); 729 spin_lock(&log->l_icloglock);
731 iclog = log->l_iclog; 730 iclog = log->l_iclog;
732 atomic_inc(&iclog->ic_refcnt); 731 atomic_inc(&iclog->ic_refcnt);
733 spin_unlock(&log->l_icloglock);
734 xlog_state_want_sync(log, iclog); 732 xlog_state_want_sync(log, iclog);
733 spin_unlock(&log->l_icloglock);
735 error = xlog_state_release_iclog(log, iclog); 734 error = xlog_state_release_iclog(log, iclog);
736 735
737 spin_lock(&log->l_icloglock); 736 spin_lock(&log->l_icloglock);
@@ -749,7 +748,7 @@ xfs_log_unmount_write(xfs_mount_t *mp)
749 if (tic) { 748 if (tic) {
750 xlog_trace_loggrant(log, tic, "unmount rec"); 749 xlog_trace_loggrant(log, tic, "unmount rec");
751 xlog_ungrant_log_space(log, tic); 750 xlog_ungrant_log_space(log, tic);
752 xlog_ticket_put(log, tic); 751 xfs_log_ticket_put(tic);
753 } 752 }
754 } else { 753 } else {
755 /* 754 /*
@@ -768,9 +767,9 @@ xfs_log_unmount_write(xfs_mount_t *mp)
768 spin_lock(&log->l_icloglock); 767 spin_lock(&log->l_icloglock);
769 iclog = log->l_iclog; 768 iclog = log->l_iclog;
770 atomic_inc(&iclog->ic_refcnt); 769 atomic_inc(&iclog->ic_refcnt);
771 spin_unlock(&log->l_icloglock);
772 770
773 xlog_state_want_sync(log, iclog); 771 xlog_state_want_sync(log, iclog);
772 spin_unlock(&log->l_icloglock);
774 error = xlog_state_release_iclog(log, iclog); 773 error = xlog_state_release_iclog(log, iclog);
775 774
776 spin_lock(&log->l_icloglock); 775 spin_lock(&log->l_icloglock);
@@ -906,7 +905,7 @@ xfs_log_move_tail(xfs_mount_t *mp,
906int 905int
907xfs_log_need_covered(xfs_mount_t *mp) 906xfs_log_need_covered(xfs_mount_t *mp)
908{ 907{
909 int needed = 0, gen; 908 int needed = 0;
910 xlog_t *log = mp->m_log; 909 xlog_t *log = mp->m_log;
911 910
912 if (!xfs_fs_writable(mp)) 911 if (!xfs_fs_writable(mp))
@@ -915,7 +914,7 @@ xfs_log_need_covered(xfs_mount_t *mp)
915 spin_lock(&log->l_icloglock); 914 spin_lock(&log->l_icloglock);
916 if (((log->l_covered_state == XLOG_STATE_COVER_NEED) || 915 if (((log->l_covered_state == XLOG_STATE_COVER_NEED) ||
917 (log->l_covered_state == XLOG_STATE_COVER_NEED2)) 916 (log->l_covered_state == XLOG_STATE_COVER_NEED2))
918 && !xfs_trans_first_ail(mp, &gen) 917 && !xfs_trans_ail_tail(log->l_ailp)
919 && xlog_iclogs_empty(log)) { 918 && xlog_iclogs_empty(log)) {
920 if (log->l_covered_state == XLOG_STATE_COVER_NEED) 919 if (log->l_covered_state == XLOG_STATE_COVER_NEED)
921 log->l_covered_state = XLOG_STATE_COVER_DONE; 920 log->l_covered_state = XLOG_STATE_COVER_DONE;
@@ -952,7 +951,7 @@ xlog_assign_tail_lsn(xfs_mount_t *mp)
952 xfs_lsn_t tail_lsn; 951 xfs_lsn_t tail_lsn;
953 xlog_t *log = mp->m_log; 952 xlog_t *log = mp->m_log;
954 953
955 tail_lsn = xfs_trans_tail_ail(mp); 954 tail_lsn = xfs_trans_ail_tail(mp->m_ail);
956 spin_lock(&log->l_grant_lock); 955 spin_lock(&log->l_grant_lock);
957 if (tail_lsn != 0) { 956 if (tail_lsn != 0) {
958 log->l_tail_lsn = tail_lsn; 957 log->l_tail_lsn = tail_lsn;
@@ -1030,12 +1029,6 @@ xlog_iodone(xfs_buf_t *bp)
1030 ASSERT(XFS_BUF_FSPRIVATE2(bp, unsigned long) == (unsigned long) 2); 1029 ASSERT(XFS_BUF_FSPRIVATE2(bp, unsigned long) == (unsigned long) 2);
1031 XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)1); 1030 XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)1);
1032 aborted = 0; 1031 aborted = 0;
1033
1034 /*
1035 * Some versions of cpp barf on the recursive definition of
1036 * ic_log -> hic_fields.ic_log and expand ic_log twice when
1037 * it is passed through two macros. Workaround broken cpp.
1038 */
1039 l = iclog->ic_log; 1032 l = iclog->ic_log;
1040 1033
1041 /* 1034 /*
@@ -1302,7 +1295,7 @@ xlog_alloc_log(xfs_mount_t *mp,
1302 XFS_BUF_SET_BDSTRAT_FUNC(bp, xlog_bdstrat_cb); 1295 XFS_BUF_SET_BDSTRAT_FUNC(bp, xlog_bdstrat_cb);
1303 XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)1); 1296 XFS_BUF_SET_FSPRIVATE2(bp, (unsigned long)1);
1304 iclog->ic_bp = bp; 1297 iclog->ic_bp = bp;
1305 iclog->hic_data = bp->b_addr; 1298 iclog->ic_data = bp->b_addr;
1306#ifdef DEBUG 1299#ifdef DEBUG
1307 log->l_iclog_bak[i] = (xfs_caddr_t)&(iclog->ic_header); 1300 log->l_iclog_bak[i] = (xfs_caddr_t)&(iclog->ic_header);
1308#endif 1301#endif
@@ -1322,7 +1315,7 @@ xlog_alloc_log(xfs_mount_t *mp,
1322 atomic_set(&iclog->ic_refcnt, 0); 1315 atomic_set(&iclog->ic_refcnt, 0);
1323 spin_lock_init(&iclog->ic_callback_lock); 1316 spin_lock_init(&iclog->ic_callback_lock);
1324 iclog->ic_callback_tail = &(iclog->ic_callback); 1317 iclog->ic_callback_tail = &(iclog->ic_callback);
1325 iclog->ic_datap = (char *)iclog->hic_data + log->l_iclog_hsize; 1318 iclog->ic_datap = (char *)iclog->ic_data + log->l_iclog_hsize;
1326 1319
1327 ASSERT(XFS_BUF_ISBUSY(iclog->ic_bp)); 1320 ASSERT(XFS_BUF_ISBUSY(iclog->ic_bp));
1328 ASSERT(XFS_BUF_VALUSEMA(iclog->ic_bp) <= 0); 1321 ASSERT(XFS_BUF_VALUSEMA(iclog->ic_bp) <= 0);
@@ -1446,7 +1439,7 @@ xlog_grant_push_ail(xfs_mount_t *mp,
1446 */ 1439 */
1447 if (threshold_lsn && 1440 if (threshold_lsn &&
1448 !XLOG_FORCED_SHUTDOWN(log)) 1441 !XLOG_FORCED_SHUTDOWN(log))
1449 xfs_trans_push_ail(mp, threshold_lsn); 1442 xfs_trans_ail_push(log->l_ailp, threshold_lsn);
1450} /* xlog_grant_push_ail */ 1443} /* xlog_grant_push_ail */
1451 1444
1452 1445
@@ -1991,7 +1984,9 @@ xlog_write(xfs_mount_t * mp,
1991 if (iclog->ic_size - log_offset <= sizeof(xlog_op_header_t)) { 1984 if (iclog->ic_size - log_offset <= sizeof(xlog_op_header_t)) {
1992 xlog_state_finish_copy(log, iclog, record_cnt, data_cnt); 1985 xlog_state_finish_copy(log, iclog, record_cnt, data_cnt);
1993 record_cnt = data_cnt = 0; 1986 record_cnt = data_cnt = 0;
1987 spin_lock(&log->l_icloglock);
1994 xlog_state_want_sync(log, iclog); 1988 xlog_state_want_sync(log, iclog);
1989 spin_unlock(&log->l_icloglock);
1995 if (commit_iclog) { 1990 if (commit_iclog) {
1996 ASSERT(flags & XLOG_COMMIT_TRANS); 1991 ASSERT(flags & XLOG_COMMIT_TRANS);
1997 *commit_iclog = iclog; 1992 *commit_iclog = iclog;
@@ -3200,7 +3195,7 @@ try_again:
3200STATIC void 3195STATIC void
3201xlog_state_want_sync(xlog_t *log, xlog_in_core_t *iclog) 3196xlog_state_want_sync(xlog_t *log, xlog_in_core_t *iclog)
3202{ 3197{
3203 spin_lock(&log->l_icloglock); 3198 ASSERT(spin_is_locked(&log->l_icloglock));
3204 3199
3205 if (iclog->ic_state == XLOG_STATE_ACTIVE) { 3200 if (iclog->ic_state == XLOG_STATE_ACTIVE) {
3206 xlog_state_switch_iclogs(log, iclog, 0); 3201 xlog_state_switch_iclogs(log, iclog, 0);
@@ -3208,10 +3203,7 @@ xlog_state_want_sync(xlog_t *log, xlog_in_core_t *iclog)
3208 ASSERT(iclog->ic_state & 3203 ASSERT(iclog->ic_state &
3209 (XLOG_STATE_WANT_SYNC|XLOG_STATE_IOERROR)); 3204 (XLOG_STATE_WANT_SYNC|XLOG_STATE_IOERROR));
3210 } 3205 }
3211 3206}
3212 spin_unlock(&log->l_icloglock);
3213} /* xlog_state_want_sync */
3214
3215 3207
3216 3208
3217/***************************************************************************** 3209/*****************************************************************************
@@ -3222,22 +3214,33 @@ xlog_state_want_sync(xlog_t *log, xlog_in_core_t *iclog)
3222 */ 3214 */
3223 3215
3224/* 3216/*
3225 * Free a used ticket. 3217 * Free a used ticket when it's refcount falls to zero.
3226 */ 3218 */
3227STATIC void 3219void
3228xlog_ticket_put(xlog_t *log, 3220xfs_log_ticket_put(
3229 xlog_ticket_t *ticket) 3221 xlog_ticket_t *ticket)
3230{ 3222{
3231 sv_destroy(&ticket->t_wait); 3223 ASSERT(atomic_read(&ticket->t_ref) > 0);
3232 kmem_zone_free(xfs_log_ticket_zone, ticket); 3224 if (atomic_dec_and_test(&ticket->t_ref)) {
3233} /* xlog_ticket_put */ 3225 sv_destroy(&ticket->t_wait);
3226 kmem_zone_free(xfs_log_ticket_zone, ticket);
3227 }
3228}
3234 3229
3230xlog_ticket_t *
3231xfs_log_ticket_get(
3232 xlog_ticket_t *ticket)
3233{
3234 ASSERT(atomic_read(&ticket->t_ref) > 0);
3235 atomic_inc(&ticket->t_ref);
3236 return ticket;
3237}
3235 3238
3236/* 3239/*
3237 * Allocate and initialise a new log ticket. 3240 * Allocate and initialise a new log ticket.
3238 */ 3241 */
3239STATIC xlog_ticket_t * 3242STATIC xlog_ticket_t *
3240xlog_ticket_get(xlog_t *log, 3243xlog_ticket_alloc(xlog_t *log,
3241 int unit_bytes, 3244 int unit_bytes,
3242 int cnt, 3245 int cnt,
3243 char client, 3246 char client,
@@ -3308,6 +3311,7 @@ xlog_ticket_get(xlog_t *log,
3308 unit_bytes += 2*BBSIZE; 3311 unit_bytes += 2*BBSIZE;
3309 } 3312 }
3310 3313
3314 atomic_set(&tic->t_ref, 1);
3311 tic->t_unit_res = unit_bytes; 3315 tic->t_unit_res = unit_bytes;
3312 tic->t_curr_res = unit_bytes; 3316 tic->t_curr_res = unit_bytes;
3313 tic->t_cnt = cnt; 3317 tic->t_cnt = cnt;
@@ -3323,7 +3327,7 @@ xlog_ticket_get(xlog_t *log,
3323 xlog_tic_reset_res(tic); 3327 xlog_tic_reset_res(tic);
3324 3328
3325 return tic; 3329 return tic;
3326} /* xlog_ticket_get */ 3330}
3327 3331
3328 3332
3329/****************************************************************************** 3333/******************************************************************************
@@ -3452,7 +3456,7 @@ xlog_verify_iclog(xlog_t *log,
3452 ptr = iclog->ic_datap; 3456 ptr = iclog->ic_datap;
3453 base_ptr = ptr; 3457 base_ptr = ptr;
3454 ophead = (xlog_op_header_t *)ptr; 3458 ophead = (xlog_op_header_t *)ptr;
3455 xhdr = (xlog_in_core_2_t *)&iclog->ic_header; 3459 xhdr = iclog->ic_data;
3456 for (i = 0; i < len; i++) { 3460 for (i = 0; i < len; i++) {
3457 ophead = (xlog_op_header_t *)ptr; 3461 ophead = (xlog_op_header_t *)ptr;
3458 3462
@@ -3558,7 +3562,8 @@ xfs_log_force_umount(
3558 if (!log || 3562 if (!log ||
3559 log->l_flags & XLOG_ACTIVE_RECOVERY) { 3563 log->l_flags & XLOG_ACTIVE_RECOVERY) {
3560 mp->m_flags |= XFS_MOUNT_FS_SHUTDOWN; 3564 mp->m_flags |= XFS_MOUNT_FS_SHUTDOWN;
3561 XFS_BUF_DONE(mp->m_sb_bp); 3565 if (mp->m_sb_bp)
3566 XFS_BUF_DONE(mp->m_sb_bp);
3562 return 0; 3567 return 0;
3563 } 3568 }
3564 3569
@@ -3579,7 +3584,9 @@ xfs_log_force_umount(
3579 spin_lock(&log->l_icloglock); 3584 spin_lock(&log->l_icloglock);
3580 spin_lock(&log->l_grant_lock); 3585 spin_lock(&log->l_grant_lock);
3581 mp->m_flags |= XFS_MOUNT_FS_SHUTDOWN; 3586 mp->m_flags |= XFS_MOUNT_FS_SHUTDOWN;
3582 XFS_BUF_DONE(mp->m_sb_bp); 3587 if (mp->m_sb_bp)
3588 XFS_BUF_DONE(mp->m_sb_bp);
3589
3583 /* 3590 /*
3584 * This flag is sort of redundant because of the mount flag, but 3591 * This flag is sort of redundant because of the mount flag, but
3585 * it's good to maintain the separation between the log and the rest 3592 * it's good to maintain the separation between the log and the rest