]> Zhao Yanbai Git Server - minix.git/commitdiff
New VFS interface
authorPhilip Homburg <philip@cs.vu.nl>
Tue, 7 Aug 2007 12:52:47 +0000 (12:52 +0000)
committerPhilip Homburg <philip@cs.vu.nl>
Tue, 7 Aug 2007 12:52:47 +0000 (12:52 +0000)
29 files changed:
servers/vfs/const.h
servers/vfs/device.c
servers/vfs/dmap.c
servers/vfs/dmap.h [new file with mode: 0644]
servers/vfs/exec.c
servers/vfs/fs.h
servers/vfs/glo.h
servers/vfs/link.c
servers/vfs/main.c
servers/vfs/misc.c
servers/vfs/mount.c
servers/vfs/open.c
servers/vfs/param.h
servers/vfs/path.c
servers/vfs/pipe.c
servers/vfs/protect.c
servers/vfs/proto.h
servers/vfs/read.c
servers/vfs/request.c
servers/vfs/request.h
servers/vfs/stadir.c
servers/vfs/super.h
servers/vfs/table.c
servers/vfs/time.c
servers/vfs/type.h
servers/vfs/utility.c
servers/vfs/vmnt.h
servers/vfs/vnode.c
servers/vfs/vnode.h

index 4894e234be363cc53eef4c582ec039f9d13bf6ce..6c0ef48050f824c1c92f5f5a9cf9dfeda007a3d7 100644 (file)
@@ -87,7 +87,6 @@
 #define DIR_ENTRY_SIZE       usizeof (struct direct)  /* # bytes/dir entry   */
 #define NR_DIR_ENTRIES(b)   ((b)/DIR_ENTRY_SIZE)  /* # dir entries/blk   */
 #define SUPER_SIZE      usizeof (struct super_block)  /* super_block size    */
-#define PIPE_SIZE(b)          (V1_NR_DZONES*(b))  /* pipe size in bytes  */
 
 #define FS_BITMAP_CHUNKS(b) ((b)/usizeof (bitchunk_t))/* # map chunks/blk   */
 #define FS_BITCHUNK_BITS               (usizeof(bitchunk_t) * CHAR_BIT)
 #define V2_INDIRECTS(b)   ((b)/V2_ZONE_NUM_SIZE)  /* # zones/indir block */
 #define V2_INODES_PER_BLOCK(b) ((b)/V2_INODE_SIZE)/* # V2 dsk inodes/blk */
 
-/* Args to dev_bio/dev_io */
+/* Args to dev_io */
 #define VFS_DEV_READ   2001
 #define        VFS_DEV_WRITE   2002
 #define VFS_DEV_SCATTER        2003
index 37f68c91b6cbce217d1362f4bc9fb8997b09060f..be6933a3b7e90612abe46c24b197ae294b061e4d 100644 (file)
@@ -303,125 +303,6 @@ int gids_size;
        return;
 }
 
-#if 0
-/*===========================================================================*
- *                             dev_bio                                      *
- *===========================================================================*/
-PUBLIC int dev_bio(op, dev, proc_e, buf, pos, bytes)
-int op;                                /* DEV_READ, DEV_WRITE, DEV_IOCTL, etc. */
-dev_t dev;                     /* major-minor device number */
-int proc_e;                    /* in whose address space is buf? */
-void *buf;                     /* virtual address of the buffer */
-off_t pos;                     /* byte position */
-int bytes;                     /* how many bytes to transfer */
-{
-/* Read or write from a device.  The parameter 'dev' tells which one. */
-  struct dmap *dp;
-  int r, safe;
-  message m;
-  iovec_t *v;
-  cp_grant_id_t gid = GRANT_INVALID;
-       int vec_grants;
-
-  /* Determine task dmap. */
-  dp = &dmap[(dev >> MAJOR) & BYTE];
-
-  /* The io vector copying relies on this I/O being for FS itself. */
-  if(proc_e != FS_PROC_NR)
-       panic(__FILE__, "doing dev_bio for non-self", proc_e);
-
-  for (;;)
-  {
-       int op_used;
-       void *buf_used;
-        static cp_grant_id_t gids[NR_IOREQS];
-        cp_grant_id_t gid = GRANT_INVALID;
-       int vec_grants;
-
-       /* See if driver is roughly valid. */
-       if (dp->dmap_driver == NONE) {
-               printf("FS: dev_io: no driver for dev %x\n", dev);
-               return ENXIO;
-       }
-
-        /* By default, these are right. */
-       m.IO_ENDPT = proc_e;
-       m.ADDRESS  = buf;
-       buf_used = buf;
-
-       /* Convert parameters to 'safe mode'. */
-       op_used = op;
-        safe = safe_io_conversion(dp->dmap_driver, &gid,
-          &op_used, gids, NR_IOREQS, &m.IO_ENDPT, &buf_used,
-         &vec_grants, bytes, &pos);
-
-       /* Set up rest of the message. */
-       if(safe) m.IO_GRANT = (char *) gid;
-
-       m.m_type   = op_used;
-       m.DEVICE   = (dev >> MINOR) & BYTE;
-       m.POSITION = pos;
-       m.COUNT    = bytes;
-       m.HIGHPOS  = 0;
-
-       /* Call the task. */
-       (*dp->dmap_io)(dp->dmap_driver, &m);
-
-       /* As block I/O never SUSPENDs, safe cleanup must be done whether
-        * the I/O succeeded or not.
-        */
-       if(safe) safe_io_cleanup(gid, gids, vec_grants);
-
-       if(dp->dmap_driver == NONE) {
-               /* Driver has vanished. Wait for a new one. */
-               for (;;)
-               {
-                       r= receive(RS_PROC_NR, &m);
-                       if (r != OK)
-                       {
-                               panic(__FILE__,
-                                       "dev_bio: unable to receive from RS",
-                                       r);
-                       }
-                       if (m.m_type == DEVCTL)
-                       {
-                               r= fs_devctl(m.ctl_req, m.dev_nr, m.driver_nr,
-                                       m.dev_style, m.m_force);
-                       }
-                       else
-                       {
-                               panic(__FILE__,
-                                       "dev_bio: got message from RS, type",
-                                       m.m_type);
-                       }
-                       m.m_type= r;
-                       r= send(RS_PROC_NR, &m);
-                       if (r != OK)
-                       {
-                               panic(__FILE__,
-                                       "dev_bio: unable to send to RS",
-                                       r);
-                       }
-                       if (dp->dmap_driver != NONE)
-                               break;
-               }
-               printf("dev_bio: trying new driver\n");
-               continue;
-       }
-
-       /* Task has completed.  See if call completed. */
-       if (m.REP_STATUS == SUSPEND) {
-               panic(__FILE__, "dev_bio: driver returned SUSPEND", NO_NUM);
-       }
-
-       if(buf != buf_used) {
-               memcpy(buf, buf_used, bytes * sizeof(iovec_t));
-       }
-
-       return(m.REP_STATUS);
-  }
-}
-#endif
 
 /*===========================================================================*
  *                             dev_io                                       *
@@ -803,12 +684,12 @@ int flags;                        /* mode bits and flags */
 
 
   if (dp->dmap_driver == NONE) {
-       printf("FS: clone_opcl: no driver for dev %x\n", dev);
+       printf("vfs:clone_opcl: no driver for dev %x\n", dev);
        return ENXIO;
   }
 
   if(isokendpt(dp->dmap_driver, &dummyproc) != OK) {
-       printf("FS: clone_opcl: old driver for dev %x (%d)\n",
+       printf("vfs:clone_opcl: bad driver endpoint for dev %x (%d)\n",
                dev, dp->dmap_driver);
        return ENXIO;
   }
@@ -822,22 +703,21 @@ int flags;                        /* mode bits and flags */
        if (dev_mess.REP_STATUS != minor) {
                 struct vnode *vp;
                 struct vmnt *vmp;
-
-                struct clone_opcl_req req;
                 struct node_details res;
+
                /* A new minor device number has been returned.
-                 * Request root FS to create a temporary device file to hold it. 
+                 * Request the root FS to create a temporary device file to
+                * hold it. 
                  */
                
                 /* Device number of the new device. */
-               dev = (dev & ~(BYTE << MINOR)) | (dev_mess.REP_STATUS << MINOR);
-               
-                /* Fill in request */
-                req.fs_e = ROOT_FS_E;
-                req.dev = dev;
+               dev = (dev & ~(BYTE << MINOR)) |
+                       (dev_mess.REP_STATUS << MINOR);
 
                 /* Issue request */
-                if ((r = req_clone_opcl(&req, &res)) != OK) {
+                r = req_newnode(ROOT_FS_E, fp->fp_effuid, fp->fp_effgid,
+                       ALL_MODES | I_CHAR_SPECIAL, dev, &res);
+                if (r != OK) {
                     (void) clone_opcl(DEV_CLOSE, dev, proc_e, 0);
                     return r;
                 }
@@ -847,17 +727,19 @@ int flags;                        /* mode bits and flags */
                
                 put_vnode(vp);
                if ((vp = get_free_vnode(__FILE__, __LINE__)) == NIL_VNODE) {
-                       printf("VFSclone_opcl: failed to get a free vnode..\n");
+                       printf(
+                       "vfs:clone_opcl: failed to get a free vnode..\n");
                        vp = fp->fp_filp[m_in.fd]->filp_vno;
                }
                
                 vp->v_fs_e = res.fs_e;
                 if ((vmp = find_vmnt(vp->v_fs_e)) == NIL_VMNT) 
-                    printf("VFSclone_opcl: no vmnt found\n");
+                    printf("vfs:clone_opcl: no vmnt found\n");
 
                 vp->v_vmnt = vmp;
                 vp->v_dev = vmp->m_dev;
                 
+               vp->v_fs_e = res.fs_e;
                 vp->v_inode_nr = res.inode_nr;
                 vp->v_mode = res.fmode; 
                 vp->v_sdev = dev;
@@ -870,6 +752,7 @@ int flags;                  /* mode bits and flags */
   return(dev_mess.REP_STATUS);
 }
 
+
 /*===========================================================================*
  *                             dev_up                                       *
  *===========================================================================*/
index 8ab0d016b72067f05904aa2c8011e151a0de6a7e..6bc92bd1c9760a27e921336cb67ecaed3dc1c00e 100644 (file)
 #include <ctype.h>
 #include <unistd.h>
 #include <minix/com.h>
+#include <minix/ds.h>
 #include "param.h"
 
 /* Some devices may or may not be there in the next table. */
-#define DT(enable, opcl, io, driver, flags) \
+#define DT(enable, opcl, io, driver, flags, label) \
   { (enable?(opcl):no_dev), (enable?(io):0), \
-       (enable?(driver):0), (flags) },
+       (enable?(driver):0), (flags), label },
 #define NC(x) (NR_CTRLRS >= (x))
 
 /* The order of the entries here determines the mapping between major device
  */
 struct dmap dmap[NR_DEVICES];                          /* actual map */ 
 PRIVATE struct dmap init_dmap[] = {
-  DT(1, no_dev,   0,       0,          0)              /* 0 = not used   */
-  DT(1, gen_opcl, gen_io,  MEM_PROC_NR, 0)             /* 1 = /dev/mem   */
-  DT(0, no_dev,   0,       0,           DMAP_MUTABLE)  /* 2 = /dev/fd0   */
-  DT(0, no_dev,   0,       0,           DMAP_MUTABLE)  /* 3 = /dev/c0    */
-  DT(1, tty_opcl, gen_io,  TTY_PROC_NR, 0)             /* 4 = /dev/tty00 */
-  DT(1, ctty_opcl,ctty_io, TTY_PROC_NR, 0)                     /* 5 = /dev/tty   */
-  DT(0, no_dev,   0,       NONE,       DMAP_MUTABLE)   /* 6 = /dev/lp    */
+  DT(1, no_dev,   0,       0,          0, "")          /* 0 = not used   */
+  DT(1, gen_opcl, gen_io,  MEM_PROC_NR, 0, "memory")        /* 1 = /dev/mem   */
+  DT(0, no_dev,   0,       0,           DMAP_MUTABLE, "")   /* 2 = /dev/fd0   */
+  DT(0, no_dev,   0,       0,           DMAP_MUTABLE, "")   /* 3 = /dev/c0    */
+  DT(1, tty_opcl, gen_io,  TTY_PROC_NR, 0, "")          /* 4 = /dev/tty00 */
+  DT(1, ctty_opcl,ctty_io, TTY_PROC_NR, 0, "")          /* 5 = /dev/tty   */
+  DT(0, no_dev,   0,       NONE,       DMAP_MUTABLE, "")       /* 6 = /dev/lp    */
 
 #if (MACHINE == IBM_PC)
-  DT(1, no_dev,   0,       0,          DMAP_MUTABLE)   /* 7 = /dev/ip    */
-  DT(0, no_dev,   0,       NONE,        DMAP_MUTABLE)   /* 8 = /dev/c1    */
-  DT(0, 0,        0,       0,          DMAP_MUTABLE)   /* 9 = not used   */
-  DT(0, no_dev,   0,       0,           DMAP_MUTABLE)   /*10 = /dev/c2    */
-  DT(0, 0,        0,       0,          DMAP_MUTABLE)   /*11 = not used   */
-  DT(0, no_dev,   0,       NONE,       DMAP_MUTABLE)   /*12 = /dev/c3    */
-  DT(0, no_dev,   0,       NONE,       DMAP_MUTABLE)   /*13 = /dev/audio */
-  DT(0, no_dev,   0,       NONE,       DMAP_MUTABLE)   /*14 = /dev/mixer */
-  DT(1, gen_opcl, gen_io,  LOG_PROC_NR, 0)             /*15 = /dev/klog  */
-  DT(0, no_dev,   0,       NONE,       DMAP_MUTABLE)   /*16 = /dev/random*/
-  DT(0, no_dev,   0,       NONE,       DMAP_MUTABLE)   /*17 = /dev/cmos  */
+  DT(1, no_dev,   0,       0,          DMAP_MUTABLE, "")   /* 7 = /dev/ip    */
+  DT(0, no_dev,   0,       NONE,        DMAP_MUTABLE, "")   /* 8 = /dev/c1    */
+  DT(0, 0,        0,       0,          DMAP_MUTABLE, "")   /* 9 = not used   */
+  DT(0, no_dev,   0,       0,           DMAP_MUTABLE, "")   /*10 = /dev/c2    */
+  DT(0, 0,        0,       0,          DMAP_MUTABLE, "")   /*11 = not used   */
+  DT(0, no_dev,   0,       NONE,       DMAP_MUTABLE, "")   /*12 = /dev/c3    */
+  DT(0, no_dev,   0,       NONE,       DMAP_MUTABLE, "")   /*13 = /dev/audio */
+  DT(0, no_dev,   0,       NONE,       DMAP_MUTABLE, "")   /*14 = /dev/mixer */
+  DT(1, gen_opcl, gen_io,  LOG_PROC_NR, 0, "")                 /*15 = /dev/klog  */
+  DT(0, no_dev,   0,       NONE,       DMAP_MUTABLE, "")   /*16 = /dev/random*/
+  DT(0, no_dev,   0,       NONE,       DMAP_MUTABLE, "")   /*17 = /dev/cmos  */
 #endif /* IBM_PC */
 };
 
+FORWARD _PROTOTYPE( int map_driverX, (char *label, int major,
+                       endpoint_t proc_nr_e, int style, int force)     );
+
 /*===========================================================================*
  *                             do_devctl                                    *
  *===========================================================================*/
@@ -116,6 +120,77 @@ int force;
   return(result);
 }
 
+
+/*===========================================================================*
+ *                             do_mapdriver                                 *
+ *===========================================================================*/
+PUBLIC int do_mapdriver()
+{
+       int r, force, major, proc_nr_n;
+       unsigned long tasknr;
+       vir_bytes label_vir;
+       size_t label_len;
+       char label[16];
+
+       if (!super_user)
+       {
+               printf("FS: unauthorized call of do_mapdriver by proc %d\n",
+                       who_e);
+               return(EPERM);  /* only su (should be only RS or some drivers)
+                                * may call do_mapdriver.
+                                */
+       }
+
+       /* Get the label */
+       label_vir= (vir_bytes)m_in.md_label;
+       label_len= m_in.md_label_len;
+
+       if (label_len+1 > sizeof(label))
+       {
+               printf("vfs:do_mapdriver: label too long\n");
+               return EINVAL;
+       }
+
+       r= sys_vircopy(who_e, D, label_vir, SELF, D, (vir_bytes)label,
+               label_len);
+       if (r != OK)
+       {
+               printf("vfs:do_mapdriver: sys_vircopy failed: %d\n", r);
+               return EINVAL;
+       }
+
+       label[label_len]= '\0';
+
+       r= ds_retrieve_u32(label, &tasknr);
+       if (r != OK)
+       {
+               printf("vfs:do_mapdriver: ds doesn't know '%s'\n", label);
+               return EINVAL;
+       }
+
+       if (isokendpt(tasknr, &proc_nr_n) != OK)
+               return(EINVAL);
+
+       /* Try to update device mapping. */
+       major= m_in.md_major;
+       force= m_in.md_force;
+       r= map_driverX(label, major, tasknr, m_in.md_style, force);
+       if (r == OK)
+       {
+               /* If a driver has completed its exec(), it can be announced
+                * to be up.
+               */
+               if(force || fproc[proc_nr_n].fp_execced) {
+                       dev_up(major);
+               } else {
+                       dmap[major].dmap_flags |= DMAP_BABY;
+               }
+       }
+
+       return(r);
+}
+
+
 /*===========================================================================*
  *                             map_driver                                   *
  *===========================================================================*/
@@ -176,6 +251,74 @@ int force;
   return(OK); 
 }
 
+
+/*===========================================================================*
+ *                             map_driverX                                  *
+ *===========================================================================*/
+PRIVATE int map_driverX(label, major, proc_nr_e, style, force)
+char *label;                   /* name of the driver */
+int major;                     /* major number of the device */
+endpoint_t proc_nr_e;          /* process number of the driver */
+int style;                     /* style of the device */
+int force;
+{
+/* Set a new device driver mapping in the dmap table. Given that correct 
+ * arguments are given, this only works if the entry is mutable and the 
+ * current driver is not busy.  If the proc_nr is set to NONE, we're supposed
+ * to unmap it.
+ *
+ * Normal error codes are returned so that this function can be used from
+ * a system call that tries to dynamically install a new driver.
+ */
+  int proc_nr_n;
+  size_t len;
+  struct dmap *dp;
+
+  /* Get pointer to device entry in the dmap table. */
+  if (major < 0 || major >= NR_DEVICES) return(ENODEV);
+  dp = &dmap[major];           
+
+  /* Check if we're supposed to unmap it. If so, do it even
+   * if busy or unmutable, as unmap is called when driver has
+   * exited.
+   */
+ if(proc_nr_e == NONE) {
+       dp->dmap_opcl = no_dev;
+       dp->dmap_io = no_dev_io;
+       dp->dmap_driver = NONE;
+       dp->dmap_flags = DMAP_MUTABLE;  /* When gone, not busy or reserved. */
+       return(OK);
+  }
+       
+  /* See if updating the entry is allowed. */
+  if (! (dp->dmap_flags & DMAP_MUTABLE))  return(EPERM);
+  if (dp->dmap_flags & DMAP_BUSY)  return(EBUSY);
+
+  if (!force)
+  {
+       /* Check process number of new driver. */
+       if (isokendpt(proc_nr_e, &proc_nr_n) != OK)
+               return(EINVAL);
+  }
+
+  len= strlen(label);
+  if (len+1 > sizeof(dp->dmap_label))
+       panic(__FILE__, "map_driver: label too long", len);
+  strcpy(dp->dmap_label, label);
+
+  /* Try to update the entry. */
+  switch (style) {
+  case STYLE_DEV:      dp->dmap_opcl = gen_opcl;       break;
+  case STYLE_TTY:      dp->dmap_opcl = tty_opcl;       break;
+  case STYLE_CLONE:    dp->dmap_opcl = clone_opcl;     break;
+  default:             return(EINVAL);
+  }
+  dp->dmap_io = gen_io;
+  dp->dmap_driver = proc_nr_e;
+
+  return(OK); 
+}
+
 /*===========================================================================*
  *                             dmap_unmap_by_endpt                          *
  *===========================================================================*/
@@ -213,6 +356,7 @@ PUBLIC void build_dmap()
           dp->dmap_io = init_dmap[i].dmap_io;
           dp->dmap_driver = init_dmap[i].dmap_driver;
           dp->dmap_flags = init_dmap[i].dmap_flags;
+         strcpy(dp->dmap_label, init_dmap[i].dmap_label);
       } else {                                         /* no default */
           dp->dmap_opcl = no_dev;
           dp->dmap_io = no_dev_io;
diff --git a/servers/vfs/dmap.h b/servers/vfs/dmap.h
new file mode 100644 (file)
index 0000000..71c2d48
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+dmap.h
+*/
+
+/*===========================================================================*
+ *                      Device <-> Driver Table                             *
+ *===========================================================================*/
+
+/* Device table.  This table is indexed by major device number.  It provides
+ * the link between major device numbers and the routines that process them.
+ * The table can be update dynamically. The field 'dmap_flags' describe an 
+ * entry's current status and determines what control options are possible. 
+ */
+#define DMAP_MUTABLE           0x01    /* mapping can be overtaken */
+#define DMAP_BUSY              0x02    /* driver busy with request */
+#define DMAP_BABY              0x04    /* driver exec() not done yet */
+
+extern struct dmap {
+  int _PROTOTYPE ((*dmap_opcl), (int, Dev_t, int, int) );
+  int _PROTOTYPE ((*dmap_io), (int, message *) );
+  int dmap_driver;
+  int dmap_flags;
+  char dmap_label[16];
+} dmap[];
index 44c077154244789dffb52c4491d28e98853dd7df..f86c10129c0e8044a658cc763467f86c87cc1766 100644 (file)
@@ -86,10 +86,6 @@ vir_bytes frame_len;
     char progname[PROC_NAME_LEN];
     static char mbuf[ARG_MAX]; /* buffer for stack and zeroes */
 
-    /* Request and response structures */
-    struct lookup_req lookup_req;
-    struct node_details Xres;
-    
     okendpt(proc_e, &proc_s);
     rfp= fp= &fproc[proc_s];
     who_e= proc_e;
@@ -129,23 +125,19 @@ printf("return at %s, %d\n", __FILE__, __LINE__);
     for (round= 0; round < 2; round++)
         /* round = 0 (first attempt), or 1 (interpreted script) */
     {
+#if 0
+       printf("vfs:pm_exec: round %d, name '%s'\n", round, user_fullpath);
+#endif
+
         /* Save the name of the program */
         (cp= strrchr(user_fullpath, '/')) ? cp++ : (cp= user_fullpath);
 
         strncpy(progname, cp, PROC_NAME_LEN-1);
         progname[PROC_NAME_LEN-1] = '\0';
 
-        /* Fill in lookup request fields */
-        lookup_req.path = user_fullpath;
-        lookup_req.lastc = NULL;
-        lookup_req.flags = EAT_PATH;
-        
         /* Request lookup */
-        if ((r = lookup_vp(&lookup_req, &vp)) != OK)
-       {
-               put_vnode(vp);
+        if ((r = lookup_vp(0 /*flags*/, 0 /*!use_realuid*/, &vp)) != OK)
                return r;
-       }
         
         if ((vp->v_mode & I_TYPE) != I_REGULAR) {
            put_vnode(vp);
@@ -153,7 +145,7 @@ printf("return at %s, %d\n", __FILE__, __LINE__);
         }
 
        /* Check access. */
-       if ((r = forbidden(vp, X_BIT)) != OK)
+       if ((r = forbidden(vp, X_BIT, 0 /*!use_realuid*/)) != OK)
        {
            put_vnode(vp);
            return r;
@@ -168,6 +160,10 @@ printf("return at %s, %d\n", __FILE__, __LINE__);
        }
         v_ctime = sb.st_ctime;
         
+#if 0
+       printf("vfs:pm_exec: round %d, mode 0%o, uid %d, gid %d\n",
+               round, vp->v_mode, vp->v_uid, vp->v_gid);
+#endif
         if (round == 0)
         {
             /* Deal with setuid/setgid executables */
@@ -340,6 +336,9 @@ int *hdrlenp;
 {
 /* Read the header and extract the text, data, bss and total sizes from it. */
   off_t pos;
+  int r;
+  u64_t new_pos;
+  unsigned int cum_io_incr;
   struct exec hdr;             /* a.out header is read in here */
 
   /* Read the header and check the magic number.  The standard MINIX header 
@@ -368,26 +367,14 @@ int *hdrlenp;
    * used here only. The symbol table is for the benefit of a debugger and 
    * is ignored here.
    */
-
-  struct readwrite_req req;
-  struct readwrite_res res;
-  int r;
   
   pos= 0;      /* Read from the start of the file */
 
-  /* Fill in request structure */
-  req.fs_e = vp->v_fs_e;
-  req.rw_flag = READING;
-  req.inode_nr = vp->v_inode_nr;
-  req.user_e = FS_PROC_NR;
-  req.seg = D;
-  req.pos = cvul64(pos);
-  req.num_of_bytes = sizeof(hdr);
-  req.user_addr = (char*)&hdr;
-  req.inode_index = vp->v_index;
-
   /* Issue request */
-  if ((r = req_readwrite(&req, &res)) != OK) return r;
+  r = req_readwrite(vp->v_fs_e, vp->v_inode_nr, vp->v_index, 
+       cvul64(pos), READING, FS_PROC_NR, (char*)&hdr, sizeof(hdr), &new_pos,
+       &cum_io_incr);
+  if (r != OK) return r;
 
   /* Interpreted script? */
   if (((char*)&hdr)[0] == '#' && ((char*)&hdr)[1] == '!' && vp->v_size >= 2)
@@ -441,32 +428,23 @@ vir_bytes *stk_bytes;             /* size of initial stack */
   int n, r;
   off_t pos;
   char *sp, *interp = NULL;
+  u64_t new_pos;
+  unsigned int cum_io_incr;
   char buf[_MAX_BLOCK_SIZE];
-  struct readwrite_req req;
-  struct readwrite_res res;
 
   /* Make user_path the new argv[0]. */
   if (!insert_arg(stack, stk_bytes, user_fullpath, REPLACE)) return(ENOMEM);
 
   pos = 0;     /* Read from the start of the file */
 
-  /* Fill in request structure */
-  req.fs_e = vp->v_fs_e;
-  req.rw_flag = READING;
-  req.inode_nr = vp->v_inode_nr;
-  req.user_e = FS_PROC_NR;
-  req.seg = D;
-  req.pos = cvul64(pos);
-  req.num_of_bytes = _MAX_BLOCK_SIZE;
-  req.user_addr = buf;
-  req.inode_index = vp->v_index;
-
   /* Issue request */
-  if ((r = req_readwrite(&req, &res)) != OK) return r;
+  r = req_readwrite(vp->v_fs_e, vp->v_inode_nr, vp->v_index, cvul64(pos),
+       READING, FS_PROC_NR, buf, _MAX_BLOCK_SIZE, &new_pos, &cum_io_incr);
+  if (r != OK) return r;
   
   n = vp->v_size;
-  if (n > vp->v_vmnt->m_block_size)
-       n = vp->v_vmnt->m_block_size;
+  if (n > _MAX_BLOCK_SIZE)
+       n = _MAX_BLOCK_SIZE;
   if (n < 2) return ENOEXEC;
   
   sp = &(buf[2]);                              /* just behind the #! */
@@ -604,28 +582,64 @@ phys_bytes seg_bytes;             /* how much is to be transferred? */
  * a segment is padded out to a click multiple, and the data segment is only
  * partially initialized.
  */
-  struct readwrite_req req;
-  struct readwrite_res res;
   int r;
+  unsigned n, o;
+  u64_t new_pos;
+  unsigned int cum_io_incr;
+  char buf[1024];
 
   /* Make sure that the file is big enough */
   if (vp->v_size < off+seg_bytes) return EIO;
+
+  if (seg != D)
+  {
+       /* We have to use a copy loop until safecopies support segments */
+       o= 0;
+       while (o < seg_bytes)
+       {
+               n= seg_bytes-o;
+               if (n > sizeof(buf))
+                       n= sizeof(buf);
+
+#if 0
+printf("read_seg for user %d, seg %d: buf 0x%x, size %d, pos %d\n",
+       proc_e, seg, buf, n, off+o);
+#endif
+
+               /* Issue request */
+               r = req_readwrite(vp->v_fs_e, vp->v_inode_nr, vp->v_index,
+                       cvul64(off+o), READING, FS_PROC_NR, buf, n, &new_pos,
+                       &cum_io_incr);
+               if (r != OK) return r;
+
+               if (cum_io_incr != n)
+               {
+                       printf(
+               "VFSread_seg segment has not been read properly by exec() \n");
+                       return EIO;
+               }
+
+               r= sys_vircopy(FS_PROC_NR, D, (vir_bytes)buf, proc_e, seg, o,
+                       n);
+               if (r != OK)
+                       return r;
+
+               o += n;
+       }
+       return OK;
+  }
   
-  /* Fill in request structure */
-  req.fs_e = vp->v_fs_e;
-  req.rw_flag = READING;
-  req.inode_nr = vp->v_inode_nr;
-  req.user_e = proc_e;
-  req.seg = seg;
-  req.pos = cvul64(off);
-  req.num_of_bytes = seg_bytes;
-  req.user_addr = 0;
-  req.inode_index = vp->v_index;
+#if 0
+printf("read_seg for user %d, seg %d: buf 0x%x, size %d, pos %d\n",
+       proc_e, seg, 0, seg_bytes, off);
+#endif
 
   /* Issue request */
-  if ((r = req_readwrite(&req, &res)) != OK) return r;
+  r = req_readwrite(vp->v_fs_e, vp->v_inode_nr, vp->v_index, cvul64(off),
+       READING, proc_e, 0, seg_bytes, &new_pos, &cum_io_incr);
+  if (r != OK) return r;
   
-  if (r == OK && res.cum_io != seg_bytes)
+  if (r == OK && cum_io_incr != seg_bytes)
       printf("VFSread_seg segment has not been read properly by exec() \n");
 
   return r; 
index b9f16ff04807034b91eaf04c07f570cfa18bacfa..7d032834026e4af98fd40af52803233fab003097 100644 (file)
@@ -22,5 +22,6 @@
 #include <minix/sysutil.h>
 
 #include "const.h"
+#include "dmap.h"
 #include "proto.h"
 #include "glo.h"
index 829353b372070de2ef3918e97737a7d83779571a..1c7fa6a1780ef2c298a23a0fd9d0aa845c5dfb1c 100644 (file)
@@ -15,7 +15,6 @@ EXTERN Dev_t root_dev;                /* device number of the root device */
 EXTERN int ROOT_FS_E;           /* kernel endpoint of the root FS proc */
 EXTERN int last_login_fs_e;     /* endpoint of the FS proc that logged in
                                    before the corresponding mount request */
-EXTERN time_t boottime;                /* time in seconds at system boot */
 
 /* The parameters of the call are kept here. */
 EXTERN message m_in;           /* the input message itself */
index 69c471bdbdf0a9cc8e23fa48381ea59df52f6dae..56e632c58f082906cbc198e8d57413bf1cda1ef4 100644 (file)
 PUBLIC int do_link()
 {
 /* Perform the link(name1, name2) system call. */
-  int linked_fs_e;
-  int linked_inode_nr;
-  int link_lastdir_fs_e;
-  int link_lastdir_inode_nr;
-  char string[NAME_MAX];
-  struct link_req req;
-  struct lookup_req lookup_req;
-  struct node_details res;
   int r;
+  endpoint_t linked_fs_e, link_lastdir_fs_e;
+  struct vnode *vp_o, *vp_d;
 
   if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) 
         return(err_code);
         
-  /* Fill in lookup request fields */
-  lookup_req.path = user_fullpath;
-  lookup_req.lastc = NULL;
-  lookup_req.flags = EAT_PATH;
-        
   /* Request lookup */
-  if ((r = lookup(&lookup_req, &res)) != OK) return r;
+  if ((r = lookup_vp(0 /*flags*/, 0 /*!use_realuid*/, &vp_o)) != OK) return r;
 
-  linked_fs_e = res.fs_e;
-  req.linked_file = res.inode_nr;
+  linked_fs_e = vp_o->v_fs_e;
 
   /* Does the final directory of 'name2' exist? */
   if (fetch_name(m_in.name2, m_in.name2_length, M1) != OK) {
+       put_vnode(vp_o);
        return(err_code);
   }
 
-  /* Fill in lookup request fields */
-  lookup_req.path = user_fullpath;
-  lookup_req.lastc = string;
-  lookup_req.flags = LAST_DIR;
-        
   /* Request lookup */
-  if ((r = lookup(&lookup_req, &res)) != OK) return r;
+  if ((r = lookup_lastdir(0 /*!use_realuid*/, &vp_d)) != OK)
+  {
+       put_vnode(vp_o);
+       return r;
+  }
+
+  link_lastdir_fs_e = vp_d->v_fs_e;
 
-  link_lastdir_fs_e = res.fs_e;
-  req.link_parent = res.inode_nr;
-  
   /* Check for links across devices. */
   if (linked_fs_e != link_lastdir_fs_e) 
+  {
+       put_vnode(vp_o);
+       put_vnode(vp_d);
         return EXDEV;
+  }
 
-  /* Send link request. */
-  req.fs_e = linked_fs_e;
-  /* Send the last component of the link name */
-  req.uid = fp->fp_effuid;
-  req.gid = fp->fp_effgid;
-  req.lastc = string;
+  r= forbidden(vp_d, W_BIT|X_BIT, 0 /*!use_realuid*/);
+  if (r != OK)
+  {
+       put_vnode(vp_o);
+       put_vnode(vp_d);
+        return r;
+  }
   
   /* Issue request */
-  return req_link(&req);
+  r= req_link(linked_fs_e, vp_d->v_inode_nr, user_fullpath, vp_o->v_inode_nr);
+  put_vnode(vp_o);
+  put_vnode(vp_d);
+  return r;
 }
 
 
@@ -100,65 +95,35 @@ PUBLIC int do_unlink()
  * may be used by the superuser to do dangerous things; rmdir() may not.
  */
   register struct fproc *rfp;
-  char string[NAME_MAX];
   struct vnode *vp;
-  struct unlink_req req;
-  struct lookup_req lookup_req;
-  struct node_details res;
   int r;
-  string[0] = '\0';
   
   if (fetch_name(m_in.name, m_in.name_length, M3) != OK) return(err_code);
-  
-  /* Fill in lookup request fields */
-  lookup_req.path = user_fullpath;
-  lookup_req.lastc = NULL;
-  lookup_req.flags = EAT_PATH_OPAQUE;
-        
-  /* Request lookup */
-  if ((r = lookup(&lookup_req, &res)) != OK) return r;
+
+  r= lookup_lastdir(0 /*!use_realuid*/, &vp);
+  if (r != OK)
+       return r;
+
+  /* The caller must have both search and execute permission */
+  r= forbidden(vp, X_BIT|W_BIT, 0 /*!use_realuid*/);
+  if (r != OK)
+  {
+       put_vnode(vp);
+       return r;
+  }
   
   /* If a directory file has to be removed the following conditions have to met:
    *   - The directory must not be the root of a mounted file system
    *   - The directory must not be anybody's root/working directory
    */
-  if ((res.fmode & I_TYPE) == I_DIRECTORY) {
-      /* Only root can unlink a directory */
-      if (call_nr == UNLINK && !super_user) return EPERM; 
-
-      /* Can't remove a root directory */
-      if (res.inode_nr == ROOT_INODE) return EBUSY;
-
-      /* Can't remove anybody's working directory */
-      if ((vp = find_vnode(res.fs_e, res.inode_nr)) != 
-              NIL_VNODE) {
-          /* Check directories */
-          for (rfp = &fproc[INIT_PROC_NR + 1]; rfp < &fproc[NR_PROCS]; 
-                  rfp++) {
-              if (rfp->fp_pid != PID_FREE && 
-                      (rfp->fp_wd == vp || rfp->fp_rd == vp))
-                  return(EBUSY); 
-          }
-      }
-  }
-  
-  /* Fill in lookup request fields */
-  lookup_req.path = user_fullpath;
-  lookup_req.lastc = string;
-  lookup_req.flags = LAST_DIR;
-        
-  /* Request lookup */
-  if ((r = lookup(&lookup_req, &res)) != OK) return r;
-  
-  /* Fill in request fields. */
-  req.fs_e = res.fs_e;
-  req.d_inode_nr = res.inode_nr;
-  req.uid = fp->fp_effuid;
-  req.gid = fp->fp_effgid;
-  req.lastc = string;
   
   /* Issue request */
-  return (call_nr == UNLINK) ? req_unlink(&req) : req_rmdir(&req);
+  r= ((call_nr == UNLINK) ? req_unlink : req_rmdir)(vp->v_fs_e,
+       vp->v_inode_nr, user_fullpath);
+
+  put_vnode(vp);
+
+  return r;
 }
 
 
@@ -168,90 +133,81 @@ PUBLIC int do_unlink()
 PUBLIC int do_rename()
 {
 /* Perform the rename(name1, name2) system call. */
+  int r;
   int old_dir_inode;
   int old_fs_e;
   int new_dir_inode;
   int new_fs_e;
-  char old_name[NAME_MAX];
-  char new_name[NAME_MAX];
-  struct vnode *vp;
-  struct fproc *rfp;
-  struct rename_req req;
-  struct lookup_req lookup_req;
-  struct node_details res;
-  int r;
+  size_t len;
+  struct vnode *vp_od, *vp_nd;
+  char old_name[PATH_MAX+1];
   
   /* See if 'name1' (existing file) exists.  Get dir and file inodes. */
   if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code);
   
-  /* Fill in lookup request fields */
-  lookup_req.path = user_fullpath;
-  lookup_req.lastc = old_name;
-  lookup_req.flags = LAST_DIR;
-        
   /* Request lookup */
-  if ((r = lookup(&lookup_req, &res)) != OK) return r;
+  if ((r = lookup_lastdir(0 /*!use_realuid*/, &vp_od)) != OK) return r;
+
+  r= forbidden(vp_od, W_BIT|X_BIT, 0 /*!use_realuid*/);
+  if (r != OK)
+  {
+       put_vnode(vp_od);
+       return r;
+  }
   
-  /* Remeber inode number and FS endpoint */
-  old_fs_e = res.fs_e;
-  req.old_dir = res.inode_nr;
+  /* Remeber FS endpoint */
+  old_fs_e = vp_od->v_fs_e;
+
+  /* Save the last component of the old name */
+  len= strlen(user_fullpath);
+  if (len >= sizeof(old_name))
+  {
+       put_vnode(vp_od);
+       return ENAMETOOLONG;
+  }
+  memcpy(old_name, user_fullpath, len+1);
 
   /* See if 'name2' (new name) exists.  Get dir inode */
-  if (fetch_name(m_in.name2, m_in.name2_length, M1) != OK) r = err_code;
+  if (fetch_name(m_in.name2, m_in.name2_length, M1) != OK)
+  {
+       put_vnode(vp_od);
+       return err_code;
+  }
   
-  /* Fill in lookup request fields */
-  lookup_req.path = user_fullpath;
-  lookup_req.lastc = NULL;
-  lookup_req.flags = EAT_PATH_OPAQUE;
-        
   /* Request lookup */
-  r = lookup(&lookup_req, &res);
-  
-  /* If a directory file has to be removed the following conditions have to met:
-   *   - The directory must not be the root of a mounted file system
-   *   - The directory must not be anybody's root/working directory
-   */
-  if (r == OK && ((res.fmode & I_TYPE) == I_DIRECTORY)) {
-      /* Can't remove a root directory */
-      if (res.inode_nr == ROOT_INODE) return EBUSY;
-
-      /* Can't remove anybody's working directory */
-      if ((vp = find_vnode(res.fs_e, res.inode_nr)) != 
-              NIL_VNODE) {
-          /* Check directories */
-          for (rfp = &fproc[INIT_PROC_NR + 1]; rfp < &fproc[NR_PROCS]; 
-                  rfp++) {
-              if (rfp->fp_pid != PID_FREE && 
-                      (rfp->fp_wd == vp || rfp->fp_rd == vp))
-                  return(EBUSY); 
-          }
-      }
+  r = lookup_lastdir(0 /*!use_realuid*/, &vp_nd);
+  if (r != OK)
+  {
+       put_vnode(vp_od);
+       return r;
+  }
+
+  r= forbidden(vp_nd, W_BIT|X_BIT, 0 /*!use_realuid*/);
+  if (r != OK)
+  {
+       put_vnode(vp_od);
+       put_vnode(vp_nd);
+       return r;
   }
   
-  /* Fill in lookup request fields */
-  lookup_req.path = user_fullpath;
-  lookup_req.lastc = new_name;
-  lookup_req.flags = LAST_DIR;
-        
-  /* Request lookup */
-  if ((r = lookup(&lookup_req, &res)) != OK) return r;
   
-  /* Remeber inode number and FS endpoint */
-  new_fs_e = res.fs_e;
-  req.new_dir = res.inode_nr;
+  /* Remeber FS endpoint */
+  new_fs_e = vp_nd->v_fs_e;
   
   /* Both parent directories must be on the same device. */
-  if (old_fs_e != new_fs_e) return EXDEV;
-
-  /* Send actual rename request */
-  req.fs_e = old_fs_e;
-  req.uid = fp->fp_effuid;
-  req.gid = fp->fp_effgid;
-  req.old_name = &old_name[0];
-  req.new_name = &new_name[0];
+  if (old_fs_e != new_fs_e)
+  {
+       put_vnode(vp_od);
+       put_vnode(vp_nd);
+       return EXDEV;
+  }
+
   /* Issue request */
-  return req_rename(&req);
+  r= req_rename(old_fs_e, vp_od->v_inode_nr, old_name, vp_nd->v_inode_nr,
+       user_fullpath);
+  put_vnode(vp_od);
+  put_vnode(vp_nd);
+  return r;
 }
   
 
@@ -266,41 +222,20 @@ PUBLIC int do_truncate()
  * work.
  */
   struct vnode *vp;
-  struct trunc_req req;
-  struct lookup_req lookup_req;
-  struct node_details res;
   int r;
 
   printf("in do_truncate\n");
   
   if (fetch_name(m_in.m2_p1, m_in.m2_i1, M1) != OK) return err_code;
   
-  /* Fill in lookup request fields */
-  lookup_req.path = user_fullpath;
-  lookup_req.lastc = NULL;
-  lookup_req.flags = EAT_PATH;
-        
   /* Request lookup */
-  if ((r = lookup(&lookup_req, &res)) != OK) return r;
-  
-  /* Check whether the file is in use or not */
-  vp = find_vnode(res.fs_e, res.inode_nr);
-
-  /* Fill in request message fields.*/
-  req.fs_e = res.fs_e;
-  req.length = m_in.m2_l1;
-  req.inode_nr = res.inode_nr;
-  req.uid = fp->fp_effuid;
-  req.gid = fp->fp_effgid;
+  if ((r = lookup_vp(0 /*flags*/, 0 /*!use_realuid*/, &vp)) != OK) return r;
   
-  /* Issue request */
-  if ((r = req_trunc(&req)) != OK) return r;
-         
-  /* Change vnode's size if found */
-  if (vp != NIL_VNODE)
-         vp->v_size = m_in.m2_l1;
-  
-  return OK;
+  r= truncate_vn(vp, m_in.m2_l1);
+
+  put_vnode(vp);
+
+  return r;
 }
 
 
@@ -327,21 +262,14 @@ struct vnode *vp;
 off_t newsize;
 {
   int r;
-  struct ftrunc_req req;
 
   if ( (vp->v_mode & I_TYPE) != I_REGULAR &&
        (vp->v_mode & I_TYPE) != I_NAMED_PIPE) {
        return EINVAL;
   }
         
-  /* Fill in FS request */
-  req.fs_e = vp->v_fs_e; 
-  req.inode_nr = vp->v_inode_nr;
-  req.start = newsize;
-  req.end = 0;     /* Indicate trunc in fs_freesp_trunc */
-
   /* Issue request */
-  if ((r = req_ftrunc(&req)) != OK) return r;
+  if ((r = req_ftrunc(vp->v_fs_e, vp->v_inode_nr, newsize, 0)) != OK) return r;
          
   vp->v_size = newsize;
   return OK;
@@ -353,38 +281,40 @@ off_t newsize;
 PUBLIC int do_slink()
 {
 /* Perform the symlink(name1, name2) system call. */
-  char string[NAME_MAX];       /* last component of the new dir's path name */
-  struct slink_req req;
-  struct lookup_req lookup_req;
-  struct node_details res;
   int r;
+  struct vnode *vp;
+  char string[NAME_MAX];       /* last component of the new dir's path name */
 
   if (fetch_name(m_in.name2, m_in.name2_length, M1) != OK)
        return(err_code);
 
   if (m_in.name1_length <= 1 || m_in.name1_length >= _MIN_BLOCK_SIZE)
        return(ENAMETOOLONG);
-  
-  /* Fill in lookup request fields */
-  lookup_req.path = user_fullpath;
-  lookup_req.lastc = string;
-  lookup_req.flags = LAST_DIR;
-        
+
   /* Request lookup */
-  if ((r = lookup(&lookup_req, &res)) != OK) return r;
-
-  /* Fill in request message */
-  req.fs_e = res.fs_e;
-  req.parent_dir = res.inode_nr;
-  req.uid = fp->fp_effuid;
-  req.gid = fp->fp_effgid;
-  req.lastc = string;
-  req.who_e = who_e;
-  req.path_addr = m_in.name1;
-  req.path_length = m_in.name1_length - 1;
+  if ((r = lookup_lastdir(0 /*!use_realuid*/, &vp)) != OK)
+  {
+       printf("vfs:do_slink: lookup_lastdir failed with %d\n", r);
+       return r;
+  }
+
+  printf("vfs:do_slink: got dir inode %d on dev 0x%x, fs %d\n",
+       vp->v_inode_nr, vp->v_dev, vp->v_fs_e);
+
+  r= forbidden(vp, W_BIT|X_BIT, 0 /*!use_realuid*/);
+  if (r != OK)
+  {
+       put_vnode(vp);
+        return r;
+  }
 
   /* Issue request */
-  return req_slink(&req);
+  r= req_slink(vp->v_fs_e, vp->v_inode_nr, user_fullpath, who_e, m_in.name1, 
+       m_in.name1_length - 1, fp->fp_effuid, fp->fp_effgid);
+
+  put_vnode(vp);
+
+  return r;
 }
 
 /*===========================================================================*
@@ -393,36 +323,25 @@ PUBLIC int do_slink()
 PUBLIC int do_rdlink()
 {
 /* Perform the readlink(name, buf) system call. */
-  int copylen;
-  struct rdlink_req req;
-  struct lookup_req lookup_req;
-  struct node_details res;
-  int r;
+  int r, copylen;
+  struct vnode *vp;
   
   copylen = m_in.m1_i2;
   if(copylen < 0) return EINVAL;
 
   if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code);
   
-  /* Fill in lookup request fields */
-  lookup_req.path = user_fullpath;
-  lookup_req.lastc = NULL;
-  lookup_req.flags = EAT_PATH_OPAQUE;
-        
   /* Request lookup */
-  if ((r = lookup(&lookup_req, &res)) != OK) return r;
-  
-  /* Fill in request message */
-  req.fs_e = res.fs_e;
-  req.inode_nr = res.inode_nr;
-  req.uid = fp->fp_effuid;
-  req.gid = fp->fp_effgid;
-  req.who_e = who_e;
-  req.path_buffer = m_in.name2;
-  req.max_length = copylen;
+  r = lookup_vp(PATH_RET_SYMLINK, 0 /*!use_realuid*/, &vp);
+  if (r != OK) return r;
 
   /* Issue request */
-  return req_rdlink(&req);
+  r= req_rdlink(vp->v_fs_e, vp->v_inode_nr, who_e, (vir_bytes)m_in.name2,
+       copylen);
+
+  put_vnode(vp);
+
+  return r;
 }
 
 
index 47018444c12437727fc1d1e1c2618d3c1e7c4b76..2551472a7c635c8dbae2f040a7bd99de6adb8ffa 100644 (file)
@@ -66,6 +66,10 @@ PUBLIC int main()
        if (who_e == PM_PROC_NR && call_nr != PROC_EVENT)
                printf("FS: strange, got message %d from PM\n", call_nr);
 
+#if 0
+       printf("VFS: got call %d from %d\n", call_nr, who_e);
+#endif
+
        /* Check for special control messages first. */
         if ((call_nr & NOTIFY_MESSAGE)) {
                if (call_nr == PROC_EVENT)
@@ -103,6 +107,11 @@ PUBLIC int main()
                if (error != SUSPEND) reply(who_e, error);
                break;
 
+       case MAPDRIVER:
+               error= do_mapdriver();
+               if (error != SUSPEND) reply(who_e, error);
+               break;
+
        default:
                /* Call the internal function that does the work. */
                if (call_nr < 0 || call_nr >= NCALLS) { 
@@ -147,15 +156,21 @@ PRIVATE void get_work()
   /* Normally wait for new input.  However, if 'reviving' is
    * nonzero, a suspended process must be awakened.
    */
+  int r, found_one, fd_nr;
+  struct filp *f;
   register struct fproc *rp;
 
-  if (reviving != 0) {
+  while (reviving != 0) {
+       found_one= FALSE;
+
        /* Revive a suspended process. */
        for (rp = &fproc[0]; rp < &fproc[NR_PROCS]; rp++) 
                if (rp->fp_pid != PID_FREE && rp->fp_revived == REVIVING) {
+                       found_one= TRUE;
                        who_p = (int)(rp - fproc);
                        who_e = rp->fp_endpoint;
                        call_nr = rp->fp_fd & BYTE;
+
                        m_in.fd = (rp->fp_fd >>8) & BYTE;
                        m_in.buffer = rp->fp_buffer;
                        m_in.nbytes = rp->fp_nbytes;
@@ -166,9 +181,25 @@ PRIVATE void get_work()
                         * If it is, it'll 'leak' grants.
                         */
                        assert(!GRANT_VALID(rp->fp_grant));
+
+                       if (rp->fp_task == -XPIPE)
+                       {
+                               fp= rp;
+                               fd_nr= (rp->fp_fd >> 8);
+                               f= get_filp(fd_nr);
+                               assert(f != NULL);
+                               r= rw_pipe((call_nr == READ) ? READING :
+                                       WRITING, who_e, fd_nr, f,
+                                       rp->fp_buffer, rp->fp_nbytes);
+                               if (r != SUSPEND)
+                                       reply(who_e, r);
+                               continue;
+                       }
+
                        return;
                }
-       panic(__FILE__,"get_work couldn't revive anyone", NO_NUM);
+       if (!found_one)
+               panic(__FILE__,"get_work couldn't revive anyone", NO_NUM);
   }
 
   for(;;) {
@@ -207,6 +238,10 @@ int result;                        /* result of the call (usually OK or error #) */
 {
 /* Send a reply to a user process.  If the send fails, just ignore it. */
   int s;
+
+  if (call_nr == SYMLINK)
+       printf("vfs:reply: replying %d for call %d\n", result, call_nr);
+
   m_out.reply_type = result;
   s = send(whom, &m_out);
   if (s != OK) printf("VFS: couldn't send reply %d to %d: %d\n",
@@ -219,10 +254,11 @@ int result;                       /* result of the call (usually OK or error #) */
 PRIVATE void fs_init()
 {
 /* Initialize global variables, tables, etc. */
-  register struct inode *rip;
+  int s;
   register struct fproc *rfp;
+  struct vmnt *vmp;
+  struct vnode *root_vp;
   message mess;
-  int s;
 
   /* Clear endpoint field */
   last_login_fs_e = NONE;
@@ -273,13 +309,21 @@ PRIVATE void fs_init()
   init_root();                 /* init root device and load super block */
   init_select();               /* init select() structures */
 
+
+  vmp = &vmnt[0];              /* Should be the root filesystem */
+  if (vmp->m_dev == NO_DEV)
+       panic(__FILE__, "vfs:fs_init: no root filesystem", NO_NUM);
+  root_vp= vmp->m_root_node;
+
   /* The root device can now be accessed; set process directories. */
   for (rfp=&fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) {
        FD_ZERO(&(rfp->fp_filp_inuse));
        if (rfp->fp_pid != PID_FREE) {
                 
-                rfp->fp_rd = get_vnode_x(ROOT_FS_E, ROOT_INODE);
-                rfp->fp_wd = get_vnode_x(ROOT_FS_E, ROOT_INODE);
+               dup_vnode(root_vp);
+                rfp->fp_rd = root_vp;
+               dup_vnode(root_vp);
+                rfp->fp_wd = root_vp;
                
        } else  rfp->fp_endpoint = NONE;
   }
@@ -290,13 +334,13 @@ PRIVATE void fs_init()
  *===========================================================================*/
 PRIVATE void init_root()
 {
+  int r = OK;
   struct vmnt *vmp;
   struct vnode *root_node;
   struct dmap *dp;
+  char *label;
   message m;
-  int r = OK;
-  struct readsuper_req sreq;
-  struct readsuper_res sres;
+  struct node_details resX;
   
   /* Open the root device. */
   root_dev = DEV_IMGRD;
@@ -335,40 +379,31 @@ PRIVATE void init_root()
        panic(__FILE__,"No driver for root device", r);
   }
 
-  /* Open the device the file system lives on. */
-  if ((r = dev_open(root_dev, ROOT_FS_E, (R_BIT|W_BIT))) != OK) 
-       panic(__FILE__,"Cannot open root device", r);
-
+  label= dp->dmap_label;
+  if (strlen(label) == 0)
+  {
+       panic(__FILE__, "vfs:init_root: no label for major", root_dev >> MAJOR);
+  }
 
-  /* Request for reading superblock and root inode */
-  sreq.fs_e = ROOT_FS_E;
-  sreq.readonly = 0;
-  sreq.boottime = boottime;
-  sreq.driver_e = dp->dmap_driver;
-  sreq.dev = root_dev;
-  sreq.slink_storage = user_fullpath;
-  sreq.isroot = 1;
   /* Issue request */
-  if ((r = req_readsuper(&sreq, &sres)) != OK) {
-      dev_close(root_dev);
+  r = req_readsuper(ROOT_FS_E, label, root_dev, 0 /*!readonly*/,
+       1 /*isroot*/, &resX);
+  if (r != OK) {
       panic(__FILE__,"Cannot read superblock from root", r);
   }
   
   /* Fill in root node's fields */
-  root_node->v_fs_e = sres.fs_e;
-  root_node->v_inode_nr = sres.inode_nr;
-  root_node->v_mode = sres.fmode;
-  root_node->v_size = sres.fsize;
+  root_node->v_fs_e = resX.fs_e;
+  root_node->v_inode_nr = resX.inode_nr;
+  root_node->v_mode = resX.fmode;
+  root_node->v_size = resX.fsize;
   root_node->v_sdev = NO_DEV;
-  root_node->v_fs_count = 0;   /* Is this correct? */
+  root_node->v_fs_count = 1;
   root_node->v_ref_count = 1;
 
   /* Fill in max file size and blocksize for the vmnt */
-  vmp->m_fs_e = sres.fs_e;
+  vmp->m_fs_e = resX.fs_e;
   vmp->m_dev = root_dev;
-  vmp->m_block_size = sres.blocksize;
-  vmp->m_max_file_size = sres.maxsize;
   vmp->m_driver_e = dp->dmap_driver;
   vmp->m_flags = 0;
   
@@ -406,16 +441,6 @@ PRIVATE void service_pm()
                call= m.m_type;
                switch(call)
                {
-               case PM_STIME:
-                       boottime = m.PM_STIME_TIME;
-                       
-                        /* Send new time for all FS processes */
-                        for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; ++vmp) { 
-                            if (vmp->m_fs_e)
-                                req_stime(vmp->m_fs_e, boottime);
-                        }
-                       /* No need to report status to PM */
-                       break;
                case PM_SETSID:
                        pm_setsid(m.PM_SETSID_PROC);
 
index 4c586725dee5f73e7db19cfe99cdb52b4eca6f1a..240fd03fb4b5aea539c43a54f3dd7a17e4b0acfe 100644 (file)
@@ -159,7 +159,6 @@ PUBLIC int do_fcntl()
   long cloexec_mask;           /* bit map for the FD_CLOEXEC flag */
   long clo_value;              /* FD_CLOEXEC flag in proper position */
   struct filp *dummy;
-  struct ftrunc_req req;
 
   /* Is the file descriptor valid? */
   if ((f = get_filp(m_in.fd)) == NIL_FILP) {
@@ -258,14 +257,9 @@ PUBLIC int do_fcntl()
                 end = 0;
        }
   
-        /* Fill in FS request */
-        req.fs_e = f->filp_vno->v_fs_e; 
-        req.inode_nr = f->filp_vno->v_inode_nr;
-        req.start = start;
-        req.end = end;
-
         /* Issue request */
-        return req_ftrunc(&req);
+        return req_ftrunc(f->filp_vno->v_fs_e, f->filp_vno->v_inode_nr, 
+               start, end);
      }
 
      default:
index a7b0b983fb98e0c384bc5297dd795ceb4f218338..7a96ef1c99fdc772abdf31cbde70674a471c9c69 100644 (file)
@@ -95,19 +95,15 @@ PRIVATE int mount_fs(endpoint_t fs_e)
 {
 /* Perform the mount(name, mfile, rd_only) system call. */
   int rdir, mdir;               /* TRUE iff {root|mount} file is dir */
-  int i, r, found;
+  int i, r, found, isroot, replace_root;
   struct fproc *tfp;
   struct dmap *dp;
   dev_t dev;
   message m;
-  struct vnode *vp, *root_node, *mounted_on, *bspec;
+  struct vnode *vp, *root_node, *Xmounted_on, *bspec;
   struct vmnt *vmp, *vmp2;
-  struct mountpoint_req mreq;
-  struct node_details res;
-  struct readsuper_req sreq;
-  struct readsuper_res sres;
-  struct lookup_req lookup_req;
-  node_req_t node_req;
+  char *label;
+  struct node_details resX;
   
   /* Only the super-user may do MOUNT. */
   if (!super_user) return(EPERM);
@@ -128,15 +124,6 @@ PRIVATE int mount_fs(endpoint_t fs_e)
   /* If 'name' is not for a block special file, return error. */
   if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code);
   
-  /* Get free vnode for the mountpoint */
-  if ((mounted_on = get_free_vnode(__FILE__, __LINE__)) == NIL_VNODE) {
-        printf("VFSmount: not free vnode available\n");
-        return ENFILE;
-  }
-  
-  /* Mark it as used so that we won't find the same for the root_node */
-  mounted_on->v_ref_count = 1;
-  
   /* Convert name to device number */
   if ((dev = name_to_dev()) == NO_DEV) return(err_code);
 
@@ -175,84 +162,101 @@ PRIVATE int mount_fs(endpoint_t fs_e)
 
   /* Partition was/is already mounted */
   if (found) {
-      /* It is possible that we have an old root lying around that 
-       * needs to be remounted. */
-      if (vmp->m_mounted_on != vmp->m_root_node ||
-              vmp->m_mounted_on == fproc[FS_PROC_NR].fp_rd) {
-          /* Normally, m_mounted_on refers to the mount point. For a root
-           * filesystem, m_mounted_on is equal to the root vnode. We assume
-           * that the root of FS is always the real root. If the two
-           * vnodes are different or if the root of FS is equal two the
-           * root of the filesystem we found, we found a filesystem that
-           * is in use. */
-          mounted_on->v_ref_count = 0;
-          return EBUSY;   /* already mounted */
-      }
-
-      if (root_dev == vmp->m_dev)
-          panic("fs", "inconsistency remounting old root", NO_NUM);
-
-      /* Now get the inode of the file to be mounted on. */
-      if (fetch_name(m_in.name2, m_in.name2_length, M1) != OK) {
-          return(err_code);
-      }
-
-      /* Fill in lookup request fields */
-      lookup_req.path = user_fullpath;
-      lookup_req.lastc = NULL;
-      lookup_req.flags = EAT_PATH;
-
-      /* Request lookup */
-      if ((r = lookup(&lookup_req, &res)) != OK) return r;
-
-      /* Fill in request message fields.*/
-      mreq.fs_e = res.fs_e;
-      mreq.inode_nr = res.inode_nr;
-      mreq.uid = fp->fp_effuid;
-      mreq.gid = fp->fp_effgid;
-
-      /* Issue request */
-      if ((r = req_mountpoint(&mreq, &res)) != OK) return r;
-
-      mounted_on->v_fs_e = res.fs_e;  
-      mounted_on->v_inode_nr = res.inode_nr;
-      mounted_on->v_mode = res.fmode;
-      mounted_on->v_size = res.fsize;
-      mounted_on->v_sdev = NO_DEV;
-      mounted_on->v_fs_count = 1;
-      mounted_on->v_ref_count = 1;
-
-      /* Find the vmnt for the vnode */
-      if ( (vmp2 = find_vmnt(mounted_on->v_fs_e)) == NIL_VMNT)
-          printf("VFS: vmnt not found by mount()\n");
-      mounted_on->v_vmnt = vmp2; 
-      mounted_on->v_dev = vmp2->m_dev;  
-
-      /* Get the root inode of the mounted file system. */
-      root_node = vmp->m_root_node;
-
-      /* File types may not conflict. */
-      if (r == OK) {
-          mdir = ((mounted_on->v_mode & I_TYPE) == I_DIRECTORY); 
-          /* TRUE iff dir */
-          rdir = ((root_node->v_mode & I_TYPE) == I_DIRECTORY);
-          if (!mdir && rdir) r = EISDIR;
-      }
-
-      /* If error, return the mount point. */
-      if (r != OK) {
-          put_vnode(mounted_on);
+       /* It is possible that we have an old root lying around that 
+        * needs to be remounted. */
+       if (vmp->m_mounted_on != vmp->m_root_node ||
+               vmp->m_mounted_on == fproc[FS_PROC_NR].fp_rd) {
+               /* Normally, m_mounted_on refers to the mount point. For a
+                * root filesystem, m_mounted_on is equal to the root vnode.
+                * We assume that the root of FS is always the real root. If
+                * the two vnodes are different or if the root of FS is equal
+                * to the root of the filesystem we found, we found a
+                * filesystem that is in use.
+                */
+               return EBUSY;   /* already mounted */
+       }
+
+       if (root_dev == vmp->m_dev)
+               panic("fs", "inconsistency remounting old root", NO_NUM);
+
+       /* Now get the inode of the file to be mounted on. */
+       if (fetch_name(m_in.name2, m_in.name2_length, M1) != OK) {
+               return(err_code);
+       }
+
+       /* Request lookup */
+       r = lookup_vp(0 /*flags*/, 0 /*!use_realuid*/, &Xmounted_on);
+       if (r != OK) return r;
+
+       if (vp->v_ref_count != 1)
+       {
+               put_vnode(vp);
+               printf("vfs:mount_fs: mount point is busy\n");
+               return EBUSY;
+       }
+
+       /* Issue mountpoint request */
+       r = req_mountpoint(Xmounted_on->v_fs_e, Xmounted_on->v_inode_nr);
+       if (r != OK)
+       {
+               put_vnode(Xmounted_on);
+               printf("vfs:mount_fs: req_mountpoint_s failed with %d\n", r);
+               return r;
+       }
+
+       /* Get the root inode of the mounted file system. */
+       root_node = vmp->m_root_node;
+
+       /* File types may not conflict. */
+       if (r == OK) {
+               mdir = ((Xmounted_on->v_mode & I_TYPE) == I_DIRECTORY); 
+               /* TRUE iff dir */
+               rdir = ((root_node->v_mode & I_TYPE) == I_DIRECTORY);
+               if (!mdir && rdir) r = EISDIR;
+       }
+
+       /* If error, return the mount point. */
+       if (r != OK) {
+               put_vnode(Xmounted_on);
+
+               return(r);
+       }
+
+       /* Nothing else can go wrong.  Perform the mount. */
+       put_vnode(vmp->m_mounted_on);
+       vmp->m_mounted_on = Xmounted_on;
+       vmp->m_flags = m_in.rd_only;
+       allow_newroot = 0;              /* The root is now fixed */
+
+       return(OK);
+  }
 
-          return(r);
-      }
+  /* Fetch the name of the mountpoint */
+  if (fetch_name(m_in.name2, m_in.name2_length, M1) != OK) {
+       return(err_code);
+  }
 
-      /* Nothing else can go wrong.  Perform the mount. */
-      put_vnode(vmp->m_mounted_on);
-      vmp->m_mounted_on = mounted_on;
-      vmp->m_flags = m_in.rd_only;
-      allow_newroot = 0;              /* The root is now fixed */
+  isroot= (strcmp(user_fullpath, "/") == 0);
+  replace_root= (isroot && allow_newroot);
 
-      return(OK);
+  if (!replace_root)
+  {
+       /* Get mount point and inform the FS it is on. */
+#if 0
+       printf("vfs:mount_fs: mount point at '%s'\n", user_fullpath);
+#endif
+
+       r = lookup_vp(0 /*flags*/, 0 /*!use_realuid*/, &Xmounted_on);
+       if (r != OK)
+               return r;
+
+       /* Issue mountpoint request */
+       r = req_mountpoint(Xmounted_on->v_fs_e, Xmounted_on->v_inode_nr);
+       if (r != OK) {
+               put_vnode(Xmounted_on);
+               printf("vfs:mount_fs: req_mountpoint_s failed with %d\n", r);
+               return r;
+       }
   }
 
   /* We'll need a vnode for the root inode, check whether there is one */
@@ -261,13 +265,6 @@ PRIVATE int mount_fs(endpoint_t fs_e)
         return ENFILE;
   }
   
-  /* Set it back to zero so that if st goes wrong it won't be kept in use */
-  mounted_on->v_ref_count = 0;
-  
-  /* Fetch the name of the mountpoint */
-  if (fetch_name(m_in.name2, m_in.name2_length, M1) != OK) {
-        return(err_code);
-  }
 
   /* Get driver process' endpoint */  
   dp = &dmap[(dev >> MAJOR) & BYTE];
@@ -275,57 +272,35 @@ PRIVATE int mount_fs(endpoint_t fs_e)
         printf("VFSmount: no driver for dev %x\n", dev);
         return(EINVAL);
   }
-
-  /* Open the device the file system lives on. */
-  if (dev_open(dev, fs_e, m_in.rd_only ? R_BIT : (R_BIT|W_BIT)) != OK) {
-        return(EINVAL);
+  label= dp->dmap_label;
+  if (strlen(label) == 0)
+  {
+       panic(__FILE__, "vfs:mount_fs: no label for major", dev >> MAJOR);
   }
+#if 0
+  printf("vfs:mount_fs: label = '%s'\n", label);
+#endif
 
-  /* Request for reading superblock and root inode */
-  sreq.fs_e = fs_e;
-  sreq.readonly = m_in.rd_only;
-  sreq.boottime = boottime;
-  sreq.driver_e = dp->dmap_driver;
-  sreq.dev = dev;
-  sreq.slink_storage = user_fullpath;
-  
-  if (!strcmp(user_fullpath, "/")) sreq.isroot = 1;
-  else sreq.isroot = 0;
   /* Issue request */
-  if ((r = req_readsuper(&sreq, &sres)) != OK) {
-      dev_close(dev);
+  r = req_readsuper(fs_e, label, dev, m_in.rd_only, isroot, &resX);
+  if (r != OK) {
       return r;
   }
 
-  /* Fill in request message fields.*/
-  node_req.fs_e = sres.fs_e;
-  node_req.inode_nr = sres.inode_nr;
-
-  /* Issue request */
-  if ((r = req_getnode(&node_req, &res)) != OK)
-  {
-       printf("mount: req_getnode failed: %d\n", r);
-        dev_close(dev);
-       return r;
-  }
-  
   /* Fill in root node's fields */
-  root_node->v_fs_e = res.fs_e;
-  root_node->v_inode_nr = res.inode_nr;
-  root_node->v_mode = res.fmode;
-  root_node->v_uid = res.uid;
-  root_node->v_gid = res.gid;
-  root_node->v_size = res.fsize;
+  root_node->v_fs_e = resX.fs_e;
+  root_node->v_inode_nr = resX.inode_nr;
+  root_node->v_mode = resX.fmode;
+  root_node->v_uid = resX.uid;
+  root_node->v_gid = resX.gid;
+  root_node->v_size = resX.fsize;
   root_node->v_sdev = NO_DEV;
-  root_node->v_fs_count = 2;
+  root_node->v_fs_count = 1;
   root_node->v_ref_count = 1;
 
   /* Fill in max file size and blocksize for the vmnt */
-  vmp->m_fs_e = sres.fs_e;
+  vmp->m_fs_e = resX.fs_e;
   vmp->m_dev = dev;
-  vmp->m_block_size = sres.blocksize;
-  vmp->m_max_file_size = sres.maxsize;
   vmp->m_flags = m_in.rd_only;
   vmp->m_driver_e = dp->dmap_driver;
   
@@ -333,7 +308,7 @@ PRIVATE int mount_fs(endpoint_t fs_e)
   root_node->v_vmnt = vmp;
   root_node->v_dev = vmp->m_dev;
   
-  if (strcmp(user_fullpath, "/") == 0 && allow_newroot) {
+  if (replace_root) {
       printf("Replacing root\n");
 
       /* Superblock and root node already read. 
@@ -365,63 +340,24 @@ PRIVATE int mount_fs(endpoint_t fs_e)
       return(OK);
   }
 
-  /* Fill in lookup request fields */
-  lookup_req.path = user_fullpath;
-  lookup_req.lastc = NULL;
-  lookup_req.flags = EAT_PATH;
-
-  /* Request lookup */
-  if ((r = lookup(&lookup_req, &res)) != OK) {
-      put_vnode(root_node);
-      return r;
-  }
-
-  /* Fill in request fields.*/
-  mreq.fs_e = res.fs_e;
-  mreq.inode_nr = res.inode_nr;
-  mreq.uid = fp->fp_effuid;
-  mreq.gid = fp->fp_effgid;
-
-  /* Issue request */
-  if ((r = req_mountpoint(&mreq, &res)) != OK) {
-      put_vnode(root_node);
-      return r;
-  }
-  
-  /* Fill in vnode's fields */
-  mounted_on->v_fs_e = res.fs_e;  
-  mounted_on->v_inode_nr = res.inode_nr;
-  mounted_on->v_mode = res.fmode;
-  mounted_on->v_size = res.fsize;
-  mounted_on->v_sdev = NO_DEV;
-  mounted_on->v_fs_count = 1;
-  mounted_on->v_ref_count = 1;
-
-  /* Find the vmnt for the vnode */
-  if ( (vmp2 = find_vmnt(mounted_on->v_fs_e)) == NIL_VMNT)
-      printf("VFS: vmnt not found by mount()");
-  mounted_on->v_vmnt = vmp2; 
-  mounted_on->v_dev = vmp2->m_dev;
-
   /* File types may not conflict. */
   if (r == OK) {
-      mdir = ((mounted_on->v_mode & I_TYPE) == I_DIRECTORY);/* TRUE iff dir */
+      mdir = ((Xmounted_on->v_mode & I_TYPE) == I_DIRECTORY);/* TRUE iff dir */
       rdir = ((root_node->v_mode & I_TYPE) == I_DIRECTORY);
       if (!mdir && rdir) r = EISDIR;
   }
 
   /* If error, return the super block and both inodes; release the vmnt. */
   if (r != OK) {
-      put_vnode(mounted_on);
+      put_vnode(Xmounted_on);
       put_vnode(root_node);
 
       vmp->m_dev = NO_DEV;
-      dev_close(dev);
       return(r);
   }
 
   /* Nothing else can go wrong.  Perform the mount. */
-  vmp->m_mounted_on = mounted_on;
+  vmp->m_mounted_on = Xmounted_on;
   vmp->m_root_node = root_node;
 
   /* The root is now fixed */
@@ -500,9 +436,6 @@ Dev_t dev;
        panic(__FILE__, "unmount: strange fs endpoint", vmp->m_fs_e);
   if ((r = req_unmount(vmp->m_fs_e)) != OK) return r;
 
-  /* Close the device the file system lives on. */
-  dev_close(dev);
-
   /* Is there a block special file that was handled by that partition? */
   for (vp = &vnode[0]; vp < &vnode[NR_VNODES]; vp++) {
       if ((vp->v_mode & I_TYPE) == I_BLOCK_SPECIAL && 
@@ -519,7 +452,6 @@ Dev_t dev;
 
           printf("VFSunmount: moving block spec %d to root FS\n", dev);
           vp->v_bfs_e = ROOT_FS_E;
-          vp->v_blocksize = _MIN_BLOCK_SIZE;
 
           /* Send the driver endpoint (even if it is known already...) */
           if ((r = req_newdriver(vp->v_bfs_e, vp->v_sdev, dp->dmap_driver))
@@ -556,23 +488,22 @@ PRIVATE dev_t name_to_dev()
 {
 /* Convert the block special file 'path' to a device number.  If 'path'
  * is not a block special file, return error code in 'err_code'. */
-  struct lookup_req lookup_req;
-  struct node_details res;
   int r;
+  dev_t dev;
+  struct vnode *vp;
   
-  /* Fill in lookup request fields */
-  lookup_req.path = user_fullpath;
-  lookup_req.lastc = NULL;
-  lookup_req.flags = EAT_PATH;
-
   /* Request lookup */
-  if ((r = lookup(&lookup_req, &res)) != OK) return r;
+  if ((r = lookup_vp(0 /*flags*/, 0 /*!use_realuid*/, &vp)) != OK) return r;
 
-  if ((res.fmode & I_TYPE) != I_BLOCK_SPECIAL) {
+  if ((vp->v_mode & I_TYPE) != I_BLOCK_SPECIAL) {
        err_code = ENOTBLK;
-       return NO_DEV;
+       dev= NO_DEV;
   }
+  else
+       dev= vp->v_sdev;
+
+  put_vnode(vp);
   
-  return res.dev;
+  return dev;
 }
 
index a8c04b570bd2a8cd03dcdcea55baa17ae2744e58..eb381976f597e869ece5d9b4c5db6d88f2fbb87e 100644 (file)
 FORWARD _PROTOTYPE( int x_open, (int bits, int oflags, int omode,
                        char *lastc, struct vnode **vpp)                );
 FORWARD _PROTOTYPE( int common_open, (int oflags, mode_t omode)                );
+FORWARD _PROTOTYPE( int create_open, (_mnx_Mode_t omode,
+                               struct vnode **vpp, int *created)       );
+FORWARD _PROTOTYPE( int y_open, (struct vnode *vp, _mnx_Mode_t bits,
+       int oflags));
 FORWARD _PROTOTYPE( int pipe_open, (struct vnode *vp,mode_t bits,int oflags));
 
 /*===========================================================================*
@@ -83,21 +87,12 @@ PUBLIC int do_open()
 PRIVATE int common_open(register int oflags, mode_t omode)
 {
 /* Common code from do_creat and do_open. */
-  int r, b, found;
-  dev_t dev;
+  int b, m, r, created, found;
   mode_t bits;
-  off_t pos;
-  struct dmap *dp;
   struct filp *fil_ptr, *filp2;
-  struct vnode *vp, *vp2;
+  struct vnode *vp;
   struct vmnt *vmp;
-  char Xlastc[NAME_MAX];
-  char *pathrem;
-  int m;
-
-  /* Request and response structures */
-  struct lookup_req Xlookup_req;
-  struct open_req Xreq;
+  struct dmap *dp;
 
   /* Remap the bottom two bits of oflags. */
   m = oflags & O_ACCMODE;
@@ -116,114 +111,29 @@ PRIVATE int common_open(register int oflags, mode_t omode)
         omode = I_REGULAR | (omode & ALL_MODES & fp->fp_umask);
   }
 
-  vp= NULL;
-
-  /* Fill in lookup request fields */
-  Xlookup_req.path = user_fullpath;
-  Xlookup_req.lastc = Xlastc;
-  Xlookup_req.flags = oflags&O_CREAT ? (oflags&O_EXCL ? LAST_DIR : 
-              LAST_DIR_EATSYM) : EAT_PATH;
-  Xlookup_req.flags = ((oflags & (O_CREAT|O_EXCL)) == (O_CREAT|O_EXCL)) ?
-       LAST_DIR : EAT_PATH;
-  Xlastc[0]= '\0';     /* Clear lastc, it will be filled with the part of the
-                        * path that cannot be resolved.
-                        */
-  
-  /* Request lookup */
-  r = Xlookup_vp(&Xlookup_req, &vp, &pathrem);
-
-  if (r == OK && ((oflags & (O_CREAT|O_EXCL)) != (O_CREAT|O_EXCL)))
-  {
-       /* Clear lastc */
-       Xlastc[0]= '\0';
-  }
-
-  /* Hide ENOENT for O_CREAT */
-  if (r == ENOENT && (oflags & O_CREAT))
+  if (oflags & O_CREAT)
+       r= create_open(omode, &vp, &created);
+  else
   {
-       if (pathrem == NULL)
-               panic(__FILE__, "no pathrem", NO_NUM);
-
-       /* If any path remains, but no '/', O_CREAT can continue.
-        * If no path remains, a null filename was provided so ENOENT
-        * remains.
-        */
-       if(*pathrem) {
-          if (strchr(pathrem, '/') == 0)
-               r= OK;
 #if 0
-          else
-          {
-               printf("common_open: / in pathrem\n");
-          }
+       printf("vfs:common_open: path '%s'\n", user_fullpath);
 #endif
-       }
+       created= FALSE;
+       r= lookup_vp(0 /*flags*/, 0 /*!use_realuid*/, &vp);
   }
-
   if (r != OK)
-  {
-       if (vp)
-       {
-               put_vnode(vp);
-               vp= NULL;
-       }
        return r;
-  }
-
-  if (!vp) panic(__FILE__, "common_open: no vp", NO_NUM);
 
-  r= x_open(bits, oflags, omode, Xlastc, &vp);
-  if (r != OK)
+  if (!created)
   {
-       if (vp)
+       r= y_open(vp, bits, oflags);
+       if (r != OK)
        {
                put_vnode(vp);
-               vp= NULL;
+               return r;
        }
-       return r;
   }
 
-#if 0
-  /* Lookup was okay, fill in request fields for 
-   * the actual open request. */
-  req.inode_nr = res.inode_nr;
-  req.fs_e = res.fs_e;
-  req.oflags = oflags;
-  req.omode = omode;
-  req.lastc = lastc;
-  req.uid = fp->fp_effuid;
-  req.gid = fp->fp_effgid;
-
-  /* Issue request */
-  if ((r = req_open(&req, &res)) != OK) return r;
-  
-  /* Check whether the vnode is already in use */
-  if ((vp2 = find_vnode(res.fs_e, res.inode_nr)) != NIL_VNODE) {
-      vp = vp2;
-      vp->v_size = res.fsize; /* In case of trunc... */
-      vp->v_ref_count++;
-      vp->v_fs_count++;
-  }
-  /* Otherwise use the free one */
-  else {
-      vp->v_fs_e = res.fs_e;
-      if ( (vmp = find_vmnt(vp->v_fs_e)) == NIL_VMNT)
-          printf("VFS: vmnt not found by open()");
-      
-      vp->v_dev = vmp->m_dev;
-      vp->v_inode_nr = res.inode_nr;
-      vp->v_mode = res.fmode;
-      vp->v_uid = res.uid;
-      vp->v_gid = res.gid;
-      vp->v_size = res.fsize;
-      vp->v_sdev = res.dev; 
-      vp->v_fs_count = 1;
-      vp->v_ref_count = 1;
-      vp->v_vmnt = vmp; 
-      vp->v_index = res.inode_index;
-  }
-#endif
-
   /* Claim the file descriptor and filp slot and fill them in. */
   fp->fp_filp[m_in.fd] = fil_ptr;
   FD_SET(m_in.fd, &fp->fp_filp_inuse);
@@ -256,11 +166,9 @@ PRIVATE int common_open(register int oflags, mode_t omode)
          /* Who is going to be responsible for this device? */
          if (found) {
              vp->v_bfs_e = vmp->m_fs_e;
-             vp->v_blocksize - vmp->m_block_size;
          }
          else { /* To be handled in the root FS proc if not mounted */ 
              vp->v_bfs_e = ROOT_FS_E;
-             vp->v_blocksize = _MIN_BLOCK_SIZE;
          }
          
          /* Get the driver endpoint of the block spec device */
@@ -332,6 +240,186 @@ PRIVATE int common_open(register int oflags, mode_t omode)
   return(m_in.fd);
 }
 
+
+/*===========================================================================*
+ *                             create_open                                  *
+ *===========================================================================*/
+PRIVATE int create_open(omode, vpp, created)
+mode_t omode;
+struct vnode **vpp;
+int *created;
+{
+       int i, r, r1;
+       size_t len;
+       struct vnode *vp, *dir_vp, *new_vp, *start_vp;
+
+       struct node_details res;
+       char lastc[PATH_MAX+1];
+
+       start_vp = (user_fullpath[0] == '/' ? fp->fp_rd : fp->fp_wd);
+       dup_vnode(start_vp);
+
+       for (i= 0; i<SYMLOOP_MAX; i++)
+       {
+#if 0
+               printf("vfs:create_open: path #%d '%s'\n", i+1, user_fullpath);
+#endif
+               r= lookup_lastdir_rel(start_vp, 0 /*!use_realuid*/, &dir_vp);
+               put_vnode(start_vp);
+               if (r != OK)
+                       return r;
+
+               /* Save the last component of the path */
+               len= strlen(user_fullpath)+1;
+               if (len > sizeof(lastc))
+               {
+                       put_vnode(dir_vp);
+                       return ENAMETOOLONG;
+               }
+               memcpy(lastc, user_fullpath, len);
+
+               /* Get a free vnode */
+               new_vp = get_free_vnode(__FILE__, __LINE__);
+               if (new_vp == NIL_VNODE) {
+                       put_vnode(dir_vp);
+                       printf("vfs:create_open: no free vnode available\n");
+                       return EINVAL;
+               }
+
+               r= forbidden(dir_vp, W_BIT|X_BIT, 0 /*!use_realuid*/);
+               if (r == OK)
+               {
+                       /* Try to create the file */
+                       r= req_create(dir_vp->v_fs_e, dir_vp->v_inode_nr,
+                               omode, fp->fp_effuid, fp->fp_effgid, lastc,
+                               &res);
+               }
+
+               if (r != EEXIST && r != EACCES)
+               {
+                       put_vnode(dir_vp);
+
+                       if (r != OK)
+                               return r;
+
+                       /* Check whether vnode is already in use or not */
+                       vp = find_vnode(res.fs_e, res.inode_nr);
+                       if (vp != NIL_VNODE) {
+                               vp->v_ref_count++;
+                               vp->v_fs_count++;
+                       }
+                       else
+                       {
+                               vp= new_vp;
+
+                               /* Fill in the free vnode's fields */
+                               vp->v_fs_e = res.fs_e;
+                               vp->v_inode_nr = res.inode_nr;
+                               vp->v_mode = res.fmode;
+                               vp->v_size = res.fsize;
+                               vp->v_uid = res.uid;
+                               vp->v_gid = res.gid;
+                               vp->v_sdev = res.dev;
+
+                               vp->v_vmnt = dir_vp->v_vmnt; 
+                               vp->v_dev = vp->v_vmnt->m_dev;
+                               vp->v_fs_count = 1;
+                               vp->v_ref_count = 1;
+                       }
+
+                       *vpp= vp;
+                       *created= TRUE;
+
+                       return OK;
+                       
+               }
+
+               /* Try a regular lookup */
+               memcpy(user_fullpath, lastc, len);
+               r1= lookup_rel_vp(dir_vp, 0 /*flags*/, 0 /*!use_realuid*/, &vp);
+               if (r1 != ENOENT)
+               {
+                       put_vnode(dir_vp);
+                       if (r1 == OK)
+                       {
+                               *vpp= vp;
+                               *created= FALSE;
+                       }
+
+                       return r1;
+               }
+               if (r == EACCES)
+               {
+                       /* We cannot create a new file and the file does not
+                        * already exist.
+                        */
+                       put_vnode(dir_vp);
+                       return r;
+               }
+
+               /* The create failed with EEXIST and the regular lookup
+                * failed with ENOENT. We have to see whether the object
+                * we try to access actually exists, but is a symlink that 
+                * cannot be resolved. If the symlink exists, we start 
+                * with the contents of the symlink.
+                */
+               memcpy(user_fullpath, lastc, len);
+               r= lookup_rel_vp(dir_vp, PATH_RET_SYMLINK, 0 /*!use_realuid*/,
+                       &vp);
+               if (r != OK)
+               {
+                       put_vnode(dir_vp);
+                       return r;
+               }
+
+               if (!S_ISLNK(vp->v_mode))
+               {
+                       /* Strange, we got an object, but it is not a symlink.
+                        * Well, just return the object.
+                        */
+                       put_vnode(dir_vp);
+                       *vpp= vp;
+                       *created= FALSE;
+                       return OK;
+               }
+
+               /* Get the contents of the link */
+               len= sizeof(user_fullpath);
+               r= req_rdlink(vp->v_fs_e, vp->v_inode_nr, FS_PROC_NR, 
+                       (vir_bytes)user_fullpath, len-1);
+               put_vnode(vp);
+               if (r < 0)
+               {
+                       printf("vfs:create_open: req_rdlink failed with %d\n",
+                               r);
+                       put_vnode(dir_vp);
+                       return r;
+               }
+               if (r >= len)
+               {
+                       printf(
+                       "vfs:create_open: got bad length %d from req_rdlink\n",
+                               r);
+                       r= len-1;
+               }
+               user_fullpath[r]= '\0';
+
+               printf("got link target '%s'\n", user_fullpath);
+               if (user_fullpath[0] == '/')
+               {
+                       put_vnode(dir_vp);
+                       start_vp= fp->fp_rd;
+                       dup_vnode(start_vp);
+               }
+               else
+                       start_vp= dir_vp;
+       }
+
+       put_vnode(start_vp);
+       return ELOOP;
+}
+
+
 /*===========================================================================*
  *                             x_open                                       *
  *===========================================================================*/
@@ -381,7 +469,7 @@ struct vnode **vpp;
                vp->v_sdev = res.dev;
 
                if ( (vmp = find_vmnt(vp->v_fs_e)) == NIL_VMNT)
-               panic(__FILE__, "lookup_vp: vmnt not found", NO_NUM);
+                       panic(__FILE__, "x_open: vmnt not found", NO_NUM);
 
                vp->v_vmnt = vmp; 
                vp->v_dev = vmp->m_dev;
@@ -404,7 +492,7 @@ struct vnode **vpp;
        return OK;
 
   /* Check protections. */
-  if ((r = forbidden(vp, bits)) != OK)
+  if ((r = forbidden(vp, bits, 0 /*!use_realuid*/)) != OK)
        return r;
 
   /* Opening reg. files directories and special files differ. */
@@ -412,7 +500,7 @@ struct vnode **vpp;
   case I_REGULAR: 
        /* Truncate regular file if O_TRUNC. */
        if (oflags & O_TRUNC) {
-               if ((r = forbidden(vp, W_BIT)) !=OK) break;
+               if ((r = forbidden(vp, W_BIT, 0 /*!use_realuid*/)) !=OK) break;
                truncate_vn(vp, 0);
        }
        break;
@@ -449,6 +537,74 @@ struct vnode **vpp;
 }
 
 
+/*===========================================================================*
+ *                             y_open                                       *
+ *===========================================================================*/
+PRIVATE int y_open(vp, bits, oflags /*, omode, lastc, vpp */)
+struct vnode *vp;
+mode_t bits;
+int oflags;
+
+#if 0
+mode_t omode;
+char *lastc;
+struct vnode **vpp;
+#endif
+{
+  int r;
+#if 0
+  int r, b, exist = TRUE;
+  struct vnode *vp, *dvp, *tmp_vp;
+  struct vmnt *vmp;
+  struct node_details res;
+#endif
+
+  /* Check protections. */
+  if ((r = forbidden(vp, bits, 0 /*!use_realuid*/)) != OK)
+       return r;
+
+  /* Opening reg. files directories and special files differ. */
+  switch (vp->v_mode & I_TYPE) {
+  case I_REGULAR: 
+       /* Truncate regular file if O_TRUNC. */
+       if (oflags & O_TRUNC) {
+               if ((r = forbidden(vp, W_BIT, 0 /*!use_realuid*/)) !=OK) break;
+               truncate_vn(vp, 0);
+       }
+       break;
+
+  case I_DIRECTORY: 
+       /* Directories may be read but not written. */
+       r = (bits & W_BIT ? EISDIR : OK);
+       break;
+
+  case I_CHAR_SPECIAL:
+  case I_BLOCK_SPECIAL:
+       if (vp->v_sdev == (dev_t)-1)
+               panic(__FILE__, "y_open: bad special", NO_NUM);
+       break;
+
+  case I_NAMED_PIPE:
+       if (vp->v_ref_count == 1)
+       {
+               if (vp->v_size != 0)
+               {
+                       r= truncate_vn(vp, 0);
+                       if (r != OK)
+                       {
+                               printf(
+                               "x_open (fifo): truncate_vn failed: %d\n",
+                                       r);
+                       }
+               }
+       }
+       break;
+  }
+
+  return(r);
+}
+
+
 /*===========================================================================*
  *                             pipe_open                                    *
  *===========================================================================*/
@@ -492,11 +648,8 @@ PUBLIC int do_mknod()
 {
 /* Perform the mknod(name, mode, addr) system call. */
   register mode_t bits, mode_bits;
-  char lastc[NAME_MAX];         /* last component of the path */
-  struct mknod_req req;
-  struct lookup_req lookup_req;
-  struct node_details res;
   int r;
+  struct vnode *vp;
 
   /* Only the super_user may make nodes other than fifos. */
   mode_bits = (mode_t) m_in.mk_mode;           /* mode of the inode */
@@ -504,26 +657,21 @@ PUBLIC int do_mknod()
   if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code);
   bits = (mode_bits & I_TYPE) | (mode_bits & ALL_MODES & fp->fp_umask);
   
-  /* Fill in lookup request fields */
-  lookup_req.path = user_fullpath;
-  lookup_req.lastc = lastc;
-  lookup_req.flags = LAST_DIR;
-        
   /* Request lookup */
-  if ((r = lookup(&lookup_req, &res)) != OK) return r;
-
-  /* Lookup was okay, fill in request fields for the actual
-   * mknod request. */
-  req.fs_e = res.fs_e;
-  req.inode_nr = res.inode_nr;
-  req.rmode = bits;
-  req.dev = m_in.mk_z0;
-  req.lastc = lastc;
-  req.uid = fp->fp_effuid;
-  req.gid = fp->fp_effgid;
-                                          
+  if ((r = lookup_lastdir(0 /*!use_realuid*/, &vp)) != OK) return r;
+
+  r= forbidden(vp, W_BIT|X_BIT, 0 /*!use_realuid*/);
+  if (r != OK)
+  {
+       put_vnode(vp);
+       return r;
+  }
+
   /* Issue request */
-  return req_mknod(&req);
+  r= req_mknod(vp->v_fs_e, vp->v_inode_nr, user_fullpath,
+       fp->fp_effuid, fp->fp_effgid, bits, m_in.mk_z0);
+  put_vnode(vp);
+  return r;
 }
 
 
@@ -534,36 +682,29 @@ PUBLIC int do_mkdir()
 {
 /* Perform the mkdir(name, mode) system call. */
   mode_t bits;                 /* mode bits for the new inode */
-  char lastc[NAME_MAX];
-  struct mkdir_req req;
-  struct lookup_req lookup_req;
-  struct node_details res;
   int r;
+  struct vnode *vp;
 
 /*printf("VFS: mkdir() START:");*/
   if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code);
 
   bits = I_DIRECTORY | (m_in.mode & RWX_MODES & fp->fp_umask);
 
-  /* Fill in lookup request fields */
-  lookup_req.path = user_fullpath;
-  lookup_req.lastc = lastc;
-  lookup_req.flags = LAST_DIR;
-        
   /* Request lookup */
-  if ((r = lookup(&lookup_req, &res)) != OK) return r;
+  if ((r = lookup_lastdir(0 /*!use_realuid*/, &vp)) != OK) return r;
+
+  r= forbidden(vp, W_BIT|X_BIT, 0 /*!use_realuid*/);
+  if (r != OK)
+  {
+       put_vnode(vp);
+       return r;
+  }
   
-  /* Lookup was okay, fill in request message fields 
-   * for the actual mknod request. */
-  req.fs_e = res.fs_e;
-  req.d_inode_nr = res.inode_nr;
-  req.rmode = bits;
-  req.lastc = lastc;
-  req.uid = fp->fp_effuid;
-  req.gid = fp->fp_effgid;
-                                          
   /* Issue request */
-  return req_mkdir(&req);
+  r= req_mkdir(vp->v_fs_e, vp->v_inode_nr, user_fullpath,
+       fp->fp_effuid, fp->fp_effgid, bits);
+  put_vnode(vp);
+  return r;
 }
 
 
@@ -579,7 +720,6 @@ PUBLIC int do_lseek()
   int r;
   long offset;
   u64_t pos, newpos;
-  struct node_req req;
 
   /* Check to see if the file descriptor is valid. */
   if ( (rfilp = get_filp(m_in.ls_fd)) == NIL_FILP) return(err_code);
@@ -606,12 +746,8 @@ PUBLIC int do_lseek()
        return EINVAL;
 
   if (cmp64(newpos, rfilp->filp_pos) != 0) { /* Inhibit read ahead request */
-      /* Fill in request message */
-      req.fs_e = rfilp->filp_vno->v_fs_e;
-      req.inode_nr = rfilp->filp_vno->v_inode_nr;
-
-      /* Issue request */
-      if ((r = req_inhibread(&req)) != OK) return r;
+      r = req_inhibread(rfilp->filp_vno->v_fs_e, rfilp->filp_vno->v_inode_nr);
+      if (r != OK) return r;
   }
 
   rfilp->filp_pos = newpos;
@@ -631,7 +767,6 @@ PUBLIC int do_llseek()
 /* Perform the llseek(ls_fd, offset, whence) system call. */
   register struct filp *rfilp;
   u64_t pos, newpos;
-  struct node_req req;
   int r;
 
   /* Check to see if the file descriptor is valid. */
@@ -657,12 +792,8 @@ PUBLIC int do_llseek()
       return(EINVAL);
 
   if (cmp64(newpos, rfilp->filp_pos) != 0) { /* Inhibit read ahead request */
-      /* Fill in request message */
-      req.fs_e = rfilp->filp_vno->v_fs_e;
-      req.inode_nr = rfilp->filp_vno->v_inode_nr;
-
-      /* Issue request */
-      if ((r = req_inhibread(&req)) != OK) return r;
+      r = req_inhibread(rfilp->filp_vno->v_fs_e, rfilp->filp_vno->v_inode_nr);
+      if (r != OK) return r;
   }
 
   rfilp->filp_pos = newpos;
index a64ecab4383129d898fa0aacc46b03d800f96c02..66461a98ecedcc7bb449797a018117ba12e62742 100644 (file)
 #define pm_stime      m1_i1
 #define info_what     m1_i1
 #define info_where    m1_p1
+#define md_label       m2_p1
+#define md_label_len   m2_l1
+#define md_major       m2_i1
+#define md_style       m2_i2
+#define md_force       m2_i3
 
 /* The following names are synonyms for the variables in the output message. */
 #define reply_type    m_type
index f9db5d5c8ff6113a37237a2b9249ece284af3291..521a29b5dc6ba6b3ccc8418b848d74d9365fe154 100644 (file)
 #include "vnode.h"
 #include "param.h"
 
-FORWARD _PROTOTYPE( int Xlookup, (lookup_req_t *lookup_req,
-                               node_details_t *node, char **pathrem)   );
+FORWARD _PROTOTYPE( int lookup_rel, (struct vnode *start_node,
+               int flags, int use_realuid, node_details_t *node)       );
+
 
 /*===========================================================================*
- *                             lookup                                       *
+ *                             lookup_rel_vp                                *
  *===========================================================================*/
-PUBLIC int lookup(lookup_req, node)
-lookup_req_t *lookup_req;
-node_details_t *node;
+PUBLIC int lookup_rel_vp(start_node, flags, use_realuid, vpp)
+struct vnode *start_node;
+int flags;
+int use_realuid;
+struct vnode **vpp;
 {
+  /* Resolve a pathname (in user_fullpath) starting at start_node to a vnode. */
+  int r, lookup_res;
+  struct vnode *new_vp, *vp;
   struct vmnt *vmp;
-  struct vnode *start_node;
-  struct lookup_res res;
-  int r, symloop = 0;
-  int cum_path_processed = 0;
-  
-  /* Make a copy of the request so that the original values will be kept */ 
-  struct lookup_req req = *lookup_req; 
-  char *fullpath = lookup_req->path;
+  struct node_details res;
 
-  /* Empty (start) path? */
-  if (fullpath[0] == '\0') {
-      node->inode_nr = 0;
-      return ENOENT;
+  /* See if free vnode is available */
+  if ((new_vp = get_free_vnode(__FILE__, __LINE__)) == NIL_VNODE) {
+      printf("vfs:lookup_rel_vp: no free vnode available\n");
+      *vpp= NULL;
+      return EINVAL;
   }
 
-  /* Set user and group ids according to the system call */
-  req.uid = (call_nr == ACCESS ? fp->fp_realuid : fp->fp_effuid); 
-  req.gid = (call_nr == ACCESS ? fp->fp_realgid : fp->fp_effgid); 
+  lookup_res = lookup_rel(start_node, flags, use_realuid, &res);
 
-  /* Set the starting directories inode number and FS endpoint */
-  start_node = (fullpath[0] == '/' ? fp->fp_rd : fp->fp_wd);
-  req.start_dir = start_node->v_inode_nr;
-  req.fs_e = start_node->v_fs_e;
+  if (lookup_res != OK)
+  {
+#if 0
+       printf("vfs:lookup_rel_vp: lookup_rel failed with %d\n", lookup_res);
+#endif
+       return lookup_res;
+  }
 
-  /* Is the process' root directory on the same partition?,
-   * if so, set the chroot directory too. */
-  if (fp->fp_rd->v_dev == fp->fp_wd->v_dev)
-      req.root_dir = fp->fp_rd->v_inode_nr; 
-  else
-      req.root_dir = 0;
+  /* Check whether vnode is already in use or not */
+  if ((vp = find_vnode(res.fs_e, res.inode_nr)) != NIL_VNODE) {
+        vp->v_ref_count++;
+       vp->v_fs_count++;       /* We got a reference from the FS */
+       *vpp= vp;
+       return OK;
+  }
 
-  req.symloop = symloop;
+  /* Fill in the free vnode's fields */
+  new_vp->v_fs_e = res.fs_e;
+  new_vp->v_inode_nr = res.inode_nr;
+  new_vp->v_mode = res.fmode;
+  new_vp->v_size = res.fsize;
+  new_vp->v_uid = res.uid;
+  new_vp->v_gid = res.gid;
+  new_vp->v_sdev = res.dev;
+
+  if ( (vmp = find_vmnt(new_vp->v_fs_e)) == NIL_VMNT)
+       panic(__FILE__, "vfs:lookup_rel_vp: vmnt not found", NO_NUM);
+
+  new_vp->v_vmnt = vmp; 
+  new_vp->v_dev = vmp->m_dev;
+  new_vp->v_fs_count = 1;
+  new_vp->v_ref_count = 1;
+
+  *vpp= new_vp;
+  return OK;
+}
 
-  /* Issue the request */
-  r = req_lookup(&req, &res);
 
-  /* While the response is related to mount control set the 
-   * new requests respectively */
-  while (r == EENTERMOUNT || r == ELEAVEMOUNT || r == ESYMLINK) {
-      
-      /* If a symlink was encountered during the lookup the 
-       * new path has been copied back and the number of characters 
-       * processed has been started over. */
-      if (r == ESYMLINK || res.symloop > symloop) {
-          /* The link's content is copied back to the user_fullpath
-           * array. Use it as the path argument from now on... */
-          fullpath = user_fullpath;
-          cum_path_processed = res.char_processed;
-      }
-      else {
-          /* Otherwise, cumulate the characters already processsed from 
-           * the path */
-          cum_path_processed += res.char_processed;
-      }
-
-      /* Remember the current value of the symloop counter */
-      symloop = res.symloop;
-
-      /* Symlink encountered with absolute path */
-      if (r == ESYMLINK) {
-          start_node = fp->fp_rd;
-      }
-      /* Entering a new partition */
-      else if (r == EENTERMOUNT) {
-          start_node = 0;
-          /* Start node is now the mounted partition's root node */
-          for (vmp = &vmnt[0]; vmp != &vmnt[NR_MNTS]; ++vmp) {
-              if (vmp->m_mounted_on->v_inode_nr == res.inode_nr
-                      && vmp->m_mounted_on->v_fs_e == res.fs_e) {
-                  start_node = vmp->m_root_node;
-                  break;
-              }
-          }
-          if (!start_node) {
-              printf("VFSlookup: mounted partition couldn't be found\n");
-             printf("VFSlookup: res.inode_nr = %d, res.fs_e = %d\n",
-               res.inode_nr, res.fs_e);
-              return ENOENT;
-          }
-
-      }
-      /* Climbing up mount */
-      else {
-          /* Find the vmnt that represents the partition on
-           * which we "climb up". */
-          if ((vmp = find_vmnt(res.fs_e)) == NIL_VMNT) {
-              printf("VFS: couldn't find vmnt during the climbup!\n");
-              return ENOENT;
-          }      
-          /* Start node is the vnode on which the partition is
-           * mounted */
-          start_node = vmp->m_mounted_on;
-      }
-      /* Fill in the request fields */
-      req.start_dir = start_node->v_inode_nr;
-      req.fs_e = start_node->v_fs_e;
-
-      /* Is the process' root directory on the same partition?*/
-      if (start_node->v_dev == fp->fp_rd->v_dev)
-          req.root_dir = fp->fp_rd->v_inode_nr;
-      else
-          req.root_dir = 0;
-
-      /* Fill in the current path name */
-      req.path = &fullpath[cum_path_processed];
-      req.symloop = symloop;
-      
-      /* Issue the request */
-      r = req_lookup(&req, &res);
-  }
+/*===========================================================================*
+ *                             lookup_vp                                    *
+ *===========================================================================*/
+PUBLIC int lookup_vp(flags, use_realuid, vpp)
+int flags;
+int use_realuid;
+struct vnode **vpp;
+{
+  /* Resolve a pathname (in user_fullpath) starting to a vnode. Call
+   * lookup_rel_vp to do the actual work.
+   */
+  struct vnode *vp;
 
-  /* Fill in response fields */
-  node->inode_nr = res.inode_nr;
-  node->fmode = res.fmode;
-  node->fsize = res.fsize;
-  node->dev = res.dev;
-  node->fs_e = res.fs_e;
-  node->uid = res.uid;
-  node->gid = res.gid;
-  
-  return r;
+  vp= (user_fullpath[0] == '/' ? fp->fp_rd : fp->fp_wd);
+
+  return lookup_rel_vp(vp, flags, use_realuid, vpp);
 }
 
 
 /*===========================================================================*
- *                             Xlookup                                      *
+ *                             lookup_lastdir_rel                           *
  *===========================================================================*/
-PRIVATE int Xlookup(lookup_req, node, pathrem)
-lookup_req_t *lookup_req;
-node_details_t *node;
-char **pathrem;
+PUBLIC int lookup_lastdir_rel(start_node, use_realuid, vpp)
+struct vnode *start_node;
+int use_realuid;
+struct vnode **vpp;
 {
-  struct vmnt *vmp;
-  struct vnode *start_node;
-  struct lookup_res res;
-  int r, symloop = 0;
-  int cum_path_processed = 0;
+       /* This function is for calls that insert or delete entries from a
+        * directory. The path name (implicitly taken from user_fullpath)
+        * is split into to parts: the name of the directory and the
+        * directory entry. The name of the directory is resolved to a 
+        * vnode. The directory entry is copied back to user_fullpath.
+        * The lookup starts at start_node.
+        */
+       int r;
+       char *cp;
+       char dir_entry[PATH_MAX+1];
+
+       if (strlen(user_fullpath) == 0)
+       {
+               /* Empty path, always fail */
+               return ENOENT;
+       }
+
+       cp= strrchr(user_fullpath, '/');
+       if (cp == NULL)
+       {
+               /* Just one entry in the current working directory */
+               dup_vnode(start_node);
+               *vpp= start_node;
+
+               return OK;
+       }
+       else if (cp[1] == '\0')
+       {
+               /* Path ends in a slash. The directory entry is '.' */
+       }
+       else
+       {
+               /* A path name for the directory and a directory entry */
+               strcpy(dir_entry, cp+1);
+               cp[1]= '\0';
+       }
+
+       /* Remove trailing slashes */
+       while(cp > user_fullpath && cp[0] == '/')
+       {
+               cp[0]= '\0';
+               cp--;
+       }
+
+       /* Request lookup */
+       r = lookup_rel_vp(start_node, 0 /*no flags*/, use_realuid, vpp);
+       if (r != OK)
+               return r;
+
+       /* Copy the directory entry back to user_fullpath */
+       strcpy(user_fullpath, dir_entry);
+
+       return OK;
+}
+
 
-  /* Make a copy of the request so that the original values will be kept */ 
-  struct lookup_req req = *lookup_req; 
-  char *fullpath = lookup_req->path;
+/*===========================================================================*
+ *                             lookup_lastdir                               *
+ *===========================================================================*/
+PUBLIC int lookup_lastdir(use_realuid, vpp)
+int use_realuid;
+struct vnode **vpp;
+{
+       /* This function is for calls that insert or delete entries from a
+        * directory. The path name (implicitly taken from user_fullpath)
+        * is split into to parts: the name of the directory and the
+        * directory entry. The name of the directory is resolved to a 
+        * vnode. The directory entry is copied back to user_fullpath.
+        * Just call lookup_lastdir_rel with the appropriate starting vnode.
+        */
+       struct vnode *vp;
+
+       vp= (user_fullpath[0] == '/' ? fp->fp_rd : fp->fp_wd);
+       return lookup_lastdir_rel(vp, use_realuid, vpp);
+}
 
-  /* Clear pathrem */
-  *pathrem= NULL;
 
+/*===========================================================================*
+ *                             lookup_rel                                   *
+ *===========================================================================*/
+PRIVATE int lookup_rel(start_node, flags, use_realuid, node)
+struct vnode *start_node;
+int flags;
+int use_realuid;
+node_details_t *node;
+{
+  /* Resolve a pathname (in user_fullpath) relative to start_node. */
+  int r, symloop;
+  endpoint_t fs_e;
+  size_t path_off;
+  ino_t dir_ino, root_ino;
+  uid_t uid;
+  gid_t gid;
+  struct vnode *dir_vp;
+  struct vmnt *vmp;
+  struct lookup_res res;
+  
   /* Empty (start) path? */
-  if (fullpath[0] == '\0') {
-      node->inode_nr = 0;
-      *pathrem = fullpath;
-      return ENOENT;
+  if (user_fullpath[0] == '\0') {
+       node->inode_nr = 0;
+       printf("vfs:lookup_rel: returning ENOENT\n");
+       return ENOENT;
   }
 
-  /* Set user and group ids according to the system call */
-  req.uid = (call_nr == ACCESS ? fp->fp_realuid : fp->fp_effuid); 
-  req.gid = (call_nr == ACCESS ? fp->fp_realgid : fp->fp_effgid); 
-
-  /* Set the starting directories inode number and FS endpoint */
-  start_node = (fullpath[0] == '/' ? fp->fp_rd : fp->fp_wd);
-  req.start_dir = start_node->v_inode_nr;
-  req.fs_e = start_node->v_fs_e;
-
+  fs_e = start_node->v_fs_e;
+  path_off = 0;
+  dir_ino = start_node->v_inode_nr;
   /* Is the process' root directory on the same partition?,
    * if so, set the chroot directory too. */
   if (fp->fp_rd->v_dev == fp->fp_wd->v_dev)
-      req.root_dir = fp->fp_rd->v_inode_nr; 
+      root_ino = fp->fp_rd->v_inode_nr; 
   else
-      req.root_dir = 0;
+      root_ino = 0;
 
-  req.symloop = symloop;
+  /* Set user and group ids according to the system call */
+  uid = (use_realuid ? fp->fp_realuid : fp->fp_effuid); 
+  gid = (use_realuid ? fp->fp_realgid : fp->fp_effgid); 
+
+  symloop= 0;  /* Number of symlinks seen so far */
 
   /* Issue the request */
-  r = req_lookup(&req, &res);
+  r = req_lookup(fs_e, path_off, dir_ino, root_ino, uid, gid, flags, &res);
+
+  if (r != OK && r != EENTERMOUNT && r != ELEAVEMOUNT && r != ESYMLINK)
+  {
+#if 0
+       printf("vfs:lookup_rel: req_lookup_s failed with %d\n", r);
+#endif
+       return r;
+  }
 
   /* While the response is related to mount control set the 
    * new requests respectively */
   while (r == EENTERMOUNT || r == ELEAVEMOUNT || r == ESYMLINK) {
-      
-      /* If a symlink was encountered during the lookup the 
-       * new path has been copied back and the number of characters 
-       * processed has been started over. */
-      if (r == ESYMLINK || res.symloop > symloop) {
-          /* The link's content is copied back to the user_fullpath
-           * array. Use it as the path argument from now on... */
-          fullpath = user_fullpath;
-          cum_path_processed = res.char_processed;
-      }
-      else {
-          /* Otherwise, cumulate the characters already processsed from 
-           * the path */
-          cum_path_processed += res.char_processed;
-      }
-
-      /* Remember the current value of the symloop counter */
-      symloop = res.symloop;
-
-      /* Symlink encountered with absolute path */
-      if (r == ESYMLINK) {
-          start_node = fp->fp_rd;
-      }
-      /* Entering a new partition */
-      else if (r == EENTERMOUNT) {
-          start_node = 0;
-          /* Start node is now the mounted partition's root node */
-          for (vmp = &vmnt[0]; vmp != &vmnt[NR_MNTS]; ++vmp) {
-              if (vmp->m_mounted_on->v_inode_nr == res.inode_nr
-                      && vmp->m_mounted_on->v_fs_e == res.fs_e) {
-                  start_node = vmp->m_root_node;
-                  break;
-              }
-          }
-          if (!start_node) {
-              printf("VFSlookup: mounted partition couldn't be found\n");
-             printf("VFSlookup: res.inode_nr = %d, res.fs_e = %d\n",
-               res.inode_nr, res.fs_e);
-              return ENOENT;
-          }
-
-      }
-      /* Climbing up mount */
-      else {
-          /* Find the vmnt that represents the partition on
-           * which we "climb up". */
-          if ((vmp = find_vmnt(res.fs_e)) == NIL_VMNT) {
-              printf("VFS: couldn't find vmnt during the climbup!\n");
-              return ENOENT;
-          }      
-          /* Start node is the vnode on which the partition is
-           * mounted */
-          start_node = vmp->m_mounted_on;
-      }
-      /* Fill in the request fields */
-      req.start_dir = start_node->v_inode_nr;
-      req.fs_e = start_node->v_fs_e;
-
-      /* Is the process' root directory on the same partition?*/
-      if (start_node->v_dev == fp->fp_rd->v_dev)
-          req.root_dir = fp->fp_rd->v_inode_nr;
-      else
-          req.root_dir = 0;
-
-      /* Fill in the current path name */
-      req.path = &fullpath[cum_path_processed];
-      req.symloop = symloop;
-      
-      /* Issue the request */
-      r = req_lookup(&req, &res);
-  }
-
-  if (r == ENOENT)
-  {
-        cum_path_processed += res.char_processed;
-       *pathrem= &fullpath[cum_path_processed];
+       /* Save the place in the (possibly updated) path where we have to
+        * continue witht henext lookup request.
+        */
+       path_off= res.char_processed;
+
+       /* Update the current value of the symloop counter */
+       symloop += res.symloop;
+       if (symloop > SYMLOOP_MAX)
+       {
+               printf("vfs:lookup_rel: returning ELOOP\n");
+               return ELOOP;
+       }
+
+       /* Symlink encountered with absolute path */
+       if (r == ESYMLINK) {
+               dir_vp = fp->fp_rd;
+       }
+       else if (r == EENTERMOUNT) {
+               /* Entering a new partition */
+               dir_vp = 0;
+               /* Start node is now the mounted partition's root node */
+               for (vmp = &vmnt[0]; vmp != &vmnt[NR_MNTS]; ++vmp) {
+                       if (vmp->m_mounted_on->v_inode_nr == res.inode_nr &&
+                               vmp->m_mounted_on->v_fs_e == res.fs_e) {
+                               dir_vp = vmp->m_root_node;
+                               break;
+                       }
+               }
+               if (!dir_vp) {
+                       printf(
+                       "vfs:lookup_rel: res.inode_nr = %d, res.fs_e = %d\n",
+                               res.inode_nr, res.fs_e);
+                       panic(__FILE__,
+                       "vfs:lookup_s: mounted partition couldn't be found",
+                               NO_NUM);
+               }
+
+       }
+       else {
+               /* Climbing up mount */
+               /* Find the vmnt that represents the partition on
+                * which we "climb up". */
+               if ((vmp = find_vmnt(res.fs_e)) == NIL_VMNT) {
+                       panic(__FILE__,
+                       "vfs:lookup_s: couldn't find vmnt during the climbup",
+                               NO_NUM);
+               }         
+               /* Start node is the vnode on which the partition is
+                * mounted */
+               dir_vp = vmp->m_mounted_on;
+       }
+
+       /* Set the starting directories inode number and FS endpoint */
+       fs_e = dir_vp->v_fs_e;
+       dir_ino = dir_vp->v_inode_nr;
+       /* Is the process' root directory on the same partition?,
+        * if so, set the chroot directory too. */
+       if (fp->fp_rd->v_dev == fp->fp_wd->v_dev)
+               root_ino = fp->fp_rd->v_inode_nr; 
+       else
+               root_ino = 0;
+
+       /* Issue the request */
+       r = req_lookup(fs_e, path_off, dir_ino, root_ino, uid, gid, flags,
+               &res);
+
+       if (r != OK && r != EENTERMOUNT && r != ELEAVEMOUNT && r != ESYMLINK)
+       {
+#if 0
+               printf("vfs:lookup_rel: req_lookup_s failed with %d\n", r);
+#endif
+               return r;
+       }
   }
 
   /* Fill in response fields */
@@ -297,152 +334,3 @@ char **pathrem;
   
   return r;
 }
-
-
-/*===========================================================================*
- *                             lookup_vp                                    *
- *===========================================================================*/
-PUBLIC int lookup_vp(lookup_req, vpp)
-lookup_req_t *lookup_req;
-struct vnode **vpp;
-{
-  int r, lookup_res;
-  struct vnode *vp;
-  struct vmnt *vmp;
-  node_req_t node_req;
-  struct node_details res;
-
-  lookup_res = lookup(lookup_req, &res);
-
-  if (res.inode_nr == 0)
-  {
-#if 0
-       printf("lookup_vp: lookup returned no inode\n");
-       printf("lookup_res = %d, last = '%s'\n\n",
-               lookup_res, lookup_req->lastc);
-#endif
-       *vpp= NULL;
-       return lookup_res;
-  }
-
-  /* Check whether vnode is already in use or not */
-  if ((vp = find_vnode(res.fs_e, res.inode_nr)) != NIL_VNODE) {
-        vp->v_ref_count++;
-       *vpp= vp;
-       return lookup_res;
-  }
-
-  /* See if free vnode is available */
-  if ((vp = get_free_vnode(__FILE__, __LINE__)) == NIL_VNODE) {
-      printf("VFS lookup_vp: no free vnode available\n");
-      *vpp= NULL;
-      return EINVAL;
-  }
-
-  /* Fill in request message fields.*/
-  node_req.fs_e = res.fs_e;
-  node_req.inode_nr = res.inode_nr;
-
-  /* Issue request */
-  if ((r = req_getnode(&node_req, &res)) != OK)
-  {
-       printf("lookup_vp: req_getnode failed: %d\n", r);
-       *vpp= NULL;
-       return r;
-  }
-  
-  /* Fill in the free vnode's fields */
-  vp->v_fs_e = res.fs_e;
-  vp->v_inode_nr = res.inode_nr;
-  vp->v_mode = res.fmode;
-  vp->v_size = res.fsize;
-  vp->v_uid = res.uid;
-  vp->v_gid = res.gid;
-  vp->v_sdev = res.dev;
-
-  if ( (vmp = find_vmnt(vp->v_fs_e)) == NIL_VMNT)
-       panic(__FILE__, "lookup_vp: vmnt not found", NO_NUM);
-
-  vp->v_vmnt = vmp; 
-  vp->v_dev = vmp->m_dev;
-  vp->v_fs_count = 1;
-  vp->v_ref_count = 1;
-
-  *vpp= vp;
-  return lookup_res;
-}
-
-/*===========================================================================*
- *                             Xlookup_vp                                   *
- *===========================================================================*/
-PUBLIC int Xlookup_vp(lookup_req, vpp, pathrem)
-lookup_req_t *lookup_req;
-struct vnode **vpp;
-char **pathrem;
-{
-  int r, lookup_res;
-  struct vnode *vp;
-  struct vmnt *vmp;
-  node_req_t node_req;
-  struct node_details res;
-
-  lookup_res = Xlookup(lookup_req, &res, pathrem);
-
-  if (res.inode_nr == 0)
-  {
-#if 0
-       printf("Xlookup_vp: lookup returned no inode\n");
-       printf("lookup_res = %d, last = '%s'\n\n",
-               lookup_res, lookup_req->lastc);
-#endif
-       *vpp= NULL;
-       return lookup_res;
-  }
-
-  /* Check whether vnode is already in use or not */
-  if ((vp = find_vnode(res.fs_e, res.inode_nr)) != NIL_VNODE) {
-        vp->v_ref_count++;
-       *vpp= vp;
-       return lookup_res;
-  }
-
-  /* See if free vnode is available */
-  if ((vp = get_free_vnode(__FILE__, __LINE__)) == NIL_VNODE) {
-      printf("VFS Xlookup_vp: no free vnode available\n");
-      *vpp= NULL;
-      return EINVAL;
-  }
-
-  /* Fill in request message fields.*/
-  node_req.fs_e = res.fs_e;
-  node_req.inode_nr = res.inode_nr;
-
-  /* Issue request */
-  if ((r = req_getnode(&node_req, &res)) != OK)
-  {
-       printf("Xlookup_vp: req_getnode failed: %d\n", r);
-       *vpp= NULL;
-       return r;
-  }
-  
-  /* Fill in the free vnode's fields */
-  vp->v_fs_e = res.fs_e;
-  vp->v_inode_nr = res.inode_nr;
-  vp->v_mode = res.fmode;
-  vp->v_size = res.fsize;
-  vp->v_uid = res.uid;
-  vp->v_gid = res.gid;
-  vp->v_sdev = res.dev;
-
-  if ( (vmp = find_vmnt(vp->v_fs_e)) == NIL_VMNT)
-       panic(__FILE__, "Xlookup_vp: vmnt not found", NO_NUM);
-
-  vp->v_vmnt = vmp; 
-  vp->v_dev = vmp->m_dev;
-  vp->v_fs_count = 1;
-  vp->v_ref_count = 1;
-
-  *vpp= vp;
-  return lookup_res;
-}
-
index 0dddab50b172b17e1afb139159a0387afd00ff17..a3f4ec3e4c377c7faad87f95595c47760fd22026 100644 (file)
@@ -51,11 +51,8 @@ PUBLIC int do_pipe()
   int r;
   struct filp *fil_ptr0, *fil_ptr1;
   int fil_des[2];              /* reply goes here */
-
   struct vnode *vp;
   struct vmnt *vmp;
-
-  struct pipe_req req;
   struct node_details res;
 
   /* See if a free vnode is available */
@@ -80,13 +77,9 @@ PUBLIC int do_pipe()
   FD_SET(fil_des[1], &rfp->fp_filp_inuse);
   fil_ptr1->filp_count = 1;
 
-  /* Fill in FS request */
-  req.fs_e = ROOT_FS_E;
-  req.uid = fp->fp_effuid;
-  req.gid = fp->fp_effgid;
-
   /* Send request */
-  r = req_pipe(&req, &res);
+  r = req_newnode(ROOT_FS_E, fp->fp_effuid, fp->fp_effgid, I_NAMED_PIPE,
+       (dev_t)0, &res);
 
   /* Handle error */
   if (r != OK) {
@@ -105,8 +98,8 @@ PUBLIC int do_pipe()
   vp->v_mode = res.fmode;
   vp->v_index = res.inode_index;
   vp->v_pipe = I_PIPE;
-  vp->v_fs_count = 2;           /* Double usage */
-  vp->v_ref_count = 2;          /* Double usage */
+  vp->v_fs_count = 1;
+  vp->v_ref_count = 1;
   vp->v_size = 0;
 
   if ( (vmp = find_vmnt(vp->v_fs_e)) == NIL_VMNT) {
@@ -120,6 +113,7 @@ PUBLIC int do_pipe()
 
   /* Fill in filp objects */
   fil_ptr0->filp_vno = vp;
+  dup_vnode(vp);
   fil_ptr1->filp_vno = vp;
   fil_ptr0->filp_flags = O_RDONLY;
   fil_ptr1->filp_flags = O_WRONLY;
@@ -133,13 +127,12 @@ PUBLIC int do_pipe()
 /*===========================================================================*
  *                             pipe_check                                   *
  *===========================================================================*/
-PUBLIC int pipe_check(vp, rw_flag, oflags, bytes, position, canwrite, notouch)
+PUBLIC int Xpipe_check(vp, rw_flag, oflags, bytes, position, notouch)
 register struct vnode *vp;     /* the inode of the pipe */
 int rw_flag;                   /* READING or WRITING */
 int oflags;                    /* flags set by open or fcntl */
 register int bytes;            /* bytes to be read or written (all chunks) */
 u64_t position;                        /* current file position */
-int *canwrite;                 /* return: number of bytes we can write */
 int notouch;                   /* check only */
 {
 /* Pipes are a little different.  If a process reads from an empty pipe for
@@ -163,8 +156,6 @@ int notouch;                        /* check only */
                        if (oflags & O_NONBLOCK) {
                                r = EAGAIN;
                        } else {
-                               if (!notouch)
-                                       suspend(XPIPE); /* block reader */
                                r = SUSPEND;
                        }
                        /* If need be, activate sleeping writers. */
@@ -173,56 +164,65 @@ int notouch;                      /* check only */
                }
                return(r);
        }
-  } else {
-       /* Process is writing to a pipe. */
-       if (find_filp(vp, R_BIT) == NIL_FILP) {
-               /* Tell kernel to generate a SIGPIPE signal. */
-               if (!notouch) {
-                       sys_kill(fp->fp_endpoint, SIGPIPE);
-               }
-               return(EPIPE);
+
+       return bytes;
+  }
+
+  /* Process is writing to a pipe. */
+  if (find_filp(vp, R_BIT) == NIL_FILP) {
+       /* Tell kernel to generate a SIGPIPE signal. */
+       if (!notouch) {
+               sys_kill(fp->fp_endpoint, SIGPIPE);
        }
+       return(EPIPE);
+  }
 
-       if (pos + bytes > PIPE_SIZE(vp->v_vmnt->m_block_size)) {
-               if ((oflags & O_NONBLOCK)
-                && bytes <= PIPE_SIZE(vp->v_vmnt->m_block_size)) {
+  if (pos + bytes > PIPE_BUF) {
+       if (oflags & O_NONBLOCK)
+       {
+               if (bytes <= PIPE_BUF) {
+                       /* Write has to be atomic */
                        return(EAGAIN);
                }
-               else if ((oflags & O_NONBLOCK)
-               && bytes > PIPE_SIZE(vp->v_vmnt->m_block_size)) {
-               if ( (*canwrite = (PIPE_SIZE(vp->v_vmnt->m_block_size) 
-                       - pos)) > 0)  {
-                               /* Do a partial write. Need to wakeup reader */
-                               if (!notouch)
-                                       release(vp, READ, susp_count);
-                               return(1);
-                       } else {
-                               return(EAGAIN);
-                       }
-                    }
-               if (bytes > PIPE_SIZE(vp->v_vmnt->m_block_size)) {
-                       if ((*canwrite = PIPE_SIZE(vp->v_vmnt->m_block_size) 
-                               - pos) > 0) {
-                               /* Do a partial write. Need to wakeup reader
-                                * since we'll suspend ourself in read_write()
-                                */
-                               if (!notouch)
-                                       release(vp, READ, susp_count);
-                               return(1);
-                       }
+
+               /* Compute available space */
+               bytes= PIPE_BUF-pos;
+
+               if (bytes > 0)  {
+                       /* Do a partial write. Need to wakeup reader */
+                       if (!notouch)
+                               release(vp, READ, susp_count);
+                       return(bytes);
+               } else {
+                       /* Pipe is full */
+                       return(EAGAIN);
+               }
+       }
+
+       if (bytes > PIPE_BUF) {
+               /* Compute available space */
+               bytes= PIPE_BUF-pos;
+
+               if (bytes > 0) {
+                       /* Do a partial write. Need to wakeup reader
+                        * since we'll suspend ourself in read_write()
+                        */
+                       if (!notouch)
+                               release(vp, READ, susp_count);
+                       return(bytes);
                }
-               if (!notouch)
-                       suspend(XPIPE); /* stop writer -- pipe full */
-               return(SUSPEND);
        }
 
-       /* Writing to an empty pipe.  Search for suspended reader. */
-       if (pos == 0 && !notouch)
-               release(vp, READ, susp_count);
+       /* Pipe is full, or we need an atomic write */
+       return(SUSPEND);
   }
 
-  *canwrite = 0;
-  return(1);
+  /* Writing to an empty pipe.  Search for suspended reader. */
+  if (pos == 0 && !notouch)
+       release(vp, READ, susp_count);
+
+  /* Requested amount fits */
+  return bytes;
 }
 
 /*===========================================================================*
@@ -238,7 +238,10 @@ int task;                  /* who is proc waiting for? (PIPE = pipe) */
  * The SUSPEND pseudo error should be returned after calling suspend().
  */
 
-  if (task == XPIPE || task == XPOPEN) susp_count++;/* #procs susp'ed on pipe*/
+  if (task == XPIPE)
+       panic(__FILE__, "suspend: called for XPIPE", NO_NUM);
+
+  if (task == XPOPEN) susp_count++;/* #procs susp'ed on pipe*/
   fp->fp_suspended = SUSPENDED;
   assert(!GRANT_VALID(fp->fp_grant));
   fp->fp_fd = m_in.fd << 8 | call_nr;
@@ -254,6 +257,31 @@ int task;                  /* who is proc waiting for? (PIPE = pipe) */
   }
 }
 
+/*===========================================================================*
+ *                             pipe_suspend                                         *
+ *===========================================================================*/
+PUBLIC void pipe_suspend(rw_flag, fd_nr, buf, size)
+int rw_flag;
+int fd_nr;
+char *buf;
+size_t size;
+{
+/* Take measures to suspend the processing of the present system call.
+ * Store the parameters to be used upon resuming in the process table.
+ * (Actually they are not used when a process is waiting for an I/O device,
+ * but they are needed for pipes, and it is not worth making the distinction.)
+ * The SUSPEND pseudo error should be returned after calling suspend().
+ */
+
+  susp_count++;                                        /* #procs susp'ed on pipe*/
+  fp->fp_suspended = SUSPENDED;
+  assert(!GRANT_VALID(fp->fp_grant));
+  fp->fp_fd = (fd_nr << 8) | ((rw_flag == READING) ? READ : WRITE);
+  fp->fp_task = -XPIPE;
+  fp->fp_buffer = buf;         
+  fp->fp_nbytes = size;
+}
+
 /*===========================================================================*
  *                             unsuspend_by_endpt                           *
  *===========================================================================*/
@@ -296,6 +324,10 @@ int count;                 /* max number of processes to release */
   register struct fproc *rp;
   struct filp *f;
 
+#if 0
+  printf("vfs:release: vp 0x%x, call %d, count %d\n", vp, call_nr, count);
+#endif
+
   /* Trying to perform the call also includes SELECTing on it with that
    * operation.
    */
@@ -481,15 +513,15 @@ PUBLIC int select_request_pipe(struct filp *f, int *ops, int block)
        int orig_ops, r = 0, err, canwrite;
        orig_ops = *ops;
        if ((*ops & (SEL_RD|SEL_ERR))) {
-               if ((err = pipe_check(f->filp_vno, READING, 0,
-                       1, f->filp_pos, &canwrite, 1)) != SUSPEND)
+               if ((err = Xpipe_check(f->filp_vno, READING, 0,
+                       1, f->filp_pos, 1)) != SUSPEND)
                        r |= SEL_RD;
                if (err < 0 && err != SUSPEND)
                        r |= SEL_ERR;
        }
        if ((*ops & (SEL_WR|SEL_ERR))) {
-               if ((err = pipe_check(f->filp_vno, WRITING, 0,
-                       1, f->filp_pos, &canwrite, 1)) != SUSPEND)
+               if ((err = Xpipe_check(f->filp_vno, WRITING, 0,
+                       1, f->filp_pos, 1)) != SUSPEND)
                        r |= SEL_WR;
                if (err < 0 && err != SUSPEND)
                        r |= SEL_ERR;
index 3ac498b7269d2c9748eb84cb8ba8aacdcbbfa05d..97082ce16ff85a04ba4820f9b07ab00944ac220d 100644 (file)
 PUBLIC int do_chmod()
 {
   struct filp *flp;
-  struct chmod_req req;
-  struct lookup_req lookup_req;
-  struct node_details res;
   struct vnode *vp;
-  int r, ch_mode;
+  int r;
+  uid_t uid;
+  gid_t gid;
+  mode_t new_mode;
     
   if (call_nr == CHMOD) {
       /* Perform the chmod(name, mode) system call. */
       if (fetch_name(m_in.name, m_in.name_length, M3) != OK) return(err_code);
 
-      /* Fill in lookup request fields */
-      lookup_req.path = user_fullpath;
-      lookup_req.lastc = NULL;
-      lookup_req.flags = EAT_PATH;
-
       /* Request lookup */
-      if ((r = lookup(&lookup_req, &res)) != OK) return r;
-
-      req.inode_nr = res.inode_nr;
-      req.fs_e = res.fs_e;
+      r = lookup_vp(0 /*flags*/, 0 /*!use_realuid*/, &vp);
+      if (r != OK) return r;
   } 
   else if (call_nr == FCHMOD) {
       if (!(flp = get_filp(m_in.m3_i1))) return err_code;
-      req.inode_nr = flp->filp_vno->v_inode_nr;
-      req.fs_e = flp->filp_vno->v_fs_e;
+      vp= flp->filp_vno;
+      dup_vnode(vp);
   }
   else panic(__FILE__, "do_chmod called with strange call_nr", call_nr);
 
-  /* Find vnode, if it's in use. */
-  vp = find_vnode(req.fs_e, req.inode_nr);
+  uid= fp->fp_effuid;
+  gid= fp->fp_effgid;
+
+  /* Only the owner or the super_user may change the mode of a file.
+   * No one may change the mode of a file on a read-only file system.
+   */
+  if (vp->v_uid != uid && uid != SU_UID)
+       r = EPERM;
+  else
+       r = read_only(vp);
+
+  /* If error, return inode. */
+  if (r != OK) {
+       put_vnode(vp);
+       return(r);
+  }
+
+  /* Now make the change. Clear setgid bit if file is not in caller's grp */
+  if (uid != SU_UID && vp->v_gid != gid) 
+         m_in.mode &= ~I_SET_GID_BIT;
 
-  /* Fill in request message fields.*/
-  req.uid = fp->fp_effuid;
-  req.gid = fp->fp_effgid;
-  req.rmode = m_in.mode;
-  
   /* Issue request */
-  if((r = req_chmod(&req, &ch_mode)) != OK) return r;
+  r = req_chmod(vp->v_fs_e, vp->v_inode_nr, m_in.mode, &new_mode);
 
-  if(vp != NIL_VNODE)
-       vp->v_mode = ch_mode;
+  if (r == OK)
+       vp->v_mode = new_mode;
+  put_vnode(vp);
 
   return OK;
 }
@@ -84,52 +91,58 @@ PUBLIC int do_chown()
   int inode_nr;
   int fs_e;
   struct filp *flp;
-  struct chown_req req;
-  struct lookup_req lookup_req;
-  struct node_details res;
   struct vnode *vp;
-  int r, ch_mode;
+  int r;
+  uid_t uid;
+  gid_t gid;
+  mode_t new_mode;
   
   if (call_nr == CHOWN) {
       /* Perform the chmod(name, mode) system call. */
       if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code);
       
-      /* Fill in lookup request fields */
-      lookup_req.path = user_fullpath;
-      lookup_req.lastc = NULL;
-      lookup_req.flags = EAT_PATH;
-
       /* Request lookup */
-      if ((r = lookup(&lookup_req, &res)) != OK) return r;
-
-      req.inode_nr = res.inode_nr;
-      req.fs_e = res.fs_e;
+      r = lookup_vp(0 /*flags*/, 0 /*!use_realuid*/, &vp);
+      if (r != OK) return r;
   } 
   else if (call_nr == FCHOWN) {
       if (!(flp = get_filp(m_in.m1_i1))) return err_code;
-      req.inode_nr = flp->filp_vno->v_inode_nr;
-      req.fs_e = flp->filp_vno->v_fs_e;
+      vp= flp->filp_vno;
+      dup_vnode(vp);
   }
   else panic(__FILE__, "do_chmod called with strange call_nr", call_nr);
 
-  /* Find vnode, if it's in use. */
-  vp = find_vnode(req.fs_e, req.inode_nr);
+  uid= fp->fp_effuid;
+  gid= fp->fp_effgid;
+
+  r= OK;
+  if (uid == SU_UID) {
+       /* The super user can do anything. */
+  } else {
+       /* Regular users can only change groups of their own files. */
+       if (vp->v_uid != uid)
+               r = EPERM;      /* File does not belong to the caller */
+       if (vp->v_uid != m_in.owner) 
+               r = EPERM;      /* no giving away */
+       if (gid != m_in.group)
+               r = EPERM;      /* only change to the current gid */
+  }
+  if (r != OK) {
+       put_vnode(vp);
+       return r;
+  }
 
-  /* Fill in request message fields.*/
-  req.uid = fp->fp_effuid;
-  req.gid = fp->fp_effgid;
-  req.newuid = m_in.owner;
-  req.newgid = m_in.group;
-  
   /* Issue request */
-  r = req_chown(&req, &ch_mode);
+  r = req_chown(vp->v_fs_e, vp->v_inode_nr, m_in.owner, m_in.group, &new_mode);
 
-  if(r == OK && vp) {
+  if(r == OK) {
        vp->v_uid = m_in.owner;
        vp->v_gid = m_in.group;
-       vp->v_mode = ch_mode;
+       vp->v_mode = new_mode;
   }
 
+  put_vnode(vp);
+
   return r;
 }
 
@@ -154,10 +167,8 @@ PUBLIC int do_umask()
 PUBLIC int do_access()
 {
 /* Perform the access(name, mode) system call. */
-  struct access_req req;
-  struct lookup_req lookup_req;
-  struct node_details res;
   int r;
+  struct vnode *vp;
     
   /* First check to see if the mode is correct. */
   if ( (m_in.mode & ~(R_OK | W_OK | X_OK)) != 0 && m_in.mode != F_OK)
@@ -165,30 +176,20 @@ PUBLIC int do_access()
 
   if (fetch_name(m_in.name, m_in.name_length, M3) != OK) return(err_code);
 
-  /* Fill in lookup request fields */
-  lookup_req.path = user_fullpath;
-  lookup_req.lastc = NULL;
-  lookup_req.flags = EAT_PATH;
-
   /* Request lookup */
-  if ((r = lookup(&lookup_req, &res)) != OK) return r;
-
-  /* Fill in request fields */
-  req.fs_e = res.fs_e;
-  req.amode = m_in.mode;
-  req.inode_nr = res.inode_nr;
-  req.uid = fp->fp_realuid;         /* real user and group id */
-  req.gid = fp->fp_realgid;
-  
-  /* Issue request */
-  return req_access(&req);
+  r = lookup_vp(0 /*flags*/, TRUE /*use_realuid*/, &vp);
+  if (r != OK) return r;
+
+  r= forbidden(vp, m_in.mode, 1 /*use_realuid*/);
+  put_vnode(vp);
+  return r;
 }
 
 
 /*===========================================================================*
  *                             forbidden                                    *
  *===========================================================================*/
-PUBLIC int forbidden(struct vnode *vp, mode_t access_desired)
+PUBLIC int forbidden(struct vnode *vp, mode_t access_desired, int use_realuid)
 {
 /* Given a pointer to an inode, 'rip', and the access desired, determine
  * if the access is allowed, and if not why not.  The routine looks up the
@@ -198,18 +199,31 @@ PUBLIC int forbidden(struct vnode *vp, mode_t access_desired)
 
   register struct super_block *sp;
   register mode_t bits, perm_bits;
+  uid_t uid;
+  gid_t gid;
   int r, shift, type;
 
   if (vp->v_uid == (uid_t)-1 || vp->v_gid == (gid_t)-1)
   {
-       printf("forbidden: bad uid/gid in vnode\n");
+       printf("forbidden: bad uid/gid in vnode: inode %d on dev 0x%x\n",
+               vp->v_inode_nr, vp->v_dev);
        printf("forbidden: last allocated at %s, %d\n", vp->v_file, vp->v_line);
        return EACCES;
   }
 
   /* Isolate the relevant rwx bits from the mode. */
   bits = vp->v_mode;
-  if (fp->fp_effuid == SU_UID) {
+  if (use_realuid)
+  {
+       uid= fp->fp_realuid;
+       gid= fp->fp_realgid;
+  }
+  else
+  {
+       uid= fp->fp_effuid;
+       gid= fp->fp_effgid;
+  }
+  if (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.
@@ -220,8 +234,8 @@ PUBLIC int forbidden(struct vnode *vp, mode_t access_desired)
        else
                perm_bits = R_BIT | W_BIT;
   } else {
-       if (fp->fp_effuid == vp->v_uid) shift = 6;      /* owner */
-       else if (fp->fp_effgid == vp->v_gid ) shift = 3;        /* group */
+       if (uid == vp->v_uid) shift = 6;        /* owner */
+       else if (gid == vp->v_gid ) shift = 3;  /* group */
        else shift = 0;                                 /* other */
        perm_bits = (bits >> shift) & (R_BIT | W_BIT | X_BIT);
   }
index 1248f5f18a2ea6449884d47e9998149d0b0e3db6..cba9fe87a571f51dd07bcabc52fa4fdadd9c4cc5 100644 (file)
@@ -12,8 +12,6 @@ struct vnode;
 /* device.c */
 _PROTOTYPE( int dev_open, (Dev_t dev, int proc, int flags)             );
 _PROTOTYPE( void dev_close, (Dev_t dev)                                        );
-_PROTOTYPE( int dev_bio, (int op, Dev_t dev, int proc, void *buf,
-                       off_t pos, int bytes)                           );
 _PROTOTYPE( int dev_io, (int op, Dev_t dev, int proc, void *buf,
                        u64_t pos, int bytes, int flags)                );
 _PROTOTYPE( int gen_opcl, (int op, Dev_t dev, int proc, int flags)     );
@@ -33,6 +31,7 @@ _PROTOTYPE( void dev_up, (int major)                                  );
 _PROTOTYPE( int do_devctl, (void)                                      );
 _PROTOTYPE( int fs_devctl, (int req, int dev, int proc_nr_e, int style,
        int force)                                                      );
+_PROTOTYPE( int do_mapdriver, (void)                                   );
 _PROTOTYPE( void build_dmap, (void)                                    );
 _PROTOTYPE( int map_driver, (int major, int proc_nr, int dev_style,
        int force)                                                      );
@@ -100,20 +99,25 @@ _PROTOTYPE( int do_open, (void)                                            );
 _PROTOTYPE( int do_slink, (void)                                        );
 
 /* path.c */
-_PROTOTYPE( int lookup, (lookup_req_t *request, node_details_t *node)   );
-_PROTOTYPE( int lookup_vp, (lookup_req_t *request, struct vnode **vpp) );
-_PROTOTYPE( int Xlookup_vp, (lookup_req_t *request, struct vnode **vpp,
-                                                       char **pathrem) );
+_PROTOTYPE( int lookup_rel_vp, (struct vnode *start_node, int flags,
+                               int use_realuid, struct vnode **vpp)    );
+_PROTOTYPE( int lookup_vp, (int flags, int use_realuid,
+                                               struct vnode **vpp)     );
+_PROTOTYPE( int lookup_lastdir_rel, (struct vnode *start_node,
+                               int use_realuid, struct vnode **vpp)    );
+_PROTOTYPE( int lookup_lastdir, (int use_realuid, struct vnode **vpp)  );
 
 /* pipe.c */
 _PROTOTYPE( int do_pipe, (void)                                                );
 _PROTOTYPE( int do_unpause, (void)                                     );
 _PROTOTYPE( int unpause, (int proc_nr_e)                               );
-_PROTOTYPE( int pipe_check, (struct vnode *vp, int rw_flag,
-      int oflags, int bytes, u64_t position, int *canwrite, int notouch));
+_PROTOTYPE( int Xpipe_check, (struct vnode *vp, int rw_flag,
+             int oflags, int bytes, u64_t position, int notouch)       );
 _PROTOTYPE( void release, (struct vnode *vp, int call_nr, int count)   );
 _PROTOTYPE( void revive, (int proc_nr, int bytes)                      );
 _PROTOTYPE( void suspend, (int task)                                   );
+_PROTOTYPE( void pipe_suspend, (int rw_flag, int fd_nr, char *buf,
+                                                       size_t size)    );
 _PROTOTYPE( int select_request_pipe, (struct filp *f, int *ops, int bl)        );
 _PROTOTYPE( int select_cancel_pipe, (struct filp *f)                   );
 _PROTOTYPE( int select_match_pipe, (struct filp *f)                    );
@@ -124,60 +128,78 @@ _PROTOTYPE( int do_access, (void)                                 );
 _PROTOTYPE( int do_chmod, (void)                                       );
 _PROTOTYPE( int do_chown, (void)                                       );
 _PROTOTYPE( int do_umask, (void)                                       );
-_PROTOTYPE( int forbidden, (struct vnode *vp, mode_t access_desired)   );
+_PROTOTYPE( int forbidden, (struct vnode *vp,
+                               mode_t access_desired, int use_realuid) );
 _PROTOTYPE( int read_only, (struct vnode *vp)                          );
 
 /* read.c */
 _PROTOTYPE( int do_read, (void)                                                );
 _PROTOTYPE( int do_getdents, (void)                                    );
 _PROTOTYPE( int read_write, (int rw_flag)                              );
+_PROTOTYPE( int rw_pipe, (int rw_flag, endpoint_t usr,
+               int fd_nr, struct filp *f, char *buf, size_t req_size)  );
 
 /* request.c */
-#define req_getnode(req, res) req_getnode_f(__FILE__, __LINE__, (req), (res))
-_PROTOTYPE( int req_getnode_f, (char *file, int line, node_req_t *req, node_details_t *res)     );
-_PROTOTYPE( int req_putnode, (int fs_e, ino_t inode_nr, int count)     );
-_PROTOTYPE( int req_open, (open_req_t *req, node_details_t *res)        ); 
+_PROTOTYPE( int req_breadwrite, (endpoint_t fs_e, endpoint_t user_e,
+                       Dev_t dev, u64_t pos, unsigned int num_of_bytes,
+                       char *user_addr, int rw_flag,
+                       u64_t *new_posp, unsigned int *cum_iop)         );
+_PROTOTYPE( int req_chmod, (int fs_e, ino_t inode_nr, _mnx_Mode_t rmode,
+                                               mode_t *new_modep)      );
+_PROTOTYPE( int req_chown, (endpoint_t fs_e, ino_t inode_nr,
+       _mnx_Uid_t newuid, _mnx_Gid_t newgid, mode_t *new_modep)        );
 _PROTOTYPE( int req_create, (int fs_e, ino_t inode_nr, int omode,
                int uid, int gid, char *path, node_details_t *res)      ); 
-_PROTOTYPE( int req_readwrite, (readwrite_req_t *req, 
-            readwrite_res_t *res)                                       );
-_PROTOTYPE( int req_pipe, (pipe_req_t *req, node_details_t *res)        );
-_PROTOTYPE( int req_clone_opcl, (clone_opcl_req_t *req, 
-            node_details_t *res)                                        );
-_PROTOTYPE( int req_ftrunc, (ftrunc_req_t *req)                         );
-_PROTOTYPE( int req_chown, (chown_req_t *req, int *mode)                );
-_PROTOTYPE( int req_chmod, (chmod_req_t *req, int *mode)                );
-_PROTOTYPE( int req_access, (access_req_t *req)                         );
-_PROTOTYPE( int req_mknod, (mknod_req_t *req)                           );
-_PROTOTYPE( int req_mkdir, (mkdir_req_t *req)                           );
-_PROTOTYPE( int req_inhibread, (node_req_t *req)                        );
-_PROTOTYPE( int req_stat, (int fs_e, ino_t inode_nr, int who_e,
-                                               char *buf, int pos)     );
+_PROTOTYPE( int req_flush, (endpoint_t fs_e, Dev_t dev)                        );
 _PROTOTYPE( int req_fstatfs, (int fs_e, ino_t inode_nr, int who_e,
                                                        char *buf)      );
-_PROTOTYPE( int req_unlink, (unlink_req_t *req)                         );
-_PROTOTYPE( int req_rmdir, (unlink_req_t *req)                          );
-_PROTOTYPE( int req_utime, (utime_req_t *req)                           );
-_PROTOTYPE( int req_stime, (endpoint_t fs_e, time_t boottime)           );
+_PROTOTYPE( int req_ftrunc, (endpoint_t fs_e, ino_t inode_nr,
+                                               off_t start, off_t end) );
+_PROTOTYPE( int req_getdents, (endpoint_t fs_e, ino_t inode_nr,
+       off_t pos, cp_grant_id_t gid, size_t size, off_t *pos_change)   );
+_PROTOTYPE( int req_inhibread, (endpoint_t fs_e, ino_t inode_nr)       );
+_PROTOTYPE( int req_link, (endpoint_t fs_e, ino_t link_parent,
+                                       char *lastc, ino_t linked_file) );
+_PROTOTYPE( int req_lookup, (endpoint_t fs_e, size_t path_off,
+                       ino_t dir_ino, ino_t root_ino, _mnx_Uid_t uid,
+                       _mnx_Gid_t gid, int flags, lookup_res_t *res)   );
+_PROTOTYPE( int req_mkdir, (endpoint_t fs_e, ino_t inode_nr,
+       char *lastc, _mnx_Uid_t uid, _mnx_Gid_t gid, _mnx_Mode_t dmode) );
+_PROTOTYPE( int req_mknod, (endpoint_t fs_e, ino_t inode_nr,
+                       char *lastc, _mnx_Uid_t uid, _mnx_Gid_t gid,
+                       _mnx_Mode_t dmode, Dev_t dev)                   );
+_PROTOTYPE( int req_mountpoint, (endpoint_t fs_e, ino_t inode_nr)      );
+_PROTOTYPE( int req_newnode, (endpoint_t fs_e, _mnx_Uid_t uid,
+                               _mnx_Gid_t gid, _mnx_Mode_t dmode,
+                               Dev_t dev, struct node_details *res)    );
+_PROTOTYPE( int req_putnode, (int fs_e, ino_t inode_nr, int count)     );
+_PROTOTYPE( int req_rdlink, (endpoint_t fs_e, ino_t inode_nr,
+                       endpoint_t who_e, vir_bytes buf, size_t len)    );
+_PROTOTYPE( int req_readsuper, (endpoint_t fs_e, char *driver_name,
+                               Dev_t dev, int readonly, int isroot,
+                               struct node_details *res_nodep)         );
+_PROTOTYPE( int req_readwrite, (endpoint_t fs_e, ino_t inode_nr,
+               int inode_index, u64_t pos, int rw_flag,
+               endpoint_t user_e, char *user_addr,
+               unsigned int num_of_bytes, u64_t *new_posp,
+               unsigned int *cum_iop)                                  ); 
+_PROTOTYPE( int req_rename, (endpoint_t fs_e, ino_t old_dir,
+                       char *old_name, ino_t new_dir, char *new_name)  );
+_PROTOTYPE( int req_rmdir, (endpoint_t fs_e, ino_t inode_nr,
+                                                       char *lastc)    );
+_PROTOTYPE(int req_slink, (endpoint_t fs_e, ino_t inode_nr, char *lastc,
+               endpoint_t who_e, char *path_addr,
+               int path_length, _mnx_Uid_t uid, _mnx_Gid_t gid)        );
+_PROTOTYPE( int req_stat, (int fs_e, ino_t inode_nr, int who_e,
+                                               char *buf, int pos)     );
 _PROTOTYPE( int req_sync, (endpoint_t fs_e)                             );
-_PROTOTYPE( int req_link, (link_req_t *req)                             );
-_PROTOTYPE( int req_slink, (slink_req_t *req)                           );
-_PROTOTYPE( int req_rdlink, (rdlink_req_t *req)                         );
-_PROTOTYPE( int req_rename, (rename_req_t *req)                         );
-_PROTOTYPE( int req_mountpoint, (mountpoint_req_t *req, 
-            node_details_t *res)                                        );
-_PROTOTYPE( int req_readsuper, (readsuper_req_t *req, 
-            readsuper_res_t *res)                                       );
+_PROTOTYPE( int req_unlink, (endpoint_t fs_e, ino_t inode_nr,
+                                                       char *lastc)    );
 _PROTOTYPE( int req_unmount, (endpoint_t fs_e)                          );
-_PROTOTYPE( int req_trunc, (trunc_req_t *req)                           );
-_PROTOTYPE( int req_lookup, (lookup_req_t *req, lookup_res_t *res)      );
+_PROTOTYPE( int req_utime, (endpoint_t fs_e, ino_t inode_nr,
+                                       time_t actime, time_t modtime)  );
 _PROTOTYPE( int req_newdriver, (endpoint_t fs_e, Dev_t dev, 
             endpoint_t driver_e)                                        );
-_PROTOTYPE( int req_breadwrite, (breadwrite_req_t *req, 
-            readwrite_res_t *res)                                       );
-_PROTOTYPE( int req_getdents, (endpoint_t fs_e, ino_t inode_nr,
-       off_t pos, cp_grant_id_t gid, size_t size, off_t *pos_change)   );
-_PROTOTYPE( int req_flush, (endpoint_t fs_e, Dev_t)                     );
 
 /* stadir.c */
 _PROTOTYPE( int do_chdir, (void)                                       );
@@ -190,7 +212,6 @@ _PROTOTYPE( int do_rdlink, (void)                                      );
 _PROTOTYPE( int do_lstat, (void)                                       );
 
 /* time.c */
-_PROTOTYPE( int do_stime, (void)                                       );
 _PROTOTYPE( int do_utime, (void)                                       );
 
 /* utility.c */
@@ -215,8 +236,10 @@ _PROTOTYPE( struct vnode *find_vnode, (int fs_e, int numb)              );
 _PROTOTYPE( void dup_vnode, (struct vnode *vp)                          );
 _PROTOTYPE( void put_vnode, (struct vnode *vp)                          );
 _PROTOTYPE( void vnode_clean_refs, (struct vnode *vp)                   );
+#if 0
 _PROTOTYPE( struct vnode *get_vnode, (int fs_e, int inode_nr)           );
 _PROTOTYPE( struct vnode *get_vnode_x, (int fs_e, int inode_nr)                );
+#endif
 #if 0
 _PROTOTYPE( void mark_vn, (struct vnode *vp, char *file, int line)     );
 _PROTOTYPE( int check_vrefs, (void)                                    );
index 47e68155f93a5140d83e4f1e7276b6efd9e1ae6e..fa37d4d43799586d8af1f865ac0132d80ccd7488 100644 (file)
@@ -27,7 +27,6 @@
 #include "vnode.h"
 #include "vmnt.h"
 
-
 /*===========================================================================*
  *                             do_read                                      *
  *===========================================================================*/
@@ -47,70 +46,74 @@ int rw_flag;                        /* READING or WRITING */
   register struct filp *f;
   register struct vnode *vp;
   off_t bytes_left;
-  u64_t position;
-  unsigned int off, cum_io;
-  int op, oflags, r, chunk, usr, seg, block_spec, char_spec;
-  int regular, partial_pipe = 0, partial_cnt = 0;
+  u64_t position, res_pos, new_pos;
+  unsigned int off, cum_io, cum_io_incr, res_cum_io, num_of_bytes;
+  int op, oflags, r, chunk, usr, block_spec, char_spec;
+  int regular;
   mode_t mode_word;
-  struct filp *wf;
   phys_bytes p;
   struct dmap *dp;
 
-  /* Request and response structures */
-  struct readwrite_req req;
-  struct readwrite_res res;
-
-  /* For block spec files */
-  struct breadwrite_req breq;
-
   /* PM loads segments by putting funny things in other bits of the
    * message, indicated by a high bit in fd. */
   if (who_e == PM_PROC_NR && (m_in.fd & _PM_SEG_FLAG)) {
-      seg = (int) m_in.m1_p2;
-      usr = (int) m_in.m1_p3;
-      m_in.fd &= ~(_PM_SEG_FLAG);      /* get rid of flag bit */
+       panic(__FILE__,
+       "read_write: special read/write calls by PM no longer supported",
+               NO_NUM);
   } 
   else {
       usr = who_e;             /* normal case */
-      seg = D;
   }
 
   /* If the file descriptor is valid, get the vnode, size and mode. */
-  if (m_in.nbytes < 0) return(EINVAL);
-  if ((f = get_filp(m_in.fd)) == NIL_FILP) return(err_code);
+  if (m_in.nbytes < 0)
+       return(EINVAL);
+
+  if ((f = get_filp(m_in.fd)) == NIL_FILP)
+  {
+       printf("vfs:read_write: returning %d\n", err_code);
+       return(err_code);
+  }
   if (((f->filp_mode) & (rw_flag == READING ? R_BIT : W_BIT)) == 0) {
+       printf("vfs:read_write: returning error\n");
       return(f->filp_mode == FILP_CLOSED ? EIO : EBADF);
   }
 
   if (m_in.nbytes == 0)
       return(0);       /* so char special files need not check for 0*/
 
-  /* check if user process has the memory it needs.
-   * if not, copying will fail later.
-   * do this after 0-check above because umap doesn't want to map 0 bytes. */
-  if ((r = sys_umap(usr, seg, (vir_bytes) m_in.buffer, m_in.nbytes, &p)) != OK)
-  {
-      printf("VFS: read_write: umap failed for process %d\n", usr);
-      return r;
-  }
-
   position = f->filp_pos;
   oflags = f->filp_flags;
 
   vp = f->filp_vno;
 
-  r = OK;
-  if (vp->v_pipe == I_PIPE) {
-      /* fp->fp_cum_io_partial is only nonzero when doing partial writes */
-      cum_io = fp->fp_cum_io_partial; 
-  } 
-  else {
-      cum_io = 0;
+  if (vp->v_pipe)
+  {
+       if (rw_flag == WRITING)
+       {
+               if (vp->v_w_pipe_busy)
+               {
+                       panic(__FILE__,
+                               "read_write: pipe already has a writer",
+                               NO_NUM);
+               }
+               if (fp->fp_cum_io_partial != 0)
+               {
+                       panic(__FILE__,
+               "read_write: fp_cum_io_partial not clear for new pipe writer",
+                               NO_NUM);
+               }
+               vp->v_w_pipe_busy= TRUE;
+       }
+       return rw_pipe(rw_flag, usr, m_in.fd, f, m_in.buffer, m_in.nbytes);
   }
 
+  r = OK;
+  cum_io = 0;
+
   op = (rw_flag == READING ? VFS_DEV_READ : VFS_DEV_WRITE);
   mode_word = vp->v_mode & I_TYPE;
-  regular = mode_word == I_REGULAR || mode_word == I_NAMED_PIPE;
+  regular = mode_word == I_REGULAR;
 
   if ((char_spec = (mode_word == I_CHAR_SPECIAL ? 1 : 0))) {
       if (vp->v_sdev == NO_DEV)
@@ -138,83 +141,49 @@ int rw_flag;                      /* READING or WRITING */
   } 
   /* Block special files. */
   else if (block_spec) {
-      /* Fill in the fields of the request */
-      breq.rw_flag = rw_flag;
-      breq.fs_e = vp->v_bfs_e;
-      breq.blocksize = vp->v_blocksize;
-      breq.dev = vp->v_sdev;
-      breq.user_e = usr;
-      breq.pos = position;
-      breq.num_of_bytes = m_in.nbytes;
-      breq.user_addr = m_in.buffer;
 
       /* Issue request */
-      r = req_breadwrite(&breq, &res);
+      r = req_breadwrite(vp->v_bfs_e, usr, vp->v_sdev, position,
+       m_in.nbytes, m_in.buffer, rw_flag, &res_pos, &res_cum_io);
 
-      position = res.new_pos;
-      cum_io += res.cum_io;
+      position = res_pos;
+      cum_io += res_cum_io;
   }
-  /* Regular files (and pipes) */
+  /* Regular files */
   else {
       if (rw_flag == WRITING && block_spec == 0) {
           /* Check for O_APPEND flag. */
           if (oflags & O_APPEND) position = cvul64(vp->v_size);
-
-          /* Check in advance to see if file will grow too big. */
-          if (cmp64ul(position, vp->v_vmnt->m_max_file_size - m_in.nbytes) > 0)
-              return(EFBIG);
-
       }
 
-      /* Pipes are a little different. Check. */
-      if (vp->v_pipe == I_PIPE) {
-          r = pipe_check(vp, rw_flag, oflags,
-                  m_in.nbytes, position, &partial_cnt, 0);
-          if (r <= 0) return(r);
-      }
-
-      if (partial_cnt > 0) {
-          /* So that we don't need to deal with partial count 
-           * in the FS process.
-          */
-          m_in.nbytes = MIN(m_in.nbytes, partial_cnt);
-          partial_pipe = 1;
-      }
 
       /* Fill in request structure */
-      req.fs_e = vp->v_fs_e;
-      req.rw_flag = rw_flag;
-      req.inode_nr = vp->v_inode_nr;
-      req.user_e = usr;
-      req.seg = seg;
-      req.pos = position;
-      req.num_of_bytes = m_in.nbytes;
-      req.user_addr = m_in.buffer;
-      req.inode_index = vp->v_index;
+      num_of_bytes = m_in.nbytes;
 
       /* Truncate read request at size (mustn't do this for special files). */
       if((rw_flag == READING) &&
-       cmp64ul(add64ul(position, req.num_of_bytes), vp->v_size) > 0) {
-       /* Position always should fit in an off_t (LONG_MAX). */
-       off_t pos32;
-       assert(cmp64ul(position, LONG_MAX) <= 0);
-       pos32 = cv64ul(position);
-       assert(pos32 >= 0);
-       assert(pos32 <= LONG_MAX);
-       req.num_of_bytes = vp->v_size - pos32;
-       assert(req.num_of_bytes >= 0);
+       cmp64ul(add64ul(position, num_of_bytes), vp->v_size) > 0) {
+               /* Position always should fit in an off_t (LONG_MAX). */
+               off_t pos32;
+               assert(cmp64ul(position, LONG_MAX) <= 0);
+               pos32 = cv64ul(position);
+               assert(pos32 >= 0);
+               assert(pos32 <= LONG_MAX);
+               num_of_bytes = vp->v_size - pos32;
+               assert(num_of_bytes >= 0);
       }
 
       /* Issue request */
-      r = req_readwrite(&req, &res);
+      r = req_readwrite(vp->v_fs_e, vp->v_inode_nr, vp->v_index, position,
+       rw_flag, usr, m_in.buffer, num_of_bytes, &new_pos, &cum_io_incr);
 
       if (r >= 0)
       {
-       if (ex64hi(res.new_pos))
+       if (ex64hi(new_pos))
                panic(__FILE__, "read_write: bad new pos", NO_NUM);
 
-       position = res.new_pos;
-       cum_io += res.cum_io;
+       position = new_pos;
+       cum_io += cum_io_incr;
       }
   }
 
@@ -233,32 +202,10 @@ int rw_flag;                      /* READING or WRITING */
          }
       }
   }
-  else {
-      if (vp->v_pipe == I_PIPE) {
-          if (cmp64ul(position, vp->v_size) >= 0) {
-              /* Reset pipe pointers */
-              vp->v_size = 0;
-              position = cvu64(0);
-              wf = find_filp(vp, W_BIT);
-              if (wf != NIL_FILP) wf->filp_pos = cvu64(0);
-          }
-      }
-  }
 
   f->filp_pos = position;
 
   if (r == OK) {
-      if (partial_pipe) {
-          partial_pipe = 0;
-          /* partial write on pipe with */
-          /* O_NONBLOCK, return write count */
-          if (!(oflags & O_NONBLOCK)) {
-              fp->fp_cum_io_partial = cum_io;
-              suspend(XPIPE);   /* partial write on pipe with */
-              return(SUSPEND);  /* nbyte > PIPE_SIZE - non-atomic */
-          }
-      }
-      fp->fp_cum_io_partial = 0;
       return cum_io;
   }
 
@@ -266,65 +213,6 @@ int rw_flag;                       /* READING or WRITING */
 }
 
 
-/* Original "uncached" code for block spec files */
-#if 0      
-  else if (block_spec) {
-        char buf[_MIN_BLOCK_SIZE];
-        block_t b;
-        int bleft = m_in.nbytes;
-       dev_t dev = vp->v_sdev;
-        
-        b = position / _MIN_BLOCK_SIZE;
-        off = position % _MIN_BLOCK_SIZE;
-       
-        while (bleft) {
-            /* First read the whole block */
-            r = dev_bio(VFS_DEV_READ, dev, FS_PROC_NR, buf,
-               b * _MIN_BLOCK_SIZE, _MIN_BLOCK_SIZE);
-
-            if (r != _MIN_BLOCK_SIZE)
-                break;
-
-            /* How many bytes to copy? */
-            chunk = MIN(bleft, _MIN_BLOCK_SIZE - off);
-
-            if (rw_flag == READING) {
-                /* Copy a chunk from the buffer to user space. */
-                r = sys_vircopy(FS_PROC_NR, D, (phys_bytes) (&buf[off]),
-                        usr, seg, (phys_bytes) m_in.buffer,
-                        (phys_bytes) chunk);
-            } 
-            else {
-                /* Copy a chunk from user space to the buffer. */
-                r = sys_vircopy(usr, seg, (phys_bytes) m_in.buffer,
-                        FS_PROC_NR, D, (phys_bytes) (&buf[off]),
-                        (phys_bytes) chunk);
-            }
-
-            /* Write back if WRITE */
-            if (rw_flag == WRITING) {
-                r = dev_bio(DEV_WRITE, dev, FS_PROC_NR, buf, 
-                       b * _MIN_BLOCK_SIZE, _MIN_BLOCK_SIZE);
-                
-                if (r != _MIN_BLOCK_SIZE)
-                    break;
-            }
-           
-            bleft -= chunk;
-            m_in.buffer += chunk;
-           
-            /* 0 offset in the next block */
-            b++;
-            off = 0;
-        } 
-        
-        cum_io = m_in.nbytes - bleft;
-        position += cum_io;
-       r = OK;
-  }        
-#endif        
-
-
 /*===========================================================================*
  *                             do_getdents                                  *
  *===========================================================================*/
@@ -366,4 +254,128 @@ PUBLIC int do_getdents()
 }
 
 
+/*===========================================================================*
+ *                             rw_pipe                                      *
+ *===========================================================================*/
+PUBLIC int rw_pipe(rw_flag, usr, fd_nr, f, buf, req_size)
+int rw_flag;                   /* READING or WRITING */
+endpoint_t usr;
+int fd_nr;
+struct filp *f;
+char *buf;
+size_t req_size;
+{
+  int r, oflags, op, partial_pipe;
+  size_t size, cum_io, cum_io_incr;
+  struct filp *wf;
+  struct vnode *vp;
+  u64_t position, new_pos;
+
+  position = f->filp_pos;
+  oflags = f->filp_flags;
+
+  vp = f->filp_vno;
+
+#if 0
+  printf("vfs:rw_pipe: pipe %s, buf 0x%x, size %d\n",
+       rw_flag == READING ? "read" : "write", buf, req_size);
+  printf("vfs:rw_pipe: pipe vp 00x%x, dev/num 0x%x/%d size %d, pos 0x%x:%08x\n",
+       vp, vp->v_dev, vp->v_inode_nr, 
+       vp->v_size, ex64hi(position), ex64lo(position));
+#endif
+
+  /* fp->fp_cum_io_partial is only nonzero when doing partial writes */
+  cum_io = fp->fp_cum_io_partial; 
+
+  op = (rw_flag == READING ? VFS_DEV_READ : VFS_DEV_WRITE);
+
+  r = Xpipe_check(vp, rw_flag, oflags, req_size, position, 0);
+  if (r <= 0)
+  {
+       if (r == SUSPEND)
+               pipe_suspend(rw_flag, fd_nr, buf, req_size);
+       return(r);
+  }
+
+  size = r;
+  if (r < req_size)
+       partial_pipe = 1;
+  else 
+       partial_pipe = 0;
+
+  /* Truncate read request at size. */
+  if((rw_flag == READING) &&
+       cmp64ul(add64ul(position, size), vp->v_size) > 0) {
+       /* Position always should fit in an off_t (LONG_MAX). */
+       off_t pos32;
+
+       assert(cmp64ul(position, LONG_MAX) <= 0);
+       pos32 = cv64ul(position);
+       assert(pos32 >= 0);
+       assert(pos32 <= LONG_MAX);
+       size = vp->v_size - pos32;
+  }
+  /* Issue request */
+  r = req_readwrite(vp->v_fs_e, vp->v_inode_nr, vp->v_index, position,
+       rw_flag, usr, buf, size, &new_pos, &cum_io_incr);
+
+  if (r >= 0)
+  {
+       if (ex64hi(new_pos))
+               panic(__FILE__, "read_write: bad new pos", NO_NUM);
+
+       position = new_pos;
+       cum_io += cum_io_incr;
+       buf += cum_io_incr;
+       req_size -= cum_io_incr;
+  }
+
+  /* On write, update file size and access time. */
+  if (rw_flag == WRITING) {
+       if (cmp64ul(position, vp->v_size) > 0)
+       {
+               if (ex64hi(position) != 0)
+               {
+                       panic(__FILE__,
+                               "read_write: file size too big for v_size",
+                               NO_NUM);
+               }
+               vp->v_size = ex64lo(position);
+       }
+  }
+  else {
+       if (cmp64ul(position, vp->v_size) >= 0) {
+               /* Reset pipe pointers */
+               vp->v_size = 0;
+               position = cvu64(0);
+               wf = find_filp(vp, W_BIT);
+               if (wf != NIL_FILP) wf->filp_pos = cvu64(0);
+       }
+  }
+
+  f->filp_pos = position;
+
+  if (r == OK) {
+       if (partial_pipe) {
+               /* partial write on pipe with */
+               /* O_NONBLOCK, return write count */
+               if (!(oflags & O_NONBLOCK)) {
+                       /* partial write on pipe with req_size > PIPE_SIZE,
+                        * non-atomic
+                        */
+                       fp->fp_cum_io_partial = cum_io;
+                       pipe_suspend(rw_flag, fd_nr, buf, req_size);
+                       return(SUSPEND);
+               }
+       }
+       fp->fp_cum_io_partial = 0;
+       if (rw_flag == WRITING)
+               vp->v_w_pipe_busy= FALSE;
+       return cum_io;
+  }
+
+  return r;
+}
+
+
 
index b4ca2810ebf08cc542d27d413af1a56f973b4a1c..2ed24f955c8922f49ccd1353855fc968c08213ee 100644 (file)
 
-/* This file contains the wrapper functions for issueing a request
- * and receiving response from FS processes.
- * Each function builds a request message according to the request
- * parameter, calls the most low-level fs_sendrec and copies
- * back the response.
- * The low-level fs_sendrec handles the recovery mechanism from
- * a dead driver and reissues the request.
+/* This file deals with protection in the file system.  It contains the code
+ * for four system calls that relate to protection.
  *
- *  Sep 2006 (Balazs Gerofi)
+ * The entry points into this file are
+ *   do_chmod: perform the CHMOD and FCHMOD system calls
+ *   do_chown: perform the CHOWN and FCHOWN system calls
+ *   do_umask: perform the UMASK system call
+ *   do_access:        perform the ACCESS system call
+ *
+ * Changes for VFS:
+ *   Jul 2006 (Balazs Gerofi)
  */
 
 #include "fs.h"
-#include <string.h>
-#include <sys/stat.h>
-#include <sys/statfs.h>
-#include <minix/callnr.h>
-#include <minix/com.h>
-#include <minix/keymap.h>
-#include <minix/const.h>
-#include <minix/endpoint.h>
-#include <minix/u64.h>
 #include <unistd.h>
+#include <minix/callnr.h>
+#include "file.h"
+#include "fproc.h"
+#include "param.h"
 
 #include <minix/vfsif.h>
-#include "fproc.h"
-#include "vmnt.h"
 #include "vnode.h"
-#include "param.h"
+#include "vmnt.h"
 
-FORWARD _PROTOTYPE(int fs_sendrec_f, (char *file, int line, endpoint_t fs_e, message *reqm));
 
-#define fs_sendrec(e, m) fs_sendrec_f(__FILE__, __LINE__, (e), (m))
 
 /*===========================================================================*
- *                             req_getnode                                  *
+ *                             do_chmod                                     *
  *===========================================================================*/
-PUBLIC int req_getnode_f(file, line, req, res)
-char *file;
-int line;
-node_req_t *req; 
-node_details_t *res;
+PUBLIC int do_chmod()
 {
-    int r;
-    message m;
-
-    /* Fill in request message */
-    m.m_type = REQ_GETNODE;
-    m.REQ_INODE_NR = req->inode_nr;
+  struct filp *flp;
+  struct vnode *vp;
+  int r;
+  uid_t uid;
+  gid_t gid;
+  mode_t new_mode;
+    
+  if (call_nr == CHMOD) {
+      /* Perform the chmod(name, mode) system call. */
+      if (fetch_name(m_in.name, m_in.name_length, M3) != OK) return(err_code);
+
+      /* Request lookup */
+      r = lookup_vp(0 /*flags*/, 0 /*!use_realuid*/, &vp);
+      if (r != OK) return r;
+  } 
+  else if (call_nr == FCHMOD) {
+      if (!(flp = get_filp(m_in.m3_i1))) return err_code;
+      vp= flp->filp_vno;
+      dup_vnode(vp);
+  }
+  else panic(__FILE__, "do_chmod called with strange call_nr", call_nr);
 
-    /* Send/rec request */
-    if ((r = fs_sendrec(req->fs_e, &m)) != OK) return r;
+  uid= fp->fp_effuid;
+  gid= fp->fp_effgid;
 
-    /* Fill in response structure */
-    res->fs_e = m.m_source;
-    res->inode_nr = m.RES_INODE_NR;
-    res->fmode = m.RES_MODE;
-    res->fsize = m.RES_FILE_SIZE;
-    res->dev = m.RES_DEV;
-    res->uid = m.RES_UID;
-    res->gid = m.RES_GID;
+  /* Only the owner or the super_user may change the mode of a file.
+   * No one may change the mode of a file on a read-only file system.
+   */
+  if (vp->v_uid != uid && uid != SU_UID)
+       r = EPERM;
+  else
+       r = read_only(vp);
 
-    return OK;
-}
+  /* If error, return inode. */
+  if (r != OK) {
+       put_vnode(vp);
+       return(r);
+  }
 
+  /* Now make the change. Clear setgid bit if file is not in caller's grp */
+  if (uid != SU_UID && vp->v_gid != gid) 
+         m_in.mode &= ~I_SET_GID_BIT;
 
-/*===========================================================================*
- *                             req_putnode                                  *
- *===========================================================================*/
-PUBLIC int req_putnode(fs_e, inode_nr, count)
-int fs_e;
-ino_t inode_nr;
-int count;
-{
-    message m;
+  /* Issue request */
+  r = req_chmod(vp->v_fs_e, vp->v_inode_nr, m_in.mode, &new_mode);
 
-    /* Fill in request message */
-    m.m_type = REQ_PUTNODE;
-    m.REQ_INODE_NR = inode_nr;
-    m.REQ_COUNT = count;
+  if (r == OK)
+       vp->v_mode = new_mode;
+  put_vnode(vp);
 
-    /* Send/rec request */
-    return fs_sendrec(fs_e, &m);
+  return OK;
 }
 
 /*===========================================================================*
- *                             req_open                                     *
+ *                             do_chown                                     *
  *===========================================================================*/
-int req_open(req, res)
-open_req_t *req; 
-node_details_t *res; 
+PUBLIC int do_chown()
 {
-    int r;
-    message m;
+  int inode_nr;
+  int fs_e;
+  struct filp *flp;
+  struct vnode *vp;
+  int r;
+  uid_t uid;
+  gid_t gid;
+  mode_t new_mode;
+  
+  if (call_nr == CHOWN) {
+      /* Perform the chmod(name, mode) system call. */
+      if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code);
+      
+      /* Request lookup */
+      r = lookup_vp(0 /*flags*/, 0 /*!use_realuid*/, &vp);
+      if (r != OK) return r;
+  } 
+  else if (call_nr == FCHOWN) {
+      if (!(flp = get_filp(m_in.m1_i1))) return err_code;
+      vp= flp->filp_vno;
+      dup_vnode(vp);
+  }
+  else panic(__FILE__, "do_chmod called with strange call_nr", call_nr);
+
+  uid= fp->fp_effuid;
+  gid= fp->fp_effgid;
+
+  r= OK;
+  if (uid == SU_UID) {
+       /* The super user can do anything. */
+  } else {
+       /* Regular users can only change groups of their own files. */
+       if (vp->v_uid != uid)
+               r = EPERM;      /* File does not belong to the caller */
+       if (vp->v_uid != m_in.owner) 
+               r = EPERM;      /* no giving away */
+       if (gid != m_in.group)
+               r = EPERM;      /* only change to the current gid */
+  }
+  if (r != OK) {
+       put_vnode(vp);
+       return r;
+  }
 
-    /* Fill in request message */
-    m.m_type = REQ_OPEN;
-    m.REQ_INODE_NR = req->inode_nr;
-    m.REQ_FLAGS = req->oflags;
-    m.REQ_MODE = req->omode;
-    m.REQ_UID = req->uid;
-    m.REQ_GID = req->gid;
-    m.REQ_PATH = req->lastc;
-    m.REQ_PATH_LEN = strlen(req->lastc) + 1;
+  /* Issue request */
+  r = req_chown(vp->v_fs_e, vp->v_inode_nr, m_in.owner, m_in.group, &new_mode);
 
-    /* Send/rec request */
-    if ((r = fs_sendrec(req->fs_e, &m)) != OK) return r;
+  if(r == OK) {
+       vp->v_uid = m_in.owner;
+       vp->v_gid = m_in.group;
+       vp->v_mode = new_mode;
+  }
 
-    /* Fill in response structure */
-    res->fs_e = m.m_source;
-    res->inode_nr = m.RES_INODE_NR;
-    res->fmode = m.RES_MODE;
-    res->fsize = m.RES_FILE_SIZE;
-    res->dev = m.RES_DEV;
-    res->inode_index = m.RES_INODE_INDEX;
-    /* For exec */
-    res->uid = m.RES_UID;
-    res->gid = m.RES_GID;
-    res->ctime = m.RES_CTIME;
+  put_vnode(vp);
 
-    return OK;
+  return r;
 }
 
 
 /*===========================================================================*
- *                             req_create                                   *
+ *                             do_umask                                     *
  *===========================================================================*/
-int req_create(fs_e, inode_nr, omode, uid, gid, path, res)
-int fs_e;
-ino_t inode_nr;
-int omode;
-uid_t uid;
-gid_t gid;
-char *path;
-node_details_t *res; 
+PUBLIC int do_umask()
 {
-    int r;
-    message m;
-
-    /* Fill in request message */
-    m.m_type = REQ_CREATE;
-    m.REQ_INODE_NR = inode_nr;
-    m.REQ_MODE = omode;
-    m.REQ_UID = uid;
-    m.REQ_GID = gid;
-    m.REQ_PATH = path;
-    m.REQ_PATH_LEN = strlen(path) + 1;
-
-    /* Send/rec request */
-    if ((r = fs_sendrec(fs_e, &m)) != OK) return r;
-
-    /* Fill in response structure */
-    res->fs_e = m.m_source;
-    res->inode_nr = m.RES_INODE_NR;
-    res->fmode = m.RES_MODE;
-    res->fsize = m.RES_FILE_SIZE;
-    res->dev = m.RES_DEV;
-    res->inode_index = m.RES_INODE_INDEX;
-    /* For exec */
-    res->uid = m.RES_UID;
-    res->gid = m.RES_GID;
-    res->ctime = m.RES_CTIME;
+/* Perform the umask(co_mode) system call. */
+  register mode_t r;
 
-    return OK;
+  r = ~fp->fp_umask;           /* set 'r' to complement of old mask */
+  fp->fp_umask = ~(m_in.co_mode & RWX_MODES);
+  return(r);                   /* return complement of old mask */
 }
 
 
 /*===========================================================================*
- *                             req_readwrite                                *
+ *                             do_access                                    *
  *===========================================================================*/
-int req_readwrite(req, res)
-readwrite_req_t *req; 
-readwrite_res_t *res; 
+PUBLIC int do_access()
 {
-    int r;
-    message m;
-
-    if (ex64hi(req->pos) != 0)
-       panic(__FILE__, "req_readwrite: pos too large", NO_NUM);
-    
-    /* Fill in request message */
-    m.m_type = req->rw_flag == READING ? REQ_READ : REQ_WRITE;
-    m.REQ_FD_INODE_NR = req->inode_nr;
-    m.REQ_FD_WHO_E = req->user_e;
-    m.REQ_FD_SEG = req->seg;
-    m.REQ_FD_POS = ex64lo(req->pos);
-    m.REQ_FD_NBYTES = req->num_of_bytes;
-    m.REQ_FD_USER_ADDR = req->user_addr;
-    m.REQ_FD_INODE_INDEX = req->inode_index;
+/* Perform the access(name, mode) system call. */
+  int r;
+  struct vnode *vp;
     
-    /* Send/rec request */
-    if ((r = fs_sendrec(req->fs_e, &m)) != OK) return r;
+  /* First check to see if the mode is correct. */
+  if ( (m_in.mode & ~(R_OK | W_OK | X_OK)) != 0 && m_in.mode != F_OK)
+       return(EINVAL);
 
-    /* Fill in response structure */
-    res->new_pos = cvul64(m.RES_FD_POS);
-    res->cum_io = m.RES_FD_CUM_IO;
+  if (fetch_name(m_in.name, m_in.name_length, M3) != OK) return(err_code);
 
-    return OK;
-}
+  /* Request lookup */
+  r = lookup_vp(0 /*flags*/, TRUE /*use_realuid*/, &vp);
+  if (r != OK) return r;
 
+  r= forbidden(vp, m_in.mode, 1 /*use_realuid*/);
+  put_vnode(vp);
+  return r;
+}
 
 
 /*===========================================================================*
- *                             req_pipe                                     *
+ *                             forbidden                                    *
  *===========================================================================*/
-PUBLIC int req_pipe(req, res)
-pipe_req_t *req; 
-node_details_t *res;
+PUBLIC int forbidden(struct vnode *vp, mode_t access_desired, int use_realuid)
 {
-    int r;
-    message m;
+/* Given a pointer to an inode, 'rip', 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.
+ */
 
-    /* Fill in request message */
-    m.m_type = REQ_PIPE;
-    m.REQ_UID = req->uid;
-    m.REQ_GID = req->gid;
+  register struct super_block *sp;
+  register mode_t bits, perm_bits;
+  uid_t uid;
+  gid_t gid;
+  int r, shift, type;
 
-    /* Send/rec request */
-    if ((r = fs_sendrec(req->fs_e, &m)) != OK) return r;
+  if (vp->v_uid == (uid_t)-1 || vp->v_gid == (gid_t)-1)
+  {
+       printf("forbidden: bad uid/gid in vnode: inode %d on dev 0x%x\n",
+               vp->v_inode_nr, vp->v_dev);
+       printf("forbidden: last allocated at %s, %d\n", vp->v_file, vp->v_line);
+       return EACCES;
+  }
 
-    /* Fill in response structure */
-    res->fs_e = m.m_source;
-    res->inode_nr = m.RES_INODE_NR;
-    res->fmode = m.RES_MODE;
-    res->fsize = m.RES_FILE_SIZE;
-    res->dev = m.RES_DEV;
-    res->inode_index = m.RES_INODE_INDEX;
-    
-    return OK;
+  /* Isolate the relevant rwx bits from the mode. */
+  bits = vp->v_mode;
+  if (use_realuid)
+  {
+       uid= fp->fp_realuid;
+       gid= fp->fp_realgid;
+  }
+  else
+  {
+       uid= fp->fp_effuid;
+       gid= fp->fp_effgid;
+  }
+  if (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 (uid == vp->v_uid) shift = 6;        /* owner */
+       else if (gid == vp->v_gid ) shift = 3;  /* group */
+       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 = read_only(vp);
+
+  return(r);
 }
 
 
 /*===========================================================================*
- *                             req_clone_opcl                               *
+ *                             read_only                                    *
  *===========================================================================*/
-PUBLIC int req_clone_opcl(req, res)
-clone_opcl_req_t *req;
-node_details_t *res;
+PUBLIC int read_only(vp)
+struct vnode *vp;              /* ptr to inode whose file sys is to be cked */
 {
-    int r;
-    message m;
-
-    /* Fill in request message */
-    m.m_type = REQ_CLONE_OPCL;
-    m.REQ_DEV = req->dev;
+/* Check to see if the file system on which the inode 'ip' resides is mounted
+ * read only.  If so, return EROFS, else return OK.
+ */
+  register struct vmnt *mp;
 
-    /* Send/rec request */
-    if ((r = fs_sendrec(req->fs_e, &m)) != OK) return r;
-    
-    /* Fill in response structure */
-    res->fs_e = m.m_source;
-    res->inode_nr = m.RES_INODE_NR;
-    res->fmode = m.RES_MODE;
-    res->fsize = m.RES_FILE_SIZE;
-    res->dev = m.RES_DEV;
-    res->inode_index = m.RES_INODE_INDEX;
-    
-    return OK;
+  mp = vp->v_vmnt;
+  return(mp->m_flags ? EROFS : OK);
 }
 
 
+/* This file contains the wrapper functions for issueing a request
+ * and receiving response from FS processes.
+ * Each function builds a request message according to the request
+ * parameter, calls the most low-level fs_sendrec and copies
+ * back the response.
+ * The low-level fs_sendrec handles the recovery mechanism from
+ * a dead driver and reissues the request.
+ *
+ *  Sep 2006 (Balazs Gerofi)
+ */
+
+#include "fs.h"
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
+#include <minix/callnr.h>
+#include <minix/com.h>
+#include <minix/keymap.h>
+#include <minix/const.h>
+#include <minix/endpoint.h>
+#include <minix/u64.h>
+#include <unistd.h>
+
+#include <minix/vfsif.h>
+#include "fproc.h"
+#include "vmnt.h"
+#include "vnode.h"
+#include "param.h"
+
+FORWARD _PROTOTYPE(int fs_sendrec_f, (char *file, int line, endpoint_t fs_e, message *reqm));
+
+#define fs_sendrec(e, m) fs_sendrec_f(__FILE__, __LINE__, (e), (m))
+
 
 /*===========================================================================*
- *                             req_ftrunc                                   *
+ *                     req_breadwrite                                       *
  *===========================================================================*/
-PUBLIC int req_ftrunc(req)
-ftrunc_req_t *req;
+PUBLIC int req_breadwrite(fs_e, user_e, dev, pos, num_of_bytes, user_addr,
+       rw_flag, new_posp, cum_iop)
+endpoint_t fs_e;
+endpoint_t user_e;
+dev_t dev;
+u64_t pos;
+unsigned int num_of_bytes;
+char *user_addr;
+int rw_flag;
+u64_t *new_posp;
+unsigned int *cum_iop;
 {
+    int r;
+    cp_grant_id_t gid;
     message m;
 
+    gid= cpf_grant_magic(fs_e, user_e, (vir_bytes)user_addr,
+       num_of_bytes, (rw_flag == READING ? CPF_WRITE : CPF_READ));
+    if (gid == -1)
+       panic(__FILE__, "req_breadwrite: cpf_grant_magic failed", NO_NUM);
+
     /* Fill in request message */
-    m.m_type = REQ_FTRUNC;
-    m.REQ_FD_INODE_NR = req->inode_nr;
-    m.REQ_FD_START = req->start;
-    m.REQ_FD_END = req->end;
+    m.m_type = rw_flag == READING ? REQ_BREAD_S : REQ_BWRITE_S;
+    m.REQ_XFD_BDEV = dev;
+    m.REQ_XFD_GID = gid;
+    m.REQ_XFD_POS_LO = ex64lo(pos);
+    m.REQ_XFD_POS_HI = ex64hi(pos);
+    m.REQ_XFD_NBYTES = num_of_bytes;
 
     /* Send/rec request */
-    return fs_sendrec(req->fs_e, &m);
+    r = fs_sendrec(fs_e, &m);
+
+    cpf_revoke(gid);
+
+    if (r != OK) return r;
+
+    /* Fill in response structure */
+    *new_posp = make64(m.RES_XFD_POS_LO, m.RES_XFD_POS_HI);
+    *cum_iop = m.RES_XFD_CUM_IO;
+
+    return OK;
 }
 
 
 /*===========================================================================*
- *                             req_chmod                                    *
+ *                             req_chmod                                    *
  *===========================================================================*/
-PUBLIC int req_chmod(req, ch_mode)
-chmod_req_t *req;
-int *ch_mode;
+PUBLIC int req_chmod(fs_e, inode_nr, rmode, new_modep)
+int fs_e;
+ino_t inode_nr;
+mode_t rmode;
+mode_t *new_modep;
 {
     message m;
     int r;
 
     /* Fill in request message */
     m.m_type = REQ_CHMOD;
-    m.REQ_INODE_NR = req->inode_nr;
-    m.REQ_MODE = req->rmode;
-    m.REQ_UID = req->uid;
-    m.REQ_GID = req->gid;
+    m.REQ_INODE_NR = inode_nr;
+    m.REQ_MODE = rmode;
+    m.REQ_UID = fp->fp_effuid;
+    m.REQ_GID = fp->fp_effgid;
 
     /* Send/rec request */
-    r = fs_sendrec(req->fs_e, &m);
+    r = fs_sendrec(fs_e, &m);
 
     /* Copy back actual mode. */
-    if(ch_mode) *ch_mode = m.RES_MODE;
+    if (r == OK)
+       *new_modep = m.RES_MODE;
 
     return r;
 }
 
 
+/* Structure for REQ_CHOWN request */
+typedef struct chown_req {
+        int fs_e;
+        ino_t inode_nr;
+        uid_t uid;
+        gid_t gid;
+        uid_t newuid;
+        gid_t newgid;
+} chown_req_t;
+
+
 /*===========================================================================*
  *                             req_chown                                    *
  *===========================================================================*/
-PUBLIC int req_chown(req, ch_mode)
-chown_req_t *req;
-int *ch_mode;
+PUBLIC int req_chown(fs_e, inode_nr, newuid, newgid, new_modep)
+endpoint_t fs_e;
+ino_t inode_nr;
+uid_t newuid;
+gid_t newgid;
+mode_t *new_modep;
 {
     message m;
     int r;
 
     /* Fill in request message */
     m.m_type = REQ_CHOWN;
-    m.REQ_INODE_NR = req->inode_nr;
-    m.REQ_UID = req->uid;
-    m.REQ_GID = req->gid;
-    m.REQ_NEW_UID = req->newuid;
-    m.REQ_NEW_GID = req->newgid;
+    m.REQ_INODE_NR = inode_nr;
+    m.REQ_UID = fp->fp_effuid;
+    m.REQ_GID = fp->fp_effgid;
+    m.REQ_NEW_UID = newuid;
+    m.REQ_NEW_GID = newgid;
 
     /* Send/rec request */
-    r = fs_sendrec(req->fs_e, &m);
+    r = fs_sendrec(fs_e, &m);
 
     /* Return new mode to caller. */
-    if(ch_mode) *ch_mode = m.RES_MODE;
+    *new_modep = m.RES_MODE;
 
     return r;
 }
 
 
 /*===========================================================================*
- *                             req_access                                   *
+ *                             req_create                                   *
  *===========================================================================*/
-PUBLIC int req_access(req)
-access_req_t *req;
+int req_create(fs_e, inode_nr, omode, uid, gid, path, res)
+int fs_e;
+ino_t inode_nr;
+int omode;
+uid_t uid;
+gid_t gid;
+char *path;
+node_details_t *res; 
 {
+    int r;
+    cp_grant_id_t grant_id;
+    size_t len;
     message m;
 
-    /* Fill in request message */
-    m.m_type = REQ_ACCESS;
-    m.REQ_INODE_NR = req->inode_nr;
-    m.REQ_MODE = req->amode;
-    m.REQ_UID = req->uid;
-    m.REQ_GID = req->gid;
-
-    /* Send/rec request */
-    return fs_sendrec(req->fs_e, &m);
-}
-
-
-/*===========================================================================*
- *                             req_mknod                                    *
- *===========================================================================*/
-PUBLIC int req_mknod(req)
-mknod_req_t *req;
-{
-    message m;
+    len= strlen(path) + 1;
+    grant_id= cpf_grant_direct(fs_e, (vir_bytes)path, len, CPF_READ);
+    if (grant_id == -1)
+       panic(__FILE__, "req_create: cpf_grant_direct failed", NO_NUM);
 
     /* Fill in request message */
-    m.m_type = REQ_MKNOD;
-    m.REQ_INODE_NR = req->inode_nr;
-    m.REQ_MODE = req->rmode;
-    m.REQ_DEV = req->dev;
-    m.REQ_UID = req->uid;
-    m.REQ_GID = req->gid;
-    m.REQ_PATH = req->lastc;
-    m.REQ_PATH_LEN = strlen(req->lastc) + 1;
+    m.m_type = REQ_CREATE_S;
+    m.REQ_INODE_NR = inode_nr;
+    m.REQ_MODE = omode;
+    m.REQ_UID = uid;
+    m.REQ_GID = gid;
+    m.REQ_GRANT = grant_id;
+    m.REQ_PATH_LEN = len;
 
     /* Send/rec request */
-    return fs_sendrec(req->fs_e, &m);
-}
+    r = fs_sendrec(fs_e, &m);
 
+    cpf_revoke(grant_id);
 
-/*===========================================================================*
- *                             req_mkdir                                    *
- *===========================================================================*/
-PUBLIC int req_mkdir(req)
-mkdir_req_t *req;
-{
-    message m;
+    if (r != OK) return r;
 
-    /* Fill in request message */
-    m.m_type = REQ_MKDIR;
-    m.REQ_INODE_NR = req->d_inode_nr;
-    m.REQ_MODE = req->rmode;
-    m.REQ_UID = req->uid;
-    m.REQ_GID = req->gid;
-    m.REQ_PATH = req->lastc;
-    m.REQ_PATH_LEN = strlen(req->lastc) + 1;
+    /* Fill in response structure */
+    res->fs_e = m.m_source;
+    res->inode_nr = m.RES_INODE_NR;
+    res->fmode = m.RES_MODE;
+    res->fsize = m.RES_FILE_SIZE;
+    res->uid = m.RES_UID;
+    res->gid = m.RES_GID;
+    res->dev = m.RES_DEV;
+    res->inode_index = m.RES_INODE_INDEX;
 
-    /* Send/rec request */
-    return fs_sendrec(req->fs_e, &m);
+    return OK;
 }
 
 
-
 /*===========================================================================*
- *                             req_inhibread                                *
+ *                             req_flush                                    *
  *===========================================================================*/
-PUBLIC int req_inhibread(req)
-node_req_t *req;
+PUBLIC int req_flush(fs_e, dev)
+endpoint_t fs_e; 
+dev_t dev;
 {
     message m;
 
     /* Fill in request message */
-    m.m_type = REQ_INHIBREAD;
-    m.REQ_INODE_NR = req->inode_nr;
-
+    m.m_type = REQ_FLUSH;
+    m.REQ_DEV = dev;
+    
     /* Send/rec request */
-    return fs_sendrec(req->fs_e, &m);
+    return fs_sendrec(fs_e, &m);
 }
 
 
 /*===========================================================================*
- *                             req_stat                                     *
+ *                             req_fstatfs                                  *
  *===========================================================================*/
-PUBLIC int req_stat(fs_e, inode_nr, who_e, buf, pos)
+PUBLIC int req_fstatfs(fs_e, inode_nr, who_e, buf)
 int fs_e;
 ino_t inode_nr;
 int who_e;
 char *buf;
-int pos;
 {
-  cp_grant_id_t gid;
   int r;
+  cp_grant_id_t gid;
   message m;
-  struct stat sb;
 
-  if (pos != 0)
-  {
-       gid= cpf_grant_direct(fs_e, (vir_bytes)&sb, sizeof(struct stat),
-               CPF_WRITE);
-  }
-  else
-  {
-       gid= cpf_grant_magic(fs_e, who_e, (vir_bytes)buf, sizeof(struct stat),
+  gid= cpf_grant_magic(fs_e, who_e, (vir_bytes)buf, sizeof(struct statfs),
                CPF_WRITE);
-  }
   if (gid < 0)
        return gid;
 
   /* Fill in request message */
-  m.m_type = REQ_STAT;
+  m.m_type = REQ_FSTATFS;
   m.REQ_INODE_NR = inode_nr;
   m.REQ_GRANT = gid;
 
@@ -455,517 +524,805 @@ int pos;
 
   cpf_revoke(gid);
 
-  if (r == OK && pos != 0)
-  {
-       sb.st_size -= pos;
-       r= sys_vircopy(SELF, D, (vir_bytes)&sb, who_e, D, (vir_bytes)buf, 
-               sizeof(struct stat));
-  }
-
   return r;
 }
 
 
 /*===========================================================================*
- *                             req_fstatfs                                  *
+ *                             req_ftrunc                                   *
  *===========================================================================*/
-PUBLIC int req_fstatfs(fs_e, inode_nr, who_e, buf)
-int fs_e;
+PUBLIC int req_ftrunc(fs_e, inode_nr, start, end)
+endpoint_t fs_e;
 ino_t inode_nr;
-int who_e;
-char *buf;
+off_t start;
+off_t end;
 {
-  int r;
-  cp_grant_id_t gid;
-  message m;
+    message m;
 
-  gid= cpf_grant_magic(fs_e, who_e, (vir_bytes)buf, sizeof(struct statfs),
-               CPF_WRITE);
-  if (gid < 0)
-       return gid;
+    /* Fill in request message */
+    m.m_type = REQ_FTRUNC;
+    m.REQ_FD_INODE_NR = inode_nr;
+    m.REQ_FD_START = start;
+    m.REQ_FD_END = end;
 
-  /* Fill in request message */
-  m.m_type = REQ_FSTATFS;
-  m.REQ_INODE_NR = inode_nr;
-  m.REQ_GRANT = gid;
+    /* Send/rec request */
+    return fs_sendrec(fs_e, &m);
+}
 
-  /* Send/rec request */
-  r= fs_sendrec(fs_e, &m);
 
-  cpf_revoke(gid);
+/*===========================================================================*
+ *                             req_getdents                                 *
+ *===========================================================================*/
+PUBLIC int req_getdents(fs_e, inode_nr, pos, gid, size, pos_change)
+endpoint_t fs_e;
+ino_t inode_nr;
+off_t pos;
+cp_grant_id_t gid;
+size_t size;
+off_t *pos_change;
+{
+       int r;
+       message m;
 
-  return r;
+       m.m_type= REQ_GETDENTS;
+       m.REQ_GDE_INODE= inode_nr;
+       m.REQ_GDE_GRANT= gid;
+       m.REQ_GDE_SIZE= size;
+       m.REQ_GDE_POS= pos;
+
+       r = fs_sendrec(fs_e, &m);
+       *pos_change= m.RES_GDE_POS_CHANGE;
+       return r;
 }
 
 
 /*===========================================================================*
- *                             req_unlink                                   *
+ *                             req_inhibread                                *
  *===========================================================================*/
-PUBLIC int req_unlink(req)
-unlink_req_t *req;
+PUBLIC int req_inhibread(fs_e, inode_nr)
+endpoint_t fs_e;
+ino_t inode_nr;
 {
     message m;
 
     /* Fill in request message */
-    m.m_type = REQ_UNLINK;
-    m.REQ_INODE_NR = req->d_inode_nr;
-    m.REQ_UID = req->uid;
-    m.REQ_GID = req->gid;
-    m.REQ_PATH = req->lastc;
-    m.REQ_PATH_LEN = strlen(req->lastc) + 1;
+    m.m_type = REQ_INHIBREAD;
+    m.REQ_INODE_NR = inode_nr;
 
     /* Send/rec request */
-    return fs_sendrec(req->fs_e, &m);
+    return fs_sendrec(fs_e, &m);
 }
 
 
 /*===========================================================================*
- *                             req_rmdir                                    *
+ *                             req_link                                     *
  *===========================================================================*/
-PUBLIC int req_rmdir(req)
-unlink_req_t *req;
+PUBLIC int req_link(fs_e, link_parent, lastc, linked_file)
+endpoint_t fs_e;
+ino_t link_parent;
+char *lastc;
+ino_t linked_file;
 {
+    int r;
+    cp_grant_id_t gid;
+    size_t len;
     message m;
 
+    len= strlen(lastc) + 1;
+    gid= cpf_grant_direct(fs_e, (vir_bytes)lastc, len, CPF_READ);
+    if (gid == -1)
+       panic(__FILE__, "req_link: cpf_grant_direct failed", NO_NUM);
+
     /* Fill in request message */
-    m.m_type = REQ_RMDIR;
-    m.REQ_INODE_NR = req->d_inode_nr;
-    m.REQ_UID = req->uid;
-    m.REQ_GID = req->gid;
-    m.REQ_PATH = req->lastc;
-    m.REQ_PATH_LEN = strlen(req->lastc) + 1;
+    m.m_type = REQ_LINK_S;
+    m.REQ_LINKED_FILE = linked_file;
+    m.REQ_LINK_PARENT = link_parent;
+    m.REQ_GRANT = gid;
+    m.REQ_PATH_LEN = len;
 
     /* Send/rec request */
-    return fs_sendrec(req->fs_e, &m);
-}
+    r = fs_sendrec(fs_e, &m);
 
+    cpf_revoke(gid);
+
+    return r;
+}
+    
 
 /*===========================================================================*
- *                             req_utime                                    *
+ *                             req_lookup                                   *
  *===========================================================================*/
-PUBLIC int req_utime(req)
-utime_req_t *req;
+PUBLIC int req_lookup(fs_e, path_off, dir_ino, root_ino, uid, gid, flags, res)
+endpoint_t fs_e;
+size_t path_off;
+ino_t dir_ino;
+ino_t root_ino;
+uid_t uid;
+gid_t gid;
+int flags;
+lookup_res_t *res;
 {
+    int r;
+    size_t len;
+    cp_grant_id_t grant_id;
     message m;
 
+#if 0
+    printf("req_lookup_s: fs %d, ino %d, root %d, string (off %d) '%s'\n",
+       fs_e, dir_ino, root_ino, path_off, user_fullpath+path_off);
+#endif
+
+    grant_id= cpf_grant_direct(fs_e, (vir_bytes)user_fullpath,
+       sizeof(user_fullpath), CPF_READ|CPF_WRITE);
+    if (grant_id == -1)
+       panic(__FILE__, "req_lookup_s: cpf_grant_direct failed", NO_NUM);
+    len= strlen(user_fullpath+path_off) + 1;
+
     /* Fill in request message */
-    m.m_type = REQ_UTIME;
-    m.REQ_INODE_NR = req->inode_nr;
-    m.REQ_UID = req->uid;
-    m.REQ_GID = req->gid;
-    m.REQ_ACTIME = req->actime;
-    m.REQ_MODTIME = req->modtime;
+    m.m_type = REQ_LOOKUP_S;
+    m.REQ_L_GRANT = grant_id;
+    m.REQ_L_PATH_LEN = len;
+    m.REQ_L_PATH_SIZE = sizeof(user_fullpath);
+    m.REQ_L_PATH_OFF = path_off;
+    m.REQ_L_DIR_INO = dir_ino;
+    m.REQ_L_ROOT_INO = root_ino;
+    m.REQ_L_FLAGS = flags;
+    m.REQ_L_UID = uid;
+    m.REQ_L_GID = gid;
 
     /* Send/rec request */
-    return fs_sendrec(req->fs_e, &m);
+    r = fs_sendrec(fs_e, &m);
+
+    cpf_revoke(grant_id);
+
+    /* Fill in response according to the return value */
+    res->fs_e = m.m_source;
+    switch (r) {
+        case OK:
+            res->inode_nr = m.RES_INODE_NR;
+            res->fmode = m.RES_MODE;
+            res->fsize = m.RES_FILE_SIZE;
+            res->dev = m.RES_DEV;
+           res->uid= m.RES_UID;
+           res->gid= m.RES_GID;
+            break;
+        case EENTERMOUNT:
+            res->inode_nr = m.RES_INODE_NR;
+            res->char_processed = m.RES_OFFSET;
+           res->symloop = m.RES_SYMLOOP2;
+           break;
+        case ELEAVEMOUNT:
+            res->char_processed = m.RES_OFFSET;
+           res->symloop = m.RES_SYMLOOP2;
+           break;
+        case ESYMLINK:
+            res->char_processed = m.RES_OFFSET;
+            res->symloop = m.RES_SYMLOOP2;
+            break;
+       default:
+           break;
+    }
+
+    return r;
 }
 
 
 /*===========================================================================*
- *                             req_stime                                    *
+ *                             req_mkdir                                    *
  *===========================================================================*/
-PUBLIC int req_stime(fs_e, boottime)
-endpoint_t fs_e; 
-time_t boottime;
+PUBLIC int req_mkdir(fs_e, inode_nr, lastc, uid, gid, dmode)
+endpoint_t fs_e;
+ino_t inode_nr;
+char *lastc;
+uid_t uid;
+gid_t gid;
+mode_t dmode;
 {
+    int r;
+    cp_grant_id_t grant_id;
+    size_t len;
     message m;
 
+    len= strlen(lastc) + 1;
+    grant_id= cpf_grant_direct(fs_e, (vir_bytes)lastc, len, CPF_READ);
+    if (gid == -1)
+       panic(__FILE__, "req_mkdir: cpf_grant_direct failed", NO_NUM);
+
     /* Fill in request message */
-    m.m_type = REQ_STIME;
-    m.REQ_BOOTTIME = boottime;
-    
+    m.m_type = REQ_MKDIR_S;
+    m.REQ_INODE_NR = inode_nr;
+    m.REQ_MODE = dmode;
+    m.REQ_UID = uid;
+    m.REQ_GID = gid;
+    m.REQ_GRANT = grant_id;
+    m.REQ_PATH_LEN = len;
+
     /* Send/rec request */
-    return fs_sendrec(fs_e, &m);
+    r = fs_sendrec(fs_e, &m);
+
+    cpf_revoke(grant_id);
+
+    return r;
 }
 
 
+/* Structure for REQ_MKNOD request */
+typedef struct mknod_req {
+        int fs_e;
+        ino_t inode_nr;
+        uid_t uid;
+        gid_t gid;
+        mode_t rmode;
+        dev_t dev;
+        char *lastc;
+} mknod_req_t;
+
+
+
 /*===========================================================================*
- *                             req_sync                                     *
+ *                             req_newnode                                  *
  *===========================================================================*/
-PUBLIC int req_sync(fs_e)
-endpoint_t fs_e; 
+PUBLIC int req_newnode(fs_e, uid, gid, dmode, dev, res)
+endpoint_t fs_e;
+uid_t uid;
+gid_t gid;
+mode_t dmode;
+dev_t dev;
+struct node_details *res;
 {
+    int r;
     message m;
 
     /* Fill in request message */
-    m.m_type = REQ_SYNC;
-    
+    m.m_type = REQ_NEWNODE;
+    m.REQ_MODE = dmode;
+    m.REQ_DEVx = dev;
+    m.REQ_UID = uid;
+    m.REQ_GID = gid;
+
     /* Send/rec request */
-    return fs_sendrec(fs_e, &m);
+    r = fs_sendrec(fs_e, &m);
+
+    res->fs_e = m.m_source;
+    res->inode_nr = m.RES_INODE_NR;
+    res->fmode = m.RES_MODE;
+    res->fsize = m.RES_FILE_SIZE;
+    res->dev = m.RES_DEV;
+    res->uid= m.RES_UID;
+    res->gid= m.RES_GID;
+
+    return r;
 }
 
 
 /*===========================================================================*
- *                             req_link                                     *
+ *                             req_mountpoint                               *
  *===========================================================================*/
-PUBLIC int req_link(req)
-link_req_t *req;
+PUBLIC int req_mountpoint(fs_e, inode_nr)
+endpoint_t fs_e;
+ino_t inode_nr;
 {
+    int r;
     message m;
 
     /* Fill in request message */
-    m.m_type = REQ_LINK;
-    m.REQ_LINKED_FILE = req->linked_file;
-    m.REQ_LINK_PARENT = req->link_parent;
-    m.REQ_UID = req->uid;
-    m.REQ_GID = req->gid;
-    m.REQ_PATH = req->lastc;
-    m.REQ_PATH_LEN = strlen(req->lastc) + 1;
+    m.m_type = REQ_MOUNTPOINT_S;
+    m.REQ_INODE_NR = inode_nr;
 
     /* Send/rec request */
-    return fs_sendrec(req->fs_e, &m);
+    return fs_sendrec(fs_e, &m);
 }
-    
+
 
 /*===========================================================================*
- *                             req_slink                                    *
+ *                             req_mknod                                    *
  *===========================================================================*/
-PUBLIC int req_slink(req)
-slink_req_t *req;
+PUBLIC int req_mknod(fs_e, inode_nr, lastc, uid, gid, dmode, dev)
+endpoint_t fs_e;
+ino_t inode_nr;
+char *lastc;
+uid_t uid;
+gid_t gid;
+mode_t dmode;
+dev_t dev;
 {
+    int r;
+    size_t len;
+    cp_grant_id_t grant_id;
     message m;
 
+    len= strlen(lastc) + 1;
+    grant_id= cpf_grant_direct(fs_e, (vir_bytes)lastc, len, CPF_READ);
+    if (gid == -1)
+       panic(__FILE__, "req_mknod: cpf_grant_direct failed", NO_NUM);
+
     /* Fill in request message */
-    m.m_type = REQ_SLINK;
-    m.REQ_INODE_NR = req->parent_dir;
-    m.REQ_UID = req->uid;
-    m.REQ_GID = req->gid;
-    m.REQ_PATH = req->lastc;
-    m.REQ_PATH_LEN = strlen(req->lastc) + 1;
-    m.REQ_WHO_E = req->who_e;
-    m.REQ_USER_ADDR = req->path_addr;
-    m.REQ_SLENGTH = req->path_length;
+    m.m_type = REQ_MKNOD_S;
+    m.REQ_INODE_NR = inode_nr;
+    m.REQ_MODE = dmode;
+    m.REQ_DEVx = dev;
+    m.REQ_UID = uid;
+    m.REQ_GID = gid;
+    m.REQ_GRANT = grant_id;
+    m.REQ_PATH_LEN = len;
 
     /* Send/rec request */
-    return fs_sendrec(req->fs_e, &m);
+    r = fs_sendrec(fs_e, &m);
+
+    cpf_revoke(grant_id);
+
+    return r;
 }
 
 
 /*===========================================================================*
- *                             req_rdlink                                   *
+ *                             req_putnode                                  *
  *===========================================================================*/
-PUBLIC int req_rdlink(req)
-rdlink_req_t *req;
+PUBLIC int req_putnode(fs_e, inode_nr, count)
+int fs_e;
+ino_t inode_nr;
+int count;
 {
     message m;
 
     /* Fill in request message */
-    m.m_type = REQ_RDLINK;
-    m.REQ_INODE_NR = req->inode_nr;
-    m.REQ_UID = req->uid;
-    m.REQ_GID = req->gid;
-    m.REQ_WHO_E = req->who_e;
-    m.REQ_USER_ADDR = req->path_buffer;
-    m.REQ_SLENGTH = req->max_length;
+    m.m_type = REQ_PUTNODE;
+    m.REQ_INODE_NR = inode_nr;
+    m.REQ_COUNT = count;
 
     /* Send/rec request */
-    return fs_sendrec(req->fs_e, &m);
+    return fs_sendrec(fs_e, &m);
 }
 
 
 /*===========================================================================*
- *                             req_rename                                   *
+ *                             req_rdlink                                   *
  *===========================================================================*/
-PUBLIC int req_rename(req)
-rename_req_t *req;
+PUBLIC int req_rdlink(fs_e, inode_nr, who_e, buf, len)
+endpoint_t fs_e;
+ino_t inode_nr;
+endpoint_t who_e;
+vir_bytes buf;
+size_t len;
 {
     message m;
+    int r;
+    cp_grant_id_t gid;
+
+    gid= cpf_grant_magic(fs_e, who_e, buf, len, CPF_WRITE);
+    if (gid == -1)
+       panic(__FILE__, "req_rdlink: cpf_grant_magic failed", NO_NUM);
 
     /* Fill in request message */
-    m.m_type = REQ_RENAME;
-    m.REQ_OLD_DIR = req->old_dir;
-    m.REQ_NEW_DIR = req->new_dir;
-    m.REQ_UID = req->uid;
-    m.REQ_GID = req->gid;
-    m.REQ_PATH = req->old_name;
-    m.REQ_PATH_LEN = strlen(req->old_name) + 1;
-    m.REQ_USER_ADDR = req->new_name;
-    m.REQ_SLENGTH = strlen(req->new_name) + 1;
+    m.m_type = REQ_RDLINK_S;
+    m.REQ_INODE_NR = inode_nr;
+    m.REQ_GRANT = gid;
+    m.REQ_SLENGTH = len;
 
     /* Send/rec request */
-    return fs_sendrec(req->fs_e, &m);
+    r= fs_sendrec(fs_e, &m);
+
+    cpf_revoke(gid);
+
+    return r;
 }
 
 
 /*===========================================================================*
- *                             req_mountpoint                               *
+ *                             req_readsuper                                *
  *===========================================================================*/
-PUBLIC int req_mountpoint(req, res)
-mountpoint_req_t *req; 
-node_details_t *res;
+PUBLIC int req_readsuper(fs_e, label, dev, readonly, isroot, res_nodep)
+endpoint_t fs_e;
+char *label;
+dev_t dev;
+int readonly;
+int isroot;
+struct node_details *res_nodep;
 {
     int r;
+    cp_grant_id_t gid;
+    size_t len;
     message m;
 
+    len= strlen(label)+1;
+    gid= cpf_grant_direct(fs_e, (vir_bytes)label, len, CPF_READ);
+    if (gid == -1)
+       panic(__FILE__, "req_req_readsuper: cpf_grant_direct failed", NO_NUM);
+
     /* Fill in request message */
-    m.m_type = REQ_MOUNTPOINT;
-    m.REQ_INODE_NR = req->inode_nr;
-    m.REQ_UID = req->uid;
-    m.REQ_GID = req->gid;
+    m.m_type = REQ_READSUPER_S;
+    m.REQ_READONLY = readonly;
+    m.REQ_GRANT2 = gid;
+    m.REQ_DEV = dev;
+    m.REQ_ISROOT = isroot;
+    m.REQ_PATH_LEN = len;
 
     /* Send/rec request */
-    if ((r = fs_sendrec(req->fs_e, &m)) != OK) return r;
+    if ((r = fs_sendrec(fs_e, &m)) != OK) return r;
 
     /* Fill in response structure */
-    res->fs_e = m.m_source;
-    res->inode_nr = m.RES_INODE_NR;
-    res->fmode = m.RES_MODE;
-    res->fsize = m.RES_FILE_SIZE;
+    res_nodep->fs_e = m.m_source;
+    res_nodep->inode_nr = m.RES_INODE_NR;
+    res_nodep->fmode = m.RES_MODE;
+    res_nodep->fsize = m.RES_FILE_SIZE;
+    res_nodep->uid = m.RES_UID;
+    res_nodep->gid = m.RES_GID;
 
     return OK;
 }
 
+/* Structure for REQ_READ and REQ_WRITE request */
+typedef struct readwrite_req {
+       int rw_flag;
+       endpoint_t fs_e;
+        endpoint_t user_e;
+       ino_t inode_nr;
+       unsigned short inode_index;
+       int seg;
+       u64_t pos;
+       unsigned int num_of_bytes;
+       char *user_addr;
+} readwrite_req_t;
+
 
 /*===========================================================================*
- *                             req_readsuper                                *
+ *                             req_readwrite                                *
  *===========================================================================*/
-PUBLIC int req_readsuper(req, res)
-readsuper_req_t *req; 
-readsuper_res_t *res;
+PUBLIC int req_readwrite(fs_e, inode_nr, inode_index, pos, rw_flag, user_e,
+       user_addr, num_of_bytes, new_posp, cum_iop)
+endpoint_t fs_e;
+ino_t inode_nr;
+unsigned short inode_index;
+u64_t pos;
+int rw_flag;
+endpoint_t user_e;
+char *user_addr;
+unsigned int num_of_bytes;
+u64_t *new_posp;
+unsigned int *cum_iop;
 {
     int r;
+    cp_grant_id_t gid;
     message m;
 
-    /* Fill in request message */
-    m.m_type = REQ_READSUPER;
-    m.REQ_READONLY = req->readonly;
-    m.REQ_BOOTTIME = req->boottime;
-    m.REQ_DRIVER_E = req->driver_e;
-    m.REQ_DEV = req->dev;
-    m.REQ_SLINK_STORAGE = req->slink_storage;
-    m.REQ_ISROOT = req->isroot;
+    if (ex64hi(pos) != 0)
+       panic(__FILE__, "req_readwrite: pos too large", NO_NUM);
+
+    gid= cpf_grant_magic(fs_e, user_e, (vir_bytes)user_addr,
+       num_of_bytes, (rw_flag == READING ? CPF_WRITE : CPF_READ));
+    if (gid == -1)
+       panic(__FILE__, "req_readwrite: cpf_grant_magic failed", NO_NUM);
 
+    /* Fill in request message */
+    m.m_type = rw_flag == READING ? REQ_READ_S : REQ_WRITE_S;
+    m.REQ_FD_INODE_NR = inode_nr;
+    m.REQ_FD_GID = gid;
+    m.REQ_FD_POS = ex64lo(pos);
+    m.REQ_FD_NBYTES = num_of_bytes;
+    m.REQ_FD_INODE_INDEX = inode_index;
+    
     /* Send/rec request */
-    if ((r = fs_sendrec(req->fs_e, &m)) != OK) return r;
+    r = fs_sendrec(fs_e, &m);
+
+    cpf_revoke(gid);
+
+    if (r != OK) return r;
 
     /* Fill in response structure */
-    res->fs_e = m.m_source;
-    res->inode_nr = m.RES_INODE_NR;
-    res->fmode = m.RES_MODE;
-    res->fsize = m.RES_FILE_SIZE;
-    res->blocksize = m.RES_BLOCKSIZE;
-    res->maxsize = m.RES_MAXSIZE;
+    *new_posp = cvul64(m.RES_FD_POS);
+    *cum_iop = m.RES_FD_CUM_IO;
 
     return OK;
 }
 
 
 /*===========================================================================*
- *                             req_unmount                                  *
+ *                             req_rename                                   *
  *===========================================================================*/
-PUBLIC int req_unmount(fs_e)
-endpoint_t fs_e; 
+PUBLIC int req_rename(fs_e, old_dir, old_name, new_dir, new_name)
+endpoint_t fs_e;
+ino_t old_dir;
+char *old_name;
+ino_t new_dir;
+char *new_name;
 {
+    int r;
+    cp_grant_id_t gid_old, gid_new;
+    size_t len_old, len_new;
     message m;
 
+    len_old= strlen(old_name) + 1;
+    gid_old= cpf_grant_direct(fs_e, (vir_bytes)old_name, len_old,
+       CPF_READ);
+    if (gid_old == -1)
+       panic(__FILE__, "req_rename: cpf_grant_direct failed", NO_NUM);
+    len_new= strlen(new_name) + 1;
+    gid_new= cpf_grant_direct(fs_e, (vir_bytes)new_name, len_new,
+       CPF_READ);
+    if (gid_new == -1)
+       panic(__FILE__, "req_rename: cpf_grant_direct failed", NO_NUM);
+
     /* Fill in request message */
-    m.m_type = REQ_UNMOUNT;
-    
+    m.m_type = REQ_RENAME_S;
+    m.REQ_REN_OLD_DIR = old_dir;
+    m.REQ_REN_NEW_DIR = new_dir;
+    m.REQ_REN_GRANT_OLD = gid_old;
+    m.REQ_REN_LEN_OLD = len_old;
+    m.REQ_REN_GRANT_NEW = gid_new;
+    m.REQ_REN_LEN_NEW = len_new;
+
     /* Send/rec request */
-    return fs_sendrec(fs_e, &m);
+    r = fs_sendrec(fs_e, &m);
+
+    cpf_revoke(gid_old);
+    cpf_revoke(gid_new);
+
+    return r;
 }
 
 
 /*===========================================================================*
- *                             req_trunc                                    *
+ *                             req_rmdir                                    *
  *===========================================================================*/
-PUBLIC int req_trunc(req)
-trunc_req_t *req;
+PUBLIC int req_rmdir(fs_e, inode_nr, lastc)
+endpoint_t fs_e;
+ino_t inode_nr;
+char *lastc;
 {
+    int r;
+    cp_grant_id_t gid;
+    size_t len;
     message m;
 
+    len= strlen(lastc) + 1;
+    gid= cpf_grant_direct(fs_e, (vir_bytes)lastc, len, CPF_READ);
+    if (gid == -1)
+       panic(__FILE__, "req_rmdir: cpf_grant_direct failed", NO_NUM);
+
     /* Fill in request message */
-    m.m_type = REQ_TRUNC;
-    m.REQ_FD_INODE_NR = req->inode_nr;
-    m.REQ_UID = req->uid;
-    m.REQ_GID = req->gid;
-    m.REQ_LENGTH = req->length;
+    m.m_type = REQ_RMDIR_S;
+    m.REQ_INODE_NR = inode_nr;
+    m.REQ_GRANT = gid;
+    m.REQ_PATH_LEN = len;
 
     /* Send/rec request */
-    return fs_sendrec(req->fs_e, &m);
-}
+    r = fs_sendrec(fs_e, &m);
 
+    cpf_revoke(gid);
+
+    return r;
+}
 
 
 /*===========================================================================*
- *                             req_newdriver                                *
+ *                             req_slink                                    *
  *===========================================================================*/
-PUBLIC int req_newdriver(fs_e, dev, driver_e)
+PUBLIC int req_slink(fs_e, inode_nr, lastc, who_e, path_addr, path_length,
+       uid, gid)
 endpoint_t fs_e;
-Dev_t dev;
-endpoint_t driver_e;
+ino_t inode_nr;
+char *lastc;
+endpoint_t who_e;
+char *path_addr;
+unsigned short path_length;
+uid_t uid;
+gid_t gid;
 {
-/* Note: this is the only request function that doesn't use the 
- * fs_sendrec internal routine, since we want to avoid the dead
- * driver recovery mechanism here. This function is actually called 
- * during the recovery.
- */
-    message m;
     int r;
+    size_t len;
+    cp_grant_id_t gid_name, gid_buf;
+    message m;
+
+    len= strlen(lastc) + 1;
+    gid_name= cpf_grant_direct(fs_e, (vir_bytes)lastc, len,
+       CPF_READ);
+    if (gid_name == -1)
+       panic(__FILE__, "req_slink: cpf_grant_direct failed", NO_NUM);
+
+    gid_buf= cpf_grant_magic(fs_e, who_e, (vir_bytes)path_addr,
+       path_length, CPF_READ);
+    if (gid_buf == -1)
+    {
+       cpf_revoke(gid_buf);
+       panic(__FILE__, "req_slink: cpf_grant_magic failed", NO_NUM);
+    }
 
     /* Fill in request message */
-    m.m_type = REQ_NEW_DRIVER;
-    m.REQ_DEV = dev;
-    m.REQ_DRIVER_E = driver_e;
+    m.m_type = REQ_SLINK_S;
+    m.REQ_INODE_NR = inode_nr;
+    m.REQ_UID = uid;
+    m.REQ_GID = gid;
+    m.REQ_GRANT = gid_name;
+    m.REQ_PATH_LEN = len;
+    m.REQ_GRANT2 = gid_buf;
+    m.REQ_SLENGTH = path_length;
 
-    /* Issue request */
-    if ((r = sendrec(fs_e, &m)) != OK) {
-        printf("VFSreq_newdriver: error sending message to %d: %d\n", fs_e, r);
-        return r;
-    }
+    /* Send/rec request */
+    r = fs_sendrec(fs_e, &m);
 
-    return OK;
+    cpf_revoke(gid_name);
+    cpf_revoke(gid_buf);
+
+    return r;
 }
 
 
 /*===========================================================================*
- *                             req_lookup                                   *
+ *                             req_stat                                     *
  *===========================================================================*/
-PUBLIC int req_lookup(req, res)
-lookup_req_t *req; 
-lookup_res_t *res;
+PUBLIC int req_stat(fs_e, inode_nr, who_e, buf, pos)
+int fs_e;
+ino_t inode_nr;
+int who_e;
+char *buf;
+int pos;
 {
-    int r;
-    message m;
+  cp_grant_id_t gid;
+  int r;
+  message m;
+  struct stat sb;
 
-    /* Fill in request message */
-    m.m_type = REQ_LOOKUP;
-    m.REQ_PATH = req->path;
-    m.REQ_PATH_LEN = strlen(req->path) + 1;
-    m.REQ_USER_ADDR = req->lastc;
-    m.REQ_FLAGS = req->flags;
-    
-    m.REQ_INODE_NR = req->start_dir;
-    m.REQ_CHROOT_NR = req->root_dir;
-    m.REQ_UID = req->uid;
-    m.REQ_GID = req->gid;
-    m.REQ_SYMLOOP = req->symloop;
+  if (pos != 0)
+  {
+       gid= cpf_grant_direct(fs_e, (vir_bytes)&sb, sizeof(struct stat),
+               CPF_WRITE);
+  }
+  else
+  {
+       gid= cpf_grant_magic(fs_e, who_e, (vir_bytes)buf, sizeof(struct stat),
+               CPF_WRITE);
+  }
+  if (gid < 0)
+       return gid;
 
-    /* Send/rec request */
-    r = fs_sendrec(req->fs_e, &m);
+  /* Fill in request message */
+  m.m_type = REQ_STAT;
+  m.REQ_INODE_NR = inode_nr;
+  m.REQ_GRANT = gid;
 
-    /* Fill in response according to the return value */
-    res->fs_e = m.m_source;
-    switch (r) {
-        case OK:
-       default:
-            res->inode_nr = m.RES_INODE_NR;
-            res->fmode = m.RES_MODE;
-            res->fsize = m.RES_FILE_SIZE;
-            res->dev = m.RES_DEV;
-           res->uid= m.RES_UID;
-           res->gid= m.RES_GID;
-            res->char_processed = m.RES_OFFSET;                /* For ENOENT */
-            break;
-        case EENTERMOUNT:
-            res->inode_nr = m.RES_INODE_NR;
-        case ELEAVEMOUNT:
-        case ESYMLINK:
-            res->char_processed = m.RES_OFFSET;
-            res->symloop = m.RES_SYMLOOP;
-            break;
-    }
+  /* Send/rec request */
+  r= fs_sendrec(fs_e, &m);
 
-    return r;
+  cpf_revoke(gid);
+
+  if (r == OK && pos != 0)
+  {
+       sb.st_size -= pos;
+       r= sys_vircopy(SELF, D, (vir_bytes)&sb, who_e, D, (vir_bytes)buf, 
+               sizeof(struct stat));
+  }
+
+  return r;
 }
 
 
 /*===========================================================================*
- *                     req_breadwrite                                       *
+ *                             req_sync                                     *
  *===========================================================================*/
-int req_breadwrite(req, res)
-breadwrite_req_t *req; 
-readwrite_res_t *res; 
+PUBLIC int req_sync(fs_e)
+endpoint_t fs_e; 
 {
-    int r;
     message m;
 
     /* Fill in request message */
-    m.m_type = req->rw_flag == READING ? REQ_BREAD : REQ_BWRITE;
-    m.REQ_XFD_BDEV = req->dev;
-    m.REQ_XFD_BLOCK_SIZE = req->blocksize;
-    m.REQ_XFD_WHO_E = req->user_e;
-    m.REQ_XFD_POS_LO = ex64lo(req->pos);
-    m.REQ_XFD_POS_HI = ex64hi(req->pos);
-    m.REQ_XFD_NBYTES = req->num_of_bytes;
-    m.REQ_XFD_USER_ADDR = req->user_addr;
+    m.m_type = REQ_SYNC;
     
     /* Send/rec request */
-    if ((r = fs_sendrec(req->fs_e, &m)) != OK) return r;
+    return fs_sendrec(fs_e, &m);
+}
 
-    /* Fill in response structure */
-    res->new_pos = make64(m.RES_XFD_POS_LO, m.RES_XFD_POS_HI);
-    res->cum_io = m.RES_XFD_CUM_IO;
+/* Structure for REQ_UNLINK request */
+typedef struct unlink_req {
+        int fs_e;
+        ino_t d_inode_nr;
+        uid_t uid;
+        gid_t gid;
+        char *lastc;
+} unlink_req_t;
 
-    return OK;
-}
 
 
-PUBLIC int req_getdents(fs_e, inode_nr, pos, gid, size, pos_change)
+/*===========================================================================*
+ *                             req_unlink                                   *
+ *===========================================================================*/
+PUBLIC int req_unlink(fs_e, inode_nr, lastc)
 endpoint_t fs_e;
 ino_t inode_nr;
-off_t pos;
-cp_grant_id_t gid;
-size_t size;
-off_t *pos_change;
+char *lastc;
 {
-       int r;
-       message m;
+    cp_grant_id_t gid;
+    size_t len;
+    int r;
+    message m;
 
-       m.m_type= REQ_GETDENTS;
-       m.REQ_GDE_INODE= inode_nr;
-       m.REQ_GDE_GRANT= gid;
-       m.REQ_GDE_SIZE= size;
-       m.REQ_GDE_POS= pos;
+    len= strlen(lastc) + 1;
+    gid= cpf_grant_direct(fs_e, (vir_bytes)lastc, len, CPF_READ);
+    if (gid == -1)
+       panic(__FILE__, "req_unlink: cpf_grant_direct failed", NO_NUM);
 
-       r = fs_sendrec(fs_e, &m);
-       *pos_change= m.RES_GDE_POS_CHANGE;
-       return r;
+    /* Fill in request message */
+    m.m_type = REQ_UNLINK_S;
+    m.REQ_INODE_NR = inode_nr;
+    m.REQ_GRANT = gid;
+    m.REQ_PATH_LEN = len;
+
+    /* Send/rec request */
+    r = fs_sendrec(fs_e, &m);
+
+    cpf_revoke(gid);
+
+    return r;
 }
 
 
 /*===========================================================================*
- *                             req_flush                                    *
+ *                             req_unmount                                  *
  *===========================================================================*/
-PUBLIC int req_flush(fs_e, dev)
+PUBLIC int req_unmount(fs_e)
 endpoint_t fs_e; 
-dev_t dev;
 {
     message m;
 
     /* Fill in request message */
-    m.m_type = REQ_FLUSH;
-    m.REQ_DEV = dev;
+    m.m_type = REQ_UNMOUNT;
     
     /* Send/rec request */
     return fs_sendrec(fs_e, &m);
 }
 
 
-#if 0           
-/*                 Wrapper pattern:                                          */
 /*===========================================================================*
- *                             req_                                 *
+ *                             req_utime                                    *
  *===========================================================================*/
-PUBLIC int req_(req, res)
-_req_t *req;
-_t *res;
+PUBLIC int req_utime(fs_e, inode_nr, actime, modtime)
+endpoint_t fs_e;
+ino_t inode_nr;
+time_t actime;
+time_t modtime;
 {
-    int r;
     message m;
 
     /* Fill in request message */
-
+    m.m_type = REQ_UTIME;
+    m.REQ_INODE_NR = inode_nr;
+    m.REQ_ACTIME = actime;
+    m.REQ_MODTIME = modtime;
 
     /* Send/rec request */
-    if ((r = fs_sendrec(req->fs_e, &m)) != OK) return r;
-    
-    /* Fill in response structure */
+    return fs_sendrec(fs_e, &m);
+}
+
+
+/*===========================================================================*
+ *                             req_newdriver                                *
+ *===========================================================================*/
+PUBLIC int req_newdriver(fs_e, dev, driver_e)
+endpoint_t fs_e;
+Dev_t dev;
+endpoint_t driver_e;
+{
+/* Note: this is the only request function that doesn't use the 
+ * fs_sendrec internal routine, since we want to avoid the dead
+ * driver recovery mechanism here. This function is actually called 
+ * during the recovery.
+ */
+    message m;
+    int r;
+
+    /* Fill in request message */
+    m.m_type = REQ_NEW_DRIVER;
+    m.REQ_DEV = dev;
+    m.REQ_DRIVER_E = driver_e;
 
+    /* Issue request */
+    if ((r = sendrec(fs_e, &m)) != OK) {
+        printf("VFSreq_newdriver: error sending message to %d: %d\n", fs_e, r);
+        return r;
+    }
 
     return OK;
 }
-#endif 
+
 
 
 
@@ -983,6 +1340,12 @@ PRIVATE int fs_sendrec_f(char *file, int line, endpoint_t fs_e, message *reqm)
   message origm, m;
   struct vmnt *vmp;
 
+  if (fs_e == PM_PROC_NR)
+  {
+       printf("from %s, %d\n", file, line);
+       panic(__FILE__, "talking to PM", NO_NUM);
+  }
+
   /* Make a copy of the request so that we can load it back in
    * case of a dead driver */
   origm = *reqm;
index ca65ac016bd4659980cc763f7cb8ac9b09419e13..087b8032b5d63ba87efcbac4681a24983c678d46 100644 (file)
@@ -7,27 +7,20 @@
 #include <sys/types.h>
 
 
-/* Structure for REQ_GETNODE and REQ_PUTNODE requests */
-typedef struct node_req {
-       endpoint_t fs_e;
-       ino_t inode_nr;
-} node_req_t;
-
-
 /* Structure for response that contains inode details */
 typedef struct node_details {
        endpoint_t fs_e;
        ino_t inode_nr;
        mode_t fmode;
        off_t fsize;
+       uid_t uid;
+       gid_t gid;
+
+       /* For faster access */
        unsigned short inode_index;
+
        /* For char/block special files */
        dev_t dev;
-       
-       /* Fields used by the exec() syscall */
-       uid_t uid;
-       gid_t gid;
-       time_t ctime;
 } node_details_t;
 
 
@@ -43,35 +36,6 @@ typedef struct open_req {
 } open_req_t;
 
 
-/* Structure for REQ_READ and REQ_WRITE request */
-typedef struct readwrite_req {
-       int rw_flag;
-       endpoint_t fs_e;
-        endpoint_t user_e;
-       ino_t inode_nr;
-       unsigned short inode_index;
-       int seg;
-       u64_t pos;
-       unsigned int num_of_bytes;
-       char *user_addr;
-} readwrite_req_t;
-
-
-/* Structure for response of REQ_READ and REQ_WRITE */
-typedef struct readwrite_res {
-       u64_t new_pos;
-       unsigned int cum_io;
-} readwrite_res_t;
-
-
-/* Structure for REQ_PIPE request */
-typedef struct pipe_req {
-        int fs_e;
-        uid_t uid;
-        gid_t gid;
-} pipe_req_t;
-
-
 /* Structure for REQ_CLONE_OPCL request */
 typedef struct clone_opcl_req {
         int fs_e;
@@ -79,147 +43,6 @@ typedef struct clone_opcl_req {
 } clone_opcl_req_t;
 
 
-/* Structure for REQ_FTRUNC request */
-typedef struct ftrunc_req {
-        int fs_e;
-        ino_t inode_nr;
-        off_t start;
-        off_t end;
-} ftrunc_req_t;
-
-
-/* Structure for REQ_CHOWN request */
-typedef struct chown_req {
-        int fs_e;
-        ino_t inode_nr;
-        uid_t uid;
-        gid_t gid;
-        uid_t newuid;
-        gid_t newgid;
-} chown_req_t;
-
-
-/* Structure for REQ_CHMOD request */
-typedef struct chmod_req {
-        int fs_e;
-        ino_t inode_nr;
-        uid_t uid;
-        gid_t gid;
-        mode_t rmode;
-} chmod_req_t;
-
-
-/* Structure for REQ_ACCESS request */
-typedef struct access_req {
-        int fs_e;
-        ino_t inode_nr;
-        uid_t uid;
-        gid_t gid;
-        mode_t amode;
-} access_req_t;
-
-
-/* Structure for REQ_MKNOD request */
-typedef struct mknod_req {
-        int fs_e;
-        ino_t inode_nr;
-        uid_t uid;
-        gid_t gid;
-        mode_t rmode;
-        dev_t dev;
-        char *lastc;
-} mknod_req_t;
-
-
-/* Structure for REQ_MKDIR request */
-typedef struct mkdir_req {
-        int fs_e;
-        ino_t d_inode_nr;
-        uid_t uid;
-        gid_t gid;
-        mode_t rmode;
-        char *lastc;
-} mkdir_req_t;
-
-
-/* Structure for REQ_UNLINK request */
-typedef struct unlink_req {
-        int fs_e;
-        ino_t d_inode_nr;
-        uid_t uid;
-        gid_t gid;
-        char *lastc;
-} unlink_req_t;
-
-
-/* Structure for REQ_UTIME request */
-typedef struct utime_req {
-        int fs_e;
-        ino_t inode_nr;
-        uid_t uid;
-        gid_t gid;
-        time_t actime;
-        time_t modtime;
-} utime_req_t;
-
-
-/* Structure for REQ_LINK request */
-typedef struct link_req {
-       endpoint_t fs_e;
-        ino_t linked_file;
-        ino_t link_parent;
-        uid_t uid;
-        gid_t gid;
-        char *lastc;
-} link_req_t;
-
-
-/* Structure for REQ_SLINK request */
-typedef struct slink_req {
-       endpoint_t fs_e;
-        ino_t parent_dir;
-        uid_t uid;
-        gid_t gid;
-        char *lastc;
-        endpoint_t who_e;
-        char *path_addr;
-        unsigned short path_length;
-} slink_req_t;
-
-
-/* Structure for REQ_RDLINK request */
-typedef struct rdlink_req {
-       endpoint_t fs_e;
-        ino_t inode_nr;
-        uid_t uid;
-        gid_t gid;
-        endpoint_t who_e;
-        char *path_buffer;
-        unsigned short max_length;
-} rdlink_req_t;
-
-
-/* Structure for REQ_RENAME request */
-typedef struct rename_req {
-       endpoint_t fs_e;
-        ino_t old_dir;
-        ino_t new_dir;
-        uid_t uid;
-        gid_t gid;
-        char *old_name;
-        char *new_name;
-} rename_req_t;
-
-
-/* Structure for REQ_MOUNTPOINT request */
-typedef struct mountpoint_req {
-       endpoint_t fs_e;
-        ino_t inode_nr;
-        uid_t uid;
-        gid_t gid;
-} mountpoint_req_t;
-
-
 /* Structure for REQ_READSUPER request */
 typedef struct readsuper_req {
        endpoint_t fs_e;
@@ -242,16 +65,6 @@ typedef struct readsuper_res {
 } readsuper_res_t;
 
         
-/* Structure for REQ_TRUNC request */
-typedef struct trunc_req {
-       endpoint_t fs_e;
-       ino_t inode_nr;
-        uid_t uid;
-        gid_t gid;
-        off_t length;
-} trunc_req_t;
-
-
 /* Structure for REQ_LOOKUP request */
 typedef struct lookup_req {
         /* Fields filled in by the caller */
@@ -285,19 +98,4 @@ typedef struct lookup_res {
 } lookup_res_t;
 
 
-/* Structure for REQ_BREAD and REQ_BWRITE request (block spec files) */
-typedef struct breadwrite_req {
-       int rw_flag;
-        short blocksize;
-       endpoint_t fs_e;
-        endpoint_t user_e;
-        endpoint_t driver_e;
-        dev_t dev;
-       u64_t pos;
-       unsigned int num_of_bytes;
-       char *user_addr;
-} breadwrite_req_t;
-
-
-
 /* Structure for REQ_ request */
index 544a315c8231e753e92d9740a02c9a176a6c2f0b..5d0954e58bef6c8da30d11a0f5c1cdd09a8de57f 100644 (file)
@@ -47,7 +47,7 @@ PUBLIC int do_fchdir()
       return ENOTDIR;
   
   /* Issue request and handle error */
-  r = forbidden(rfilp->filp_vno, X_BIT);
+  r = forbidden(rfilp->filp_vno, X_BIT, 0 /*!use_realuid*/);
   if (r != OK) return r;
   
   rfilp->filp_vno->v_ref_count++;      /* change_into expects a reference  */
@@ -122,18 +122,12 @@ int len;                  /* length of the directory name string */
 {
 /* Do the actual work for chdir() and chroot(). */
   struct vnode *vp;
-  struct lookup_req lookup_req;
   int r;
 
   if (fetch_name(name_ptr, len, M3) != OK) return(err_code);
   
-  /* Fill in lookup request fields */
-  lookup_req.path = user_fullpath;
-  lookup_req.lastc = NULL;
-  lookup_req.flags = EAT_PATH;
-        
   /* Request lookup */
-  if ((r = lookup_vp(&lookup_req, &vp)) != OK) return r;
+  if ((r = lookup_vp(0 /*flags*/, 0 /*!use_realuid*/, &vp)) != OK) return r;
 
   /* Is it a dir? */
   if ((vp->v_mode & I_TYPE) != I_DIRECTORY)
@@ -143,7 +137,7 @@ int len;                    /* length of the directory name string */
   }
 
   /* Access check */
-  r = forbidden(vp, X_BIT);
+  r = forbidden(vp, X_BIT, 0 /*!use_realuid*/);
   if (r != OK) {
         put_vnode(vp);
        return r;
@@ -174,22 +168,19 @@ struct vnode *vp;         /* this is what the inode has to become */
 PUBLIC int do_stat()
 {
 /* Perform the stat(name, buf) system call. */
-  struct node_details res;
-  struct lookup_req lookup_req;
   int r;
-    
+  struct vnode *vp;
+
   if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code);
   
-  /* Fill in lookup request fields */
-  lookup_req.path = user_fullpath;
-  lookup_req.lastc = NULL;
-  lookup_req.flags = EAT_PATH;
-        
   /* Request lookup */
-  if ((r = lookup(&lookup_req, &res)) != OK) return r;
+  if ((r = lookup_vp(0 /*flags*/, 0 /*!use_realuid*/, &vp)) != OK)
+       return r;
 
   /* Issue request */
-  return req_stat(res.fs_e, res.inode_nr, who_e, m_in.name2, 0);
+  r= req_stat(vp->v_fs_e, vp->v_inode_nr, who_e, m_in.name2, 0);
+  put_vnode(vp);
+  return r;
 }
 
 
@@ -246,13 +237,13 @@ PUBLIC int do_fstatfs()
 
 
 /*===========================================================================*
- *                             do_lstat                                      *
+ *                             do_lstat                                             *
  *===========================================================================*/
 PUBLIC int do_lstat()
 {
 /* Perform the lstat(name, buf) system call. */
-  struct node_details res;
   struct lookup_req lookup_req;
+  struct vnode *vp;
   int r;
 
   if (fetch_name(m_in.name1, m_in.name1_length, M1) != OK) return(err_code);
@@ -263,10 +254,15 @@ PUBLIC int do_lstat()
   lookup_req.flags = EAT_PATH_OPAQUE;
         
   /* Request lookup */
-  if ((r = lookup(&lookup_req, &res)) != OK) return r;
+  if ((r = lookup_vp(PATH_RET_SYMLINK, 0 /*!use_realuid*/, &vp)) != OK)
+       return r;
 
   /* Issue request */
-  return req_stat(res.fs_e, res.inode_nr, who_e, m_in.name2, 0);
+  r= req_stat(vp->v_fs_e, vp->v_inode_nr, who_e, m_in.name2, 0);
+
+  put_vnode(vp);
+
+  return r;
 }
 
 
index 035c87b3896f245bfd2292a0bc702b6d2886eea0..b784a272fbbec9c3ee276ff951a155cc1c1574bb 100644 (file)
@@ -18,6 +18,7 @@
  * A super_block slot is free if s_dev == NO_DEV. 
  */
 
+#if 0
 EXTERN struct super_block {
   ino_t s_ninodes;             /* # usable inodes on the minor device */
   zone1_t  s_nzones;           /* total device size, including bit maps etc */
@@ -53,6 +54,7 @@ EXTERN struct super_block {
   bit_t s_isearch;             /* inodes below this bit number are in use */
   bit_t s_zsearch;             /* all zones below this bit number are in use*/
 } super_block[NR_SUPERS];
+#endif
 
 #define NIL_SUPER (struct super_block *) 0
 #define IMAP           0       /* operating on the inode bit map */
index 5b27eefc748b0935b00464beb7a11cfe373d9164..859eee3d8d442fc373678a4c0fde4bb195c71749 100644 (file)
@@ -41,7 +41,7 @@ PUBLIC _PROTOTYPE (int (*call_vec[]), (void) ) = {
        do_umount,      /* 22 = umount  */
        no_sys,         /* 23 = (setuid) */
        no_sys,         /* 24 = getuid  */
-       do_stime,       /* 25 = stime   */
+       no_sys,         /* 25 = (stime) */
        no_sys,         /* 26 = ptrace  */
        no_sys,         /* 27 = alarm   */
        do_fstat,       /* 28 = fstat   */
index 806fee9a24e6b99c5106b75376934272c4b6a19c..5e34e395bfef3c5f516e3f1e38094c06330d20f0 100644 (file)
@@ -11,6 +11,7 @@
 #include "file.h"
 #include "fproc.h"
 #include "param.h"
+#include "vnode.h"
 
 #include <minix/vfsif.h>
 #include "vmnt.h"
@@ -22,10 +23,10 @@ PUBLIC int do_utime()
 {
 /* Perform the utime(name, timep) system call. */
   register int len;
-  struct utime_req req;
-  struct lookup_req lookup_req;
-  struct node_details res;
   int r;
+  uid_t uid;
+  time_t actime, modtime;
+  struct vnode *vp;
   
   /* Adjust for case of 'timep' being NULL;
    * utime_strlen then holds the actual size: strlen(name)+1.
@@ -35,46 +36,38 @@ PUBLIC int do_utime()
 
   if (fetch_name(m_in.utime_file, len, M1) != OK) return(err_code);
   
-  /* Fill in lookup request fields */
-  lookup_req.path = user_fullpath;
-  lookup_req.lastc = NULL;
-  lookup_req.flags = EAT_PATH;
-        
   /* Request lookup */
-  if ((r = lookup(&lookup_req, &res)) != OK) return r;
+  if ((r = lookup_vp(0 /*flags*/, 0 /*!use_realuid*/, &vp)) != OK) return r;
 
   /* Fill in request fields.*/
   if (m_in.utime_length == 0) {
-        req.actime = 0;        
-        req.modtime = clock_time();
+        actime = modtime = clock_time();
   } else {
-        req.actime = m_in.utime_actime;
-        req.modtime = m_in.utime_modtime;
+        actime = m_in.utime_actime;
+        modtime = m_in.utime_modtime;
   }
-  req.fs_e = res.fs_e;
-  req.inode_nr = res.inode_nr;
-  req.uid = fp->fp_effuid;
-  req.gid = fp->fp_effgid;
-  
-  /* Issue request */
-  return req_utime(&req);
-}
 
+  uid= fp->fp_effuid;
 
-/*===========================================================================*
- *                             do_stime                                     *
- *===========================================================================*/
-PUBLIC int do_stime()
-{
-  struct vmnt *vmp;
-  /* Perform the stime(tp) system call. */
-  boottime = (long) m_in.pm_stime; 
-    
-  /* Send new time for all FS processes */
-  for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; ++vmp) { 
-      if (vmp->m_fs_e) req_stime(vmp->m_fs_e, boottime);
+  r= OK;
+  if (vp->v_uid != uid && uid != SU_UID) r = EPERM;
+  if (m_in.utime_length == 0 && r != OK)
+  {
+       /* With a null times pointer, updating the times (to the current time)
+        * is allow if the object is writable. 
+        */
+       r = forbidden(vp, W_BIT, 0 /*!use_realuid*/);
   }
 
-  return OK;
+  if (r != OK)
+  {
+       put_vnode(vp);
+       return r;
+  }
+  
+  /* Issue request */
+  r= req_utime(vp->v_fs_e, vp->v_inode_nr, actime, modtime);
+  put_vnode(vp);
+  return r;
 }
 
index 19749fef0ed021c408c754cc5effaa725a0e8518..5206d3e210fc0c65137dbb5b1bc8e576ef15cded 100644 (file)
@@ -21,3 +21,13 @@ typedef struct {             /* V2.x disk inode */
   time_t d2_ctime;             /* when was inode data last changed */
   zone_t d2_zone[V2_NR_TZONES];        /* block nums for direct, ind, and dbl ind */
 } d2_inode;
+
+#if 1
+extern struct dmap {
+  int _PROTOTYPE ((*dmap_opcl), (int, Dev_t, int, int) );
+  int _PROTOTYPE ((*dmap_io), (int, message *) );
+  int dmap_driver;
+  int dmap_flags;
+} dmap[];
+#endif
+
index 97f12a3d72d76363667eb2cd11ac20f02ccfbab2..a3e893409533f37f00d8d280cb9dbdf6212cfd30 100644 (file)
@@ -143,10 +143,14 @@ PUBLIC time_t clock_time()
  * rate and that such things as leap seconds do not exist.
  */
 
-  register int k;
+  register int r;
   clock_t uptime;
+  time_t boottime;
+
+  r= getuptime2(&uptime, &boottime);
+  if (r != OK)
+       panic(__FILE__,"clock_time err", r);
 
-  if ( (k=getuptime(&uptime)) != OK) panic(__FILE__,"clock_time err", k);
   return( (time_t) (boottime + (uptime/HZ)));
 }
 
index f1916fcdb9a7121678bd80ecf7425b3a78bbd773..266c549077997c73017c3d98a9d58be4ccd0e888 100644 (file)
@@ -5,8 +5,6 @@ EXTERN struct vmnt {
   dev_t m_dev;                  /* device number */
   int m_driver_e;               /* device driver process' kernel endpoint */
   int m_flags;                  /* mount flags */
-  int m_max_file_size;          /* maximum file size on partition */
-  unsigned short m_block_size;  /* block size */
   struct vnode *m_mounted_on;   /* the vnode on which the partition is mounted */
   struct vnode *m_root_node;    /* root vnode */
 } vmnt[NR_MNTS];
index b0d2bd4fa5900a28fb4aca3ceb7b74e12a5a7f8e..6628a89cdfda29a4ebd4454df4b44a911de8461f 100644 (file)
 
 #include <minix/vfsif.h>
 
-/*===========================================================================*
- *                             get_vnode                                    *
- *===========================================================================*/
-PUBLIC struct vnode *get_vnode(int fs_e, int inode_nr)
-{
-/* get_vnode() is called to get the details of the specified inode.
- * Note that inode's usage counter in the FS is supposed to be incremented.
- */
-  struct vnode *vp, *vp2;
-  struct vmnt *vmp;
-
-  /* Request & response structures */
-  struct node_req req;
-  struct node_details res;
-
-  /* XXX remove this when debugging is complete */
-  if (find_vnode(fs_e, inode_nr) != NULL)
-       panic(__FILE__, "get_vnode: vnode already present", NO_NUM);
-  
-  /* Check whether a free vnode is avaliable */
-  if ((vp = get_free_vnode(__FILE__, __LINE__)) == NIL_VNODE) {
-        printf("VFSget_vnode: no vnode available\n");
-        return NIL_VNODE;
-  }
-  
-  /* Fill req struct */
-  req.inode_nr = inode_nr;
-  req.fs_e = fs_e;
-
-  /* Send request to FS */
-  if (req_getnode(&req, &res) != OK) {
-        printf("VFSget_vnode: couldn't find vnode\n"); 
-        return NIL_VNODE;
-  }
-
-  /* Fill in the free vnode's fields and return it */
-  vp->v_fs_e = res.fs_e;
-  vp->v_inode_nr = res.inode_nr;
-  vp->v_mode = res.fmode;
-  vp->v_size = res.fsize;
-  vp->v_sdev = res.dev;
-  
-  /* Find corresponding virtual mount object */
-  if ( (vmp = find_vmnt(vp->v_fs_e)) == NIL_VMNT)
-        printf("VFS: vmnt not found by get_vnode()\n");
-  
-  vp->v_vmnt = vmp; 
-  vp->v_dev = vmp->m_dev;
-  vp->v_fs_count = 1;
-  vp->v_ref_count = 1;
-  
-  return vp; 
-}
-
-
-/*===========================================================================*
- *                             get_vnode                                    *
- *===========================================================================*/
-PUBLIC struct vnode *get_vnode_x(int fs_e, int inode_nr)
-{
-/* get_vnode() is called to get the details of the specified inode.
- * Note that inode's usage counter in the FS is supposed to be incremented.
- */
-  struct vnode *vp, *vp2;
-  struct vmnt *vmp;
-
-  /* Request & response structures */
-  struct node_req req;
-  struct node_details res;
-
-  vp= find_vnode(fs_e, inode_nr);
-  if (vp)
-  {
-       vp->v_ref_count++;
-       return vp;
-  }
-
-  return get_vnode(fs_e, inode_nr);
-}
-
 
 /*===========================================================================*
  *                             get_free_vnode                               *
@@ -114,6 +34,7 @@ int line;
        if (vp->v_ref_count == 0)
        {
                vp->v_pipe= NO_PIPE;
+               vp->v_w_pipe_busy= FALSE;
                vp->v_uid= -1;
                vp->v_gid= -1;
                vp->v_sdev= -1;
index 6cc1eec0c6068ccbdb325bba121dbb034bc94006..ee7dc6c7a830f525bf569b6690239ee3c7965f9f 100644 (file)
@@ -11,6 +11,7 @@ EXTERN struct vnode {
   int v_fs_count;              /* # reference at the underlying FS */
   int v_ref_check;             /* for consistency checks */
   char v_pipe;                 /* set to I_PIPE if pipe */
+  char v_w_pipe_busy;          /* true iff writer suspended */
   off_t v_pipe_rd_pos;
   off_t v_pipe_wr_pos;
   endpoint_t v_bfs_e;          /* endpoint number for the FS proces in case
@@ -20,7 +21,6 @@ EXTERN struct vnode {
                                    inode resides */
   
   Dev_t v_sdev;                 /* device number for special files */
-  int v_blocksize;              /* block size of the filesys */
   unsigned short v_index;       /* inode's index in the FS inode table */
   struct vmnt *v_vmnt;          /* vmnt object of the partition */