]> Zhao Yanbai Git Server - minix.git/commitdiff
libpuffs: use libfsdriver 47/2747/3
authorDavid van Moolenbroek <david@minix3.org>
Sun, 24 Aug 2014 09:51:35 +0000 (09:51 +0000)
committerDavid van Moolenbroek <david@minix3.org>
Thu, 18 Sep 2014 12:46:25 +0000 (12:46 +0000)
Change-Id: I26651578066e1098dc275a9cfbe5710870a13811

20 files changed:
lib/libpuffs/Makefile
lib/libpuffs/fs.h
lib/libpuffs/glo.h
lib/libpuffs/inode.c
lib/libpuffs/link.c
lib/libpuffs/misc.c
lib/libpuffs/mount.c
lib/libpuffs/open.c
lib/libpuffs/path.c
lib/libpuffs/pnode.c
lib/libpuffs/protect.c
lib/libpuffs/proto.h
lib/libpuffs/puffs.c
lib/libpuffs/puffs.h
lib/libpuffs/puffs_priv.h
lib/libpuffs/read.c
lib/libpuffs/stadir.c
lib/libpuffs/table.c
lib/libpuffs/time.c
lib/libpuffs/utility.c

index 138d7a504cf81993a70e5b468b70e79236102afc..1c29729fd186b6faaa3aad226b410dc5169599c6 100644 (file)
@@ -25,7 +25,6 @@ SRCS+=                inode.c link.c misc.c mount.c open.c path.c path_puffs.c \
 CPPFLAGS+= -D_MINIX_SYSTEM
 
 NOGCCERROR=yes
-NOCLANGERROR=yes
 .endif # defined(__MINIX)
 
 .include <bsd.lib.mk>
index 15b07614408ff64ba1f52b71170d95e758765638..d7ac392986f8d57cd322b8aeaeb37e0f173f7d26 100644 (file)
@@ -14,7 +14,6 @@
 #include <sys/types.h>
 #include <minix/const.h>
 #include <minix/type.h>
-#include <minix/dmap.h>
 
 #include <lib.h>
 #include <limits.h>
@@ -23,6 +22,8 @@
 #include <minix/syslib.h>
 #include <minix/sysutil.h>
 
+#include <minix/fsdriver.h>
+
 #include "proto.h"
 #include "glo.h"
 
index b38c7634660ab0aacb6978e10813432c1fd72054..6e4645216441884d222d3e6a572368a1b6e6fea7 100644 (file)
@@ -8,48 +8,30 @@
 #define EXTERN
 #endif
 
-#include <minix/vfsif.h>
-
 #include <fs/puffs/puffs_msgif.h>
 
 EXTERN struct puffs_usermount *global_pu;
 
 EXTERN int is_readonly_fs;
-EXTERN int is_root_fs;
 EXTERN int buildpath;
 
 /* Sometimes user can call exit. If we received a message,
  * report a failure to VFS before exiting. Especially on mount
  * and unmount.
- *
- * Either transid of last request or 0.
  */
-EXTERN int last_request_transid;
 
 /* The following variables are used for returning results to the caller. */
 EXTERN int err_code;        /* temporary storage for error number */
 
-/* TODO: it duplicates caller_uid and caller_gid */
 EXTERN struct puffs_kcred global_kcred;
 
-extern int(*fs_call_vec[]) (void);
-
-EXTERN message fs_m_in;
-EXTERN message fs_m_out;
-EXTERN vfs_ucred_t credentials;
-
-EXTERN uid_t caller_uid;
-EXTERN gid_t caller_gid;
-
-EXTERN int req_nr;
-
-EXTERN char user_path[PATH_MAX+1];  /* pathname to be processed */
-
 EXTERN dev_t fs_dev;              /* The device that is handled by this FS proc
                                    */
 EXTERN char fs_name[PATH_MAX+1];
 
-EXTERN int unmountdone;
+EXTERN int mounted;
 EXTERN int exitsignaled;
 
+extern struct fsdriver puffs_table;
+
 #endif /* LIBPUFFS_GLO_H */
index 629ea8dcaf1eb1ab699b129c588424ea6f2c4573..e62149dc783532eacba111efde64a877604b2a2c 100644 (file)
@@ -6,7 +6,6 @@
 #include "fs.h"
 #include <string.h>
 #include <assert.h>
-#include <minix/vfsif.h>
 
 #include "puffs.h"
 #include "puffs_priv.h"
@@ -31,22 +30,20 @@ void release_node(struct puffs_usermount *pu, struct puffs_node *pn)
 /*===========================================================================*
  *                fs_putnode                                                 *
  *===========================================================================*/
-int fs_putnode(void)
+int fs_putnode(ino_t ino_nr, unsigned int count)
 {
 /* Find the pnode specified by the request message and decrease its counter.
  * Release unused pnode.
  */
   struct puffs_node *pn;
-  int count = fs_m_in.m_vfs_fs_putnode.count;
-  ino_t inum = fs_m_in.m_vfs_fs_putnode.inode;
 
-  if ((pn = puffs_pn_nodewalk(global_pu, 0, &inum)) == NULL) {
+  if ((pn = puffs_pn_nodewalk(global_pu, 0, &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);
        while (pn_cur) {
                pn_next = LIST_NEXT(pn_cur, pn_entries);
-               if (pn_cur->pn_va.va_fileid == inum) {
+               if (pn_cur->pn_va.va_fileid == ino_nr) {
                        pn = pn_cur;
                        break;
                }
@@ -55,8 +52,8 @@ int fs_putnode(void)
   }
 
   if (pn == NULL) {
-       lpuffs_debug("%s:%d putnode: pnode #%ld dev: %d not found\n", __FILE__,
-               __LINE__, inum, fs_dev);
+       lpuffs_debug("%s:%d putnode: pnode #%"PRIu64" dev: %"PRIu64
+               " not found\n", __FILE__, __LINE__, ino_nr, fs_dev);
        panic("fs_putnode failed");
   }
 
@@ -82,7 +79,9 @@ int fs_putnode(void)
        while (pn_cur) {
                pn_next = LIST_NEXT(pn_cur, pn_entries);
                if (pn_cur->pn_va.va_fileid == ino) {
-                       lpuffs_debug("%ld: %d %s %u %u\n", ino, pn_cur->pn_count,
+                       lpuffs_debug("%"PRIu64": %d %s %u %u\n",
+                               ino,
+                               pn_cur->pn_count,
                                pn_cur->pn_po.po_path,
                                pn_cur->pn_po.po_len,
                                pn_cur->pn_po.po_hash);
index 99740ade2efe753151adc6fdfde24dcb953fa508..a3bb7991d1e7df410fc875607774f8d238bbafa7 100644 (file)
@@ -6,25 +6,19 @@
 #include "puffs.h"
 #include "puffs_priv.h"
 
-#define SAME 1000
-
 
 /*===========================================================================*
- *                              fs_ftrunc                                    *
+ *                             fs_trunc                                     *
  *===========================================================================*/
-int fs_ftrunc(void)
+int fs_trunc(ino_t ino_nr, off_t start, off_t end)
 {
   int r;
   struct puffs_node *pn;
-  off_t start, end;
   PUFFS_MAKECRED(pcr, &global_kcred);
 
-  if ((pn = puffs_pn_nodewalk(global_pu, 0, &fs_m_in.m_vfs_fs_ftrunc.inode)) == NULL)
+  if ((pn = puffs_pn_nodewalk(global_pu, 0, &ino_nr)) == NULL)
           return(EINVAL);
 
-  start = fs_m_in.m_vfs_fs_ftrunc.trc_start;
-  end = fs_m_in.m_vfs_fs_ftrunc.trc_end;
-
   if (end == 0) {
        struct vattr va;
 
@@ -68,13 +62,11 @@ int fs_ftrunc(void)
 /*===========================================================================*
  *                              fs_link                                      *
  *===========================================================================*/
-int fs_link(void)
+int fs_link(ino_t dir_nr, char *name, ino_t ino_nr)
 {
 /* Perform the link(name1, name2) system call. */
 
   register int r;
-  char string[NAME_MAX + 1];
-  phys_bytes len;
   struct puffs_node *pn, *pn_dir, *new_pn;
   struct timespec cur_time;
   struct puffs_kcn pkcnp;
@@ -84,28 +76,18 @@ int fs_link(void)
   if (global_pu->pu_ops.puffs_node_link == NULL)
        return(OK);
 
-  /* Copy the link name's last component */
-  len = fs_m_in.m_vfs_fs_link.path_len;
-  if (len > NAME_MAX + 1)
-        return(ENAMETOOLONG);
-
-  r = sys_safecopyfrom(VFS_PROC_NR, fs_m_in.m_vfs_fs_link.grant, 0,
-                       (vir_bytes) string, (size_t) len);
-  if (r != OK) return(r);
-  NUL(string, len, sizeof(string));
-
-  if ((pn = puffs_pn_nodewalk(global_pu, 0, &fs_m_in.m_vfs_fs_link.inode)) == NULL)
+  if ((pn = puffs_pn_nodewalk(global_pu, 0, &ino_nr)) == NULL)
        return(EINVAL);
 
   /* Check to see if the file has maximum number of links already. */
   if (pn->pn_va.va_nlink >= LINK_MAX)
        return(EMLINK);
 
-  /* Only super_user may link to directories. */
-  if ((pn->pn_va.va_mode & I_TYPE) == I_DIRECTORY && caller_uid != SU_UID)
+  /* Linking directories is too dangerous to allow. */
+  if (S_ISDIR(pn->pn_va.va_mode))
        return(EPERM);
 
-  if ((pn_dir = puffs_pn_nodewalk(global_pu, 0, &fs_m_in.m_vfs_fs_link.dir_ino)) == NULL)
+  if ((pn_dir = puffs_pn_nodewalk(global_pu, 0, &dir_nr)) == NULL)
         return(EINVAL);
 
   if (pn_dir->pn_va.va_nlink == NO_LINK) {
@@ -114,7 +96,7 @@ int fs_link(void)
   }
 
   /* If 'name2' exists in full (even if no space) set 'r' to error. */
-  if ((new_pn = advance(pn_dir, string, IGN_PERM)) == NULL) {
+  if ((new_pn = advance(pn_dir, name)) == NULL) {
         r = err_code;
         if (r == ENOENT) r = OK;
   } else {
@@ -124,9 +106,9 @@ int fs_link(void)
   if (r != OK) return(r);
 
   /* Try to link. */
-  pcn.pcn_namelen = strlen(string);
-  assert(pcn.pcn_namelen <= MAXPATHLEN);
-  strcpy(pcn.pcn_name, string);
+  pcn.pcn_namelen = strlen(name);
+  assert(pcn.pcn_namelen <= NAME_MAX);
+  strcpy(pcn.pcn_name, name);
 
   if (buildpath) {
        if (puffs_path_pcnbuild(global_pu, &pcn, pn_dir) != 0)
@@ -152,20 +134,17 @@ int fs_link(void)
 /*===========================================================================*
  *                             fs_rdlink                                     *
  *===========================================================================*/
-int fs_rdlink(void)
+ssize_t fs_rdlink(ino_t ino_nr, struct fsdriver_data *data, size_t bytes)
 {
   register int r;              /* return value */
-  size_t copylen;
   struct puffs_node *pn;
   char path[PATH_MAX];
   PUFFS_MAKECRED(pcr, &global_kcred);
 
-  copylen = fs_m_in.m_vfs_fs_rdlink.mem_size < UMAX_FILE_POS ?
-       fs_m_in.m_vfs_fs_rdlink.mem_size : UMAX_FILE_POS;
+  if (bytes > sizeof(path))
+       bytes = sizeof(path);
   
-  assert(copylen <= PATH_MAX);
-
-  if ((pn = puffs_pn_nodewalk(global_pu, 0, &fs_m_in.m_vfs_fs_rdlink.inode)) == NULL)
+  if ((pn = puffs_pn_nodewalk(global_pu, 0, &ino_nr)) == NULL)
        return(EINVAL);
 
   if (!S_ISLNK(pn->pn_va.va_mode))
@@ -174,26 +153,23 @@ int fs_rdlink(void)
   if (global_pu->pu_ops.puffs_node_readlink == NULL)
        return(EINVAL);
 
-  r = global_pu->pu_ops.puffs_node_readlink(global_pu, pn, pcr, path,
-                                               &copylen);
+  r = global_pu->pu_ops.puffs_node_readlink(global_pu, pn, pcr, path, &bytes);
   if (r != OK) {
        if (r > 0) r = -r;
        return(r);
   }
 
-  r = sys_safecopyto(VFS_PROC_NR, fs_m_in.m_vfs_fs_rdlink.grant,
-                 (vir_bytes) 0, (vir_bytes) path, (size_t) copylen);
-  if (r == OK)
-         fs_m_out.m_fs_vfs_rdlink.nbytes = copylen;
+  r = fsdriver_copyout(data, 0, path, bytes);
 
-  return(r);
+  return (r == OK) ? bytes : r;
 }
 
 
 /*===========================================================================*
  *                              fs_rename                                    *
  *===========================================================================*/
-int fs_rename(void)
+int fs_rename(ino_t old_dir_nr, char *old_name, ino_t new_dir_nr,
+       char *new_name)
 {
 /* Perform the rename(name1, name2) system call. */
   struct puffs_node *old_dirp, *old_ip;      /* ptrs to old dir, file pnodes */
@@ -207,55 +183,35 @@ int fs_rename(void)
   int r = OK;                           /* error flag; initially no error */
   int odir, ndir;                       /* TRUE iff {old|new} file is dir */
   int same_pdir;                        /* TRUE iff parent dirs are the same */
-  phys_bytes len;
   struct timespec cur_time;
 
   if (global_pu->pu_ops.puffs_node_rename == NULL)
        return(EINVAL);
 
   /* Copy the last component of the old name */
-  len = fs_m_in.m_vfs_fs_rename.len_old; /* including trailing '\0' */
-  if (len > NAME_MAX + 1)
-        return(ENAMETOOLONG);
-
-  r = sys_safecopyfrom(VFS_PROC_NR, fs_m_in.m_vfs_fs_rename.grant_old,
-                (vir_bytes) 0, (vir_bytes) pcn_src.pcn_name, (size_t) len);
-  if (r != OK) return(r);
-  NUL(pcn_src.pcn_name, len, sizeof(pcn_src.pcn_name));
-  pcn_src.pcn_namelen = len - 1;
+  pcn_src.pcn_namelen = strlen(old_name);
+  assert(pcn_src.pcn_namelen <= NAME_MAX);
+  strcpy(pcn_src.pcn_name, old_name);
 
   /* Copy the last component of the new name */
-  len = fs_m_in.m_vfs_fs_rename.len_new; /* including trailing '\0' */
-  if (len > NAME_MAX + 1)
-        return(ENAMETOOLONG);
-
-  r = sys_safecopyfrom(VFS_PROC_NR, fs_m_in.m_vfs_fs_rename.grant_new,
-                (vir_bytes) 0, (vir_bytes) pcn_targ.pcn_name, (size_t) len);
-  if (r != OK) return(r);
-  NUL(pcn_targ.pcn_name, len, sizeof(pcn_targ.pcn_name));
-  pcn_targ.pcn_namelen = len - 1;
+  pcn_targ.pcn_namelen = strlen(new_name);
+  assert(pcn_targ.pcn_namelen <= NAME_MAX);
+  strcpy(pcn_targ.pcn_name, new_name);
 
   /* Get old dir pnode */
-  if ((old_dirp = puffs_pn_nodewalk(global_pu, 0, &fs_m_in.m_vfs_fs_rename.dir_old))
-         == NULL)
+  if ((old_dirp = puffs_pn_nodewalk(global_pu, 0, &old_dir_nr)) == NULL)
         return(ENOENT);
 
-  old_ip = advance(old_dirp, pcn_src.pcn_name, IGN_PERM);
-  if (!old_ip) {
-       return(ENOENT);
-  }
-  r = err_code;
+  old_ip = advance(old_dirp, pcn_src.pcn_name);
+  if (!old_ip)
+       return(err_code);
 
-  if (r == EENTERMOUNT || r == ELEAVEMOUNT) {
-        old_ip = NULL;
-        if (r == EENTERMOUNT) r = EXDEV;        /* should this fail at all? */
-        else if (r == ELEAVEMOUNT) r = EINVAL;  /* rename on dot-dot */
-  }
+  if (old_ip->pn_mountpoint)
+       return(EBUSY);
 
   /* Get new dir pnode */
-  if ((new_dirp = puffs_pn_nodewalk(global_pu, 0, &fs_m_in.m_vfs_fs_rename.dir_new))
-         == NULL) {
-        r = ENOENT;
+  if ((new_dirp = puffs_pn_nodewalk(global_pu, 0, &new_dir_nr)) == NULL) {
+        return(ENOENT);
   } else {
         if (new_dirp->pn_va.va_nlink == NO_LINK) {
                /* Dir does not actually exist */
@@ -264,14 +220,11 @@ int fs_rename(void)
   }
 
   /* not required to exist */
-  new_ip = advance(new_dirp, pcn_targ.pcn_name, IGN_PERM);
+  new_ip = advance(new_dirp, pcn_targ.pcn_name);
 
-  /* However, if the check failed because the file does exist, don't continue.
-   * Note that ELEAVEMOUNT is covered by the dot-dot check later. */
-  if (err_code == EENTERMOUNT) {
-        new_ip = NULL;
-        r = EBUSY;
-  }
+  /* If the node does exist, make sure it's not a mountpoint. */
+  if (new_ip != NULL && new_ip->pn_mountpoint)
+       return(EBUSY);
 
   if (old_ip != NULL) {
        /* TRUE iff dir */
@@ -280,42 +233,25 @@ int fs_rename(void)
        odir = FALSE;
   }
 
-  if (r != OK) return(r);
-
   /* Check for a variety of possible errors. */
   same_pdir = (old_dirp == new_dirp);
 
-  /* The old or new name must not be . or .. */
-  if (strcmp(pcn_src.pcn_name, ".") == 0 ||
-      strcmp(pcn_src.pcn_name, "..") == 0 ||
-      strcmp(pcn_targ.pcn_name, ".") == 0 ||
-      strcmp(pcn_targ.pcn_name, "..") == 0) {
-       r = EINVAL;
-  }
-
   /* Some tests apply only if the new path exists. */
   if (new_ip == NULL) {
        if (odir && (new_dirp->pn_va.va_nlink >= SHRT_MAX ||
-                    new_dirp->pn_va.va_nlink >= LINK_MAX) &&
-           !same_pdir && r == OK) {
-               r = EMLINK;
+                    new_dirp->pn_va.va_nlink >= LINK_MAX) && !same_pdir) {
+               return(EMLINK);
        }
   } else {
-       if (old_ip == new_ip) r = SAME; /* old=new */
+       if (old_ip == new_ip) /* old=new */
+               return(OK); /* do NOT update directory times in this case */
 
        /* dir ? */
        ndir = ((new_ip->pn_va.va_mode & I_TYPE) == I_DIRECTORY);
-       if (odir == TRUE && ndir == FALSE) r = ENOTDIR;
-       if (odir == FALSE && ndir == TRUE) r = EISDIR;
+       if (odir == TRUE && ndir == FALSE) return(ENOTDIR);
+       if (odir == FALSE && ndir == TRUE) return(EISDIR);
   }
 
-  if (r == SAME) {
-       r = OK;
-       goto rename_out;
-  }
-
-  if (r != OK) return(r);
-
   /* If a process has another root directory than the system root, we might
    * "accidently" be moving it's working directory to a place where it's
    * root directory isn't a super directory of it anymore. This can make
@@ -372,7 +308,6 @@ int fs_rename(void)
        }
   }
 
-rename_out: 
   cur_time = clock_timespec();
   update_timens(old_dirp, MTIME | CTIME, &cur_time);
   update_timens(new_dirp, MTIME | CTIME, &cur_time);
@@ -391,13 +326,12 @@ static int unlink_file(struct puffs_node *dirp, struct puffs_node *pn,
        struct puffs_cn *pcn);
 
 /*===========================================================================*
- *                              fs_unlink                                    *
+ *                             fs_unlink                                    *
  *===========================================================================*/
-int fs_unlink(void)
+int fs_unlink(ino_t dir_nr, char *name, int call)
 {
 /* Perform the unlink(name) or rmdir(name) system call. The code for these two
- * is almost the same.  They differ only in some condition testing.  Unlink()
- * may be used by the superuser to do dangerous things; rmdir() may not.
+ * is almost the same.  They differ only in some condition testing.
  */
   int r;
   struct puffs_node *pn, *pn_dir;
@@ -405,43 +339,28 @@ int fs_unlink(void)
   struct puffs_kcn pkcnp;
   struct puffs_cn pcn = {&pkcnp, 0, {0,0,0}};
   PUFFS_KCREDTOCRED(pcn.pcn_cred, &global_kcred);
-  int len;
 
   /* Copy the last component */
-  len = fs_m_in.m_vfs_fs_unlink.path_len;
-  pcn.pcn_namelen = len - 1;
-  if (pcn.pcn_namelen > NAME_MAX)
-        return(ENAMETOOLONG);
-
-  r = sys_safecopyfrom(VFS_PROC_NR, fs_m_in.m_vfs_fs_unlink.grant,
-                      (vir_bytes) 0, (vir_bytes) pcn.pcn_name,
-                      (size_t) len);
-  if (r != OK) return (r);
-  NUL(pcn.pcn_name, len, sizeof(pcn.pcn_name));
-
-  if ((pn_dir = puffs_pn_nodewalk(global_pu, 0, &fs_m_in.m_vfs_fs_unlink.inode)) == NULL)
+  pcn.pcn_namelen = strlen(name);
+  assert(pcn.pcn_namelen <= NAME_MAX);
+  strcpy(pcn.pcn_name, name);
+
+  if ((pn_dir = puffs_pn_nodewalk(global_pu, 0, &dir_nr)) == NULL)
        return(EINVAL);
 
   /* The last directory exists. Does the file also exist? */
-  pn = advance(pn_dir, pcn.pcn_name, IGN_PERM);
+  pn = advance(pn_dir, pcn.pcn_name);
   r = err_code;
 
   /* If error, return pnode. */
-  if (r != OK) {
-        /* Mount point? */
-        if (r == EENTERMOUNT || r == ELEAVEMOUNT) {
-                r = EBUSY;
-        }
+  if (r != OK)
         return(r);
-  }
+  if (pn->pn_mountpoint)
+       return EBUSY;
 
   /* Now test if the call is allowed, separately for unlink() and rmdir(). */
-  if (fs_m_in.m_type == REQ_UNLINK) {
-       /* Only the su may unlink directories, but the su can unlink any dir */
-       if ((pn->pn_va.va_mode & I_TYPE) == I_DIRECTORY)
-               r = EPERM;
-       if (r == OK)
-               r = unlink_file(pn_dir, pn, &pcn);
+  if (call == FSC_UNLINK) {
+       r = unlink_file(pn_dir, pn, &pcn);
   } else {
        r = remove_dir(pn_dir, pn, &pcn); /* call is RMDIR */
   }
@@ -502,9 +421,6 @@ static int remove_dir(
   if (r) return(EINVAL);
   if (!eofflag) return(ENOTEMPTY);
 
-  if (strcmp(pcn->pcn_name, ".") == 0 || strcmp(pcn->pcn_name, "..") == 0)
-       return(EINVAL);
-
   if (pn->pn_va.va_fileid == global_pu->pu_pn_root->pn_va.va_fileid)
        return(EBUSY); /* can't remove 'root' */
   
@@ -541,7 +457,7 @@ static int unlink_file(
        return(EINVAL);
 
   if (S_ISDIR(pn->pn_va.va_mode))
-       return(EINVAL);
+       return(EPERM);
 
   if (buildpath) {
        r = puffs_path_pcnbuild(global_pu, pcn, dirp);
index 9b80632a22dc6ec74f4379acccf97e8abadf0bd4..f58c225edfa079a8bb63cd2104bb20d23960e6f8 100644 (file)
@@ -4,7 +4,6 @@
 
 #include "fs.h"
 #include <assert.h>
-#include <minix/vfsif.h>
 
 #include "puffs.h"
 #include "puffs_priv.h"
@@ -12,7 +11,7 @@
 /*===========================================================================*
  *                             fs_sync                                      *
  *===========================================================================*/
-int fs_sync(void)
+void fs_sync(void)
 {
 /* Perform the sync() system call.  Flush all the tables.
  * The order in which the various tables are flushed is critical.
@@ -21,44 +20,10 @@ int fs_sync(void)
   PUFFS_MAKECRED(pcr, &global_kcred);
 
   if (is_readonly_fs)
-       return(OK); /* nothing to sync */
+       return; /* nothing to sync */
 
   r = global_pu->pu_ops.puffs_fs_sync(global_pu, MNT_WAIT, pcr);
   if (r) {
        lpuffs_debug("Warning: sync failed!\n");
   }
-
-  return(OK);          /* sync() can't fail */
-}
-
-
-/*===========================================================================*
- *                             fs_flush                                     *
- *===========================================================================*/
-int fs_flush(void)
-{
-/* Flush the blocks of a device from the cache after writing any dirty blocks
- * to disk.
- */
-#if 0
-  dev_t dev = fs_m_in.m_vfs_fs_flush.device;
-
-  if(dev == fs_dev) return(EBUSY);
-
-  flushall(dev);
-  invalidate(dev);
-#endif
-
-  return(OK);
-}
-
-
-/*===========================================================================*
- *                             fs_new_driver                                *
- *===========================================================================*/
-int fs_new_driver(void)
-{
-/* Do not do anything. */
-
-  return(OK);
 }
index 036c5bd900c61f049c7f4108ac59fdda3e4b7e73..05272e9f8e844ea889da3c88149d07899e913ba7 100644 (file)
@@ -5,44 +5,45 @@
 #include "fs.h"
 #include <fcntl.h>
 #include <string.h>
-#include <minix/com.h>
-#include <sys/stat.h>
-#include <minix/ds.h>
 #include <minix/vfsif.h>
 
 #include "puffs_priv.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)
 {
   struct vattr *root_va;
 
-  fs_dev    = fs_m_in.m_vfs_fs_readsuper.device;
-  is_readonly_fs  = (fs_m_in.m_vfs_fs_readsuper.flags & REQ_RDONLY) ? 1 : 0;
-  is_root_fs    = (fs_m_in.m_vfs_fs_readsuper.flags & REQ_ISROOT) ? 1 : 0;
+  fs_dev = dev;
+  is_readonly_fs = !!(flags & REQ_RDONLY);
 
   /* Open root pnode */
   global_pu->pu_pn_root->pn_count = 1;
 
   /* Root pnode properties */
   root_va = &global_pu->pu_pn_root->pn_va;
-  fs_m_out.m_fs_vfs_readsuper.inode = root_va->va_fileid;
-  fs_m_out.m_fs_vfs_readsuper.mode = root_va->va_mode;
-  fs_m_out.m_fs_vfs_readsuper.file_size = root_va->va_size;
-  fs_m_out.m_fs_vfs_readsuper.uid = root_va->va_uid;
-  fs_m_out.m_fs_vfs_readsuper.gid = root_va->va_gid;
-  fs_m_out.m_fs_vfs_readsuper.flags = RES_NOFLAGS;
+  root_node->fn_ino_nr = root_va->va_fileid;
+  root_node->fn_mode = root_va->va_mode;
+  root_node->fn_size = root_va->va_size;
+  root_node->fn_uid = root_va->va_uid;
+  root_node->fn_gid = root_va->va_gid;
+  root_node->fn_dev = NO_DEV;
+
+  *res_flags = RES_NOFLAGS;
+
+  mounted = TRUE;
 
   return(OK);
 }
 
 
 /*===========================================================================*
- *                             fs_mountpoint                                *
+ *                             fs_mountpt                                   *
  *===========================================================================*/
-int fs_mountpoint(void)
+int fs_mountpt(ino_t ino_nr)
 {
 /* This function looks up the mount point, it checks the condition whether
  * the partition can be mounted on the pnode or not.
@@ -51,15 +52,9 @@ int fs_mountpoint(void)
   struct puffs_node *pn;
   mode_t bits;
 
-  /*
-   * XXX: we assume that lookup was done first, so pnode can be found with
-   * puffs_pn_nodewalk.
-   */
-  if ((pn = puffs_pn_nodewalk(global_pu, 0, &fs_m_in.m_vfs_fs_mountpoint.inode))
-         == NULL)
+  if ((pn = puffs_pn_nodewalk(global_pu, 0, &ino_nr)) == NULL)
        return(EINVAL);
 
-
   if (pn->pn_mountpoint) r = EBUSY;
 
   /* It may not be special. */
@@ -76,14 +71,13 @@ int fs_mountpoint(void)
 /*===========================================================================*
  *                             fs_unmount                                   *
  *===========================================================================*/
-int fs_unmount(void)
+void fs_unmount(void)
 {
   int error;
 
-  /* XXX there is no information about flags, 0 should be safe enough */
-  error = global_pu->pu_ops.puffs_fs_unmount(global_pu, 0);
+  /* Always force unmounting, as VFS will not tolerate failure. */
+  error = global_pu->pu_ops.puffs_fs_unmount(global_pu, MNT_FORCE);
   if (error) {
-        /* XXX we can't return any error to VFS */
        lpuffs_debug("user handler failed to unmount filesystem!\
                Force unmount!\n");
   } 
@@ -92,8 +86,6 @@ int fs_unmount(void)
 
   /* Finish off the unmount. */
   PU_SETSTATE(global_pu, PUFFS_STATE_UNMOUNTED);
-  unmountdone = TRUE;
+  mounted = FALSE;
   global_pu->pu_pn_root->pn_count--;
-
-  return(OK);
 }
index e516dfcb784f4334e647528e2ad2ec8031906cd1..855bc27a60a03d34613a383b7d1195ec791958fa 100644 (file)
@@ -3,11 +3,8 @@
  */
 
 #include "fs.h"
-#include <sys/stat.h>
 #include <string.h>
 #include <assert.h>
-#include <minix/com.h>
-#include <minix/vfsif.h>
 
 #include "puffs.h"
 #include "puffs_priv.h"
 /*===========================================================================*
  *                             fs_create                                    *
  *===========================================================================*/
-int fs_create(void)
+int fs_create(ino_t dir_nr, char *name, mode_t mode, uid_t uid, gid_t gid,
+       struct fsdriver_node *node)
 {
   int r;
   struct puffs_node *pn_dir;
   struct puffs_node *pn;
-  mode_t omode;
   struct puffs_newinfo pni;
   struct puffs_kcn pkcnp;
   PUFFS_MAKECRED(pcr, &global_kcred);
   struct puffs_cn pcn = {&pkcnp, (struct puffs_cred *) __UNCONST(pcr), {0,0,0}};
   struct vattr va;
   struct timespec cur_time;
-  int len;
 
   if (global_pu->pu_ops.puffs_node_create == NULL) {
        lpuffs_debug("No puffs_node_create");
        return(ENFILE);
   }
 
-  /* Read request message */
-  omode = fs_m_in.m_vfs_fs_create.mode;
-  caller_uid = fs_m_in.m_vfs_fs_create.uid;
-  caller_gid = fs_m_in.m_vfs_fs_create.gid;
-
   /* Copy the last component (i.e., file name) */
-  len = fs_m_in.m_vfs_fs_create.path_len;
-  pcn.pcn_namelen = len - 1;
-  if (pcn.pcn_namelen > NAME_MAX)
-       return(ENAMETOOLONG);
-
-  err_code = sys_safecopyfrom(VFS_PROC_NR, fs_m_in.m_vfs_fs_create.grant,
-                             (vir_bytes) 0, (vir_bytes) pcn.pcn_name,
-                             (size_t) len);
-  if (err_code != OK) return(err_code);
-  NUL(pcn.pcn_name, len, sizeof(pcn.pcn_name));
+  pcn.pcn_namelen = strlen(name);
+  assert(pcn.pcn_namelen <= NAME_MAX);
+  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, &fs_m_in.m_vfs_fs_create.inode)) == NULL)
+  if ((pn_dir = puffs_pn_nodewalk(global_pu, 0, &dir_nr)) == NULL)
        return(ENOENT);
 
   memset(&pni, 0, sizeof(pni));
@@ -63,9 +47,9 @@ int fs_create(void)
   
   memset(&va, 0, sizeof(va));
   va.va_type = VREG;
-  va.va_mode = omode;
-  va.va_uid = caller_uid;
-  va.va_gid = caller_gid;
+  va.va_mode = mode;
+  va.va_uid = uid;
+  va.va_gid = gid;
   va.va_atime = va.va_mtime = va.va_ctime = cur_time;
 
   if (buildpath) {
@@ -99,13 +83,12 @@ int fs_create(void)
   update_timens(pn_dir, MTIME | CTIME, &cur_time);
 
   /* Reply message */
-  fs_m_out.m_fs_vfs_create.inode = pn->pn_va.va_fileid;
-  fs_m_out.m_fs_vfs_create.mode = pn->pn_va.va_mode;
-  fs_m_out.m_fs_vfs_create.file_size = pn->pn_va.va_size;
-
-  /* This values are needed for the execution */
-  fs_m_out.m_fs_vfs_create.uid = pn->pn_va.va_uid;
-  fs_m_out.m_fs_vfs_create.gid = pn->pn_va.va_gid;
+  node->fn_ino_nr = pn->pn_va.va_fileid;
+  node->fn_mode = pn->pn_va.va_mode;
+  node->fn_size = pn->pn_va.va_size;
+  node->fn_uid = pn->pn_va.va_uid;
+  node->fn_gid = pn->pn_va.va_gid;
+  node->fn_dev = NO_DEV;
 
   return(OK);
 }
@@ -114,7 +97,8 @@ int fs_create(void)
 /*===========================================================================*
  *                             fs_mknod                                     *
  *===========================================================================*/
-int fs_mknod(void)
+int fs_mknod(ino_t dir_nr, char *name, mode_t mode, uid_t uid, gid_t gid,
+       dev_t dev)
 {
   int r;
   struct puffs_node *pn_dir;
@@ -125,30 +109,19 @@ int fs_mknod(void)
   struct puffs_cn pcn = {&pkcnp, (struct puffs_cred *) __UNCONST(pcr), {0,0,0}};
   struct vattr va;
   struct timespec cur_time;
-  int len;
 
   if (global_pu->pu_ops.puffs_node_mknod == NULL) {
        lpuffs_debug("No puffs_node_mknod");
        return(ENFILE);
   }
 
-  /* Copy the last component and set up caller's user and group id */
-  len = fs_m_in.m_vfs_fs_mknod.path_len;
-  pcn.pcn_namelen = len - 1;
-  if (pcn.pcn_namelen > NAME_MAX)
-       return(ENAMETOOLONG);
-
-  err_code = sys_safecopyfrom(VFS_PROC_NR, fs_m_in.m_vfs_fs_mknod.grant,
-                             (vir_bytes) 0, (vir_bytes) pcn.pcn_name,
-                            (size_t) len);
-  if (err_code != OK) return(err_code);
-  NUL(pcn.pcn_name, len, sizeof(pcn.pcn_name));
-
-  caller_uid = fs_m_in.m_vfs_fs_mknod.uid;
-  caller_gid = fs_m_in.m_vfs_fs_mknod.gid;
+  /* Copy the last component */
+  pcn.pcn_namelen = strlen(name);
+  assert(pcn.pcn_namelen <= NAME_MAX);
+  strcpy(pcn.pcn_name, name);
 
   /* Get last directory pnode */
-  if ((pn_dir = puffs_pn_nodewalk(global_pu, 0, &fs_m_in.m_vfs_fs_mknod.inode)) == NULL)
+  if ((pn_dir = puffs_pn_nodewalk(global_pu, 0, &dir_nr)) == NULL)
        return(ENOENT);
 
   memset(&pni, 0, sizeof(pni));
@@ -158,10 +131,10 @@ int fs_mknod(void)
 
   memset(&va, 0, sizeof(va));
   va.va_type = VDIR;
-  va.va_mode = fs_m_in.m_vfs_fs_mknod.mode;
-  va.va_uid = caller_uid;
-  va.va_gid = caller_gid;
-  va.va_rdev = fs_m_in.m_vfs_fs_mknod.device;
+  va.va_mode = mode;
+  va.va_uid = uid;
+  va.va_gid = gid;
+  va.va_rdev = dev;
   va.va_atime = va.va_mtime = va.va_ctime = cur_time;
 
   if (buildpath) {
@@ -197,7 +170,7 @@ int fs_mknod(void)
 /*===========================================================================*
  *                             fs_mkdir                                     *
  *===========================================================================*/
-int fs_mkdir(void)
+int fs_mkdir(ino_t dir_nr, char *name, mode_t mode, uid_t uid, gid_t gid)
 {
   int r;
   struct puffs_node *pn_dir;
@@ -208,30 +181,19 @@ int fs_mkdir(void)
   struct puffs_cn pcn = {&pkcnp, (struct puffs_cred *) __UNCONST(pcr), {0,0,0}};
   struct vattr va;
   struct timespec cur_time;
-  int len;
 
   if (global_pu->pu_ops.puffs_node_mkdir == NULL) {
        lpuffs_debug("No puffs_node_mkdir");
        return(ENFILE);
   }
 
-  /* Copy the last component and set up caller's user and group id */
-  len = fs_m_in.m_vfs_fs_mkdir.path_len;
-  pcn.pcn_namelen = len - 1;
-  if (pcn.pcn_namelen > NAME_MAX)
-       return(ENAMETOOLONG);
-
-  err_code = sys_safecopyfrom(VFS_PROC_NR, fs_m_in.m_vfs_fs_mkdir.grant,
-                             (vir_bytes) 0, (vir_bytes) pcn.pcn_name,
-                             (phys_bytes) len);
-  if (err_code != OK) return(err_code);
-  NUL(pcn.pcn_name, len, sizeof(pcn.pcn_name));
-
-  caller_uid = fs_m_in.m_vfs_fs_mkdir.uid;
-  caller_gid = fs_m_in.m_vfs_fs_mkdir.gid;
+  /* Copy the last component */
+  pcn.pcn_namelen = strlen(name);
+  assert(pcn.pcn_namelen <= NAME_MAX);
+  strcpy(pcn.pcn_name, name);
 
   /* Get last directory pnode */
-  if ((pn_dir = puffs_pn_nodewalk(global_pu, 0, &fs_m_in.m_vfs_fs_mkdir.inode)) == NULL)
+  if ((pn_dir = puffs_pn_nodewalk(global_pu, 0, &dir_nr)) == NULL)
        return(ENOENT);
   
   cur_time = clock_timespec();
@@ -241,9 +203,9 @@ int fs_mkdir(void)
 
   memset(&va, 0, sizeof(va));
   va.va_type = VDIR;
-  va.va_mode = fs_m_in.m_vfs_fs_mkdir.mode;
-  va.va_uid = caller_uid;
-  va.va_gid = caller_gid;
+  va.va_mode = mode;
+  va.va_uid = uid;
+  va.va_gid = gid;
   va.va_atime = va.va_mtime = va.va_ctime = cur_time;
 
   if (buildpath) {
@@ -280,7 +242,8 @@ int fs_mkdir(void)
 /*===========================================================================*
  *                             fs_slink                                     *
  *===========================================================================*/
-int fs_slink(void)
+int fs_slink(ino_t dir_nr, char *name, uid_t uid, gid_t gid,
+       struct fsdriver_data *data, size_t bytes)
 {
   int r;
   struct pnode *pn;            /* pnode containing symbolic link */
@@ -291,34 +254,22 @@ int fs_slink(void)
   PUFFS_MAKECRED(pcr, &global_kcred);
   struct puffs_cn pcn = {&pkcnp, (struct puffs_cred *) __UNCONST(pcr), {0,0,0}};
   struct vattr va;
-  int len;
-
-  caller_uid = fs_m_in.m_vfs_fs_slink.uid;
-  caller_gid = fs_m_in.m_vfs_fs_slink.gid;
 
   /* Copy the link name's last component */
-  len = fs_m_in.m_vfs_fs_slink.path_len;
-  pcn.pcn_namelen = len - 1;
-  if (pcn.pcn_namelen > NAME_MAX)
-       return(ENAMETOOLONG);
+  pcn.pcn_namelen = strlen(name);
+  if (pcn.pcn_namelen <= NAME_MAX);
+  strcpy(pcn.pcn_name, name);
 
-  if (fs_m_in.m_vfs_fs_slink.mem_size >= PATH_MAX)
+  if (bytes >= PATH_MAX)
        return(ENAMETOOLONG);
 
-  r = sys_safecopyfrom(VFS_PROC_NR, fs_m_in.m_vfs_fs_slink.grant_path,
-                      (vir_bytes) 0, (vir_bytes) pcn.pcn_name,
-                      (size_t) len);
-  if (r != OK) return(r);
-  NUL(pcn.pcn_name, len, sizeof(pcn.pcn_name));
-
   /* Copy the target path (note that it's not null terminated) */
-  r = sys_safecopyfrom(VFS_PROC_NR, fs_m_in.m_vfs_fs_slink.grant_target,
-                      (vir_bytes) 0, (vir_bytes) target, 
-                      fs_m_in.m_vfs_fs_slink.mem_size);
-  if (r != OK) return(r);
-  target[fs_m_in.m_vfs_fs_slink.mem_size] = '\0';
+  if ((r = fsdriver_copyin(data, 0, target, bytes)) != OK)
+       return r;
+
+  target[bytes] = '\0';
 
-  if (strlen(target) != (size_t) fs_m_in.m_vfs_fs_slink.mem_size) {
+  if (strlen(target) != bytes) {
        /* This can happen if the user provides a buffer
         * with a \0 in it. This can cause a lot of trouble
         * when the symlink is used later. We could just use
@@ -330,7 +281,7 @@ int fs_slink(void)
        return(ENAMETOOLONG);
   }
 
-  if ((pn_dir = puffs_pn_nodewalk(global_pu, 0, &fs_m_in.m_vfs_fs_slink.inode)) == NULL)
+  if ((pn_dir = puffs_pn_nodewalk(global_pu, 0, &dir_nr)) == NULL)
        return(EINVAL);
 
   memset(&pni, 0, sizeof(pni));
@@ -339,8 +290,8 @@ int fs_slink(void)
   memset(&va, 0, sizeof(va));
   va.va_type = VLNK;
   va.va_mode = (I_SYMBOLIC_LINK | RWX_MODES);
-  va.va_uid = caller_uid;
-  va.va_gid = caller_gid;
+  va.va_uid = uid;
+  va.va_gid = gid;
   va.va_atime = va.va_mtime = va.va_ctime = clock_timespec();
 
   if (buildpath) {
@@ -367,12 +318,3 @@ int fs_slink(void)
 
   return(r);
 }
-
-
-/*===========================================================================*
- *                             fs_inhibread                                 *
- *===========================================================================*/
-int fs_inhibread(void)
-{
-  return(OK);
-}
index eece52592e896a9fd4becf83c2a3cf5db4ba2b97..76a4de60b18c2ba6d381c6dfdd284d2323b00541 100644 (file)
 #include <stdlib.h>
 #include <string.h>
 
-#include <minix/endpoint.h>
-#include <minix/vfsif.h>
-#include <minix/libminixfs.h>
-
 #include "puffs.h"
 #include "puffs_priv.h"
 
-char dot2[3] = "..";   /* permissions for . and ..                 */
-
-static char *get_name(char *name, char string[NAME_MAX+1]);
-static int ltraverse(struct puffs_node *pn, char *suffix);
-static int parse_path(ino_t dir_ino, ino_t root_ino, int flags, struct
-       puffs_node **res_inop, size_t *offsetp, int *symlinkp);
-
-/*===========================================================================*
- *                             fs_lookup                                    *
- *===========================================================================*/
-int fs_lookup(void)
-{
-  cp_grant_id_t grant;
-  int r, r1, flags, symlinks;
-  unsigned int len;
-  size_t offset = 0, path_size;
-  ino_t dir_ino, root_ino;
-  struct puffs_node *pn;
-
-  grant                = fs_m_in.m_vfs_fs_lookup.grant_path;
-  path_size    = fs_m_in.m_vfs_fs_lookup.path_size;    /* Size of the buffer */
-  len          = fs_m_in.m_vfs_fs_lookup.path_len;     /* including terminating nul */
-  dir_ino      = fs_m_in.m_vfs_fs_lookup.dir_ino;
-  root_ino     = fs_m_in.m_vfs_fs_lookup.root_ino;
-  flags                = fs_m_in.m_vfs_fs_lookup.flags;
-
-  /* Check length. */
-  if (len > sizeof(user_path)) return(E2BIG);  /* too big for buffer */
-  if (len == 0) return(EINVAL);                        /* too small */
-
-  /* Copy the pathname and set up caller's user and group id */
-  r = sys_safecopyfrom(VFS_PROC_NR, grant, /*offset*/ 0,
-            (vir_bytes) user_path, (size_t) len);
-  if (r != OK) return(r);
-
-  /* Verify this is a null-terminated path. */
-  if (user_path[len - 1] != '\0') return(EINVAL);
-
-  memset(&credentials, 0, sizeof(credentials));
-  if(!(flags & PATH_GET_UCRED)) { /* Do we have to copy uid/gid credentials? */
-        caller_uid      = fs_m_in.m_vfs_fs_lookup.uid;
-        caller_gid      = fs_m_in.m_vfs_fs_lookup.gid;
-  } else {
-       if((r=fs_lookup_credentials(&credentials,
-               &caller_uid, &caller_gid,
-               fs_m_in.m_vfs_fs_lookup.grant_ucred,
-               fs_m_in.m_vfs_fs_lookup.ucred_size)) != OK)
-               return r;
-  }
-
-
-  /* Lookup pnode */
-  pn = NULL;
-  r = parse_path(dir_ino, root_ino, flags, &pn, &offset, &symlinks);
-
-  if (symlinks != 0 && (r == ELEAVEMOUNT || r == EENTERMOUNT || r == ESYMLINK)){
-       len = strlen(user_path)+1;
-       if (len > path_size) return(ENAMETOOLONG);
-
-       r1 = sys_safecopyto(VFS_PROC_NR, grant, (vir_bytes) 0,
-                           (vir_bytes) user_path, (size_t) len);
-       if (r1 != OK) return(r1);
-  }
-
-  if (r == ELEAVEMOUNT || r == ESYMLINK) {
-       /* Report offset and the error */
-       fs_m_out.m_fs_vfs_lookup.offset = offset;
-       fs_m_out.m_fs_vfs_lookup.symloop = symlinks;
-       
-       return(r);
-  }
-
-  if (r != OK && r != EENTERMOUNT) {
-       return(r);
-  }
-
-  if (r == OK) {
-       /* Open pnode */
-       pn->pn_count++;
-  }
-
-  fs_m_out.m_fs_vfs_lookup.inode       = pn->pn_va.va_fileid;
-  fs_m_out.m_fs_vfs_lookup.mode                = pn->pn_va.va_mode;
-  fs_m_out.m_fs_vfs_lookup.file_size   = pn->pn_va.va_size;
-  fs_m_out.m_fs_vfs_lookup.symloop     = symlinks;
-  fs_m_out.m_fs_vfs_lookup.uid         = pn->pn_va.va_uid;
-  fs_m_out.m_fs_vfs_lookup.gid         = pn->pn_va.va_gid;
-
-  /* This is only valid for block and character specials. But it doesn't
-   * cause any harm to always set the device field. */
-  fs_m_out.m_fs_vfs_lookup.device      = pn->pn_va.va_rdev;
-
-  if (r == EENTERMOUNT) {
-       fs_m_out.m_fs_vfs_lookup.offset = offset;
-  }
-  
-  return(r);
-}
-
 
 /*===========================================================================*
- *                             parse_path                                   *
+ *                             fs_lookup                                    *
  *===========================================================================*/
-static int parse_path(
-       ino_t dir_ino,
-       ino_t root_ino,
-       int flags,
-       struct puffs_node **res_inop,
-       size_t *offsetp,
-       int *symlinkp
-)
+int fs_lookup(ino_t dir_nr, char *name, struct fsdriver_node *node,
+       int *is_mountpt)
 {
-  /* Parse the path in user_path, starting at dir_ino. If the path is the empty
-   * string, just return dir_ino. It is upto the caller to treat an empty
-   * path in a special way. Otherwise, if the path consists of just one or
-   * more slash ('/') characters, the path is replaced with ".". Otherwise,
-   * just look up the first (or only) component in path after skipping any
-   * leading slashes.
-   */
-  int r, leaving_mount;
   struct puffs_node *pn, *pn_dir;
-  char *cp, *next_cp; /* component and next component */
-  char component[NAME_MAX+1];
-
-  /* Start parsing path at the first component in user_path */
-  cp = user_path;
 
-  /* No symlinks encountered yet */
-  *symlinkp = 0;
-
-  /* Find starting pnode according to the request message */
-  /* XXX it's deffinitely OK to use nodewalk here */
-  if ((pn = puffs_pn_nodewalk(global_pu, 0, &dir_ino)) == NULL) {
+  /* Find the pnode of the directory node. */
+  if ((pn_dir = puffs_pn_nodewalk(global_pu, 0, &dir_nr)) == NULL) {
        lpuffs_debug("nodewalk failed\n");
-       return(ENOENT);
-  }
-
-  /* If dir has been removed return ENOENT. */
-  if (pn->pn_va.va_nlink == NO_LINK) return(ENOENT);
-
-  /* If the given start pnode is a mountpoint, we must be here because the file
-   * system mounted on top returned an ELEAVEMOUNT error. In this case, we must
-   * only accept ".." as the first path component.
-   */
-  leaving_mount = pn->pn_mountpoint; /* True iff pn is a mountpoint */
-
-  /* Scan the path component by component. */
-  while (TRUE) {
-       if (cp[0] == '\0') {
-               /* We're done; either the path was empty or we've parsed all
-                  components of the path */
-
-               *res_inop = pn;
-               *offsetp += cp - user_path;
-
-               /* Return EENTERMOUNT if we are at a mount point */
-               if (pn->pn_mountpoint) return(EENTERMOUNT);
-
-               return(OK);
-       }
-
-       while(cp[0] == '/') cp++;
-       next_cp = get_name(cp, component);
-       if (next_cp == NULL) {
-               return(err_code);
-       }
-
-       /* Special code for '..'. A process is not allowed to leave a chrooted
-        * environment. A lookup of '..' at the root of a mounted filesystem
-        * has to return ELEAVEMOUNT. In both cases, the caller needs search
-        * permission for the current pnode, as it is used as directory.
-        */
-       if (strcmp(component, "..") == 0) {
-               /* 'pn' is now accessed as directory */
-               if ((r = forbidden(pn, X_BIT)) != OK) {
-                       return(r);
-               }
-
-               if (pn->pn_va.va_fileid == root_ino) {
-                       cp = next_cp;
-                       continue;       /* Ignore the '..' at a process' root
-                                          and move on to the next component */
-               }
-
-               if (pn->pn_va.va_fileid == global_pu->pu_pn_root->pn_va.va_fileid
-                       && !is_root_fs) {
-                       /* Climbing up to parent FS */
-                       *offsetp += cp - user_path;
-                       return(ELEAVEMOUNT);
-               }
-       }
-
-       /* Only check for a mount point if we are not coming from one. */
-       if (!leaving_mount && pn->pn_mountpoint) {
-               /* Going to enter a child FS */
-
-               *res_inop = pn;
-               *offsetp += cp - user_path;
-               return(EENTERMOUNT);
-       }
-
-       /* There is more path.  Keep parsing.
-        * If we're leaving a mountpoint, skip directory permission checks.
-        */
-       pn_dir = pn;
-       if ((pn_dir->pn_va.va_mode & I_TYPE) != I_DIRECTORY)  {
-               return(ENOTDIR);
-       }
-       pn = advance(pn_dir, leaving_mount ? dot2 : component, CHK_PERM);
-       if (err_code == ELEAVEMOUNT || err_code == EENTERMOUNT)
-               err_code = OK;
-
-       if (err_code != OK) {
-               return(err_code);
-       }
-       
-       assert(pn != NULL);
-
-       leaving_mount = 0;
-
-       /* The call to advance() succeeded.  Fetch next component. */
-       if (S_ISLNK(pn->pn_va.va_mode)) {
-               if (next_cp[0] == '\0' && (flags & PATH_RET_SYMLINK)) {
-                       *res_inop = pn;
-                       *offsetp += next_cp - user_path;
-                       return(OK);
-               }
-
-               /* Extract path name from the symlink file */
-               r = ltraverse(pn, next_cp);
-               next_cp = user_path;
-               *offsetp = 0;
-
-               /* Symloop limit reached? */
-               if (++(*symlinkp) > _POSIX_SYMLOOP_MAX)
-                       r = ELOOP;
-
-               if (r != OK)
-                       return(r);
-
-               if (next_cp[0] == '/')
-                        return(ESYMLINK);
-
-               pn = pn_dir;
-       }
-
-       cp = next_cp; /* Process subsequent component in next round */
-  }
-
-}
-
-
-/*===========================================================================*
- *                             ltraverse                                    *
- *===========================================================================*/
-static int ltraverse(
-       struct puffs_node *pn,  /* symbolic link */
-       char *suffix            /* current remaining path. Has to point in the
-                                * user_path buffer
-                                */
-)
-{
-/* Traverse a symbolic link. Copy the link text from the pnode and insert
- * the text into the path. Return error code or report success. Base
- * directory has to be determined according to the first character of the
- * new pathname.
- */
-  int r;
-  char sp[PATH_MAX];
-  size_t llen = PATH_MAX; /* length of link */
-  size_t slen;           /* length of suffix */
-  PUFFS_MAKECRED(pcr, &global_kcred);
-
-
-  if (!S_ISLNK(pn->pn_va.va_mode))
-       r = EACCES;
-
-  if (global_pu->pu_ops.puffs_node_readlink == NULL)
        return(EINVAL);
+  }
 
-  if (global_pu->pu_ops.puffs_node_readlink(global_pu, pn, pcr, sp, &llen) != 0)
-       return(EINVAL);
+  if (!S_ISDIR(pn_dir->pn_va.va_mode))
+       return ENOTDIR;
 
-  slen = strlen(suffix);
-
-  /* The path we're parsing looks like this:
-   * /already/processed/path/<link> or
-   * /already/processed/path/<link>/not/yet/processed/path
-   * After expanding the <link>, the path will look like
-   * <expandedlink> or
-   * <expandedlink>/not/yet/processed
-   * In both cases user_path must have enough room to hold <expandedlink>.
-   * However, in the latter case we have to move /not/yet/processed to the
-   * right place first, before we expand <link>. When strlen(<expandedlink>) is
-   * smaller than strlen(/already/processes/path), we move the suffix to the
-   * left. Is strlen(<expandedlink>) greater then we move it to the right. Else
-   * we do nothing.
-   */
-
-  if (slen > 0) { /* Do we have path after the link? */
-       /* For simplicity we require that suffix starts with a slash */
-       if (suffix[0] != '/') {
-               panic("ltraverse: suffix does not start with a slash");
-       }
+  if ((pn = advance(pn_dir, name)) == NULL)
+       return err_code;
 
-       /* To be able to expand the <link>, we have to move the 'suffix'
-        * to the right place.
-        */
-       if (slen + llen + 1 > sizeof(user_path))
-               return(ENAMETOOLONG);/* <expandedlink>+suffix+\0 does not fit*/
-       if ((unsigned)(suffix - user_path) != llen) {
-               /* Move suffix left or right if needed */
-               memmove(&user_path[llen], suffix, slen+1);
-       }
-  } else {
-       if (llen + 1 > sizeof(user_path))
-               return(ENAMETOOLONG); /* <expandedlink> + \0 does not fit */
+  pn->pn_count++; /* open pnode */
 
-       /* Set terminating nul */
-       user_path[llen]= '\0';
-  }
+  node->fn_ino_nr = pn->pn_va.va_fileid;
+  node->fn_mode = pn->pn_va.va_mode;
+  node->fn_size = pn->pn_va.va_size;
+  node->fn_uid = pn->pn_va.va_uid;
+  node->fn_gid = pn->pn_va.va_gid;
+  node->fn_dev = pn->pn_va.va_rdev;
 
-  /* Everything is set, now copy the expanded link to user_path */
-  memmove(user_path, sp, llen);
+  *is_mountpt = pn->pn_mountpoint;
 
-  return(OK);
+  return OK;
 }
 
 
@@ -359,9 +62,7 @@ static int ltraverse(
  *===========================================================================*/
 struct puffs_node *advance(
        struct puffs_node *pn_dir,      /* pnode for directory to be searched */
-       char string[NAME_MAX + 1],      /* component name to look for */
-       int chk_perm                    /* check permissions when string is
-                                        * looked up*/
+       char string[NAME_MAX + 1]       /* component name to look for */
 )
 {
 /* Given a directory and a component of a path, look up the component in
@@ -382,6 +83,8 @@ struct puffs_node *advance(
   dev_t rdev;
   int error;
 
+  assert(pn_dir != NULL);
+
   err_code = OK;
 
   /* If 'string' is empty, return an error. */
@@ -390,16 +93,10 @@ struct puffs_node *advance(
        return(NULL);
   }
 
-  /* Check for NULL. */
-  if (pn_dir == NULL)
+  /* If dir has been removed return ENOENT. */
+  if (pn_dir->pn_va.va_nlink == NO_LINK) {
+       err_code = ENOENT;
        return(NULL);
-
-  if (chk_perm) {
-       /* Just search permission is checked */
-       if (forbidden(pn_dir, X_BIT)) {
-               err_code = EACCES;
-               return(NULL);
-       }
   }
 
   if (strcmp(string, ".") == 0) {
@@ -407,10 +104,13 @@ struct puffs_node *advance(
         * will be parent path (same pnode as the one to be looked up) +
         * requested path. E.g. after several lookups we might get advance
         * for "." with parent path "/././././././././.".
+        * FIXME: how is ".." handled then?
         *
         * Another problem is that after lookup pnode will be added
         * to the pu_pnodelst, which already contains pnode instance for this
         * pnode. It will cause lot of troubles.
+        * FIXME: check if this is actually correct, because if it is, we are
+        * in lots of trouble; there are many ways to reach already-open pnodes
         */
        return pn_dir;
   }
@@ -433,8 +133,7 @@ struct puffs_node *advance(
   }
 
   /* lookup *must* be present */
-  error = global_pu->pu_ops.puffs_node_lookup(global_pu, pn_dir,
-                 &pni, &pcn);
+  error = global_pu->pu_ops.puffs_node_lookup(global_pu, pn_dir, &pni, &pcn);
 
   if (buildpath) {
        if (error) {
@@ -459,96 +158,11 @@ struct puffs_node *advance(
   if (error) {
        err_code = error < 0 ? error : -error;
        return(NULL);
-  } else {
-       /* In MFS/ext2 it's set by search_dir, puffs_node_lookup error codes are unclear,
-        * so we use error variable there
-        */
-       err_code = OK;
   }
 
-  assert(pn != NULL);
-
-  /* The following test is for "mountpoint/.." where mountpoint is a
-   * mountpoint. ".." will refer to the root of the mounted filesystem,
-   * but has to become a reference to the parent of the 'mountpoint'
-   * directory.
-   *
-   * This case is recognized by the looked up name pointing to a
-   * root pnode, and the directory in which it is held being a
-   * root pnode, _and_ the name[1] being '.'. (This is a test for '..'
-   * and excludes '.'.)
-   */
-  if (pn->pn_va.va_fileid == global_pu->pu_pn_root->pn_va.va_fileid) {
-         if (pn_dir->pn_va.va_fileid == global_pu->pu_pn_root->pn_va.va_fileid) {
-                 if (string[1] == '.') {
-                         if (!is_root_fs) {
-                                 /* Climbing up mountpoint */
-                                 err_code = ELEAVEMOUNT;
-                         }
-                 }
-         }
-  }
+  err_code = OK;
 
-  /* See if the pnode is mounted on.  If so, switch to root directory of the
-   * mounted file system.  The super_block provides the linkage between the
-   * pnode mounted on and the root directory of the mounted file system.
-   */
-  if (pn->pn_mountpoint) {
-         /* Mountpoint encountered, report it */
-         err_code = EENTERMOUNT;
-  }
+  assert(pn != NULL);
 
   return(pn);
 }
-
-
-/*===========================================================================*
- *                             get_name                                     *
- *===========================================================================*/
-static char *get_name(
-       char *path_name,         /* path name to parse */
-       char string[NAME_MAX+1]  /* component extracted from 'old_name' */
-)
-{
-/* Given a pointer to a path name in fs space, 'path_name', copy the first
- * component to 'string' (truncated if necessary, always nul terminated).
- * A pointer to the string after the first component of the name as yet
- * unparsed is returned.  Roughly speaking,
- * 'get_name' = 'path_name' - 'string'.
- *
- * This routine follows the standard convention that /usr/ast, /usr//ast,
- * //usr///ast and /usr/ast/ are all equivalent.
- *
- * If len of component is greater, than allowed, then return 0.
- */
-  size_t len;
-  char *cp, *ep;
-
-  cp = path_name;
-
-  /* Skip leading slashes */
-  while (cp[0] == '/') cp++;
-
-  /* Find the end of the first component */
-  ep = cp;
-  while (ep[0] != '\0' && ep[0] != '/')
-       ep++;
-
-  len = (size_t) (ep - cp);
-  /* XXX we don't check name_max of fileserver (probably we can't) */
-  if (len > NAME_MAX) {
-       err_code = ENAMETOOLONG;
-       return(NULL);
-  }
-
-  /* Special case of the string at cp is empty */
-  if (len == 0)
-       strcpy(string, ".");  /* Return "." */
-  else {
-       memcpy(string, cp, len);
-       string[len]= '\0';
-  }
-
-  return(ep);
-}
index b8283091539c85f56a33b2961da05cf770fca8e7..49438cf966b711cd2dae87b1b77259c907dceb0a 100644 (file)
@@ -39,10 +39,6 @@ __RCSID("$NetBSD: pnode.c,v 1.13 2012/08/16 09:25:43 manu Exp $");
 #include <string.h>
 
 #include "puffs_priv.h"
-#if defined(__minix)
-#include <minix/type.h>
-#include "proto.h"
-#endif /* defined(__minix) */
 
 /*
  * Well, you're probably wondering why this isn't optimized.
index 6a127f51305a47f22bc0d05885ba0b7c7620c7ec..818180692cb27763a738061124f0c16ab2cd6af0 100644 (file)
@@ -3,43 +3,37 @@
  */
 
 #include "fs.h"
-#include <minix/vfsif.h>
 
 #include "puffs.h"
 #include "puffs_priv.h"
 
-static int in_group(gid_t grp);
-
 
 /*===========================================================================*
  *                             fs_chmod                                     *
  *===========================================================================*/
-int fs_chmod(void)
+int fs_chmod(ino_t ino_nr, mode_t *mode)
 {
 /* Perform the chmod(name, mode) system call. */
   struct puffs_node *pn;
-  mode_t mode;
   struct vattr va;
   PUFFS_MAKECRED(pcr, &global_kcred);
 
   if (global_pu->pu_ops.puffs_node_setattr == NULL)
        return(EINVAL);
 
-  mode = fs_m_in.m_vfs_fs_chmod.mode;
-
-  if ((pn = puffs_pn_nodewalk(global_pu, 0, &fs_m_in.m_vfs_fs_chmod.inode)) == NULL)
+  if ((pn = puffs_pn_nodewalk(global_pu, 0, &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);
+  va.va_mode = (pn->pn_va.va_mode & ~ALL_MODES) | (*mode & ALL_MODES);
   va.va_ctime = clock_timespec();
 
   if (global_pu->pu_ops.puffs_node_setattr(global_pu, pn, &va, pcr) != 0)
        return(EINVAL);
 
   /* Return full new mode to caller. */
-  fs_m_out.m_fs_vfs_chmod.mode = pn->pn_va.va_mode;
+  *mode = pn->pn_va.va_mode;
 
   return(OK);
 }
@@ -48,94 +42,26 @@ int fs_chmod(void)
 /*===========================================================================*
  *                             fs_chown                                     *
  *===========================================================================*/
-int fs_chown(void)
+int fs_chown(ino_t ino_nr, uid_t uid, gid_t gid, mode_t *mode)
 {
   struct puffs_node *pn;
   struct vattr va;
   PUFFS_MAKECRED(pcr, &global_kcred);
 
-  if ((pn = puffs_pn_nodewalk(global_pu, 0, &fs_m_in.m_vfs_fs_chown.inode)) == NULL)
+  if ((pn = puffs_pn_nodewalk(global_pu, 0, &ino_nr)) == NULL)
        return(EINVAL);
 
-  /* Not permitted to change the owner of a file on a read-only file sys. */
-  if (!is_readonly_fs) {
-       puffs_vattr_null(&va);
-       va.va_uid = fs_m_in.m_vfs_fs_chown.uid;
-       va.va_gid = fs_m_in.m_vfs_fs_chown.gid;
-       va.va_mode = pn->pn_va.va_mode & ~(I_SET_UID_BIT | I_SET_GID_BIT);
-       va.va_ctime = clock_timespec();
+  puffs_vattr_null(&va);
+  va.va_uid = uid;
+  va.va_gid = gid;
+  va.va_mode = pn->pn_va.va_mode & ~(I_SET_UID_BIT | I_SET_GID_BIT);
+  va.va_ctime = clock_timespec();
 
-       if (global_pu->pu_ops.puffs_node_setattr(global_pu, pn, &va, pcr) != 0)
-               return(EINVAL);
-  }
+  if (global_pu->pu_ops.puffs_node_setattr(global_pu, pn, &va, pcr) != 0)
+       return(EINVAL);
 
   /* Update caller on current mode, as it may have changed. */
-  fs_m_out.m_fs_vfs_chown.mode = pn->pn_va.va_mode;
+  *mode = pn->pn_va.va_mode;
 
   return(OK);
 }
-
-
-/*===========================================================================*
- *                             forbidden                                    *
- *===========================================================================*/
-int forbidden(register struct puffs_node *pn, mode_t access_desired)
-{
-/* Given a pointer to an pnode, 'pn', and the access desired, determine
- * if the access is allowed, and if not why not.  The routine looks up the
- * caller's uid in the 'fproc' table.  If access is allowed, OK is returned
- * if it is forbidden, EACCES is returned.
- */
-
-  register mode_t bits, perm_bits;
-  int r, shift;
-
-  /* Isolate the relevant rwx bits from the mode. */
-  bits = pn->pn_va.va_mode;
-  if (caller_uid == SU_UID) {
-       /* Grant read and write permission.  Grant search permission for
-        * directories.  Grant execute permission (for non-directories) if
-        * and only if one of the 'X' bits is set.
-        */
-       if ( (bits & I_TYPE) == I_DIRECTORY ||
-            bits & ((X_BIT << 6) | (X_BIT << 3) | X_BIT))
-               perm_bits = R_BIT | W_BIT | X_BIT;
-       else
-               perm_bits = R_BIT | W_BIT;
-  } else {
-       if (caller_uid == pn->pn_va.va_uid) shift = 6;  /* owner */
-       else if (caller_gid == pn->pn_va.va_gid) shift = 3;     /* group */
-       else if (in_group(pn->pn_va.va_gid) == OK) shift = 3;   /* other groups */
-       else shift = 0;                                 /* other */
-       perm_bits = (bits >> shift) & (R_BIT | W_BIT | X_BIT);
-  }
-
-  /* If access desired is not a subset of what is allowed, it is refused. */
-  r = OK;
-  if ((perm_bits | access_desired) != perm_bits) r = EACCES;
-
-  /* Check to see if someone is trying to write on a file system that is
-   * mounted read-only.
-   */
-  if (r == OK) {
-       if (access_desired & W_BIT) {
-               r = is_readonly_fs ? EROFS : OK;
-       }
-  }
-
-  return(r);
-}
-
-
-/*===========================================================================*
- *                             in_group                                     *
- *===========================================================================*/
-static int in_group(gid_t grp)
-{
-  int i;
-  for(i = 0; i < credentials.vu_ngroups; i++)
-       if (credentials.vu_sgroups[i] == grp)
-               return(OK);
-
-  return(EINVAL);
-}
index 10ecfcd49fba8258a26173dff702d54be9ba148b..e67b7b4a4befe4aaf03359fa014410ca7538a235 100644 (file)
@@ -7,68 +7,64 @@ struct timespec;
 
 /* Function prototypes. */
 
-int fs_new_driver(void);
-
 /* inode.c */
-int fs_putnode(void);
+int fs_putnode(ino_t ino_nr, unsigned int count);
 void release_node(struct puffs_usermount *pu, struct puffs_node *pn );
 
-/* device.c */
-int dev_open(endpoint_t driver_e, dev_t dev, endpoint_t proc_e, int
-       flags);
-void dev_close(endpoint_t driver_e, dev_t dev);
-
 /* link.c */
-int fs_ftrunc(void);
-int fs_link(void);
-int fs_rdlink(void);
-int fs_rename(void);
-int fs_unlink(void);
+int fs_trunc(ino_t ino_nr, off_t start, off_t end);
+int fs_link(ino_t dir_nr, char *name, ino_t ino_nr);
+ssize_t fs_rdlink(ino_t ino_nr, struct fsdriver_data *data, size_t bytes);
+int fs_rename(ino_t old_dir_nr, char *old_name, ino_t new_dir_nr,
+       char *new_name);
+int fs_unlink(ino_t dir_nr, char *name, int call);
 
 /* misc.c */
-int fs_flush(void);
-int fs_sync(void);
+void fs_sync(void);
 
 /* mount.c */
-int fs_mountpoint(void);
-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);
+int fs_mountpt(ino_t ino_nr);
 
 /* open.c */
-int fs_create(void);
-int fs_inhibread(void);
-int fs_mkdir(void);
-int fs_mknod(void);
-int fs_slink(void);
+int fs_create(ino_t dir_nr, char *name, mode_t mode, uid_t uid, gid_t gid,
+       struct fsdriver_node *node);
+int fs_mkdir(ino_t dir_nr, char *name, mode_t mode, uid_t uid, gid_t gid);
+int fs_mknod(ino_t dir_nr, char *name, mode_t mode, uid_t uid, gid_t gid,
+       dev_t dev);
+int fs_slink(ino_t dir_nr, char *name, uid_t uid, gid_t gid,
+       struct fsdriver_data *data, size_t bytes);
 
 /* path.c */
-int fs_lookup(void);
-struct puffs_node *advance(struct puffs_node *dirp, char string[NAME_MAX
-       + 1], int chk_perm);
+int fs_lookup(ino_t dir_nr, char *name, struct fsdriver_node *node,
+       int *is_mountpt);
+struct puffs_node *advance(struct puffs_node *dirp, char string[NAME_MAX + 1]);
 
 /* protect.c */
-int fs_chmod(void);
-int fs_chown(void);
-int fs_getdents(void);
-int forbidden(struct puffs_node *rip, mode_t access_desired);
+int fs_chmod(ino_t ino_nr, mode_t *mode);
+int fs_chown(ino_t ino_nr, uid_t uid, gid_t gid, mode_t *mode);
 
 /* read.c */
-int fs_breadwrite(void);
-int fs_readwrite(void);
+ssize_t fs_read(ino_t ino_nr, struct fsdriver_data *data, size_t bytes,
+       off_t pos, int call);
+ssize_t fs_write(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);
 
 /* stadir.c */
-int fs_stat(void);
-int fs_statvfs(void);
+int fs_stat(ino_t ino, struct stat *statbuf);
+int fs_statvfs(struct statvfs *st);
 
 /* time.c */
-int fs_utime(void);
+int fs_utime(ino_t ino_nr, struct timespec *atime, struct timespec *mtime);
 
 /* utility.c */
-int no_sys(void);
-void mfs_nul_f(const char *file, int line, char *str, unsigned int len,
-       unsigned int maxlen);
 struct timespec clock_timespec(void);
 int update_timens(struct puffs_node *pn, int fl, struct timespec *);
-void lpuffs_debug(const char *format, ...);
+void lpuffs_debug(const char *format, ...)
+       __attribute__((__format__(__printf__, 1, 2)));
 
 #endif /* PUFFS_PROTO_H */
index 1d5bfe32cfc73a8257b0854b1dff2b7d501bf74e..d419631f99f366331dc266a65edcae6cb48dc6f1 100644 (file)
@@ -39,8 +39,6 @@ __RCSID("$NetBSD: puffs.c,v 1.117 2011/11/14 01:27:42 chs Exp $");
 
 #if defined(__minix)
 #include "fs.h"
-#include <minix/endpoint.h>
-#include <minix/vfsif.h>
 #endif /* defined(__minix) */
 
 #include <assert.h>
@@ -69,10 +67,13 @@ const struct mntopt puffsmopts[] = {
 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 void get_work(message *m_in);
-static void reply(endpoint_t who, message *m_out);
+static int get_work(message *msg, int *ipc_status);
 
 /* SEF functions and variables. */
 static void sef_local_startup(void);
@@ -126,7 +127,8 @@ int __wrap_main(int argc, char *argv[])
 
   assert(new_argc > 0);
 
-  get_work(&fs_m_in);
+  /* 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);
 }
@@ -419,43 +421,16 @@ puffs_mount(struct puffs_usermount *pu, const char *dir, int mntflags,
        puffs_cookie_t cookie)
 {
 #if defined(__minix)
-       endpoint_t src;
-       int error, ind;
-
        pu->pu_kargp->pa_root_cookie = cookie;
-       
-       src = fs_m_in.m_source;
-       error = OK;
-       caller_uid = INVAL_UID; /* To trap errors */
-       caller_gid = INVAL_GID;
-       req_nr = fs_m_in.m_type;
-
-       if (req_nr < FS_BASE) {
-               fs_m_in.m_type += FS_BASE;
-               req_nr = fs_m_in.m_type;
-        }
-       ind = req_nr - FS_BASE;
-
-       assert(ind == REQ_READ_SUPER);
-
-       if (ind < 0 || ind >= NREQS) {
-               error = EINVAL;
-       } else {
-               error = (*fs_call_vec[ind])();
-       }
 
-       fs_m_out.m_type = error;
-       if (IS_VFS_FS_TRANSID(last_request_transid)) {
-               /* If a transaction ID was set, reset it */
-               fs_m_out.m_type = TRNS_ADD_ID(fs_m_out.m_type,
-                                               last_request_transid);
-       }
-       reply(src, &fs_m_out);
+       /* Process the already-received mount request. */
+       fsdriver_process(&puffs_table, &fs_msg, fs_ipc_status, FALSE);
 
-       if (error) {
+       if (!mounted) {
+               /* This should never happen, unless VFS misbehaves.. */
                free(pu->pu_kargp);
                pu->pu_kargp = NULL;
-               errno = error;
+               errno = -EINVAL;
                return -1;
        }
 
@@ -466,7 +441,7 @@ puffs_mount(struct puffs_usermount *pu, const char *dir, int mntflags,
 
 /*ARGSUSED*/
 struct puffs_usermount *
-_puffs_init(int dummy, struct puffs_ops *pops, const char *mntfromname,
+puffs_init(struct puffs_ops *pops, const char *mntfromname,
        const char *puffsname, void *priv, uint32_t pflags)
 {
        struct puffs_usermount *pu;
@@ -492,7 +467,7 @@ _puffs_init(int dummy, struct puffs_ops *pops, const char *mntfromname,
 
        pargs->pa_vers = PUFFSVERSION;
        pargs->pa_flags = PUFFS_FLAG_KERN(pflags);
-       fillvnopmask(pops, pargs->pa_vnopmask);
+       fillvnopmask(pops, pargs);
        puffs_setmntinfo(pu, mntfromname, puffsname);
 
        puffs_zerostatvfs(&pargs->pa_svfsb);
@@ -584,11 +559,8 @@ void
 puffs__theloop(struct puffs_cc *pcc)
 {
        struct puffs_usermount *pu = pcc->pcc_pu;
-       int error, ind;
-
-       while (!unmountdone || !exitsignaled) {
-               endpoint_t src;
 
+       while (mounted || !exitsignaled) {
                /*
                 * Schedule existing requests.
                 */
@@ -604,32 +576,11 @@ puffs__theloop(struct puffs_cc *pcc)
                }
 
                /* Wait for request message. */
-               get_work(&fs_m_in);
+               if (get_work(&fs_msg, &fs_ipc_status) != OK)
+                       continue; /* recheck loop conditions */
 
-               src = fs_m_in.m_source;
-               error = OK;
-               caller_uid = INVAL_UID; /* To trap errors */
-               caller_gid = INVAL_GID;
-               req_nr = fs_m_in.m_type;
-
-               if (req_nr < FS_BASE) {
-                       fs_m_in.m_type += FS_BASE;
-                       req_nr = fs_m_in.m_type;
-               }
-               ind = req_nr - FS_BASE;
-
-               if (ind < 0 || ind >= NREQS) {
-                       error = EINVAL;
-               } else {
-                       error = (*fs_call_vec[ind])();
-               }
-
-               fs_m_out.m_type = error;
-               if (IS_VFS_FS_TRANSID(last_request_transid)) {
-                       /* If a transaction ID was set, reset it */
-                       fs_m_out.m_type = TRNS_ADD_ID(fs_m_out.m_type, last_request_transid);
-               }
-               reply(src, &fs_m_out);
+               /* Process it, and send a reply. */
+               fsdriver_process(&puffs_table, &fs_msg, fs_ipc_status, FALSE);
        }
 
        if (puffs__cc_restoremain(pu) == -1)
@@ -718,69 +669,27 @@ static void sef_cb_signal_handler(int signo)
   exitsignaled = 1;
   fs_sync();
 
-  /* If unmounting has already been performed, exit immediately.
-   * We might not get another message.
-   */
-  if (unmountdone) {
-        if (puffs__cc_restoremain(global_pu) == -1)
-                warn("cannot restore main context.  impending doom");
-       /* May happen if puffs_fakecc is set to 1. Currently librefuse sets it.
-        * There is a chance, that main loop hangs in receive() and we will
-        * never get any new message, so we have to exit() here.
-        */
-       exit(0);
-  }
+  sef_cancel();
 }
 
 /*===========================================================================*
  *                             get_work                                     *
  *===========================================================================*/
-static void get_work(
-       message *m_in   /* pointer to message */
-)
+static int get_work(message *msg, int *ipc_status)
 {
-  int r, srcok = 0;
-  endpoint_t src;
+  int r;
 
-  do {
-       if ((r = sef_receive(ANY, m_in)) != OK)         /* wait for message */
+  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);
-       src = m_in->m_source;
-
-       if(src == VFS_PROC_NR) {
-               if(unmountdone)
-                       lpuffs_debug("libpuffs: unmounted: unexpected message from FS\n");
-               else
-                       srcok = 1;              /* Normal FS request. */
-
-       } else
-               lpuffs_debug("libpuffs: unexpected source %d\n", src);
-  } while(!srcok);
-
-  assert((src == VFS_PROC_NR && !unmountdone));
-
-  last_request_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(last_request_transid));
-         fs_m_in.m_type = last_request_transid;  /* Backwards compat. */
-         last_request_transid = 0;
-  } else
-         assert(IS_VFS_FS_TRANSID(last_request_transid));
-}
-
-
-/*===========================================================================*
- *                             reply                                        *
- *===========================================================================*/
-static void reply(
-  endpoint_t who,
-  message *m_out                               /* report result */
-)
-{
-  if (OK != ipc_send(who, m_out))    /* send the message */
-       lpuffs_debug("libpuffs(%d) was unable to send reply\n", sef_self());
+       }
+       if (msg->m_source == VFS_PROC_NR)
+               break;
+       lpuffs_debug("libpuffs: unexpected source %d\n", msg->m_source);
+  }
 
-  last_request_transid = 0;
+  return r;
 }
 #endif /* defined(__minix) */
index 7e8817574fd576e7e298b90bb9c1904b3315a0ae..9b165b8f014cae022765cfa9c5cbb1b9474b7ddc 100644 (file)
@@ -93,7 +93,7 @@ struct puffs_node {
 #if defined(__minix)
        /* MINIX fields */
        char                    pn_mountpoint; /* true if mounted on */
-       int                     pn_count;          /* # times inode used */
+       unsigned int            pn_count;          /* # times inode used */
 #endif /* defined(__minix) */
 };
 #define PUFFS_NODE_REMOVED     0x01            /* not on entry list    */
index 4eaa14dbf2055669905707d6c357c0e79f6a7101..39bc9826d3f571eb15b46c68954603d88c1723d7 100644 (file)
 
 #if defined(__minix)
 
-/* XXX: MINIX */
-#define IGN_PERM            0
-#define CHK_PERM            1
-#define SU_UID          ((uid_t) 0)     /* super_user's uid_t */
-
 /* 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 */
 
-#define REQ_READ_SUPER   28
-
-#define NUL(str,l,m) mfs_nul_f(__FILE__,__LINE__,(str), (l), (m))
-
 #else
 extern pthread_mutex_t pu_lock;
 #define PU_LOCK() pthread_mutex_lock(&pu_lock)
index 84ee644b64dbb33ff5255a3aca5efb2f1e8dc68f..f7484033d680910b9bd7e5f2ea22e14690e648e2 100644 (file)
@@ -7,9 +7,6 @@
 #include <string.h>
 #include <stdlib.h>
 #include <dirent.h>
-#include <minix/com.h>
-#include <minix/u64.h>
-#include <minix/vfsif.h>
 #include <assert.h>
 #include <sys/param.h>
 
 #define GETDENTS_BUFSIZ  4096
 static char getdents_buf[GETDENTS_BUFSIZ];
 
-#define RW_BUFSIZ      (128 << 10)
+#define RW_BUFSIZ      (128 * 1024)
 static char rw_buf[RW_BUFSIZ];
 
 
 /*===========================================================================*
- *                             fs_readwrite                                 *
+ *                             fs_read                                      *
  *===========================================================================*/
-int fs_readwrite(void)
+ssize_t fs_read(ino_t ino_nr, struct fsdriver_data *data, size_t bytes,
+       off_t pos, int call)
 {
-  int r = OK, rw_flag;
-  cp_grant_id_t gid;
-  off_t pos;
-  size_t nrbytes, bytes_left, bytes_done = 0;
+  int r;
+  size_t bytes_left, bytes_done;
   struct puffs_node *pn;
-  struct vattr va;
   PUFFS_MAKECRED(pcr, &global_kcred);
 
-  if ((pn = puffs_pn_nodewalk(global_pu, 0, &fs_m_in.m_vfs_fs_readwrite.inode)) == NULL) {
-       lpuffs_debug("walk failed...\n");
+  if ((pn = puffs_pn_nodewalk(global_pu, 0, &ino_nr)) == NULL) {
+       lpuffs_debug("walk failed...\n");
         return(EINVAL);
   }
 
-  /* Get the values from the request message */
-  rw_flag = (fs_m_in.m_type == REQ_READ ? READING : WRITING);
-  gid = fs_m_in.m_vfs_fs_readwrite.grant;
-  pos = fs_m_in.m_vfs_fs_readwrite.seek_pos;
-  nrbytes = bytes_left = fs_m_in.m_vfs_fs_readwrite.nbytes;
-
-  if (nrbytes > RW_BUFSIZ)
-       nrbytes = bytes_left = RW_BUFSIZ;
-
-  memset(getdents_buf, '\0', GETDENTS_BUFSIZ);  /* Avoid leaking any data */
+  if (bytes > sizeof(rw_buf))
+       bytes = sizeof(rw_buf);
+  bytes_left = bytes;
 
-  if (rw_flag == READING) {
-       if (global_pu->pu_ops.puffs_node_read == NULL)
-               return(EINVAL);
+  if (global_pu->pu_ops.puffs_node_read == NULL)
+       return(EINVAL);
 
-       r = global_pu->pu_ops.puffs_node_read(global_pu, pn, (uint8_t *)rw_buf,
-                                               pos, &bytes_left, pcr, 0);
-       if (r) {
-               lpuffs_debug("puffs_node_read failed\n");
-               return(EINVAL);
-       }
-
-       bytes_done = nrbytes - bytes_left;
-       if (bytes_done) {
-               r = sys_safecopyto(VFS_PROC_NR, gid, (vir_bytes) 0,
-                                  (vir_bytes) rw_buf, bytes_done);
-               update_timens(pn, ATIME, NULL);
-       }
-  } else if (rw_flag == WRITING) {
-       /* At first try to change vattr */
-       if (global_pu->pu_ops.puffs_node_setattr == NULL)
-               return(EINVAL);
-
-       puffs_vattr_null(&va);
-       if ((u_quad_t)(pos + bytes_left) > pn->pn_va.va_size)
-               va.va_size = bytes_left + pos;
-       va.va_ctime = va.va_mtime = clock_timespec();
-       va.va_atime = pn->pn_va.va_atime;
-
-       r = global_pu->pu_ops.puffs_node_setattr(global_pu, pn, &va, pcr);
-       if (r) return(EINVAL);
-
-       r = sys_safecopyfrom(VFS_PROC_NR, gid, (vir_bytes) 0,
-                            (vir_bytes) rw_buf, nrbytes);
-       if (r != OK) return(EINVAL);
-
-       if (global_pu->pu_ops.puffs_node_write == NULL)
-               return(EINVAL);
-
-       r = global_pu->pu_ops.puffs_node_write(global_pu, pn, (uint8_t *)rw_buf,
+  r = global_pu->pu_ops.puffs_node_read(global_pu, pn, (uint8_t *)rw_buf,
                                                pos, &bytes_left, pcr, 0);
-       bytes_done = nrbytes - bytes_left;
+  if (r) {
+       lpuffs_debug("puffs_node_read failed\n");
+       return(EINVAL);
   }
 
-  if (r != OK) return(EINVAL);
+  bytes_done = bytes - bytes_left;
 
-  fs_m_out.m_fs_vfs_readwrite.seek_pos = pos + bytes_done;
-  fs_m_out.m_fs_vfs_readwrite.nbytes = bytes_done;
+  if (bytes_done > 0) {
+       if ((r = fsdriver_copyout(data, 0, rw_buf, bytes_done)) != OK)
+               return r;
+       update_timens(pn, ATIME, NULL);
+  }
 
-  return(r);
+  return (ssize_t)bytes_done;
 }
 
 
 /*===========================================================================*
- *                             fs_breadwrite                                *
+ *                             fs_write                                     *
  *===========================================================================*/
-int fs_breadwrite(void)
+ssize_t fs_write(ino_t ino_nr, struct fsdriver_data *data, size_t bytes,
+       off_t pos, int call)
 {
-  /* We do not support breads/writes */
-  panic("bread write requested, but FS doesn't support it!\n");
-  return(OK);
+  int r;
+  size_t bytes_left;
+  struct puffs_node *pn;
+  struct vattr va;
+  PUFFS_MAKECRED(pcr, &global_kcred);
+
+  if ((pn = puffs_pn_nodewalk(global_pu, 0, &ino_nr)) == NULL) {
+       lpuffs_debug("walk failed...\n");
+        return(EINVAL);
+  }
+
+  if (bytes > sizeof(rw_buf))
+       bytes = sizeof(rw_buf);
+  bytes_left = bytes;
+
+  /* At first try to change vattr */
+  if (global_pu->pu_ops.puffs_node_setattr == NULL)
+       return(EINVAL);
+
+  puffs_vattr_null(&va);
+  if ((u_quad_t)(pos + bytes_left) > pn->pn_va.va_size)
+       va.va_size = bytes_left + pos;
+  va.va_ctime = va.va_mtime = clock_timespec();
+  va.va_atime = pn->pn_va.va_atime;
+
+  r = global_pu->pu_ops.puffs_node_setattr(global_pu, pn, &va, pcr);
+  if (r) return(EINVAL);
+
+  if ((r = fsdriver_copyin(data, 0, rw_buf, bytes)) != OK)
+       return r;
+
+  if (global_pu->pu_ops.puffs_node_write == NULL)
+       return(EINVAL);
+
+  r = global_pu->pu_ops.puffs_node_write(global_pu, pn, (uint8_t *)rw_buf,
+                                               pos, &bytes_left, pcr, 0);
+  if (r != OK) return(EINVAL);
+
+  return (ssize_t)(bytes - bytes_left);
 }
 
 
 /*===========================================================================*
  *                             fs_getdents                                  *
  *===========================================================================*/
-int fs_getdents(void)
+ssize_t fs_getdents(ino_t ino_nr, struct fsdriver_data *data, size_t bytes,
+       off_t *pos)
 {
   int r;
   register struct puffs_node *pn;
-  ino_t ino;
-  cp_grant_id_t gid;
-  size_t size, buf_left;
-  off_t pos;
+  size_t buf_left, written;
   struct dirent *dent;
   int eofflag = 0;
-  size_t written;
   PUFFS_MAKECRED(pcr, &global_kcred);
 
-  ino = fs_m_in.m_vfs_fs_getdents.inode;
-  gid = fs_m_in.m_vfs_fs_getdents.grant;
-  size = buf_left = fs_m_in.m_vfs_fs_getdents.mem_size;
-  pos = fs_m_in.m_vfs_fs_getdents.seek_pos;
-
-  if ((pn = puffs_pn_nodewalk(global_pu, 0, &ino)) == NULL) {
+  if ((pn = puffs_pn_nodewalk(global_pu, 0, &ino_nr)) == NULL) {
        lpuffs_debug("walk failed...\n");
         return(EINVAL);
   }
 
-  if (GETDENTS_BUFSIZ < size)
-         size = buf_left = GETDENTS_BUFSIZ;
-  memset(getdents_buf, '\0', GETDENTS_BUFSIZ);  /* Avoid leaking any data */
+  if (bytes > sizeof(getdents_buf))
+         bytes = sizeof(getdents_buf);
+  memset(getdents_buf, 0, sizeof(getdents_buf)); /* Avoid leaking any data */
+
+  buf_left = bytes;
 
   dent = (struct dirent*) getdents_buf;
 
-  r = global_pu->pu_ops.puffs_node_readdir(global_pu, pn, dent, &pos,
+  r = global_pu->pu_ops.puffs_node_readdir(global_pu, pn, dent, pos,
                                                &buf_left, pcr, &eofflag, 0, 0);
   if (r) {
        lpuffs_debug("puffs_node_readdir returned error\n");
        return(EINVAL);
   }
 
-  assert(buf_left <= size);
-  written = size - buf_left;
+  assert(buf_left <= bytes);
+  written = bytes - buf_left;
 
   if (written == 0 && !eofflag) {
        lpuffs_debug("The user's buffer is too small\n");
@@ -164,15 +153,12 @@ int fs_getdents(void)
   }
 
   if (written) {
-       r = sys_safecopyto(VFS_PROC_NR, gid, (vir_bytes) 0,
-                            (vir_bytes) getdents_buf, written);
-       if (r != OK) return(r);
+       if ((r = fsdriver_copyout(data, 0, getdents_buf, written)) != OK)
+               return r;
   }
 
   update_timens(pn, ATIME, NULL);
 
-  fs_m_out.m_fs_vfs_getdents.nbytes = written;
-  fs_m_out.m_fs_vfs_getdents.seek_pos = pos;
-
-  return(OK);
+  /* The puffs readdir call has already updated the position. */
+  return written;
 }
index 291b098c4f552f6cfe81ec897760a5309af69eac..a5be843bb1e5969d9aa12fc35c894b431722b84e 100644 (file)
@@ -5,7 +5,6 @@
 #include "fs.h"
 #include <sys/stat.h>
 #include <sys/statvfs.h>
-#include <minix/vfsif.h>
 
 #include "puffs.h"
 #include "puffs_priv.h"
 /*===========================================================================*
  *                             fs_stat                                      *
  *===========================================================================*/
-int fs_stat(void)
+int fs_stat(ino_t ino_nr, struct stat *statbuf)
 {
-  register int r;              /* return value */
   register struct puffs_node *pn;  /* target pnode */
   struct vattr va;
-  struct stat statbuf;
   mode_t mo;
   int s;
   PUFFS_MAKECRED(pcr, &global_kcred);
@@ -29,7 +26,7 @@ int fs_stat(void)
        return(EINVAL);
   }
 
-  if ((pn = puffs_pn_nodewalk(global_pu, 0, &fs_m_in.m_vfs_fs_stat.inode)) == NULL) {
+  if ((pn = puffs_pn_nodewalk(global_pu, 0, &ino_nr)) == NULL) {
        lpuffs_debug("walk failed...\n");
         return(EINVAL);
   }
@@ -48,57 +45,41 @@ int fs_stat(void)
   /* true iff special */
   s = (mo == I_CHAR_SPECIAL || mo == I_BLOCK_SPECIAL);
 
-  statbuf.st_dev = fs_dev;
-  statbuf.st_ino = va.va_fileid;
-  statbuf.st_mode = va.va_mode;
-  statbuf.st_nlink = va.va_nlink;
-  statbuf.st_uid = va.va_uid;
-  statbuf.st_gid = va.va_gid;
-  statbuf.st_rdev = (s ? va.va_rdev : NO_DEV);
-  statbuf.st_size = va.va_size;
-  statbuf.st_atimespec = va.va_atime;
-  statbuf.st_mtimespec = va.va_mtime;
-  statbuf.st_ctimespec = va.va_ctime;
-
-  statbuf.st_birthtimespec = va.va_birthtime;
-  statbuf.st_blksize = va.va_blocksize;
-  statbuf.st_blocks = va.va_bytes / va.va_blocksize;
-  statbuf.st_flags = va.va_flags;
-  statbuf.st_gen = va.va_gen;
-
-  /* Copy the struct to user space. */
-  r = sys_safecopyto(fs_m_in.m_source, fs_m_in.m_vfs_fs_stat.grant,
-                    (vir_bytes) 0, (vir_bytes) &statbuf,
-                    (size_t) sizeof(statbuf));
-
-  return(r);
+  statbuf->st_dev = fs_dev;
+  statbuf->st_ino = va.va_fileid;
+  statbuf->st_mode = va.va_mode;
+  statbuf->st_nlink = va.va_nlink;
+  statbuf->st_uid = va.va_uid;
+  statbuf->st_gid = va.va_gid;
+  statbuf->st_rdev = (s ? va.va_rdev : NO_DEV);
+  statbuf->st_size = va.va_size;
+  statbuf->st_atimespec = va.va_atime;
+  statbuf->st_mtimespec = va.va_mtime;
+  statbuf->st_ctimespec = va.va_ctime;
+
+  statbuf->st_birthtimespec = va.va_birthtime;
+  statbuf->st_blksize = va.va_blocksize;
+  statbuf->st_blocks = va.va_bytes / va.va_blocksize;
+  statbuf->st_flags = va.va_flags;
+  statbuf->st_gen = va.va_gen;
+
+  return(OK);
 }
 
 
 /*===========================================================================*
  *                             fs_statvfs                                    *
  *===========================================================================*/
-int fs_statvfs(void)
+int fs_statvfs(struct statvfs *st)
 {
-  int r;
-  struct statvfs st;
 
-  memset(&st, 0, sizeof(st));
-
-  if (global_pu->pu_ops.puffs_fs_statvfs(global_pu, &st) != 0) {
+  if (global_pu->pu_ops.puffs_fs_statvfs(global_pu, st) != 0) {
        lpuffs_debug("statvfs failed\n");
        return(EINVAL);
   }
 
-  /* XXX libpuffs doesn't truncate filenames and returns ENAMETOOLONG,
-   * though some servers would like to behave differently.
-   * See subtest 2.18-19 of test23 and test/common.c:does_fs_truncate().
-   */
-  st.f_flag |= ST_NOTRUNC;
-
-  /* Copy the struct to user space. */
-  r = sys_safecopyto(fs_m_in.m_source, fs_m_in.m_vfs_fs_statvfs.grant, 0,
-                       (vir_bytes) &st, (phys_bytes) sizeof(st));
+  /* libpuffs doesn't truncate filenames */
+  st->f_flag |= ST_NOTRUNC;
 
-  return(r);
+  return(OK);
 }
index d00ede2c47782b56bba5f8e827c3ebe32ac93595..90f5a48b943abfb362ba470101deb174dd291c3f 100644 (file)
@@ -9,39 +9,29 @@
 
 #include "fs.h"
 
-int (*fs_call_vec[])(void) = {
-    no_sys,             /* 0   not used */
-    no_sys,             /* 1   */       /* Was: fs_getnode */
-    fs_putnode,         /* 2   */
-    fs_slink,           /* 3   */
-    fs_ftrunc,          /* 4   */
-    fs_chown,           /* 5   */
-    fs_chmod,           /* 6   */
-    fs_inhibread,       /* 7   */
-    fs_stat,            /* 8   */
-    fs_utime,           /* 9   */
-    fs_statvfs,                /* 10  */
-    fs_breadwrite,      /* 11  */
-    fs_breadwrite,      /* 12  */
-    fs_unlink,          /* 13  */
-    fs_unlink,          /* 14  */
-    fs_unmount,         /* 15  */
-    fs_sync,            /* 16  */
-    fs_new_driver,      /* 17  */
-    fs_flush,           /* 18  */
-    fs_readwrite,       /* 19  */
-    fs_readwrite,       /* 20  */
-    fs_mknod,           /* 21  */
-    fs_mkdir,           /* 22  */
-    fs_create,          /* 23  */
-    fs_link,            /* 24  */
-    fs_rename,          /* 25  */
-    fs_lookup,          /* 26  */
-    fs_mountpoint,      /* 27  */
-    fs_readsuper,       /* 28  */
-    no_sys,            /* 29  */       /* Was: fs_newnode */
-    fs_rdlink,          /* 30  */
-    fs_getdents,        /* 31  */
-    no_sys,            /* 32 peek */
-    no_sys,            /* 33 bpeek */
+struct fsdriver puffs_table = {
+       .fdr_mount      = fs_mount,
+       .fdr_unmount    = fs_unmount,
+       .fdr_lookup     = fs_lookup,
+       .fdr_putnode    = fs_putnode,
+       .fdr_read       = fs_read,
+       .fdr_write      = fs_write,
+       .fdr_getdents   = fs_getdents,
+       .fdr_trunc      = fs_trunc,
+       .fdr_create     = fs_create,
+       .fdr_mkdir      = fs_mkdir,
+       .fdr_mknod      = fs_mknod,
+       .fdr_link       = fs_link,
+       .fdr_unlink     = fs_unlink,
+       .fdr_rmdir      = fs_unlink,
+       .fdr_rename     = fs_rename,
+       .fdr_slink      = fs_slink,
+       .fdr_rdlink     = fs_rdlink,
+       .fdr_stat       = fs_stat,
+       .fdr_chown      = fs_chown,
+       .fdr_chmod      = fs_chmod,
+       .fdr_utime      = fs_utime,
+       .fdr_mountpt    = fs_mountpt,
+       .fdr_statvfs    = fs_statvfs,
+       .fdr_sync       = fs_sync
 };
index e752036f9b6d7e3b40f896a6ec37c297b1d69e2e..bc57ab07a971c76262e40a6a5983ebfcec841a0e 100644 (file)
@@ -3,10 +3,6 @@
  */
 
 #include "fs.h"
-#include <minix/callnr.h>
-#include <minix/com.h>
-#include <minix/vfsif.h>
-
 #include "puffs.h"
 #include "puffs_priv.h"
 
 /*===========================================================================*
  *                             fs_utime                                     *
  *===========================================================================*/
-int fs_utime(void)
+int fs_utime(ino_t ino_nr, struct timespec *atime, struct timespec *mtime)
 {
   struct puffs_node *pn;
   struct vattr va;
   PUFFS_MAKECRED(pcr, &global_kcred);
 
-  if (is_readonly_fs)
-       return(EROFS);
-
   if (global_pu->pu_ops.puffs_node_setattr == NULL)
        return(EINVAL);
 
-  if( (pn = puffs_pn_nodewalk(global_pu, 0, &fs_m_in.m_vfs_fs_utime.inode)) == NULL)
+  if( (pn = puffs_pn_nodewalk(global_pu, 0, &ino_nr)) == NULL)
         return(EINVAL);
-  
+
+  /* FIXME: shouldn't this check the special UTIME_ values? */
   puffs_vattr_null(&va);
-  va.va_atime.tv_sec = fs_m_in.m_vfs_fs_utime.actime;
-  va.va_atime.tv_nsec = fs_m_in.m_vfs_fs_utime.acnsec;
-  va.va_mtime.tv_sec = fs_m_in.m_vfs_fs_utime.modtime;
-  va.va_mtime.tv_nsec = fs_m_in.m_vfs_fs_utime.modnsec;
+  va.va_atime = *atime;
+  va.va_mtime = *mtime;
   va.va_ctime = clock_timespec();
 
   if (global_pu->pu_ops.puffs_node_setattr(global_pu, pn, &va, pcr) != 0)
index 2f41cb76a529e82fcae89adcbf4a25e7fdbdda9a..e4607344be50e15cf6e5966746c69ac98d1489e1 100644 (file)
 #include "puffs_priv.h"
 
 
-/*===========================================================================*
- *                             no_sys                                       *
- *===========================================================================*/
-int no_sys(void)
-{
-/* Somebody has used an illegal system call number */
-  lpuffs_debug("no_sys: invalid call %d\n", req_nr);
-  return(EINVAL);
-}
-
-
-/*===========================================================================*
- *                              mfs_nul                                      *
- *===========================================================================*/
-void mfs_nul_f(const char *file, int line, char *str, unsigned int len,
-                      unsigned int maxlen)
-{
-  if (len < maxlen && str[len-1] != '\0') {
-       lpuffs_debug("%s:%d string (length %d,maxlen %d) not null-terminated\n",
-                file, line, len, maxlen);
-  }
-}
-
-
 /*===========================================================================*
  *                             clock_timespec                               *
  *===========================================================================*/