Sun Mar 5 13:57:29 2017 UTC ()
add some event counters, for commits, writes, cache flush


(jdolecek)
diff -r1.86 -r1.87 src/sys/kern/vfs_wapbl.c

cvs diff -r1.86 -r1.87 src/sys/kern/vfs_wapbl.c (expand / switch to unified diff)

--- src/sys/kern/vfs_wapbl.c 2016/11/10 20:56:32 1.86
+++ src/sys/kern/vfs_wapbl.c 2017/03/05 13:57:29 1.87
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: vfs_wapbl.c,v 1.86 2016/11/10 20:56:32 jdolecek Exp $ */ 1/* $NetBSD: vfs_wapbl.c,v 1.87 2017/03/05 13:57:29 jdolecek Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2003, 2008, 2009 The NetBSD Foundation, Inc. 4 * Copyright (c) 2003, 2008, 2009 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Wasabi Systems, Inc. 8 * by Wasabi Systems, Inc.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -26,27 +26,27 @@ @@ -26,27 +26,27 @@
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * This implements file system independent write ahead filesystem logging. 33 * This implements file system independent write ahead filesystem logging.
34 */ 34 */
35 35
36#define WAPBL_INTERNAL 36#define WAPBL_INTERNAL
37 37
38#include <sys/cdefs.h> 38#include <sys/cdefs.h>
39__KERNEL_RCSID(0, "$NetBSD: vfs_wapbl.c,v 1.86 2016/11/10 20:56:32 jdolecek Exp $"); 39__KERNEL_RCSID(0, "$NetBSD: vfs_wapbl.c,v 1.87 2017/03/05 13:57:29 jdolecek Exp $");
40 40
41#include <sys/param.h> 41#include <sys/param.h>
42#include <sys/bitops.h> 42#include <sys/bitops.h>
43#include <sys/time.h> 43#include <sys/time.h>
44#include <sys/wapbl.h> 44#include <sys/wapbl.h>
45#include <sys/wapbl_replay.h> 45#include <sys/wapbl_replay.h>
46 46
47#ifdef _KERNEL 47#ifdef _KERNEL
48 48
49#include <sys/atomic.h> 49#include <sys/atomic.h>
50#include <sys/conf.h> 50#include <sys/conf.h>
51#include <sys/file.h> 51#include <sys/file.h>
52#include <sys/kauth.h> 52#include <sys/kauth.h>
@@ -166,34 +166,41 @@ struct wapbl { @@ -166,34 +166,41 @@ struct wapbl {
166 */ 166 */
167 167
168 struct wapbl_wc_header *wl_wc_header; /* l */ 168 struct wapbl_wc_header *wl_wc_header; /* l */
169 void *wl_wc_scratch; /* l: scratch space (XXX: por que?!?) */ 169 void *wl_wc_scratch; /* l: scratch space (XXX: por que?!?) */
170 170
171 kmutex_t wl_mtx; /* u: short-term lock */ 171 kmutex_t wl_mtx; /* u: short-term lock */
172 krwlock_t wl_rwlock; /* u: File system transaction lock */ 172 krwlock_t wl_rwlock; /* u: File system transaction lock */
173 173
174 /* 174 /*
175 * Must be held while accessing 175 * Must be held while accessing
176 * wl_count or wl_bufs or head or tail 176 * wl_count or wl_bufs or head or tail
177 */ 177 */
178 178
 179#if _KERNEL
179 /* 180 /*
180 * Callback called from within the flush routine to flush any extra 181 * Callback called from within the flush routine to flush any extra
181 * bits. Note that flush may be skipped without calling this if 182 * bits. Note that flush may be skipped without calling this if
182 * there are no outstanding buffers in the transaction. 183 * there are no outstanding buffers in the transaction.
183 */ 184 */
184#if _KERNEL 
185 wapbl_flush_fn_t wl_flush; /* r */ 185 wapbl_flush_fn_t wl_flush; /* r */
186 wapbl_flush_fn_t wl_flush_abort;/* r */ 186 wapbl_flush_fn_t wl_flush_abort;/* r */
 187
 188 /* Event counters */
 189 char wl_ev_group[EVCNT_STRING_MAX]; /* r */
 190 struct evcnt wl_ev_commit; /* l */
 191 struct evcnt wl_ev_journalwrite; /* l */
 192 struct evcnt wl_ev_metawrite; /* lm */
 193 struct evcnt wl_ev_cacheflush; /* l */
187#endif 194#endif
188 195
189 size_t wl_bufbytes; /* m: Byte count of pages in wl_bufs */ 196 size_t wl_bufbytes; /* m: Byte count of pages in wl_bufs */
190 size_t wl_bufcount; /* m: Count of buffers in wl_bufs */ 197 size_t wl_bufcount; /* m: Count of buffers in wl_bufs */
191 size_t wl_bcount; /* m: Total bcount of wl_bufs */ 198 size_t wl_bcount; /* m: Total bcount of wl_bufs */
192 199
193 LIST_HEAD(, buf) wl_bufs; /* m: Buffers in current transaction */ 200 LIST_HEAD(, buf) wl_bufs; /* m: Buffers in current transaction */
194 201
195 kcondvar_t wl_reclaimable_cv; /* m (obviously) */ 202 kcondvar_t wl_reclaimable_cv; /* m (obviously) */
196 size_t wl_reclaimable_bytes; /* m: Amount of space available for 203 size_t wl_reclaimable_bytes; /* m: Amount of space available for
197 reclamation by truncate */ 204 reclamation by truncate */
198 int wl_error_count; /* m: # of wl_entries with errors */ 205 int wl_error_count; /* m: # of wl_entries with errors */
199 size_t wl_reserved_bytes; /* never truncate log smaller than this */ 206 size_t wl_reserved_bytes; /* never truncate log smaller than this */
@@ -260,26 +267,29 @@ struct wapbl_ino { @@ -260,26 +267,29 @@ struct wapbl_ino {
260 mode_t wi_mode; 267 mode_t wi_mode;
261}; 268};
262 269
263static void wapbl_inodetrk_init(struct wapbl *wl, u_int size); 270static void wapbl_inodetrk_init(struct wapbl *wl, u_int size);
264static void wapbl_inodetrk_free(struct wapbl *wl); 271static void wapbl_inodetrk_free(struct wapbl *wl);
265static struct wapbl_ino *wapbl_inodetrk_get(struct wapbl *wl, ino_t ino); 272static struct wapbl_ino *wapbl_inodetrk_get(struct wapbl *wl, ino_t ino);
266 273
267static size_t wapbl_transaction_len(struct wapbl *wl); 274static size_t wapbl_transaction_len(struct wapbl *wl);
268static inline size_t wapbl_transaction_inodes_len(struct wapbl *wl); 275static inline size_t wapbl_transaction_inodes_len(struct wapbl *wl);
269 276
270static void wapbl_deallocation_free(struct wapbl *, struct wapbl_dealloc *, 277static void wapbl_deallocation_free(struct wapbl *, struct wapbl_dealloc *,
271 bool); 278 bool);
272 279
 280static void wapbl_evcnt_init(struct wapbl *);
 281static void wapbl_evcnt_free(struct wapbl *);
 282
273#if 0 283#if 0
274int wapbl_replay_verify(struct wapbl_replay *, struct vnode *); 284int wapbl_replay_verify(struct wapbl_replay *, struct vnode *);
275#endif 285#endif
276 286
277static int wapbl_replay_isopen1(struct wapbl_replay *); 287static int wapbl_replay_isopen1(struct wapbl_replay *);
278 288
279struct wapbl_ops wapbl_ops = { 289struct wapbl_ops wapbl_ops = {
280 .wo_wapbl_discard = wapbl_discard, 290 .wo_wapbl_discard = wapbl_discard,
281 .wo_wapbl_replay_isopen = wapbl_replay_isopen1, 291 .wo_wapbl_replay_isopen = wapbl_replay_isopen1,
282 .wo_wapbl_replay_can_read = wapbl_replay_can_read, 292 .wo_wapbl_replay_can_read = wapbl_replay_can_read,
283 .wo_wapbl_replay_read = wapbl_replay_read, 293 .wo_wapbl_replay_read = wapbl_replay_read,
284 .wo_wapbl_add_buf = wapbl_add_buf, 294 .wo_wapbl_add_buf = wapbl_add_buf,
285 .wo_wapbl_remove_buf = wapbl_remove_buf, 295 .wo_wapbl_remove_buf = wapbl_remove_buf,
@@ -342,26 +352,54 @@ wapbl_init(void) @@ -342,26 +352,54 @@ wapbl_init(void)
342static int 352static int
343wapbl_fini(void) 353wapbl_fini(void)
344{ 354{
345 355
346 if (wapbl_sysctl != NULL) 356 if (wapbl_sysctl != NULL)
347 sysctl_teardown(&wapbl_sysctl); 357 sysctl_teardown(&wapbl_sysctl);
348 358
349 pool_destroy(&wapbl_dealloc_pool); 359 pool_destroy(&wapbl_dealloc_pool);
350 pool_destroy(&wapbl_entry_pool); 360 pool_destroy(&wapbl_entry_pool);
351 361
352 return 0; 362 return 0;
353} 363}
354 364
 365static void
 366wapbl_evcnt_init(struct wapbl *wl)
 367{
 368 snprintf(wl->wl_ev_group, sizeof(wl->wl_ev_group),
 369 "wapbl fsid 0x%x/0x%x",
 370 wl->wl_mount->mnt_stat.f_fsidx.__fsid_val[0],
 371 wl->wl_mount->mnt_stat.f_fsidx.__fsid_val[1]
 372 );
 373
 374 evcnt_attach_dynamic(&wl->wl_ev_commit, EVCNT_TYPE_MISC,
 375 NULL, wl->wl_ev_group, "commit");
 376 evcnt_attach_dynamic(&wl->wl_ev_journalwrite, EVCNT_TYPE_MISC,
 377 NULL, wl->wl_ev_group, "journal sync block write");
 378 evcnt_attach_dynamic(&wl->wl_ev_metawrite, EVCNT_TYPE_MISC,
 379 NULL, wl->wl_ev_group, "metadata finished block write");
 380 evcnt_attach_dynamic(&wl->wl_ev_cacheflush, EVCNT_TYPE_MISC,
 381 NULL, wl->wl_ev_group, "cache flush");
 382}
 383
 384static void
 385wapbl_evcnt_free(struct wapbl *wl)
 386{
 387 evcnt_detach(&wl->wl_ev_commit);
 388 evcnt_detach(&wl->wl_ev_journalwrite);
 389 evcnt_detach(&wl->wl_ev_metawrite);
 390 evcnt_detach(&wl->wl_ev_cacheflush);
 391}
 392
355static int 393static int
356wapbl_start_flush_inodes(struct wapbl *wl, struct wapbl_replay *wr) 394wapbl_start_flush_inodes(struct wapbl *wl, struct wapbl_replay *wr)
357{ 395{
358 int error, i; 396 int error, i;
359 397
360 WAPBL_PRINTF(WAPBL_PRINT_REPLAY, 398 WAPBL_PRINTF(WAPBL_PRINT_REPLAY,
361 ("wapbl_start: reusing log with %d inodes\n", wr->wr_inodescnt)); 399 ("wapbl_start: reusing log with %d inodes\n", wr->wr_inodescnt));
362 400
363 /* 401 /*
364 * Its only valid to reuse the replay log if its 402 * Its only valid to reuse the replay log if its
365 * the same as the new log we just opened. 403 * the same as the new log we just opened.
366 */ 404 */
367 KDASSERT(!wapbl_replay_isopen(wr)); 405 KDASSERT(!wapbl_replay_isopen(wr));
@@ -512,26 +550,28 @@ wapbl_start(struct wapbl ** wlp, struct  @@ -512,26 +550,28 @@ wapbl_start(struct wapbl ** wlp, struct
512 - offsetof(struct wapbl_wc_blocklist, wc_blocks)) / 550 - offsetof(struct wapbl_wc_blocklist, wc_blocks)) /
513 sizeof(((struct wapbl_wc_blocklist *)0)->wc_blocks[0]); 551 sizeof(((struct wapbl_wc_blocklist *)0)->wc_blocks[0]);
514 KASSERT(wl->wl_brperjblock > 0); 552 KASSERT(wl->wl_brperjblock > 0);
515 553
516 /* XXX tie this into resource estimation */ 554 /* XXX tie this into resource estimation */
517 wl->wl_dealloclim = wl->wl_bufbytes_max / mp->mnt_stat.f_bsize / 2; 555 wl->wl_dealloclim = wl->wl_bufbytes_max / mp->mnt_stat.f_bsize / 2;
518 TAILQ_INIT(&wl->wl_dealloclist); 556 TAILQ_INIT(&wl->wl_dealloclist);
519  557
520 wl->wl_buffer = wapbl_alloc(MAXPHYS); 558 wl->wl_buffer = wapbl_alloc(MAXPHYS);
521 wl->wl_buffer_used = 0; 559 wl->wl_buffer_used = 0;
522 560
523 wapbl_inodetrk_init(wl, WAPBL_INODETRK_SIZE); 561 wapbl_inodetrk_init(wl, WAPBL_INODETRK_SIZE);
524 562
 563 wapbl_evcnt_init(wl);
 564
525 /* Initialize the commit header */ 565 /* Initialize the commit header */
526 { 566 {
527 struct wapbl_wc_header *wc; 567 struct wapbl_wc_header *wc;
528 size_t len = 1 << wl->wl_log_dev_bshift; 568 size_t len = 1 << wl->wl_log_dev_bshift;
529 wc = wapbl_calloc(1, len); 569 wc = wapbl_calloc(1, len);
530 wc->wc_type = WAPBL_WC_HEADER; 570 wc->wc_type = WAPBL_WC_HEADER;
531 wc->wc_len = len; 571 wc->wc_len = len;
532 wc->wc_circ_off = wl->wl_circ_off; 572 wc->wc_circ_off = wl->wl_circ_off;
533 wc->wc_circ_size = wl->wl_circ_size; 573 wc->wc_circ_size = wl->wl_circ_size;
534 /* XXX wc->wc_fsid */ 574 /* XXX wc->wc_fsid */
535 wc->wc_log_dev_bshift = wl->wl_log_dev_bshift; 575 wc->wc_log_dev_bshift = wl->wl_log_dev_bshift;
536 wc->wc_fs_dev_bshift = wl->wl_fs_dev_bshift; 576 wc->wc_fs_dev_bshift = wl->wl_fs_dev_bshift;
537 wl->wl_wc_header = wc; 577 wl->wl_wc_header = wc;
@@ -736,26 +776,28 @@ wapbl_stop(struct wapbl *wl, int force) @@ -736,26 +776,28 @@ wapbl_stop(struct wapbl *wl, int force)
736 KASSERT(wl->wl_bufcount == 0); 776 KASSERT(wl->wl_bufcount == 0);
737 KASSERT(LIST_EMPTY(&wl->wl_bufs)); 777 KASSERT(LIST_EMPTY(&wl->wl_bufs));
738 KASSERT(wl->wl_dealloccnt == 0); 778 KASSERT(wl->wl_dealloccnt == 0);
739 KASSERT(SIMPLEQ_EMPTY(&wl->wl_entries)); 779 KASSERT(SIMPLEQ_EMPTY(&wl->wl_entries));
740 KASSERT(wl->wl_inohashcnt == 0); 780 KASSERT(wl->wl_inohashcnt == 0);
741 KASSERT(TAILQ_EMPTY(&wl->wl_dealloclist)); 781 KASSERT(TAILQ_EMPTY(&wl->wl_dealloclist));
742 KASSERT(wl->wl_dealloccnt == 0); 782 KASSERT(wl->wl_dealloccnt == 0);
743 783
744 wapbl_free(wl->wl_wc_scratch, wl->wl_wc_header->wc_len); 784 wapbl_free(wl->wl_wc_scratch, wl->wl_wc_header->wc_len);
745 wapbl_free(wl->wl_wc_header, wl->wl_wc_header->wc_len); 785 wapbl_free(wl->wl_wc_header, wl->wl_wc_header->wc_len);
746 wapbl_free(wl->wl_buffer, MAXPHYS); 786 wapbl_free(wl->wl_buffer, MAXPHYS);
747 wapbl_inodetrk_free(wl); 787 wapbl_inodetrk_free(wl);
748 788
 789 wapbl_evcnt_free(wl);
 790
749 cv_destroy(&wl->wl_reclaimable_cv); 791 cv_destroy(&wl->wl_reclaimable_cv);
750 mutex_destroy(&wl->wl_mtx); 792 mutex_destroy(&wl->wl_mtx);
751 rw_destroy(&wl->wl_rwlock); 793 rw_destroy(&wl->wl_rwlock);
752 wapbl_free(wl, sizeof(*wl)); 794 wapbl_free(wl, sizeof(*wl));
753 795
754 return 0; 796 return 0;
755} 797}
756 798
757/****************************************************************/ 799/****************************************************************/
758/* 800/*
759 * Unbuffered disk I/O 801 * Unbuffered disk I/O
760 */ 802 */
761 803
@@ -848,26 +890,28 @@ wapbl_read(void *data, size_t len, struc @@ -848,26 +890,28 @@ wapbl_read(void *data, size_t len, struc
848 */ 890 */
849static int 891static int
850wapbl_buffered_flush(struct wapbl *wl) 892wapbl_buffered_flush(struct wapbl *wl)
851{ 893{
852 int error; 894 int error;
853 895
854 if (wl->wl_buffer_used == 0) 896 if (wl->wl_buffer_used == 0)
855 return 0; 897 return 0;
856 898
857 error = wapbl_doio(wl->wl_buffer, wl->wl_buffer_used, 899 error = wapbl_doio(wl->wl_buffer, wl->wl_buffer_used,
858 wl->wl_devvp, wl->wl_buffer_dblk, B_WRITE); 900 wl->wl_devvp, wl->wl_buffer_dblk, B_WRITE);
859 wl->wl_buffer_used = 0; 901 wl->wl_buffer_used = 0;
860 902
 903 wl->wl_ev_journalwrite.ev_count++;
 904
861 return error; 905 return error;
862} 906}
863 907
864/* 908/*
865 * wapbl_buffered_write(data, len, wl, pbn) 909 * wapbl_buffered_write(data, len, wl, pbn)
866 * 910 *
867 * Write len bytes from data to physical block pbn on 911 * Write len bytes from data to physical block pbn on
868 * wl->wl_devvp. The write may not complete until 912 * wl->wl_devvp. The write may not complete until
869 * wapbl_buffered_flush. 913 * wapbl_buffered_flush.
870 */ 914 */
871static int 915static int
872wapbl_buffered_write(void *data, size_t len, struct wapbl *wl, daddr_t pbn) 916wapbl_buffered_write(void *data, size_t len, struct wapbl *wl, daddr_t pbn)
873{ 917{
@@ -1461,26 +1505,27 @@ wapbl_biodone(struct buf *bp) @@ -1461,26 +1505,27 @@ wapbl_biodone(struct buf *bp)
1461 */ 1505 */
1462 brelse(bp, 0); 1506 brelse(bp, 0);
1463 1507
1464 mutex_enter(&wl->wl_mtx); 1508 mutex_enter(&wl->wl_mtx);
1465 1509
1466 KASSERT(we->we_bufcount > 0); 1510 KASSERT(we->we_bufcount > 0);
1467 we->we_bufcount--; 1511 we->we_bufcount--;
1468#ifdef WAPBL_DEBUG_BUFBYTES 1512#ifdef WAPBL_DEBUG_BUFBYTES
1469 KASSERT(we->we_unsynced_bufbytes >= bufsize); 1513 KASSERT(we->we_unsynced_bufbytes >= bufsize);
1470 we->we_unsynced_bufbytes -= bufsize; 1514 we->we_unsynced_bufbytes -= bufsize;
1471 KASSERT(wl->wl_unsynced_bufbytes >= bufsize); 1515 KASSERT(wl->wl_unsynced_bufbytes >= bufsize);
1472 wl->wl_unsynced_bufbytes -= bufsize; 1516 wl->wl_unsynced_bufbytes -= bufsize;
1473#endif 1517#endif
 1518 wl->wl_ev_metawrite.ev_count++;
1474 1519
1475 /* 1520 /*
1476 * If the current transaction can be reclaimed, start 1521 * If the current transaction can be reclaimed, start
1477 * at the beginning and reclaim any consecutive reclaimable 1522 * at the beginning and reclaim any consecutive reclaimable
1478 * transactions. If we successfully reclaim anything, 1523 * transactions. If we successfully reclaim anything,
1479 * then wakeup anyone waiting for the reclaim. 1524 * then wakeup anyone waiting for the reclaim.
1480 */ 1525 */
1481 if (we->we_bufcount == 0) { 1526 if (we->we_bufcount == 0) {
1482 size_t delta = 0; 1527 size_t delta = 0;
1483 int errcnt = 0; 1528 int errcnt = 0;
1484#ifdef WAPBL_DEBUG_BUFBYTES 1529#ifdef WAPBL_DEBUG_BUFBYTES
1485 KDASSERT(we->we_unsynced_bufbytes == 0); 1530 KDASSERT(we->we_unsynced_bufbytes == 0);
1486#endif 1531#endif
@@ -2169,26 +2214,29 @@ wapbl_cache_sync(struct wapbl *wl, const @@ -2169,26 +2214,29 @@ wapbl_cache_sync(struct wapbl *wl, const
2169 "returned %d\n", (uintmax_t)wl->wl_devvp->v_rdev, error)); 2214 "returned %d\n", (uintmax_t)wl->wl_devvp->v_rdev, error));
2170 } 2215 }
2171 if (verbose) { 2216 if (verbose) {
2172 struct bintime d; 2217 struct bintime d;
2173 struct timespec ts; 2218 struct timespec ts;
2174 2219
2175 bintime(&d); 2220 bintime(&d);
2176 bintime_sub(&d, &start_time); 2221 bintime_sub(&d, &start_time);
2177 bintime2timespec(&d, &ts); 2222 bintime2timespec(&d, &ts);
2178 printf("wapbl_cache_sync: %s: dev 0x%jx %ju.%09lu\n", 2223 printf("wapbl_cache_sync: %s: dev 0x%jx %ju.%09lu\n",
2179 msg, (uintmax_t)wl->wl_devvp->v_rdev, 2224 msg, (uintmax_t)wl->wl_devvp->v_rdev,
2180 (uintmax_t)ts.tv_sec, ts.tv_nsec); 2225 (uintmax_t)ts.tv_sec, ts.tv_nsec);
2181 } 2226 }
 2227
 2228 wl->wl_ev_cacheflush.ev_count++;
 2229
2182 return error; 2230 return error;
2183} 2231}
2184 2232
2185/* 2233/*
2186 * wapbl_write_commit(wl, head, tail) 2234 * wapbl_write_commit(wl, head, tail)
2187 * 2235 *
2188 * Issue a disk cache sync to wait for all pending writes to the 2236 * Issue a disk cache sync to wait for all pending writes to the
2189 * log to complete, and then synchronously commit the current 2237 * log to complete, and then synchronously commit the current
2190 * circular queue head and tail to the log, in the next of two 2238 * circular queue head and tail to the log, in the next of two
2191 * locations for commit headers on disk. 2239 * locations for commit headers on disk.
2192 * 2240 *
2193 * Increment the generation number. If the generation number 2241 * Increment the generation number. If the generation number
2194 * rolls over to zero, then a subsequent commit would appear to 2242 * rolls over to zero, then a subsequent commit would appear to
@@ -2259,26 +2307,29 @@ wapbl_write_commit(struct wapbl *wl, off @@ -2259,26 +2307,29 @@ wapbl_write_commit(struct wapbl *wl, off
2259 * This handles initialization and generation number rollover 2307 * This handles initialization and generation number rollover
2260 */ 2308 */
2261 if (wc->wc_generation++ == 0) { 2309 if (wc->wc_generation++ == 0) {
2262 error = wapbl_write_commit(wl, head, tail); 2310 error = wapbl_write_commit(wl, head, tail);
2263 /* 2311 /*
2264 * This panic should be able to be removed if we do the 2312 * This panic should be able to be removed if we do the
2265 * zero'ing mentioned above, and we are certain to roll 2313 * zero'ing mentioned above, and we are certain to roll
2266 * back generation number on failure. 2314 * back generation number on failure.
2267 */ 2315 */
2268 if (error) 2316 if (error)
2269 panic("wapbl_write_commit: error writing duplicate " 2317 panic("wapbl_write_commit: error writing duplicate "
2270 "log header: %d", error); 2318 "log header: %d", error);
2271 } 2319 }
 2320
 2321 wl->wl_ev_commit.ev_count++;
 2322
2272 return 0; 2323 return 0;
2273} 2324}
2274 2325
2275/* 2326/*
2276 * wapbl_write_blocks(wl, offp) 2327 * wapbl_write_blocks(wl, offp)
2277 * 2328 *
2278 * Write all pending physical blocks in the current transaction 2329 * Write all pending physical blocks in the current transaction
2279 * from wapbl_add_buf to the log on disk, adding to the circular 2330 * from wapbl_add_buf to the log on disk, adding to the circular
2280 * queue head at byte offset *offp, and returning the new head's 2331 * queue head at byte offset *offp, and returning the new head's
2281 * byte offset in *offp. 2332 * byte offset in *offp.
2282 */ 2333 */
2283static int 2334static int
2284wapbl_write_blocks(struct wapbl *wl, off_t *offp) 2335wapbl_write_blocks(struct wapbl *wl, off_t *offp)