]> Zhao Yanbai Git Server - minix.git/commitdiff
libvtreefs: use libfsdriver 48/2748/3
authorDavid van Moolenbroek <david@minix3.org>
Sun, 24 Aug 2014 09:55:05 +0000 (09:55 +0000)
committerDavid van Moolenbroek <david@minix3.org>
Thu, 18 Sep 2014 12:46:26 +0000 (12:46 +0000)
Change-Id: I0e6446bd0ccc3b89edc237be441ebfd92585f352

18 files changed:
minix/drivers/system/gpio/Makefile
minix/fs/procfs/Makefile
minix/fs/procfs/main.c
minix/lib/libvtreefs/Makefile
minix/lib/libvtreefs/glo.h
minix/lib/libvtreefs/inc.h
minix/lib/libvtreefs/inode.c
minix/lib/libvtreefs/inode.h
minix/lib/libvtreefs/link.c
minix/lib/libvtreefs/mount.c
minix/lib/libvtreefs/path.c
minix/lib/libvtreefs/proto.h
minix/lib/libvtreefs/read.c
minix/lib/libvtreefs/stadir.c
minix/lib/libvtreefs/table.c
minix/lib/libvtreefs/utility.c [deleted file]
minix/lib/libvtreefs/vtreefs.c
minix/servers/devman/Makefile

index 6ebe8007069d039272205a132c1894a1710cf913..ef195ea068bc54e33e4bf618802d23b9a66cd0f4 100644 (file)
@@ -2,8 +2,8 @@
 PROG=  gpio
 SRCS=  gpio.c
 
-DPADD+=        ${LIBBLOCKDRIVER} ${LIBSYS} ${LIBGPIO} ${LIBCLKCONF}
-LDADD+=        -lvtreefs -lsys -lgpio -lclkconf
+DPADD+=        ${LIBVTREEFS} ${LIBFSDRIVER} ${LIBSYS} ${LIBGPIO} ${LIBCLKCONF}
+LDADD+=        -lvtreefs -lfsdriver -lsys -lgpio -lclkconf
 
 # This is a system driver.
 CPPFLAGS+= -D_SYSTEM=1
index 04b619601e8861927290bf6167d55a01cc9152e6..51c87dc4eb56f7fb3dab0e437e257e87438410e8 100644 (file)
@@ -8,7 +8,7 @@ CPPFLAGS+= -I${NETBSDSRCDIR}/minix
 CPPFLAGS+= -I${NETBSDSRCDIR}/minix/fs
 CPPFLAGS+= -I${NETBSDSRCDIR}/minix/servers
 
-DPADD+=        ${LIBVTREEFS} ${LIBMINIXFS}
-LDADD+=        -lvtreefs -lminixfs
+DPADD+=        ${LIBVTREEFS} ${LIBFSDRIVER}
+LDADD+=        -lvtreefs -lfsdriver
 
 .include <minix.service.mk>
index 6a99bdc891df546f660c158f9784da8859ac547f..180543aa2debc41c452ffa26e0adcd7cfe6fac23 100644 (file)
@@ -89,7 +89,7 @@ int main(void)
        stat.size       = 0;
        stat.dev        = NO_DEV;
 
-       /* Start VTreeFS. This call does not return. */
+       /* Start VTreeFS. */
        start_vtreefs(&hooks, NR_INODES, &stat, NR_PROCS + NR_TASKS);
 
        return 0;
index 35f091728dbbc6806dbdea44e403159d7e4d39a0..379d9b3cb664a425b3fdfd341a097b86a6f8c244 100644 (file)
@@ -1,8 +1,8 @@
+# Makefile for libvtreefs
+
 NOGCCERROR=yes
-NOCLANGERROR=yes
-CPPFLAGS+= -D_MINIX_SYSTEM
 
-# Makefile for libvtreefs
+CPPFLAGS+= -D_MINIX_SYSTEM
 
 LIB=   vtreefs
 
@@ -17,7 +17,6 @@ SRCS= \
        sdbm.c \
        stadir.c \
        table.c \
-       utility.c \
        vtreefs.c
 
 .include <bsd.lib.mk>
index c770ae5d0235e5df523d07612bffb1772727b413..0e5fd1a5940ddd5d5c561497f5a4d3d8df9cc24b 100644 (file)
@@ -8,13 +8,8 @@
 
 EXTERN struct fs_hooks *vtreefs_hooks;
 
-EXTERN message fs_m_in;
-EXTERN message fs_m_out;
-
 EXTERN dev_t fs_dev;
 
-EXTERN int fs_mounted;
-
-extern int(*fs_call_vec[]) (void);
+extern struct fsdriver vtreefs_table;
 
 #endif /* _VTREEFS_GLO_H */
index 15249f1d852c74cce24eb61692d352dedb498bca..acef05f17db8d72365d799ac3342c86e7ec43da9 100644 (file)
@@ -1,29 +1,8 @@
-#define _SYSTEM                1       /* tell headers that this is the kernel */
+#include <minix/drivers.h>
+#include <minix/vtreefs.h>
+#include <minix/fsdriver.h>
 
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
 #include <assert.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/queue.h>
-#include <sys/ucred.h>
-#include <limits.h>
-#include <unistd.h>
-#include <signal.h>
-#include <errno.h>
-
-#include <minix/config.h>
-#include <minix/callnr.h>
-#include <minix/type.h>
-#include <minix/const.h>
-#include <minix/com.h>
-#include <minix/syslib.h>
-#include <minix/sysutil.h>
-#include <minix/bitmap.h>
-#include <minix/vfsif.h>
-#include <minix/endpoint.h>
-#include <minix/vtreefs.h>
 
 #include "glo.h"
 #include "proto.h"
index c7fdda1b552758e52e51904f0fd236ba51f154aa..9aaef3233d0e1f522141fb00391bc2402893c5a5 100644 (file)
@@ -33,7 +33,7 @@ void init_inodes(unsigned int inodes, struct inode_stat *stat,
        /* Initialize the inode-related state.
         */
        struct inode *node;
-       int i;
+       unsigned int i;
 
        assert(inodes > 0);
        assert(nr_indexed_entries >= 0);
@@ -134,7 +134,7 @@ static int parent_index_hash(struct inode *parent, index_t index)
 /*===========================================================================*
  *                             purge_inode                                  *
  *===========================================================================*/
-void purge_inode(struct inode *parent)
+static void purge_inode(struct inode *parent)
 {
        /* Delete a deletable inode to make room for a new inode.
         */
@@ -149,7 +149,7 @@ void purge_inode(struct inode *parent)
         */
        static int last_checked = 0;
        struct inode *node;
-       int count;
+       unsigned int count;
 
        assert(TAILQ_EMPTY(&unused_inodes));
 
@@ -484,7 +484,6 @@ void ref_inode(struct inode *node)
         */
 
        CHECK_INODE(node);
-       assert(node->i_count >= 0);
 
        node->i_count++;
 }
@@ -581,7 +580,7 @@ int is_inode_deleted(struct inode *node)
 /*===========================================================================*
  *                             fs_putnode                                   *
  *===========================================================================*/
-int fs_putnode(void)
+int fs_putnode(ino_t ino_nr, unsigned int count)
 {
        /* Find the inode specified by the request message, and decrease its
         * reference count.
@@ -589,14 +588,13 @@ int fs_putnode(void)
        struct inode *node;
 
        /* Get the inode specified by its number. */
-       if ((node = find_inode(fs_m_in.m_vfs_fs_putnode.inode)) == NULL)
+       if ((node = find_inode(ino_nr)) == NULL)
                return EINVAL;
 
        /* Decrease the reference count. */
-       node->i_count -= fs_m_in.m_vfs_fs_putnode.count - 1;
-
-       assert(node->i_count > 0);
+       assert(node->i_count >= count);
 
+       node->i_count -= count - 1;
        put_inode(node);
 
        return OK;
index a20445bf757ac50517021c8c74e85bca67c9d331..6160ac7711ea96e791f3e1248906a021a8cb95b1 100644 (file)
@@ -18,7 +18,7 @@ struct inode {
        /* Inode metadata */
        struct inode_stat i_stat;       /* POSIX attributes */
        char i_name[PNAME_MAX + 1];     /* name of the inode in the parent */
-       int i_count;                    /* reference count */
+       unsigned int i_count;           /* reference count */
        index_t i_index;                /* index number in parent / NO_INDEX */
        int i_indexed;                  /* number of indexed entries */
        cbdata_t i_cbdata;              /* callback data */
index a1d4d9908fcf07939dadc4ece325ecde4f0ad1ef..61711b2285b179fed4b2804290be4a3f5cdf85c1 100644 (file)
@@ -5,7 +5,7 @@
 /*===========================================================================*
  *                             fs_rdlink                                    *
  *===========================================================================*/
-int fs_rdlink(void)
+ssize_t fs_rdlink(ino_t ino_nr, struct fsdriver_data *data, size_t bytes)
 {
        /* Retrieve symbolic link target.
         */
@@ -14,7 +14,7 @@ int fs_rdlink(void)
        size_t len;
        int r;
 
-       if ((node = find_inode(fs_m_in.m_vfs_fs_rdlink.inode)) == NULL)
+       if ((node = find_inode(ino_nr)) == NULL)
                return EINVAL;
 
        /* Call the rdlink hook. */
@@ -28,14 +28,12 @@ int fs_rdlink(void)
        len = strlen(path);
        assert(len > 0 && len < sizeof(path));
 
-       if (len > fs_m_in.m_vfs_fs_rdlink.mem_size)
-               len = fs_m_in.m_vfs_fs_rdlink.mem_size;
+       if (len > bytes)
+               len = bytes;
 
        /* Copy out the result. */
-       r = sys_safecopyto(fs_m_in.m_source, fs_m_in.m_vfs_fs_rdlink.grant, 0,
-               (vir_bytes) path, len);
-       if (r != OK) return r;
+       if ((r = fsdriver_copyout(data, 0, path, len)) != OK)
+               return r;
 
-       fs_m_out.m_fs_vfs_rdlink.nbytes = len;
-       return OK;
+       return len;
 }
index ee18941f07f4d1d340742937e8b44da07086a33c..e9bfeaf6d9e69026b4eea3c8da8da81c08d3da4b 100644 (file)
@@ -1,21 +1,23 @@
 /* VTreeFS - mount.c - by Alen Stojanov and David van Moolenbroek */
 
 #include "inc.h"
+#include <minix/vfsif.h>
 
 /*===========================================================================*
- *                             fs_readsuper                                 *
+ *                             fs_mount                                     *
  *===========================================================================*/
-int fs_readsuper(void)
+int fs_mount(dev_t dev, unsigned int flags, struct fsdriver_node *root_node,
+       unsigned int *res_flags)
 {
        /* This function gets the root inode and sends back its details.
         */
        struct inode *root;
 
        /* Get the device number, for stat requests. */
-       fs_dev = fs_m_in.m_vfs_fs_readsuper.device;
+       fs_dev = dev;
 
        /* The VTreeFS must not be mounted as a root file system. */
-       if (fs_m_in.m_vfs_fs_readsuper.flags & REQ_ISROOT)
+       if (flags & REQ_ISROOT)
                return EINVAL;
 
        /* Get the root inode and increase its reference count. */
@@ -27,15 +29,14 @@ int fs_readsuper(void)
                vtreefs_hooks->init_hook();
 
        /* Return the root inode's properties. */
-       fs_m_out.m_fs_vfs_readsuper.inode = get_inode_number(root);
-       fs_m_out.m_fs_vfs_readsuper.mode = root->i_stat.mode;
-       fs_m_out.m_fs_vfs_readsuper.file_size = root->i_stat.size;
-       fs_m_out.m_fs_vfs_readsuper.uid = root->i_stat.uid;
-       fs_m_out.m_fs_vfs_readsuper.gid = root->i_stat.gid;
-       fs_m_out.m_fs_vfs_readsuper.device = NO_DEV;
-       fs_m_out.m_fs_vfs_readsuper.flags = RES_NOFLAGS;
+       root_node->fn_ino_nr = get_inode_number(root);
+       root_node->fn_mode = root->i_stat.mode;
+       root_node->fn_size = root->i_stat.size;
+       root_node->fn_uid = root->i_stat.uid;
+       root_node->fn_gid = root->i_stat.gid;
+       root_node->fn_dev = NO_DEV;
 
-       fs_mounted = TRUE;
+       *res_flags = RES_NOFLAGS;
 
        return OK;
 }
@@ -43,7 +44,7 @@ int fs_readsuper(void)
 /*===========================================================================*
  *                             fs_unmount                                   *
  *===========================================================================*/
-int fs_unmount(void)
+void fs_unmount(void)
 {
        /* Unmount the file system.
         */
@@ -57,9 +58,4 @@ int fs_unmount(void)
        /* The system is unmounted. Call the cleanup hook. */
        if (vtreefs_hooks->cleanup_hook != NULL)
                vtreefs_hooks->cleanup_hook();
-
-       /* We can now be shut down safely. */
-       fs_mounted = FALSE;
-
-       return OK;
 }
index a06c9709cc48228d9bc0b9bc1dbebbdf3c6aee30..686a79e3a5c87f53feb12a3e9be503285bc5fb58 100644 (file)
 
 #include "inc.h"
 
-/*===========================================================================*
- *                             access_as_dir                                *
- *===========================================================================*/
-static int access_as_dir(struct inode *node, vfs_ucred_t *ucred)
-{
-       /* Check whether the given inode may be accessed as directory.
-        * Return OK or an appropriate error code.
-        */
-       mode_t mask;
-       int i;
-
-       /* The inode must be a directory to begin with. */
-       if (!S_ISDIR(node->i_stat.mode)) return ENOTDIR;
-
-       /* The caller must have search access to the directory.
-        * Root always does.
-        */
-       if (ucred->vu_uid == SUPER_USER) return OK;
-
-       if (ucred->vu_uid == node->i_stat.uid) mask = S_IXUSR;
-       else if (ucred->vu_gid == node->i_stat.gid) mask = S_IXGRP;
-       else {
-               mask = S_IXOTH;
-
-               for (i = 0; i < ucred->vu_ngroups; i++) {
-                       if (ucred->vu_sgroups[i] == node->i_stat.gid) {
-                               mask = S_IXGRP;
-
-                               break;
-                       }
-               }
-       }
-
-       return (node->i_stat.mode & mask) ? OK : EACCES;
-}
-
-/*===========================================================================*
- *                             next_name                                    *
- *===========================================================================*/
-static int next_name(char **ptr, char **start, char name[PNAME_MAX+1])
-{
-       /* Get the next path component from a path.
-        */
-       char *p;
-       int i;
-
-       for (p = *ptr; *p == '/'; p++);
-
-       *start = p;
-
-       if (*p) {
-               for (i = 0; *p && *p != '/' && i <= PNAME_MAX; p++, i++)
-                       name[i] = *p;
-
-               if (i > PNAME_MAX)
-                       return ENAMETOOLONG;
-
-               name[i] = 0;
-       } else {
-               strcpy(name, ".");
-       }
-
-       *ptr = p;
-       return OK;
-}
-
-/*===========================================================================*
- *                             go_up                                        *
- *===========================================================================*/
-static int go_up(struct inode *node, struct inode **parent)
-{
-       /* Given a directory inode, progress into the parent directory.
-        */
-
-       *parent = get_parent_inode(node);
-
-       /* Trapped in a deleted directory? Should not be possible. */
-       if (*parent == NULL)
-               return ENOENT;
-
-       ref_inode(*parent);
-
-       return OK;
-}
-
-/*===========================================================================*
- *                             go_down                                      *
- *===========================================================================*/
-static int go_down(struct inode *parent, char *name, struct inode **child)
-{
-       /* Given a directory inode and a name, progress into a directory entry.
-        */
-       int r;
-
-       /* Call the lookup hook, if present, before doing the actual lookup. */
-       if (!is_inode_deleted(parent) && vtreefs_hooks->lookup_hook != NULL) {
-               r = vtreefs_hooks->lookup_hook(parent, name,
-                       get_inode_cbdata(parent));
-               if (r != OK) return r;
-       }
-
-       if ((*child = get_inode_by_name(parent, name)) == NULL)
-               return ENOENT;
-
-       ref_inode(*child);
-
-       return OK;
-}
-
-/*===========================================================================*
- *                             resolve_link                                 *
- *===========================================================================*/
-static int resolve_link(struct inode *node, char pptr[PATH_MAX], char *tail)
-{
-       /* Given a symbolic link, resolve and return the contents of the link.
-        */
-       char path[PATH_MAX];
-       size_t len;
-       int r;
-
-       assert(vtreefs_hooks->rdlink_hook != NULL);
-       assert(!is_inode_deleted(node));
-
-       r = vtreefs_hooks->rdlink_hook(node, path, sizeof(path),
-               get_inode_cbdata(node));
-       if (r != OK) return r;
-
-       len = strlen(path);
-       assert(len > 0 && len < sizeof(path));
-
-       if (len + strlen(tail) >= sizeof(path))
-               return ENAMETOOLONG;
-
-       strlcat(path, tail, sizeof(path));
-
-       strlcpy(pptr, path, PATH_MAX);
-
-       return OK;
-}
-
 /*===========================================================================*
  *                             fs_lookup                                    *
  *===========================================================================*/
-int fs_lookup(void)
+int fs_lookup(ino_t dir_nr, char *name, struct fsdriver_node *node_details,
+       int *is_mountpt)
 {
        /* Resolve a path string to an inode.
         */
-       ino_t dir_ino_nr, root_ino_nr;
-       struct inode *cur_ino, *next_ino, *root_ino;
-       char path[PATH_MAX], name[PNAME_MAX+1];
-       char *ptr, *last;
-       vfs_ucred_t ucred;
-       size_t len;
-       int r, r2, symloop;
-
-       dir_ino_nr = fs_m_in.m_vfs_fs_lookup.dir_ino;
-       root_ino_nr = fs_m_in.m_vfs_fs_lookup.root_ino;
-       len = fs_m_in.m_vfs_fs_lookup.path_len;
-
-       /* Fetch the path name. */
-       if (len < 1 || len > PATH_MAX)
-               return EINVAL;
-
-       r = sys_safecopyfrom(fs_m_in.m_source,
-               fs_m_in.m_vfs_fs_lookup.grant_path, 0, (vir_bytes) path,
-               (phys_bytes) len);
-       if (r != OK) return r;
-
-       if (path[len-1] != 0) return EINVAL;
-
-       /* Fetch the caller's credentials. */
-       if (fs_m_in.m_vfs_fs_lookup.flags & PATH_GET_UCRED) {
-               assert(fs_m_in.m_vfs_fs_lookup.ucred_size == sizeof(ucred));
-
-               r = sys_safecopyfrom(fs_m_in.m_source,
-                       fs_m_in.m_vfs_fs_lookup.grant_ucred, 0,
-                       (vir_bytes) &ucred, fs_m_in.m_vfs_fs_lookup.ucred_size);
-
-               if (r != OK)
-                       return r;
-       }
-       else {
-               ucred.vu_uid = fs_m_in.m_vfs_fs_lookup.uid;
-               ucred.vu_gid = fs_m_in.m_vfs_fs_lookup.gid;
-               ucred.vu_ngroups = 0;
-       }
+       struct inode *node, *child;
+       int r;
 
-       /* Start the actual lookup. */
-       if ((cur_ino = get_inode(dir_ino_nr)) == NULL)
+       if ((node = find_inode(dir_nr)) == NULL)
                return EINVAL;
 
-       /* Chroot'ed environment? */
-       if (root_ino_nr > 0)
-               root_ino = find_inode(root_ino_nr);
-       else
-               root_ino = NULL;
+       if (!S_ISDIR(node->i_stat.mode))
+               return ENOTDIR;
 
-       symloop = 0;
-
-       for (ptr = last = path; ptr[0] != 0; ) {
-               /* There is more path to process. That means that the current
-                * file is now being accessed as a directory. Check type and
-                * permissions.
-                */
-               if ((r = access_as_dir(cur_ino, &ucred)) != OK)
-                       break;
+       if (strlen(name) > PNAME_MAX)
+               return ENAMETOOLONG;
 
-               /* Get the next path component. The result is a non-empty
-                * string.
+       if (!strcmp(name, ".")) {
+               /* Stay in the given directory. */
+               child = node;
+       } else if (!strcmp(name, "..")) {
+               /* Progress into the parent directory. */
+               if ((child = get_parent_inode(node)) == NULL)
+                       return ENOENT;  /* deleted? should not be possible */
+       } else {
+               /* Progress into a directory entry. Call the lookup hook, if
+                * present, before doing the actual lookup.
                 */
-               if ((r = next_name(&ptr, &last, name)) != OK)
-                       break;
-
-               if (!strcmp(name, ".") ||
-                               (cur_ino == root_ino && !strcmp(name, "..")))
-                       continue;
-
-               if (!strcmp(name, "..")) {
-                       if (cur_ino == get_root_inode())
-                               r = ELEAVEMOUNT;
-                       else
-                               r = go_up(cur_ino, &next_ino);
-               } else {
-                       r = go_down(cur_ino, name, &next_ino);
-
-                       /* Perform symlink resolution if we have to. */
-                       if (r == OK && S_ISLNK(next_ino->i_stat.mode) &&
-                               (ptr[0] != '\0' ||
-                               !(fs_m_in.m_vfs_fs_lookup.flags & PATH_RET_SYMLINK))) {
-
-                               if (++symloop == _POSIX_SYMLOOP_MAX) {
-                                       put_inode(next_ino);
-
-                                       r = ELOOP;
-
-                                       break;
-                               }
-
-                               /* Resolve the symlink, and append the
-                                * remaining unresolved part of the path.
-                                */
-                               r = resolve_link(next_ino, path, ptr);
-
-                               put_inode(next_ino);
-
-                               if (r != OK)
-                                       break;
-
-                               /* If the symlink is absolute, return it to
-                                * VFS.
-                                */
-                               if (path[0] == '/') {
-                                       r = ESYMLINK;
-                                       last = path;
-
-                                       break;
-                               }
-
-                               ptr = path;
-                               continue;
-                       }
+               if (!is_inode_deleted(node) &&
+                   vtreefs_hooks->lookup_hook != NULL) {
+                       r = vtreefs_hooks->lookup_hook(node, name,
+                               get_inode_cbdata(node));
+                       if (r != OK) return r;
                }
 
-               if (r != OK)
-                       break;
-
-               /* We have found a new file. Continue from this file. */
-               assert(next_ino != NULL);
-
-               put_inode(cur_ino);
-
-               cur_ino = next_ino;
+               if ((child = get_inode_by_name(node, name)) == NULL)
+                       return ENOENT;
        }
 
-       /* If an error occurred, close the file and return error information.
-        */
-       if (r != OK) {
-               put_inode(cur_ino);
-
-               /* We'd need support for this here. */
-               assert(r != EENTERMOUNT);
+       /* On success, open the resulting file and return its details. */
+       ref_inode(child);
 
-               /* Copy back the path if we resolved at least one symlink. */
-               if (symloop > 0 && (r == ELEAVEMOUNT || r == ESYMLINK)) {
-                       r2 = sys_safecopyto(fs_m_in.m_source,
-                               fs_m_in.m_vfs_fs_lookup.grant_path, 0,
-                               (vir_bytes) path, strlen(path) + 1);
-
-                       if (r2 != OK)
-                               r = r2;
-               }
-
-               if (r == ELEAVEMOUNT || r == ESYMLINK) {
-                       fs_m_out.m_fs_vfs_lookup.offset = (int) (last - path);
-                       fs_m_out.m_fs_vfs_lookup.symloop = symloop;
-               }
-
-               return r;
-       }
+       node_details->fn_ino_nr = get_inode_number(child);
+       node_details->fn_mode = child->i_stat.mode;
+       node_details->fn_size = child->i_stat.size;
+       node_details->fn_uid = child->i_stat.uid;
+       node_details->fn_gid = child->i_stat.gid;
+       node_details->fn_dev = child->i_stat.dev;
 
-       /* On success, leave the resulting file open and return its details. */
-       fs_m_out.m_fs_vfs_lookup.inode = get_inode_number(cur_ino);
-       fs_m_out.m_fs_vfs_lookup.mode = cur_ino->i_stat.mode;
-       fs_m_out.m_fs_vfs_lookup.file_size = cur_ino->i_stat.size;
-       fs_m_out.m_fs_vfs_lookup.uid = cur_ino->i_stat.uid;
-       fs_m_out.m_fs_vfs_lookup.gid = cur_ino->i_stat.gid;
-       fs_m_out.m_fs_vfs_lookup.device = cur_ino->i_stat.dev;
+       *is_mountpt = FALSE;
 
        return OK;
 }
index 6c558da7370a6ab5163192f4f6b5f6481b3266b8..6bc5083b1cc17d9477e739cb95052a4e9032a8f0 100644 (file)
@@ -11,31 +11,34 @@ void put_inode(struct inode *node);
 void ref_inode(struct inode *node);
 int get_inode_number(struct inode *node);
 int is_inode_deleted(struct inode *node);
-int fs_putnode(void);
+int fs_putnode(ino_t ino_nr, unsigned int count);
 
 /* link.c */
-int fs_rdlink(void);
+ssize_t fs_rdlink(ino_t ino_nr, struct fsdriver_data *data, size_t bytes);
 
 /* mount.c */
-int fs_readsuper(void);
-int fs_unmount(void);
+int fs_mount(dev_t dev, unsigned int flags, struct fsdriver_node *root_node,
+       unsigned int *res_flags);
+void fs_unmount(void);
+
+/* main.c */
+void fs_other(const message *m_ptr, int ipc_status);
 
 /* path.c */
-int fs_lookup(void);
+int fs_lookup(ino_t dir_nr, char *name, struct fsdriver_node *node,
+       int *is_mountpt);
 
 /* read.c */
-int fs_read(void);
-int fs_getdents(void);
+ssize_t fs_read(ino_t ino_nr, struct fsdriver_data *data, size_t bytes,
+       off_t pos, int call);
+ssize_t fs_getdents(ino_t ino_nr, struct fsdriver_data *data, size_t bytes,
+       off_t *pos);
 
 /* sdbm.c */
 long sdbm_hash(char *str, int len);
 
 /* stadir.c */
-int fs_stat(void);
-int fs_statvfs(void);
-
-/* utility.c */
-int no_sys(void);
-int do_noop(void);
+int fs_stat(ino_t ino_nr, struct stat *buf);
+int fs_statvfs(struct statvfs *buf);
 
 #endif /* _VTREEFS_PROTO_H */
index ad3d6c20228ffae9fef285e10b7bfd982359ca16..85b99262c7bd88b71b121d6343a3dd86babfdf64 100644 (file)
@@ -2,40 +2,33 @@
 
 #include "inc.h"
 #include <dirent.h>
-#include <minix/minlib.h>
 
 #define GETDENTS_BUFSIZ 4096
-#define DWORD_ALIGN(len) (((len) + sizeof(long) - 1) & ~(sizeof(long) - 1))
 
 /*===========================================================================*
  *                             fs_read                                      *
  *===========================================================================*/
-int fs_read(void)
+ssize_t fs_read(ino_t ino_nr, struct fsdriver_data *data, size_t bytes,
+       off_t pos, int __unused call)
 {
        /* Read from a file.
         */
-       cp_grant_id_t gid;
        struct inode *node;
-       off_t pos;
        size_t len;
        char *ptr;
        int r;
 
-       /* Try to get inode by to its inode number. */
-       if ((node = find_inode(fs_m_in.m_vfs_fs_readwrite.inode)) == NULL)
+       /* Try to get inode by its inode number. */
+       if ((node = find_inode(ino_nr)) == NULL)
                return EINVAL;
 
        /* Check whether the node is a regular file. */
        if (!S_ISREG(node->i_stat.mode))
                return EINVAL;
 
-       /* Get the values from the request message. */
-       gid = fs_m_in.m_vfs_fs_readwrite.grant;
-       pos = fs_m_in.m_vfs_fs_readwrite.seek_pos;
-
        /* Call the read hook, if any. */
        if (!is_inode_deleted(node) && vtreefs_hooks->read_hook != NULL) {
-               len = fs_m_in.m_vfs_fs_readwrite.nbytes;
+               len = bytes;
 
                /* On success, the read hook provides us with a pointer to the
                 * resulting data. This avoids copying overhead.
@@ -43,51 +36,41 @@ int fs_read(void)
                r = vtreefs_hooks->read_hook(node, pos, &ptr, &len,
                        get_inode_cbdata(node));
 
-               assert(len <= fs_m_in.m_vfs_fs_readwrite.nbytes);
+               assert(len <= bytes);
 
                /* Copy the resulting data to user space. */
-               if (r == OK && len > 0) {
-                       r = sys_safecopyto(fs_m_in.m_source, fs_m_in.m_vfs_fs_readwrite.grant,
-                               0, (vir_bytes) ptr, len);
-               }
+               if (r == OK && len > 0)
+                       r = fsdriver_copyout(data, 0, ptr, len);
        } else {
                /* Feign an empty file. */
                r = OK;
                len = 0;
        }
 
-       if (r == OK) {
-               fs_m_out.m_fs_vfs_readwrite.seek_pos = pos + len;
-               fs_m_out.m_fs_vfs_readwrite.nbytes = len;
-       }
-
-       return r;
+       return (r != OK) ? r : len;
 }
 
 /*===========================================================================*
  *                             fs_getdents                                  *
  *===========================================================================*/
-int fs_getdents(void)
+ssize_t fs_getdents(ino_t ino_nr, struct fsdriver_data *data, size_t bytes,
+       off_t *posp)
 {
        /* Retrieve directory entries.
         */
-       struct inode *node, *child = NULL;
-       struct dirent *dent;
-       char *name;
-       size_t len, off, user_off, user_left;
+       struct fsdriver_dentry fsdentry;
+       struct inode *node, *child;
+       const char *name;
        off_t pos;
        int r, skip, get_next, indexed;
        static char buf[GETDENTS_BUFSIZ];
 
-       if (fs_m_in.m_vfs_fs_getdents.seek_pos >= ULONG_MAX)
+       if (*posp >= ULONG_MAX)
                return EIO;
 
-       if ((node = find_inode(fs_m_in.m_vfs_fs_getdents.inode)) == NULL)
+       if ((node = find_inode(ino_nr)) == NULL)
                return EINVAL;
 
-       off = 0;
-       user_off = 0;
-       user_left = fs_m_in.m_vfs_fs_getdents.mem_size;
        indexed = node->i_indexed;
        get_next = FALSE;
        child = NULL;
@@ -98,8 +81,12 @@ int fs_getdents(void)
                if (r != OK) return r;
        }
 
-       for (pos = fs_m_in.m_vfs_fs_getdents.seek_pos; ; pos++) {
+       fsdriver_dentry_init(&fsdentry, data, bytes, buf, sizeof(buf));
+
+       do {
                /* Determine which inode and name to use for this entry. */
+               pos = (*posp)++;
+
                if (pos == 0) {
                        /* The "." entry. */
                        child = node;
@@ -158,56 +145,13 @@ int fs_getdents(void)
                        name = child->i_name;
                }
 
-               /* record length incl. alignment. */
-                len = _DIRENT_RECLEN(dent, strlen(name));
-
-               /* Is the user buffer too small to store another record? */
-               if (user_off + off + len > user_left) {
-                       /* Is the user buffer too small for even a single
-                        * record?
-                        */
-                       if (user_off == 0 && off == 0)
-                               return EINVAL;
-
-                       break;
-               }
-
-               /* If our own buffer cannot contain the new record, copy out
-                * first.
-                */
-               if (off + len > sizeof(buf)) {
-                       r = sys_safecopyto(fs_m_in.m_source, fs_m_in.m_vfs_fs_getdents.grant,
-                               user_off, (vir_bytes) buf, off);
-                       if (r != OK) return r;
-
-                       user_off += off;
-                       user_left -= off;
-                       off = 0;
-               }
-
-               /* Fill in the actual directory entry. */
-               dent = (struct dirent *) &buf[off];
-               dent->d_ino = (ino_t) get_inode_number(child);
-               dent->d_reclen = len;
-               dent->d_type = fs_mode_to_type(child->i_stat.mode);
-               dent->d_namlen = strlen(name);
-               strcpy(dent->d_name, name);
-
-               off += len;
-       }
-
-       /* If there is anything left in our own buffer, copy that out now. */
-       if (off > 0) {
-               r = sys_safecopyto(fs_m_in.m_source, fs_m_in.m_vfs_fs_getdents.grant,
-                       user_off, (vir_bytes) buf, off);
-               if (r != OK)
+               /* Add the directory entry to the output. */
+               r = fsdriver_dentry_add(&fsdentry,
+                       (ino_t) get_inode_number(child), name, strlen(name),
+                       IFTODT(child->i_stat.mode));
+               if (r < 0)
                        return r;
+       } while (r > 0);
 
-               user_off += off;
-       }
-
-       fs_m_out.m_fs_vfs_getdents.seek_pos = pos;
-       fs_m_out.m_fs_vfs_getdents.nbytes = user_off;
-
-       return OK;
+       return fsdriver_dentry_finish(&fsdentry);
 }
index 615d886fbfd79de63946801b6e756c4a53af5275..f29e3e6d17534bab1452b383f4529c848b7568e0 100644 (file)
@@ -2,37 +2,30 @@
 
 #include "inc.h"
 
-#include <time.h>
-#include <sys/statvfs.h>
-#include <string.h>
-
 /*===========================================================================*
  *                             fs_stat                                      *
  *===========================================================================*/
-int fs_stat(void)
+int fs_stat(ino_t ino_nr, struct stat *buf)
 {
        /* Retrieve file status.
         */
        char path[PATH_MAX];
-       struct stat statbuf;
        time_t cur_time;
        struct inode *node;
        int r;
 
-       if ((node = find_inode(fs_m_in.m_vfs_fs_stat.inode)) == NULL)
+       if ((node = find_inode(ino_nr)) == NULL)
                return EINVAL;
 
-       memset(&statbuf, 0, sizeof(struct stat));
-
        /* Fill in the basic info. */
-       statbuf.st_dev = fs_dev;
-       statbuf.st_ino = get_inode_number(node);
-       statbuf.st_mode = node->i_stat.mode;
-       statbuf.st_nlink = !is_inode_deleted(node);
-       statbuf.st_uid = node->i_stat.uid;
-       statbuf.st_gid = node->i_stat.gid;
-       statbuf.st_rdev = (dev_t) node->i_stat.dev;
-       statbuf.st_size = node->i_stat.size;
+       buf->st_dev = fs_dev;
+       buf->st_ino = get_inode_number(node);
+       buf->st_mode = node->i_stat.mode;
+       buf->st_nlink = !is_inode_deleted(node);
+       buf->st_uid = node->i_stat.uid;
+       buf->st_gid = node->i_stat.gid;
+       buf->st_rdev = (dev_t) node->i_stat.dev;
+       buf->st_size = node->i_stat.size;
 
        /* If it is a symbolic link, return the size of the link target. */
        if (S_ISLNK(node->i_stat.mode) && vtreefs_hooks->rdlink_hook != NULL) {
@@ -40,34 +33,28 @@ int fs_stat(void)
                        get_inode_cbdata(node));
 
                if (r == OK)
-                       statbuf.st_size = strlen(path);
+                       buf->st_size = strlen(path);
        }
 
        /* Take the current time as file time for all files. */
        cur_time = time(NULL);
-       statbuf.st_atime = cur_time;
-       statbuf.st_mtime = cur_time;
-       statbuf.st_ctime = cur_time;
+       buf->st_atime = cur_time;
+       buf->st_mtime = cur_time;
+       buf->st_ctime = cur_time;
 
-       /* Copy the struct to user space. */
-       return sys_safecopyto(fs_m_in.m_source, fs_m_in.m_vfs_fs_stat.grant, 0,
-               (vir_bytes) &statbuf, (phys_bytes) sizeof(statbuf));
+       return OK;
 }
 
 /*===========================================================================*
  *                             fs_statvfs                                   *
  *===========================================================================*/
-int fs_statvfs(void)
+int fs_statvfs(struct statvfs *buf)
 {
        /* Retrieve file system statistics.
         */
-       struct statvfs statvfs;
-
-       memset(&statvfs, 0, sizeof(statvfs));
 
-       statvfs.f_flag = ST_NOTRUNC;
-       statvfs.f_namemax = PNAME_MAX;
+       buf->f_flag = ST_NOTRUNC;
+       buf->f_namemax = PNAME_MAX;
 
-       return sys_safecopyto(fs_m_in.m_source, fs_m_in.m_vfs_fs_statvfs.grant,
-                               0, (vir_bytes) &statvfs, sizeof(statvfs));
+       return OK;
 }
index 468dccba7ad71f64c45d2ba1947f4a7b973958f2..193d896609e38f00e316c98311caf702c551ad60 100644 (file)
@@ -3,43 +3,15 @@
 #define _TABLE
 #include "inc.h"
 
-int (*fs_call_vec[])(void) = {
-       no_sys,         /*  0                   */
-       no_sys,         /*  1   getnode         */
-       fs_putnode,     /*  2   putnode         */
-       no_sys,         /*  3   slink           */
-       no_sys,         /*  4   ftrunc          */
-       no_sys,         /*  5   chown           */
-       no_sys,         /*  6   chmod           */
-       do_noop,        /*  7   inhibread       */
-       fs_stat,        /*  8   stat            */
-       no_sys,         /*  9   utime           */
-       fs_statvfs,     /* 10   statvfs         */
-       no_sys,         /* 11   bread           */
-       no_sys,         /* 12   bwrite          */
-       no_sys,         /* 13   unlink          */
-       no_sys,         /* 14   rmdir           */
-       fs_unmount,     /* 15   unmount         */
-       do_noop,        /* 16   sync            */
-       do_noop,        /* 17   new_driver      */
-       no_sys,         /* 18   flush           */
-       fs_read,        /* 19   read            */
-       no_sys,         /* 20   write           */
-       no_sys,         /* 21   mknod           */
-       no_sys,         /* 22   mkdir           */
-       no_sys,         /* 23   create          */
-       no_sys,         /* 24   link            */
-       no_sys,         /* 25   rename          */
-       fs_lookup,      /* 26   lookup          */
-       no_sys,         /* 27   mountpoint      */
-       fs_readsuper,   /* 28   readsuper       */
-       no_sys,         /* 29   newnode         */
-       fs_rdlink,      /* 30   rdlink          */
-       fs_getdents,    /* 31   getdents        */
-       no_sys,         /* 32   peek            */
-       no_sys,         /* 33   bpeek           */
+struct fsdriver vtreefs_table = {
+       .fdr_mount      = fs_mount,
+       .fdr_unmount    = fs_unmount,
+       .fdr_lookup     = fs_lookup,
+       .fdr_putnode    = fs_putnode,
+       .fdr_read       = fs_read,
+       .fdr_getdents   = fs_getdents,
+       .fdr_rdlink     = fs_rdlink,
+       .fdr_stat       = fs_stat,
+       .fdr_statvfs    = fs_statvfs,
+       .fdr_other      = fs_other
 };
-
-/* This should not fail with "array size is negative": */
-extern int
-       dummy[sizeof(fs_call_vec) == NREQS * sizeof(fs_call_vec[0]) ? 1 : -1];
diff --git a/minix/lib/libvtreefs/utility.c b/minix/lib/libvtreefs/utility.c
deleted file mode 100644 (file)
index d4b0e86..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-/* VTreeFS - utility.c - by Alen Stojanov and David van Moolenbroek */
-
-#include "inc.h"
-
-/*===========================================================================*
- *                             no_sys                                       *
- *===========================================================================*/
-int no_sys(void)
-{
-       /* This call is not recognized by VTreeFS. If a message hook is
-        * defined, let it handle the call; otherwise return ENOSYS.
-        */
-
-       if (vtreefs_hooks->message_hook != NULL)
-               return vtreefs_hooks->message_hook(&fs_m_in);
-
-       return ENOSYS;
-}
-
-/*===========================================================================*
- *                             do_noop                                      *
- *===========================================================================*/
-int do_noop(void)
-{
-       /* This call has no effect.
-        */
-
-       return OK;
-}
index 1cc59ed9eff0052a3e2d33666b2f885de355d6ab..ebdd0e9d23b597c0ab6e97b7616396384c0d7bcf 100644 (file)
@@ -2,10 +2,6 @@
 
 #include "inc.h"
 
-static int get_work(void);
-static void send_reply(int err, int transid);
-static void got_signal(int signal);
-
 static unsigned int inodes;
 static struct inode_stat *root_stat;
 static index_t root_entries;
@@ -21,12 +17,23 @@ static int init_server(int UNUSED(type), sef_init_info_t *UNUSED(info))
        /* Initialize the virtual tree. */
        init_inodes(inodes, root_stat, root_entries);
 
-       /* Do not yet allow any requests except REQ_READSUPER. */
-       fs_mounted = FALSE;
-
        return OK;
 }
 
+/*===========================================================================*
+ *                             got_signal                                   *
+ *===========================================================================*/
+static void got_signal(int signal)
+{
+       /* We received a signal.
+        */
+
+       if (signal != SIGTERM)
+               return;
+
+       fsdriver_terminate();
+}
+
 /*===========================================================================*
  *                             sef_local_startup                            *
  *===========================================================================*/
@@ -42,18 +49,36 @@ static void sef_local_startup(void)
        sef_startup();
 }
 
+/*===========================================================================*
+ *                             fs_other                                     *
+ *===========================================================================*/
+void fs_other(const message *m_ptr, int __unused ipc_status)
+{
+       /* We received a message that is not among the recognized file system
+        * requests.  Call the message hook, if there is one.
+        */
+       message msg;
+
+       if (vtreefs_hooks->message_hook != NULL) {
+               /* Not all of vtreefs's users play nice with the message, so
+                * make a copy to allow it to be modified.
+                */
+               msg = *m_ptr;
+
+               vtreefs_hooks->message_hook(&msg);
+       }
+}
+
 /*===========================================================================*
  *                             start_vtreefs                                *
  *===========================================================================*/
 void start_vtreefs(struct fs_hooks *hooks, unsigned int nr_inodes,
                struct inode_stat *stat, index_t nr_indexed_entries)
 {
-       /* This is the main routine of this service. The main loop consists of
-        * three major activities: getting new work, processing the work, and
-        * sending the reply. The loop exits when the process is signaled to
-        * exit; due to limitations of SEF, it can not return to the caller.
+       /* This is the main routine of this service. It uses the main loop as
+        * provided by the fsdriver library. The routine returns once the file
+        * system has been unmounted and the process is signaled to exit.
         */
-       int call_nr, err, transid;
 
        /* Use global variables to work around the inability to pass parameters
         * through SEF to the initialization function..
@@ -65,95 +90,7 @@ void start_vtreefs(struct fs_hooks *hooks, unsigned int nr_inodes,
 
        sef_local_startup();
 
-       for (;;) {
-               get_work();
-
-               transid = TRNS_GET_ID(fs_m_in.m_type);
-               fs_m_in.m_type = TRNS_DEL_ID(fs_m_in.m_type);
-               if (fs_m_in.m_type == 0) {
-                       assert(!IS_VFS_FS_TRANSID(transid));
-                       fs_m_in.m_type = transid;       /* Backwards compat. */
-                       transid = 0;
-               } else
-                       assert(IS_VFS_FS_TRANSID(transid));
-
-               call_nr = fs_m_in.m_type;
-
-               if (fs_m_in.m_source != VFS_PROC_NR) {
-                       if (vtreefs_hooks->message_hook != NULL) {
-                               /* If the request is not among the recognized
-                                * requests, call the message hook.
-                                */
-                               vtreefs_hooks->message_hook(&fs_m_in);
-                       }
-
-                       continue;
-               }
-
-               if (fs_mounted || call_nr == REQ_READSUPER) {
-                       call_nr -= FS_BASE;
-
-                       if (call_nr >= 0 && call_nr < NREQS) {
-                               err = (*fs_call_vec[call_nr])();
-                       } else {
-                               err = ENOSYS;
-                       }
-               }
-               else err = EINVAL;
-
-               send_reply(err, transid);
-       }
-}
-
-/*===========================================================================*
- *                             get_work                                     *
- *===========================================================================*/
-static int get_work(void)
-{
-       /* Retrieve work. Return the call number.
-        */
-       int r;
-
-       if ((r = sef_receive(ANY, &fs_m_in)) != OK)
-               panic("receive failed: %d", r);
-
-       return fs_m_in.m_type;
-}
-
-/*===========================================================================*
- *                             send_reply                                   *
- *===========================================================================*/
-static void send_reply(int err, int transid)
-{
-       /* Send a reply to the caller.
-        */
-       int r;
-
-       fs_m_out.m_type = err;
-       if (IS_VFS_FS_TRANSID(transid)) {
-               fs_m_out.m_type = TRNS_ADD_ID(fs_m_out.m_type, transid);
-       }
-
-       if ((r = ipc_send(fs_m_in.m_source, &fs_m_out)) != OK)
-               panic("unable to send reply: %d", r);
-}
-
-/*===========================================================================*
- *                             got_signal                                   *
- *===========================================================================*/
-static void got_signal(int signal)
-{
-       /* We received a signal. If it is a termination signal, and the file
-        * system has already been unmounted, clean up and exit.
-        */
-
-       if (signal != SIGTERM)
-               return;
-
-       if (fs_mounted)
-               return;
+       fsdriver_task(&vtreefs_table);
 
        cleanup_inodes();
-
-       exit(0);
 }
index 84d67e65435dcb6a6489a3c1e14036406222e8a2..770cf575d2a4e00cc71d5933bfbb3b7fd071ef45 100644 (file)
@@ -1,7 +1,7 @@
 PROG = devman
 SRCS =  main.c device.c buf.c bind.c
 
-DPADD+=        ${LIBSYS} 
-LDADD =  -lvtreefs -lsys 
+DPADD+=        ${LIBVTREEFS} ${LIBFSDRIVER} ${LIBSYS}
+LDADD+=  -lvtreefs -lfsdriver -lsys
 
 .include <minix.service.mk>