From: David van Moolenbroek Date: Wed, 30 Nov 2011 18:05:26 +0000 (+0100) Subject: VFS/FS: REQ_NEW_DRIVER now provides a label X-Git-Tag: v3.2.0~208 X-Git-Url: http://zhaoyanbai.com/repos/%22http:/www.isc.org/icons/Bv9ARM.html?a=commitdiff_plain;h=db087efac42d926ba11f63cbc25237ba0f7cfa40;p=minix.git VFS/FS: REQ_NEW_DRIVER now provides a label --- diff --git a/common/include/minix/bdev.h b/common/include/minix/bdev.h index 827f29399..9f1170eac 100644 --- a/common/include/minix/bdev.h +++ b/common/include/minix/bdev.h @@ -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); diff --git a/common/include/minix/vfsif.h b/common/include/minix/vfsif.h index 2bde532a2..60446eb42 100644 --- a/common/include/minix/vfsif.h +++ b/common/include/minix/vfsif.h @@ -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 diff --git a/lib/libbdev/bdev.c b/lib/libbdev/bdev.c index e188aa383..2bd536c35 100644 --- a/lib/libbdev/bdev.c +++ b/lib/libbdev/bdev.c @@ -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 index 000000000..8f88835f5 --- /dev/null +++ b/lib/libbdev/const.h @@ -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 */ diff --git a/lib/libbdev/driver.c b/lib/libbdev/driver.c index f4a8be48b..b7bd187a9 100644 --- a/lib/libbdev/driver.c +++ b/lib/libbdev/driver.c @@ -2,11 +2,16 @@ #include #include +#include #include +#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; } diff --git a/lib/libbdev/ipc.c b/lib/libbdev/ipc.c index afff3e49a..3cbf64380 100644 --- a/lib/libbdev/ipc.c +++ b/lib/libbdev/ipc.c @@ -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) diff --git a/lib/libbdev/proto.h b/lib/libbdev/proto.h index 31b3ee499..45392c053 100644 --- a/lib/libbdev/proto.h +++ b/lib/libbdev/proto.h @@ -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 */ diff --git a/servers/avfs/device.c b/servers/avfs/device.c index bc6b0d90c..66a0ae40a 100644 --- a/servers/avfs/device.c +++ b/servers/avfs/device.c @@ -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); } } diff --git a/servers/avfs/mount.c b/servers/avfs/mount.c index 02ed26752..f8457a2d4 100644 --- a/servers/avfs/mount.c +++ b/servers/avfs/mount.c @@ -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); } } } diff --git a/servers/avfs/open.c b/servers/avfs/open.c index f3bb7331e..caac61df4 100644 --- a/servers/avfs/open.c +++ b/servers/avfs/open.c @@ -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; } diff --git a/servers/avfs/proto.h b/servers/avfs/proto.h index 9046f04fc..d1766f5cd 100644 --- a/servers/avfs/proto.h +++ b/servers/avfs/proto.h @@ -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) ); diff --git a/servers/avfs/request.c b/servers/avfs/request.c index d1df5ef0c..f95c44ed1 100644 --- a/servers/avfs/request.c +++ b/servers/avfs/request.c @@ -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); } diff --git a/servers/ext2/misc.c b/servers/ext2/misc.c index faa184b40..2ee2e8cf1 100644 --- a/servers/ext2/misc.c +++ b/servers/ext2/misc.c @@ -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); } diff --git a/servers/ext2/mount.c b/servers/ext2/mount.c index ceb562e65..9d0133154 100644 --- a/servers/ext2/mount.c +++ b/servers/ext2/mount.c @@ -10,7 +10,6 @@ #include "buf.h" #include "inode.h" #include "super.h" -#include #include #include @@ -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) { diff --git a/servers/iso9660fs/misc.c b/servers/iso9660fs/misc.c index bce2b1617..ae5cab0dc 100644 --- a/servers/iso9660fs/misc.c +++ b/servers/iso9660fs/misc.c @@ -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); } diff --git a/servers/iso9660fs/mount.c b/servers/iso9660fs/mount.c index 95467b8e4..e8053bccb 100644 --- a/servers/iso9660fs/mount.c +++ b/servers/iso9660fs/mount.c @@ -1,6 +1,5 @@ #include "inc.h" #include -#include #include #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) { diff --git a/servers/mfs/misc.c b/servers/mfs/misc.c index 064e9138d..460aed7b3 100644 --- a/servers/mfs/misc.c +++ b/servers/mfs/misc.c @@ -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); } diff --git a/servers/mfs/mount.c b/servers/mfs/mount.c index a64054f86..c70d6a347 100644 --- a/servers/mfs/mount.c +++ b/servers/mfs/mount.c @@ -1,7 +1,6 @@ #include "fs.h" #include "inode.h" #include "super.h" -#include #include #include @@ -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) { diff --git a/servers/vfs/device.c b/servers/vfs/device.c index f6f936835..14f7370d1 100644 --- a/servers/vfs/device.c +++ b/servers/vfs/device.c @@ -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); } } diff --git a/servers/vfs/mount.c b/servers/vfs/mount.c index 42f1c202c..118568ef9 100644 --- a/servers/vfs/mount.c +++ b/servers/vfs/mount.c @@ -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); } } diff --git a/servers/vfs/open.c b/servers/vfs/open.c index 2a949b31f..fc6698f26 100644 --- a/servers/vfs/open.c +++ b/servers/vfs/open.c @@ -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; } diff --git a/servers/vfs/proto.h b/servers/vfs/proto.h index 485dc35af..3c9841d20 100644 --- a/servers/vfs/proto.h +++ b/servers/vfs/proto.h @@ -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) ); diff --git a/servers/vfs/request.c b/servers/vfs/request.c index 277300349..834ae8631 100644 --- a/servers/vfs/request.c +++ b/servers/vfs/request.c @@ -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); }