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.c281
1 files changed, 91 insertions, 190 deletions
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 54a6f1142403..29af51275ca9 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -1,58 +1,47 @@
1/* 1/*
2 * Copyright (c) 2000-2004 Silicon Graphics, Inc. All Rights Reserved. 2 * Copyright (c) 2000-2005 Silicon Graphics, Inc.
3 * All Rights Reserved.
3 * 4 *
4 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or
5 * under the terms of version 2 of the GNU General Public License as 6 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
7 * 8 *
8 * This program is distributed in the hope that it would be useful, but 9 * This program is distributed in the hope that it would be useful,
9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
11 * 13 *
12 * Further, this software is distributed without any warranty that it is 14 * You should have received a copy of the GNU General Public License
13 * free of the rightful claim of any third person regarding infringement 15 * along with this program; if not, write the Free Software Foundation,
14 * or the like. Any license provided herein, whether implied or 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15 * otherwise, applies only to this software file. Patent licenses, if
16 * any, provided herein do not apply to combinations of this program with
17 * other software, or any other product whatsoever.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write the Free Software Foundation, Inc., 59
21 * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22 *
23 * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24 * Mountain View, CA 94043, or:
25 *
26 * http://www.sgi.com
27 *
28 * For further information regarding this notice, see:
29 *
30 * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31 */ 17 */
32
33/*
34 * High level interface routines for log manager
35 */
36
37#include "xfs.h" 18#include "xfs.h"
38#include "xfs_macros.h" 19#include "xfs_fs.h"
39#include "xfs_types.h" 20#include "xfs_types.h"
40#include "xfs_inum.h" 21#include "xfs_bit.h"
41#include "xfs_ag.h"
42#include "xfs_sb.h"
43#include "xfs_log.h" 22#include "xfs_log.h"
23#include "xfs_inum.h"
44#include "xfs_trans.h" 24#include "xfs_trans.h"
25#include "xfs_sb.h"
26#include "xfs_ag.h"
45#include "xfs_dir.h" 27#include "xfs_dir.h"
28#include "xfs_dir2.h"
46#include "xfs_dmapi.h" 29#include "xfs_dmapi.h"
47#include "xfs_mount.h" 30#include "xfs_mount.h"
48#include "xfs_error.h" 31#include "xfs_error.h"
49#include "xfs_log_priv.h" 32#include "xfs_log_priv.h"
50#include "xfs_buf_item.h" 33#include "xfs_buf_item.h"
34#include "xfs_bmap_btree.h"
51#include "xfs_alloc_btree.h" 35#include "xfs_alloc_btree.h"
36#include "xfs_ialloc_btree.h"
52#include "xfs_log_recover.h" 37#include "xfs_log_recover.h"
53#include "xfs_bit.h"
54#include "xfs_rw.h"
55#include "xfs_trans_priv.h" 38#include "xfs_trans_priv.h"
39#include "xfs_dir_sf.h"
40#include "xfs_dir2_sf.h"
41#include "xfs_attr_sf.h"
42#include "xfs_dinode.h"
43#include "xfs_inode.h"
44#include "xfs_rw.h"
56 45
57 46
58#define xlog_write_adv_cnt(ptr, len, off, bytes) \ 47#define xlog_write_adv_cnt(ptr, len, off, bytes) \
@@ -93,8 +82,11 @@ STATIC int xlog_state_release_iclog(xlog_t *log,
93STATIC void xlog_state_switch_iclogs(xlog_t *log, 82STATIC void xlog_state_switch_iclogs(xlog_t *log,
94 xlog_in_core_t *iclog, 83 xlog_in_core_t *iclog,
95 int eventual_size); 84 int eventual_size);
96STATIC int xlog_state_sync(xlog_t *log, xfs_lsn_t lsn, uint flags); 85STATIC int xlog_state_sync(xlog_t *log,
97STATIC int xlog_state_sync_all(xlog_t *log, uint flags); 86 xfs_lsn_t lsn,
87 uint flags,
88 int *log_flushed);
89STATIC int xlog_state_sync_all(xlog_t *log, uint flags, int *log_flushed);
98STATIC void xlog_state_want_sync(xlog_t *log, xlog_in_core_t *iclog); 90STATIC void xlog_state_want_sync(xlog_t *log, xlog_in_core_t *iclog);
99 91
100/* local functions to manipulate grant head */ 92/* local functions to manipulate grant head */
@@ -119,8 +111,7 @@ STATIC xlog_ticket_t *xlog_ticket_get(xlog_t *log,
119 uint flags); 111 uint flags);
120STATIC void xlog_ticket_put(xlog_t *log, xlog_ticket_t *ticket); 112STATIC void xlog_ticket_put(xlog_t *log, xlog_ticket_t *ticket);
121 113
122/* local debug functions */ 114#if defined(DEBUG)
123#if defined(DEBUG) && !defined(XLOG_NOLOG)
124STATIC void xlog_verify_dest_ptr(xlog_t *log, __psint_t ptr); 115STATIC void xlog_verify_dest_ptr(xlog_t *log, __psint_t ptr);
125STATIC void xlog_verify_grant_head(xlog_t *log, int equals); 116STATIC void xlog_verify_grant_head(xlog_t *log, int equals);
126STATIC void xlog_verify_iclog(xlog_t *log, xlog_in_core_t *iclog, 117STATIC void xlog_verify_iclog(xlog_t *log, xlog_in_core_t *iclog,
@@ -136,26 +127,7 @@ STATIC void xlog_verify_tail_lsn(xlog_t *log, xlog_in_core_t *iclog,
136 127
137STATIC int xlog_iclogs_empty(xlog_t *log); 128STATIC int xlog_iclogs_empty(xlog_t *log);
138 129
139#ifdef DEBUG
140int xlog_do_error = 0;
141int xlog_req_num = 0;
142int xlog_error_mod = 33;
143#endif
144
145#define XLOG_FORCED_SHUTDOWN(log) (log->l_flags & XLOG_IO_ERROR)
146
147/*
148 * 0 => disable log manager
149 * 1 => enable log manager
150 * 2 => enable log manager and log debugging
151 */
152#if defined(XLOG_NOLOG) || defined(DEBUG)
153int xlog_debug = 1;
154xfs_buftarg_t *xlog_target;
155#endif
156
157#if defined(XFS_LOG_TRACE) 130#if defined(XFS_LOG_TRACE)
158
159void 131void
160xlog_trace_loggrant(xlog_t *log, xlog_ticket_t *tic, xfs_caddr_t string) 132xlog_trace_loggrant(xlog_t *log, xlog_ticket_t *tic, xfs_caddr_t string)
161{ 133{
@@ -191,31 +163,16 @@ xlog_trace_loggrant(xlog_t *log, xlog_ticket_t *tic, xfs_caddr_t string)
191void 163void
192xlog_trace_iclog(xlog_in_core_t *iclog, uint state) 164xlog_trace_iclog(xlog_in_core_t *iclog, uint state)
193{ 165{
194 pid_t pid;
195
196 pid = current_pid();
197
198 if (!iclog->ic_trace) 166 if (!iclog->ic_trace)
199 iclog->ic_trace = ktrace_alloc(256, KM_SLEEP); 167 iclog->ic_trace = ktrace_alloc(256, KM_SLEEP);
200 ktrace_enter(iclog->ic_trace, 168 ktrace_enter(iclog->ic_trace,
201 (void *)((unsigned long)state), 169 (void *)((unsigned long)state),
202 (void *)((unsigned long)pid), 170 (void *)((unsigned long)current_pid()),
203 (void *)0, 171 (void *)NULL, (void *)NULL, (void *)NULL, (void *)NULL,
204 (void *)0, 172 (void *)NULL, (void *)NULL, (void *)NULL, (void *)NULL,
205 (void *)0, 173 (void *)NULL, (void *)NULL, (void *)NULL, (void *)NULL,
206 (void *)0, 174 (void *)NULL, (void *)NULL);
207 (void *)0,
208 (void *)0,
209 (void *)0,
210 (void *)0,
211 (void *)0,
212 (void *)0,
213 (void *)0,
214 (void *)0,
215 (void *)0,
216 (void *)0);
217} 175}
218
219#else 176#else
220#define xlog_trace_loggrant(log,tic,string) 177#define xlog_trace_loggrant(log,tic,string)
221#define xlog_trace_iclog(iclog,state) 178#define xlog_trace_iclog(iclog,state)
@@ -252,11 +209,6 @@ xfs_log_done(xfs_mount_t *mp,
252 xlog_ticket_t *ticket = (xfs_log_ticket_t) xtic; 209 xlog_ticket_t *ticket = (xfs_log_ticket_t) xtic;
253 xfs_lsn_t lsn = 0; 210 xfs_lsn_t lsn = 0;
254 211
255#if defined(DEBUG) || defined(XLOG_NOLOG)
256 if (!xlog_debug && xlog_target == log->l_targ)
257 return 0;
258#endif
259
260 if (XLOG_FORCED_SHUTDOWN(log) || 212 if (XLOG_FORCED_SHUTDOWN(log) ||
261 /* 213 /*
262 * If nothing was ever written, don't write out commit record. 214 * If nothing was ever written, don't write out commit record.
@@ -312,33 +264,28 @@ xfs_log_done(xfs_mount_t *mp,
312 * semaphore. 264 * semaphore.
313 */ 265 */
314int 266int
315xfs_log_force(xfs_mount_t *mp, 267_xfs_log_force(
316 xfs_lsn_t lsn, 268 xfs_mount_t *mp,
317 uint flags) 269 xfs_lsn_t lsn,
270 uint flags,
271 int *log_flushed)
318{ 272{
319 int rval; 273 xlog_t *log = mp->m_log;
320 xlog_t *log = mp->m_log; 274 int dummy;
321 275
322#if defined(DEBUG) || defined(XLOG_NOLOG) 276 if (!log_flushed)
323 if (!xlog_debug && xlog_target == log->l_targ) 277 log_flushed = &dummy;
324 return 0;
325#endif
326 278
327 ASSERT(flags & XFS_LOG_FORCE); 279 ASSERT(flags & XFS_LOG_FORCE);
328 280
329 XFS_STATS_INC(xs_log_force); 281 XFS_STATS_INC(xs_log_force);
330 282
331 if ((log->l_flags & XLOG_IO_ERROR) == 0) { 283 if (log->l_flags & XLOG_IO_ERROR)
332 if (lsn == 0) 284 return XFS_ERROR(EIO);
333 rval = xlog_state_sync_all(log, flags); 285 if (lsn == 0)
334 else 286 return xlog_state_sync_all(log, flags, log_flushed);
335 rval = xlog_state_sync(log, lsn, flags); 287 else
336 } else { 288 return xlog_state_sync(log, lsn, flags, log_flushed);
337 rval = XFS_ERROR(EIO);
338 }
339
340 return rval;
341
342} /* xfs_log_force */ 289} /* xfs_log_force */
343 290
344/* 291/*
@@ -356,10 +303,6 @@ xfs_log_notify(xfs_mount_t *mp, /* mount of partition */
356 xlog_in_core_t *iclog = (xlog_in_core_t *)iclog_hndl; 303 xlog_in_core_t *iclog = (xlog_in_core_t *)iclog_hndl;
357 int abortflg, spl; 304 int abortflg, spl;
358 305
359#if defined(DEBUG) || defined(XLOG_NOLOG)
360 if (!xlog_debug && xlog_target == log->l_targ)
361 return 0;
362#endif
363 cb->cb_next = NULL; 306 cb->cb_next = NULL;
364 spl = LOG_LOCK(log); 307 spl = LOG_LOCK(log);
365 abortflg = (iclog->ic_state & XLOG_STATE_IOERROR); 308 abortflg = (iclog->ic_state & XLOG_STATE_IOERROR);
@@ -410,13 +353,8 @@ xfs_log_reserve(xfs_mount_t *mp,
410{ 353{
411 xlog_t *log = mp->m_log; 354 xlog_t *log = mp->m_log;
412 xlog_ticket_t *internal_ticket; 355 xlog_ticket_t *internal_ticket;
413 int retval; 356 int retval = 0;
414 357
415#if defined(DEBUG) || defined(XLOG_NOLOG)
416 if (!xlog_debug && xlog_target == log->l_targ)
417 return 0;
418#endif
419 retval = 0;
420 ASSERT(client == XFS_TRANSACTION || client == XFS_LOG); 358 ASSERT(client == XFS_TRANSACTION || client == XFS_LOG);
421 ASSERT((flags & XFS_LOG_NOSLEEP) == 0); 359 ASSERT((flags & XFS_LOG_NOSLEEP) == 0);
422 360
@@ -478,12 +416,6 @@ xfs_log_mount(xfs_mount_t *mp,
478 416
479 mp->m_log = xlog_alloc_log(mp, log_target, blk_offset, num_bblks); 417 mp->m_log = xlog_alloc_log(mp, log_target, blk_offset, num_bblks);
480 418
481#if defined(DEBUG) || defined(XLOG_NOLOG)
482 if (!xlog_debug) {
483 cmn_err(CE_NOTE, "log dev: %s", XFS_BUFTARG_NAME(log_target));
484 return 0;
485 }
486#endif
487 /* 419 /*
488 * skip log recovery on a norecovery mount. pretend it all 420 * skip log recovery on a norecovery mount. pretend it all
489 * just worked. 421 * just worked.
@@ -587,11 +519,6 @@ xfs_log_unmount_write(xfs_mount_t *mp)
587 __uint32_t pad2; /* may as well make it 64 bits */ 519 __uint32_t pad2; /* may as well make it 64 bits */
588 } magic = { XLOG_UNMOUNT_TYPE, 0, 0 }; 520 } magic = { XLOG_UNMOUNT_TYPE, 0, 0 };
589 521
590#if defined(DEBUG) || defined(XLOG_NOLOG)
591 if (!xlog_debug && xlog_target == log->l_targ)
592 return 0;
593#endif
594
595 /* 522 /*
596 * Don't write out unmount record on read-only mounts. 523 * Don't write out unmount record on read-only mounts.
597 * 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).
@@ -718,12 +645,6 @@ xfs_log_write(xfs_mount_t * mp,
718 int error; 645 int error;
719 xlog_t *log = mp->m_log; 646 xlog_t *log = mp->m_log;
720 647
721#if defined(DEBUG) || defined(XLOG_NOLOG)
722 if (!xlog_debug && xlog_target == log->l_targ) {
723 *start_lsn = 0;
724 return 0;
725 }
726#endif
727 if (XLOG_FORCED_SHUTDOWN(log)) 648 if (XLOG_FORCED_SHUTDOWN(log))
728 return XFS_ERROR(EIO); 649 return XFS_ERROR(EIO);
729 650
@@ -743,11 +664,6 @@ xfs_log_move_tail(xfs_mount_t *mp,
743 int need_bytes, free_bytes, cycle, bytes; 664 int need_bytes, free_bytes, cycle, bytes;
744 SPLDECL(s); 665 SPLDECL(s);
745 666
746#if defined(DEBUG) || defined(XLOG_NOLOG)
747 if (!xlog_debug && xlog_target == log->l_targ)
748 return;
749#endif
750 /* XXXsup tmp */
751 if (XLOG_FORCED_SHUTDOWN(log)) 667 if (XLOG_FORCED_SHUTDOWN(log))
752 return; 668 return;
753 ASSERT(!XFS_FORCED_SHUTDOWN(mp)); 669 ASSERT(!XFS_FORCED_SHUTDOWN(mp));
@@ -1034,51 +950,22 @@ xlog_get_iclog_buffer_size(xfs_mount_t *mp,
1034 int size; 950 int size;
1035 int xhdrs; 951 int xhdrs;
1036 952
1037#if defined(DEBUG) || defined(XLOG_NOLOG) 953 if (mp->m_logbufs <= 0) {
1038 /* 954 if (xfs_physmem <= btoc(128*1024*1024)) {
1039 * When logbufs == 0, someone has disabled the log from the FSTAB 955 log->l_iclog_bufs = XLOG_MIN_ICLOGS;
1040 * file. This is not a documented feature. We need to set xlog_debug 956 } else if (xfs_physmem <= btoc(400*1024*1024)) {
1041 * to zero (this deactivates the log) and set xlog_target to the 957 log->l_iclog_bufs = XLOG_MED_ICLOGS;
1042 * appropriate device. Only one filesystem may be affected as such 958 } else { /* 256K with 32K bufs */
1043 * since this is just a performance hack to test what we might be able 959 log->l_iclog_bufs = XLOG_MAX_ICLOGS;
1044 * to get if the log were not present.
1045 */
1046 if (mp->m_logbufs == 0) {
1047 xlog_debug = 0;
1048 xlog_target = log->l_targ;
1049 log->l_iclog_bufs = XLOG_MIN_ICLOGS;
1050 } else
1051#endif
1052 {
1053 /*
1054 * This is the normal path. If m_logbufs == -1, then the
1055 * admin has chosen to use the system defaults for logbuffers.
1056 */
1057 if (mp->m_logbufs == -1) {
1058 if (xfs_physmem <= btoc(128*1024*1024)) {
1059 log->l_iclog_bufs = XLOG_MIN_ICLOGS;
1060 } else if (xfs_physmem <= btoc(400*1024*1024)) {
1061 log->l_iclog_bufs = XLOG_MED_ICLOGS;
1062 } else {
1063 /* 256K with 32K bufs */
1064 log->l_iclog_bufs = XLOG_MAX_ICLOGS;
1065 }
1066 } else
1067 log->l_iclog_bufs = mp->m_logbufs;
1068
1069#if defined(DEBUG) || defined(XLOG_NOLOG)
1070 /* We are reactivating a filesystem after it was inactive */
1071 if (log->l_targ == xlog_target) {
1072 xlog_target = NULL;
1073 xlog_debug = 1;
1074 } 960 }
1075#endif 961 } else {
962 log->l_iclog_bufs = mp->m_logbufs;
1076 } 963 }
1077 964
1078 /* 965 /*
1079 * Buffer size passed in from mount system call. 966 * Buffer size passed in from mount system call.
1080 */ 967 */
1081 if (mp->m_logbsize != -1) { 968 if (mp->m_logbsize > 0) {
1082 size = log->l_iclog_size = mp->m_logbsize; 969 size = log->l_iclog_size = mp->m_logbsize;
1083 log->l_iclog_size_log = 0; 970 log->l_iclog_size_log = 0;
1084 while (size != 1) { 971 while (size != 1) {
@@ -1101,7 +988,7 @@ xlog_get_iclog_buffer_size(xfs_mount_t *mp,
1101 log->l_iclog_hsize = BBSIZE; 988 log->l_iclog_hsize = BBSIZE;
1102 log->l_iclog_heads = 1; 989 log->l_iclog_heads = 1;
1103 } 990 }
1104 return; 991 goto done;
1105 } 992 }
1106 993
1107 /* 994 /*
@@ -1128,7 +1015,7 @@ xlog_get_iclog_buffer_size(xfs_mount_t *mp,
1128 if (mp->m_sb.sb_blocksize >= 16*1024) { 1015 if (mp->m_sb.sb_blocksize >= 16*1024) {
1129 log->l_iclog_size = XLOG_BIG_RECORD_BSIZE; 1016 log->l_iclog_size = XLOG_BIG_RECORD_BSIZE;
1130 log->l_iclog_size_log = XLOG_BIG_RECORD_BSHIFT; 1017 log->l_iclog_size_log = XLOG_BIG_RECORD_BSHIFT;
1131 if (mp->m_logbufs == -1) { 1018 if (mp->m_logbufs <= 0) {
1132 switch (mp->m_sb.sb_blocksize) { 1019 switch (mp->m_sb.sb_blocksize) {
1133 case 16*1024: /* 16 KB */ 1020 case 16*1024: /* 16 KB */
1134 log->l_iclog_bufs = 3; 1021 log->l_iclog_bufs = 3;
@@ -1145,6 +1032,12 @@ xlog_get_iclog_buffer_size(xfs_mount_t *mp,
1145 } 1032 }
1146 } 1033 }
1147 } 1034 }
1035
1036done: /* are we being asked to make the sizes selected above visible? */
1037 if (mp->m_logbufs == 0)
1038 mp->m_logbufs = log->l_iclog_bufs;
1039 if (mp->m_logbsize == 0)
1040 mp->m_logbsize = log->l_iclog_size;
1148} /* xlog_get_iclog_buffer_size */ 1041} /* xlog_get_iclog_buffer_size */
1149 1042
1150 1043
@@ -1467,14 +1360,13 @@ xlog_sync(xlog_t *log,
1467 XFS_BUF_BUSY(bp); 1360 XFS_BUF_BUSY(bp);
1468 XFS_BUF_ASYNC(bp); 1361 XFS_BUF_ASYNC(bp);
1469 /* 1362 /*
1470 * Do a disk write cache flush for the log block. 1363 * Do an ordered write for the log block.
1471 * This is a bit of a sledgehammer, it would be better 1364 *
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 1365 * 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 1366 * case, but do it anyways to be safe -AK
1475 */ 1367 */
1476 if (!(log->l_mp->m_flags & XFS_MOUNT_NOLOGFLUSH)) 1368 if (log->l_mp->m_flags & XFS_MOUNT_BARRIER)
1477 XFS_BUF_FLUSH(bp); 1369 XFS_BUF_ORDERED(bp);
1478 1370
1479 ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1); 1371 ASSERT(XFS_BUF_ADDR(bp) <= log->l_logBBsize-1);
1480 ASSERT(XFS_BUF_ADDR(bp) + BTOBB(count) <= log->l_logBBsize); 1372 ASSERT(XFS_BUF_ADDR(bp) + BTOBB(count) <= log->l_logBBsize);
@@ -1505,8 +1397,8 @@ xlog_sync(xlog_t *log,
1505 XFS_BUF_SET_FSPRIVATE(bp, iclog); 1397 XFS_BUF_SET_FSPRIVATE(bp, iclog);
1506 XFS_BUF_BUSY(bp); 1398 XFS_BUF_BUSY(bp);
1507 XFS_BUF_ASYNC(bp); 1399 XFS_BUF_ASYNC(bp);
1508 if (!(log->l_mp->m_flags & XFS_MOUNT_NOLOGFLUSH)) 1400 if (log->l_mp->m_flags & XFS_MOUNT_BARRIER)
1509 XFS_BUF_FLUSH(bp); 1401 XFS_BUF_ORDERED(bp);
1510 dptr = XFS_BUF_PTR(bp); 1402 dptr = XFS_BUF_PTR(bp);
1511 /* 1403 /*
1512 * Bump the cycle numbers at the start of each block 1404 * Bump the cycle numbers at the start of each block
@@ -2951,7 +2843,7 @@ xlog_state_switch_iclogs(xlog_t *log,
2951 * not in the active nor dirty state. 2843 * not in the active nor dirty state.
2952 */ 2844 */
2953STATIC int 2845STATIC int
2954xlog_state_sync_all(xlog_t *log, uint flags) 2846xlog_state_sync_all(xlog_t *log, uint flags, int *log_flushed)
2955{ 2847{
2956 xlog_in_core_t *iclog; 2848 xlog_in_core_t *iclog;
2957 xfs_lsn_t lsn; 2849 xfs_lsn_t lsn;
@@ -3000,6 +2892,7 @@ xlog_state_sync_all(xlog_t *log, uint flags)
3000 2892
3001 if (xlog_state_release_iclog(log, iclog)) 2893 if (xlog_state_release_iclog(log, iclog))
3002 return XFS_ERROR(EIO); 2894 return XFS_ERROR(EIO);
2895 *log_flushed = 1;
3003 s = LOG_LOCK(log); 2896 s = LOG_LOCK(log);
3004 if (INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT) == lsn && 2897 if (INT_GET(iclog->ic_header.h_lsn, ARCH_CONVERT) == lsn &&
3005 iclog->ic_state != XLOG_STATE_DIRTY) 2898 iclog->ic_state != XLOG_STATE_DIRTY)
@@ -3043,6 +2936,7 @@ maybe_sleep:
3043 */ 2936 */
3044 if (iclog->ic_state & XLOG_STATE_IOERROR) 2937 if (iclog->ic_state & XLOG_STATE_IOERROR)
3045 return XFS_ERROR(EIO); 2938 return XFS_ERROR(EIO);
2939 *log_flushed = 1;
3046 2940
3047 } else { 2941 } else {
3048 2942
@@ -3068,7 +2962,8 @@ no_sleep:
3068int 2962int
3069xlog_state_sync(xlog_t *log, 2963xlog_state_sync(xlog_t *log,
3070 xfs_lsn_t lsn, 2964 xfs_lsn_t lsn,
3071 uint flags) 2965 uint flags,
2966 int *log_flushed)
3072{ 2967{
3073 xlog_in_core_t *iclog; 2968 xlog_in_core_t *iclog;
3074 int already_slept = 0; 2969 int already_slept = 0;
@@ -3120,6 +3015,7 @@ try_again:
3120 XFS_STATS_INC(xs_log_force_sleep); 3015 XFS_STATS_INC(xs_log_force_sleep);
3121 sv_wait(&iclog->ic_prev->ic_writesema, PSWP, 3016 sv_wait(&iclog->ic_prev->ic_writesema, PSWP,
3122 &log->l_icloglock, s); 3017 &log->l_icloglock, s);
3018 *log_flushed = 1;
3123 already_slept = 1; 3019 already_slept = 1;
3124 goto try_again; 3020 goto try_again;
3125 } else { 3021 } else {
@@ -3128,6 +3024,7 @@ try_again:
3128 LOG_UNLOCK(log, s); 3024 LOG_UNLOCK(log, s);
3129 if (xlog_state_release_iclog(log, iclog)) 3025 if (xlog_state_release_iclog(log, iclog))
3130 return XFS_ERROR(EIO); 3026 return XFS_ERROR(EIO);
3027 *log_flushed = 1;
3131 s = LOG_LOCK(log); 3028 s = LOG_LOCK(log);
3132 } 3029 }
3133 } 3030 }
@@ -3152,6 +3049,7 @@ try_again:
3152 */ 3049 */
3153 if (iclog->ic_state & XLOG_STATE_IOERROR) 3050 if (iclog->ic_state & XLOG_STATE_IOERROR)
3154 return XFS_ERROR(EIO); 3051 return XFS_ERROR(EIO);
3052 *log_flushed = 1;
3155 } else { /* just return */ 3053 } else { /* just return */
3156 LOG_UNLOCK(log, s); 3054 LOG_UNLOCK(log, s);
3157 } 3055 }
@@ -3392,7 +3290,7 @@ xlog_ticket_get(xlog_t *log,
3392 * 3290 *
3393 ****************************************************************************** 3291 ******************************************************************************
3394 */ 3292 */
3395#if defined(DEBUG) && !defined(XLOG_NOLOG) 3293#if defined(DEBUG)
3396/* 3294/*
3397 * Make sure that the destination ptr is within the valid data region of 3295 * Make sure that the destination ptr is within the valid data region of
3398 * one of the iclogs. This uses backup pointers stored in a different 3296 * one of the iclogs. This uses backup pointers stored in a different
@@ -3533,7 +3431,9 @@ xlog_verify_iclog(xlog_t *log,
3533 } 3431 }
3534 } 3432 }
3535 if (clientid != XFS_TRANSACTION && clientid != XFS_LOG) 3433 if (clientid != XFS_TRANSACTION && clientid != XFS_LOG)
3536 cmn_err(CE_WARN, "xlog_verify_iclog: invalid clientid %d op 0x%p offset 0x%x", clientid, ophead, field_offset); 3434 cmn_err(CE_WARN, "xlog_verify_iclog: "
3435 "invalid clientid %d op 0x%p offset 0x%lx",
3436 clientid, ophead, (unsigned long)field_offset);
3537 3437
3538 /* check length */ 3438 /* check length */
3539 field_offset = (__psint_t) 3439 field_offset = (__psint_t)
@@ -3554,7 +3454,7 @@ xlog_verify_iclog(xlog_t *log,
3554 ptr += sizeof(xlog_op_header_t) + op_len; 3454 ptr += sizeof(xlog_op_header_t) + op_len;
3555 } 3455 }
3556} /* xlog_verify_iclog */ 3456} /* xlog_verify_iclog */
3557#endif /* DEBUG && !XLOG_NOLOG */ 3457#endif
3558 3458
3559/* 3459/*
3560 * Mark all iclogs IOERROR. LOG_LOCK is held by the caller. 3460 * Mark all iclogs IOERROR. LOG_LOCK is held by the caller.
@@ -3604,6 +3504,7 @@ xfs_log_force_umount(
3604 xlog_ticket_t *tic; 3504 xlog_ticket_t *tic;
3605 xlog_t *log; 3505 xlog_t *log;
3606 int retval; 3506 int retval;
3507 int dummy;
3607 SPLDECL(s); 3508 SPLDECL(s);
3608 SPLDECL(s2); 3509 SPLDECL(s2);
3609 3510
@@ -3682,7 +3583,7 @@ xfs_log_force_umount(
3682 * Force the incore logs to disk before shutting the 3583 * Force the incore logs to disk before shutting the
3683 * log down completely. 3584 * log down completely.
3684 */ 3585 */
3685 xlog_state_sync_all(log, XFS_LOG_FORCE|XFS_LOG_SYNC); 3586 xlog_state_sync_all(log, XFS_LOG_FORCE|XFS_LOG_SYNC, &dummy);
3686 s2 = LOG_LOCK(log); 3587 s2 = LOG_LOCK(log);
3687 retval = xlog_state_ioerror(log); 3588 retval = xlog_state_ioerror(log);
3688 LOG_UNLOCK(log, s2); 3589 LOG_UNLOCK(log, s2);