#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);
#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
#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.
first = FALSE;
}
- bdev_update(dev, endpt);
+ bdev_update(dev, label);
}
static int bdev_opcl(int req, dev_t dev, int access)
--- /dev/null
+#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 */
#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)
{
*/
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)
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)
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;
}
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)
/* 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 */
/* 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.
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
}
/* 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);
}
}
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);
}
}
}
}
/* 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;
}
- /* 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();
}
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;
}
_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) );
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;
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
* 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);
}
{
/* 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);
}
#include "buf.h"
#include "inode.h"
#include "super.h"
-#include <minix/ds.h>
#include <minix/vfsif.h>
#include <minix/bdev.h>
cp_grant_id_t label_gid;
size_t label_len;
int r = OK;
- endpoint_t driver_e;
int readonly, isroot;
u32_t mask;
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) {
/*===========================================================================*
* 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);
}
#include "inc.h"
#include <minix/vfsif.h>
-#include <minix/ds.h>
#include <minix/bdev.h>
#include "const.h"
#include "glo.h"
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) {
{
/* 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);
}
#include "fs.h"
#include "inode.h"
#include "super.h"
-#include <minix/ds.h>
#include <minix/vfsif.h>
#include <minix/bdev.h>
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;
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) {
/* 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
}
/* 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);
}
}
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);
}
}
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;
}
_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) );
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
* 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);
}
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);
}