]> Zhao Yanbai Git Server - minix.git/commitdiff
VFS: further cleanup of device code
authorDavid van Moolenbroek <david@minix3.org>
Sun, 6 Oct 2013 13:58:54 +0000 (15:58 +0200)
committerLionel Sambuc <lionel@minix3.org>
Sat, 1 Mar 2014 08:04:58 +0000 (09:04 +0100)
- all TTY-related exceptions have now been merged into the regular
  code paths, allowing non-TTY drivers to expose TTY-like devices;
- as part of this, CTTY_MAJOR is now fully managed by VFS instead of
  being an ugly stepchild of the TTY driver;
- device styles have become completely obsolete, support for them has
  been removed throughout the system; same for device flags, which had
  already become useless a while ago;
- device map open/close and I/O function pointers have lost their use,
  thus finally making the VFS device code actually readable;
- the device-unrelated pm_setsid has been moved to misc.c;
- some other small cleanup-related changes.

Change-Id: If90b10d1818e98a12139da3e94a15d250c9933da

25 files changed:
commands/service/service.8
commands/service/service.c
include/lib.h
include/minix/const.h
include/minix/dmap.h
include/minix/rs.h
lib/libminlib/mapdriver.c
servers/is/dmp_fs.c
servers/is/dmp_rs.c
servers/rs/const.h
servers/rs/main.c
servers/rs/manager.c
servers/rs/table.c
servers/rs/type.h
servers/rs/utility.c
servers/vfs/comm.c
servers/vfs/const.h
servers/vfs/device.c
servers/vfs/dmap.c
servers/vfs/dmap.h
servers/vfs/main.c
servers/vfs/misc.c
servers/vfs/param.h
servers/vfs/proto.h
servers/vfs/utility.c

index d46d29bbbb4523361bbcd4c06548c8617200a87c..711c02248b2fcb55ed7dd670fb09a8342793ccd7 100644 (file)
@@ -5,7 +5,7 @@ service \- Manage an operating system service.
 .PP
 \fBservice [-b -c -n -p -r] (up|run|edit|update)\fR \fI<binary|self>\fR
 [\fB-args\fR \fI<args>\fR] [\fB-dev\fR \fI<special>\fR]
-[\fB-devstyle\fR \fI<style>\fR] [\fB-period\fR \fI<ticks>\fR]
+[\fB-period\fR \fI<ticks>\fR]
 [\fB-script\fR \fI<path>\fR] [\fB-label\fR \fI<name>\fR]
 [\fB-config\fR \fI<path>\fR] [\fB-state\fR \fI<state>\fR]
 [\fB-maxtime\fR \fI<time>\fR]
@@ -103,12 +103,6 @@ given by \fI<binary>\fR. The default is to use no arguments.
 specifies the device file to associate to the system service (used only for
 device drivers). The default is to associate no device file to the service.
 .TP
-.BI \-devstyle " <style>"
-specifies the device style to associate to the system service (used only for
-device drivers). The list of supported device styles is available in
-the header file \fB<minix/dmap.h>\fR.
-The default is to associate no device style (\fBSTYLE_NDEV\fR) to the service.
-.TP
 .BI \-period " <ticks>"
 specifies the period to use for the system service.
 When a period is specified, \fBRS\fR sends a ping request to
@@ -160,7 +154,7 @@ label \fI<name>\fR. This action can be used to dynamically update the
 properties of any system service, including those contained in the
 boot image (e.g. \fBVM\fR). There are a few exceptions to the properties
 that can be actually overridden dynamically. For example, the device file
-and the device style associated to the service will no be updated. This
+associated to the service will no be updated. This
 action takes the same options supported by the \fBup\fR action.
 .PP
 .SS
index b1b05e5e79b68f16da4397302241bf9da88c4453..afd5b72dfac222f9cced0d4081048c8bdce0cd63 100644 (file)
@@ -86,7 +86,6 @@ static char *known_requests[] = {
 #define ARG_ARGS       "-args"         /* list of arguments to be passed */
 #define ARG_DEV                "-dev"          /* major device number for drivers */
 #define ARG_MAJOR      "-major"        /* major number */
-#define ARG_DEVSTYLE   "-devstyle"     /* device style */
 #define ARG_PERIOD     "-period"       /* heartbeat period in ticks */
 #define ARG_SCRIPT     "-script"       /* name of the script to restart a
                                         * system service
@@ -113,7 +112,6 @@ static char *req_path_self = SELF_REQ_PATH;
 static char *req_args = "";
 static int req_major = 0;
 static int devman_id = 0;
-static int req_dev_style = STYLE_NDEV;
 static long req_period = 0;
 static char *req_script = NULL;
 static char *req_config = PATH_CONFIG;
@@ -131,9 +129,9 @@ static void print_usage(char *app_name, char *problem)
   fprintf(stderr, "Warning, %s\n", problem);
   fprintf(stderr, "Usage:\n");
   fprintf(stderr,
-  "    %s [%s %s %s %s] (up|run|edit|update) <binary|%s> [%s <args>] [%s <special>] [%s <style>] [%s <major_nr>] [%s <dev_id>] [%s <ticks>] [%s <path>] [%s <name>] [%s <path>] [%s <state>] [%s <time>]\n", 
+  "    %s [%s %s %s %s] (up|run|edit|update) <binary|%s> [%s <args>] [%s <special>] [%s <major_nr>] [%s <dev_id>] [%s <ticks>] [%s <path>] [%s <name>] [%s <path>] [%s <state>] [%s <time>]\n", 
        app_name, OPT_COPY, OPT_REUSE, OPT_NOBLOCK, OPT_REPLICA, SELF_BINARY,
-       ARG_ARGS, ARG_DEV, ARG_DEVSTYLE, ARG_MAJOR, ARG_DEVMANID, ARG_PERIOD, ARG_SCRIPT,
+       ARG_ARGS, ARG_DEV, ARG_MAJOR, ARG_DEVMANID, ARG_PERIOD, ARG_SCRIPT,
        ARG_LABELNAME, ARG_CONFIG, ARG_LU_STATE, ARG_LU_MAXTIME);
   fprintf(stderr, "    %s down <label>\n", app_name);
   fprintf(stderr, "    %s refresh <label>\n", app_name);
@@ -315,9 +313,6 @@ static int parse_arguments(int argc, char **argv, u32_t *rss_flags)
                                  exit(EINVAL);
                          }
               req_major = major(stat_buf.st_rdev);
-              if(req_dev_style == STYLE_NDEV) {
-                  req_dev_style = STYLE_DEV;
-              }
           }
                  else if (strcmp(argv[i], ARG_MAJOR)==0) {
                          if (req_major != 0) {
@@ -329,26 +324,7 @@ static int parse_arguments(int argc, char **argv, u32_t *rss_flags)
                         } else {
                                 exit(EINVAL);
                         }
-                        if(req_dev_style == STYLE_NDEV) {
-                  req_dev_style = STYLE_DEV;
-              }
                  }
-          else if (strcmp(argv[i], ARG_DEVSTYLE)==0) {
-              char* dev_style_keys[] = { "STYLE_DEV", "STYLE_TTY",
-                  "STYLE_CTTY", NULL };
-              int dev_style_values[] = { STYLE_DEV, STYLE_TTY,
-                  STYLE_CTTY };
-              for(j=0;dev_style_keys[j]!=NULL;j++) {
-                  if(!strcmp(dev_style_keys[j], argv[i+1])) {
-                      break;
-                  }
-              }
-              if(dev_style_keys[j] == NULL) {
-                  print_usage(argv[ARG_NAME], "bad device style");
-                  exit(EINVAL);
-              }
-              req_dev_style = dev_style_values[j];
-          }
           else if (strcmp(argv[i], ARG_SCRIPT)==0) {
               req_script = argv[i+1];
           }
@@ -466,7 +442,6 @@ int main(int argc, char **argv)
       config.rs_start.rss_cmd= command;
       config.rs_start.rss_cmdlen= strlen(command);
       config.rs_start.rss_major= req_major;
-      config.rs_start.rss_dev_style= req_dev_style;
       config.rs_start.rss_period= req_period;
       config.rs_start.rss_script= req_script;
       config.rs_start.devman_id= devman_id;
index 006cbb078e5f1cae2f5f54b4963df5fa606f7723..a3018e841a66bd1747d1f97413bcbc743d70a858 100644 (file)
@@ -40,7 +40,7 @@ int getprocnr(void);
 int getnprocnr(pid_t pid);
 int getpprocnr(void);
 int _pm_findproc(char *proc_name, int *proc_nr);
-int mapdriver(char *label, int major, int style, int flags);
+int mapdriver(char *label, int major);
 pid_t getnpid(endpoint_t proc_ep);
 uid_t getnuid(endpoint_t proc_ep);
 gid_t getngid(endpoint_t proc_ep);
index e685e1608be507171e8a7e54732c2b97744ef526..f6da60b864ee7af7db9994c5ca19c8bb6d562f5a 100644 (file)
 #define LU_SYS_PROC     0x400   /* this is a live updated sys proc instance */
 #define RST_SYS_PROC    0x800   /* this is a restarted sys proc instance */
 
-/* Bits for device driver flags managed by RS and VFS. */
-#define DRV_FORCED      0x01    /* driver is mapped even if not alive yet */
-
 /* Values for the "verbose" boot monitor variable */
 #define VERBOSEBOOT_QUIET 0
 #define VERBOSEBOOT_BASIC 1
index b4e560f898202108202ce8fcd5324826c2486316..32bff92becf87e1e78aad8f4e2bb71d5f15052d6 100644 (file)
@@ -4,9 +4,6 @@
 #include <minix/sys_config.h>
 #include <minix/ipc.h>
 
-enum dev_style { STYLE_NDEV, STYLE_DEV, STYLE_TTY, STYLE_CTTY };
-#define IS_DEV_STYLE(s) (s>=STYLE_NDEV && s<=STYLE_CTTY)
-
 /*===========================================================================*
  *                      Major and minor device numbers                      *
  *===========================================================================*/
index a0c79497e59a1133bb1a77e6f2fd6c32e86ec087..6a499f55c621650491289a2da6f69a0eedf3b273 100644 (file)
@@ -73,7 +73,6 @@ struct rs_start
        int rss_priority;
        int rss_quantum;
        int rss_major;
-       int rss_dev_style;
        long rss_period;
        char *rss_script;
        size_t rss_scriptlen;
@@ -119,10 +118,7 @@ struct rprocpub {
   unsigned sys_flags;            /* sys flags */
   endpoint_t endpoint;           /* process endpoint number */
 
-  int dev_flags;                 /* device flags */
-  dev_t dev_nr;                          /* major device number */
-  int dev_style;                 /* device style */
-  int dev_style2;                /* device style for next major dev number */
+  dev_t dev_nr;                          /* major device number or NO_DEV */
 
   char label[RS_MAX_LABEL_LEN];          /* label of this service */
   char proc_name[RS_MAX_LABEL_LEN]; /* process name of this service */
index 34c674e64259e37ff1a119e6c429fca895d4e738..d91be239b03d689d00e813a06117748592a1dbb8 100644 (file)
@@ -3,18 +3,14 @@
 #include <unistd.h>
 
 
-int mapdriver(label, major, dev_style, flags)
+int mapdriver(label, major)
 char *label;
 int major;
-int dev_style;
-int flags;
 {
   message m;
   m.m2_p1 = label;
   m.m2_l1 = strlen(label);
   m.m2_i1 = major;
-  m.m2_i2 = dev_style;
-  m.m2_i3 = flags;
   if (_syscall(VFS_PROC_NR, MAPDRIVER, &m) < 0) return(-1);
   return(0);
 }
index a17475b7def89662fa80e670889d840658e8780a..d4aa92a50f7ea8ce93c74bb38e1371b5687b2b67 100644 (file)
@@ -58,30 +58,6 @@ void fproc_dmp()
   prev_i = i;
 }
 
-/*===========================================================================*
- *                             dmap_flags                                   *
- *===========================================================================*/
-static char * dmap_flags(int flags)
-{
-       static char fl[10];
-       strlcpy(fl, "-----", sizeof(fl));
-       if(flags & DRV_FORCED)  fl[0] = 'F';
-       return fl;
-}
-
-/*===========================================================================*
- *                             dmap_style                                   *
- *===========================================================================*/
-static char * dmap_style(int dev_style)
-{
-       switch(dev_style) {
-       case STYLE_DEV:      return "STYLE_DEV";
-       case STYLE_TTY:      return "STYLE_TTY";
-       case STYLE_CTTY:     return "STYLE_CTTY";
-       default:             return "UNKNOWN";
-       }
-}
-
 /*===========================================================================*
  *                             dtab_dmp                                     *
  *===========================================================================*/
@@ -95,13 +71,10 @@ void dtab_dmp()
     }
     
     printf("File System (FS) device <-> driver mappings\n");
-    printf("    Label     Major Driver ept Flags     Style   \n");
-    printf("------------- ----- ---------- ----- -------------\n");
+    printf("    Label     Major Driver ept\n");
+    printf("------------- ----- ----------\n");
     for (i=0; i<NR_DEVICES; i++) {
         if (dmap[i].dmap_driver == NONE) continue;
-        printf("%13s %5d %10d %s %-13s\n",
-               dmap[i].dmap_label, i, dmap[i].dmap_driver,
-               dmap_flags(dmap[i].dmap_flags), dmap_style(dmap[i].dmap_style));
+        printf("%13s %5d %10d\n", dmap[i].dmap_label, i, dmap[i].dmap_driver);
     }
 }
-
index f71145d712ce144f80f5f784dddba711647a4946..8ca64dacd12fb518d51ac45a716cbf98174b9447 100644 (file)
@@ -42,10 +42,10 @@ void rproc_dmp()
        rpub = &rprocpub[i];
        if (! (rp->r_flags & RS_IN_USE)) continue;
        if (++n > 22) break;
-       printf("%13s %9d %5d %6s %3d/%1d %3ld %8lu %5dx %s",
+       printf("%13s %9d %5d %6s %4d %4ld %8lu %5dx %s",
                rpub->label, rpub->endpoint, rp->r_pid,
                s_flags_str(rp->r_flags, rpub->sys_flags), rpub->dev_nr,
-               rpub->dev_style, rp->r_period, rp->r_alive_tm, rp->r_restarts,
+               rp->r_period, rp->r_alive_tm, rp->r_restarts,
                rp->r_args
        );
        printf("\n");
index 9917a7c99a071646cee4873f655d313449dfc3bf..e1ed8ff7740ba72eed5c9a0914b099e0ccf2d2e7 100644 (file)
 #define DSRV_SF  (0)                           /* dynamic system services */
 #define VM_SF    (SRVR_SF)                             /* vm */
 
-/* Define device flags for the various process types. */
-#define SRV_DF   (DRV_FORCED)            /* system services */
-#define DSRV_DF  (SRV_DF)                /* dynamic system services */
-
 /* Shorthands. */
 #define SRV_OR_USR(rp, X, Y) (rp->r_priv.s_flags & SYS_PROC ? X : Y)
 
index 0201fe1b04dbcc3bf42b83e3604f2961aea1d126..46fa104aa43660c11f2d35a9ba69528d70fc5d82 100644 (file)
@@ -299,10 +299,7 @@ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *UNUSED(info))
       /*
        * Set dev properties.
        */
-      rpub->dev_flags = boot_image_dev->flags;        /* device flags */
       rpub->dev_nr = boot_image_dev->dev_nr;          /* major device number */
-      rpub->dev_style = boot_image_dev->dev_style;    /* device style */
-      rpub->dev_style2 = boot_image_dev->dev_style2;  /* device style 2 */
 
       /* Build command settings. This will also set the process name. */
       strlcpy(rp->r_cmd, ip->proc_name, sizeof(rp->r_cmd));
index a7ef923a8a59fa1008b52b7d1326fe7998259321..43918103e23a3b854a1d737bc34f945967d6e5d0 100644 (file)
@@ -677,8 +677,7 @@ struct rproc *rp;                           /* pointer to service slot */
        */
       setuid(0);
 
-      if (mapdriver(rpub->label, rpub->dev_nr, rpub->dev_style,
-          rpub->dev_flags) != OK) {
+      if (mapdriver(rpub->label, rpub->dev_nr) != OK) {
           return kill_service(rp, "couldn't map driver", errno);
       }
   }
@@ -1225,10 +1224,7 @@ struct rproc *rp;
   rpub = rp->r_pub;
 
   /* Device and PCI settings. These properties cannot change. */
-  rpub->dev_flags = def_rpub->dev_flags;
   rpub->dev_nr = def_rpub->dev_nr;
-  rpub->dev_style = def_rpub->dev_style;
-  rpub->dev_style2 = def_rpub->dev_style2;
   rpub->pci_acl = def_rpub->pci_acl;
 
   /* Immutable system and privilege flags. */
@@ -1608,15 +1604,8 @@ endpoint_t source;
   rp->r_uid= rs_start->rss_uid;
 
   /* Initialize device driver settings. */
-  rpub->dev_flags = DSRV_DF;
   rpub->dev_nr = rs_start->rss_major;
-  rpub->dev_style = rs_start->rss_dev_style;
   rpub->devman_id = rs_start->devman_id;
-  if(rpub->dev_nr && !IS_DEV_STYLE(rs_start->rss_dev_style)) {
-      printf("RS: init_slot: bad device style\n");
-      return EINVAL;
-  }
-  rpub->dev_style2 = STYLE_NDEV;
 
   /* Initialize pci settings. */
   if (rs_start->rss_nr_pci_id > RS_NR_PCI_DEVICE) {
index 774ced2814be0586989cef85852f4c6a4035b180..d4c77a6aa59e9d2df81c646dceed7fd8ac25a98c 100644 (file)
@@ -42,11 +42,8 @@ struct boot_image_sys boot_image_sys_table[] = {
 
 /* Definition of the boot image dev table. */
 struct boot_image_dev boot_image_dev_table[] = {
-  /*endpoint,        flags,   dev_nr,       dev_style,  dev_style2 */
-  { TTY_PROC_NR,     SRV_DF,  TTY_MAJOR,    STYLE_TTY,  STYLE_CTTY },
-  { MEM_PROC_NR,     SRV_DF,  MEMORY_MAJOR, STYLE_DEV,  STYLE_NDEV },
-  { DEFAULT_BOOT_NR, SRV_DF,  0,            STYLE_NDEV, STYLE_NDEV } /* default
-                                                                      * entry
-                                                                      */
+  /*endpoint,        dev_nr       */
+  { TTY_PROC_NR,     TTY_MAJOR    },
+  { MEM_PROC_NR,     MEMORY_MAJOR },
+  { DEFAULT_BOOT_NR, 0            } /* default entry */
 };
-
index 17e92d1d2cc0faf736af8ad1327f875b5e8d2d8e..dcc21a6cbc3534e8ab483c8ee20fdeb5c7057d9b 100644 (file)
@@ -22,10 +22,7 @@ struct boot_image_sys {
 struct boot_image_dev {
   endpoint_t endpoint;         /* process endpoint number */
 
-  int flags;                   /* device flags */
   dev_t dev_nr;                /* major device number */
-  int dev_style;               /* device style */
-  int dev_style2;              /* device style for next major device number */
 };
 
 /* Definition of an entry of the system process table. */
index e2e6b8e67435c6f80bd0a2424a08c38bf63e47a9..fef7c5c4674c7c0d4d15b95e9ff72bb7958452f8 100644 (file)
@@ -135,11 +135,11 @@ struct rproc *rp;                 /* pointer to process slot */
     ((rp)->r_old_rp || (rp)->r_prev_rp ? "+" : " "))
 
 #if DEBUG
-  sprintf(srv_string, "service '%s'%s%s(slot %d, ep %d, pid %d, cmd %s, script %s, proc %s, major %d, style %d, flags 0x%03x, sys_flags 0x%02x)",
+  sprintf(srv_string, "service '%s'%s%s(slot %d, ep %d, pid %d, cmd %s, script %s, proc %s, major %d, flags 0x%03x, sys_flags 0x%02x)",
       rpub->label, srv_active_str(rp), srv_version_str(rp),
       slot_nr, rpub->endpoint, rp->r_pid, srv_str(rp->r_cmd),
       srv_str(rp->r_script), srv_str(rpub->proc_name), rpub->dev_nr,
-      rpub->dev_style, rp->r_flags, rpub->sys_flags);
+      rp->r_flags, rpub->sys_flags);
 #else
   sprintf(srv_string, "service '%s'%s%s(slot %d, ep %d, pid %d)",
       rpub->label, srv_active_str(rp), srv_version_str(rp),
index 840c96785a2e4c3763dbfd08dbbf257493760de9..71e8fcaaa0e81a1acf03b33cbebd668b19d2d53e 100644 (file)
@@ -89,6 +89,16 @@ int drv_sendrec(endpoint_t drv_e, message *reqmp)
        int r;
        struct dmap *dp;
 
+       /* For the CTTY_MAJOR case, we would actually have to lock the device
+        * entry being redirected to.  However, the CTTY major only hosts a
+        * character device while this function is used only for block devices.
+        * Thus, we can simply deny the request immediately.
+        */
+       if (drv_e == CTTY_ENDPT) {
+               printf("VFS: /dev/tty is not a block device!\n");
+               return EIO;
+       }
+
        if ((dp = get_dmap(drv_e)) == NULL)
                panic("driver endpoint %d invalid", drv_e);
 
index bb5bdcaac092d7714d2603c54dfe20f54852c7e2..9fbb6d2d0813f2ffcaee5a082d19edc4b250f301 100644 (file)
@@ -42,4 +42,7 @@
 #define SEL_ERR                CDEV_OP_ERR
 #define SEL_NOTIFY     CDEV_NOTIFY /* not a real select operation */
 
+/* special driver endpoint for CTTY_MAJOR; must be able to pass isokendpt() */
+#define CTTY_ENDPT     VFS_PROC_NR
+
 #endif
index 828048968abfc7e1c2fde62fbe45343dc6e60d00..4785314a16f793d94e66bbb5cb84e494d915144f 100644 (file)
  *   bdev_close:  close a block device
  *   bdev_reply:  process the result of a block driver request
  *   bdev_up:     a block driver has been mapped in
- *   gen_opcl:    generic call to a character driver to perform an open/close
- *   gen_io:      generic call to a character driver to initiate I/O
- *   no_dev:      open/close processing for devices that don't exist
- *   no_dev_io:   i/o processing for devices that don't exist
- *   tty_opcl:    perform tty-specific processing for open/close
- *   ctty_opcl:   perform controlling-tty-specific processing for open/close
- *   ctty_io:     perform controlling-tty-specific processing for I/O
- *   pm_setsid:   perform VFS's side of setsid system call
  *   do_ioctl:    perform the IOCTL system call
  */
 
 #include "vmnt.h"
 #include "param.h"
 
+static int cdev_opcl(int op, dev_t dev, int flags);
 static int block_io(endpoint_t driver_e, message *mess_ptr);
 static cp_grant_id_t make_grant(endpoint_t driver_e, endpoint_t user_e, int op,
        void *buf, unsigned long size);
 
-/*===========================================================================*
- *                             cdev_open                                    *
- *===========================================================================*/
-int cdev_open(dev_t dev, int flags)
-{
-/* Open a character device. */
-  devmajor_t major_dev;
-  int r;
-
-  /* Determine the major device number so as to call the device class specific
-   * open/close routine.  (This is the only routine that must check the
-   * device number for being in range.  All others can trust this check.)
-   */
-  major_dev = major(dev);
-  if (major_dev < 0 || major_dev >= NR_DEVICES) return(ENXIO);
-  if (dmap[major_dev].dmap_driver == NONE) return(ENXIO);
-  r = (*dmap[major_dev].dmap_opcl)(CDEV_OPEN, dev, fp->fp_endpoint, flags);
-  return(r);
-}
-
-
-/*===========================================================================*
- *                             cdev_close                                   *
- *===========================================================================*/
-int cdev_close(dev_t dev)
-{
-/* Close a character device. */
-  devmajor_t major_dev;
-  int r;
-
-  /* See if driver is roughly valid. */
-  major_dev = major(dev);
-  if (major_dev < 0 || major_dev >= NR_DEVICES) return(ENXIO);
-  if (dmap[major_dev].dmap_driver == NONE) return(ENXIO);
-  r = (*dmap[major_dev].dmap_opcl)(CDEV_CLOSE, dev, fp->fp_endpoint, 0);
-  return(r);
-}
-
-
 /*===========================================================================*
  *                             bdev_open                                    *
  *===========================================================================*/
@@ -158,6 +112,7 @@ static int bdev_ioctl(dev_t dev, endpoint_t proc_e, unsigned long req,
   message dev_mess;
   devmajor_t major_dev;
   devminor_t minor_dev;
+  int r;
 
   major_dev = major(dev);
   minor_dev = minor(dev);
@@ -183,17 +138,15 @@ static int bdev_ioctl(dev_t dev, endpoint_t proc_e, unsigned long req,
   dev_mess.BDEV_ID = 0;
 
   /* Call the task. */
-  block_io(dp->dmap_driver, &dev_mess);
+  r = block_io(dp->dmap_driver, &dev_mess);
 
   /* Clean up. */
   if (GRANT_VALID(gid)) cpf_revoke(gid);
 
-  if (dp->dmap_driver == NONE) {
-       printf("VFS: block driver gone!?\n");
-       return(EIO);
-  }
-
   /* Return the result. */
+  if (r != OK)
+       return(r);
+
   return(dev_mess.BDEV_STATUS);
 }
 
@@ -246,6 +199,48 @@ static cp_grant_id_t make_grant(endpoint_t driver_e, endpoint_t user_e, int op,
   return gid;
 }
 
+/*===========================================================================*
+ *                             cdev_get                                     *
+ *===========================================================================*/
+static struct dmap *cdev_get(dev_t dev, devminor_t *minor_dev)
+{
+/* Obtain the dmap structure for the given device, if a valid driver exists for
+ * the major device. Perform redirection for CTTY_MAJOR.
+ */
+  devmajor_t major_dev;
+  struct dmap *dp;
+  int slot;
+
+  /* First cover one special case: /dev/tty, the magic device that translates
+   * to the controlling tty.
+   */
+  if (major(dev) == CTTY_MAJOR) {
+       /* No controlling terminal? Fail the request. */
+       if (fp->fp_tty == 0) return(NULL);
+
+       /* Substitute the controlling terminal device. */
+       dev = fp->fp_tty;
+  }
+
+  /* Determine task dmap. */
+  major_dev = major(dev);
+  if (major_dev < 0 || major_dev >= NR_DEVICES) return(NULL);
+
+  dp = &dmap[major_dev];
+
+  /* See if driver is roughly valid. */
+  if (dp->dmap_driver == NONE) return(NULL);
+
+  if (isokendpt(dp->dmap_driver, &slot) != OK) {
+       printf("VFS: cdev_get: old driver for major %x (%d)\n", major_dev,
+               dp->dmap_driver);
+       return(NULL);
+  }
+
+  /* Also return the (possibly redirected) minor number. */
+  *minor_dev = minor(dev);
+  return dp;
+}
 
 /*===========================================================================*
  *                             cdev_io                                      *
@@ -261,28 +256,17 @@ int cdev_io(
 )
 {
 /* Initiate a read, write, or ioctl to a character device. */
+  devminor_t minor_dev;
   struct dmap *dp;
   message dev_mess;
   cp_grant_id_t gid;
-  devmajor_t major_dev;
-  devminor_t minor_dev;
-  int r, slot;
+  int r;
 
   assert(op == CDEV_READ || op == CDEV_WRITE || op == CDEV_IOCTL);
 
-  /* Determine task dmap. */
-  major_dev = major(dev);
-  minor_dev = minor(dev);
-  dp = &dmap[major_dev];
-
-  /* See if driver is roughly valid. */
-  if (dp->dmap_driver == NONE) return(ENXIO);
-
-  if(isokendpt(dp->dmap_driver, &slot) != OK) {
-       printf("VFS: dev_io: old driver for major %x (%d)\n", major_dev,
-               dp->dmap_driver);
-       return(ENXIO);
-  }
+  /* Determine task map. */
+  if ((dp = cdev_get(dev, &minor_dev)) == NULL)
+       return(EIO);
 
   /* Create a grant for the buffer provided by the user process. */
   gid = make_grant(dp->dmap_driver, proc_e, op, buf, bytes);
@@ -306,13 +290,8 @@ int cdev_io(
          dev_mess.CDEV_FLAGS |= CDEV_NONBLOCK;
 
   /* Send the request to the driver. */
-  r = (*dp->dmap_io)(dp->dmap_driver, &dev_mess);
-
-  if (r != OK) {
-       cpf_revoke(gid);
-
-       return r;
-  }
+  if ((r = asynsend3(dp->dmap_driver, &dev_mess, AMF_NOREPLY)) != OK)
+       panic("VFS: asynsend in cdev_io failed: %d", r);
 
   /* Suspend the calling process until a reply arrives. */
   wait_for(dp->dmap_driver);
@@ -324,9 +303,9 @@ int cdev_io(
 
 
 /*===========================================================================*
- *                             clone_cdev                                   *
+ *                             cdev_clone                                   *
  *===========================================================================*/
-static int cdev_clone(dev_t dev, endpoint_t proc_e, devminor_t new_minor)
+static int cdev_clone(dev_t dev, devminor_t new_minor)
 {
 /* A new minor device number has been returned. Request PFS to create a
  * temporary device file to hold it.
@@ -335,8 +314,6 @@ static int cdev_clone(dev_t dev, endpoint_t proc_e, devminor_t new_minor)
   struct node_details res;
   int r;
 
-  assert(proc_e == fp->fp_endpoint);
-
   /* Device number of the new device. */
   dev = makedev(major(dev), new_minor);
 
@@ -344,14 +321,14 @@ static int cdev_clone(dev_t dev, endpoint_t proc_e, devminor_t new_minor)
   r = req_newnode(PFS_PROC_NR, fp->fp_effuid, fp->fp_effgid,
       ALL_MODES | I_CHAR_SPECIAL, dev, &res);
   if (r != OK) {
-       (void) gen_opcl(CDEV_CLOSE, dev, proc_e, 0);
+       (void) cdev_opcl(CDEV_CLOSE, dev, 0);
        return r;
   }
 
   /* Drop old node and use the new values */
   if ((vp = get_free_vnode()) == NULL) {
        req_putnode(PFS_PROC_NR, res.inode_nr, 1); /* is this right? */
-       (void) gen_opcl(CDEV_CLOSE, dev, proc_e, 0);
+       (void) cdev_opcl(CDEV_CLOSE, dev, 0);
        return(err_code);
   }
   lock_vnode(vp, VNODE_OPCL);
@@ -376,49 +353,63 @@ static int cdev_clone(dev_t dev, endpoint_t proc_e, devminor_t new_minor)
 
 
 /*===========================================================================*
- *                             gen_opcl                                     *
+ *                             cdev_opcl                                    *
  *===========================================================================*/
-int gen_opcl(
+static int cdev_opcl(
   int op,                      /* operation, CDEV_OPEN or CDEV_CLOSE */
   dev_t dev,                   /* device to open or close */
-  endpoint_t proc_e,           /* process to open/close for */
   int flags                    /* mode bits and flags */
 )
 {
-/* Called from the dmap struct on opens & closes of special files.*/
-  devmajor_t major_dev;
+/* Open or close a character device. */
   devminor_t minor_dev, new_minor;
   struct dmap *dp;
+  struct fproc *rfp;
   message dev_mess;
   int r, r2;
 
+  assert(op == CDEV_OPEN || op == CDEV_CLOSE);
+
   /* Determine task dmap. */
-  major_dev = major(dev);
-  minor_dev = minor(dev);
-  assert(major_dev >= 0 && major_dev < NR_DEVICES);
-  dp = &dmap[major_dev];
-  assert(dp->dmap_driver != NONE);
+  if ((dp = cdev_get(dev, &minor_dev)) == NULL)
+       return(ENXIO);
 
-  assert(!IS_BDEV_RQ(op));
+  /* CTTY exception: do not actually send the open/close request for /dev/tty
+   * to the driver.  This avoids the case that the actual device will remain
+   * open forever if the process calls setsid() after opening /dev/tty.
+   */
+  if (major(dev) == CTTY_MAJOR) return(OK);
+
+  /* Add O_NOCTTY to the access flags if this process is not a session leader,
+   * or if it already has a controlling tty, or if it is someone else's
+   * controlling tty.  For performance reasons, only search the full process
+   * table if this driver has set controlling ttys before.
+   */
+  if (!(fp->fp_flags & FP_SESLDR) || fp->fp_tty != 0) {
+       flags |= O_NOCTTY;
+  } else if (!(flags & O_NOCTTY) && dp->dmap_seen_tty) {
+       for (rfp = &fproc[0]; rfp < &fproc[NR_PROCS]; rfp++)
+               if (rfp->fp_pid != PID_FREE && rfp->fp_tty == dev)
+                       flags |= O_NOCTTY;
+  }
 
   /* Prepare the request message. */
   memset(&dev_mess, 0, sizeof(dev_mess));
 
   dev_mess.m_type = op;
   dev_mess.CDEV_MINOR = minor_dev;
-  dev_mess.CDEV_ID = proc_e;
+  dev_mess.CDEV_ID = who_e;
   if (op == CDEV_OPEN) {
-       dev_mess.CDEV_USER = proc_e;
+       dev_mess.CDEV_USER = who_e;
        dev_mess.CDEV_ACCESS = 0;
        if (flags & R_BIT)      dev_mess.CDEV_ACCESS |= CDEV_R_BIT;
        if (flags & W_BIT)      dev_mess.CDEV_ACCESS |= CDEV_W_BIT;
        if (flags & O_NOCTTY)   dev_mess.CDEV_ACCESS |= CDEV_NOCTTY;
   }
 
-  /* Call the task. */
-  r = (*dp->dmap_io)(dp->dmap_driver, &dev_mess);
-
-  if (r != OK) return(r);
+  /* Send the request to the driver. */
+  if ((r = asynsend3(dp->dmap_driver, &dev_mess, AMF_NOREPLY)) != OK)
+       panic("VFS: asynsend in cdev_opcl failed: %d", r);
 
   /* Block the thread waiting for a reply. */
   fp->fp_task = dp->dmap_driver;
@@ -430,106 +421,55 @@ int gen_opcl(
   self->w_task = NONE;
   self->w_drv_sendrec = NULL;
 
+  /* Process the reply. */
   r = dev_mess.CDEV_STATUS;
 
-  /* Some devices need special processing upon open. Such a device is "cloned",
-   * i.e. on a succesful open it is replaced by a new device with a new unique
-   * minor device number. This new device number identifies a new object (such
-   * as a new network connection) that has been allocated within a task.
-   */
   if (op == CDEV_OPEN && r >= 0) {
+       /* Some devices need special processing upon open. Such a device is
+        * "cloned", i.e. on a succesful open it is replaced by a new device
+        * with a new unique minor device number. This new device number
+        * identifies a new object (such as a new network connection) that has
+        * been allocated within a driver.
+        */
        if (r & CDEV_CLONED) {
                new_minor = r & ~(CDEV_CLONED | CDEV_CTTY);
-               r &= CDEV_CTTY;
-               if ((r2 = cdev_clone(dev, proc_e, new_minor)) < 0)
-                       r = r2;
-       } else
-               r &= CDEV_CTTY;
-       /* Upon success, we now return either OK or CDEV_CTTY. */
-  }
-
-  /* Return the result from the driver. */
-  return(r);
-}
-
-/*===========================================================================*
- *                             tty_opcl                                     *
- *===========================================================================*/
-int tty_opcl(
-  int op,                      /* operation, CDEV_OPEN or CDEV_CLOSE */
-  dev_t dev,                   /* device to open or close */
-  endpoint_t proc_e,           /* process to open/close for */
-  int flags                    /* mode bits and flags */
-)
-{
-/* This procedure is called from the dmap struct on tty open/close. */
-  int r;
-  register struct fproc *rfp;
-
-  assert(!IS_BDEV_RQ(op));
-
-  /* Add O_NOCTTY to the flags if this process is not a session leader, or
-   * if it already has a controlling tty, or if it is someone elses
-   * controlling tty.
-   */
-  if (!(fp->fp_flags & FP_SESLDR) || fp->fp_tty != 0) {
-       flags |= O_NOCTTY;
-  } else {
-       for (rfp = &fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) {
-               if(rfp->fp_pid == PID_FREE) continue;
-               if (rfp->fp_tty == dev) flags |= O_NOCTTY;
+               if ((r2 = cdev_clone(dev, new_minor)) < 0)
+                       return(r2);
        }
-  }
 
-  r = gen_opcl(op, dev, proc_e, flags);
+       /* Did this call make the tty the controlling tty? */
+       if (r & CDEV_CTTY) {
+               fp->fp_tty = dev;
+               dp->dmap_seen_tty = TRUE;
+       }
 
-  /* Did this call make the tty the controlling tty? */
-  if (r >= 0 && (r & CDEV_CTTY)) {
-       fp->fp_tty = dev;
        r = OK;
   }
 
+  /* Return the result from the driver. */
   return(r);
 }
 
 
 /*===========================================================================*
- *                             ctty_opcl                                    *
+ *                             cdev_open                                    *
  *===========================================================================*/
-int ctty_opcl(
-  int op,                      /* operation, CDEV_OPEN or CDEV_CLOSE */
-  dev_t UNUSED(dev),           /* device to open or close */
-  endpoint_t UNUSED(proc_e),   /* process to open/close for */
-  int UNUSED(flags)            /* mode bits and flags */
-)
+int cdev_open(dev_t dev, int flags)
 {
-/* This procedure is called from the dmap struct on opening or closing
- * /dev/tty, the magic device that translates to the controlling tty.
- */
-
-  if (IS_BDEV_RQ(op))
-       panic("ctty_opcl() called for block device request?");
+/* Open a character device. */
 
-  return(fp->fp_tty == 0 ? ENXIO : OK);
+  return cdev_opcl(CDEV_OPEN, dev, flags);
 }
 
 
 /*===========================================================================*
- *                             pm_setsid                                    *
+ *                             cdev_close                                   *
  *===========================================================================*/
-void pm_setsid(endpoint_t proc_e)
+int cdev_close(dev_t dev)
 {
-/* Perform the VFS side of the SETSID call, i.e. get rid of the controlling
- * terminal of a process, and make the process a session leader.
- */
-  register struct fproc *rfp;
-  int slot;
+/* Close a character device. */
 
-  /* Make the process a session leader with no controlling tty. */
-  okendpt(proc_e, &slot);
-  rfp = &fproc[slot];
-  rfp->fp_flags |= FP_SESLDR;
-  rfp->fp_tty = 0;
+  return cdev_opcl(CDEV_CLOSE, dev, 0);
 }
 
 
@@ -583,25 +523,27 @@ int do_ioctl(message *UNUSED(m_out))
 int cdev_select(dev_t dev, int ops)
 {
 /* Initiate a select call on a device. Return OK iff the request was sent. */
-  devmajor_t major_dev;
   devminor_t minor_dev;
   message dev_mess;
   struct dmap *dp;
+  int r;
 
-  major_dev = major(dev);
-  minor_dev = minor(dev);
-  dp = &dmap[major_dev];
-
-  if (dp->dmap_driver == NONE) return ENXIO;
+  /* Determine task dmap. */
+  if ((dp = cdev_get(dev, &minor_dev)) == NULL)
+       return(EIO);
 
+  /* Prepare the request message. */
   memset(&dev_mess, 0, sizeof(dev_mess));
 
   dev_mess.m_type = CDEV_SELECT;
   dev_mess.CDEV_MINOR = minor_dev;
   dev_mess.CDEV_OPS = ops;
 
-  /* Call the task. */
-  return (*dp->dmap_io)(dp->dmap_driver, &dev_mess);
+  /* Send the request to the driver. */
+  if ((r = asynsend3(dp->dmap_driver, &dev_mess, AMF_NOREPLY)) != OK)
+       panic("VFS: asynsend in cdev_select failed: %d", r);
+
+  return(OK);
 }
 
 
@@ -611,24 +553,25 @@ int cdev_select(dev_t dev, int ops)
 int cdev_cancel(dev_t dev)
 {
 /* Cancel an I/O request, blocking until it has been cancelled. */
-  devmajor_t major_dev;
   devminor_t minor_dev;
   message dev_mess;
   struct dmap *dp;
   int r;
 
-  major_dev = major(dev);
-  minor_dev = minor(dev);
-  dp = &dmap[major_dev];
+  /* Determine task dmap. */
+  if ((dp = cdev_get(dev, &minor_dev)) == NULL)
+       return(EIO);
 
+  /* Prepare the request message. */
   memset(&dev_mess, 0, sizeof(dev_mess));
 
   dev_mess.m_type = CDEV_CANCEL;
   dev_mess.CDEV_MINOR = minor_dev;
   dev_mess.CDEV_ID = fp->fp_endpoint;
 
-  r = (*dp->dmap_io)(fp->fp_task, &dev_mess);
-  if (r != OK) return r; /* ctty_io returned an error? should be impossible */
+  /* Send the request to the driver. */
+  if ((r = asynsend3(dp->dmap_driver, &dev_mess, AMF_NOREPLY)) != OK)
+       panic("VFS: asynsend in cdev_cancel failed: %d", r);
 
   /* Suspend this thread until we have received the response. */
   fp->fp_task = dp->dmap_driver;
@@ -668,30 +611,29 @@ static int block_io(endpoint_t driver_e, message *mess_ptr)
 
   do {
        r = drv_sendrec(driver_e, mess_ptr);
-       if (r == OK) {
-               status = mess_ptr->BDEV_STATUS;
-               if (status == ERESTART) {
-                       r = EDEADEPT;
-                       *mess_ptr = mess_retry;
-                       retry_count++;
-               }
+       if (r != OK)
+               return r;
+
+       status = mess_ptr->BDEV_STATUS;
+       if (status == ERESTART) {
+               r = EDEADEPT;
+               *mess_ptr = mess_retry;
+               retry_count++;
        }
   } while (status == ERESTART && retry_count < 5);
 
   /* If we failed to restart the request, return EIO */
-  if (status == ERESTART && retry_count >= 5) {
-       r = OK;
-       mess_ptr->m_type = EIO;
-  }
+  if (status == ERESTART && retry_count >= 5)
+       return EIO;
 
   if (r != OK) {
        if (r == EDEADSRCDST || r == EDEADEPT) {
                printf("VFS: dead driver %d\n", driver_e);
                dmap_unmap_by_endpt(driver_e);
-               return(r);
+               return(EIO);
        } else if (r == ELOCKED) {
                printf("VFS: ELOCKED talking to %d\n", driver_e);
-               return(r);
+               return(EIO);
        }
        panic("block_io: can't send/receive: %d", r);
   }
@@ -700,87 +642,6 @@ static int block_io(endpoint_t driver_e, message *mess_ptr)
 }
 
 
-/*===========================================================================*
- *                             gen_io                                       *
- *===========================================================================*/
-int gen_io(endpoint_t drv_e, message *mess_ptr)
-{
-/* Initiate I/O to a character driver. Do not wait for the reply. */
-  int r;
-
-  assert(!IS_BDEV_RQ(mess_ptr->m_type));
-
-  r = asynsend3(drv_e, mess_ptr, AMF_NOREPLY);
-
-  if (r != OK) panic("VFS: asynsend in gen_io failed: %d", r);
-
-  return(OK);
-}
-
-
-/*===========================================================================*
- *                             ctty_io                                      *
- *===========================================================================*/
-int ctty_io(
-  endpoint_t UNUSED(task_nr),  /* not used - for compatibility with dmap_t */
-  message *mess_ptr            /* pointer to message for task */
-)
-{
-/* This routine is only called for one device, namely /dev/tty.  Its job
- * is to change the message to use the controlling terminal, instead of the
- * major/minor pair for /dev/tty itself.
- */
-  struct dmap *dp;
-  int slot;
-
-  if (fp->fp_tty == 0) {
-       /* No controlling tty present anymore, return an I/O error. */
-       return(EIO);
-  } else {
-       /* Substitute the controlling terminal device. */
-       dp = &dmap[major(fp->fp_tty)];
-       mess_ptr->CDEV_MINOR = minor(fp->fp_tty);
-
-       if (dp->dmap_driver == NONE) {
-               printf("FS: ctty_io: no driver for dev\n");
-               return(EIO);
-       }
-
-       if (isokendpt(dp->dmap_driver, &slot) != OK) {
-               printf("VFS: ctty_io: old driver %d\n", dp->dmap_driver);
-               return(EIO);
-       }
-
-       return (*dp->dmap_io)(dp->dmap_driver, mess_ptr);
-  }
-}
-
-
-/*===========================================================================*
- *                             no_dev                                       *
- *===========================================================================*/
-int no_dev(
-  int UNUSED(op),              /* operation, CDEV_OPEN or CDEV_CLOSE */
-  dev_t UNUSED(dev),           /* device to open or close */
-  endpoint_t UNUSED(proc),             /* process to open/close for */
-  int UNUSED(flags)            /* mode bits and flags */
-)
-{
-/* Called when opening a nonexistent device. */
-  return(ENODEV);
-}
-
-/*===========================================================================*
- *                             no_dev_io                                    *
- *===========================================================================*/
-int no_dev_io(endpoint_t UNUSED(proc), message *UNUSED(m))
-{
-/* Called when doing i/o on a nonexistent device. */
-  printf("VFS: I/O on unmapped device number\n");
-  return(EIO);
-}
-
-
 /*===========================================================================*
  *                             bdev_up                                      *
  *===========================================================================*/
index 0221aacb8ef422bb8bf9bed87cbaa84473458a32..fd303e2c9d374a1e21cbd6b945090cf0b369226c 100644 (file)
@@ -36,7 +36,7 @@ void lock_dmap(struct dmap *dp)
 
        org_self = worker_suspend();
 
-       if ((r = mutex_lock(dp->dmap_lock_ref)) != 0)
+       if ((r = mutex_lock(&dp->dmap_lock)) != 0)
                panic("unable to get a lock on dmap: %d\n", r);
 
        worker_resume(org_self);
@@ -52,10 +52,57 @@ void unlock_dmap(struct dmap *dp)
 
        assert(dp != NULL);
 
-       if ((r = mutex_unlock(dp->dmap_lock_ref)) != 0)
+       if ((r = mutex_unlock(&dp->dmap_lock)) != 0)
                panic("unable to unlock dmap lock: %d\n", r);
 }
 
+/*===========================================================================*
+ *                             map_driver                                   *
+ *===========================================================================*/
+static int map_driver(label, major, proc_nr_e)
+const char label[LABEL_MAX];   /* name of the driver */
+int major;                     /* major number of the device */
+endpoint_t proc_nr_e;          /* process number of the driver */
+{
+/* Add a new device driver mapping in the dmap table. If the proc_nr is set to
+ * NONE, we're supposed to unmap it.
+ */
+  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 (proc_nr_e == NONE) {
+       /* Even when a driver is now unmapped and is shortly to be mapped in
+        * due to recovery, invalidate associated filps if they're character
+        * special files. More sophisticated recovery mechanisms which would
+        * reduce the need to invalidate files are possible, but would require
+        * cooperation of the driver and more recovery framework between RS,
+        * VFS, and DS.
+        */
+       invalidate_filp_by_char_major(major);
+       dp->dmap_driver = NONE;
+       return(OK);
+  }
+
+  if (label != NULL) {
+       len = strlen(label);
+       if (len+1 > sizeof(dp->dmap_label)) {
+               printf("VFS: map_driver: label too long: %d\n", len);
+               return(EINVAL);
+       }
+       strlcpy(dp->dmap_label, label, sizeof(dp->dmap_label));
+  }
+
+  /* Store driver I/O routines based on type of device */
+  dp->dmap_driver = proc_nr_e;
+
+  return(OK);
+}
+
 /*===========================================================================*
  *                             do_mapdriver                                 *
  *===========================================================================*/
@@ -66,7 +113,7 @@ int do_mapdriver(message *UNUSED(m_out))
  * etc), and its label. This label is registered with DS, and allows us to
  * retrieve the driver's endpoint.
  */
-  int r, flags, major, style, slot;
+  int r, major, slot;
   endpoint_t endpoint;
   vir_bytes label_vir;
   size_t label_len;
@@ -79,8 +126,6 @@ int do_mapdriver(message *UNUSED(m_out))
   label_vir = (vir_bytes) job_m_in.md_label;
   label_len = (size_t) job_m_in.md_label_len;
   major = job_m_in.md_major;
-  flags = job_m_in.md_flags;
-  style = job_m_in.md_style;
 
   /* Get the label */
   if (label_len+1 > sizeof(label)) { /* Can we store this label? */
@@ -110,88 +155,7 @@ int do_mapdriver(message *UNUSED(m_out))
   rfp->fp_flags |= FP_SRV_PROC;
 
   /* Try to update device mapping. */
-  return map_driver(label, major, endpoint, style, flags);
-}
-
-/*===========================================================================*
- *                             map_driver                                   *
- *===========================================================================*/
-int map_driver(label, major, proc_nr_e, style, flags)
-const char label[LABEL_MAX];   /* 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 flags;                     /* device flags */
-{
-/* Add a new device driver mapping in the dmap table. If the proc_nr is set to
- * NONE, we're supposed to unmap it.
- */
-
-  int slot, s;
-  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 (proc_nr_e == NONE) {
-       /* Even when a driver is now unmapped and is shortly to be mapped in
-        * due to recovery, invalidate associated filps if they're character
-        * special files. More sophisticated recovery mechanisms which would
-        * reduce the need to invalidate files are possible, but would require
-        * cooperation of the driver and more recovery framework between RS,
-        * VFS, and DS.
-        */
-       invalidate_filp_by_char_major(major);
-       dp->dmap_opcl = no_dev;
-       dp->dmap_io = no_dev_io;
-       dp->dmap_driver = NONE;
-       dp->dmap_flags = flags;
-       dp->dmap_lock_ref = &dp->dmap_lock;
-       return(OK);
-  }
-
-  /* Check process number of new driver if it was alive before mapping */
-  s = isokendpt(proc_nr_e, &slot);
-  if (s != OK) {
-       /* This is not a problem only when we force this driver mapping */
-       if (! (flags & DRV_FORCED))
-               return(EINVAL);
-  }
-
-  if (label != NULL) {
-       len = strlen(label);
-       if (len+1 > sizeof(dp->dmap_label))
-               panic("VFS: map_driver: label too long: %d", len);
-       strlcpy(dp->dmap_label, label, LABEL_MAX);
-  }
-
-  /* Store driver I/O routines based on type of device */
-  switch (style) {
-    case STYLE_DEV:
-       dp->dmap_opcl = gen_opcl;
-       dp->dmap_io = gen_io;
-       break;
-    case STYLE_TTY:
-       dp->dmap_opcl = tty_opcl;
-       dp->dmap_io = gen_io;
-       break;
-    case STYLE_CTTY:
-       dp->dmap_opcl = ctty_opcl;
-       dp->dmap_io = ctty_io;
-       break;
-       break;
-    default:
-       return(EINVAL);
-  }
-
-  dp->dmap_driver = proc_nr_e;
-  dp->dmap_flags = flags;
-  dp->dmap_style = style;
-
-  return(OK);
+  return map_driver(label, major, endpoint);
 }
 
 /*===========================================================================*
@@ -205,7 +169,7 @@ void dmap_unmap_by_endpt(endpoint_t proc_e)
   for (major = 0; major < NR_DEVICES; major++) {
        if (dmap_driver_match(proc_e, major)) {
                /* Found driver; overwrite it with a NULL entry */
-               if ((r = map_driver(NULL, major, NONE, 0, 0)) != OK) {
+               if ((r = map_driver(NULL, major, NONE)) != OK) {
                        printf("VFS: unmapping driver %d for major %d failed:"
                                " %d\n", proc_e, major, r);
                }
@@ -220,7 +184,6 @@ int map_service(struct rprocpub *rpub)
 {
 /* Map a new service by storing its device driver properties. */
   int r, slot;
-  struct dmap *fdp, *sdp;
   struct fproc *rfp;
 
   if (IS_RPUB_BOOT_USR(rpub)) return(OK);
@@ -238,62 +201,32 @@ int map_service(struct rprocpub *rpub)
   if (rpub->dev_nr == NO_DEV) return(OK);
 
   /* Map driver. */
-  r = map_driver(rpub->label, rpub->dev_nr, rpub->endpoint, rpub->dev_style,
-                rpub->dev_flags);
+  r = map_driver(rpub->label, rpub->dev_nr, rpub->endpoint);
   if(r != OK) return(r);
 
-  /* If driver has two major numbers associated, also map the other one. */
-  if(rpub->dev_style2 != STYLE_NDEV) {
-       r = map_driver(rpub->label, rpub->dev_nr+1, rpub->endpoint,
-                      rpub->dev_style2, rpub->dev_flags);
-       if(r != OK) return(r);
-
-       /* To ensure that future dmap lock attempts always lock the same driver
-        * regardless of major number, refer the second dmap lock reference
-        * to the first dmap entry.
-        */
-       fdp = get_dmap_by_major(rpub->dev_nr);
-       sdp = get_dmap_by_major(rpub->dev_nr+1);
-       assert(fdp != NULL);
-       assert(sdp != NULL);
-       assert(fdp != sdp);
-       sdp->dmap_lock_ref = &fdp->dmap_lock;
-  }
-
   return(OK);
 }
 
 /*===========================================================================*
  *                             init_dmap                                    *
  *===========================================================================*/
-void init_dmap()
+void init_dmap(void)
 {
-/* Initialize the table with empty device <-> driver mappings. */
+/* Initialize the device mapping table. */
   int i;
 
   memset(dmap, 0, sizeof(dmap));
 
   for (i = 0; i < NR_DEVICES; i++) {
-       dmap[i].dmap_opcl = no_dev;
-       dmap[i].dmap_io = no_dev_io;
        dmap[i].dmap_driver = NONE;
-       dmap[i].dmap_style = STYLE_NDEV;
        dmap[i].dmap_servicing = INVALID_THREAD;
-  }
-}
-
-/*===========================================================================*
- *                             init_dmap_locks                              *
- *===========================================================================*/
-void init_dmap_locks()
-{
-  int i;
-
-  for (i = 0; i < NR_DEVICES; i++) {
        if (mutex_init(&dmap[i].dmap_lock, NULL) != 0)
                panic("unable to initialize dmap lock");
-       dmap[i].dmap_lock_ref = &dmap[i].dmap_lock;
   }
+
+  /* CTTY_MAJOR is a special case, which is handled by VFS itself. */
+  if (map_driver("vfs", CTTY_MAJOR, CTTY_ENDPT) != OK)
+       panic("map_driver(CTTY_MAJOR) failed");
 }
 
 /*===========================================================================*
index 959ecb0702977629099022d4ef1ecceace06795a..b4da8f31daed933be2753b6b8eaafe9f8fa781a8 100644 (file)
  */
 
 extern struct dmap {
-  int(*dmap_opcl) (int, dev_t, endpoint_t, int);
-  int(*dmap_io) (endpoint_t, message *);
   endpoint_t dmap_driver;
   char dmap_label[LABEL_MAX];
-  int dmap_flags;
-  int dmap_style;
   int dmap_sel_busy;
   struct filp *dmap_sel_filp;
   thread_t dmap_servicing;
   mutex_t dmap_lock;
-  mutex_t *dmap_lock_ref;
   int dmap_recovering;
+  int dmap_seen_tty;
 } dmap[];
 
 #endif
index abfd095b88d8ea947722a65f997a0595a64d30be..d99f39ec3109ff688f6d99cb53b0ff793bdf671e 100644 (file)
@@ -325,10 +325,21 @@ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *info)
   mess.m_type = OK;                    /* tell PM that we succeeded */
   s = send(PM_PROC_NR, &mess);         /* send synchronization message */
 
-  /* All process table entries have been set. Continue with initialization. */
-  init_dmap();                 /* Initialize device table. */
   system_hz = sys_hz();
 
+  /* Subscribe to block and character driver events. */
+  s = ds_subscribe("drv\\.[bc]..\\..*", DSF_INITIAL | DSF_OVERWRITE);
+  if (s != OK) panic("VFS: can't subscribe to driver events (%d)", s);
+
+  /* Initialize worker threads */
+  worker_init();
+
+  /* Initialize global locks */
+  if (mthread_mutex_init(&bsf_lock, NULL) != 0)
+       panic("VFS: couldn't initialize block special file lock");
+
+  init_dmap();                 /* Initialize device table. */
+
   /* Map all the services in the boot image. */
   if ((s = sys_safecopyfrom(RS_PROC_NR, info->rproctab_gid, 0,
                            (vir_bytes) rprocpub, sizeof(rprocpub))) != OK){
@@ -342,17 +353,6 @@ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *info)
        }
   }
 
-  /* Subscribe to block and character driver events. */
-  s = ds_subscribe("drv\\.[bc]..\\..*", DSF_INITIAL | DSF_OVERWRITE);
-  if (s != OK) panic("VFS: can't subscribe to driver events (%d)", s);
-
-  /* Initialize worker threads */
-  worker_init();
-
-  /* Initialize global locks */
-  if (mthread_mutex_init(&bsf_lock, NULL) != 0)
-       panic("VFS: couldn't initialize block special file lock");
-
   /* Initialize locks and initial values for all processes. */
   for (rfp = &fproc[0]; rfp < &fproc[NR_PROCS]; rfp++) {
        if (mutex_init(&rfp->fp_lock, NULL) != 0)
@@ -372,7 +372,6 @@ static int sef_cb_init_fresh(int UNUSED(type), sef_init_info_t *info)
        rfp->fp_wd = NULL;
   }
 
-  init_dmap_locks();           /* init dmap locks */
   init_vnodes();               /* init vnodes */
   init_vmnts();                        /* init vmnt structures */
   init_select();               /* init select() structures */
index b8cc977781dbf7da3e44e4df3afa663160a1b9b0..81e2df697ed8c56f8ef98337cc64a6817776765f 100644 (file)
@@ -6,6 +6,7 @@
  *   do_fcntl:   perform the FCNTL system call
  *   do_sync:    perform the SYNC system call
  *   do_fsync:   perform the FSYNC system call
+ *   pm_setsid:          perform VFS's side of setsid system call
  *   pm_reboot:          sync disks and prepare for shutdown
  *   pm_fork:    adjust the tables after PM has performed a FORK system call
  *   do_exec:    handle files with FD_CLOEXEC on after PM has done an EXEC
@@ -745,6 +746,24 @@ int ruid;
   tfp->fp_realuid = ruid;
 }
 
+/*===========================================================================*
+ *                             pm_setsid                                    *
+ *===========================================================================*/
+void pm_setsid(endpoint_t proc_e)
+{
+/* Perform the VFS side of the SETSID call, i.e. get rid of the controlling
+ * terminal of a process, and make the process a session leader.
+ */
+  struct fproc *rfp;
+  int slot;
+
+  /* Make the process a session leader with no controlling tty. */
+  okendpt(proc_e, &slot);
+  rfp = &fproc[slot];
+  rfp->fp_flags |= FP_SESLDR;
+  rfp->fp_tty = 0;
+}
+
 /*===========================================================================*
  *                             do_svrctl                                    *
  *===========================================================================*/
index e76ce33f486df8a5a26a71af41be2dbb1e133ced..a606c4df25b7d3b6a31fedf7ea6796190aa9b009 100644 (file)
@@ -49,8 +49,6 @@
 #define md_label       m2_p1
 #define md_label_len   m2_l1
 #define md_major       m2_i1
-#define md_style       m2_i2
-#define md_flags       m2_i3
 
 /* The following names are synonyms for the variables in the output message. */
 #define reply_type    m_type
index 72a0a94f77271e23e4df7c2e74d8117bf58840f4..06e873b0d1dc7d44c2c371459e07ab0d45ea2a82 100644 (file)
@@ -39,32 +39,18 @@ int bdev_open(dev_t dev, int access);
 int bdev_close(dev_t dev);
 void bdev_reply(void);
 void bdev_up(int major);
-int gen_opcl(int op, dev_t dev, endpoint_t task_nr, int flags);
-int gen_io(endpoint_t drv_e, message *mess_ptr);
-int no_dev(int op, dev_t dev, endpoint_t proc, int flags);
-int no_dev_io(endpoint_t, message *);
-int tty_opcl(int op, dev_t dev, endpoint_t proc, int flags);
-int ctty_opcl(int op, dev_t dev, endpoint_t proc, int flags);
-int clone_opcl(int op, dev_t dev, endpoint_t proc, int flags);
-int ctty_io(endpoint_t task_nr, message *mess_ptr);
 int do_ioctl(message *m_out);
-void pm_setsid(endpoint_t proc_e);
 
 /* dmap.c */
 void lock_dmap(struct dmap *dp);
 void unlock_dmap(struct dmap *dp);
 int do_mapdriver(message *m_out);
 void init_dmap(void);
-void init_dmap_locks(void);
 int dmap_driver_match(endpoint_t proc, int major);
 void dmap_endpt_up(endpoint_t proc_nr, int is_blk);
-void dmap_unmap_by_endpt(endpoint_t proc_nr);
 struct dmap *get_dmap(endpoint_t proc_e);
 struct dmap *get_dmap_by_major(int major);
-int map_service(struct rprocpub *rpub);
 void dmap_unmap_by_endpt(endpoint_t proc_nr);
-int map_driver(const char *label, int major, endpoint_t proc_nr, int
-       dev_style, int flags);
 int map_service(struct rprocpub *rpub);
 
 /* elf_core_dump.c */
@@ -124,6 +110,7 @@ void pm_fork(endpoint_t pproc, endpoint_t cproc, pid_t cpid);
 void pm_setgid(endpoint_t proc_e, int egid, int rgid);
 void pm_setuid(endpoint_t proc_e, int euid, int ruid);
 void pm_setgroups(endpoint_t proc_e, int ngroups, gid_t *addr);
+void pm_setsid(endpoint_t proc_e);
 int do_sync(message *m_out);
 int do_fsync(message *m_out);
 void pm_reboot(void);
@@ -296,7 +283,7 @@ long conv4(int norm, long x);
 int copy_name(size_t len, char *dest);
 int fetch_name(vir_bytes path, size_t len, char *dest);
 int no_sys(message *);
-int isokendpt_f(char *f, int l, endpoint_t e, int *p, int ft);
+int isokendpt_f(const char *f, int l, endpoint_t e, int *p, int ft);
 int in_group(struct fproc *rfp, gid_t grp);
 
 #define okendpt(e, p) isokendpt_f(__FILE__, __LINE__, (e), (p), 1)
index b35d2809de7b4f7c3786db00bd04750704d4e5a1..275be25606fb5956b0dc8173f1c03eb50a2de8a0 100644 (file)
@@ -106,7 +106,7 @@ int no_sys(message *UNUSED(m_out))
 /*===========================================================================*
  *                             isokendpt_f                                  *
  *===========================================================================*/
-int isokendpt_f(char *file, int line, endpoint_t endpoint, int *proc,
+int isokendpt_f(const char *file, int line, endpoint_t endpoint, int *proc,
        int fatal)
 {
   int failed = 0;