]> Zhao Yanbai Git Server - minix.git/commitdiff
PFS: use libfsdriver 53/2753/3
authorDavid van Moolenbroek <david@minix3.org>
Sun, 24 Aug 2014 10:18:30 +0000 (10:18 +0000)
committerDavid van Moolenbroek <david@minix3.org>
Thu, 18 Sep 2014 12:46:28 +0000 (12:46 +0000)
In order to avoid creating libfsdriver exceptions, two changes to VFS
are necessary:

- the returned position field for reads/writes is no longer abused to
  return the new pipe size; VFS is perfectly capable of updating the
  size itself;
- during system startup, PFS is now sent a mount request, just like all
  other file systems.

In proper "two steps forward, one step back" fashion, the latter point
has the consequence that PFS can no longer drop its privileges at
startup.  This is probably best resolved with a more general solution
for all boot image system services.  The upside is that PFS no longer
needs to be linked with libc.

Change-Id: I92e2410cdb0d93d0e6107bae10bc08efc2dbb8b3

20 files changed:
minix/fs/pfs/Makefile
minix/fs/pfs/buffer.c
minix/fs/pfs/fs.h
minix/fs/pfs/glo.h
minix/fs/pfs/inode.c
minix/fs/pfs/inode.h
minix/fs/pfs/link.c
minix/fs/pfs/main.c
minix/fs/pfs/misc.c
minix/fs/pfs/mount.c
minix/fs/pfs/open.c
minix/fs/pfs/proto.h
minix/fs/pfs/read.c
minix/fs/pfs/stadir.c
minix/fs/pfs/super.c
minix/fs/pfs/table.c
minix/fs/pfs/utility.c [deleted file]
minix/servers/vfs/main.c
minix/servers/vfs/mount.c
minix/servers/vfs/read.c

index 48619fee0223c9bb5010c056f04d9c8c017078f4..d1841c193b59da5f8cb7750c6660134b697ed928 100644 (file)
@@ -1,11 +1,9 @@
 # Makefile for Pipe File System (PFS)
 PROG=  pfs
 SRCS=  open.c table.c inode.c main.c super.c link.c \
-       buffer.c read.c misc.c mount.c utility.c stadir.c
+       buffer.c read.c misc.c mount.c stadir.c
 
-DPADD+=        ${LIBCHARDRIVER} ${LIBSYS}
-LDADD+=        -lchardriver -lsys
-
-LDADD+= -lc
+DPADD+=        ${LIBFSDRIVER} ${LIBSYS}
+LDADD+=        -lfsdriver -lsys
 
 .include <minix.service.mk>
index 825ca1b525f1ce4ec14898132d5ee88e3858739e..746aebd8a4d680d4b42dfc7207982bee9a81b907 100644 (file)
@@ -1,9 +1,4 @@
 #include "fs.h"
-#include "buf.h"
-#include "inode.h"
-#include <sys/types.h>
-#include <stdlib.h>
-#include <string.h>
 
 static struct buf *new_block(dev_t dev, ino_t inum);
 
index a5e0ca40ff7b76deef219326f32ed730c1db68ce..417e30fc58cb648376e21657c971a16c98a6e661 100644 (file)
 #include <sys/types.h>
 #include <minix/const.h>
 #include <minix/type.h>
-#include <minix/dmap.h>
 
-#include <minix/vfsif.h>
 #include <lib.h>
-#include <limits.h>
-#include <errno.h>
 #include <minix/syslib.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <stdio.h>
 #include <minix/sysutil.h>
 
+#include <minix/fsdriver.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <assert.h>
+
 #include "const.h"
 #include "proto.h"
 #include "glo.h"
+#include "buf.h"
+#include "inode.h"
 
 #endif
index 96ca9c42eab0090c43b47e6c9d863a3fbc9115d0..77bff50efacff4e6a7dd1abe58228c0d4c21d80d 100644 (file)
@@ -7,16 +7,12 @@
 #define EXTERN
 #endif
 
-#include <minix/vfsif.h>
-
 /* The following variables are used for returning results to the caller. */
 EXTERN int err_code;           /* temporary storage for error number */
 
-EXTERN int(*fs_call_vec[]) (message *fs_m_in, message *fs_m_out);
+extern struct fsdriver pfs_table;
 
-EXTERN int exitsignaled;
 EXTERN int busy;
-EXTERN int unmountdone;
 
 /* Inode map. */
 EXTERN bitchunk_t inodemap[FS_BITMAP_CHUNKS(PFS_NR_INODES)];
index 442f824dc5a115a0cae3b684b58e9ee359f780f3..b5918fbae99a6383f889ba37309d5347418af7c1 100644 (file)
@@ -15,9 +15,6 @@
  */
 
 #include "fs.h"
-#include "buf.h"
-#include "inode.h"
-#include <minix/vfsif.h>
 
 static void addhash_inode(struct inode * const node);
 static void unhash_inode(struct inode * const node);
@@ -26,29 +23,21 @@ static void unhash_inode(struct inode * const node);
 /*===========================================================================*
  *                             fs_putnode                                   *
  *===========================================================================*/
-int fs_putnode(message *fs_m_in, message *fs_m_out)
+int fs_putnode(ino_t ino_nr, unsigned int count)
 {
 /* Find the inode specified by the request message and decrease its counter.*/
-
   struct inode *rip;
-  int count;
   dev_t dev;
-  ino_t inum;
 
-  rip = find_inode(fs_m_in->m_vfs_fs_putnode.inode);
+  rip = find_inode(ino_nr);
 
   if(!rip) {
-         printf("%s:%d put_inode: inode #%llu not found\n", __FILE__,
-                __LINE__, fs_m_in->m_vfs_fs_putnode.inode);
-         panic("fs_putnode failed");
+       printf("%s:%d put_inode: inode #%llu not found\n", __FILE__,
+               __LINE__, ino_nr);
+       panic("fs_putnode failed");
   }
 
-  count = fs_m_in->m_vfs_fs_putnode.count;
-  if (count <= 0) {
-       printf("%s:%d put_inode: bad value for count: %d\n", __FILE__,
-              __LINE__, count);
-       panic("fs_putnode failed");
-  } else if(count > rip->i_count) {
+  if (count > rip->i_count) {
        printf("%s:%d put_inode: count too high: %d > %d\n", __FILE__,
               __LINE__, count, rip->i_count);
        panic("fs_putnode failed");
@@ -58,9 +47,8 @@ int fs_putnode(message *fs_m_in, message *fs_m_out)
    * put_inode(). */
   rip->i_count -= count - 1;
   dev = rip->i_dev;
-  inum = rip->i_num;
   put_inode(rip);
-  if (rip->i_count == 0) put_block(dev, inum);
+  if (rip->i_count == 0) put_block(dev, ino_nr);
   return(OK);
 }
 
index 897ba7aca606d327f5c895e28083d2131c95f8e9..75689c9e3b6460697e51b3cc97a6ecec5891f1a6 100644 (file)
@@ -11,12 +11,11 @@ EXTERN struct inode {
   nlink_t i_nlinks;            /* how many links to this file */
   uid_t i_uid;                 /* user id of the file's owner */
   gid_t i_gid;                 /* group number */
-  off_t i_size;                        /* current file size in bytes */
+  size_t i_size;                       /* current file size in bytes */
   time_t i_atime;              /* time of last access (V2 only) */
   time_t i_mtime;              /* when was file data last changed */
   time_t i_ctime;              /* when was inode itself changed (V2 only)*/
 
-  /* The following items are not present on the disk. */
   dev_t i_dev;                 /* which device is the inode on */
   dev_t i_rdev;                        /* which special device is the inode on */
   ino_t i_num;                 /* inode number on its (minor) device */
@@ -35,5 +34,4 @@ EXTERN TAILQ_HEAD(unused_inodes_t, inode)  unused_inodes;
 /* inode hashtable */
 EXTERN LIST_HEAD(inodelist, inode)         hash_inodes[INODE_HASH_SIZE];
 
-
 #endif
index 7b1286d51fc4eb6a95e6fa07c7dbdbf86c9eaa5c..d8c7d1a777eea559b18d6d8832b0c927465ea931 100644 (file)
@@ -1,22 +1,15 @@
 #include "fs.h"
-#include "buf.h"
-#include "inode.h"
-#include <minix/vfsif.h>
 
 /*===========================================================================*
- *                             fs_ftrunc                                    *
+ *                             fs_trunc                                     *
  *===========================================================================*/
-int fs_ftrunc(message *fs_m_in, message *fs_m_out)
+int fs_trunc(ino_t ino_nr, off_t start, off_t end)
 {
   struct inode *rip;
-  off_t start;
-  ino_t inumb;
 
-  inumb = fs_m_in->m_vfs_fs_ftrunc.inode;
+  if( (rip = find_inode(ino_nr)) == NULL) return(EINVAL);
 
-  if( (rip = find_inode(inumb)) == NULL) return(EINVAL);
-
-  start = fs_m_in->m_vfs_fs_ftrunc.trc_start;
+  if (end != 0) return(EINVAL); /* creating holes is not supported */
 
   return truncate_inode(rip, start);
 }
index 09b96dc1ad1f9209046397e29699fe6ce702cf4e..09d7dde7908ed83dd042d8eb4889fad880d8d588 100644 (file)
@@ -1,17 +1,4 @@
 #include "fs.h"
-#include <assert.h>
-#include <signal.h>
-#include <minix/dmap.h>
-#include <minix/driver.h>
-#include <minix/endpoint.h>
-#include <minix/rs.h>
-#include <minix/vfsif.h>
-#include <sys/types.h>
-#include <pwd.h>
-#include "buf.h"
-#include "inode.h"
-
-static void get_work(message *m_in, int *status);
 
 /* SEF functions and variables. */
 static void sef_local_startup(void);
@@ -23,54 +10,15 @@ static void sef_cb_signal_handler(int signo);
  *===========================================================================*/
 int main(int argc, char *argv[])
 {
-/* 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 never terminates, unless a panic occurs.
- */
-  int ind, transid, req_nr, ipc_status;
-  message pfs_m_in;
-  message pfs_m_out;
-  endpoint_t src;
+/* This is the main routine of this service. */
 
   /* SEF local startup. */
   env_setargs(argc, argv);
   sef_local_startup();
 
-  while(!unmountdone || !exitsignaled) {
-       /* Wait for request message. */
-       get_work(&pfs_m_in, &ipc_status);
-
-       transid = TRNS_GET_ID(pfs_m_in.m_type);
-       pfs_m_in.m_type = TRNS_DEL_ID(pfs_m_in.m_type);
-       if (pfs_m_in.m_type == 0) {
-               assert(!IS_VFS_FS_TRANSID(transid));
-               pfs_m_in.m_type = transid;
-               transid = 0;
-       } else
-               assert(IS_VFS_FS_TRANSID(transid) || transid == 0);
-
-       src = pfs_m_in.m_source;
-       req_nr = pfs_m_in.m_type;
-
-       if (IS_FS_RQ(req_nr)) {
-               ind = req_nr - FS_BASE;
-               if (ind < 0 || ind >= FS_CALL_VEC_SIZE) {
-                       printf("pfs: bad FS request %d\n", req_nr);
-                       pfs_m_out.m_type = EINVAL;
-               } else {
-                       pfs_m_out.m_type =
-                               (*fs_call_vec[ind])(&pfs_m_in, &pfs_m_out);
-               }
-       } else {
-               printf("pfs: bad request %d\n", req_nr);
-               pfs_m_out.m_type = EINVAL;
-       }
-
-       if (IS_FS_RQ(req_nr) && IS_VFS_FS_TRANSID(transid)) {
-               pfs_m_out.m_type = TRNS_ADD_ID(pfs_m_out.m_type, transid);
-       }
-       reply(src, &pfs_m_out);
-  }
+  /* The fsdriver library does the actual work here. */
+  fsdriver_task(&pfs_table);
+
   return(OK);
 }
 
@@ -102,7 +50,6 @@ static int sef_cb_init_fresh(int type, sef_init_info_t *info)
   struct passwd *pw;
 
   /* Initialize main loop parameters. */
-  exitsignaled = 0;    /* No exit request seen yet. */
   busy = 0;            /* Server is not 'busy' (i.e., inodes in use). */
 
   /* Init inode table */
@@ -113,14 +60,6 @@ static int sef_cb_init_fresh(int type, sef_init_info_t *info)
   init_inode_cache();
   buf_pool();
 
-  /* Drop root privileges */
-  if ((pw = getpwnam(SERVICE_LOGIN)) == NULL) {
-       printf("PFS: unable to retrieve uid of SERVICE_LOGIN, "
-               "still running as root");
-  } else if (setuid(pw->pw_uid) != 0) {
-       panic("unable to drop privileges");
-  }
-
   return(OK);
 }
 
@@ -132,41 +71,5 @@ static void sef_cb_signal_handler(int signo)
   /* Only check for termination signal, ignore anything else. */
   if (signo != SIGTERM) return;
 
-
-  exitsignaled = 1;
-}
-
-/*===========================================================================*
- *                             get_work                                     *
- *===========================================================================*/
-static void get_work(message * m_in, int *status)
-{
-  int r, srcok = 0;
-  endpoint_t src;
-
-  do {
-       /* wait for a message */
-       if ((r = sef_receive_status(ANY, m_in, status)) != OK)
-               panic("sef_receive_status failed: %d", r);
-       src = m_in->m_source;
-
-       if(src == VFS_PROC_NR) {
-               srcok = 1;              /* Normal FS request. */
-       } else
-               printf("PFS: unexpected source %d\n", src);
-  } while(!srcok);
-}
-
-
-/*===========================================================================*
- *                             reply                                        *
- *===========================================================================*/
-void reply(who, m_out)
-endpoint_t who;
-message *m_out;                        /* report result */
-{
-  int r;
-
-  if (OK != (r = ipc_send(who, m_out)))        /* send the message */
-       printf("PFS: unable to send reply: %d\n", r);
+  fsdriver_terminate();
 }
index 0ba9b7c067d8df0235531f720c0e72f79033ad51..24aeb89cc55ea9a81c0c070dc8036e93a0bb54ba 100644 (file)
@@ -1,28 +1,17 @@
 #include "fs.h"
-#include "inode.h"
 
 
-/*===========================================================================*
- *                             fs_sync                                      *
- *===========================================================================*/
-int fs_sync(message *fs_m_in, message *fs_m_out)
-{
-/* Perform the sync() system call.  No-op on this FS. */
-
-  return(OK);          /* sync() can't fail */
-}
-
 /*===========================================================================*
  *                             fs_chmod                                             *
  *===========================================================================*/
-int fs_chmod(message *fs_m_in, message *fs_m_out)
+int fs_chmod(ino_t ino_nr, mode_t *mode)
 {
   struct inode *rip;  /* target inode */
-  mode_t mode = fs_m_in->m_vfs_fs_chmod.mode;
 
-  if( (rip = find_inode(fs_m_in->m_vfs_fs_chmod.inode)) == NULL) return(EINVAL);
-  get_inode(rip->i_dev, rip->i_num);   /* mark inode in use */
-  rip->i_mode = (rip->i_mode & ~ALL_MODES) | (mode & ALL_MODES);
-  put_inode(rip);                      /* release the inode */
+  if( (rip = find_inode(ino_nr)) == NULL) return(EINVAL);
+
+  rip->i_mode = (rip->i_mode & ~ALL_MODES) | (*mode & ALL_MODES);
+
+  *mode = rip->i_mode; /* return new mode */
   return OK;
 }
index 3bb52d9d63957b1e60c2390e7a1506533d2bf934..35636338b42e628be8dd979ba6b9fc10691b4250 100644 (file)
@@ -3,16 +3,33 @@
 
 
 /*===========================================================================*
- *                             fs_unmount                                   *
+ *                             fs_mount                                     *
  *===========================================================================*/
-int fs_unmount(message *fs_m_in, message *fs_m_out)
+int fs_mount(dev_t __unused dev, unsigned int __unused flags,
+       struct fsdriver_node *node, unsigned int *res_flags)
 {
-/* Unmount Pipe File Server. */
-
-  if (busy) return(EBUSY);     /* can't umount a busy file system */
+/* Mount Pipe File Server. */
 
-  /* Finish off the unmount. */
-  unmountdone = TRUE;
+  /* This function does not do much. PFS has no root node, and VFS will ignore
+   * the returned node details anyway. The whole idea is to provide symmetry
+   * with other file systems, thus keeping libfsdriver simple and free of
+   * special cases. Everything else (e.g., mounting PFS in VFS) is already an
+   * exception anyway.
+   */
+  memset(node, 0, sizeof(*node));
+  *res_flags = 0;
 
   return(OK);
 }
+
+
+/*===========================================================================*
+ *                             fs_unmount                                   *
+ *===========================================================================*/
+void fs_unmount(void)
+{
+/* Unmount Pipe File Server. */
+
+  if (busy)
+       printf("PFS: unmounting while busy!\n"); /* nothing we can do anyway */
+}
index b3f17643cb93fa14eadf60a3432616feac6491c8..e3308fc81043d1963bf7813114aecc8e8b35a71e 100644 (file)
@@ -1,31 +1,19 @@
 #include "fs.h"
-#include <sys/stat.h>
-#include "buf.h"
-#include "inode.h"
-#include <minix/vfsif.h>
 
 
 /*===========================================================================*
  *                             fs_newnode                                   *
  *===========================================================================*/
-int fs_newnode(message *fs_m_in, message *fs_m_out)
+int fs_newnode(mode_t mode, uid_t uid, gid_t gid, dev_t dev,
+       struct fsdriver_node *node)
 {
   register int r = OK;
-  mode_t bits;
   struct inode *rip;
-  uid_t uid;
-  gid_t gid;
-  dev_t dev;
-
-  uid = fs_m_in->m_vfs_fs_newnode.uid;
-  gid = fs_m_in->m_vfs_fs_newnode.gid;
-  bits = fs_m_in->m_vfs_fs_newnode.mode;
-  dev = fs_m_in->m_vfs_fs_newnode.device;
 
   /* Try to allocate the inode */
-  if( (rip = alloc_inode(dev, bits, uid, gid) ) == NULL) return(err_code);
+  if( (rip = alloc_inode(dev, mode, uid, gid) ) == NULL) return(err_code);
 
-  switch (bits & S_IFMT) {
+  switch (mode & S_IFMT) {
        case S_IFBLK:
        case S_IFCHR:
                rip->i_rdev = dev;              /* Major/minor dev numbers */
@@ -42,12 +30,12 @@ int fs_newnode(message *fs_m_in, message *fs_m_out)
        free_inode(rip);
   } else {
        /* Fill in the fields of the response message */
-       fs_m_out->m_fs_vfs_newnode.inode = rip->i_num;
-       fs_m_out->m_fs_vfs_newnode.mode = rip->i_mode;
-       fs_m_out->m_fs_vfs_newnode.file_size = rip->i_size;
-       fs_m_out->m_fs_vfs_newnode.uid = rip->i_uid;
-       fs_m_out->m_fs_vfs_newnode.gid = rip->i_gid;
-       fs_m_out->m_fs_vfs_newnode.device = dev;
+       node->fn_ino_nr = rip->i_num;
+       node->fn_mode = rip->i_mode;
+       node->fn_size = rip->i_size;
+       node->fn_uid = rip->i_uid;
+       node->fn_gid = rip->i_gid;
+       node->fn_dev = dev;
   }
 
   return(r);
index 6a5bc90d5298568b7ea9741b0646758bad5c47c5..3569551e5591119cd7f94d7a078daa7ca77b4da3 100644 (file)
@@ -10,8 +10,6 @@ struct inode;
 /* buffer.c */
 struct buf *get_block(dev_t dev, ino_t inum);
 void put_block(dev_t dev, ino_t inum);
-
-/* cache.c */
 void buf_pool(void);
 
 /* inode.c */
@@ -19,7 +17,7 @@ struct inode *alloc_inode(dev_t dev, mode_t mode, uid_t uid, gid_t gid);
 void dup_inode(struct inode *ip);
 struct inode *find_inode(ino_t numb);
 void free_inode(struct inode *rip);
-int fs_putnode(message *fs_m_in, message *fs_m_out);
+int fs_putnode(ino_t ino_nr, unsigned int count);
 void init_inode_cache(void);
 struct inode *get_inode(dev_t dev, ino_t numb);
 void put_inode(struct inode *rip);
@@ -27,30 +25,29 @@ void update_times(struct inode *rip);
 void wipe_inode(struct inode *rip);
 
 /* link.c */
-int fs_ftrunc(message *fs_m_in, message *fs_m_out);
+int fs_trunc(ino_t ino_nr, off_t start, off_t end);
 int truncate_inode(struct inode *rip, off_t newsize);
 
-/* main.c */
-void reply(endpoint_t who, message *m_out);
-
 /* misc.c */
-int fs_sync(message *fs_m_in, message *fs_m_out);
-int fs_chmod(message *fs_m_in, message *fs_m_out);
+int fs_chmod(ino_t ino_nr, mode_t *mode);
 
 /* mount.c */
-int fs_unmount(message *fs_m_in, message *fs_m_out);
+int fs_mount(dev_t dev, unsigned int flags, struct fsdriver_node *node,
+       unsigned int *res_flags);
+void fs_unmount(void);
 
 /* open.c */
-int fs_newnode(message *fs_m_in, message *fs_m_out);
+int fs_newnode(mode_t mode, uid_t uid, gid_t gid, dev_t dev,
+       struct fsdriver_node *node);
 
 /* read.c */
-int fs_readwrite(message *fs_m_in, message *fs_m_out);
-
-/* utility.c */
-int no_sys(message *pfs_m_in, message *pfs_m_out);
+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);
 
 /* stadir.c */
-int fs_stat(message *fs_m_in, message *fs_m_out);
+int fs_stat(ino_t ino_nr, struct stat *statbuf);
 
 /* super.c */
 bit_t alloc_bit(void);
index d7a8ff877cdd26ae8a73c09c6b25c216a3e9afb4..db4b776000d99b342483f30f1372c37a455f6787 100644 (file)
@@ -1,97 +1,85 @@
 #include "fs.h"
-#include "buf.h"
-#include "inode.h"
-#include <minix/com.h>
-#include <string.h>
 
 
 /*===========================================================================*
- *                             fs_readwrite                                 *
+ *                             fs_read                                      *
  *===========================================================================*/
-int fs_readwrite(message *fs_m_in, message *fs_m_out)
+ssize_t fs_read(ino_t ino_nr, struct fsdriver_data *data, size_t bytes,
+       off_t __unused pos, int call)
 {
-  int r, rw_flag;
+  int r;
   struct buf *bp;
-  cp_grant_id_t gid;
-  off_t position, f_size;
-  size_t nrbytes, cum_io;
-  mode_t mode_word;
   struct inode *rip;
-  ino_t inumb;
-
-  r = OK;
-  cum_io = 0;
-  inumb = fs_m_in->m_vfs_fs_readwrite.inode;
 
   /* Find the inode referred */
-  if ((rip = find_inode(inumb)) == NULL) return(EINVAL);
+  if ((rip = find_inode(ino_nr)) == NULL) return(EINVAL);
 
-  mode_word = rip->i_mode & I_TYPE;
-  if (mode_word != I_NAMED_PIPE) return(EIO);
-  f_size = rip->i_size;
+  if (!S_ISFIFO(rip->i_mode)) return(EIO);
 
-  /* 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;
-  nrbytes = fs_m_in->m_vfs_fs_readwrite.nbytes;
+  /* We can't read or write beyond the max file position */
+  if (bytes > PIPE_BUF) return(EFBIG);
 
-  /* We can't read beyond the max file position */
-  if (nrbytes > PIPE_BUF) return(EFBIG);
+  if (bytes > rip->i_size) {
+       /* There aren't that many bytes to read */
+       bytes = rip->i_size;
+  }
 
-  /* Mark inode in use */
-  if ((get_inode(rip->i_dev, rip->i_num)) == NULL) return(err_code);
+  /* Copy a chunk from the block buffer to user space. */
   if ((bp = get_block(rip->i_dev, rip->i_num)) == NULL) return(err_code);
 
-  if (rw_flag == WRITING) {
-       /* Check in advance to see if file will grow too big. */
-       /* Casting nrbytes to signed is safe, because it's guaranteed not to
-        * be beyond max signed value (i.e., MAX_FILE_POS).
-        */
-       position = rip->i_size;
-       if ((unsigned) position + nrbytes > PIPE_BUF) {
-               put_inode(rip);
-               put_block(rip->i_dev, rip->i_num);
-               return(EFBIG);
-       }
-  } else {
-       position = 0;
-       if (nrbytes > rip->i_size) {
-               /* There aren't that many bytes to read */
-               nrbytes = rip->i_size;
-       }
-  }
+  r = fsdriver_copyout(data, 0, bp->b_data, bytes);
 
-  if (rw_flag == READING) {
-       /* Copy a chunk from the block buffer to user space. */
-       r = sys_safecopyto(fs_m_in->m_source, gid, (vir_bytes) 0,
-               (vir_bytes) (bp->b_data+position), (size_t) nrbytes);
-  } else {
-       /* Copy a chunk from user space to the block buffer. */
-       r = sys_safecopyfrom(fs_m_in->m_source, gid, (vir_bytes) 0,
-               (vir_bytes) (bp->b_data+position), (size_t) nrbytes);
+  if (r == OK && rip->i_size > bytes) {
+       /* Move any remaining data to the front of the buffer. */
+       /* FIXME: see if this really is the optimal strategy. */
+       memmove(bp->b_data, bp->b_data + bytes, rip->i_size - bytes);
   }
 
-  if (r == OK) {
-       position += (signed) nrbytes; /* Update position */
-       cum_io += nrbytes;
+  put_block(rip->i_dev, rip->i_num);
 
-       /* On write, update file size and access time. */
-       if (rw_flag == WRITING) {
-               rip->i_size = position;
-       } else {
-               memmove(bp->b_data, bp->b_data+nrbytes, rip->i_size - nrbytes);
-               rip->i_size -= nrbytes;
-       }
+  if (r != OK)
+       return r;
 
-       if (rw_flag == READING) rip->i_update |= ATIME;
-       if (rw_flag == WRITING) rip->i_update |= CTIME | MTIME;
-  }
+  /* Update file size and access time. */
+  rip->i_size -= bytes;
+  rip->i_update |= ATIME;
+
+  return(bytes);
+}
+
+
+/*===========================================================================*
+ *                             fs_write                                     *
+ *===========================================================================*/
+ssize_t fs_write(ino_t ino_nr, struct fsdriver_data *data, size_t bytes,
+       off_t __unused pos, int __unused call)
+{
+  int r;
+  struct buf *bp;
+  struct inode *rip;
+
+  /* Find the inode referred */
+  if ((rip = find_inode(ino_nr)) == NULL) return(EINVAL);
+
+  if (!S_ISFIFO(rip->i_mode)) return(EIO);
 
-  fs_m_out->m_fs_vfs_readwrite.nbytes = cum_io;
-  fs_m_out->m_fs_vfs_readwrite.seek_pos = rip->i_size;
+  /* Check in advance to see if file will grow too big. */
+  if (rip->i_size + bytes > PIPE_BUF)
+       return(EFBIG);
+
+  /* Copy the data from user space to the block buffer. */
+  if ((bp = get_block(rip->i_dev, rip->i_num)) == NULL) return(err_code);
+
+  r = fsdriver_copyin(data, 0, bp->b_data + rip->i_size, bytes);
 
-  put_inode(rip);
   put_block(rip->i_dev, rip->i_num);
 
-  return(r);
+  if (r != OK)
+       return r;
+
+  /* Update file size and file times. */
+  rip->i_size += bytes;
+  rip->i_update |= CTIME | MTIME;
+
+  return(bytes);
 }
index c6aa2aad097a4625db1baabefe744b6f2504f2d6..127ff60bff0112bd6ad8d4cc841a2818fb7c5b81 100644 (file)
@@ -1,23 +1,17 @@
 #include "fs.h"
-#include "inode.h"
-#include <string.h>
-#include <sys/stat.h>
 
 
 /*===========================================================================*
- *                             stat_inode                                   *
+ *                             fs_stat                                      *
  *===========================================================================*/
-static int stat_inode(
-  register struct inode *rip,  /* pointer to inode to stat */
-  endpoint_t who_e,            /* Caller endpoint */
-  cp_grant_id_t gid            /* grant for the stat buf */
-)
+int fs_stat(ino_t ino_nr, struct stat *statbuf)
 {
-/* Common code for stat and fstat system calls. */
+  struct inode *rip;
   mode_t type;
-  struct stat statbuf;
   u32_t blocks; /* The unit of this is 512 */
-  int r, s;
+  int s;
+
+  if ((rip = find_inode(ino_nr)) == NULL) return(EINVAL);
 
   type = rip->i_mode & I_TYPE;
   s = (type == I_CHAR_SPECIAL || type == I_BLOCK_SPECIAL);
@@ -29,42 +23,20 @@ static int stat_inode(
   if (rip->i_size % S_BLKSIZE != 0)
        blocks += 1;
 
-  memset(&statbuf, 0, sizeof(struct stat));
-
-  statbuf.st_dev = rip->i_dev;
-  statbuf.st_ino = rip->i_num;
-  statbuf.st_mode = rip->i_mode;
-  statbuf.st_nlink = rip->i_nlinks;
-  statbuf.st_uid = rip->i_uid;
-  statbuf.st_gid = (short int) rip->i_gid;
-  statbuf.st_rdev = (s ? rip->i_rdev : NO_DEV);
-  statbuf.st_size = rip->i_size;
-  if (!s)  statbuf.st_mode &= ~I_REGULAR;/* wipe out I_REGULAR bit for pipes */
-  statbuf.st_atime = rip->i_atime;
-  statbuf.st_mtime = rip->i_mtime;
-  statbuf.st_ctime = rip->i_ctime;
-  statbuf.st_blksize = PIPE_BUF;
-  statbuf.st_blocks = blocks;
-
-  /* Copy the struct to user space. */
-  r = sys_safecopyto(who_e, gid, (vir_bytes) 0, (vir_bytes) &statbuf,
-               (size_t) sizeof(statbuf));
-
-  return(r);
-}
-
-
-/*===========================================================================*
- *                             fs_stat                                      *
- *===========================================================================*/
-int fs_stat(message *fs_m_in, message *fs_m_out)
-{
-  register int r;              /* return value */
-  register struct inode *rip;  /* target inode */
-
-  if( (rip = find_inode(fs_m_in->m_vfs_fs_stat.inode)) == NULL) return(EINVAL);
-  get_inode(rip->i_dev, rip->i_num);   /* mark inode in use */
-  r = stat_inode(rip, fs_m_in->m_source, fs_m_in->m_vfs_fs_stat.grant);
-  put_inode(rip);                      /* release the inode */
-  return(r);
+  statbuf->st_dev = rip->i_dev;
+  statbuf->st_ino = rip->i_num;
+  statbuf->st_mode = rip->i_mode;
+  statbuf->st_nlink = rip->i_nlinks;
+  statbuf->st_uid = rip->i_uid;
+  statbuf->st_gid = (short int) rip->i_gid;
+  statbuf->st_rdev = (s ? rip->i_rdev : NO_DEV);
+  statbuf->st_size = rip->i_size;
+  if (!s) statbuf->st_mode &= ~I_REGULAR;/* wipe out I_REGULAR bit for pipes */
+  statbuf->st_atime = rip->i_atime;
+  statbuf->st_mtime = rip->i_mtime;
+  statbuf->st_ctime = rip->i_ctime;
+  statbuf->st_blksize = PIPE_BUF;
+  statbuf->st_blocks = blocks;
+
+  return(OK);
 }
index dc022946d90427fb04e7dda396b59d1eec68c145..d10702fa01a54547ce8ea448e46414436d0f9e8c 100644 (file)
@@ -9,9 +9,6 @@
  */
 
 #include "fs.h"
-#include "buf.h"
-#include "inode.h"
-#include "const.h"
 
 
 /*===========================================================================*
index d90e70252de9556851578421823e118e6ddc5d70..5cad1c1721a6f52ff7ee607621d3e0e2569a631c 100644 (file)
@@ -6,42 +6,16 @@
 #define _TABLE
 
 #include "fs.h"
-#include "inode.h"
-#include "buf.h"
 
 /* File System Handlers (pfs) */
-int (*fs_call_vec[])(message *fs_m_in, message *fs_m_out) = {
-        no_sys,             /* 0   not used */
-        no_sys,             /* 1   */
-        fs_putnode,         /* 2   */
-        no_sys,             /* 3   */
-        fs_ftrunc,          /* 4   */
-        no_sys,             /* 5   */
-       fs_chmod,           /* 6   */
-        no_sys,             /* 7   */
-        fs_stat,            /* 8   */
-        no_sys,             /* 9   */
-        no_sys,             /* 10  */
-        no_sys,             /* 11  */
-        no_sys,             /* 12  */
-        no_sys,                    /* 13  */
-        no_sys,             /* 14  */
-        fs_unmount,         /* 15  */
-       fs_sync,            /* 16  */
-        no_sys,             /* 17  */
-        no_sys,                    /* 18  */
-        fs_readwrite,      /* 19  */
-        fs_readwrite,      /* 20  */
-        no_sys,             /* 21  */
-        no_sys,             /* 22  */
-        no_sys,             /* 23  */
-        no_sys,             /* 24  */
-        no_sys,             /* 25  */
-        no_sys,             /* 26  */
-        no_sys,             /* 27  */
-        no_sys,                    /* 28  */
-        fs_newnode,        /* 29  */
-        no_sys,                    /* 30  */
-        no_sys,                    /* 31  */
-       no_sys,             /* 32 */
+struct fsdriver pfs_table = {
+       .fdr_mount      = fs_mount,
+       .fdr_unmount    = fs_unmount,
+       .fdr_newnode    = fs_newnode,
+       .fdr_putnode    = fs_putnode,
+       .fdr_read       = fs_read,
+       .fdr_write      = fs_write,
+       .fdr_trunc      = fs_trunc,
+       .fdr_stat       = fs_stat,
+       .fdr_chmod      = fs_chmod
 };
diff --git a/minix/fs/pfs/utility.c b/minix/fs/pfs/utility.c
deleted file mode 100644 (file)
index 468f46d..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-#include "fs.h"
-
-
-/*===========================================================================*
- *                             no_sys                                       *
- *===========================================================================*/
-int no_sys(message *pfs_m_in, message *pfs_m_out)
-{
-/* Somebody has used an illegal system call number */
-  printf("no_sys: invalid call 0x%x to pfs\n", pfs_m_in->m_type);
-  return(EINVAL);
-}
index 4e3fd3630b2ee9d23fb161e010cf9d7dc43d8247..c092404f77c631a459c629b6e43d44949308d131 100644 (file)
@@ -289,7 +289,7 @@ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *info)
   message mess;
   struct rprocpub rprocpub[NR_BOOT_PROCS];
 
-  receive_from = ANY;
+  receive_from = NONE;
   self = NULL;
   verbose = 0;
 
@@ -379,10 +379,8 @@ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *info)
   init_vmnts();                        /* init vmnt structures */
   init_select();               /* init select() structures */
   init_filps();                        /* Init filp structures */
-  mount_pfs();                 /* mount Pipe File Server */
 
-  /* Mount initial ramdisk as file system root. */
-  receive_from = MFS_PROC_NR;
+  /* Mount PFS and initial file system root. */
   worker_start(fproc_addr(VFS_PROC_NR), do_init_root, &mess /*unused*/,
        FALSE /*use_spare*/);
 
@@ -394,9 +392,19 @@ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *info)
  *===========================================================================*/
 static void do_init_root(void)
 {
+  char *mount_type, *mount_label;
   int r;
-  char *mount_type = "mfs"; /* FIXME: use boot image process name instead */
-  char *mount_label = "fs_imgrd"; /* FIXME: obtain this from RS */
+
+  /* Mount the pipe file server. */
+  receive_from = PFS_PROC_NR;
+
+  mount_pfs();
+
+  /* Mount the root file system. */
+  receive_from = MFS_PROC_NR;
+
+  mount_type = "mfs";       /* FIXME: use boot image process name instead */
+  mount_label = "fs_imgrd"; /* FIXME: obtain this from RS */
 
   r = mount_fs(DEV_IMGRD, "bootramdisk", "/", MFS_PROC_NR, 0, mount_type,
        mount_label);
@@ -485,6 +493,8 @@ static void get_work()
   }
 
   for(;;) {
+       assert(receive_from != NONE);
+
        /* Normal case.  No one to revive. Get a useful request. */
        if ((r = sef_receive(receive_from, &m_in)) != OK) {
                panic("VFS: sef_receive error: %d", r);
index 17ef918dc775806d9ad3eacc8ede5e50e8ed13a2..2506f7ecde9063177beb23d39220c967ca69173f 100644 (file)
@@ -390,11 +390,16 @@ char mount_label[LABEL_MAX] )
  *===========================================================================*/
 void mount_pfs(void)
 {
-/* Mount the Pipe File Server. It's not really mounted onto the file system,
-   but it's necessary it has a vmnt entry to make locking easier */
-
+/* Mount the Pipe File Server.  We treat it as a regular file system to a
+ * certain extent, to prevent creating too many exceptions all over the place.
+ * For example, it has a vmnt entry to make locking easier, and it gets sent
+ * a mount request to keep the fsdriver library happy.
+ */
   dev_t dev;
   struct vmnt *vmp;
+  struct node_details res;
+  unsigned int fs_flags;
+  int r;
 
   if ((dev = find_free_nonedev()) == NO_DEV)
        panic("VFS: no nonedev to initialize PFS");
@@ -410,6 +415,13 @@ void mount_pfs(void)
   strlcpy(vmp->m_label, "pfs", LABEL_MAX);
   strlcpy(vmp->m_mount_path, "pipe", PATH_MAX);
   strlcpy(vmp->m_mount_dev, "none", PATH_MAX);
+
+  /* Ask PFS to acknowledge being mounted. Ignore the returned node details. */
+  r = req_readsuper(vmp, "", dev, FALSE, FALSE, &res, &fs_flags);
+  if (r != OK)
+       printf("VFS: unable to mount PFS (%d)\n", r);
+  else
+       vmp->m_fs_flags = fs_flags;
 }
 
 /*===========================================================================*
index f772b06d308dc2994929e2a51342328c823f7823..203c606b3f87ee241a05204b2ccbaadb92422369 100644 (file)
@@ -355,7 +355,10 @@ size_t req_size;
   buf += cum_io_incr;
   req_size -= cum_io_incr;
 
-  vp->v_size = new_pos;
+  if (rw_flag == READING)
+       vp->v_size -= cum_io_incr;
+  else
+       vp->v_size += cum_io_incr;
 
   if (partial_pipe) {
        /* partial write on pipe with */