diff options
Diffstat (limited to 'fs/xfs/xfs_log.c')
-rw-r--r-- | fs/xfs/xfs_log.c | 281 |
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, | |||
93 | STATIC void xlog_state_switch_iclogs(xlog_t *log, | 82 | STATIC 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); |
96 | STATIC int xlog_state_sync(xlog_t *log, xfs_lsn_t lsn, uint flags); | 85 | STATIC int xlog_state_sync(xlog_t *log, |
97 | STATIC int xlog_state_sync_all(xlog_t *log, uint flags); | 86 | xfs_lsn_t lsn, |
87 | uint flags, | ||
88 | int *log_flushed); | ||
89 | 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); | 90 | STATIC 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); |
120 | STATIC void xlog_ticket_put(xlog_t *log, xlog_ticket_t *ticket); | 112 | STATIC 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) | ||
124 | STATIC void xlog_verify_dest_ptr(xlog_t *log, __psint_t ptr); | 115 | STATIC void xlog_verify_dest_ptr(xlog_t *log, __psint_t ptr); |
125 | STATIC void xlog_verify_grant_head(xlog_t *log, int equals); | 116 | STATIC void xlog_verify_grant_head(xlog_t *log, int equals); |
126 | STATIC void xlog_verify_iclog(xlog_t *log, xlog_in_core_t *iclog, | 117 | STATIC 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 | ||
137 | STATIC int xlog_iclogs_empty(xlog_t *log); | 128 | STATIC int xlog_iclogs_empty(xlog_t *log); |
138 | 129 | ||
139 | #ifdef DEBUG | ||
140 | int xlog_do_error = 0; | ||
141 | int xlog_req_num = 0; | ||
142 | int 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) | ||
153 | int xlog_debug = 1; | ||
154 | xfs_buftarg_t *xlog_target; | ||
155 | #endif | ||
156 | |||
157 | #if defined(XFS_LOG_TRACE) | 130 | #if defined(XFS_LOG_TRACE) |
158 | |||
159 | void | 131 | void |
160 | xlog_trace_loggrant(xlog_t *log, xlog_ticket_t *tic, xfs_caddr_t string) | 132 | xlog_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) | |||
191 | void | 163 | void |
192 | xlog_trace_iclog(xlog_in_core_t *iclog, uint state) | 164 | xlog_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 | */ |
314 | int | 266 | int |
315 | xfs_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 | |||
1036 | done: /* 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 | */ |
2953 | STATIC int | 2845 | STATIC int |
2954 | xlog_state_sync_all(xlog_t *log, uint flags) | 2846 | xlog_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: | |||
3068 | int | 2962 | int |
3069 | xlog_state_sync(xlog_t *log, | 2963 | xlog_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); |