]> Zhao Yanbai Git Server - minix.git/commitdiff
VFS/FS: REQ_NEW_DRIVER now provides a label
authorDavid van Moolenbroek <david@minix3.org>
Wed, 30 Nov 2011 18:05:26 +0000 (19:05 +0100)
committerDavid van Moolenbroek <david@minix3.org>
Wed, 30 Nov 2011 18:05:26 +0000 (19:05 +0100)
23 files changed:
common/include/minix/bdev.h
common/include/minix/vfsif.h
lib/libbdev/bdev.c
lib/libbdev/const.h [new file with mode: 0644]
lib/libbdev/driver.c
lib/libbdev/ipc.c
lib/libbdev/proto.h
servers/avfs/device.c
servers/avfs/mount.c
servers/avfs/open.c
servers/avfs/proto.h
servers/avfs/request.c
servers/ext2/misc.c
servers/ext2/mount.c
servers/iso9660fs/misc.c
servers/iso9660fs/mount.c
servers/mfs/misc.c
servers/mfs/mount.c
servers/vfs/device.c
servers/vfs/mount.c
servers/vfs/open.c
servers/vfs/proto.h
servers/vfs/request.c

index 827f293995d096b9686bb56ea759032eb8bfb8a7..9f1170eace7d79286f871efb2b9070b62b920ec5 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef __MINIX_BDEV_H
 #define __MINIX_BDEV_H
 
-extern void bdev_driver(dev_t dev, endpoint_t endpt);
+extern void bdev_driver(dev_t dev, char *label);
 
 extern int bdev_open(dev_t dev, int access);
 extern int bdev_close(dev_t dev);
index 2bde532a2c61c9ac836f8b3d0e5a0e89cbb77632..60446eb42070fb940e1d4bfcd27a5a34dd9da797 100644 (file)
@@ -10,7 +10,6 @@
 #define REQ_DEV                        m9_l5
 #define REQ_DEV2               m9_l1
 #define REQ_DIR_INO            m9_l3
-#define REQ_DRIVER_E           m9_l2
 #define REQ_FLAGS              m9_s3
 #define REQ_GID                        m9_s1
 #define REQ_GRANT              m9_l2
index e188aa38317c806e9449118fd16235566e868c36..2bd536c35e7a12ef2ab56835f9bd556a3c114c81 100644 (file)
@@ -9,7 +9,7 @@
 
 #include "proto.h"
 
-void bdev_driver(dev_t dev, endpoint_t endpt)
+void bdev_driver(dev_t dev, char *label)
 {
 /* Associate a driver with the given (major) device, using its endpoint.
  * File system usage note: typically called from mount and newdriver.
@@ -23,7 +23,7 @@ void bdev_driver(dev_t dev, endpoint_t endpt)
        first = FALSE;
   }
 
-  bdev_update(dev, endpt);
+  bdev_update(dev, label);
 }
 
 static int bdev_opcl(int req, dev_t dev, int access)
diff --git a/lib/libbdev/const.h b/lib/libbdev/const.h
new file mode 100644 (file)
index 0000000..8f88835
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef _BDEV_CONST_H
+#define _BDEV_CONST_H
+
+#define DS_NR_TRIES    100     /* number of times to check endpoint in DS */
+#define DS_DELAY       50000   /* delay time (us) between DS checks */
+
+#endif /* _BDEV_CONST_H */
index f4a8be48b4eb1f8f5aa57db96a94eba5c90e5349..b7bd187a9bc962d2cd520692ed66aaa9b5a5ee6f 100644 (file)
@@ -2,11 +2,16 @@
 
 #include <minix/drivers.h>
 #include <minix/bdev.h>
+#include <minix/ds.h>
 #include <assert.h>
 
+#include "const.h"
 #include "proto.h"
 
-static endpoint_t driver_endpt[NR_DEVICES];
+static struct {
+  endpoint_t endpt;
+  char label[DS_MAX_KEYLEN];
+} driver_tab[NR_DEVICES];
 
 void bdev_driver_init(void)
 {
@@ -14,8 +19,10 @@ void bdev_driver_init(void)
  */
   int i;
 
-  for (i = 0; i < NR_DEVICES; i++)
-       driver_endpt[i] = NONE;
+  for (i = 0; i < NR_DEVICES; i++) {
+       driver_tab[i].endpt = NONE;
+       driver_tab[i].label[0] = '\0';
+  }
 }
 
 void bdev_driver_clear(dev_t dev)
@@ -28,20 +35,26 @@ void bdev_driver_clear(dev_t dev)
 
   assert(major >= 0 && major < NR_DEVICES);
 
-  driver_endpt[major] = NONE;
+  driver_tab[major].endpt = NONE;
+  driver_tab[major].label[0] = '\0';
 }
 
-void bdev_driver_set(dev_t dev, endpoint_t endpt)
+endpoint_t bdev_driver_set(dev_t dev, char *label)
 {
-/* Set the endpoint for a driver.
+/* Set the label for a driver, and retrieve the associated endpoint.
  */
   int major;
 
   major = major(dev);
 
   assert(major >= 0 && major < NR_DEVICES);
+  assert(strlen(label) < sizeof(driver_tab[major].label));
 
-  driver_endpt[major] = endpt;
+  strcpy(driver_tab[major].label, label);
+
+  driver_tab[major].endpt = NONE;
+
+  return bdev_driver_update(dev);
 }
 
 endpoint_t bdev_driver_get(dev_t dev)
@@ -54,5 +67,55 @@ endpoint_t bdev_driver_get(dev_t dev)
 
   assert(major >= 0 && major < NR_DEVICES);
 
-  return driver_endpt[major];
+  return driver_tab[major].endpt;
+}
+
+endpoint_t bdev_driver_update(dev_t dev)
+{
+/* Update the endpoint of a driver. The caller of this function already knows
+ * that the current endpoint may no longer be valid, and must be updated.
+ * Return the new endpoint upon success, and NONE otherwise.
+ */
+  endpoint_t endpt;
+  int r, major, nr_tries;
+
+  major = major(dev);
+
+  assert(major >= 0 && major < NR_DEVICES);
+  assert(driver_tab[major].label[0] != '\0');
+
+  /* Repeatedly retrieve the endpoint for the driver label, and see if it is a
+   * different, valid endpoint. If retrieval fails at first, we have to wait.
+   * We use polling, as opposed to a DS subscription, for a number of reasons:
+   * 1) DS supports only one subscription per process, and our main program may
+   *    already have a subscription;
+   * 2) if we block on receiving a notification from DS, we cannot impose an
+   *    upper bound on the retry time;
+   * 3) temporarily subscribing and then unsubscribing may cause leftover DS
+   *    notifications, which the main program would then have to deal with.
+   *    As of writing, unsubscribing from DS is not possible at all, anyway.
+   *
+   * In the normal case, the driver's label/endpoint mapping entry disappears
+   * completely for a short moment, before being replaced with the new mapping.
+   * Hence, failure to retrieve the entry at all does not constitute permanent
+   * failure. In fact, there is no way to determine reliably that a driver has
+   * failed permanently in the current approach. For this we simply rely on the
+   * retry limit.
+   */
+  for (nr_tries = 0; nr_tries < DS_NR_TRIES; nr_tries++) {
+       r = ds_retrieve_label_endpt(driver_tab[major].label, &endpt);
+
+       if (r == OK && endpt != NONE && endpt != driver_tab[major].endpt) {
+               driver_tab[major].endpt = endpt;
+
+               return endpt;
+       }
+
+       if (nr_tries < DS_NR_TRIES - 1)
+               micro_delay(DS_DELAY);
+  }
+
+  driver_tab[major].endpt = NONE;
+
+  return NONE;
 }
index afff3e49ab5932b00f23092a78731df25bb69ea7..3cbf64380eab6396a3ab50983640f173159946aa 100644 (file)
@@ -19,15 +19,19 @@ static void bdev_cancel(dev_t dev)
   bdev_driver_clear(dev);
 }
 
-void bdev_update(dev_t dev, endpoint_t endpt)
+void bdev_update(dev_t dev, char *label)
 {
 /* Set the endpoint for a driver. Perform recovery if necessary.
  */
-  endpoint_t old_endpt;
+  endpoint_t endpt, old_endpt;
 
   old_endpt = bdev_driver_get(dev);
 
-  bdev_driver_set(dev, endpt);
+  endpt = bdev_driver_set(dev, label);
+
+  /* If updating the driver causes an endpoint change, we need to perform
+   * recovery, but not update the endpoint yet again.
+   */
 }
 
 int bdev_sendrec(dev_t dev, const message *m_orig)
index 31b3ee499626ce516fb72533b0fe769cc2e1001c..45392c05382de81b67ef73528e0388e4df0d47da 100644 (file)
@@ -4,11 +4,12 @@
 /* driver.c */
 extern void bdev_driver_init(void);
 extern void bdev_driver_clear(dev_t dev);
-extern void bdev_driver_set(dev_t dev, endpoint_t endpt);
+extern endpoint_t bdev_driver_set(dev_t dev, char *label);
 extern endpoint_t bdev_driver_get(dev_t dev);
+extern endpoint_t bdev_driver_update(dev_t dev);
 
 /* ipc.c */
-extern void bdev_update(dev_t dev, endpoint_t endpt);
+extern void bdev_update(dev_t dev, char *label);
 extern int bdev_sendrec(dev_t dev, const message *m_orig);
 
 #endif /* _BDEV_PROTO_H */
index bc6b0d90c607960a37a413a6bdab405147f214b7..66a0ae40a183ea58e9492bebd44df2d39da9142b 100644 (file)
@@ -911,13 +911,14 @@ PUBLIC void bdev_up(int maj)
   /* A new block device driver has been mapped in. This may affect both mounted
    * file systems and open block-special files.
    */
-  int r, new_driver_e, found, bits;
+  int r, found, bits;
   struct filp *rfilp;
   struct vmnt *vmp;
   struct vnode *vp;
+  char *label;
 
   if (maj < 0 || maj >= NR_DEVICES) panic("VFS: out-of-bound major");
-  new_driver_e = dmap[maj].dmap_driver;
+  label = dmap[maj].dmap_label;
 
   /* Tell each affected mounted file system about the new endpoint. This code
    * is currently useless, as driver endpoints do not change across restarts.
@@ -925,10 +926,10 @@ PUBLIC void bdev_up(int maj)
   for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; ++vmp) {
        if (major(vmp->m_dev) != maj) continue;
 
-       /* Send the new driver endpoint to the mounted file system. */
-       if (OK != req_newdriver(vmp->m_fs_e, vmp->m_dev, new_driver_e))
-               printf("VFS dev_up: error sending new driver endpoint."
-                      " FS_e: %d req_nr: %d\n", vmp->m_fs_e, REQ_NEW_DRIVER);
+       /* Send the driver label to the mounted file system. */
+       if (OK != req_newdriver(vmp->m_fs_e, vmp->m_dev, label))
+               printf("VFS dev_up: error sending new driver label to %d\n",
+                      vmp->m_fs_e);
   }
 
   /* For each block-special file that was previously opened on the affected
@@ -950,14 +951,14 @@ PUBLIC void bdev_up(int maj)
   }
 
   /* If any block-special file was open for this major at all, also inform the
-   * root file system about the new endpoint of the driver. We do this even if
-   * the block-special file is linked to another mounted file system, merely
+   * root file system about the new driver. We do this even if the
+   * block-special file is linked to another mounted file system, merely
    * because it is more work to check for that case.
    */
   if (found) {
-       if (OK != req_newdriver(ROOT_FS_E, makedev(maj, 0), new_driver_e))
-               printf("VFSdev_up: error sending new driver endpoint."
-                      " FS_e: %d req_nr: %d\n", ROOT_FS_E, REQ_NEW_DRIVER);
+       if (OK != req_newdriver(ROOT_FS_E, makedev(maj, 0), label))
+               printf("VFSdev_up: error sending new driver label to %d\n",
+                       ROOT_FS_E);
   }
 }
 
index 02ed267527375ffa6c2913be4f51688b1e1f52af..f8457a2d4c64ecefb786a5318d85b6075cf815d4 100644 (file)
@@ -65,22 +65,21 @@ PRIVATE void update_bspec(dev_t dev, endpoint_t fs_e, int send_drv_e)
                if (send_drv_e) {
                        major = major(dev);
                        if (major < 0 || major >= NR_DEVICES) {
-                               /* Can't update driver endpoint for out of
-                                * range major */
+                               /* Can't update for out-of-range major */
                                continue;
                        }
                        dp = &dmap[major(dev)];
                        if (dp->dmap_driver == NONE) {
-                               /* Can't send new driver endpoint for
-                                * vanished driver */
-                               printf("VFS: can't send new driver endpt\n");
+                               /* Can't update for vanished driver */
+                               printf("VFS: can't send new driver label\n");
                                continue;
                        }
 
                        if ((r = req_newdriver(fs_e, vp->v_sdev,
-                                               dp->dmap_driver)) != OK) {
-                               printf("VFS: Failed to send new driver endpoint"
-                                      " for moved block special file\n");
+                                       dp->dmap_label)) != OK) {
+                               printf("VFS: Failed to send new driver label"
+                                      " for moved block special file to %d\n",
+                                      fs_e);
                        }
                }
        }
index f3bb7331e026f1253ce71215b26703a99cc2807e..caac61df4074aa65a8c4616e14af3968e010b15b 100644 (file)
@@ -186,8 +186,9 @@ PRIVATE int common_open(char path[PATH_MAX], int oflags, mode_t omode)
                        }
 
                        /* Check whether the device is mounted or not. If so,
-                        * then that FS is responsible for this device. Else
-                        * we default to ROOT_FS. */
+                        * then that FS is responsible for this device.
+                        * Otherwise we default to ROOT_FS.
+                        */
                        vp->v_bfs_e = ROOT_FS_E; /* By default */
                        for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; ++vmp)
                                if (vmp->m_dev == vp->v_sdev &&
@@ -195,11 +196,11 @@ PRIVATE int common_open(char path[PATH_MAX], int oflags, mode_t omode)
                                        vp->v_bfs_e = vmp->m_fs_e;
                                }
 
-                       /* Send the driver endpoint to the file system that
-                        * will handle the block I/O requests (even when its
-                        * endpoint is known already), but only when it is the
-                        * root file system. Other file systems will already
-                        * have it anyway.
+                       /* Send the driver label to the file system that will
+                        * handle the block I/O requests (even when its label
+                        * and endpoint are known already), but only when it is
+                        * the root file system. Other file systems will
+                        * already have it anyway.
                         */
                        if (vp->v_bfs_e != ROOT_FS_E) {
                                unlock_bsf();
@@ -207,8 +208,8 @@ PRIVATE int common_open(char path[PATH_MAX], int oflags, mode_t omode)
                        }
 
                        if (req_newdriver(vp->v_bfs_e, vp->v_sdev,
-                                              dp->dmap_driver) != OK) {
-                               printf("VFS: error sending driver endpoint\n");
+                                       dp->dmap_label) != OK) {
+                               printf("VFS: error sending driver label\n");
                                bdev_close(dev);
                                r = ENXIO;
                        }
index 9046f04fc730c374626cb38c5db5f920b096884c..d1766f5cd217be080766ec4e6e6d79e4196ff59f 100644 (file)
@@ -277,7 +277,7 @@ _PROTOTYPE( int req_unmount, (endpoint_t fs_e)                          );
 _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)                                        );
+            char *label)                                               );
 
 /* stadir.c */
 _PROTOTYPE( int do_chdir, (void)                                       );
index d1df5ef0caf0ea57f2aa9d5b1fe8b78211bd2308..f95c44ed132080d70f4bf58f2fb8bb124979f93f 100644 (file)
@@ -556,7 +556,6 @@ PUBLIC int req_mknod(
 PUBLIC int req_mountpoint(endpoint_t fs_e, ino_t inode_nr)
 {
   message m;
-  int r;
 
   /* Fill in request message */
   m.m_type = REQ_MOUNTPOINT;
@@ -610,7 +609,7 @@ PUBLIC int req_newnode(
 PUBLIC int req_newdriver(
   endpoint_t fs_e,
   dev_t dev,
-  endpoint_t driver_e
+  char *label
 )
 {
 /* Note: this is the only request function that doesn't use the
@@ -618,23 +617,33 @@ PUBLIC int req_newdriver(
  * driver recovery mechanism here. This function is actually called
  * during the recovery.
  */
+  cp_grant_id_t grant_id;
+  size_t len;
   message m;
   int r;
 
+  /* Grant access to label */
+  len = strlen(label) + 1;
+  grant_id = cpf_grant_direct(fs_e, (vir_bytes) label, len, CPF_READ);
+  if (grant_id == -1)
+       panic("req_newdriver: cpf_grant_direct failed");
+
   /* Fill in request message */
   m.m_type = REQ_NEW_DRIVER;
   m.REQ_DEV = dev;
-  m.REQ_DRIVER_E = driver_e;
+  m.REQ_GRANT = grant_id;
+  m.REQ_PATH_LEN = len;
 
   /* Issue request */
   if((r = sendrec(fs_e, &m)) != OK) {
          printf("%s:%d VFS req_newdriver: error sending message %d to %d\n",
                 __FILE__, __LINE__, r, fs_e);
          util_stacktrace();
-         return(r);
   }
 
-  return(OK);
+  cpf_revoke(grant_id);
+
+  return(r);
 }
 
 
index faa184b40696a1826fec8dfb9fe6768292aaefe3..2ee2e8cf164f096a2451f546fd8841abf2b9d66b 100644 (file)
@@ -71,12 +71,27 @@ PUBLIC int fs_new_driver(void)
 {
 /* Set a new driver endpoint for this device. */
   dev_t dev;
-  endpoint_t endpt;
+  cp_grant_id_t label_gid;
+  size_t label_len;
+  char label[sizeof(fs_dev_label)];
+  int r;
 
   dev = (dev_t) fs_m_in.REQ_DEV;
-  endpt = (endpoint_t) fs_m_in.REQ_DRIVER_E;
+  label_gid = (cp_grant_id_t) fs_m_in.REQ_GRANT;
+  label_len = (size_t) fs_m_in.REQ_PATH_LEN;
 
-  bdev_driver(dev, endpt);
+  if (label_len > sizeof(label))
+       return(EINVAL);
+
+  r = sys_safecopyfrom(fs_m_in.m_source, label_gid, (vir_bytes) 0,
+       (vir_bytes) label, label_len, D);
+
+  if (r != OK) {
+       printf("ext2: fs_new_driver safecopyfrom failed (%d)\n", r);
+       return(EINVAL);
+  }
+
+  bdev_driver(dev, label);
 
   return(OK);
 }
index ceb562e658fcf089b1f86a73547469ec9ca1d800..9d0133154820eae16fb51f2bcc16a4e90c465808 100644 (file)
@@ -10,7 +10,6 @@
 #include "buf.h"
 #include "inode.h"
 #include "super.h"
-#include <minix/ds.h>
 #include <minix/vfsif.h>
 #include <minix/bdev.h>
 
@@ -31,7 +30,6 @@ PUBLIC int fs_readsuper()
   cp_grant_id_t label_gid;
   size_t label_len;
   int r = OK;
-  endpoint_t driver_e;
   int readonly, isroot;
   u32_t mask;
 
@@ -52,16 +50,8 @@ PUBLIC int fs_readsuper()
        return(EINVAL);
   }
 
-  r= ds_retrieve_label_endpt(fs_dev_label, &driver_e);
-  if (r != OK)
-  {
-       printf("ext2:fs_readsuper: ds_retrieve_label_endpt failed for '%s': %d\n",
-               fs_dev_label, r);
-       return EINVAL;
-  }
-
-  /* Map the driver endpoint for this major */
-  bdev_driver(fs_dev, driver_e);
+  /* Map the driver label for this major. */
+  bdev_driver(fs_dev, fs_dev_label);
 
   /* Open the device the file system lives on. */
   if (bdev_open(fs_dev, readonly ? R_BIT : (R_BIT|W_BIT)) != OK) {
index bce2b1617bce3754bab0ebc91d8d3855950680d9..ae5cab0dc1993aec1012956d9875ffa03d9bf0e6 100644 (file)
@@ -17,16 +17,31 @@ PUBLIC int fs_sync()
 /*===========================================================================*
  *                             fs_new_driver                                *
  *===========================================================================*/
-PUBLIC int fs_new_driver()
+PUBLIC int fs_new_driver(void)
 {
 /* Set a new driver endpoint for this device. */
   dev_t dev;
-  endpoint_t endpt;
+  cp_grant_id_t label_gid;
+  size_t label_len;
+  char label[sizeof(fs_dev_label)];
+  int r;
 
   dev = (dev_t) fs_m_in.REQ_DEV;
-  endpt = (endpoint_t) fs_m_in.REQ_DRIVER_E;
+  label_gid = (cp_grant_id_t) fs_m_in.REQ_GRANT;
+  label_len = (size_t) fs_m_in.REQ_PATH_LEN;
 
-  bdev_driver(dev, endpt);
+  if (label_len > sizeof(label))
+       return(EINVAL);
+
+  r = sys_safecopyfrom(fs_m_in.m_source, label_gid, (vir_bytes) 0,
+       (vir_bytes) label, label_len, D);
+
+  if (r != OK) {
+       printf("ISOFS: fs_new_driver safecopyfrom failed (%d)\n", r);
+       return(EINVAL);
+  }
+
+  bdev_driver(dev, label);
 
   return(OK);
 }
index 95467b8e4e88d9ed6c78e6f598489267cb092fb6..e8053bccb34ce9cb7c932a5dcf3bc1061a25f4e7 100644 (file)
@@ -1,6 +1,5 @@
 #include "inc.h"
 #include <minix/vfsif.h>
-#include <minix/ds.h>
 #include <minix/bdev.h>
 #include "const.h"
 #include "glo.h"
@@ -32,15 +31,8 @@ PUBLIC int fs_readsuper() {
        return(EINVAL);
   }
 
-  r = ds_retrieve_label_endpt(fs_dev_label, &driver_e);
-  if (r != OK) {
-       printf("ISOFS %s:%d ds_retrieve_label_endpt failed for '%s': %d\n",
-               __FILE__, __LINE__, fs_dev_label, r);
-       return(EINVAL);
-  }
-
-  /* Map the driver endpoint for this major */
-  bdev_driver(fs_dev, driver_e);
+  /* Map the driver label for this major */
+  bdev_driver(fs_dev, fs_dev_label);
 
   /* Open the device the file system lives on */
   if (bdev_open(fs_dev, readonly ? R_BIT : (R_BIT|W_BIT)) != OK) {
index 064e9138db45a596cafee96b090d06ee03b9bd29..460aed7b3126cb06f12bf6a7c9b83b4a94d8b3be 100644 (file)
@@ -59,12 +59,27 @@ PUBLIC int fs_new_driver(void)
 {
 /* Set a new driver endpoint for this device. */
   dev_t dev;
-  endpoint_t endpt;
+  cp_grant_id_t label_gid;
+  size_t label_len;
+  char label[sizeof(fs_dev_label)];
+  int r;
 
   dev = (dev_t) fs_m_in.REQ_DEV;
-  endpt = (endpoint_t) fs_m_in.REQ_DRIVER_E;
+  label_gid = (cp_grant_id_t) fs_m_in.REQ_GRANT;
+  label_len = (size_t) fs_m_in.REQ_PATH_LEN;
 
-  bdev_driver(dev, endpt);
+  if (label_len > sizeof(label))
+       return(EINVAL);
+
+  r = sys_safecopyfrom(fs_m_in.m_source, label_gid, (vir_bytes) 0,
+       (vir_bytes) label, label_len, D);
+
+  if (r != OK) {
+       printf("MFS: fs_new_driver safecopyfrom failed (%d)\n", r);
+       return(EINVAL);
+  }
+
+  bdev_driver(dev, label);
 
   return(OK);
 }
index a64054f86069eddff3ddd0e8bf9244e1bd2d55d1..c70d6a347c3f1f491f73ce5a0668deb52bd12d9c 100644 (file)
@@ -1,7 +1,6 @@
 #include "fs.h"
 #include "inode.h"
 #include "super.h"
-#include <minix/ds.h>
 #include <minix/vfsif.h>
 #include <minix/bdev.h>
 
@@ -22,7 +21,6 @@ PUBLIC int fs_readsuper()
   cp_grant_id_t label_gid;
   size_t label_len;
   int r;
-  endpoint_t driver_e;
   int readonly, isroot;
 
   fs_dev    = (dev_t) fs_m_in.REQ_DEV;
@@ -41,15 +39,8 @@ PUBLIC int fs_readsuper()
        return(EINVAL);
   }
 
-  r = ds_retrieve_label_endpt(fs_dev_label, &driver_e);
-  if (r != OK) {
-       printf("MFS %s:%d ds_retrieve_label_endpt failed for '%s': %d\n",
-               __FILE__, __LINE__, fs_dev_label, r);
-       return(EINVAL);
-  }
-
-  /* Map the driver endpoint for this major */
-  bdev_driver(fs_dev, driver_e);
+  /* Map the driver label for this major. */
+  bdev_driver(fs_dev, fs_dev_label);
 
   /* Open the device the file system lives on. */
   if (bdev_open(fs_dev, readonly ? R_BIT : (R_BIT|W_BIT) ) != OK) {
index f6f93683542f2566348106f6c35e7358824ec9db..14f7370d133e082d614ac83fb01d3437cacaa4ab 100644 (file)
@@ -976,23 +976,24 @@ PUBLIC void bdev_up(int maj)
   /* A new block device driver has been mapped in. This may affect both mounted
    * file systems and open block-special files.
    */
-  int r, new_driver_e, found, bits;
+  int r, found, bits;
   struct filp *fp;
   struct vmnt *vmp;
   struct vnode *vp;
+  char *label;
 
-  new_driver_e = dmap[maj].dmap_driver;
+  label = dmap[maj].dmap_label;
 
-  /* Tell each affected mounted file system about the new endpoint. This code
+  /* Tell each affected mounted file system about the new driver. This code
    * is currently useless, as driver endpoints do not change across restarts.
    */
   for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; ++vmp) {
        if (major(vmp->m_dev) != maj) continue;
 
-       /* Send the new driver endpoint to the mounted file system. */
-       if (OK != req_newdriver(vmp->m_fs_e, vmp->m_dev, new_driver_e))
-               printf("VFSdev_up: error sending new driver endpoint."
-                      " FS_e: %d req_nr: %d\n", vmp->m_fs_e, REQ_NEW_DRIVER);
+       /* Send the driver label to the mounted file system. */
+       if (OK != req_newdriver(vmp->m_fs_e, vmp->m_dev, label))
+               printf("VFSdev_up: error sending new driver label to %d\n",
+                      vmp->m_fs_e);
   }
 
   /* For each block-special file that was previously opened on the affected
@@ -1014,14 +1015,14 @@ PUBLIC void bdev_up(int maj)
   }
 
   /* If any block-special file was open for this major at all, also inform the
-   * root file system about the new endpoint of the driver. We do this even if
-   * the block-special file is linked to another mounted file system, merely
+   * root file system about the endpoint update of the driver. We do this even
+   * if the block-special file is linked to another mounted file system, merely
    * because it is more work to check for that case.
    */
   if (found) {
-       if (OK != req_newdriver(ROOT_FS_E, makedev(maj, 0), new_driver_e))
-               printf("VFSdev_up: error sending new driver endpoint."
-                      " FS_e: %d req_nr: %d\n", ROOT_FS_E, REQ_NEW_DRIVER);
+       if (OK != req_newdriver(ROOT_FS_E, makedev(maj, 0), label))
+               printf("VFSdev_up: error sending new driver label to %d\n",
+                      ROOT_FS_E);
   }
 }
 
index 42f1c202c7259b5b7ba937ff84c01c0df49a3051..118568ef9304035203629dac508a5db1cba1b5fe 100644 (file)
@@ -452,11 +452,11 @@ PUBLIC int unmount(
                printf("VFS: umount moving block spec %d to root FS\n", dev);
                vp->v_bfs_e = ROOT_FS_E;
                        
-                 /* Send the (potentially new) driver endpoint */
-               r = req_newdriver(vp->v_bfs_e, vp->v_sdev, dp->dmap_driver);
+               /* Send the driver label */
+               r = req_newdriver(vp->v_bfs_e, vp->v_sdev, dp->dmap_label);
                if (r != OK) 
-                       printf("VFS: error sending driver endpoint for"
-                               " moved block spec\n");
+                       printf("VFS: error sending driver label for"
+                               " moved block spec to %d\n", vp->v_bfs_e);
                  
        }
   }
index 2a949b31feffbd4299ca85f3408ead4761857dc7..fc6698f26b12f2f7fd0869eb01f2b50e5183727e 100644 (file)
@@ -145,22 +145,21 @@ PUBLIC int common_open(register int oflags, mode_t omode)
                        if (r != OK) break;
 
                        /* Check whether the device is mounted or not. If so,
-                          then that FS is responsible for this device. Else
-                          we default to ROOT_FS. */
+                        * then that FS is responsible for this device.
+                        * Otherwise we default to ROOT_FS.
+                        */
                        vp->v_bfs_e = ROOT_FS_E; /* By default */
                        for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; ++vmp) 
                                if (vmp->m_dev == vp->v_sdev) 
                                        vp->v_bfs_e = vmp->m_fs_e;
 
-                       /* Get the driver endpoint of the block spec device */
-                       dp = &dmap[major(vp->v_sdev)];
-
-                       /* Send the driver endpoint to the file system (even
-                        * when known already).
+                       /* Send the driver label to the file system (even when
+                        * known already).
                         */
+                       dp = &dmap[major(vp->v_sdev)];
                        if ((r = req_newdriver(vp->v_bfs_e, vp->v_sdev,
-                                              dp->dmap_driver)) != OK) {
-                               printf("VFS: error sending driver endpoint\n");
+                                       dp->dmap_label)) != OK) {
+                               printf("VFS: error sending driver label\n");
                                bdev_close(dev);
                                r = ENXIO;
                        }
index 485dc35af710c8c4209c1b0623817df2f12c1626..3c9841d20f12478e8ba940e2a801e503a735a393 100644 (file)
@@ -238,7 +238,7 @@ _PROTOTYPE( int req_unmount, (endpoint_t fs_e)                          );
 _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)                                        );
+            char *label)                                               );
 
 /* stadir.c */
 _PROTOTYPE( int do_chdir, (void)                                       );
index 2773003495f7d8bc3782d35b5776a2ef533325e2..834ae86316a6b4b71a2afcb6107014a8713c4ac7 100644 (file)
@@ -611,7 +611,7 @@ PUBLIC int req_newnode(
 PUBLIC int req_newdriver(
   endpoint_t fs_e,
   dev_t dev,
-  endpoint_t driver_e
+  char *label
 )
 {
 /* Note: this is the only request function that doesn't use the 
@@ -619,23 +619,33 @@ PUBLIC int req_newdriver(
  * driver recovery mechanism here. This function is actually called 
  * during the recovery.
  */
+  cp_grant_id_t grant_id;
+  size_t len;
   message m;
   int r;
 
+  /* Grant access to label */
+  len = strlen(label) + 1;
+  grant_id = cpf_grant_direct(fs_e, (vir_bytes) label, len, CPF_READ);
+  if (grant_id == -1)
+       panic("req_newdriver: cpf_grant_direct failed");
+
   /* Fill in request message */
   m.m_type = REQ_NEW_DRIVER;
   m.REQ_DEV = dev;
-  m.REQ_DRIVER_E = driver_e;
+  m.REQ_GRANT = grant_id;
+  m.REQ_PATH_LEN = len;
 
   /* Issue request */
   if((r = sendrec(fs_e, &m)) != OK) {
          printf("%s:%d VFS req_newdriver: error sending message %d to %d\n",
                 __FILE__, __LINE__, r, fs_e);
          util_stacktrace();
-         return(r);
   }
 
-  return(OK);
+  cpf_revoke(grant_id);
+
+  return(r);
 }
 
 
@@ -1151,68 +1161,6 @@ PRIVATE int fs_sendrec_f(char *file, int line, endpoint_t fs_e, message *reqm)
        nested_fs_call(reqm);
   }
 
-#if 0
-      if(r == OK) {
-       /* Sendrec was okay */
-       break;
-      }
-      /* Dead driver */
-      if (r == EDEADSRCDST || r == EDSTDIED || r == ESRCDIED) {
-          old_driver_e = NONE;
-          /* Find old driver by endpoint */
-          for (vmp = &vmnt[0]; vmp < &vmnt[NR_MNTS]; ++vmp) {
-              if (vmp->m_fs_e == fs_e) {   /* found FS */
-#if 0
-                  old_driver_e = vmp->m_driver_e;
-#endif
-                  dmap_unmap_by_endpt(old_driver_e); /* unmap driver */
-                  break;
-              }
-          }
-         
-          /* No FS ?? */
-          if (old_driver_e == NONE)
-              panic("VFSdead_driver: couldn't find FS: %d", fs_e);
-
-          /* Wait for a new driver. */
-          for (;;) {
-              new_driver_e = 0;
-              printf("VFSdead_driver: waiting for new driver\n");
-              r = sef_receive(RS_PROC_NR, &m);
-              if (r != OK) {
-                       panic("VFSdead_driver: unable to receive from RS: %d",  r);
-              }
-              if (m.m_type == DEVCTL) {
-                  /* Map new driver */
-                  r = fs_devctl(m.ctl_req, m.dev_nr, m.driver_nr,
-                          m.dev_style, m.m_force);
-                  if (m.ctl_req == DEV_MAP && r == OK) {
-                      new_driver_e = m.driver_nr;
-                      printf("VFSdead_driver: new driver endpoint: %d\n",
-                              new_driver_e);
-                  }
-              }
-              else {
-                       panic("VFSdead_driver: got message from RS type: %d", m.m_type);
-              }
-              m.m_type = r;
-              if ((r = send(RS_PROC_NR, &m)) != OK) {
-                       panic("VFSdead_driver: unable to send to RS: %d", r);
-              }
-              /* New driver is ready */
-              if (new_driver_e) break;
-          }
-          
-          /* Copy back original request */
-          *reqm = origm;  
-          continue;
-      }
-
-       printf("fs_sendrec: unhandled error %d sending to %d\n", r, fs_e);
-       panic("fs_sendrec: unhandled error");
-  }
-#endif
-
   /* Return message type */
   return(reqm->m_type);
 }