VFS/FS: REQ_NEW_DRIVER now provides a label

This commit is contained in:
David van Moolenbroek 2011-11-30 19:05:26 +01:00
parent 41e69065b9
commit db087efac4
23 changed files with 236 additions and 186 deletions

View 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);

View 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

View 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)

7
lib/libbdev/const.h Normal file
View File

@ -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 */

View 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;
}

View 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)

View 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 */

View 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);
}
}

View 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);
}
}
}

View 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;
}

View 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) );

View 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);
}

View 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);
}

View 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) {

View 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);
}

View 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) {

View 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);
}

View 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) {

View 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);
}
}

View 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);
}
}

View 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;
}

View 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) );

View 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);
}