From 2281065eeeb411cecbefa52be5ac6aae0883e642 Mon Sep 17 00:00:00 2001 From: Matthew Dillon Date: Wed, 29 Dec 2004 02:40:03 +0000 Subject: [PATCH] Journaling layer work. * Adjust the new mountctl syscall to make the passed file descriptor an explicit argument rather then storing the fd in the control structure. Convert the fd to a file pointer to make kern_mountctl() callable from a pure thread. * Get rid of vop_stdmountctl and just have the VOP default ops call journal_mountctl(), which makes things less confusing. * Get more of the journaling infrastructure working. Basic installation and removal of the journaling structure and the creation and destruction of the worker thread and stream file pointer now works (with lots of XXX's). * Add a journaling vector for VOP_NMKDIR to test the journaling VOP ops shim. --- sys/kern/init_sysent.c | 4 +- sys/kern/syscalls.c | 4 +- sys/kern/syscalls.master | 4 +- sys/kern/vfs_default.c | 23 +-- sys/kern/vfs_jops.c | 343 ++++++++++++++++++++++++++++++++++++++- sys/kern/vfs_journal.c | 343 ++++++++++++++++++++++++++++++++++++++- sys/kern/vfs_mount.c | 5 +- sys/kern/vfs_syscalls.c | 30 +++- sys/kern/vfs_vopops.c | 6 +- sys/sys/kern_syscall.h | 5 +- sys/sys/mount.h | 12 +- sys/sys/mountctl.h | 49 +++++- sys/sys/syscall-args | 6 +- sys/sys/syscall-hide.h | 4 +- sys/sys/syscall.h | 4 +- sys/sys/syscall.mk | 4 +- sys/sys/sysproto.h | 5 +- sys/sys/sysunion.h | 4 +- sys/sys/vfsops.h | 7 +- sys/sys/vnode.h | 3 +- 20 files changed, 778 insertions(+), 87 deletions(-) diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index 1a7cb5b9df..4a2f716230 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -2,8 +2,8 @@ * System call switch table. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/kern/init_sysent.c,v 1.19 2004/12/24 05:00:17 dillon Exp $ - * created from DragonFly: src/sys/kern/syscalls.master,v 1.13 2004/11/23 06:32:32 dillon Exp + * $DragonFly: src/sys/kern/init_sysent.c,v 1.20 2004/12/29 02:40:02 dillon Exp $ + * created from DragonFly: src/sys/kern/syscalls.master,v 1.14 2004/12/24 05:00:17 dillon Exp */ #include "opt_compat.h" diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index 53f5e956a2..405752c2bc 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -2,8 +2,8 @@ * System call names. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/kern/syscalls.c,v 1.19 2004/12/24 05:00:17 dillon Exp $ - * created from DragonFly: src/sys/kern/syscalls.master,v 1.13 2004/11/23 06:32:32 dillon Exp + * $DragonFly: src/sys/kern/syscalls.c,v 1.20 2004/12/29 02:40:02 dillon Exp $ + * created from DragonFly: src/sys/kern/syscalls.master,v 1.14 2004/12/24 05:00:17 dillon Exp */ char *syscallnames[] = { diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index e8e11ee404..1591cbc226 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -1,4 +1,4 @@ - $DragonFly: src/sys/kern/syscalls.master,v 1.14 2004/12/24 05:00:17 dillon Exp $ + $DragonFly: src/sys/kern/syscalls.master,v 1.15 2004/12/29 02:40:02 dillon Exp $ ; @(#)syscalls.master 8.2 (Berkeley) 1/13/94 ; $FreeBSD: src/sys/kern/syscalls.master,v 1.72.2.10 2002/07/12 08:22:46 alfred Exp $ @@ -630,4 +630,4 @@ 465 STD BSD { int exec_sys_register(void *entry); } 466 STD BSD { int exec_sys_unregister(int id); } 467 STD BSD { int sys_checkpoint(int type, int fd, pid_t pid, int retval); } -468 STD BSD { int mountctl(char *path, int op, const void *ctl, int ctllen, void *buf, int buflen); } +468 STD BSD { int mountctl(const char *path, int op, int fd, const void *ctl, int ctllen, void *buf, int buflen); } diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c index a55de86b13..71724e0c98 100644 --- a/sys/kern/vfs_default.c +++ b/sys/kern/vfs_default.c @@ -37,7 +37,7 @@ * * * $FreeBSD: src/sys/kern/vfs_default.c,v 1.28.2.7 2003/01/10 18:23:26 bde Exp $ - * $DragonFly: src/sys/kern/vfs_default.c,v 1.24 2004/12/24 05:00:17 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_default.c,v 1.25 2004/12/29 02:40:02 dillon Exp $ */ #include @@ -112,7 +112,7 @@ static struct vnodeopv_entry_desc default_vnodeop_entries[] = { { &vop_nremove_desc, (void *) vop_compat_nremove }, { &vop_nrmdir_desc, (void *) vop_compat_nrmdir }, { &vop_nrename_desc, (void *) vop_compat_nrename }, - { &vop_mountctl_desc, (void *) vop_stdmountctl }, + { &vop_mountctl_desc, (void *) journal_mountctl }, { NULL, NULL } }; @@ -1408,25 +1408,6 @@ vop_stdgetvobject(ap) return (vp->v_object ? 0 : EINVAL); } -/* - * Standard mount controls. These are overridden when the journal is - * installed so we only have to 'bootstrap' the journal installation - * operation here. - */ -int -vop_stdmountctl(struct vop_mountctl_args *ap) -{ - int error = EOPNOTSUPP; - - switch(ap->a_op) { - case MOUNTCTL_INSTALL_VFS_JOURNAL: - case MOUNTCTL_INSTALL_BLK_JOURNAL: - default: - break; - } - return (error); -} - /* * vfs default ops * used to fill the vfs fucntion table to get reasonable default return values. diff --git a/sys/kern/vfs_jops.c b/sys/kern/vfs_jops.c index 2058e27789..82031f11f8 100644 --- a/sys/kern/vfs_jops.c +++ b/sys/kern/vfs_jops.c @@ -31,7 +31,44 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/kern/vfs_jops.c,v 1.2 2004/12/24 05:00:17 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_jops.c,v 1.3 2004/12/29 02:40:02 dillon Exp $ + */ +/* + * Each mount point may have zero or more independantly configured journals + * attached to it. Each journal is represented by a memory FIFO and worker + * thread. Journal events are streamed through the FIFO to the thread, + * batched up (typically on one-second intervals), and written out by the + * thread. + * + * Journal vnode ops are executed instead of mnt_vn_norm_ops when one or + * more journals have been installed on a mount point. It becomes the + * responsibility of the journal op to call the underlying normal op as + * appropriate. + * + * The journaling protocol is intended to evolve into a two-way stream + * whereby transaction IDs can be acknowledged by the journaling target + * when the data has been committed to hard storage. Both implicit and + * explicit acknowledgement schemes will be supported, depending on the + * sophistication of the journaling stream, plus resynchronization and + * restart when a journaling stream is interrupted. This information will + * also be made available to journaling-aware filesystems to allow better + * management of their own physical storage synchronization mechanisms as + * well as to allow such filesystems to take direct advantage of the kernel's + * journaling layer so they don't have to roll their own. + * + * In addition, the journaling thread will have access to much larger + * spooling areas then the memory buffer is able to provide by e.g. + * reserving swap space, in order to absorb potentially long interruptions + * of off-site journaling streams, and to prevent 'slow' off-site linkages + * from radically slowing down local filesystem operations. + * + * Because of the non-trivial algorithms the journaling system will be + * required to support, use of a worker thread is mandatory. Efficiencies + * are maintained by utilitizing the memory FIFO to batch transactions when + * possible, reducing the number of gratuitous thread switches and taking + * advantage of cpu caches through the use of shorter batched code paths + * rather then trying to do everything in the context of the process + * originating the filesystem op. */ #include @@ -45,6 +82,8 @@ #include #include #include +#include +#include #include @@ -54,23 +93,309 @@ #include #include +#include +#include + +static int journal_attach(struct mount *mp); +static void journal_detach(struct mount *mp); +static int journal_install_vfs_journal(struct mount *mp, struct file *fp, + const struct mountctl_install_journal *info); +static int journal_remove_vfs_journal(struct mount *mp, + const struct mountctl_remove_journal *info); +static int journal_resync_vfs_journal(struct mount *mp, const void *ctl); +static void journal_thread(void *info); +static void journal_write_record(struct journal *jo, const char *ctl, + const char *buf, int bytes); +static void journal_write(struct journal *jo, const char *buf, int bytes); + +static int journal_nmkdir(struct vop_nmkdir_args *ap); + static struct vnodeopv_entry_desc journal_vnodeop_entries[] = { - { &vop_default_desc, vop_journal_operate_ap }, -/* { &vop_mountctl_desc, NULL },*/ - { NULL, NULL } + { &vop_default_desc, vop_journal_operate_ap }, + { &vop_mountctl_desc, (void *)journal_mountctl }, + { &vop_nmkdir_desc, (void *)journal_nmkdir }, + { NULL, NULL } }; +static MALLOC_DEFINE(M_JOURNAL, "journal", "Journaling structure"); +static MALLOC_DEFINE(M_JFIFO, "journal-fifo", "Journal FIFO"); + int +journal_mountctl(struct vop_mountctl_args *ap) +{ + struct mount *mp; + int error = 0; + + mp = ap->a_head.a_ops->vv_mount; + KKASSERT(mp); + + if (mp->mnt_vn_journal_ops == NULL) { + switch(ap->a_op) { + case MOUNTCTL_INSTALL_VFS_JOURNAL: + error = journal_attach(mp); + if (error == 0 && ap->a_ctllen != sizeof(struct mountctl_install_journal)) + error = EINVAL; + if (error == 0 && ap->a_fp == NULL) + error = EBADF; + if (error == 0) + error = journal_install_vfs_journal(mp, ap->a_fp, ap->a_ctl); + if (TAILQ_EMPTY(&mp->mnt_jlist)) + journal_detach(mp); + break; + case MOUNTCTL_REMOVE_VFS_JOURNAL: + case MOUNTCTL_RESYNC_VFS_JOURNAL: + error = EINVAL; + break; + default: + error = EOPNOTSUPP; + break; + } + } else { + switch(ap->a_op) { + case MOUNTCTL_INSTALL_VFS_JOURNAL: + if (ap->a_ctllen != sizeof(struct mountctl_install_journal)) + error = EINVAL; + if (error == 0 && ap->a_fp == NULL) + error = EBADF; + if (error == 0) + error = journal_install_vfs_journal(mp, ap->a_fp, ap->a_ctl); + break; + case MOUNTCTL_REMOVE_VFS_JOURNAL: + if (ap->a_ctllen != sizeof(struct mountctl_remove_journal)) + error = EINVAL; + if (error == 0) + error = journal_remove_vfs_journal(mp, ap->a_ctl); + if (TAILQ_EMPTY(&mp->mnt_jlist)) + journal_detach(mp); + break; + case MOUNTCTL_RESYNC_VFS_JOURNAL: + if (ap->a_ctllen != 0) + error = EINVAL; + error = journal_resync_vfs_journal(mp, ap->a_ctl); + break; + default: + error = EOPNOTSUPP; + break; + } + } + return (error); +} + +/* + * High level mount point setup. When a + */ +static int journal_attach(struct mount *mp) { - vfs_add_vnodeops(mp, &mp->mnt_vn_journal_ops, journal_vnodeop_entries); - return(0); + vfs_add_vnodeops(mp, &mp->mnt_vn_journal_ops, journal_vnodeop_entries); + return(0); } -void +static void journal_detach(struct mount *mp) { - if (mp->mnt_vn_journal_ops) - vfs_rm_vnodeops(&mp->mnt_vn_journal_ops); + if (mp->mnt_vn_journal_ops) + vfs_rm_vnodeops(&mp->mnt_vn_journal_ops); +} + +/* + * Install a journal on a mount point + */ +static int +journal_install_vfs_journal(struct mount *mp, struct file *fp, + const struct mountctl_install_journal *info) +{ + struct journal *jo; + int error = 0; + int size; + + jo = malloc(sizeof(struct journal), M_JOURNAL, M_WAITOK|M_ZERO); + bcopy(info->id, jo->id, sizeof(jo->id)); + jo->flags = info->flags & ~(MC_JOURNAL_ACTIVE | MC_JOURNAL_STOP_REQ); + + /* + * Memory FIFO size, round to nearest power of 2 + */ + if (info->flags & MC_JOURNAL_MBSIZE_PROVIDED) { + if (info->membufsize < 65536) + size = 65536; + else if (info->membufsize > 128 * 1024 * 1024) + size = 128 * 1024 * 1024; + else + size = (int)info->membufsize; + } else { + size = 1024 * 1024; + } + jo->fifo.size = 1; + while (jo->fifo.size < size) + jo->fifo.size <<= 1; + + /* + * Other parameters. If not specified the starting transaction id + * will be the current date. + */ + if (info->flags & MC_JOURNAL_TRANSID_PROVIDED) { + jo->transid = info->transid; + } else { + struct timespec ts; + getnanotime(&ts); + jo->transid = ((int64_t)ts.tv_sec << 30) | ts.tv_nsec; + } + + jo->fp = fp; + + /* + * Allocate the memory FIFO + */ + jo->fifo.mask = jo->fifo.size - 1; + jo->fifo.membase = malloc(jo->fifo.size, M_JFIFO, M_WAITOK|M_ZERO|M_NULLOK); + if (jo->fifo.membase == NULL) + error = ENOMEM; + + if (error) { + free(jo, M_JOURNAL); + } else { + fhold(fp); + jo->flags |= MC_JOURNAL_ACTIVE; + lwkt_create(journal_thread, jo, NULL, &jo->thread, + TDF_STOPREQ, -1, "journal %.*s", JIDMAX, jo->id); + lwkt_setpri(&jo->thread, TDPRI_KERN_DAEMON); + lwkt_schedule(&jo->thread); + journal_write_record(jo, "INSTALL", NULL, 0); + + TAILQ_INSERT_TAIL(&mp->mnt_jlist, jo, jentry); + } + return(error); +} + +static int +journal_remove_vfs_journal(struct mount *mp, const struct mountctl_remove_journal *info) +{ + struct journal *jo; + int error; + + TAILQ_FOREACH(jo, &mp->mnt_jlist, jentry) { + if (bcmp(jo->id, info->id, sizeof(jo->id)) == 0) + break; + } + if (jo) { + error = 0; + TAILQ_REMOVE(&mp->mnt_jlist, jo, jentry); + journal_write_record(jo, "REMOVE", NULL, 0); /* XXX sequencing */ + jo->flags |= MC_JOURNAL_STOP_REQ | (info->flags & MC_JOURNAL_STOP_IMM); + wakeup(&jo->fifo); + while (jo->flags & MC_JOURNAL_ACTIVE) { + tsleep(jo, 0, "jwait", 0); + } + lwkt_free_thread(&jo->thread); /* XXX SMP */ + if (jo->fp) + fdrop(jo->fp, curthread); + if (jo->fifo.membase) + free(jo->fifo.membase, M_JFIFO); + free(jo, M_JOURNAL); + } else { + error = EINVAL; + } + return (error); +} + +static int +journal_resync_vfs_journal(struct mount *mp, const void *ctl) +{ + return(EINVAL); +} + +static void +journal_thread(void *info) +{ + struct journal *jo = info; + int bytes; + int error; + int res; + + for (;;) { + bytes = (jo->fifo.windex - jo->fifo.rindex) & jo->fifo.mask; + if (bytes == 0 || (jo->flags & MC_JOURNAL_STOP_IMM)) { + if (jo->flags & MC_JOURNAL_STOP_REQ) + break; + tsleep(&jo->fifo, 0, "jfifo", 0); /* XXX add heartbeat */ + } + if (bytes > jo->fifo.size - jo->fifo.windex) + bytes = jo->fifo.size - jo->fifo.windex; + error = fp_write(jo->fp, jo->fifo.membase + jo->fifo.rindex, bytes, &res); + if (error) { + printf("journal_thread(%s) write, error %d\n", jo->id, error); + jo->fifo.rindex = jo->fifo.windex; /* XXX flag out-of-sync */ + } else { + printf("journal_thread(%s) write %d\n", jo->id, res); + jo->fifo.rindex = (jo->fifo.rindex + res) & jo->fifo.mask; + if (jo->flags & MC_JOURNAL_WWAIT) { + jo->flags &= ~MC_JOURNAL_WWAIT; /* XXX hysteresis */ + wakeup(&jo->fifo.windex); + } + } + } + jo->flags &= ~MC_JOURNAL_ACTIVE; + wakeup(jo); + wakeup(&jo->fifo.windex); +} + +static +void +journal_write_record(struct journal *jo, const char *ctl, + const char *buf, int bytes) +{ + char head[64]; + + if (jo->flags & MC_JOURNAL_STOP_REQ) + return; + snprintf(head, sizeof(head), "%016llx %s\n", jo->transid, ctl); + /* XXX locking (token) or cmpexgl space reservation */ + ++jo->transid; /* XXX embed nanotime, force monotonic */ + journal_write(jo, head, strlen(head)); + if (bytes) + journal_write(jo, buf, bytes); +} + +static +void +journal_write(struct journal *jo, const char *buf, int bytes) +{ + int avail; + + while (bytes && (jo->flags & MC_JOURNAL_ACTIVE)) { + avail = (jo->fifo.windex - jo->fifo.rindex) & jo->fifo.mask; + avail = jo->fifo.size - avail - 1; + if (avail == 0) { + if (jo->flags & MC_JOURNAL_STOP_IMM) + break; + jo->flags |= MC_JOURNAL_WWAIT; + tsleep(&jo->fifo.windex, 0, "jwrite", 0); + continue; + } + if (avail > jo->fifo.size - jo->fifo.windex) + avail = jo->fifo.size - jo->fifo.windex; + if (avail > bytes) + avail = bytes; + bcopy(buf, jo->fifo.membase + jo->fifo.windex, avail); + bytes -= avail; + jo->fifo.windex = (jo->fifo.windex + avail) & jo->fifo.mask; + tsleep(&jo->fifo, 0, "jfifo", 0); /* XXX hysteresis */ + } +} + +/************************************************************************ + * JOURNAL VNOPS * + ************************************************************************/ + +static +int +journal_nmkdir(struct vop_nmkdir_args *ap) +{ + int error; + + printf("JMKDIR %s\n", ap->a_ncp->nc_name); + error = vop_journal_operate_ap(&ap->a_head); + return (error); } diff --git a/sys/kern/vfs_journal.c b/sys/kern/vfs_journal.c index 1f2e997981..68f610145b 100644 --- a/sys/kern/vfs_journal.c +++ b/sys/kern/vfs_journal.c @@ -31,7 +31,44 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/kern/vfs_journal.c,v 1.2 2004/12/24 05:00:17 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_journal.c,v 1.3 2004/12/29 02:40:02 dillon Exp $ + */ +/* + * Each mount point may have zero or more independantly configured journals + * attached to it. Each journal is represented by a memory FIFO and worker + * thread. Journal events are streamed through the FIFO to the thread, + * batched up (typically on one-second intervals), and written out by the + * thread. + * + * Journal vnode ops are executed instead of mnt_vn_norm_ops when one or + * more journals have been installed on a mount point. It becomes the + * responsibility of the journal op to call the underlying normal op as + * appropriate. + * + * The journaling protocol is intended to evolve into a two-way stream + * whereby transaction IDs can be acknowledged by the journaling target + * when the data has been committed to hard storage. Both implicit and + * explicit acknowledgement schemes will be supported, depending on the + * sophistication of the journaling stream, plus resynchronization and + * restart when a journaling stream is interrupted. This information will + * also be made available to journaling-aware filesystems to allow better + * management of their own physical storage synchronization mechanisms as + * well as to allow such filesystems to take direct advantage of the kernel's + * journaling layer so they don't have to roll their own. + * + * In addition, the journaling thread will have access to much larger + * spooling areas then the memory buffer is able to provide by e.g. + * reserving swap space, in order to absorb potentially long interruptions + * of off-site journaling streams, and to prevent 'slow' off-site linkages + * from radically slowing down local filesystem operations. + * + * Because of the non-trivial algorithms the journaling system will be + * required to support, use of a worker thread is mandatory. Efficiencies + * are maintained by utilitizing the memory FIFO to batch transactions when + * possible, reducing the number of gratuitous thread switches and taking + * advantage of cpu caches through the use of shorter batched code paths + * rather then trying to do everything in the context of the process + * originating the filesystem op. */ #include @@ -45,6 +82,8 @@ #include #include #include +#include +#include #include @@ -54,23 +93,309 @@ #include #include +#include +#include + +static int journal_attach(struct mount *mp); +static void journal_detach(struct mount *mp); +static int journal_install_vfs_journal(struct mount *mp, struct file *fp, + const struct mountctl_install_journal *info); +static int journal_remove_vfs_journal(struct mount *mp, + const struct mountctl_remove_journal *info); +static int journal_resync_vfs_journal(struct mount *mp, const void *ctl); +static void journal_thread(void *info); +static void journal_write_record(struct journal *jo, const char *ctl, + const char *buf, int bytes); +static void journal_write(struct journal *jo, const char *buf, int bytes); + +static int journal_nmkdir(struct vop_nmkdir_args *ap); + static struct vnodeopv_entry_desc journal_vnodeop_entries[] = { - { &vop_default_desc, vop_journal_operate_ap }, -/* { &vop_mountctl_desc, NULL },*/ - { NULL, NULL } + { &vop_default_desc, vop_journal_operate_ap }, + { &vop_mountctl_desc, (void *)journal_mountctl }, + { &vop_nmkdir_desc, (void *)journal_nmkdir }, + { NULL, NULL } }; +static MALLOC_DEFINE(M_JOURNAL, "journal", "Journaling structure"); +static MALLOC_DEFINE(M_JFIFO, "journal-fifo", "Journal FIFO"); + int +journal_mountctl(struct vop_mountctl_args *ap) +{ + struct mount *mp; + int error = 0; + + mp = ap->a_head.a_ops->vv_mount; + KKASSERT(mp); + + if (mp->mnt_vn_journal_ops == NULL) { + switch(ap->a_op) { + case MOUNTCTL_INSTALL_VFS_JOURNAL: + error = journal_attach(mp); + if (error == 0 && ap->a_ctllen != sizeof(struct mountctl_install_journal)) + error = EINVAL; + if (error == 0 && ap->a_fp == NULL) + error = EBADF; + if (error == 0) + error = journal_install_vfs_journal(mp, ap->a_fp, ap->a_ctl); + if (TAILQ_EMPTY(&mp->mnt_jlist)) + journal_detach(mp); + break; + case MOUNTCTL_REMOVE_VFS_JOURNAL: + case MOUNTCTL_RESYNC_VFS_JOURNAL: + error = EINVAL; + break; + default: + error = EOPNOTSUPP; + break; + } + } else { + switch(ap->a_op) { + case MOUNTCTL_INSTALL_VFS_JOURNAL: + if (ap->a_ctllen != sizeof(struct mountctl_install_journal)) + error = EINVAL; + if (error == 0 && ap->a_fp == NULL) + error = EBADF; + if (error == 0) + error = journal_install_vfs_journal(mp, ap->a_fp, ap->a_ctl); + break; + case MOUNTCTL_REMOVE_VFS_JOURNAL: + if (ap->a_ctllen != sizeof(struct mountctl_remove_journal)) + error = EINVAL; + if (error == 0) + error = journal_remove_vfs_journal(mp, ap->a_ctl); + if (TAILQ_EMPTY(&mp->mnt_jlist)) + journal_detach(mp); + break; + case MOUNTCTL_RESYNC_VFS_JOURNAL: + if (ap->a_ctllen != 0) + error = EINVAL; + error = journal_resync_vfs_journal(mp, ap->a_ctl); + break; + default: + error = EOPNOTSUPP; + break; + } + } + return (error); +} + +/* + * High level mount point setup. When a + */ +static int journal_attach(struct mount *mp) { - vfs_add_vnodeops(mp, &mp->mnt_vn_journal_ops, journal_vnodeop_entries); - return(0); + vfs_add_vnodeops(mp, &mp->mnt_vn_journal_ops, journal_vnodeop_entries); + return(0); } -void +static void journal_detach(struct mount *mp) { - if (mp->mnt_vn_journal_ops) - vfs_rm_vnodeops(&mp->mnt_vn_journal_ops); + if (mp->mnt_vn_journal_ops) + vfs_rm_vnodeops(&mp->mnt_vn_journal_ops); +} + +/* + * Install a journal on a mount point + */ +static int +journal_install_vfs_journal(struct mount *mp, struct file *fp, + const struct mountctl_install_journal *info) +{ + struct journal *jo; + int error = 0; + int size; + + jo = malloc(sizeof(struct journal), M_JOURNAL, M_WAITOK|M_ZERO); + bcopy(info->id, jo->id, sizeof(jo->id)); + jo->flags = info->flags & ~(MC_JOURNAL_ACTIVE | MC_JOURNAL_STOP_REQ); + + /* + * Memory FIFO size, round to nearest power of 2 + */ + if (info->flags & MC_JOURNAL_MBSIZE_PROVIDED) { + if (info->membufsize < 65536) + size = 65536; + else if (info->membufsize > 128 * 1024 * 1024) + size = 128 * 1024 * 1024; + else + size = (int)info->membufsize; + } else { + size = 1024 * 1024; + } + jo->fifo.size = 1; + while (jo->fifo.size < size) + jo->fifo.size <<= 1; + + /* + * Other parameters. If not specified the starting transaction id + * will be the current date. + */ + if (info->flags & MC_JOURNAL_TRANSID_PROVIDED) { + jo->transid = info->transid; + } else { + struct timespec ts; + getnanotime(&ts); + jo->transid = ((int64_t)ts.tv_sec << 30) | ts.tv_nsec; + } + + jo->fp = fp; + + /* + * Allocate the memory FIFO + */ + jo->fifo.mask = jo->fifo.size - 1; + jo->fifo.membase = malloc(jo->fifo.size, M_JFIFO, M_WAITOK|M_ZERO|M_NULLOK); + if (jo->fifo.membase == NULL) + error = ENOMEM; + + if (error) { + free(jo, M_JOURNAL); + } else { + fhold(fp); + jo->flags |= MC_JOURNAL_ACTIVE; + lwkt_create(journal_thread, jo, NULL, &jo->thread, + TDF_STOPREQ, -1, "journal %.*s", JIDMAX, jo->id); + lwkt_setpri(&jo->thread, TDPRI_KERN_DAEMON); + lwkt_schedule(&jo->thread); + journal_write_record(jo, "INSTALL", NULL, 0); + + TAILQ_INSERT_TAIL(&mp->mnt_jlist, jo, jentry); + } + return(error); +} + +static int +journal_remove_vfs_journal(struct mount *mp, const struct mountctl_remove_journal *info) +{ + struct journal *jo; + int error; + + TAILQ_FOREACH(jo, &mp->mnt_jlist, jentry) { + if (bcmp(jo->id, info->id, sizeof(jo->id)) == 0) + break; + } + if (jo) { + error = 0; + TAILQ_REMOVE(&mp->mnt_jlist, jo, jentry); + journal_write_record(jo, "REMOVE", NULL, 0); /* XXX sequencing */ + jo->flags |= MC_JOURNAL_STOP_REQ | (info->flags & MC_JOURNAL_STOP_IMM); + wakeup(&jo->fifo); + while (jo->flags & MC_JOURNAL_ACTIVE) { + tsleep(jo, 0, "jwait", 0); + } + lwkt_free_thread(&jo->thread); /* XXX SMP */ + if (jo->fp) + fdrop(jo->fp, curthread); + if (jo->fifo.membase) + free(jo->fifo.membase, M_JFIFO); + free(jo, M_JOURNAL); + } else { + error = EINVAL; + } + return (error); +} + +static int +journal_resync_vfs_journal(struct mount *mp, const void *ctl) +{ + return(EINVAL); +} + +static void +journal_thread(void *info) +{ + struct journal *jo = info; + int bytes; + int error; + int res; + + for (;;) { + bytes = (jo->fifo.windex - jo->fifo.rindex) & jo->fifo.mask; + if (bytes == 0 || (jo->flags & MC_JOURNAL_STOP_IMM)) { + if (jo->flags & MC_JOURNAL_STOP_REQ) + break; + tsleep(&jo->fifo, 0, "jfifo", 0); /* XXX add heartbeat */ + } + if (bytes > jo->fifo.size - jo->fifo.windex) + bytes = jo->fifo.size - jo->fifo.windex; + error = fp_write(jo->fp, jo->fifo.membase + jo->fifo.rindex, bytes, &res); + if (error) { + printf("journal_thread(%s) write, error %d\n", jo->id, error); + jo->fifo.rindex = jo->fifo.windex; /* XXX flag out-of-sync */ + } else { + printf("journal_thread(%s) write %d\n", jo->id, res); + jo->fifo.rindex = (jo->fifo.rindex + res) & jo->fifo.mask; + if (jo->flags & MC_JOURNAL_WWAIT) { + jo->flags &= ~MC_JOURNAL_WWAIT; /* XXX hysteresis */ + wakeup(&jo->fifo.windex); + } + } + } + jo->flags &= ~MC_JOURNAL_ACTIVE; + wakeup(jo); + wakeup(&jo->fifo.windex); +} + +static +void +journal_write_record(struct journal *jo, const char *ctl, + const char *buf, int bytes) +{ + char head[64]; + + if (jo->flags & MC_JOURNAL_STOP_REQ) + return; + snprintf(head, sizeof(head), "%016llx %s\n", jo->transid, ctl); + /* XXX locking (token) or cmpexgl space reservation */ + ++jo->transid; /* XXX embed nanotime, force monotonic */ + journal_write(jo, head, strlen(head)); + if (bytes) + journal_write(jo, buf, bytes); +} + +static +void +journal_write(struct journal *jo, const char *buf, int bytes) +{ + int avail; + + while (bytes && (jo->flags & MC_JOURNAL_ACTIVE)) { + avail = (jo->fifo.windex - jo->fifo.rindex) & jo->fifo.mask; + avail = jo->fifo.size - avail - 1; + if (avail == 0) { + if (jo->flags & MC_JOURNAL_STOP_IMM) + break; + jo->flags |= MC_JOURNAL_WWAIT; + tsleep(&jo->fifo.windex, 0, "jwrite", 0); + continue; + } + if (avail > jo->fifo.size - jo->fifo.windex) + avail = jo->fifo.size - jo->fifo.windex; + if (avail > bytes) + avail = bytes; + bcopy(buf, jo->fifo.membase + jo->fifo.windex, avail); + bytes -= avail; + jo->fifo.windex = (jo->fifo.windex + avail) & jo->fifo.mask; + tsleep(&jo->fifo, 0, "jfifo", 0); /* XXX hysteresis */ + } +} + +/************************************************************************ + * JOURNAL VNOPS * + ************************************************************************/ + +static +int +journal_nmkdir(struct vop_nmkdir_args *ap) +{ + int error; + + printf("JMKDIR %s\n", ap->a_ncp->nc_name); + error = vop_journal_operate_ap(&ap->a_head); + return (error); } diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index 08c8fb6497..00ffabd29a 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -67,7 +67,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/kern/vfs_mount.c,v 1.3 2004/12/17 00:18:07 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_mount.c,v 1.4 2004/12/29 02:40:02 dillon Exp $ */ /* @@ -255,12 +255,13 @@ vfs_rootmountalloc(char *fstypename, char *devname, struct mount **mpp) } if (vfsp == NULL) return (ENODEV); - mp = malloc((u_long)sizeof(struct mount), M_MOUNT, M_WAITOK); + mp = malloc(sizeof(struct mount), M_MOUNT, M_WAITOK); bzero((char *)mp, (u_long)sizeof(struct mount)); lockinit(&mp->mnt_lock, 0, "vfslock", VLKTIMEOUT, LK_NOPAUSE); vfs_busy(mp, LK_NOWAIT, NULL, td); TAILQ_INIT(&mp->mnt_nvnodelist); TAILQ_INIT(&mp->mnt_reservedvnlist); + TAILQ_INIT(&mp->mnt_jlist); mp->mnt_nvnodelistsize = 0; mp->mnt_vfc = vfsp; mp->mnt_op = vfsp->vfc_vfsops; diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 0b2d306430..5a0cf97a88 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -37,7 +37,7 @@ * * @(#)vfs_syscalls.c 8.13 (Berkeley) 4/15/94 * $FreeBSD: src/sys/kern/vfs_syscalls.c,v 1.151.2.18 2003/04/04 20:35:58 tegge Exp $ - * $DragonFly: src/sys/kern/vfs_syscalls.c,v 1.51 2004/12/28 04:39:59 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_syscalls.c,v 1.52 2004/12/29 02:40:02 dillon Exp $ */ #include @@ -290,6 +290,7 @@ mount(struct mount_args *uap) mp = malloc(sizeof(struct mount), M_MOUNT, M_ZERO|M_WAITOK); TAILQ_INIT(&mp->mnt_nvnodelist); TAILQ_INIT(&mp->mnt_reservedvnlist); + TAILQ_INIT(&mp->mnt_jlist); mp->mnt_nvnodelistsize = 0; lockinit(&mp->mnt_lock, 0, "vfslock", 0, LK_NOPAUSE); vfs_busy(mp, LK_NOWAIT, NULL, td); @@ -671,7 +672,7 @@ quotactl(struct quotactl_args *uap) } /* - * mountctl(char *path, int op, const void *ctl, int ctllen, + * mountctl(char *path, int op, int fd, const void *ctl, int ctllen, * void *buf, int buflen) * * This function operates on a mount point and executes the specified @@ -686,6 +687,8 @@ mountctl(struct mountctl_args *uap) { struct thread *td = curthread; struct proc *p = td->td_proc; + struct filedesc *fdp = p->p_fd; + struct file *fp; void *ctl = NULL; void *buf = NULL; char *path = NULL; @@ -727,10 +730,25 @@ mountctl(struct mountctl_args *uap) if (uap->buflen) buf = malloc(uap->buflen + 1, M_TEMP, M_WAITOK|M_ZERO); + /* + * Validate the descriptor + */ + if (uap->fd == -1) { + fp = NULL; + } else if ((u_int)uap->fd >= fdp->fd_nfiles || + (fp = fdp->fd_ofiles[uap->fd]) == NULL) { + error = EBADF; + goto done; + } + if (fp) + fhold(fp); + /* * Execute the internal kernel function and clean up. */ - error = kern_mountctl(path, uap->op, ctl, uap->ctllen, buf, uap->buflen, &uap->sysmsg_result); + error = kern_mountctl(path, uap->op, fp, ctl, uap->ctllen, buf, uap->buflen, &uap->sysmsg_result); + if (fp) + fdrop(fp, td); if (error == 0 && uap->sysmsg_result > 0) error = copyout(buf, uap->buf, uap->sysmsg_result); done: @@ -748,10 +766,10 @@ done: * and calling vop_mountctl(). */ int -kern_mountctl(const char *path, int op, const void *ctl, int ctllen, +kern_mountctl(const char *path, int op, struct file *fp, + const void *ctl, int ctllen, void *buf, int buflen, int *res) { - struct thread *td = curthread; struct vnode *vp; struct mount *mp; struct nlookupdata nd; @@ -777,7 +795,7 @@ kern_mountctl(const char *path, int op, const void *ctl, int ctllen, vput(vp); return (EINVAL); } - error = vop_mountctl(mp->mnt_vn_use_ops, op, ctl, ctllen, + error = vop_mountctl(mp->mnt_vn_use_ops, op, fp, ctl, ctllen, buf, buflen, res); vput(vp); return (error); diff --git a/sys/kern/vfs_vopops.c b/sys/kern/vfs_vopops.c index a60cf6448b..0756cf1fc4 100644 --- a/sys/kern/vfs_vopops.c +++ b/sys/kern/vfs_vopops.c @@ -32,7 +32,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/kern/vfs_vopops.c,v 1.12 2004/12/24 05:00:17 dillon Exp $ + * $DragonFly: src/sys/kern/vfs_vopops.c,v 1.13 2004/12/29 02:40:02 dillon Exp $ */ #include @@ -1176,7 +1176,8 @@ vop_getvobject(struct vop_ops *ops, struct vnode *vp, struct vm_object **objpp) } int -vop_mountctl(struct vop_ops *ops, int op, const void *ctl, int ctllen, void *buf, int buflen, int *res) +vop_mountctl(struct vop_ops *ops, int op, struct file *fp, + const void *ctl, int ctllen, void *buf, int buflen, int *res) { struct vop_mountctl_args ap; int error; @@ -1185,6 +1186,7 @@ vop_mountctl(struct vop_ops *ops, int op, const void *ctl, int ctllen, void *buf ap.a_head.a_ops = ops; ap.a_op = op; ap.a_ctl = ctl; + ap.a_fp = fp; ap.a_ctllen = ctllen; ap.a_buf = buf; ap.a_buflen = buflen; diff --git a/sys/sys/kern_syscall.h b/sys/sys/kern_syscall.h index 0eda929280..25d768d96a 100644 --- a/sys/sys/kern_syscall.h +++ b/sys/sys/kern_syscall.h @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/sys/kern_syscall.h,v 1.22 2004/12/24 05:00:22 dillon Exp $ + * $DragonFly: src/sys/sys/kern_syscall.h,v 1.23 2004/12/29 02:40:03 dillon Exp $ */ #ifndef _SYS_KERN_SYSCALL_H_ @@ -128,7 +128,8 @@ int kern_futimes(int fd, struct timeval *tptr); int kern_getdirentries(int fd, char *buf, u_int count, long *basep, int *res); int kern_link(struct nlookupdata *nd, struct nlookupdata *linknd); int kern_lseek(int fd, off_t offset, int whence, off_t *res); -int kern_mountctl(const char *path, int op, const void *ctl, int ctllen, +int kern_mountctl(const char *path, int op, struct file *fp, + const void *ctl, int ctllen, void *buf, int buflen, int *res); int kern_mkdir(struct nlookupdata *nd, int mode); int kern_mkfifo(struct nlookupdata *nd, int mode); diff --git a/sys/sys/mount.h b/sys/sys/mount.h index a9eb54cf46..2a2d74a594 100644 --- a/sys/sys/mount.h +++ b/sys/sys/mount.h @@ -32,7 +32,7 @@ * * @(#)mount.h 8.21 (Berkeley) 5/20/95 * $FreeBSD: src/sys/sys/mount.h,v 1.89.2.7 2003/04/04 20:35:57 tegge Exp $ - * $DragonFly: src/sys/sys/mount.h,v 1.15 2004/12/17 00:18:09 dillon Exp $ + * $DragonFly: src/sys/sys/mount.h,v 1.16 2004/12/29 02:40:03 dillon Exp $ */ #ifndef _SYS_MOUNT_H_ @@ -52,7 +52,9 @@ #endif struct thread; +struct journal; struct vop_ops; +struct vop_mountctl_args; typedef struct fsid { int32_t val[2]; } fsid_t; /* file system id type */ @@ -128,6 +130,7 @@ struct statfs { * vector via namecache->nc_mount. */ TAILQ_HEAD(vnodelst, vnode); +TAILQ_HEAD(journallst, journal); struct mount { TAILQ_ENTRY(mount) mnt_list; /* mount list */ @@ -161,7 +164,10 @@ struct mount { struct vop_ops *mnt_vn_spec_ops; /* for use by the VFS */ struct vop_ops *mnt_vn_fifo_ops; /* for use by the VFS */ struct namecache *mnt_ncp; /* NCF_MNTPT ncp */ + + struct journallst mnt_jlist; /* list of active journals */ }; + #endif /* _KERNEL || _KERNEL_STRUCTURES */ /* @@ -511,6 +517,7 @@ int vfs_stdinit (struct vfsconf *); int vfs_stduninit (struct vfsconf *); int vfs_stdextattrctl (struct mount *mp, int cmd, const char *attrname, caddr_t arg, struct thread *p); +int journal_mountctl(struct vop_mountctl_args *ap); #else /* !_KERNEL */ @@ -528,9 +535,6 @@ int fhopen (const struct fhandle *, int); int fhstat (const struct fhandle *, struct stat *); int fhstatfs (const struct fhandle *, struct statfs *); -int journal_attach(struct mount *mp); -int journal_detach(struct mount *mp); - /* C library stuff */ void endvfsent (void); struct ovfsconf *getvfsbyname (const char *); diff --git a/sys/sys/mountctl.h b/sys/sys/mountctl.h index e42ae0db4c..29f9b2b7d6 100644 --- a/sys/sys/mountctl.h +++ b/sys/sys/mountctl.h @@ -31,9 +31,15 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/sys/mountctl.h,v 1.1 2004/12/24 05:00:22 dillon Exp $ + * $DragonFly: src/sys/sys/mountctl.h,v 1.2 2004/12/29 02:40:03 dillon Exp $ */ +/* + * General constants + */ + +#define JIDMAX 32 /* id string buf[] size (incls \0) */ + /* * Data structures for the journaling API */ @@ -49,9 +55,8 @@ #define MOUNTCTL_JOURNAL_BLK_STATUS 11 struct mountctl_install_journal { - int id; /* journal identifier */ + char id[JIDMAX]; int flags; /* journaling flags */ - int fd; /* streaming descriptor (-1 to close) */ int unused01; int64_t membufsize; /* backing store */ int64_t swapbufsize; /* backing store */ @@ -65,9 +70,11 @@ struct mountctl_install_journal { #define MC_JOURNAL_REVERSABLE 0x00000001 /* reversable log */ #define MC_JOURNAL_BINARY 0x00000002 /* use binary format */ -#define MC_JOURNAL_UNUSED04 0x00000004 +#define MC_JOURNAL_ACTIVE 0x00000004 /* journal is active */ #define MC_JOURNAL_STREAM_TWO_WAY 0x00000008 /* trans id ack */ -#define MC_JOURNAL_FD_PROVIDED 0x00000100 /* stream desc */ +#define MC_JOURNAL_STOP_REQ 0x00000010 /* stop request pend */ +#define MC_JOURNAL_STOP_IMM 0x00000020 /* do not flush */ +#define MC_JOURNAL_WWAIT 0x00000040 /* write stall */ #define MC_JOURNAL_MBSIZE_PROVIDED 0x00000200 /* data space */ #define MC_JOURNAL_SWSIZE_PROVIDED 0x00000400 /* data space */ #define MC_JOURNAL_TRANSID_PROVIDED 0x00000800 /* restart transid */ @@ -75,7 +82,7 @@ struct mountctl_install_journal { #define MC_JOURNAL_STALLERROR_PROVIDED 0x00002000 /* restart transid */ struct mountctl_remove_journal { - int id; + char id[JIDMAX]; int flags; }; @@ -83,9 +90,8 @@ struct mountctl_remove_journal { #define MC_JOURNAL_REMOVE_ASSYNC 0x00000002 /* asynchronous op */ struct mountctl_journal_status { - int id; + char id[JIDMAX]; int flags; - int fd; int64_t membufsize; int64_t membufused; int64_t membufqueued; @@ -103,4 +109,31 @@ struct mountctl_journal_status { #define MC_JOURNAL_STATUS_NEXT 0x80000000 /* find next id */ +#if defined(_KERNEL) || defined(_KERNEL_STRUCTURES) + +/* + * Support structures for the generic journaling structure + */ +struct journal_memfifo { + int size; /* size (power of two) */ + int mask; /* index mask (size - 1) */ + int rindex; /* stream reader index */ + int xindex; /* last acked / reader restart */ + int windex; /* stream writer index */ + char *membase; /* memory buffer representing the FIFO */ +}; + +/* + * Generic journaling structure attached to a mount point. + */ +struct journal { + TAILQ_ENTRY(journal) jentry; + struct file *fp; + char id[JIDMAX]; + int flags; /* journaling flags */ + int64_t transid; + struct journal_memfifo fifo; + struct thread thread; +}; +#endif diff --git a/sys/sys/syscall-args b/sys/sys/syscall-args index d90b0036ae..72506406cb 100644 --- a/sys/sys/syscall-args +++ b/sys/sys/syscall-args @@ -1,8 +1,8 @@ # System call argument table. # DO NOT EDIT-- this file is automatically generated. -# $DragonFly: src/sys/sys/Attic/syscall-args,v 1.3 2004/12/24 05:00:22 dillon Exp $ +# $DragonFly: src/sys/sys/Attic/syscall-args,v 1.4 2004/12/29 02:40:03 dillon Exp $ -# Created from DragonFly: src/sys/kern/syscalls.master,v 1.13 2004/11/23 06:32:32 dillon Exp +# Created from DragonFly: src/sys/kern/syscalls.master,v 1.14 2004/12/24 05:00:17 dillon Exp int syscall nosys nosys_args void exit sys_exit sys_exit_args int rval @@ -255,4 +255,4 @@ int caps_sys_setgen caps_sys_setgen caps_sys_setgen_args int portid off_t gen int exec_sys_register exec_sys_register exec_sys_register_args void * entry int exec_sys_unregister exec_sys_unregister exec_sys_unregister_args int id int sys_checkpoint sys_checkpoint sys_checkpoint_args int type int fd pid_t pid int retval -int mountctl mountctl mountctl_args char * path int op const void * ctl int ctllen void * buf int buflen +int mountctl mountctl mountctl_args char * path int op int fd const void * ctl int ctllen void * buf int buflen diff --git a/sys/sys/syscall-hide.h b/sys/sys/syscall-hide.h index 7b8dbd26b4..ccdc232ad3 100644 --- a/sys/sys/syscall-hide.h +++ b/sys/sys/syscall-hide.h @@ -2,8 +2,8 @@ * System call hiders. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/sys/syscall-hide.h,v 1.20 2004/12/24 05:00:22 dillon Exp $ - * created from DragonFly: src/sys/kern/syscalls.master,v 1.13 2004/11/23 06:32:32 dillon Exp + * $DragonFly: src/sys/sys/syscall-hide.h,v 1.21 2004/12/29 02:40:03 dillon Exp $ + * created from DragonFly: src/sys/kern/syscalls.master,v 1.14 2004/12/24 05:00:17 dillon Exp */ HIDE_POSIX(fork) diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h index b065a18c33..52cb4c9498 100644 --- a/sys/sys/syscall.h +++ b/sys/sys/syscall.h @@ -2,8 +2,8 @@ * System call numbers. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/sys/syscall.h,v 1.20 2004/12/24 05:00:22 dillon Exp $ - * created from DragonFly: src/sys/kern/syscalls.master,v 1.13 2004/11/23 06:32:32 dillon Exp + * $DragonFly: src/sys/sys/syscall.h,v 1.21 2004/12/29 02:40:03 dillon Exp $ + * created from DragonFly: src/sys/kern/syscalls.master,v 1.14 2004/12/24 05:00:17 dillon Exp */ #define SYS_syscall 0 diff --git a/sys/sys/syscall.mk b/sys/sys/syscall.mk index 8bab9c1cb2..0ead23388b 100644 --- a/sys/sys/syscall.mk +++ b/sys/sys/syscall.mk @@ -1,7 +1,7 @@ # DragonFly system call names. # DO NOT EDIT-- this file is automatically generated. -# $DragonFly: src/sys/sys/syscall.mk,v 1.20 2004/12/24 05:00:22 dillon Exp $ -# created from DragonFly: src/sys/kern/syscalls.master,v 1.13 2004/11/23 06:32:32 dillon Exp +# $DragonFly: src/sys/sys/syscall.mk,v 1.21 2004/12/29 02:40:03 dillon Exp $ +# created from DragonFly: src/sys/kern/syscalls.master,v 1.14 2004/12/24 05:00:17 dillon Exp MIASM = \ syscall.o \ exit.o \ diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h index ba6203f02d..84c3a618df 100644 --- a/sys/sys/sysproto.h +++ b/sys/sys/sysproto.h @@ -2,8 +2,8 @@ * System call prototypes. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/sys/sysproto.h,v 1.20 2004/12/24 05:00:22 dillon Exp $ - * created from DragonFly: src/sys/kern/syscalls.master,v 1.13 2004/11/23 06:32:32 dillon Exp + * $DragonFly: src/sys/sys/sysproto.h,v 1.21 2004/12/29 02:40:03 dillon Exp $ + * created from DragonFly: src/sys/kern/syscalls.master,v 1.14 2004/12/24 05:00:17 dillon Exp */ #ifndef _SYS_SYSPROTO_H_ @@ -2129,6 +2129,7 @@ struct mountctl_args { union usrmsg usrmsg; char * path; char path_[PAD_(char *)]; int op; char op_[PAD_(int)]; + int fd; char fd_[PAD_(int)]; const void * ctl; char ctl_[PAD_(const void *)]; int ctllen; char ctllen_[PAD_(int)]; void * buf; char buf_[PAD_(void *)]; diff --git a/sys/sys/sysunion.h b/sys/sys/sysunion.h index 3e3fb37128..b22b709f80 100644 --- a/sys/sys/sysunion.h +++ b/sys/sys/sysunion.h @@ -2,8 +2,8 @@ * Union of syscall args for messaging. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/sys/sysunion.h,v 1.17 2004/12/24 05:00:22 dillon Exp $ - * created from DragonFly: src/sys/kern/syscalls.master,v 1.13 2004/11/23 06:32:32 dillon Exp + * $DragonFly: src/sys/sys/sysunion.h,v 1.18 2004/12/29 02:40:03 dillon Exp $ + * created from DragonFly: src/sys/kern/syscalls.master,v 1.14 2004/12/24 05:00:17 dillon Exp */ union sysunion { diff --git a/sys/sys/vfsops.h b/sys/sys/vfsops.h index 44c6e01c82..3fbd4161eb 100644 --- a/sys/sys/vfsops.h +++ b/sys/sys/vfsops.h @@ -31,7 +31,7 @@ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/sys/vfsops.h,v 1.11 2004/12/24 05:00:22 dillon Exp $ + * $DragonFly: src/sys/sys/vfsops.h,v 1.12 2004/12/29 02:40:03 dillon Exp $ */ /* @@ -473,6 +473,7 @@ struct vop_getvobject_args { struct vop_mountctl_args { struct vop_generic_args a_head; int a_op; + struct file *a_fp; const void *a_ctl; int a_ctllen; void *a_buf; @@ -850,8 +851,8 @@ int vop_createvobject(struct vop_ops *ops, int vop_destroyvobject(struct vop_ops *ops, struct vnode *vp); int vop_getvobject(struct vop_ops *ops, struct vnode *vp, struct vm_object **objpp); -int vop_mountctl(struct vop_ops *ops, int op, const void *ctl, int ctllen, void *buf, int buflen, int *res); - +int vop_mountctl(struct vop_ops *ops, int op, struct file *fp, + const void *ctl, int ctllen, void *buf, int buflen, int *res); int vop_nresolve(struct vop_ops *ops, struct namecache *ncp, struct ucred *cred); int vop_nlookupdotdot(struct vop_ops *ops, struct vnode *dvp, diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h index 1fe4235648..95898654b2 100644 --- a/sys/sys/vnode.h +++ b/sys/sys/vnode.h @@ -32,7 +32,7 @@ * * @(#)vnode.h 8.7 (Berkeley) 2/4/94 * $FreeBSD: src/sys/sys/vnode.h,v 1.111.2.19 2002/12/29 18:19:53 dillon Exp $ - * $DragonFly: src/sys/sys/vnode.h,v 1.29 2004/12/24 05:00:22 dillon Exp $ + * $DragonFly: src/sys/sys/vnode.h,v 1.30 2004/12/29 02:40:03 dillon Exp $ */ #ifndef _SYS_VNODE_H_ @@ -649,7 +649,6 @@ int vn_writechk (struct vnode *vp); int vop_stdbwrite (struct vop_bwrite_args *ap); int vop_stdislocked (struct vop_islocked_args *ap); int vop_stdlock (struct vop_lock_args *ap); -int vop_stdmountctl (struct vop_mountctl_args *ap); int vop_stdrlock (struct vop_lock_args *ap); int vop_stdunlock (struct vop_unlock_args *ap); int vop_nopoll (struct vop_poll_args *ap); -- 2.41.0