VFS/FS: REQ_NEW_DRIVER now provides a label
This commit is contained in:
parent
41e69065b9
commit
db087efac4
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
7
lib/libbdev/const.h
Normal 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 */
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) );
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) );
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user