Journaling layer work.
authorMatthew Dillon <dillon@dragonflybsd.org>
Wed, 29 Dec 2004 02:40:03 +0000 (02:40 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Wed, 29 Dec 2004 02:40:03 +0000 (02:40 +0000)
* 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.

20 files changed:
sys/kern/init_sysent.c
sys/kern/syscalls.c
sys/kern/syscalls.master
sys/kern/vfs_default.c
sys/kern/vfs_jops.c
sys/kern/vfs_journal.c
sys/kern/vfs_mount.c
sys/kern/vfs_syscalls.c
sys/kern/vfs_vopops.c
sys/sys/kern_syscall.h
sys/sys/mount.h
sys/sys/mountctl.h
sys/sys/syscall-args
sys/sys/syscall-hide.h
sys/sys/syscall.h
sys/sys/syscall.mk
sys/sys/sysproto.h
sys/sys/sysunion.h
sys/sys/vfsops.h
sys/sys/vnode.h

index 1a7cb5b..4a2f716 100644 (file)
@@ -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"
index 53f5e95..405752c 100644 (file)
@@ -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[] = {
index e8e11ee..1591cbc 100644 (file)
@@ -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 $
 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); }
index a55de86..71724e0 100644 (file)
@@ -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 <sys/param.h>
@@ -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.
index 2058e27..82031f1 100644 (file)
  * 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 <sys/param.h>
@@ -45,6 +82,8 @@
 #include <sys/unistd.h>
 #include <sys/vnode.h>
 #include <sys/poll.h>
+#include <sys/mountctl.h>
+#include <sys/file.h>
 
 #include <machine/limits.h>
 
 #include <vm/vm_pager.h>
 #include <vm/vnode_pager.h>
 
+#include <sys/file2.h>
+#include <sys/thread2.h>
+
+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);
 }
 
index 1f2e997..68f6101 100644 (file)
  * 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 <sys/param.h>
@@ -45,6 +82,8 @@
 #include <sys/unistd.h>
 #include <sys/vnode.h>
 #include <sys/poll.h>
+#include <sys/mountctl.h>
+#include <sys/file.h>
 
 #include <machine/limits.h>
 
 #include <vm/vm_pager.h>
 #include <vm/vnode_pager.h>
 
+#include <sys/file2.h>
+#include <sys/thread2.h>
+
+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);
 }
 
index 08c8fb6..00ffabd 100644 (file)
@@ -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;
index 0b2d306..5a0cf97 100644 (file)
@@ -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 <sys/param.h>
@@ -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;
@@ -728,9 +731,24 @@ mountctl(struct mountctl_args *uap)
                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);
index a60cf64..0756cf1 100644 (file)
@@ -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 <sys/param.h>
@@ -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;
index 0eda929..25d768d 100644 (file)
@@ -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);
index a9eb54c..2a2d74a 100644 (file)
@@ -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 *);
index e42ae0d..29f9b2b 100644 (file)
  * 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
index d90b003..7250640 100644 (file)
@@ -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
index 7b8dbd2..ccdc232 100644 (file)
@@ -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)
index b065a18..52cb4c9 100644 (file)
@@ -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
index 8bab9c1..0ead233 100644 (file)
@@ -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 \
index ba6203f..84c3a61 100644 (file)
@@ -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 *)];
index 3e3fb37..b22b709 100644 (file)
@@ -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 {
index 44c6e01..3fbd416 100644 (file)
@@ -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,
index 1fe4235..9589865 100644 (file)
@@ -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);