]> Zhao Yanbai Git Server - minix.git/commitdiff
libpuffs: clean up, unbreak 96/3196/1
authorDavid van Moolenbroek <david@minix3.org>
Tue, 22 Sep 2015 12:41:58 +0000 (12:41 +0000)
committerDavid van Moolenbroek <david@minix3.org>
Wed, 23 Sep 2015 12:05:03 +0000 (12:05 +0000)
- move MINIX3-specific files into minix/lib/libpuffs;
- resynchronize the remaining files with NetBSD code;
- remove a few unnecessary changes;
- put remaining MINIX3-specific changes in __minix blocks;
- sort out the source files being linked at all.

The result is that libpuffs now successfully links against FUSE
file system programs again.  It can successfully mount, perform
some of the most basic operations, and unmount the file system.

Change-Id: Ieac220f7ad8c4d1fa293abda81967e8045be0bb4

25 files changed:
lib/libpuffs/Makefile
lib/libpuffs/callcontext.c
lib/libpuffs/dispatcher.c
lib/libpuffs/path_puffs.c [deleted file]
lib/libpuffs/pnode.c
lib/libpuffs/puffs.c
lib/libpuffs/puffs_priv.h
lib/libpuffs/requests.c
minix/lib/libpuffs/const.h [new file with mode: 0644]
minix/lib/libpuffs/fs.h [moved from lib/libpuffs/fs.h with 85% similarity]
minix/lib/libpuffs/glo.h [moved from lib/libpuffs/glo.h with 100% similarity]
minix/lib/libpuffs/inode.c [moved from lib/libpuffs/inode.c with 94% similarity]
minix/lib/libpuffs/link.c [moved from lib/libpuffs/link.c with 93% similarity]
minix/lib/libpuffs/main.c [new file with mode: 0644]
minix/lib/libpuffs/misc.c [moved from lib/libpuffs/misc.c with 90% similarity]
minix/lib/libpuffs/mount.c [moved from lib/libpuffs/mount.c with 92% similarity]
minix/lib/libpuffs/open.c [moved from lib/libpuffs/open.c with 94% similarity]
minix/lib/libpuffs/path.c [moved from lib/libpuffs/path.c with 94% similarity]
minix/lib/libpuffs/protect.c [moved from lib/libpuffs/protect.c with 91% similarity]
minix/lib/libpuffs/proto.h [moved from lib/libpuffs/proto.h with 95% similarity]
minix/lib/libpuffs/read.c [moved from lib/libpuffs/read.c with 92% similarity]
minix/lib/libpuffs/stadir.c [moved from lib/libpuffs/stadir.c with 91% similarity]
minix/lib/libpuffs/table.c [moved from lib/libpuffs/table.c with 100% similarity]
minix/lib/libpuffs/time.c [moved from lib/libpuffs/time.c with 87% similarity]
minix/lib/libpuffs/utility.c [moved from lib/libpuffs/utility.c with 84% similarity]

index 1c29729fd186b6faaa3aad226b410dc5169599c6..c43a4c710acdd285cd4355ffc2d0e8f1a32a63ba 100644 (file)
@@ -10,7 +10,7 @@ WARNS?=               5
 LIB=           puffs
 
 SRCS=          puffs.c callcontext.c creds.c \
-               null.c pnode.c \
+               paths.c pnode.c \
                subr.c
 MAN=           puffs.3 puffs_cc.3 puffs_cred.3 puffs_flush.3           \
                puffs_framebuf.3 puffs_node.3 puffs_ops.3 puffs_path.3
@@ -19,10 +19,12 @@ INCSDIR=    /usr/include
 LINTFLAGS+=-S -w
 
 .if defined(__MINIX)
-SRCS+=         inode.c link.c misc.c mount.c open.c path.c path_puffs.c \
-               protect.c read.c stadir.c time.c utility.c table.c
+.PATH:         ${NETBSDSRCDIR}/minix/lib/libpuffs
+SRCS+=         inode.c link.c main.c misc.c mount.c open.c path.c \
+               protect.c read.c stadir.c time.c utility.c \
+               table.c
 
-CPPFLAGS+= -D_MINIX_SYSTEM
+CPPFLAGS+= -D_MINIX_SYSTEM -I${.CURDIR} -I${NETBSDSRCDIR}/minix/lib/libpuffs
 
 NOGCCERROR=yes
 .endif # defined(__MINIX)
index eddcdeea089dfff4c3ff1be31a1ba96c2c5fc0cb..53af07345946db5a5bf33faaea7a228a20e0ec05 100644 (file)
@@ -188,18 +188,29 @@ slowccalloc(struct puffs_usermount *pu)
        struct puffs_cc *volatile pcc;
        void *sp;
        size_t stacksize = 1<<pu->pu_cc_stackshift;
+#ifndef __minix
+       const long psize = sysconf(_SC_PAGESIZE);
+#endif /* !__minix */
 
        if (puffs_fakecc)
                return &fakecc;
 
        sp = mmap(NULL, stacksize, PROT_READ|PROT_WRITE,
-           MAP_ANON|MAP_PRIVATE, -1, 0);
+           MAP_ANON|MAP_PRIVATE|MAP_ALIGNED(pu->pu_cc_stackshift), -1, 0);
        if (sp == MAP_FAILED)
                return NULL;
 
        pcc = sp;
        memset(pcc, 0, sizeof(struct puffs_cc));
 
+#ifndef __minix
+#ifndef __MACHINE_STACK_GROWS_UP
+       mprotect((uint8_t *)sp + psize, (size_t)psize, PROT_NONE);
+#else
+       mprotect((uint8_t *)sp + stacksize - psize, (size_t)psize, PROT_NONE);
+#endif
+#endif /* !__minix */
+
        /* initialize both ucontext's */
        if (getcontext(&pcc->pcc_uc) == -1) {
                munmap(pcc, stacksize);
@@ -242,6 +253,8 @@ puffs__cc_create(struct puffs_usermount *pu, puffs_ccfunc func,
                pcc->pcc_func = func;
                pcc->pcc_farg = pcc;
        } else {
+               const long psize = sysconf(_SC_PAGESIZE);
+
                /* link context */
                pcc->pcc_uc.uc_link = &pcc->pcc_uc_ret;
 
@@ -251,8 +264,8 @@ puffs__cc_create(struct puffs_usermount *pu, puffs_ccfunc func,
                 * swapcontext().  However, it gets lost.  So reinit it.
                 */
                st = &pcc->pcc_uc.uc_stack;
-               st->ss_sp = pcc;
-               st->ss_size = stacksize;
+               st->ss_sp = ((uint8_t *)(void *)pcc) + psize;
+               st->ss_size = stacksize - psize;
                st->ss_flags = 0;
 
                /*
index 590c8a802ebbd20418b0b67fe1628948e8ae58ae..d457067157584e21b135c1ad5f69272384e4d61e 100644 (file)
@@ -39,9 +39,7 @@ __RCSID("$NetBSD: dispatcher.c,v 1.46 2013/11/06 19:56:38 christos Exp $");
 
 #include <assert.h>
 #include <errno.h>
-#if !defined(__minix)
 #include <pthread.h>
-#endif /* !defined(__minix) */
 #include <puffs.h>
 #include <puffsdump.h>
 #include <stdio.h>
diff --git a/lib/libpuffs/path_puffs.c b/lib/libpuffs/path_puffs.c
deleted file mode 100644 (file)
index 70a64ad..0000000
+++ /dev/null
@@ -1,298 +0,0 @@
-/* 
- * Copyright (c) 2007  Antti Kantee.  All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
- * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include <sys/hash.h>
-
-#include <assert.h>
-#include <errno.h>
-#include <puffs.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "puffs.h"
-#include "puffs_priv.h"
-
-
-/*
- * Generic routines for pathbuilding code
- */
-
-int
-puffs_path_pcnbuild(struct puffs_usermount *pu, struct puffs_cn *pcn,
-       puffs_cookie_t parent)
-{
-       struct puffs_node *pn_parent = PU_CMAP(pu, parent);
-       struct puffs_cn pcn_orig;
-       struct puffs_pathobj po;
-       int rv;
-
-       assert(pn_parent->pn_po.po_path != NULL);
-       assert(pu->pu_flags & PUFFS_FLAG_BUILDPATH);
-       pcn_orig = *pcn;
-
-       if (pu->pu_pathtransform) {
-               rv = pu->pu_pathtransform(pu, &pn_parent->pn_po, pcn, &po);
-               if (rv)
-                       return rv;
-       } else {
-               po.po_path = pcn->pcn_name;
-               po.po_len = pcn->pcn_namelen;
-       }
-
-       if (pu->pu_namemod) {
-               rv = pu->pu_namemod(pu, &pn_parent->pn_po, pcn);
-               if (rv)
-                       return rv;
-       }
-
-       rv = pu->pu_pathbuild(pu, &pn_parent->pn_po, &po, 0,
-           &pcn->pcn_po_full);
-       puffs_path_buildhash(pu, &pcn->pcn_po_full);
-
-       if (pu->pu_pathtransform)
-               pu->pu_pathfree(pu, &po);
-
-       if (pu->pu_namemod && rv)
-               *pcn = pcn_orig;
-
-       return rv;
-}
-
-/*
- * substitute all (child) patch prefixes.  called from nodewalk, which
- * in turn is called from rename
- */
-void *
-puffs_path_prefixadj(struct puffs_usermount *pu, struct puffs_node *pn,
-       void *arg)
-{
-       struct puffs_pathinfo *pi = arg;
-       struct puffs_pathobj localpo;
-       struct puffs_pathobj oldpo;
-       int rv;
-
-       /* can't be a path prefix */
-       if (pn->pn_po.po_len < pi->pi_old->po_len)
-               return NULL;
-
-       if (pu->pu_pathcmp(pu, &pn->pn_po, pi->pi_old, pi->pi_old->po_len, 1))
-               return NULL;
-
-       /* otherwise we'd have two nodes with an equal path */
-       assert(pn->pn_po.po_len > pi->pi_old->po_len);
-
-       /* found a matching prefix */
-       rv = pu->pu_pathbuild(pu, pi->pi_new, &pn->pn_po,
-           pi->pi_old->po_len, &localpo);
-       /*
-        * XXX: technically we shouldn't fail, but this is the only
-        * sensible thing to do here.  If the buildpath routine fails,
-        * we will have paths in an inconsistent state.  Should fix this,
-        * either by having two separate passes or by doing other tricks
-        * to make an invalid path with BUILDPATHS acceptable.
-        */
-       if (rv != 0)
-               abort();
-
-       /* adjust hash sum */
-       puffs_path_buildhash(pu, &localpo);
-
-       /* out with the old and in with the new */
-       oldpo = pn->pn_po;
-       pn->pn_po = localpo;
-       pu->pu_pathfree(pu, &oldpo);
-
-       /* continue the walk */
-       return NULL;
-}
-
-/*
- * called from nodewalk, checks for exact match
- */
-void *
-puffs_path_walkcmp(struct puffs_usermount *pu, struct puffs_node *pn, void *arg)
-{
-       struct puffs_pathobj *po = arg;
-       struct puffs_pathobj po2;
-
-       if (po->po_len != PNPLEN(pn))
-               return NULL;
-
-       /*
-        * If hashing and the hash doesn't match, we know this is
-        * definitely not a match.  Otherwise check for collisions.
-        */
-       if (pu->pu_flags & PUFFS_FLAG_HASHPATH)
-               if (pn->pn_po.po_hash != po->po_hash)
-                       return NULL;
-
-       po2.po_path = PNPATH(pn);
-       po2.po_len = PNPLEN(pn);
-
-       if (pu->pu_pathcmp(pu, po, &po2, PNPLEN(pn), 0) == 0)
-               return pn;
-       return NULL;
-}
-
-/*
- * Hash sum building routine.  Use string hash if the buildpath routine
- * is the standard one, otherwise use binary hashes.  A bit whimsical
- * way to choose the routine, but the binary works for strings also,
- * so don't sweat it.
- */
-void
-puffs_path_buildhash(struct puffs_usermount *pu, struct puffs_pathobj *po)
-{
-
-       if ((pu->pu_flags & PUFFS_FLAG_HASHPATH) == 0)
-               return;
-
-       if (pu->pu_pathbuild == puffs_stdpath_buildpath)
-               po->po_hash = hash32_strn(po->po_path, po->po_len,
-                   HASH32_STR_INIT);
-       else
-               po->po_hash = hash32_buf(po->po_path, po->po_len,
-                   HASH32_BUF_INIT);
-}
-
-/*
- * Routines provided to file systems which consider a path a tuple of
- * strings and / the component separator.
- */
-
-/*ARGSUSED*/
-int
-puffs_stdpath_cmppath(struct puffs_usermount *pu, struct puffs_pathobj *c1,
-       struct puffs_pathobj *c2, size_t clen, int checkprefix)
-{
-       char *p;
-       int rv;
-
-       rv = strncmp(c1->po_path, c2->po_path, clen);
-       if (rv)
-               return 1;
-
-       if (checkprefix == 0)
-               return 0;
-
-       /* sanity for next step */
-       if (!(c1->po_len > c2->po_len))
-               return 1;
-
-       /* check if it's really a complete path prefix */
-       p = c1->po_path;
-       if ((*(p + clen)) != '/')
-               return 1;
-
-       return 0;
-}
-
-/*ARGSUSED*/
-int
-puffs_stdpath_buildpath(struct puffs_usermount *pu,
-       const struct puffs_pathobj *po_pre, const struct puffs_pathobj *po_comp,
-       size_t offset, struct puffs_pathobj *newpath)
-{
-       char *path, *pcomp;
-       size_t plen, complen;
-       size_t prelen;
-       int isdotdot;
-
-       complen = po_comp->po_len - offset;
-
-       /* seek to correct place & remove all leading '/' from component */
-       pcomp = po_comp->po_path;
-       pcomp += offset;
-       while (*pcomp == '/') {
-               pcomp++;
-               complen--;
-       }
-
-       /* todotdot or nottodotdot */
-       if (complen == 2 && strcmp(pcomp, "..") == 0)
-               isdotdot = 1;
-       else
-               isdotdot = 0;
-
-       /*
-        * Strip trailing components from the preceending component.
-        * This is an issue only for the root node, which we might want
-        * to be at path "/" for some file systems.
-        */
-       prelen = po_pre->po_len;
-       while (prelen > 0 && *((char *)po_pre->po_path + (prelen-1)) == '/') {
-               assert(isdotdot == 0);
-               prelen--;
-       }
-
-       if (isdotdot) {
-               char *slash; /* sweet char of mine */
-               
-               slash = strrchr(po_pre->po_path, '/');
-               assert(slash != NULL);
-
-               plen = slash - (char *)po_pre->po_path;
-
-               /*
-                * As the converse to not stripping the initial "/" above,
-                * don't nuke it here either.
-                */
-               if (plen == 0)
-                       plen++;
-
-               path = malloc(plen + 1);
-               if (path == NULL)
-                       return errno;
-
-               strlcpy(path, po_pre->po_path, plen+1);
-       } else {
-               /* + '/' + '\0' */
-               plen = prelen + 1 + complen;
-               path = malloc(plen + 1);
-               if (path == NULL)
-                       return errno;
-
-               strlcpy(path, po_pre->po_path, prelen+1);
-               strcat(path, "/");
-               strncat(path, pcomp, complen);
-       }
-
-       newpath->po_path = path;
-       newpath->po_len = plen;
-
-       return 0;
-}
-
-/*ARGSUSED*/
-void
-puffs_stdpath_freepath(struct puffs_usermount *pu, struct puffs_pathobj *po)
-{
-
-       free(po->po_path);
-}
index 49438cf966b711cd2dae87b1b77259c907dceb0a..717b4a8a15c4c466ae9523c4392056592bd19266 100644 (file)
@@ -68,12 +68,14 @@ puffs_pn_new(struct puffs_usermount *pu, void *privdata)
 void
 puffs_pn_remove(struct puffs_node *pn)
 {
-       struct puffs_usermount *pu = pn->pn_mnt;
-       assert(pu != NULL);
 
        LIST_REMOVE(pn, pn_entries);
        pn->pn_flags |= PUFFS_NODE_REMOVED;
+#ifdef __minix
        if (pn->pn_count != 0) {
+               struct puffs_usermount *pu = pn->pn_mnt;
+               assert(pu != NULL);
+
                /* XXX FS removes this pn from the list to prevent further
                 * lookups from finding node after remove/rm/rename op.
                 * But VFS still uses it, i.e. pnode is still open, and
@@ -82,6 +84,7 @@ puffs_pn_remove(struct puffs_node *pn)
                 */
                LIST_INSERT_HEAD(&pu->pu_pnode_removed_lst, pn, pn_entries);
        }
+#endif /* __minix */
 }
 
 void
@@ -95,10 +98,7 @@ puffs_pn_put(struct puffs_node *pn)
        free(pn);
 }
 
-/* walk list, rv can be used either to halt or to return a value
- * XXX (MINIX note): if fn is 0, then arg is ino_t and we search
- * node with ino_t. TODO: modify docs.
- */
+/* walk list, rv can be used either to halt or to return a value */
 void *
 puffs_pn_nodewalk(struct puffs_usermount *pu, puffs_nodewalk_fn fn, void *arg)
 {
@@ -108,14 +108,9 @@ puffs_pn_nodewalk(struct puffs_usermount *pu, puffs_nodewalk_fn fn, void *arg)
        pn_cur = LIST_FIRST(&pu->pu_pnodelst);
        while (pn_cur) {
                pn_next = LIST_NEXT(pn_cur, pn_entries);
-               if (fn) {
-                       rv = fn(pu, pn_cur, arg);
-                       if (rv)
-                               return rv;
-               } else {
-                       if (pn_cur->pn_va.va_fileid == *((ino_t*) arg))
-                               return pn_cur;
-               }
+               rv = fn(pu, pn_cur, arg);
+               if (rv)
+                       return rv;
                pn_cur = pn_next;
        }
 
index 5e645536fac4cbd4ec1c484494224b43b4072d34..abf37571bef24b5d77ffd89f8f4861212e77f990 100644 (file)
@@ -37,16 +37,15 @@ __RCSID("$NetBSD: puffs.c,v 1.117 2011/11/14 01:27:42 chs Exp $");
 #include <sys/param.h>
 #include <sys/mount.h>
 
-#if defined(__minix)
-#include "fs.h"
-#endif /* defined(__minix) */
-
 #include <assert.h>
 #include <err.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <mntopts.h>
 #include <paths.h>
+#ifndef __minix
+#include <pthread.h>
+#endif /* !__minix */
 #include <puffs.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -62,77 +61,10 @@ const struct mntopt puffsmopts[] = {
        PUFFSMOPT_STD,
        MOPT_NULL,
 };
-#ifdef PUFFS_WITH_THREADS
-#include <pthread.h>
-pthread_mutex_t pu_lock = PTHREAD_MUTEX_INITIALIZER;
-#endif
-
-#if defined(__minix)
-static message fs_msg;
-static int fs_ipc_status;
-#endif
-
-/* Declare some local functions. */
-static int get_work(message *msg, int *ipc_status);
-
-/* SEF functions and variables. */
-static void sef_local_startup(void);
-static int sef_cb_init_fresh(int type, sef_init_info_t *info);
-static void sef_cb_signal_handler(int signo);
-
-EXTERN int env_argc;
-EXTERN char **env_argv;
-
-
-#define PUFFS_MAX_ARGS 20
-
-int __real_main(int argc, char* argv[]);
-int __wrap_main(int argc, char* argv[]);
-
-int __wrap_main(int argc, char *argv[])
-{
-  int i;
-  int new_argc = 0;
-  static char* new_argv[PUFFS_MAX_ARGS];
-  char *name;
-
-  /* SEF local startup. */
-  env_setargs(argc, argv);
-  sef_local_startup();
-
-  global_kcred.pkcr_type = PUFFCRED_TYPE_INTERNAL;
-
-  if (argc < 3) {
-       panic("Unexpected arguments, use:\
-               mount -t fs /dev/ /dir [-o option1,option2]\n");
-  }
-
-  name = argv[0] + strlen(argv[0]);
-  while (*name != '/' && name != argv[0])
-         name--;
-  if (name != argv[0])
-         name++;
-  strcpy(fs_name, name);
-
-  new_argv[new_argc] = argv[0];
-  new_argc++;
-  
-  for (i = 1; i < argc; i++) {
-       if (new_argc >= PUFFS_MAX_ARGS) {
-               panic("Too many arguments, change PUFFS_MAX_ARGS");
-       }
-       new_argv[new_argc] = argv[i];
-       new_argc++;
-  }
-
-  assert(new_argc > 0);
-
-  /* Get the mount request from VFS, so we can deal with it later. */
-  (void)get_work(&fs_msg, &fs_ipc_status);
-
-  return __real_main(new_argc, new_argv);
-}
 
+#ifndef __minix
+pthread_mutex_t pu_lock = PTHREAD_MUTEX_INITIALIZER;
+#endif /* !__minix */
 
 #define FILLOP(lower, upper)                                           \
 do {                                                                   \
@@ -170,22 +102,106 @@ fillvnopmask(struct puffs_ops *pops, struct puffs_kargs *pa)
        FILLOP(print,    PRINT);
        FILLOP(read,     READ);
        FILLOP(write,    WRITE);
+       FILLOP(advlock,  ADVLOCK);
        FILLOP(abortop,  ABORTOP);
+       FILLOP(pathconf, PATHCONF);
+
+       FILLOP(getextattr,  GETEXTATTR);
+       FILLOP(setextattr,  SETEXTATTR);
+       FILLOP(listextattr, LISTEXTATTR);
+       FILLOP(deleteextattr, DELETEEXTATTR);
 }
 #undef FILLOP
 
+/*
+ * Go over all framev entries and write everything we can.  This is
+ * mostly for the benefit of delivering "unmount" to the kernel.
+ */
+static void
+finalpush(struct puffs_usermount *pu)
+{
+#ifndef __minix
+       struct puffs_fctrl_io *fio;
+
+       LIST_FOREACH(fio, &pu->pu_ios, fio_entries) {
+               if (fio->stat & FIO_WRGONE)
+                       continue;
+
+               puffs__framev_output(pu, fio->fctrl, fio);
+       }
+#endif /* !__minix */
+}
 
 /*ARGSUSED*/
-__dead static void
-puffs_defaulterror(struct puffs_usermount *pu, uint8_t type,
+void
+puffs_kernerr_abort(struct puffs_usermount *pu, uint8_t type,
        int error, const char *str, puffs_cookie_t cookie)
 {
 
+#ifndef __minix
+       fprintf(stderr, "abort: type %d, error %d, cookie %p (%s)\n",
+#else /* __minix */
        lpuffs_debug("abort: type %d, error %d, cookie %p (%s)\n",
+#endif /* __minix */
            type, error, cookie, str);
        abort();
 }
 
+/*ARGSUSED*/
+void
+puffs_kernerr_log(struct puffs_usermount *pu, uint8_t type,
+       int error, const char *str, puffs_cookie_t cookie)
+{
+
+       syslog(LOG_WARNING, "kernel: type %d, error %d, cookie %p (%s)\n",
+           type, error, cookie, str);
+}
+
+#ifndef __minix
+int
+puffs_getselectable(struct puffs_usermount *pu)
+{
+
+       return pu->pu_fd;
+}
+
+uint64_t
+puffs__nextreq(struct puffs_usermount *pu)
+{
+       uint64_t rv;
+
+       PU_LOCK();
+       rv = pu->pu_nextreq++ | (uint64_t)1<<63;
+       PU_UNLOCK();
+
+       return rv;
+}
+
+int
+puffs_setblockingmode(struct puffs_usermount *pu, int mode)
+{
+       int rv, x;
+
+       assert(puffs_getstate(pu) == PUFFS_STATE_RUNNING);
+
+       if (mode != PUFFSDEV_BLOCK && mode != PUFFSDEV_NONBLOCK) {
+               errno = EINVAL;
+               return -1;
+       }
+
+       x = mode;
+       rv = ioctl(pu->pu_fd, FIONBIO, &x);
+
+       if (rv == 0) {
+               if (mode == PUFFSDEV_BLOCK)
+                       pu->pu_state &= ~PU_ASYNCFD;
+               else
+                       pu->pu_state |= PU_ASYNCFD;
+       }
+
+       return rv;
+}
+#endif /* !__minix */
 
 int
 puffs_getstate(struct puffs_usermount *pu)
@@ -207,8 +223,10 @@ puffs_setstacksize(struct puffs_usermount *pu, size_t ss)
        minsize = 4*psize;
        if (ss < (size_t)minsize || ss == PUFFS_STACKSIZE_MIN) {
                if (ss != PUFFS_STACKSIZE_MIN)
-                       lpuffs_debug("puffs_setstacksize: adjusting "
+#ifndef __minix
+                       fprintf(stderr, "puffs_setstacksize: adjusting "
                            "stacksize to minimum %ld\n", minsize);
+#endif /* !__minix */
                ss = 4*psize;
        }
  
@@ -222,8 +240,10 @@ puffs_setstacksize(struct puffs_usermount *pu, size_t ss)
        }
        if (bonus > 1) {
                stackshift++;
-               lpuffs_debug("puffs_setstacksize: using next power of two: "
+#ifndef __minix
+               fprintf(stderr, "puffs_setstacksize: using next power of two: "
                    "%d\n", 1<<stackshift);
+#endif /* !__minix */
        }
 
        pu->pu_cc_stackshift = stackshift;
@@ -416,30 +436,223 @@ puffs_set_prepost(struct puffs_usermount *pu,
        pu->pu_oppost = pst;
 }
 
+#ifndef __minix
+void
+puffs_setback(struct puffs_cc *pcc, int whatback)
+{
+       struct puffs_req *preq = puffs__framebuf_getdataptr(pcc->pcc_pb);
+
+       assert(PUFFSOP_OPCLASS(preq->preq_opclass) == PUFFSOP_VN && (
+           preq->preq_optype == PUFFS_VN_OPEN ||
+           preq->preq_optype == PUFFS_VN_MMAP ||
+           preq->preq_optype == PUFFS_VN_REMOVE ||
+           preq->preq_optype == PUFFS_VN_RMDIR ||
+           preq->preq_optype == PUFFS_VN_INACTIVE));
+
+       preq->preq_setbacks |= whatback & PUFFS_SETBACK_MASK;
+}
+
+int
+puffs_daemon(struct puffs_usermount *pu, int nochdir, int noclose)
+{
+       long int n;
+       int parent, value, fd;
+
+       if (pipe(pu->pu_dpipe) == -1)
+               return -1;
+
+       switch (fork()) {
+       case -1:
+               return -1;
+       case 0:
+               parent = 0;
+               break;
+       default:
+               parent = 1;
+               break;
+       }
+       pu->pu_state |= PU_PUFFSDAEMON;
+
+       if (parent) {
+               close(pu->pu_dpipe[1]);
+               n = read(pu->pu_dpipe[0], &value, sizeof(int));
+               if (n == -1)
+                       err(1, "puffs_daemon");
+               if (n != sizeof(value))
+                       errx(1, "puffs_daemon got %ld bytes", n);
+               if (value) {
+                       errno = value;
+                       err(1, "puffs_daemon");
+               }
+               exit(0);
+       } else {
+               if (setsid() == -1)
+                       goto fail;
+
+               if (!nochdir)
+                       chdir("/");
+
+               if (!noclose) {
+                       fd = open(_PATH_DEVNULL, O_RDWR, 0);
+                       if (fd == -1)
+                               goto fail;
+                       dup2(fd, STDIN_FILENO);
+                       dup2(fd, STDOUT_FILENO);
+                       dup2(fd, STDERR_FILENO);
+                       if (fd > STDERR_FILENO)
+                               close(fd);
+               }
+               return 0;
+       }
+
+ fail:
+       n = write(pu->pu_dpipe[1], &errno, sizeof(int));
+       assert(n == 4);
+       return -1;
+}
+#endif /* !__minix */
+
+static void
+shutdaemon(struct puffs_usermount *pu, int error)
+{
+#ifndef __minix
+       ssize_t n;
+
+       n = write(pu->pu_dpipe[1], &error, sizeof(int));
+       assert(n == 4);
+       close(pu->pu_dpipe[0]);
+       close(pu->pu_dpipe[1]);
+#endif /* !__minix */
+       pu->pu_state &= ~PU_PUFFSDAEMON;
+}
+
 int
 puffs_mount(struct puffs_usermount *pu, const char *dir, int mntflags,
        puffs_cookie_t cookie)
 {
-#if defined(__minix)
+#ifndef __minix
+       int rv, fd, sverrno;
+       char *comfd;
+#endif /* !__minix */
+
        pu->pu_kargp->pa_root_cookie = cookie;
 
-       /* Process the already-received mount request. */
-       fsdriver_process(&puffs_table, &fs_msg, fs_ipc_status, FALSE);
+#ifndef __minix
+       /* XXXkludgehere */
+       /* kauth doesn't provide this service any longer */
+       if (geteuid() != 0)
+               mntflags |= MNT_NOSUID | MNT_NODEV;
+
+       /*
+        * Undocumented...  Well, documented only here.
+        *
+        * This is used for imaginative purposes.  If the env variable is
+        * set, puffs_mount() doesn't do the regular mount procedure.
+        * Rather, it crams the mount data down the comfd and sets comfd as
+        * the puffs descriptor.
+        *
+        * This shouldn't be used unless you can read my mind ( ... or write
+        * it, not to mention execute it, but that's starting to get silly).
+        */
+       if ((comfd = getenv("PUFFS_COMFD")) != NULL) {
+               size_t len;
+
+               if (sscanf(comfd, "%d", &pu->pu_fd) != 1) {
+                       errno = EINVAL;
+                       rv = -1;
+                       goto out;
+               }
+               /* check that what we got at least resembles an fd */
+               if (fcntl(pu->pu_fd, F_GETFL) == -1) {
+                       rv = -1;
+                       goto out;
+               }
+
+#define allwrite(buf, len)                                             \
+do {                                                                   \
+       ssize_t al_rv;                                                  \
+       al_rv = write(pu->pu_fd, buf, len);                             \
+       if ((size_t)al_rv != len) {                                     \
+               if (al_rv != -1)                                        \
+                       errno = EIO;                                    \
+               rv = -1;                                                \
+               goto out;                                               \
+       }                                                               \
+} while (/*CONSTCOND*/0)
+               len = strlen(dir)+1;
+               allwrite(&len, sizeof(len));
+               allwrite(dir, len);
+               len = strlen(pu->pu_kargp->pa_mntfromname)+1;
+               allwrite(&len, sizeof(len));
+               allwrite(pu->pu_kargp->pa_mntfromname, len);
+               allwrite(&mntflags, sizeof(mntflags));
+               len = sizeof(*pu->pu_kargp);
+               allwrite(&len, sizeof(len));
+               allwrite(pu->pu_kargp, sizeof(*pu->pu_kargp));
+               allwrite(&pu->pu_flags, sizeof(pu->pu_flags));
+#undef allwrite
+
+               rv = 0;
+       } else {
+               char rp[MAXPATHLEN];
+
+               if (realpath(dir, rp) == NULL) {
+                       rv = -1;
+                       goto out;
+               }
 
-       if (!mounted) {
-               /* This should never happen, unless VFS misbehaves.. */
+               if (strcmp(dir, rp) != 0) {
+                       warnx("puffs_mount: \"%s\" is a relative path.", dir);
+                       warnx("puffs_mount: using \"%s\" instead.", rp);
+               }
+
+               fd = open(_PATH_PUFFS, O_RDWR);
+               if (fd == -1) {
+                       warnx("puffs_mount: cannot open %s", _PATH_PUFFS);
+                       rv = -1;
+                       goto out;
+               }
+               if (fd <= 2)
+                       warnx("puffs_mount: device fd %d (<= 2), sure this is "
+                           "what you want?", fd);
+
+               pu->pu_kargp->pa_fd = pu->pu_fd = fd;
+               if ((rv = mount(MOUNT_PUFFS, rp, mntflags,
+                   pu->pu_kargp, sizeof(struct puffs_kargs))) == -1)
+                       goto out;
+       }
+#else /* __minix */
+       /* Process the already-received mount request. */
+       if (!lpuffs_pump()) {
+               /* Not mounted?  This should never happen.. */
                free(pu->pu_kargp);
                pu->pu_kargp = NULL;
-               errno = -EINVAL;
+               errno = EINVAL;
                return -1;
        }
+#endif /* __minix */
 
        PU_SETSTATE(pu, PUFFS_STATE_RUNNING);
+
+#ifndef __minix
+ out:
+       if (rv != 0)
+               sverrno = errno;
+       else
+               sverrno = 0;
+       free(pu->pu_kargp);
+       pu->pu_kargp = NULL;
+
+       if (pu->pu_state & PU_PUFFSDAEMON)
+               shutdaemon(pu, sverrno);
+
+       errno = sverrno;
+       return rv;
+#else /* __minix */
        return 0;
-#endif /* defined(__minix) */
+#endif /* __minix */
 }
 
-/*ARGSUSED*/
 struct puffs_usermount *
 puffs_init(struct puffs_ops *pops, const char *mntfromname,
        const char *puffsname, void *priv, uint32_t pflags)
@@ -482,19 +695,25 @@ puffs_init(struct puffs_ops *pops, const char *mntfromname,
                pargs->pa_time32 = 0;
 
        pu->pu_flags = pflags;
-       buildpath = pu->pu_flags & PUFFS_FLAG_BUILDPATH; /* XXX */
        pu->pu_ops = *pops;
        free(pops); /* XXX */
 
        pu->pu_privdata = priv;
        pu->pu_cc_stackshift = PUFFS_CC_STACKSHIFT_DEFAULT;
        LIST_INIT(&pu->pu_pnodelst);
-       LIST_INIT(&pu->pu_pnode_removed_lst);
        LIST_INIT(&pu->pu_ios);
        LIST_INIT(&pu->pu_ios_rmlist);
        LIST_INIT(&pu->pu_ccmagazin);
        TAILQ_INIT(&pu->pu_sched);
 
+#ifndef __minix
+       pu->pu_framectrl[PU_FRAMECTRL_FS].rfb = puffs__fsframe_read;
+       pu->pu_framectrl[PU_FRAMECTRL_FS].wfb = puffs__fsframe_write;
+       pu->pu_framectrl[PU_FRAMECTRL_FS].cmpfb = puffs__fsframe_cmp;
+       pu->pu_framectrl[PU_FRAMECTRL_FS].gotfb = puffs__fsframe_gotframe;
+       pu->pu_framectrl[PU_FRAMECTRL_FS].fdnotfn = puffs_framev_unmountonclose;
+#endif /* !__minix */
+
        /* defaults for some user-settable translation functions */
        pu->pu_cmap = NULL; /* identity translation */
 
@@ -504,11 +723,14 @@ puffs_init(struct puffs_ops *pops, const char *mntfromname,
        pu->pu_pathtransform = NULL;
        pu->pu_namemod = NULL;
 
-        pu->pu_errnotify = puffs_defaulterror;
+       pu->pu_errnotify = puffs_kernerr_log;
 
        PU_SETSTATE(pu, PUFFS_STATE_BEFOREMOUNT);
 
-       global_pu = pu;
+#ifdef __minix
+       /* Do the MINIX3-specific side of the initialization. */
+       lpuffs_init(pu);
+#endif /* __minix */
 
        return pu;
 
@@ -525,16 +747,45 @@ puffs_cancel(struct puffs_usermount *pu, int error)
 {
 
        assert(puffs_getstate(pu) < PUFFS_STATE_RUNNING);
+       shutdaemon(pu, error);
        free(pu);
 }
 
 /*ARGSUSED1*/
 int
-puffs_exit(struct puffs_usermount *pu, int force)
+puffs_exit(struct puffs_usermount *pu, int unused /* strict compat */)
 {
+#ifndef __minix
+       struct puffs_framebuf *pb;
+       struct puffs_req *preq;
+       void *winp;
+       size_t winlen;
+       int sverrno;
+
+       pb = puffs_framebuf_make();
+       if (pb == NULL) {
+               errno = ENOMEM;
+               return -1;
+       }
+
+       winlen = sizeof(struct puffs_req);
+       if (puffs_framebuf_getwindow(pb, 0, &winp, &winlen) == -1) {
+               sverrno = errno;
+               puffs_framebuf_destroy(pb);
+               errno = sverrno;
+               return -1;
+       }
+       preq = winp;
+
+       preq->preq_buflen = sizeof(struct puffs_req);
+       preq->preq_opclass = PUFFSOP_UNMOUNT;
+       preq->preq_id = puffs__nextreq(pu);
+
+       puffs_framev_enqueue_justsend(pu, puffs_getselectable(pu), pb, 1, 0);
+#else /* __minix */
        struct puffs_node *pn;
-        
-        lpuffs_debug("puffs_exit\n");
+
+       lpuffs_debug("puffs_exit\n");
 
        while ((pn = LIST_FIRST(&pu->pu_pnodelst)) != NULL)
                puffs_pn_put(pn);
@@ -546,10 +797,36 @@ puffs_exit(struct puffs_usermount *pu, int force)
        if (pu->pu_state & PU_HASKQ)
                close(pu->pu_kq);
        free(pu);
+#endif /* __minix */
 
-       return 0; /* always succesful for now, WILL CHANGE */
+       return 0;
 }
 
+#ifndef __minix
+/* no sigset_t static intializer */
+static int sigs[NSIG] = { 0, };
+static int sigcatch = 0;
+
+int
+puffs_unmountonsignal(int sig, bool sigignore)
+{
+
+       if (sig < 0 || sig >= (int)NSIG) {
+               errno = EINVAL;
+               return -1;
+       }
+       if (sigignore)
+               if (signal(sig, SIG_IGN) == SIG_ERR)
+                       return -1;
+
+       if (!sigs[sig])
+               sigcatch++;
+       sigs[sig] = 1;
+
+       return 0;
+}
+#endif /* !__minix */
+
 /*
  * Actual mainloop.  This is called from a context which can block.
  * It is called either from puffs_mainloop (indirectly, via
@@ -559,46 +836,235 @@ void
 puffs__theloop(struct puffs_cc *pcc)
 {
        struct puffs_usermount *pu = pcc->pcc_pu;
+#ifndef __minix
+       struct puffs_framectrl *pfctrl;
+       struct puffs_fctrl_io *fio;
+       struct kevent *curev;
+       size_t nchanges;
+       int ndone;
+#endif /* !__minix */
+
+#ifndef __minix
+       while (puffs_getstate(pu) != PUFFS_STATE_UNMOUNTED) {
+#else /* __minix */
+       do {
+#endif /* __minix */
 
-       while (mounted || !exitsignaled) {
                /*
                 * Schedule existing requests.
                 */
                while ((pcc = TAILQ_FIRST(&pu->pu_sched)) != NULL) {
-                       lpuffs_debug("scheduling existing tasks\n");
                        TAILQ_REMOVE(&pu->pu_sched, pcc, pcc_schedent);
                        puffs__goto(pcc);
                }
 
-               if (pu->pu_ml_lfn) {
-                        lpuffs_debug("Calling user mainloop handler\n");
+               if (pu->pu_ml_lfn)
                        pu->pu_ml_lfn(pu);
+
+#ifndef __minix
+               /* XXX: can we still do these optimizations? */
+#if 0
+               /*
+                * Do this here, because:
+                *  a) loopfunc might generate some results
+                *  b) it's still "after" event handling (except for round 1)
+                */
+               if (puffs_req_putput(ppr) == -1)
+                       goto out;
+               puffs_req_resetput(ppr);
+
+               /* micro optimization: skip kevent syscall if possible */
+               if (pu->pu_nfds == 1 && pu->pu_ml_timep == NULL
+                   && (pu->pu_state & PU_ASYNCFD) == 0) {
+                       pfctrl = XXX->fctrl;
+                       puffs_framev_input(pu, pfctrl, XXX);
+                       continue;
                }
+#endif
 
-               /* Wait for request message. */
-               if (get_work(&fs_msg, &fs_ipc_status) != OK)
-                       continue; /* recheck loop conditions */
+               /* else: do full processing */
+               /* Don't bother worrying about O(n) for now */
+               LIST_FOREACH(fio, &pu->pu_ios, fio_entries) {
+                       if (fio->stat & FIO_WRGONE)
+                               continue;
+
+                       pfctrl = fio->fctrl;
+
+                       /*
+                        * Try to write out everything to avoid the
+                        * need for enabling EVFILT_WRITE.  The likely
+                        * case is that we can fit everything into the
+                        * socket buffer.
+                        */
+                       puffs__framev_output(pu, pfctrl, fio);
+               }
 
-               /* Process it, and send a reply. */
-               fsdriver_process(&puffs_table, &fs_msg, fs_ipc_status, FALSE);
+               /*
+                * Build list of which to enable/disable in writecheck.
+                */
+               nchanges = 0;
+               LIST_FOREACH(fio, &pu->pu_ios, fio_entries) {
+                       if (fio->stat & FIO_WRGONE)
+                               continue;
+
+                       /* en/disable write checks for kqueue as needed */
+                       assert((FIO_EN_WRITE(fio) && FIO_RM_WRITE(fio)) == 0);
+                       if (FIO_EN_WRITE(fio)) {
+                               EV_SET(&pu->pu_evs[nchanges], fio->io_fd,
+                                   EVFILT_WRITE, EV_ENABLE, 0, 0,
+                                   (uintptr_t)fio);
+                               fio->stat |= FIO_WR;
+                               nchanges++;
+                       }
+                       if (FIO_RM_WRITE(fio)) {
+                               EV_SET(&pu->pu_evs[nchanges], fio->io_fd,
+                                   EVFILT_WRITE, EV_DISABLE, 0, 0,
+                                   (uintptr_t)fio);
+                               fio->stat &= ~FIO_WR;
+                               nchanges++;
+                       }
+               }
+
+               ndone = kevent(pu->pu_kq, pu->pu_evs, nchanges,
+                   pu->pu_evs, pu->pu_nevs, pu->pu_ml_timep);
+
+               if (ndone == -1) {
+                       if (errno != EINTR)
+                               break;
+                       else
+                               continue;
+               }
+
+               /* uoptimize */
+               if (ndone == 0)
+                       continue;
+
+               /* iterate over the results */
+               for (curev = pu->pu_evs; ndone--; curev++) {
+                       int what;
+
+#if 0
+                       /* get & possibly dispatch events from kernel */
+                       if (curev->ident == puffsfd) {
+                               if (puffs_req_handle(pgr, ppr, 0) == -1)
+                                       goto out;
+                               continue;
+                       }
+#endif
+
+                       fio = (void *)curev->udata;
+                       if (__predict_true(fio))
+                               pfctrl = fio->fctrl;
+                       else
+                               pfctrl = NULL;
+                       if (curev->flags & EV_ERROR) {
+                               assert(curev->filter == EVFILT_WRITE);
+                               fio->stat &= ~FIO_WR;
+
+                               /* XXX: how to know if it's a transient error */
+                               puffs__framev_writeclose(pu, fio,
+                                   (int)curev->data);
+                               puffs__framev_notify(fio, PUFFS_FBIO_ERROR);
+                               continue;
+                       }
+
+                       what = 0;
+                       if (curev->filter == EVFILT_READ) {
+                               puffs__framev_input(pu, pfctrl, fio);
+                               what |= PUFFS_FBIO_READ;
+                       }
+
+                       else if (curev->filter == EVFILT_WRITE) {
+                               puffs__framev_output(pu, pfctrl, fio);
+                               what |= PUFFS_FBIO_WRITE;
+                       }
+
+                       else if (__predict_false(curev->filter==EVFILT_SIGNAL)){
+                               if ((pu->pu_state & PU_DONEXIT) == 0) {
+                                       PU_SETSFLAG(pu, PU_DONEXIT);
+                                       puffs_exit(pu, 0);
+                               }
+                       }
+                       if (what)
+                               puffs__framev_notify(fio, what);
+               }
+
+               /*
+                * Really free fd's now that we don't have references
+                * to them.
+                */
+               while ((fio = LIST_FIRST(&pu->pu_ios_rmlist)) != NULL) {
+                       LIST_REMOVE(fio, fio_entries);
+                       free(fio);
+               }
+#endif /* !__minix */
        }
+#ifdef __minix
+               while (lpuffs_pump());
+#endif /* __minix */
 
        if (puffs__cc_restoremain(pu) == -1)
                warn("cannot restore main context.  impending doom");
-
-       /* May get here, if puffs_fakecc is set to 1. Currently librefuse sets it.
-        * Now we just return to the caller.
-        */
 }
 int
 puffs_mainloop(struct puffs_usermount *pu)
 {
+#ifndef __minix
+       struct puffs_fctrl_io *fio;
+#endif /* !__minix */
        struct puffs_cc *pcc;
+#ifndef __minix
+       struct kevent *curev;
+       size_t nevs;
+       int sverrno, i;
+#else /* __minix */
        int sverrno;
+#endif /* !__minix */
 
        assert(puffs_getstate(pu) >= PUFFS_STATE_RUNNING);
 
-       pu->pu_state |= PU_HASKQ | PU_INLOOP;
+#ifndef __minix
+       pu->pu_kq = kqueue();
+       if (pu->pu_kq == -1)
+               goto out;
+#endif /* !__minix */
+       pu->pu_state |= PU_HASKQ;
+
+#ifndef __minix
+       puffs_setblockingmode(pu, PUFFSDEV_NONBLOCK);
+       if (puffs__framev_addfd_ctrl(pu, puffs_getselectable(pu),
+           PUFFS_FBIO_READ | PUFFS_FBIO_WRITE,
+           &pu->pu_framectrl[PU_FRAMECTRL_FS]) == -1)
+               goto out;
+
+       nevs = pu->pu_nevs + sigcatch;
+       curev = realloc(pu->pu_evs, nevs * sizeof(struct kevent));
+       if (curev == NULL)
+               goto out;
+       pu->pu_evs = curev;
+       pu->pu_nevs = nevs;
+
+       LIST_FOREACH(fio, &pu->pu_ios, fio_entries) {
+               EV_SET(curev, fio->io_fd, EVFILT_READ, EV_ADD,
+                   0, 0, (uintptr_t)fio);
+               curev++;
+               EV_SET(curev, fio->io_fd, EVFILT_WRITE, EV_ADD | EV_DISABLE,
+                   0, 0, (uintptr_t)fio);
+               curev++;
+       }
+       for (i = 0; i < NSIG; i++) {
+               if (sigs[i]) {
+                       EV_SET(curev, i, EVFILT_SIGNAL, EV_ADD | EV_ENABLE,
+                           0, 0, 0);
+                       curev++;
+               }
+       }
+       assert(curev - pu->pu_evs == (ssize_t)pu->pu_nevs);
+       if (kevent(pu->pu_kq, pu->pu_evs, pu->pu_nevs, NULL, 0, NULL) == -1)
+               goto out;
+#endif /* !__minix */
+
+       pu->pu_state |= PU_INLOOP;
 
        /*
         * Create alternate execution context and jump to it.  Note
@@ -611,12 +1077,34 @@ puffs_mainloop(struct puffs_usermount *pu)
        if (puffs__cc_create(pu, puffs__theloop, &pcc) == -1) {
                goto out;
        }
+
+#if 0
        if (puffs__cc_savemain(pu) == -1) {
                goto out;
        }
+#else
+       /*
+        * XXX
+        * puffs__cc_savemain() uses getcontext() and then returns.
+        * the caller (this function) may overwrite the stack frame
+        * of puffs__cc_savemain(), so when we call setcontext() later and
+        * return from puffs__cc_savemain() again, the return address or
+        * saved stack pointer can be garbage.
+        * avoid this by calling getcontext() directly here.
+        */
+       extern int puffs_fakecc;
+       if (!puffs_fakecc) {
+               PU_CLRSFLAG(pu, PU_MAINRESTORE);
+               if (getcontext(&pu->pu_mainctx) == -1) {
+                       goto out;
+               }
+       }
+#endif
+
        if ((pu->pu_state & PU_MAINRESTORE) == 0)
                puffs_cc_continue(pcc);
 
+       finalpush(pu);
        errno = 0;
 
  out:
@@ -629,64 +1117,3 @@ puffs_mainloop(struct puffs_usermount *pu)
        else
                return 0;
 }
-
-#if defined(__minix)
-/*===========================================================================*
- *                            sef_local_startup                             *
- *===========================================================================*/
-static void sef_local_startup(void)
-{
-  /* Register init callbacks. */
-  sef_setcb_init_fresh(sef_cb_init_fresh);
-
-  /* Register signal callbacks. */
-  sef_setcb_signal_handler(sef_cb_signal_handler);
-
-  /* Let SEF perform startup. */
-  sef_startup();
-}
-
-/*===========================================================================*
- *                         sef_cb_init_fresh                                *
- *===========================================================================*/
-static int sef_cb_init_fresh(int type, sef_init_info_t *info)
-{
-/* Initialize the Minix file server. */
-  return(OK);
-}
-
-/*===========================================================================*
- *                        sef_cb_signal_handler                             *
- *===========================================================================*/
-static void sef_cb_signal_handler(int signo)
-{
-  /* Only check for termination signal, ignore anything else. */
-  if (signo != SIGTERM) return;
-
-  exitsignaled = 1;
-  fs_sync();
-
-  sef_cancel();
-}
-
-/*===========================================================================*
- *                             get_work                                     *
- *===========================================================================*/
-static int get_work(message *msg, int *ipc_status)
-{
-  int r;
-
-  for (;;) {
-       if ((r = sef_receive_status(ANY, msg, ipc_status)) != OK) {
-               if (r == EINTR) /* sef_cancel from signal handler? */
-                       break; /* see if we can exit the main loop */
-               panic("sef_receive failed: %d", r);
-       }
-       if (msg->m_source == VFS_PROC_NR)
-               break;
-       lpuffs_debug("libpuffs: unexpected source %d\n", msg->m_source);
-  }
-
-  return r;
-}
-#endif /* defined(__minix) */
index 39bc9826d3f571eb15b46c68954603d88c1723d7..15ea12716cd2e8c4870a13edecb38b862c9a6b67 100644 (file)
 #include <puffs.h>
 #include <ucontext.h>
 
-#if defined(__minix)
-
-/* XXX: MINIX */
-#define ATIME            002    /* set if atime field needs updating */
-#define CTIME            004    /* set if ctime field needs updating */
-#define MTIME            010    /* set if mtime field needs updating */
-
-#else
+#if !defined(__minix)
 extern pthread_mutex_t pu_lock;
 #define PU_LOCK() pthread_mutex_lock(&pu_lock)
 #define PU_UNLOCK() pthread_mutex_unlock(&pu_lock)
-#endif /* defined(__minix) */
-#if defined(__minix)
+#else /* defined(__minix) */
 #define PU_LOCK() /* nothing */
 #define PU_UNLOCK()  /* nothing */
 #endif /* defined(__minix) */
@@ -135,7 +127,7 @@ struct puffs_usermount {
        struct puffs_node       *pu_pn_root;
 
        LIST_HEAD(, puffs_node) pu_pnodelst;
-#if defined(__minix) // LSC TO KEEP??
+#if defined(__minix)
        LIST_HEAD(, puffs_node) pu_pnode_removed_lst;
 #endif /* defined(__minix) */
 
@@ -272,6 +264,15 @@ int        puffs__fsframe_cmp(struct puffs_usermount *, struct puffs_framebuf *,
 void   puffs__fsframe_gotframe(struct puffs_usermount *,
                                struct puffs_framebuf *);
 
+uint64_t       puffs__nextreq(struct puffs_usermount *pu);
+
+#ifdef __minix
+int lpuffs_pump(void);
+void lpuffs_init(struct puffs_usermount *);
+void lpuffs_debug(const char *format, ...)
+       __attribute__((__format__(__printf__, 1, 2)));
+#endif /* __minix */
+
 __END_DECLS
 
 #endif /* _PUFFS_PRIVATE_H_ */
index ce8473c1eb1aa2ab6bd791e5a740d0f38a5d4da7..e33fe017b0ba70a139397f2a72ad334ba4383f42 100644 (file)
@@ -38,9 +38,7 @@ __RCSID("$NetBSD: requests.c,v 1.24 2013/01/23 20:22:34 riastradh Exp $");
 #include <sys/queue.h>
 #include <sys/socket.h>
 
-#if !defined(__minix)
 #include <dev/putter/putter.h>
-#endif /* !defined(__minix) */
 
 #include <assert.h>
 #include <errno.h>
diff --git a/minix/lib/libpuffs/const.h b/minix/lib/libpuffs/const.h
new file mode 100644 (file)
index 0000000..4b3eee0
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _LIBPUFFS_CONST_H
+#define _LIBPUFFS_CONST_H
+
+#define ATIME            002    /* set if atime field needs updating */
+#define CTIME            004    /* set if ctime field needs updating */
+#define MTIME            010    /* set if mtime field needs updating */
+
+#endif /* !_LIBPUFFS_CONST_H */
similarity index 85%
rename from lib/libpuffs/fs.h
rename to minix/lib/libpuffs/fs.h
index d7ac392986f8d57cd322b8aeaeb37e0f173f7d26..add8a17d226acb68a746aae570b5d7f7a830ce47 100644 (file)
 
 #include <minix/fsdriver.h>
 
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "puffs.h"
+#include "puffs_priv.h"
+
+#include "const.h"
 #include "proto.h"
 #include "glo.h"
 
similarity index 100%
rename from lib/libpuffs/glo.h
rename to minix/lib/libpuffs/glo.h
similarity index 94%
rename from lib/libpuffs/inode.c
rename to minix/lib/libpuffs/inode.c
index a773b6eddbf12940c864134fb0744c02a68fb573..4b581b3a3dc781a89b9d370db803b24599336569 100644 (file)
@@ -4,12 +4,6 @@
  */
 
 #include "fs.h"
-#include <string.h>
-#include <assert.h>
-
-#include "puffs.h"
-#include "puffs_priv.h"
-
 
 void release_node(struct puffs_usermount *pu, struct puffs_node *pn)
 {
@@ -37,7 +31,7 @@ int fs_putnode(ino_t ino_nr, unsigned int count)
  */
   struct puffs_node *pn;
 
-  if ((pn = puffs_pn_nodewalk(global_pu, 0, &ino_nr)) == NULL) {
+  if ((pn = puffs_pn_nodewalk(global_pu, find_inode_cb, &ino_nr)) == NULL) {
        /* XXX Probably removed from the list, see puffs_pn_remove() */
        struct puffs_node *pn_cur, *pn_next;
        pn_cur = LIST_FIRST(&global_pu->pu_pnode_removed_lst);
similarity index 93%
rename from lib/libpuffs/link.c
rename to minix/lib/libpuffs/link.c
index 3d07fa6c26b413927d8189d9f8f4f0ed45bb2493..b55ed00ee6637bf8139a4d4a49a68d31b9f249f0 100644 (file)
@@ -1,12 +1,5 @@
 #include "fs.h"
 
-#include <stdlib.h>
-#include <assert.h>
-
-#include "puffs.h"
-#include "puffs_priv.h"
-
-
 /*===========================================================================*
  *                             fs_trunc                                     *
  *===========================================================================*/
@@ -16,7 +9,7 @@ int fs_trunc(ino_t ino_nr, off_t start, off_t end)
   struct puffs_node *pn;
   PUFFS_MAKECRED(pcr, &global_kcred);
 
-  if ((pn = puffs_pn_nodewalk(global_pu, 0, &ino_nr)) == NULL)
+  if ((pn = puffs_pn_nodewalk(global_pu, find_inode_cb, &ino_nr)) == NULL)
           return(EINVAL);
 
   if (end == 0) {
@@ -27,7 +20,7 @@ int fs_trunc(ino_t ino_nr, off_t start, off_t end)
 
        if (global_pu->pu_ops.puffs_node_setattr == NULL)
                return(EINVAL);
-       
+
        puffs_vattr_null(&va);
        va.va_size = start;
 
@@ -74,9 +67,9 @@ int fs_link(ino_t dir_nr, char *name, ino_t ino_nr)
   struct puffs_cn pcn = {&pkcnp, (struct puffs_cred *) __UNCONST(pcr), {0,0,0}};
 
   if (global_pu->pu_ops.puffs_node_link == NULL)
-       return(OK);
+       return(OK);
 
-  if ((pn = puffs_pn_nodewalk(global_pu, 0, &ino_nr)) == NULL)
+  if ((pn = puffs_pn_nodewalk(global_pu, find_inode_cb, &ino_nr)) == NULL)
        return(EINVAL);
 
   /* Check to see if the file has maximum number of links already. */
@@ -87,7 +80,7 @@ int fs_link(ino_t dir_nr, char *name, ino_t ino_nr)
   if (S_ISDIR(pn->pn_va.va_mode))
        return(EPERM);
 
-  if ((pn_dir = puffs_pn_nodewalk(global_pu, 0, &dir_nr)) == NULL)
+  if ((pn_dir = puffs_pn_nodewalk(global_pu, find_inode_cb, &dir_nr)) == NULL)
         return(EINVAL);
 
   if (pn_dir->pn_va.va_nlink == NO_LINK) {
@@ -120,7 +113,7 @@ int fs_link(ino_t dir_nr, char *name, ino_t ino_nr)
 
   if (buildpath)
        global_pu->pu_pathfree(global_pu, &pcn.pcn_po_full);
-  
+
   if (r != OK) return(EINVAL);
 
   (void)clock_time(&cur_time);
@@ -143,8 +136,8 @@ ssize_t fs_rdlink(ino_t ino_nr, struct fsdriver_data *data, size_t bytes)
 
   if (bytes > sizeof(path))
        bytes = sizeof(path);
-  
-  if ((pn = puffs_pn_nodewalk(global_pu, 0, &ino_nr)) == NULL)
+
+  if ((pn = puffs_pn_nodewalk(global_pu, find_inode_cb, &ino_nr)) == NULL)
        return(EINVAL);
 
   if (!S_ISLNK(pn->pn_va.va_mode))
@@ -199,7 +192,8 @@ int fs_rename(ino_t old_dir_nr, char *old_name, ino_t new_dir_nr,
   strcpy(pcn_targ.pcn_name, new_name);
 
   /* Get old dir pnode */
-  if ((old_dirp = puffs_pn_nodewalk(global_pu, 0, &old_dir_nr)) == NULL)
+  if ((old_dirp = puffs_pn_nodewalk(global_pu, find_inode_cb,
+    &old_dir_nr)) == NULL)
         return(ENOENT);
 
   old_ip = advance(old_dirp, pcn_src.pcn_name);
@@ -210,7 +204,8 @@ int fs_rename(ino_t old_dir_nr, char *old_name, ino_t new_dir_nr,
        return(EBUSY);
 
   /* Get new dir pnode */
-  if ((new_dirp = puffs_pn_nodewalk(global_pu, 0, &new_dir_nr)) == NULL) {
+  if ((new_dirp = puffs_pn_nodewalk(global_pu, find_inode_cb,
+    &new_dir_nr)) == NULL) {
         return(ENOENT);
   } else {
         if (new_dirp->pn_va.va_nlink == NO_LINK) {
@@ -345,7 +340,7 @@ int fs_unlink(ino_t dir_nr, char *name, int call)
   assert(pcn.pcn_namelen <= NAME_MAX);
   strcpy(pcn.pcn_name, name);
 
-  if ((pn_dir = puffs_pn_nodewalk(global_pu, 0, &dir_nr)) == NULL)
+  if ((pn_dir = puffs_pn_nodewalk(global_pu, find_inode_cb, &dir_nr)) == NULL)
        return(EINVAL);
 
   /* The last directory exists. Does the file also exist? */
@@ -388,12 +383,12 @@ int fs_unlink(ino_t dir_nr, char *name, int call)
  *===========================================================================*/
 static int remove_dir(
        struct puffs_node *pn_dir,      /* parent directory */
-       struct puffs_node *pn,          /* directory to be removed */
-       struct puffs_cn *pcn            /* Name, creads of directory */
+       struct puffs_node *pn,          /* directory to be removed */
+       struct puffs_cn *pcn            /* Name, creads of directory */
 )
 {
   /* A directory file has to be removed. Five conditions have to met:
-   *   - The file must be a directory
+   *   - The file must be a directory
    *   - The directory must be empty (except for . and ..)
    *   - The final component of the path must not be . or ..
    *   - The directory must not be the root of a mounted file system (VFS)
@@ -423,7 +418,7 @@ static int remove_dir(
 
   if (pn->pn_va.va_fileid == global_pu->pu_pn_root->pn_va.va_fileid)
        return(EBUSY); /* can't remove 'root' */
-  
+
   if (buildpath) {
        r = puffs_path_pcnbuild(global_pu, pcn, pn_dir);
        if (r) return(EINVAL);
@@ -444,8 +439,8 @@ static int remove_dir(
  *===========================================================================*/
 static int unlink_file(
        struct puffs_node *dirp,        /* parent directory of file */
-       struct puffs_node *pn,          /* pnode of file, may be NULL too. */
-       struct puffs_cn *pcn            /* Name, creads of file */
+       struct puffs_node *pn,          /* pnode of file, may be NULL too. */
+       struct puffs_cn *pcn            /* Name, creads of file */
 )
 {
 /* Unlink 'file_name'; pn must be the pnode of 'file_name' */
@@ -454,7 +449,7 @@ static int unlink_file(
   assert(pn != NULL);
 
   if (global_pu->pu_ops.puffs_node_remove == NULL)
-       return(EINVAL);
+       return(EINVAL);
 
   if (S_ISDIR(pn->pn_va.va_mode))
        return(EPERM);
diff --git a/minix/lib/libpuffs/main.c b/minix/lib/libpuffs/main.c
new file mode 100644 (file)
index 0000000..54e98f2
--- /dev/null
@@ -0,0 +1,147 @@
+
+#include "fs.h"
+
+static message fs_msg;
+static int fs_ipc_status;
+static int fs_pending;
+
+#define PUFFS_MAX_ARGS 20
+
+/*===========================================================================*
+ *                         sef_cb_init_fresh                                *
+ *===========================================================================*/
+static int sef_cb_init_fresh(int type, sef_init_info_t *info)
+{
+/* Initialize the Minix file server. */
+  return(OK);
+}
+
+/*===========================================================================*
+ *                        sef_cb_signal_handler                             *
+ *===========================================================================*/
+static void sef_cb_signal_handler(int signo)
+{
+  /* Only check for termination signal, ignore anything else. */
+  if (signo != SIGTERM) return;
+
+  exitsignaled = 1;
+  if (mounted)
+       fs_sync();
+
+  sef_cancel();
+}
+
+/*===========================================================================*
+ *                            sef_local_startup                             *
+ *===========================================================================*/
+static void sef_local_startup(void)
+{
+  /* Register init callbacks. */
+  sef_setcb_init_fresh(sef_cb_init_fresh);
+
+  /* Register signal callbacks. */
+  sef_setcb_signal_handler(sef_cb_signal_handler);
+
+  /* Let SEF perform startup. */
+  sef_startup();
+}
+
+/*===========================================================================*
+ *                             get_work                                     *
+ *===========================================================================*/
+static int get_work(message *msg, int *ipc_status)
+{
+  int r;
+
+  for (;;) {
+       if ((r = sef_receive_status(ANY, msg, ipc_status)) != OK) {
+               if (r == EINTR) /* sef_cancel from signal handler? */
+                       break; /* see if we can exit the main loop */
+               panic("sef_receive failed: %d", r);
+       }
+       if (msg->m_source == VFS_PROC_NR)
+               break;
+       lpuffs_debug("libpuffs: unexpected source %d\n", msg->m_source);
+  }
+
+  return r;
+}
+
+int __wrap_main(int argc, char *argv[]);
+int __real_main(int argc, char* argv[]);
+
+int __wrap_main(int argc, char *argv[])
+{
+  int i;
+  int new_argc = 0;
+  static char* new_argv[PUFFS_MAX_ARGS];
+  char *name;
+
+  /* SEF local startup. */
+  env_setargs(argc, argv);
+  sef_local_startup();
+
+  global_kcred.pkcr_type = PUFFCRED_TYPE_INTERNAL;
+
+  if (argc < 3) {
+       panic("Unexpected arguments, use:\
+               mount -t fs /dev/ /dir [-o option1,option2]\n");
+  }
+
+  name = argv[0] + strlen(argv[0]);
+  while (*name != '/' && name != argv[0])
+         name--;
+  if (name != argv[0])
+         name++;
+  strcpy(fs_name, name);
+
+  new_argv[new_argc] = argv[0];
+  new_argc++;
+
+  for (i = 1; i < argc; i++) {
+       if (new_argc >= PUFFS_MAX_ARGS) {
+               panic("Too many arguments, change PUFFS_MAX_ARGS");
+       }
+       new_argv[new_argc] = argv[i];
+       new_argc++;
+  }
+
+  assert(new_argc > 0);
+
+  /* Get the mount request from VFS, so we can deal with it later. */
+  (void)get_work(&fs_msg, &fs_ipc_status);
+  fs_pending = TRUE;
+
+  return __real_main(new_argc, new_argv);
+}
+
+/*
+ * Receive a message unless one was already pending.  Process the message, and
+ * send a reply if necessary.  Return whether puffs should keep running.
+ */
+int
+lpuffs_pump(void)
+{
+
+       if (fs_pending == TRUE || get_work(&fs_msg, &fs_ipc_status) == OK) {
+               fs_pending = FALSE;
+
+               fsdriver_process(&puffs_table, &fs_msg, fs_ipc_status, FALSE);
+       }
+
+       return mounted || !exitsignaled;
+}
+
+/*
+ * Initialize MINIX3-specific settings.
+ */
+void
+lpuffs_init(struct puffs_usermount * pu)
+{
+
+       buildpath = pu->pu_flags & PUFFS_FLAG_BUILDPATH; /* XXX */
+
+       LIST_INIT(&pu->pu_pnode_removed_lst);
+
+       global_pu = pu;
+}
similarity index 90%
rename from lib/libpuffs/misc.c
rename to minix/lib/libpuffs/misc.c
index f58c225edfa079a8bb63cd2104bb20d23960e6f8..19391e8c41e80d907e969b423fb54f2a1df676df 100644 (file)
@@ -3,10 +3,6 @@
  */
 
 #include "fs.h"
-#include <assert.h>
-
-#include "puffs.h"
-#include "puffs_priv.h"
 
 /*===========================================================================*
  *                             fs_sync                                      *
similarity index 92%
rename from lib/libpuffs/mount.c
rename to minix/lib/libpuffs/mount.c
index 237744e150aff1c3d0e34852127bef58a5e0c9c5..c3d712f3db5e3d0636fb2cf637797760e4d2f0b5 100644 (file)
@@ -4,11 +4,8 @@
 
 #include "fs.h"
 #include <fcntl.h>
-#include <string.h>
 #include <minix/vfsif.h>
 
-#include "puffs_priv.h"
-
 /*===========================================================================*
  *                             fs_mount                                     *
  *===========================================================================*/
@@ -51,7 +48,7 @@ int fs_mountpt(ino_t ino_nr)
   struct puffs_node *pn;
   mode_t bits;
 
-  if ((pn = puffs_pn_nodewalk(global_pu, 0, &ino_nr)) == NULL)
+  if ((pn = puffs_pn_nodewalk(global_pu, find_inode_cb, &ino_nr)) == NULL)
        return(EINVAL);
 
   if (pn->pn_mountpoint) r = EBUSY;
@@ -77,10 +74,10 @@ void fs_unmount(void)
   /* Always force unmounting, as VFS will not tolerate failure. */
   error = global_pu->pu_ops.puffs_fs_unmount(global_pu, MNT_FORCE);
   if (error) {
-       lpuffs_debug("user handler failed to unmount filesystem!\
+       lpuffs_debug("user handler failed to unmount filesystem!\
                Force unmount!\n");
-  } 
-  
+  }
+
   fs_sync();
 
   /* Finish off the unmount. */
similarity index 94%
rename from lib/libpuffs/open.c
rename to minix/lib/libpuffs/open.c
index 6fbe414cf1e13ac39767620757759f158a4a48fe..ccd588572c76f34d438a4d0adf5e0591bdda21db 100644 (file)
@@ -3,12 +3,6 @@
  */
 
 #include "fs.h"
-#include <string.h>
-#include <assert.h>
-
-#include "puffs.h"
-#include "puffs_priv.h"
-
 
 /*===========================================================================*
  *                             fs_create                                    *
@@ -27,7 +21,7 @@ int fs_create(ino_t dir_nr, char *name, mode_t mode, uid_t uid, gid_t gid,
   struct timespec cur_time;
 
   if (global_pu->pu_ops.puffs_node_create == NULL) {
-       lpuffs_debug("No puffs_node_create");
+       lpuffs_debug("No puffs_node_create");
        return(ENFILE);
   }
 
@@ -37,14 +31,14 @@ int fs_create(ino_t dir_nr, char *name, mode_t mode, uid_t uid, gid_t gid,
   strcpy(pcn.pcn_name, name);
 
   /* Get last directory pnode (i.e., directory that will hold the new pnode) */
-  if ((pn_dir = puffs_pn_nodewalk(global_pu, 0, &dir_nr)) == NULL)
+  if ((pn_dir = puffs_pn_nodewalk(global_pu, find_inode_cb, &dir_nr)) == NULL)
        return(ENOENT);
 
   memset(&pni, 0, sizeof(pni));
   pni.pni_cookie = (void** )&pn;
 
   (void)clock_time(&cur_time);
-  
+
   memset(&va, 0, sizeof(va));
   va.va_type = VREG;
   va.va_mode = mode;
@@ -111,7 +105,7 @@ int fs_mknod(ino_t dir_nr, char *name, mode_t mode, uid_t uid, gid_t gid,
   struct timespec cur_time;
 
   if (global_pu->pu_ops.puffs_node_mknod == NULL) {
-       lpuffs_debug("No puffs_node_mknod");
+       lpuffs_debug("No puffs_node_mknod");
        return(ENFILE);
   }
 
@@ -121,7 +115,7 @@ int fs_mknod(ino_t dir_nr, char *name, mode_t mode, uid_t uid, gid_t gid,
   strcpy(pcn.pcn_name, name);
 
   /* Get last directory pnode */
-  if ((pn_dir = puffs_pn_nodewalk(global_pu, 0, &dir_nr)) == NULL)
+  if ((pn_dir = puffs_pn_nodewalk(global_pu, find_inode_cb, &dir_nr)) == NULL)
        return(ENOENT);
 
   memset(&pni, 0, sizeof(pni));
@@ -183,7 +177,7 @@ int fs_mkdir(ino_t dir_nr, char *name, mode_t mode, uid_t uid, gid_t gid)
   struct timespec cur_time;
 
   if (global_pu->pu_ops.puffs_node_mkdir == NULL) {
-       lpuffs_debug("No puffs_node_mkdir");
+       lpuffs_debug("No puffs_node_mkdir");
        return(ENFILE);
   }
 
@@ -193,9 +187,9 @@ int fs_mkdir(ino_t dir_nr, char *name, mode_t mode, uid_t uid, gid_t gid)
   strcpy(pcn.pcn_name, name);
 
   /* Get last directory pnode */
-  if ((pn_dir = puffs_pn_nodewalk(global_pu, 0, &dir_nr)) == NULL)
+  if ((pn_dir = puffs_pn_nodewalk(global_pu, find_inode_cb, &dir_nr)) == NULL)
        return(ENOENT);
-  
+
   (void)clock_time(&cur_time);
 
   memset(&pni, 0, sizeof(pni));
@@ -283,7 +277,7 @@ int fs_slink(ino_t dir_nr, char *name, uid_t uid, gid_t gid,
        return(ENAMETOOLONG);
   }
 
-  if ((pn_dir = puffs_pn_nodewalk(global_pu, 0, &dir_nr)) == NULL)
+  if ((pn_dir = puffs_pn_nodewalk(global_pu, find_inode_cb, &dir_nr)) == NULL)
        return(EINVAL);
 
   memset(&pni, 0, sizeof(pni));
similarity index 94%
rename from lib/libpuffs/path.c
rename to minix/lib/libpuffs/path.c
index 76a4de60b18c2ba6d381c6dfdd284d2323b00541..5c08eef29691768f515dc3b5f79ad9e93f79abab 100644 (file)
 #include <sys/stat.h>
 #include <sys/types.h>
 
-#include <assert.h>
-#include <errno.h>
-#include <puffs.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "puffs.h"
-#include "puffs_priv.h"
-
-
 /*===========================================================================*
  *                             fs_lookup                                    *
  *===========================================================================*/
@@ -31,7 +21,7 @@ int fs_lookup(ino_t dir_nr, char *name, struct fsdriver_node *node,
   struct puffs_node *pn, *pn_dir;
 
   /* Find the pnode of the directory node. */
-  if ((pn_dir = puffs_pn_nodewalk(global_pu, 0, &dir_nr)) == NULL) {
+  if ((pn_dir = puffs_pn_nodewalk(global_pu, find_inode_cb, &dir_nr)) == NULL) {
        lpuffs_debug("nodewalk failed\n");
        return(EINVAL);
   }
similarity index 91%
rename from lib/libpuffs/protect.c
rename to minix/lib/libpuffs/protect.c
index b612552fc59a616545627dd3576921df7fd9cbb8..ef34808484b29177ec6cadf0ae4088f6068943b4 100644 (file)
@@ -21,9 +21,9 @@ int fs_chmod(ino_t ino_nr, mode_t *mode)
   if (global_pu->pu_ops.puffs_node_setattr == NULL)
        return(EINVAL);
 
-  if ((pn = puffs_pn_nodewalk(global_pu, 0, &ino_nr)) == NULL)
+  if ((pn = puffs_pn_nodewalk(global_pu, find_inode_cb, &ino_nr)) == NULL)
        return(EINVAL);
-   
+
   puffs_vattr_null(&va);
   /* Clear setgid bit if file is not in caller's grp */
   va.va_mode = (pn->pn_va.va_mode & ~ALL_MODES) | (*mode & ALL_MODES);
@@ -48,7 +48,7 @@ int fs_chown(ino_t ino_nr, uid_t uid, gid_t gid, mode_t *mode)
   struct vattr va;
   PUFFS_MAKECRED(pcr, &global_kcred);
 
-  if ((pn = puffs_pn_nodewalk(global_pu, 0, &ino_nr)) == NULL)
+  if ((pn = puffs_pn_nodewalk(global_pu, find_inode_cb, &ino_nr)) == NULL)
        return(EINVAL);
 
   puffs_vattr_null(&va);
similarity index 95%
rename from lib/libpuffs/proto.h
rename to minix/lib/libpuffs/proto.h
index 35a14826d829dbd742b1f6b43cb093054adc3a7a..b566a1ba921e3cc6b5dc16db43e1dc249472bd83 100644 (file)
@@ -61,8 +61,8 @@ int fs_statvfs(struct statvfs *st);
 int fs_utime(ino_t ino_nr, struct timespec *atime, struct timespec *mtime);
 
 /* utility.c */
+void *find_inode_cb(struct puffs_usermount *pu, struct puffs_node *pn,
+       void *arg);
 int update_timens(struct puffs_node *pn, int fl, struct timespec *);
-void lpuffs_debug(const char *format, ...)
-       __attribute__((__format__(__printf__, 1, 2)));
 
 #endif /* PUFFS_PROTO_H */
similarity index 92%
rename from lib/libpuffs/read.c
rename to minix/lib/libpuffs/read.c
index a528a708bc8702a72e4735a40b5fb06f6f97d4a4..5fdbe5b5045f2c996fc9d59955c55ea2b85a6c10 100644 (file)
@@ -4,15 +4,9 @@
 
 #include "fs.h"
 #include <stddef.h>
-#include <string.h>
-#include <stdlib.h>
 #include <dirent.h>
-#include <assert.h>
 #include <sys/param.h>
 
-#include "puffs.h"
-#include "puffs_priv.h"
-
 
 #define GETDENTS_BUFSIZ  4096
 static char getdents_buf[GETDENTS_BUFSIZ];
@@ -32,7 +26,7 @@ ssize_t fs_read(ino_t ino_nr, struct fsdriver_data *data, size_t bytes,
   struct puffs_node *pn;
   PUFFS_MAKECRED(pcr, &global_kcred);
 
-  if ((pn = puffs_pn_nodewalk(global_pu, 0, &ino_nr)) == NULL) {
+  if ((pn = puffs_pn_nodewalk(global_pu, find_inode_cb, &ino_nr)) == NULL) {
        lpuffs_debug("walk failed...\n");
         return(EINVAL);
   }
@@ -76,7 +70,7 @@ ssize_t fs_write(ino_t ino_nr, struct fsdriver_data *data, size_t bytes,
   struct timespec cur_time;
   PUFFS_MAKECRED(pcr, &global_kcred);
 
-  if ((pn = puffs_pn_nodewalk(global_pu, 0, &ino_nr)) == NULL) {
+  if ((pn = puffs_pn_nodewalk(global_pu, find_inode_cb, &ino_nr)) == NULL) {
        lpuffs_debug("walk failed...\n");
         return(EINVAL);
   }
@@ -127,7 +121,7 @@ ssize_t fs_getdents(ino_t ino_nr, struct fsdriver_data *data, size_t bytes,
   int eofflag = 0;
   PUFFS_MAKECRED(pcr, &global_kcred);
 
-  if ((pn = puffs_pn_nodewalk(global_pu, 0, &ino_nr)) == NULL) {
+  if ((pn = puffs_pn_nodewalk(global_pu, find_inode_cb, &ino_nr)) == NULL) {
        lpuffs_debug("walk failed...\n");
         return(EINVAL);
   }
similarity index 91%
rename from lib/libpuffs/stadir.c
rename to minix/lib/libpuffs/stadir.c
index c617bc4bfbeaac2db617199fc6c76a9823e61a5b..d6decd3649d672cbd46a7afddf6e905df30f5303 100644 (file)
@@ -3,12 +3,6 @@
  */
 
 #include "fs.h"
-#include <sys/stat.h>
-#include <sys/statvfs.h>
-
-#include "puffs.h"
-#include "puffs_priv.h"
-
 
 /*===========================================================================*
  *                             fs_stat                                      *
@@ -26,8 +20,8 @@ int fs_stat(ino_t ino_nr, struct stat *statbuf)
        return(EINVAL);
   }
 
-  if ((pn = puffs_pn_nodewalk(global_pu, 0, &ino_nr)) == NULL) {
-       lpuffs_debug("walk failed...\n");
+  if ((pn = puffs_pn_nodewalk(global_pu, find_inode_cb, &ino_nr)) == NULL) {
+       lpuffs_debug("walk failed...\n");
         return(EINVAL);
   }
 
similarity index 87%
rename from lib/libpuffs/time.c
rename to minix/lib/libpuffs/time.c
index 4edcca59fc4d5ab40c46d9ad86341ce29d30b727..73c07aaf6746c4de6071662920239ab3dfc3d89a 100644 (file)
@@ -3,8 +3,6 @@
  */
 
 #include "fs.h"
-#include "puffs.h"
-#include "puffs_priv.h"
 
 
 /*===========================================================================*
@@ -19,7 +17,7 @@ int fs_utime(ino_t ino_nr, struct timespec *atime, struct timespec *mtime)
   if (global_pu->pu_ops.puffs_node_setattr == NULL)
        return(EINVAL);
 
-  if( (pn = puffs_pn_nodewalk(global_pu, 0, &ino_nr)) == NULL)
+  if( (pn = puffs_pn_nodewalk(global_pu, find_inode_cb, &ino_nr)) == NULL)
         return(EINVAL);
 
   puffs_vattr_null(&va);
similarity index 84%
rename from lib/libpuffs/utility.c
rename to minix/lib/libpuffs/utility.c
index bbd5123e2e3b43a51e4c9a30155325a8922b72b8..4c0a6bad8be1a61bbdcbec107fb5ef3d00e71210 100644 (file)
@@ -4,12 +4,21 @@
 
 #include "fs.h"
 
-#include <assert.h>
 #include <stdarg.h>
 
-#include "puffs.h"
-#include "puffs_priv.h"
+/*
+ * Match by inode number in a puffs_pn_nodewalk call.  This should not exist.
+ */
+void *
+find_inode_cb(struct puffs_usermount * __unused pu, struct puffs_node * pn,
+       void * arg)
+{
 
+       if (pn->pn_va.va_fileid == *(ino_t *)arg)
+               return pn;
+       else
+               return NULL;
+}
 
 /*===========================================================================*
  *                             update_timens                                *
@@ -31,7 +40,7 @@ int update_timens(struct puffs_node *pn, int flags, struct timespec *t)
        new_time = *t;
   else
        (void)clock_time(&new_time);
-  
+
   puffs_vattr_null(&va);
   /* librefuse modifies atime and mtime together,
    * so set old values to avoid setting either one
@@ -57,7 +66,7 @@ int update_timens(struct puffs_node *pn, int flags, struct timespec *t)
  *                             lpuffs_debug                                 *
  *===========================================================================*/
 void lpuffs_debug(const char *format, ...)
-{   
+{
   char buffer[256];
   va_list args;
   va_start (args, format);