Add two sysctls one that does verbose transaction logging and a second one

that disables flushing the disk cache (which is fast but dangerous for
data integrity). From simon a long while back.
This commit is contained in:
christos 2011-01-08 20:37:05 +00:00
parent 27ec421326
commit f79b6ffa09
1 changed files with 98 additions and 17 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: vfs_wapbl.c,v 1.38 2010/11/09 16:30:26 hannken Exp $ */
/* $NetBSD: vfs_wapbl.c,v 1.39 2011/01/08 20:37:05 christos Exp $ */
/*-
* Copyright (c) 2003, 2008, 2009 The NetBSD Foundation, Inc.
@ -36,7 +36,7 @@
#define WAPBL_INTERNAL
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vfs_wapbl.c,v 1.38 2010/11/09 16:30:26 hannken Exp $");
__KERNEL_RCSID(0, "$NetBSD: vfs_wapbl.c,v 1.39 2011/01/08 20:37:05 christos Exp $");
#include <sys/param.h>
#include <sys/bitops.h>
@ -45,6 +45,7 @@ __KERNEL_RCSID(0, "$NetBSD: vfs_wapbl.c,v 1.38 2010/11/09 16:30:26 hannken Exp $
#include <sys/param.h>
#include <sys/namei.h>
#include <sys/proc.h>
#include <sys/sysctl.h>
#include <sys/uio.h>
#include <sys/vnode.h>
#include <sys/file.h>
@ -73,6 +74,10 @@ MALLOC_JUSTDEFINE(M_WAPBL, "wapbl", "write-ahead physical block logging");
#define wapbl_calloc(n, s) malloc((n)*(s), M_WAPBL, M_WAITOK | M_ZERO)
#endif
static struct sysctllog *wapbl_sysctl;
static int wapbl_flush_disk_cache = 1;
static int wapbl_verbose_commit = 0;
#else /* !_KERNEL */
#include <assert.h>
#include <errno.h>
@ -259,6 +264,66 @@ struct wapbl_ops wapbl_ops = {
.wo_wapbl_biodone = wapbl_biodone,
};
static int
wapbl_sysctl_init(void)
{
int rv;
const struct sysctlnode *rnode, *cnode;
wapbl_sysctl = NULL;
rv = sysctl_createv(&wapbl_sysctl, 0, NULL, &rnode,
CTLFLAG_PERMANENT,
CTLTYPE_NODE, "vfs", NULL,
NULL, 0, NULL, 0,
CTL_VFS, CTL_EOL);
if (rv)
return rv;
rv = sysctl_createv(&wapbl_sysctl, 0, &rnode, &rnode,
CTLFLAG_PERMANENT,
CTLTYPE_NODE, "wapbl",
SYSCTL_DESCR("WAPBL journaling options"),
NULL, 0, NULL, 0,
CTL_CREATE, CTL_EOL);
if (rv)
return rv;
rv = sysctl_createv(&wapbl_sysctl, 0, &rnode, &cnode,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
CTLTYPE_INT, "flush_disk_cache",
SYSCTL_DESCR("flush disk cache"),
NULL, 0, &wapbl_flush_disk_cache, 0,
CTL_CREATE, CTL_EOL);
if (rv)
return rv;
rv = sysctl_createv(&wapbl_sysctl, 0, &rnode, &cnode,
CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
CTLTYPE_INT, "verbose_commit",
SYSCTL_DESCR("show time and size of wapbl log commits"),
NULL, 0, &wapbl_verbose_commit, 0,
CTL_CREATE, CTL_EOL);
return rv;
}
static void
wapbl_init(void)
{
malloc_type_attach(M_WAPBL);
wapbl_sysctl_init();
}
#ifdef notyet
static int
wapbl_fini(bool interface)
{
if (aio_sysctl != NULL)
sysctl_teardown(&aio_sysctl);
return 0;
}
#endif
static int
wapbl_start_flush_inodes(struct wapbl *wl, struct wapbl_replay *wr)
{
@ -1327,6 +1392,13 @@ wapbl_flush(struct wapbl *wl, int waitfor)
/* Calculate amount of space needed to flush */
flushsize = wapbl_transaction_len(wl);
if (wapbl_verbose_commit) {
struct timespec ts;
getnanotime(&ts);
printf("%s: %lld.%06ld this transaction = %zu bytes\n",
__func__, (long long)ts.tv_sec,
(long)ts.tv_nsec, flushsize);
}
if (flushsize > (wl->wl_circ_size - wl->wl_reserved_bytes)) {
/*
@ -1791,7 +1863,7 @@ wapbl_transaction_inodes_len(struct wapbl *wl)
KASSERT(iph > 0);
return MAX(1, howmany(wl->wl_inohashcnt, iph))*blocklen;
return MAX(1, howmany(wl->wl_inohashcnt, iph)) * blocklen;
}
@ -1810,8 +1882,8 @@ wapbl_transaction_len(struct wapbl *wl)
KASSERT(bph > 0);
len = wl->wl_bcount;
len += howmany(wl->wl_bufcount, bph)*blocklen;
len += howmany(wl->wl_dealloccnt, bph)*blocklen;
len += howmany(wl->wl_bufcount, bph) * blocklen;
len += howmany(wl->wl_dealloccnt, bph) * blocklen;
len += wapbl_transaction_inodes_len(wl);
return len;
@ -1834,12 +1906,15 @@ wapbl_write_commit(struct wapbl *wl, off_t head, off_t tail)
int force = 1;
daddr_t pbn;
/* XXX Calc checksum here, instead we do this for now */
error = VOP_IOCTL(wl->wl_devvp, DIOCCACHESYNC, &force, FWRITE, FSCRED);
if (error) {
WAPBL_PRINTF(WAPBL_PRINT_ERROR,
("wapbl_write_commit: DIOCCACHESYNC on dev 0x%"PRIx64
" returned %d\n", wl->wl_devvp->v_rdev, error));
if (wapbl_flush_disk_cache) {
/* XXX Calc checksum here, instead we do this for now */
error = VOP_IOCTL(wl->wl_devvp, DIOCCACHESYNC, &force,
FWRITE, FSCRED);
if (error) {
WAPBL_PRINTF(WAPBL_PRINT_ERROR,
("wapbl_write_commit: DIOCCACHESYNC on dev 0x%x "
"returned %d\n", wl->wl_devvp->v_rdev, error));
}
}
wc->wc_head = head;
@ -1867,11 +1942,14 @@ wapbl_write_commit(struct wapbl *wl, off_t head, off_t tail)
if (error)
return error;
error = VOP_IOCTL(wl->wl_devvp, DIOCCACHESYNC, &force, FWRITE, FSCRED);
if (error) {
WAPBL_PRINTF(WAPBL_PRINT_ERROR,
("wapbl_write_commit: DIOCCACHESYNC on dev 0x%"PRIx64
" returned %d\n", wl->wl_devvp->v_rdev, error));
if (wapbl_flush_disk_cache) {
error = VOP_IOCTL(wl->wl_devvp, DIOCCACHESYNC, &force,
FWRITE, FSCRED);
if (error) {
WAPBL_PRINTF(WAPBL_PRINT_ERROR,
("wapbl_write_commit: DIOCCACHESYNC on dev 0x%x "
"returned %d\n", wl->wl_devvp->v_rdev, error));
}
}
/*
@ -2723,9 +2801,12 @@ wapbl_modcmd(modcmd_t cmd, void *arg)
switch (cmd) {
case MODULE_CMD_INIT:
malloc_type_attach(M_WAPBL);
wapbl_init();
return 0;
case MODULE_CMD_FINI:
#ifdef notyet
return wapbl_fini(true);
#endif
return EOPNOTSUPP;
default:
return ENOTTY;