diff options
Diffstat (limited to 'fs/xfs/xfs_log.c')
-rw-r--r-- | fs/xfs/xfs_log.c | 65 |
1 files changed, 37 insertions, 28 deletions
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 51814c32eddf..b9d3ad35240e 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -93,8 +93,11 @@ STATIC int xlog_state_release_iclog(xlog_t *log, | |||
93 | STATIC void xlog_state_switch_iclogs(xlog_t *log, | 93 | STATIC void xlog_state_switch_iclogs(xlog_t *log, |
94 | xlog_in_core_t *iclog, | 94 | xlog_in_core_t *iclog, |
95 | int eventual_size); | 95 | int eventual_size); |
96 | STATIC int xlog_state_sync(xlog_t *log, xfs_lsn_t lsn, uint flags); | 96 | STATIC int xlog_state_sync(xlog_t *log, |
97 | STATIC int xlog_state_sync_all(xlog_t *log, uint flags); | 97 | xfs_lsn_t lsn, |
98 | uint flags, | ||
99 | int *log_flushed); | ||
100 | STATIC int xlog_state_sync_all(xlog_t *log, uint flags, int *log_flushed); | ||
98 | STATIC void xlog_state_want_sync(xlog_t *log, xlog_in_core_t *iclog); | 101 | STATIC void xlog_state_want_sync(xlog_t *log, xlog_in_core_t *iclog); |
99 | 102 | ||
100 | /* local functions to manipulate grant head */ | 103 | /* local functions to manipulate grant head */ |
@@ -312,12 +315,17 @@ xfs_log_done(xfs_mount_t *mp, | |||
312 | * semaphore. | 315 | * semaphore. |
313 | */ | 316 | */ |
314 | int | 317 | int |
315 | xfs_log_force(xfs_mount_t *mp, | 318 | _xfs_log_force( |
316 | xfs_lsn_t lsn, | 319 | xfs_mount_t *mp, |
317 | uint flags) | 320 | xfs_lsn_t lsn, |
321 | uint flags, | ||
322 | int *log_flushed) | ||
318 | { | 323 | { |
319 | int rval; | 324 | xlog_t *log = mp->m_log; |
320 | xlog_t *log = mp->m_log; | 325 | int dummy; |
326 | |||
327 | if (!log_flushed) | ||
328 | log_flushed = &dummy; | ||
321 | 329 | ||
322 | #if defined(DEBUG) || defined(XLOG_NOLOG) | 330 | #if defined(DEBUG) || defined(XLOG_NOLOG) |
323 | if (!xlog_debug && xlog_target == log->l_targ) | 331 | if (!xlog_debug && xlog_target == log->l_targ) |
@@ -328,17 +336,12 @@ xfs_log_force(xfs_mount_t *mp, | |||
328 | 336 | ||
329 | XFS_STATS_INC(xs_log_force); | 337 | XFS_STATS_INC(xs_log_force); |
330 | 338 | ||
331 | if ((log->l_flags & XLOG_IO_ERROR) == 0) { | 339 | if (log->l_flags & XLOG_IO_ERROR) |
332 | if (lsn == 0) | 340 | return XFS_ERROR(EIO); |
333 | rval = xlog_state_sync_all(log, flags); | 341 | if (lsn == 0) |
334 | else | 342 | return xlog_state_sync_all(log, flags, log_flushed); |
335 | rval = xlog_state_sync(log, lsn, flags); | 343 | else |
336 | } else { | 344 | return xlog_state_sync(log, lsn, flags, log_flushed); |
337 | rval = XFS_ERROR(EIO); | ||
338 | } | ||
339 | |||
340 | return rval; | ||
341 | |||
342 | } /* xfs_log_force */ | 345 | } /* xfs_log_force */ |
343 | 346 | ||
344 | /* | 347 | /* |
@@ -1467,14 +1470,13 @@ xlog_sync(xlog_t *log, | |||
1467 | XFS_BUF_BUSY(bp); | 1470 | XFS_BUF_BUSY(bp); |
1468 | XFS_BUF_ASYNC(bp); | 1471 | XFS_BUF_ASYNC(bp); |
1469 | /* | 1472 | /* |
1470 | * Do a disk write cache flush for the log block. | 1473 | * Do an ordered write for the log block. |
1471 | * This is a bit of a sledgehammer, it would be better | 1474 | * |
1472 | * to use a tag barrier here that just prevents reordering. | ||
1473 | * It may not be needed to flush the first split block in the log wrap | 1475 | * It may not be needed to flush the first split block in the log wrap |
1474 | * case, but do it anyways to be safe -AK | 1476 | * case, but do it anyways to be safe -AK |
1475 | */ | 1477 | */ |
1476 | if (!(log->l_mp->m_flags & XFS_MOUNT_NOLOGFLUSH)) | 1478 | if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) |
1477 | XFS_BUF_FLUSH(bp); | 1479 | XFS_BUF_ORDERED(bp); |
1478 | 1480 | ||
1479 | ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1); | 1481 | ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1); |
1480 | ASSERT(XFS_BUF_ADDR(bp) + BTOBB(count) <= log->l_logBBsize); | 1482 | ASSERT(XFS_BUF_ADDR(bp) + BTOBB(count) <= log->l_logBBsize); |
@@ -1505,8 +1507,8 @@ xlog_sync(xlog_t *log, | |||
1505 | XFS_BUF_SET_FSPRIVATE(bp, iclog); | 1507 | XFS_BUF_SET_FSPRIVATE(bp, iclog); |
1506 | XFS_BUF_BUSY(bp); | 1508 | XFS_BUF_BUSY(bp); |
1507 | XFS_BUF_ASYNC(bp); | 1509 | XFS_BUF_ASYNC(bp); |
1508 | if (!(log->l_mp->m_flags & XFS_MOUNT_NOLOGFLUSH)) | 1510 | if (log->l_mp->m_flags & XFS_MOUNT_BARRIER) |
1509 | XFS_BUF_FLUSH(bp); | 1511 | XFS_BUF_ORDERED(bp); |
1510 | dptr = XFS_BUF_PTR(bp); | 1512 | dptr = XFS_BUF_PTR(bp); |
1511 | /* | 1513 | /* |
1512 | * Bump the cycle numbers at the start of each block | 1514 | * Bump the cycle numbers at the start of each block |
@@ -2951,7 +2953,7 @@ xlog_state_switch_iclogs(xlog_t *log, | |||
2951 | * not in the active nor dirty state. | 2953 | * not in the active nor dirty state. |
2952 | */ | 2954 | */ |
2953 | STATIC int | 2955 | STATIC int |
2954 | xlog_state_sync_all(xlog_t *log, uint flags) | 2956 | xlog_state_sync_all(xlog_t *log, uint flags, int *log_flushed) |
2955 | { | 2957 | { |
2956 | xlog_in_core_t *iclog; | 2958 | xlog_in_core_t *iclog; |
2957 | xfs_lsn_t lsn; | 2959 | xfs_lsn_t lsn; |
@@ -3000,6 +3002,7 @@ xlog_state_sync_all(xlog_t *log, uint flags) | |||
3000 | 3002 | ||
3001 | if (xlog_state_release_iclog(log, iclog)) | 3003 | if (xlog_state_release_iclog(log, iclog)) |
3002 | return XFS_ERROR(EIO); | 3004 | return XFS_ERROR(EIO); |
3005 | *log_flushed = 1; | ||
3003 | s = LOG_LOCK(log); | 3006 | s = LOG_LOCK(log); |
3004 | if (INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT) == lsn && | 3007 | if (INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT) == lsn && |
3005 | iclog->ic_state != XLOG_STATE_DIRTY) | 3008 | iclog->ic_state != XLOG_STATE_DIRTY) |
@@ -3043,6 +3046,7 @@ maybe_sleep: | |||
3043 | */ | 3046 | */ |
3044 | if (iclog->ic_state & XLOG_STATE_IOERROR) | 3047 | if (iclog->ic_state & XLOG_STATE_IOERROR) |
3045 | return XFS_ERROR(EIO); | 3048 | return XFS_ERROR(EIO); |
3049 | *log_flushed = 1; | ||
3046 | 3050 | ||
3047 | } else { | 3051 | } else { |
3048 | 3052 | ||
@@ -3068,7 +3072,8 @@ no_sleep: | |||
3068 | int | 3072 | int |
3069 | xlog_state_sync(xlog_t *log, | 3073 | xlog_state_sync(xlog_t *log, |
3070 | xfs_lsn_t lsn, | 3074 | xfs_lsn_t lsn, |
3071 | uint flags) | 3075 | uint flags, |
3076 | int *log_flushed) | ||
3072 | { | 3077 | { |
3073 | xlog_in_core_t *iclog; | 3078 | xlog_in_core_t *iclog; |
3074 | int already_slept = 0; | 3079 | int already_slept = 0; |
@@ -3120,6 +3125,7 @@ try_again: | |||
3120 | XFS_STATS_INC(xs_log_force_sleep); | 3125 | XFS_STATS_INC(xs_log_force_sleep); |
3121 | sv_wait(&iclog->ic_prev->ic_writesema, PSWP, | 3126 | sv_wait(&iclog->ic_prev->ic_writesema, PSWP, |
3122 | &log->l_icloglock, s); | 3127 | &log->l_icloglock, s); |
3128 | *log_flushed = 1; | ||
3123 | already_slept = 1; | 3129 | already_slept = 1; |
3124 | goto try_again; | 3130 | goto try_again; |
3125 | } else { | 3131 | } else { |
@@ -3128,6 +3134,7 @@ try_again: | |||
3128 | LOG_UNLOCK(log, s); | 3134 | LOG_UNLOCK(log, s); |
3129 | if (xlog_state_release_iclog(log, iclog)) | 3135 | if (xlog_state_release_iclog(log, iclog)) |
3130 | return XFS_ERROR(EIO); | 3136 | return XFS_ERROR(EIO); |
3137 | *log_flushed = 1; | ||
3131 | s = LOG_LOCK(log); | 3138 | s = LOG_LOCK(log); |
3132 | } | 3139 | } |
3133 | } | 3140 | } |
@@ -3152,6 +3159,7 @@ try_again: | |||
3152 | */ | 3159 | */ |
3153 | if (iclog->ic_state & XLOG_STATE_IOERROR) | 3160 | if (iclog->ic_state & XLOG_STATE_IOERROR) |
3154 | return XFS_ERROR(EIO); | 3161 | return XFS_ERROR(EIO); |
3162 | *log_flushed = 1; | ||
3155 | } else { /* just return */ | 3163 | } else { /* just return */ |
3156 | LOG_UNLOCK(log, s); | 3164 | LOG_UNLOCK(log, s); |
3157 | } | 3165 | } |
@@ -3606,6 +3614,7 @@ xfs_log_force_umount( | |||
3606 | xlog_ticket_t *tic; | 3614 | xlog_ticket_t *tic; |
3607 | xlog_t *log; | 3615 | xlog_t *log; |
3608 | int retval; | 3616 | int retval; |
3617 | int dummy; | ||
3609 | SPLDECL(s); | 3618 | SPLDECL(s); |
3610 | SPLDECL(s2); | 3619 | SPLDECL(s2); |
3611 | 3620 | ||
@@ -3684,7 +3693,7 @@ xfs_log_force_umount( | |||
3684 | * Force the incore logs to disk before shutting the | 3693 | * Force the incore logs to disk before shutting the |
3685 | * log down completely. | 3694 | * log down completely. |
3686 | */ | 3695 | */ |
3687 | xlog_state_sync_all(log, XFS_LOG_FORCE|XFS_LOG_SYNC); | 3696 | xlog_state_sync_all(log, XFS_LOG_FORCE|XFS_LOG_SYNC, &dummy); |
3688 | s2 = LOG_LOCK(log); | 3697 | s2 = LOG_LOCK(log); |
3689 | retval = xlog_state_ioerror(log); | 3698 | retval = xlog_state_ioerror(log); |
3690 | LOG_UNLOCK(log, s2); | 3699 | LOG_UNLOCK(log, s2); |