diff --git a/common/include/Makefile.inc b/common/include/Makefile.inc index 24a39355d..25df3fa0a 100644 --- a/common/include/Makefile.inc +++ b/common/include/Makefile.inc @@ -5,6 +5,7 @@ INCS+= env.h fetch.h hgfs.h lib.h libutil.h timers.h INCS+= minix/acpi.h minix/ansi.h minix/audio_fw.h minix/bitmap.h \ + minix/bdev.h \ minix/callnr.h minix/com.h minix/compiler.h minix/config.h \ minix/const.h minix/cpufeature.h minix/crtso.h minix/debug.h \ minix/devio.h minix/devman.h minix/dmap.h minix/driver.h \ diff --git a/common/include/minix/bdev.h b/common/include/minix/bdev.h new file mode 100644 index 000000000..e0ef8067c --- /dev/null +++ b/common/include/minix/bdev.h @@ -0,0 +1,19 @@ +#ifndef __MINIX_BDEV_H +#define __MINIX_BDEV_H + +#define BDEV_NOFLAGS 0 + +extern void bdev_driver(dev_t dev, endpoint_t endpt); + +extern int bdev_open(dev_t dev, int access); +extern int bdev_close(dev_t dev); + +extern int bdev_read(dev_t dev, u64_t pos, char *buf, int count, int flags); +extern int bdev_write(dev_t dev, u64_t pos, char *buf, int count, int flags); +extern int bdev_gather(dev_t dev, u64_t pos, iovec_t *vec, int count, + int flags, vir_bytes *size); +extern int bdev_scatter(dev_t dev, u64_t pos, iovec_t *vec, int count, + int flags, vir_bytes *size); +extern int bdev_ioctl(dev_t dev, int request, void *buf); + +#endif /* __MINIX_BDEV_H */ diff --git a/lib/Makefile b/lib/Makefile index 3e9dc86d9..16cdf1382 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -18,7 +18,7 @@ SUBDIR= csu ${LIBCOMPAT_DIR} ${LIBC_DIR} libdriver libnetdriver \ libedit ${LIBM_DIR} libsys libtimers libminixutil libbz2 libl libhgfs \ libz libfetch libarchive libvtreefs libaudiodriver libmthread \ libexec libdevman libusb ${LIBMINLIB_DIR} ${LIBASYN_DIR} \ - libddekit libminixfs + libddekit libminixfs libbdev .if defined(NBSD_LIBC) && (${NBSD_LIBC} != "no") SUBDIR+= libelf libminc libcrypt libterminfo libcurses libvassert libutil diff --git a/lib/libbdev/Makefile b/lib/libbdev/Makefile new file mode 100644 index 000000000..37e4021a8 --- /dev/null +++ b/lib/libbdev/Makefile @@ -0,0 +1,8 @@ +# Makefile for libbdev +.include + +LIB= bdev + +SRCS= bdev.c ipc.c driver.c + +.include diff --git a/lib/libbdev/bdev.c b/lib/libbdev/bdev.c new file mode 100644 index 000000000..8182dcd55 --- /dev/null +++ b/lib/libbdev/bdev.c @@ -0,0 +1,348 @@ +/* libbdev - block device interfacing library, by D.C. van Moolenbroek */ + +/* This is a preliminary, bare-essentials-only version of this library. */ + +#include +#include +#include +#include + +#include "proto.h" + +void bdev_driver(dev_t dev, endpoint_t endpt) +{ +/* Associate a driver with the given (major) device, using its endpoint. + * File system usage note: typically called from mount and newdriver. + */ + static int first = TRUE; + + if (first) { + /* Initialize the driver endpoint array. */ + bdev_driver_init(); + + first = FALSE; + } + + bdev_update(dev, endpt); +} + +static int bdev_opcl(int req, dev_t dev, int access) +{ +/* Open or close the given minor device. + */ + message m; + + m.m_type = req; + m.DEVICE = minor(dev); + m.COUNT = access; + + return bdev_sendrec(dev, &m); +} + +int bdev_open(dev_t dev, int access) +{ +/* Open the given minor device. + * File system usage note: typically called from mount, after bdev_driver. + */ + + return bdev_opcl(DEV_OPEN, dev, access); +} + +int bdev_close(dev_t dev) +{ +/* Close the given minor device. + * File system usage note: typically called from unmount. + */ + + return bdev_opcl(DEV_CLOSE, dev, 0); +} + +static int bdev_rdwt_setup(int req, dev_t dev, u64_t pos, char *buf, int count, + int UNUSED(flags), message *m) +{ +/* Set up a single-buffer read/write request. + */ + endpoint_t endpt; + cp_grant_id_t grant; + int access; + + if ((endpt = bdev_driver_get(dev)) == NONE) + return EDEADSRCDST; + + access = (req == DEV_READ_S) ? CPF_WRITE : CPF_READ; + + grant = cpf_grant_direct(endpt, (vir_bytes) buf, count, access); + + if (!GRANT_VALID(grant)) { + printf("bdev: unable to allocate grant!\n"); + return EINVAL; + } + + m->m_type = req; + m->DEVICE = minor(dev); + m->POSITION = ex64lo(pos); + m->HIGHPOS = ex64hi(pos); + m->COUNT = count; + m->IO_GRANT = (void *) grant; + + return OK; +} + +static void bdev_rdwt_cleanup(message *m) +{ +/* Clean up a single-buffer read/write request. + */ + cp_grant_id_t grant; + + grant = (cp_grant_id_t) m->IO_GRANT; + + cpf_revoke(grant); +} + +static int bdev_rdwt(int req, dev_t dev, u64_t pos, char *buf, int count, + int flags) +{ +/* Perform a read or write call using a single buffer. + */ + message m; + int r; + + if ((r = bdev_rdwt_setup(req, dev, pos, buf, count, flags, &m)) != OK) + return r; + + r = bdev_sendrec(dev, &m); + + bdev_rdwt_cleanup(&m); + + return r; +} + +static int bdev_vrdwt_setup(int req, dev_t dev, u64_t pos, iovec_t *vec, + int count, int UNUSED(flags), message *m, iovec_s_t *gvec, + cp_grant_id_t *grants, vir_bytes *size) +{ +/* Set up a vectored read/write request. + */ + endpoint_t endpt; + cp_grant_id_t grant; + int i, access; + + assert(count <= NR_IOREQS); + + if ((endpt = bdev_driver_get(dev)) == NONE) + return EDEADSRCDST; + + access = (req == DEV_GATHER_S) ? CPF_WRITE : CPF_READ; + *size = 0; + + for (i = 0; i < count; i++) { + grants[i] = cpf_grant_direct(endpt, vec[i].iov_addr, vec[i].iov_size, + access); + + if (!GRANT_VALID(grants[i])) { + printf("bdev: unable to allocate grant!\n"); + + for (i--; i >= 0; i--) + cpf_revoke(grants[i]); + + return EINVAL; + } + + /* We keep a separate grants array to prevent local leaks if the driver + * ends up clobbering the grant vector. Future protocol updates should + * make the grant for the vector read-only. + */ + gvec[i].iov_grant = grants[i]; + gvec[i].iov_size = vec[i].iov_size; + + assert(*size + vec[i].iov_size > *size); + + *size += vec[i].iov_size; + } + + grant = cpf_grant_direct(endpt, (vir_bytes) gvec, sizeof(gvec[0]) * count, + CPF_READ | CPF_WRITE); + + if (!GRANT_VALID(grant)) { + printf("bdev: unable to allocate grant!\n"); + + for (i = count - 1; i >= 0; i--) + cpf_revoke(grants[i]); + + return EINVAL; + } + + m->m_type = req; + m->DEVICE = minor(dev); + m->POSITION = ex64lo(pos); + m->HIGHPOS = ex64hi(pos); + m->COUNT = count; + m->IO_GRANT = (void *) grant; + + return OK; +} + +static void bdev_vrdwt_cleanup(message *m, cp_grant_id_t *grants) +{ +/* Clean up a vectored read/write request. + */ + cp_grant_id_t grant; + int i; + + grant = (cp_grant_id_t) m->IO_GRANT; + + cpf_revoke(grant); + + for (i = m->COUNT - 1; i >= 0; i--) + cpf_revoke(grants[i]); +} + +static int bdev_vrdwt_adjust(dev_t dev, iovec_s_t *gvec, int count, + vir_bytes *size) +{ +/* Adjust the number of bytes transferred, by subtracting from it the number of + * bytes *not* transferred according to the result vector. + */ + int i; + + for (i = 0; i < count; i++) { + if (*size < gvec[i].iov_size) { + printf("bdev: driver (%d) returned bad vector\n", + bdev_driver_get(dev)); + + return FALSE; + } + + *size -= gvec[i].iov_size; + } + + return TRUE; +} + +static int bdev_vrdwt(int req, dev_t dev, u64_t pos, iovec_t *vec, int count, + int flags, vir_bytes *size) +{ +/* Perform a read or write call using a vector of buffer. + */ + iovec_s_t gvec[NR_IOREQS]; + cp_grant_id_t grants[NR_IOREQS]; + message m; + int r; + + if ((r = bdev_vrdwt_setup(req, dev, pos, vec, count, flags, &m, gvec, + grants, size)) != OK) { + *size = 0; + return r; + } + + r = bdev_sendrec(dev, &m); + + bdev_vrdwt_cleanup(&m, grants); + + /* Also return the number of bytes transferred. */ + if (!bdev_vrdwt_adjust(dev, gvec, count, size)) { + *size = 0; + r = EIO; + } + + return r; +} + +int bdev_read(dev_t dev, u64_t pos, char *buf, int count, int flags) +{ +/* Perform a read call into a single buffer. + */ + + return bdev_rdwt(DEV_READ_S, dev, pos, buf, count, flags); +} + +int bdev_write(dev_t dev, u64_t pos, char *buf, int count, int flags) +{ +/* Perform a write call from a single buffer. + */ + + return bdev_rdwt(DEV_WRITE_S, dev, pos, buf, count, flags); +} + +int bdev_gather(dev_t dev, u64_t pos, iovec_t *vec, int count, int flags, + vir_bytes *size) +{ +/* Perform a read call into a vector of buffers. + */ + + return bdev_vrdwt(DEV_GATHER_S, dev, pos, vec, count, flags, size); +} + +int bdev_scatter(dev_t dev, u64_t pos, iovec_t *vec, int count, int flags, + vir_bytes *size) +{ +/* Perform a write call from a vector of buffers. + */ + + return bdev_vrdwt(DEV_SCATTER_S, dev, pos, vec, count, flags, size); +} + +static int bdev_ioctl_setup(dev_t dev, int request, void *buf, message *m) +{ +/* Set up an I/O control request. + */ + endpoint_t endpt; + size_t size; + cp_grant_id_t grant; + int access; + + if ((endpt = bdev_driver_get(dev)) == NONE) + return EDEADSRCDST; + + if (_MINIX_IOCTL_BIG(request)) + size = _MINIX_IOCTL_SIZE_BIG(request); + else + size = _MINIX_IOCTL_SIZE(request); + + access = 0; + if (_MINIX_IOCTL_IOR(access)) access |= CPF_WRITE; + if (_MINIX_IOCTL_IOW(access)) access |= CPF_READ; + + /* The size may be 0, in which case 'buf' need not be a valid pointer. */ + grant = cpf_grant_direct(endpt, (vir_bytes) buf, size, access); + + if (!GRANT_VALID(grant)) { + printf("bdev: unable to allocate grant!\n"); + return EINVAL; + } + + m->m_type = DEV_IOCTL_S; + m->DEVICE = minor(dev); + m->REQUEST = request; + m->IO_GRANT = (void *) grant; + + return OK; +} + +static void bdev_ioctl_cleanup(message *m) +{ +/* Clean up an I/O control request. + */ + cp_grant_id_t grant; + + grant = (cp_grant_id_t) m->IO_GRANT; + + cpf_revoke(grant); +} + +int bdev_ioctl(dev_t dev, int request, void *buf) +{ +/* Perform an I/O control request. + */ + message m; + int r; + + if ((r = bdev_ioctl_setup(dev, request, buf, &m)) != OK) + return r; + + r = bdev_sendrec(dev, &m); + + bdev_ioctl_cleanup(&m); + + return r; +} diff --git a/lib/libbdev/driver.c b/lib/libbdev/driver.c new file mode 100644 index 000000000..f4a8be48b --- /dev/null +++ b/lib/libbdev/driver.c @@ -0,0 +1,58 @@ +/* libbdev - driver endpoint management */ + +#include +#include +#include + +#include "proto.h" + +static endpoint_t driver_endpt[NR_DEVICES]; + +void bdev_driver_init(void) +{ +/* Initialize the driver table. + */ + int i; + + for (i = 0; i < NR_DEVICES; i++) + driver_endpt[i] = NONE; +} + +void bdev_driver_clear(dev_t dev) +{ +/* Clear information about a driver. + */ + int major; + + major = major(dev); + + assert(major >= 0 && major < NR_DEVICES); + + driver_endpt[major] = NONE; +} + +void bdev_driver_set(dev_t dev, endpoint_t endpt) +{ +/* Set the endpoint for a driver. + */ + int major; + + major = major(dev); + + assert(major >= 0 && major < NR_DEVICES); + + driver_endpt[major] = endpt; +} + +endpoint_t bdev_driver_get(dev_t dev) +{ +/* Return the endpoint for a driver, or NONE if we do not know its endpoint. + */ + int major; + + major = major(dev); + + assert(major >= 0 && major < NR_DEVICES); + + return driver_endpt[major]; +} diff --git a/lib/libbdev/ipc.c b/lib/libbdev/ipc.c new file mode 100644 index 000000000..941d2e187 --- /dev/null +++ b/lib/libbdev/ipc.c @@ -0,0 +1,89 @@ +/* libbdev - IPC and recovery functions */ + +#include +#include +#include + +#include "proto.h" + +static void bdev_cancel(dev_t dev) +{ +/* Recovering the driver for the given device has failed repeatedly. Mark it as + * permanently unusable, and clean up any associated calls and resources. + */ + + printf("bdev: driver for major %d crashed\n", major(dev)); + + /* Mark the driver as unusable. */ + bdev_driver_clear(dev); +} + +void bdev_update(dev_t dev, endpoint_t endpt) +{ +/* Set the endpoint for a driver. Perform recovery if necessary. + */ + endpoint_t old_endpt; + + old_endpt = bdev_driver_get(dev); + + bdev_driver_set(dev, endpt); + + /* If updating the driver causes an endpoint change, the driver has + * restarted. + */ + if (old_endpt != NONE && old_endpt != endpt) + bdev_cancel(dev); +} + +int bdev_sendrec(dev_t dev, const message *m_orig) +{ +/* Send a request to the given device, and wait for the reply. + */ + endpoint_t endpt; + message m; + int r; + + /* If we have no usable driver endpoint, fail instantly. */ + if ((endpt = bdev_driver_get(dev)) == NONE) + return EDEADSRCDST; + + /* Send the request and block until we receive a reply. */ + m = *m_orig; + m.USER_ENDPT = (endpoint_t) -1; /* synchronous request; no ID */ + + r = sendrec(endpt, &m); + + /* This version of libbdev does not support recovery. Forget the driver. */ + if (r == EDEADSRCDST) { + bdev_cancel(dev); + + return EDEADSRCDST; + } + + if (r != OK) { + printf("bdev: IPC to driver (%d) failed (%d)\n", endpt, r); + return r; + } + + if (m.m_type != TASK_REPLY) { + printf("bdev: driver (%d) sent weird response (%d)\n", + endpt, m.m_type); + return EIO; + } + + /* ERESTART signifies a driver restart. Again, we do not support this yet. */ + if (m.REP_STATUS == ERESTART) { + bdev_cancel(dev); + + return EDEADSRCDST; + } + + if (m.REP_ENDPT != (endpoint_t) -1) { + printf("bdev: driver (%d) sent invalid response (%d)\n", + endpt, m.REP_ENDPT); + return EIO; + } + + /* We got a reply to our request. */ + return m.REP_STATUS; +} diff --git a/lib/libbdev/proto.h b/lib/libbdev/proto.h new file mode 100644 index 000000000..31b3ee499 --- /dev/null +++ b/lib/libbdev/proto.h @@ -0,0 +1,14 @@ +#ifndef _BDEV_PROTO_H +#define _BDEV_PROTO_H + +/* 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_get(dev_t dev); + +/* ipc.c */ +extern void bdev_update(dev_t dev, endpoint_t endpt); +extern int bdev_sendrec(dev_t dev, const message *m_orig); + +#endif /* _BDEV_PROTO_H */ diff --git a/servers/ext2/Makefile b/servers/ext2/Makefile index 599355c96..dcc1bea64 100644 --- a/servers/ext2/Makefile +++ b/servers/ext2/Makefile @@ -1,12 +1,12 @@ # Makefile for ext2 filesystem PROG= ext2 -SRCS= balloc.c cache.c device.c link.c \ +SRCS= balloc.c cache.c link.c \ mount.c misc.c open.c protect.c read.c \ stadir.c table.c time.c utility.c \ write.c ialloc.c inode.c main.c path.c \ super.c DPADD+= ${LIBSYS} -LDADD+= -lminixfs -lsys +LDADD+= -lminixfs -lbdev -lsys MAN= diff --git a/servers/ext2/cache.c b/servers/ext2/cache.c index 2b0305d85..9fb27ff4f 100644 --- a/servers/ext2/cache.c +++ b/servers/ext2/cache.c @@ -17,6 +17,7 @@ #include "fs.h" #include +#include #include #include #include @@ -290,14 +291,18 @@ PRIVATE void rw_block( * is not reported to the caller. If the error occurred while purging a block * from the cache, it is not clear what the caller could do about it anyway. */ - int r, op, op_failed = 0; + int r, op_failed = 0; u64_t pos; dev_t dev; if ( (dev = bp->b_dev) != NO_DEV) { pos = mul64u(bp->b_blocknr, fs_block_size); - op = (rw_flag == READING ? MFS_DEV_READ : MFS_DEV_WRITE); - r = block_dev_io(op, dev, SELF_E, bp->b_data, pos, fs_block_size); + if (rw_flag == READING) + r = bdev_read(dev, pos, bp->b_data, fs_block_size, + BDEV_NOFLAGS); + else + r = bdev_write(dev, pos, bp->b_data, fs_block_size, + BDEV_NOFLAGS); if (r < 0) { printf("Ext2(%d) I/O error on device %d/%d, block %u\n", SELF_E, major(dev), minor(dev), bp->b_blocknr); @@ -382,6 +387,8 @@ PUBLIC void rw_scattered( register int i; register iovec_t *iop; static iovec_t *iovec = NULL; + vir_bytes size; + u64_t pos; int j, r; STATICINIT(iovec, NR_IOREQS); @@ -414,16 +421,18 @@ PUBLIC void rw_scattered( iop->iov_addr = (vir_bytes) bp->b_data; iop->iov_size = (vir_bytes) fs_block_size; } - r = block_dev_io(rw_flag == WRITING ? MFS_DEV_SCATTER : MFS_DEV_GATHER, - dev, SELF_E, iovec, - mul64u(bufq[0]->b_blocknr, fs_block_size), j); + pos = mul64u(bufq[0]->b_blocknr, fs_block_size); + if (rw_flag == READING) + r = bdev_gather(dev, pos, iovec, j, BDEV_NOFLAGS, &size); + else + r = bdev_scatter(dev, pos, iovec, j, BDEV_NOFLAGS, &size); /* Harvest the results. Dev_io reports the first error it may have * encountered, but we only care if it's the first block that failed. */ for (i = 0, iop = iovec; i < j; i++, iop++) { bp = bufq[i]; - if (iop->iov_size != 0) { + if (size < iop->iov_size) { /* Transfer failed. An error? Do we care? */ if (r != OK && i == 0) { printf( @@ -440,6 +449,7 @@ PUBLIC void rw_scattered( } else { bp->b_dirt = CLEAN; } + size -= iop->iov_size; } bufq += i; bufqsize -= i; diff --git a/servers/ext2/const.h b/servers/ext2/const.h index 6a511cafd..a6d415e8b 100644 --- a/servers/ext2/const.h +++ b/servers/ext2/const.h @@ -116,12 +116,6 @@ #define NUL(str,l,m) mfs_nul_f(__FILE__,__LINE__,(str), (l), (m)) -/* Args to dev_bio/dev_io */ -#define MFS_DEV_READ 10001 -#define MFS_DEV_WRITE 10002 -#define MFS_DEV_SCATTER 10003 -#define MFS_DEV_GATHER 10004 - /* FS states */ #define EXT2_VALID_FS 0x0001 /* Cleanly unmounted */ #define EXT2_ERROR_FS 0x0002 /* Errors detected */ diff --git a/servers/ext2/device.c b/servers/ext2/device.c deleted file mode 100644 index d29d39331..000000000 --- a/servers/ext2/device.c +++ /dev/null @@ -1,359 +0,0 @@ -#include "fs.h" -#include -#include -#include -#include -#include -#include "inode.h" -#include "super.h" -#include "const.h" -#include "drivers.h" - -#include - -FORWARD _PROTOTYPE( int safe_io_conversion, (endpoint_t driver, - cp_grant_id_t *gid, int *op, cp_grant_id_t *gids, endpoint_t *io_ept, - void **buffer, int *vec_grants, size_t bytes)); -FORWARD _PROTOTYPE( void safe_io_cleanup, (cp_grant_id_t, cp_grant_id_t *, - int)); -FORWARD _PROTOTYPE( int gen_opcl, (endpoint_t driver_e, int op, - dev_t dev, endpoint_t proc_e, int flags) ); -FORWARD _PROTOTYPE( int gen_io, (endpoint_t task_nr, message *mess_ptr) ); - - -/*===========================================================================* - * fs_new_driver * - *===========================================================================*/ -PUBLIC int fs_new_driver(void) -{ - /* New driver endpoint for this device */ - dev_t dev; - dev = (dev_t) fs_m_in.REQ_DEV; - driver_endpoints[major(dev)].driver_e = (endpoint_t) fs_m_in.REQ_DRIVER_E; - return(OK); -} - - -/*===========================================================================* - * safe_io_conversion * - *===========================================================================*/ -PRIVATE int safe_io_conversion(driver, gid, op, gids, io_ept, buffer, - vec_grants, bytes) -endpoint_t driver; -cp_grant_id_t *gid; -int *op; -cp_grant_id_t *gids; -endpoint_t *io_ept; -void **buffer; -int *vec_grants; -size_t bytes; -{ - unsigned int j; - int access; - iovec_t *v; - static iovec_t *new_iovec; - - STATICINIT(new_iovec, NR_IOREQS); - - /* Number of grants allocated in vector I/O. */ - *vec_grants = 0; - - /* Driver can handle it - change request to a safe one. */ - - *gid = GRANT_INVALID; - - switch(*op) { - case MFS_DEV_READ: - case MFS_DEV_WRITE: - /* Change to safe op. */ - *op = *op == MFS_DEV_READ ? DEV_READ_S : DEV_WRITE_S; - *gid = cpf_grant_direct(driver, (vir_bytes) *buffer, bytes, - *op == DEV_READ_S ? CPF_WRITE : CPF_READ); - if(*gid == GRANT_INVALID) { - panic("cpf_grant_magic of buffer failed"); - } - - break; - case MFS_DEV_GATHER: - case MFS_DEV_SCATTER: - /* Change to safe op. */ - *op = *op == MFS_DEV_GATHER ? DEV_GATHER_S : DEV_SCATTER_S; - - /* Grant access to my new i/o vector. */ - *gid = cpf_grant_direct(driver, (vir_bytes) new_iovec, - bytes * sizeof(iovec_t), CPF_READ|CPF_WRITE); - if(*gid == GRANT_INVALID) { - panic("cpf_grant_direct of vector failed"); - } - - v = (iovec_t *) *buffer; - - /* Grant access to i/o buffers. */ - for(j = 0; j < bytes; j++) { - if(j >= NR_IOREQS) - panic("vec too big: %u", bytes); - access = (*op == DEV_GATHER_S) ? CPF_WRITE : CPF_READ; - new_iovec[j].iov_addr = gids[j] = - cpf_grant_direct(driver, (vir_bytes) v[j].iov_addr, - (size_t) v[j].iov_size, access); - - if(!GRANT_VALID(gids[j])) { - panic("ext2: grant to iovec buf failed"); - } - new_iovec[j].iov_size = v[j].iov_size; - (*vec_grants)++; - } - - /* Set user's vector to the new one. */ - *buffer = new_iovec; - break; - default: - panic("Illegal operation %d\n", *op); - break; - } - - /* If we have converted to a safe operation, I/O - * endpoint becomes FS if it wasn't already. - */ - if(GRANT_VALID(*gid)) { - *io_ept = SELF_E; - return 1; - } - - /* Not converted to a safe operation (because there is no - * copying involved in this operation). - */ - return 0; -} - -/*===========================================================================* - * safe_io_cleanup * - *===========================================================================*/ -PRIVATE void safe_io_cleanup(gid, gids, gids_size) -cp_grant_id_t gid; -cp_grant_id_t *gids; -int gids_size; -{ -/* Free resources (specifically, grants) allocated by safe_io_conversion(). */ - int j; - - (void) cpf_revoke(gid); - - for(j = 0; j < gids_size; j++) - (void) cpf_revoke(gids[j]); - - return; -} - -/*===========================================================================* - * block_dev_io * - *===========================================================================*/ -PUBLIC int block_dev_io( - int op, /* MFS_DEV_READ, MFS_DEV_WRITE, etc. */ - dev_t dev, /* major-minor device number */ - endpoint_t proc_e, /* in whose address space is buf? */ - void *buffer, /* virtual address of the buffer */ - u64_t pos, /* byte position */ - size_t bytes /* how many bytes to transfer */ -) -{ -/* Read or write from a device. The parameter 'dev' tells which one. */ - int r, safe; - message m; - cp_grant_id_t gid = GRANT_INVALID; - int vec_grants; - int op_used; - void *buf_used; - static cp_grant_id_t *gids; - endpoint_t driver_e; - - STATICINIT(gids, NR_IOREQS); - - /* Determine driver endpoint for this device */ - driver_e = driver_endpoints[major(dev)].driver_e; - - /* See if driver is roughly valid. */ - if (driver_e == NONE) { - printf("ext2(%d) block_dev_io: no driver for dev %x\n", SELF_E, dev); - return(EDEADEPT); - } - - /* The io vector copying relies on this I/O being for FS itself. */ - if(proc_e != SELF_E) { - printf("ext2(%d) doing block_dev_io for non-self %d\n", SELF_E, proc_e); - panic("doing block_dev_io for non-self: %d", proc_e); - } - - /* By default, these are right. */ - m.USER_ENDPT = proc_e; - m.ADDRESS = buffer; - buf_used = buffer; - - /* Convert parameters to 'safe mode'. */ - op_used = op; - safe = safe_io_conversion(driver_e, &gid, &op_used, gids, &m.USER_ENDPT, - &buf_used, &vec_grants, bytes); - - /* Set up rest of the message. */ - if (safe) m.IO_GRANT = (char *) gid; - - m.m_type = op_used; - m.DEVICE = minor(dev); - m.POSITION = ex64lo(pos); - m.COUNT = bytes; - m.HIGHPOS = ex64hi(pos); - - /* Call the task. */ - r = sendrec(driver_e, &m); - if(r == OK && m.REP_STATUS == ERESTART) r = EDEADEPT; - - /* As block I/O never SUSPENDs, safe cleanup must be done whether - * the I/O succeeded or not. */ - if (safe) safe_io_cleanup(gid, gids, vec_grants); - - /* RECOVERY: - * - send back dead driver number - * - VFS unmaps it, waits for new driver - * - VFS sends the new driver endp for the FS proc and the request again - */ - if (r != OK) { - if (r == EDEADSRCDST || r == EDEADEPT) { - printf("ext2(%d) dead driver %d\n", SELF_E, driver_e); - driver_endpoints[major(dev)].driver_e = NONE; - return(r); - } else if (r == ELOCKED) { - printf("ext2(%d) ELOCKED talking to %d\n", SELF_E, driver_e); - return(r); - } else - panic("call_task: can't send/receive: %d", r); - } else { - /* Did the process we did the sendrec() for get a result? */ - if (m.REP_ENDPT != proc_e) { - printf("ext2(%d) strange device reply from %d, type = %d, proc " - "= %d (not %d) (2) ignored\n", SELF_E, m.m_source, - m.m_type, proc_e, m.REP_ENDPT); - r = EIO; - } - } - - /* Task has completed. See if call completed. */ - if (m.REP_STATUS == SUSPEND) { - panic("ext2 block_dev_io: driver returned SUSPEND"); - } - - if(buffer != buf_used && r == OK) { - memcpy(buffer, buf_used, bytes * sizeof(iovec_t)); - } - - return(m.REP_STATUS); -} - -/*===========================================================================* - * dev_open * - *===========================================================================*/ -PUBLIC int dev_open( - endpoint_t driver_e, - dev_t dev, /* device to open */ - endpoint_t proc_e, /* process to open for */ - int flags /* mode bits and flags */ -) -{ - int major, r; - - /* Determine the major device number call the device class specific - * open/close routine. (This is the only routine that must check the - * device number for being in range. All others can trust this check.) - */ - major = major(dev); - if (major >= NR_DEVICES) { - printf("Major device number %d not in range\n", major(dev)); - return(EIO); - } - r = gen_opcl(driver_e, DEV_OPEN, dev, proc_e, flags); - if (r == SUSPEND) panic("suspend on open from"); - return(r); -} - - -/*===========================================================================* - * dev_close * - *===========================================================================*/ -PUBLIC void dev_close( - endpoint_t driver_e, - dev_t dev /* device to close */ -) -{ - (void) gen_opcl(driver_e, DEV_CLOSE, dev, 0, 0); -} - - -/*===========================================================================* - * gen_opcl * - *===========================================================================*/ -PRIVATE int gen_opcl( - endpoint_t driver_e, - int op, /* operation, DEV_OPEN or DEV_CLOSE */ - dev_t dev, /* device to open or close */ - endpoint_t proc_e, /* process to open/close for */ - int flags /* mode bits and flags */ -) -{ -/* Called from the dmap struct in table.c on opens & closes of special files.*/ - message dev_mess; - - dev_mess.m_type = op; - dev_mess.DEVICE = minor(dev); - dev_mess.USER_ENDPT = proc_e; - dev_mess.COUNT = flags; - - /* Call the task. */ - (void) gen_io(driver_e, &dev_mess); - - return(dev_mess.REP_STATUS); -} - - -/*===========================================================================* - * gen_io * - *===========================================================================*/ -PRIVATE int gen_io( - endpoint_t task_nr, /* which task to call */ - message *mess_ptr /* pointer to message for task */ -) -{ -/* All file system I/O ultimately comes down to I/O on major/minor device - * pairs. These lead to calls on the following routines via the dmap table. - */ - - int r, proc_e; - - proc_e = mess_ptr->USER_ENDPT; - - r = sendrec(task_nr, mess_ptr); - if(r == OK && mess_ptr->REP_STATUS == ERESTART) - r = EDEADEPT; - - if (r != OK) { - if (r == EDEADSRCDST || r == EDEADEPT) { - printf("fs: dead driver %d\n", task_nr); - panic("should handle crashed drivers"); - return(r); - } - if (r == ELOCKED) { - printf("fs: ELOCKED talking to %d\n", task_nr); - return(r); - } - panic("call_task: can't send/receive: %d", r); - } - - /* Did the process we did the sendrec() for get a result? */ - if (mess_ptr->REP_ENDPT != proc_e) { - printf("fs: strange device reply from %d, type = %d, proc = %d (not " - "%d) (2) ignored\n", mess_ptr->m_source, mess_ptr->m_type, - proc_e, - mess_ptr->REP_ENDPT); - return(EIO); - } - - return(OK); -} diff --git a/servers/ext2/drivers.h b/servers/ext2/drivers.h deleted file mode 100644 index 24eaeec08..000000000 --- a/servers/ext2/drivers.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef EXT2_DRIVERS_H -#define EXT2_DRIVERS_H - -/* Driver endpoints for major devices. Only the block devices - * are mapped here, it's a subset of the mapping in the VFS */ - -EXTERN struct driver_endpoints { - endpoint_t driver_e; -} driver_endpoints[NR_DEVICES]; - -#endif /* EXT2_DRIVERS_H */ diff --git a/servers/ext2/main.c b/servers/ext2/main.c index 0561877ec..f7f581991 100644 --- a/servers/ext2/main.c +++ b/servers/ext2/main.c @@ -11,7 +11,6 @@ #include #include "buf.h" #include "inode.h" -#include "drivers.h" /* Declare some local functions. */ FORWARD _PROTOTYPE(void get_work, (message *m_in) ); @@ -101,6 +100,8 @@ PUBLIC int main(int argc, char *argv[]) if (error == OK) read_ahead(); /* do block read ahead */ } + + return 0; } /*===========================================================================* @@ -151,10 +152,6 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) init_inode_cache(); - /* Init driver mapping */ - for (i = 0; i < NR_DEVICES; ++i) - driver_endpoints[i].driver_e = NONE; - SELF_E = getprocnr(); /* just a small number before we find out the block size at mount time */ diff --git a/servers/ext2/misc.c b/servers/ext2/misc.c index 435637ebf..faa184b40 100644 --- a/servers/ext2/misc.c +++ b/servers/ext2/misc.c @@ -5,6 +5,7 @@ #include "fs.h" #include #include +#include #include "inode.h" #include "super.h" @@ -62,3 +63,20 @@ PUBLIC int fs_flush() return(OK); } + +/*===========================================================================* + * fs_new_driver * + *===========================================================================*/ +PUBLIC int fs_new_driver(void) +{ +/* Set a new driver endpoint for this device. */ + dev_t dev; + endpoint_t endpt; + + dev = (dev_t) fs_m_in.REQ_DEV; + endpt = (endpoint_t) fs_m_in.REQ_DRIVER_E; + + bdev_driver(dev, endpt); + + return(OK); +} diff --git a/servers/ext2/mount.c b/servers/ext2/mount.c index a062e4e6b..ceb562e65 100644 --- a/servers/ext2/mount.c +++ b/servers/ext2/mount.c @@ -10,9 +10,9 @@ #include "buf.h" #include "inode.h" #include "super.h" -#include "drivers.h" #include #include +#include /*===========================================================================* @@ -61,11 +61,10 @@ PUBLIC int fs_readsuper() } /* Map the driver endpoint for this major */ - driver_endpoints[(fs_dev >> MAJOR) & BYTE].driver_e = driver_e; + bdev_driver(fs_dev, driver_e); /* Open the device the file system lives on. */ - if (dev_open(driver_e, fs_dev, driver_e, - readonly ? R_BIT : (R_BIT|W_BIT)) != OK) { + if (bdev_open(fs_dev, readonly ? R_BIT : (R_BIT|W_BIT)) != OK) { return(EINVAL); } @@ -79,7 +78,7 @@ PUBLIC int fs_readsuper() /* Is it recognized as a Minix filesystem? */ if (r != OK) { superblock->s_dev = NO_DEV; - dev_close(driver_e, fs_dev); + bdev_close(fs_dev); return(r); } @@ -120,7 +119,7 @@ PUBLIC int fs_readsuper() if (superblock->s_state == EXT2_ERROR_FS) { printf("ext2: filesystem wasn't cleanly unmounted previous time\n"); superblock->s_dev = NO_DEV; - dev_close(driver_e, fs_dev); + bdev_close(fs_dev); return(EINVAL); } @@ -133,17 +132,17 @@ PUBLIC int fs_readsuper() /* Get the root inode of the mounted file system. */ if ( (root_ip = get_inode(fs_dev, ROOT_INODE)) == NULL) { printf("ext2: couldn't get root inode\n"); - superblock->s_dev = NO_DEV; - dev_close(driver_e, fs_dev); - return(EINVAL); + superblock->s_dev = NO_DEV; + bdev_close(fs_dev); + return(EINVAL); } if (root_ip != NULL && root_ip->i_mode == 0) { - printf("%s:%d zero mode for root inode?\n", __FILE__, __LINE__); - put_inode(root_ip); - superblock->s_dev = NO_DEV; - dev_close(driver_e, fs_dev); - return(EINVAL); + printf("%s:%d zero mode for root inode?\n", __FILE__, __LINE__); + put_inode(root_ip); + superblock->s_dev = NO_DEV; + bdev_close(fs_dev); + return(EINVAL); } if (root_ip != NULL && (root_ip->i_mode & I_TYPE) != I_DIRECTORY) { @@ -151,7 +150,7 @@ PUBLIC int fs_readsuper() __FILE__, __LINE__); put_inode(root_ip); superblock->s_dev = NO_DEV; - dev_close(driver_e, fs_dev); + bdev_close(fs_dev); return(EINVAL); } @@ -253,7 +252,7 @@ PUBLIC int fs_unmount() } /* Close the device the file system lives on. */ - dev_close(driver_endpoints[(fs_dev >> MAJOR) & BYTE].driver_e, fs_dev); + bdev_close(fs_dev); /* Finish off the unmount. */ superblock->s_dev = NO_DEV; diff --git a/servers/ext2/path.c b/servers/ext2/path.c index ee054ac64..939452019 100644 --- a/servers/ext2/path.c +++ b/servers/ext2/path.c @@ -21,6 +21,7 @@ #include "inode.h" #include "super.h" #include +#include PUBLIC char dot1[2] = "."; /* used for search_dir to bypass the access */ PUBLIC char dot2[3] = ".."; /* permissions for . and .. */ diff --git a/servers/ext2/proto.h b/servers/ext2/proto.h index a76d0657e..093aecd62 100644 --- a/servers/ext2/proto.h +++ b/servers/ext2/proto.h @@ -26,14 +26,6 @@ _PROTOTYPE( void set_blocksize, (unsigned int blocksize, u32_t blocks, _PROTOTYPE( void rw_scattered, (dev_t dev, struct buf **bufq, int bufqsize, int rw_flag) ); -/* device.c */ -_PROTOTYPE( int block_dev_io, (int op, dev_t dev, endpoint_t proc_e, - void *buf, u64_t pos, size_t bytes) ); -_PROTOTYPE( int dev_open, (endpoint_t driver_e, dev_t dev, endpoint_t proc_e, - int flags) ); -_PROTOTYPE( void dev_close, (endpoint_t driver_e, dev_t dev) ); -_PROTOTYPE( int fs_new_driver, (void) ); - /* ialloc.c */ _PROTOTYPE( struct inode *alloc_inode, (struct inode *parent, mode_t bits)); _PROTOTYPE( void free_inode, (struct inode *rip) ); @@ -59,6 +51,7 @@ _PROTOTYPE( int truncate_inode, (struct inode *rip, off_t len) ); /* misc.c */ _PROTOTYPE( int fs_flush, (void) ); _PROTOTYPE( int fs_sync, (void) ); +_PROTOTYPE( int fs_new_driver, (void) ); /* mount.c */ _PROTOTYPE( int fs_mountpoint, (void) ); diff --git a/servers/ext2/super.c b/servers/ext2/super.c index fd2b5d97a..c1fc4279a 100644 --- a/servers/ext2/super.c +++ b/servers/ext2/super.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "buf.h" #include "inode.h" #include "super.h" @@ -92,10 +93,9 @@ register struct super_block *sp; /* pointer to a superblock */ panic("can't allocate memory for super_block buffers"); assert(_MIN_BLOCK_SIZE <= sizeof(*ondisk_superblock)); - r = block_dev_io(MFS_DEV_READ, dev, SELF_E, - (char*) ondisk_superblock, cvu64(super_block_offset), - _MIN_BLOCK_SIZE); - + r = bdev_read(dev, cvu64(super_block_offset), (char*) ondisk_superblock, + _MIN_BLOCK_SIZE, BDEV_NOFLAGS); + if (r != _MIN_BLOCK_SIZE) return(EINVAL); @@ -178,9 +178,8 @@ register struct super_block *sp; /* pointer to a superblock */ gdt_position = (opt.block_with_super + 1) * 1024; } - r = block_dev_io(MFS_DEV_READ, dev, SELF_E, - (char*) ondisk_group_descs, cvu64(gdt_position), - gd_size); + r = bdev_read(dev, cvu64(gdt_position), (char*) ondisk_group_descs, + gd_size, BDEV_NOFLAGS); if (r != gd_size) { printf("Can not read group descriptors\n"); return(EINVAL); @@ -232,8 +231,8 @@ struct super_block *sp; /* pointer to a superblock */ super_copy(ondisk_superblock, sp); - r = block_dev_io(MFS_DEV_WRITE, sp->s_dev, SELF_E, - sp, cvu64(super_block_offset), SUPER_SIZE_D); + r = bdev_write(sp->s_dev, cvu64(super_block_offset), (char *) sp, + SUPER_SIZE_D, BDEV_NOFLAGS); if (r != SUPER_SIZE_D) printf("ext2: Warning, failed to write superblock to the disk!\n"); @@ -250,9 +249,8 @@ struct super_block *sp; /* pointer to a superblock */ copy_group_descriptors(ondisk_group_descs, sp->s_group_desc, sp->s_groups_count); - r = block_dev_io(MFS_DEV_WRITE, sp->s_dev, SELF_E, - (char*) ondisk_group_descs, cvu64(gdt_position), - gd_size); + r = bdev_write(sp->s_dev, cvu64(gdt_position), + (char*) ondisk_group_descs, gd_size, BDEV_NOFLAGS); if (r != gd_size) { printf("Can not write group descriptors\n"); } diff --git a/servers/ext2/table.c b/servers/ext2/table.c index 222bd6d03..28330864a 100644 --- a/servers/ext2/table.c +++ b/servers/ext2/table.c @@ -11,7 +11,6 @@ #include "inode.h" #include "buf.h" #include "super.h" -#include "drivers.h" PUBLIC _PROTOTYPE (int (*fs_call_vec[]), (void) ) = { no_sys, /* 0 not used */ diff --git a/servers/iso9660fs/Makefile b/servers/iso9660fs/Makefile index 3e79a43eb..aa1a4edb2 100644 --- a/servers/iso9660fs/Makefile +++ b/servers/iso9660fs/Makefile @@ -1,10 +1,10 @@ # Makefile for ISO9660 fs PROG= isofs -SRCS= main.c table.c mount.c super.c inode.c device.c \ +SRCS= main.c table.c mount.c super.c inode.c \ utility.c misc.c path.c read.c stadir.c cache.c DPADD+= ${LIBSYS} ${LIBTIMERS} -LDADD+= -lsys -ltimers +LDADD+= -lbdev -lsys MAN= diff --git a/servers/iso9660fs/cache.c b/servers/iso9660fs/cache.c index d58e93e4f..b8f1e9a98 100644 --- a/servers/iso9660fs/cache.c +++ b/servers/iso9660fs/cache.c @@ -14,6 +14,7 @@ #include "inc.h" #include #include +#include #include "buf.h" FORWARD _PROTOTYPE(int read_block, (struct buf *)); @@ -89,7 +90,7 @@ register struct buf *bp; /* pointer to the buffer to be released */ PRIVATE int read_block(bp) register struct buf *bp; /* buffer pointer */ { - int r, op; + int r; u64_t pos; int block_size; @@ -98,8 +99,7 @@ register struct buf *bp; /* buffer pointer */ pos = mul64u(bp->b_blocknr, block_size); /* get absolute position */ - op = MFS_DEV_READ; /* flag to read */ - r = block_dev_io(op, fs_dev, SELF_E, bp->b_data, pos, block_size, 0); + r = bdev_read(fs_dev, pos, bp->b_data, block_size, BDEV_NOFLAGS); if (r != block_size) { if (r >= 0) r = END_OF_FILE; if (r != END_OF_FILE) diff --git a/servers/iso9660fs/const.h b/servers/iso9660fs/const.h index f6cde1994..3dfd35317 100644 --- a/servers/iso9660fs/const.h +++ b/servers/iso9660fs/const.h @@ -55,11 +55,6 @@ /* maximum size of length of name file used in dir records */ #define ISO9660_MAX_FILE_ID_LEN 32 -#define MFS_DEV_READ 10001 -#define MFS_DEV_WRITE 10002 -#define MFS_DEV_SCATTER 10003 -#define MFS_DEV_GATHER 10004 - #define END_OF_FILE (-104) /* eof detected */ /* Miscellaneous constants */ diff --git a/servers/iso9660fs/device.c b/servers/iso9660fs/device.c deleted file mode 100644 index 440d258ef..000000000 --- a/servers/iso9660fs/device.c +++ /dev/null @@ -1,337 +0,0 @@ -#include "inc.h" -#include - -FORWARD _PROTOTYPE( int safe_io_conversion, (endpoint_t, cp_grant_id_t *, - int *, cp_grant_id_t *, int, - endpoint_t *, void **, int *, - vir_bytes)); -FORWARD _PROTOTYPE( void safe_io_cleanup, (cp_grant_id_t, cp_grant_id_t *, - int)); -FORWARD _PROTOTYPE( int gen_opcl, (endpoint_t driver_e, int op, - dev_t dev, int proc_e, int flags)); -FORWARD _PROTOTYPE( int gen_io, (endpoint_t task_nr, message *mess_ptr)); - - -/*===========================================================================* - * fs_new_driver * - *===========================================================================*/ -PUBLIC int fs_new_driver(void) -{ - /* New driver endpoint for this device */ - driver_endpoints[(fs_m_in.REQ_DEV >> MAJOR) & BYTE].driver_e = - fs_m_in.REQ_DRIVER_E; - return(OK); -} - - -/*===========================================================================* - * safe_io_conversion * - *===========================================================================*/ -PRIVATE int safe_io_conversion(driver, gid, op, gids, gids_size, - io_ept, buf, vec_grants, bytes) -endpoint_t driver; -cp_grant_id_t *gid; -int *op; -cp_grant_id_t *gids; -int gids_size; -endpoint_t *io_ept; -void **buf; -int *vec_grants; -vir_bytes bytes; -{ - int j; - iovec_t *v; - static iovec_t new_iovec[NR_IOREQS]; - - /* Number of grants allocated in vector I/O. */ - *vec_grants = 0; - - /* Driver can handle it - change request to a safe one. */ - - *gid = GRANT_INVALID; - - switch(*op) { - case MFS_DEV_READ: - case MFS_DEV_WRITE: - /* Change to safe op. */ - *op = *op == MFS_DEV_READ ? DEV_READ_S : DEV_WRITE_S; - - if((*gid=cpf_grant_direct(driver, (vir_bytes) *buf, - bytes, *op == DEV_READ_S ? CPF_WRITE : - CPF_READ)) < 0) { - panic("cpf_grant_magic of buffer failed"); - } - - break; - case MFS_DEV_GATHER: - case MFS_DEV_SCATTER: - /* Change to safe op. */ - *op = *op == MFS_DEV_GATHER ? - DEV_GATHER_S : DEV_SCATTER_S; - - /* Grant access to my new i/o vector. */ - if((*gid = cpf_grant_direct(driver, - (vir_bytes) new_iovec, bytes * sizeof(iovec_t), - CPF_READ | CPF_WRITE)) < 0) { - panic("cpf_grant_direct of vector failed"); - } - v = (iovec_t *) *buf; - /* Grant access to i/o buffers. */ - for(j = 0; j < bytes; j++) { - if(j >= NR_IOREQS) - panic("vec too big: %d", bytes); - new_iovec[j].iov_addr = gids[j] = - cpf_grant_direct(driver, (vir_bytes) - v[j].iov_addr, v[j].iov_size, - *op == DEV_GATHER_S ? CPF_WRITE : CPF_READ); - if(!GRANT_VALID(gids[j])) { - panic("mfs: grant to iovec buf failed"); - } - new_iovec[j].iov_size = v[j].iov_size; - (*vec_grants)++; - } - - /* Set user's vector to the new one. */ - *buf = new_iovec; - break; - } - - /* If we have converted to a safe operation, I/O - * endpoint becomes FS if it wasn't already. - */ - if(GRANT_VALID(*gid)) { - *io_ept = SELF_E; - return 1; - } - - /* Not converted to a safe operation (because there is no - * copying involved in this operation). - */ - return 0; -} - - -/*===========================================================================* - * safe_io_cleanup * - *===========================================================================*/ -PRIVATE void safe_io_cleanup(gid, gids, gids_size) -cp_grant_id_t gid; -cp_grant_id_t *gids; -int gids_size; -{ -/* Free resources (specifically, grants) allocated by safe_io_conversion(). */ - int j; - - cpf_revoke(gid); - - for(j = 0; j < gids_size; j++) - cpf_revoke(gids[j]); - - return; -} - - -/*===========================================================================* - * dev_open * - *===========================================================================*/ -PUBLIC int dev_open( - endpoint_t driver_e, - dev_t dev, /* device to open */ - int proc, /* process to open for */ - int flags /* mode bits and flags */ -) -{ - int major, r; - - /* Determine the major device number call the device class specific - * open/close routine. (This is the only routine that must check the - * device number for being in range. All others can trust this check.) - */ - major = (dev >> MAJOR) & BYTE; - if (major >= NR_DEVICES) major = 0; - r = gen_opcl(driver_e, DEV_OPEN, dev, proc, flags); - if (r == SUSPEND) panic("suspend on open from"); - return(r); -} - - -/*===========================================================================* - * block_dev_io * - *===========================================================================*/ -PUBLIC int block_dev_io( - int op, /* MFS_DEV_READ, MFS_DEV_WRITE, etc. */ - dev_t dev, /* major-minor device number */ - int proc_e, /* in whose address space is buf? */ - void *buf, /* virtual address of the buffer */ - u64_t pos, /* byte position */ - int bytes, /* how many bytes to transfer */ - int flags /* special flags, like O_NONBLOCK */ -) -{ -/* Read or write from a device. The parameter 'dev' tells which one. */ - int r, safe; - message m; - cp_grant_id_t gid = GRANT_INVALID; - int vec_grants; - int op_used; - void *buf_used; - static cp_grant_id_t gids[NR_IOREQS]; - endpoint_t driver_e; - - /* Determine driver endpoint for this device */ - driver_e = driver_endpoints[(dev >> MAJOR) & BYTE].driver_e; - - /* See if driver is roughly valid. */ - if (driver_e == NONE) return(EDEADEPT); - - /* The io vector copying relies on this I/O being for FS itself. */ - if(proc_e != SELF_E) { - printf("ISOFS(%d) doing block_dev_io for non-self %d\n", SELF_E, proc_e); - panic("doing block_dev_io for non-self: %d", proc_e); - } - - /* By default, these are right. */ - m.USER_ENDPT = proc_e; - m.ADDRESS = buf; - buf_used = buf; - - /* Convert parameters to 'safe mode'. */ - op_used = op; - safe = safe_io_conversion(driver_e, &gid, - &op_used, gids, NR_IOREQS, &m.USER_ENDPT, &buf_used, - &vec_grants, bytes); - - /* Set up rest of the message. */ - if (safe) m.IO_GRANT = (char *) gid; - - m.m_type = op_used; - m.DEVICE = (dev >> MINOR) & BYTE; - m.POSITION = ex64lo(pos); - m.COUNT = bytes; - m.HIGHPOS = ex64hi(pos); - - /* Call the task. */ - r = sendrec(driver_e, &m); - if(r == OK && m.REP_STATUS == ERESTART) r = EDEADEPT; - - /* As block I/O never SUSPENDs, safe cleanup must be done whether - * the I/O succeeded or not. */ - if (safe) safe_io_cleanup(gid, gids, vec_grants); - - /* RECOVERY: - * - send back dead driver number - * - VFS unmaps it, waits for new driver - * - VFS sends the new driver endp for the FS proc and the request again - */ - if (r != OK) { - if (r == EDEADSRCDST || r == EDEADEPT) { - printf("ISOFS(%d) dead driver %d\n", SELF_E, driver_e); - driver_endpoints[(dev >> MAJOR) & BYTE].driver_e = NONE; - return(r); - } - else if (r == ELOCKED) { - return(r); - } - else - panic("call_task: can't send/receive: %d", r); - } else { - /* Did the process we did the sendrec() for get a result? */ - if (m.REP_ENDPT != proc_e) { - printf("ISOFS (%d) strange device reply from %d, type = %d, proc = %d (not %d) (2) ignored\n", SELF_E, m.m_source, m.m_type, proc_e, m.REP_ENDPT); - r = EIO; - } - } - - /* Task has completed. See if call completed. */ - if (m.REP_STATUS == SUSPEND) { - panic("ISOFS block_dev_io: driver returned SUSPEND"); - } - - if(buf != buf_used && r == OK) { - memcpy(buf, buf_used, bytes * sizeof(iovec_t)); - } - - return(m.REP_STATUS); -} - - -/*===========================================================================* - * gen_opcl * - *===========================================================================*/ -PRIVATE int gen_opcl( - endpoint_t driver_e, - int op, /* operation, DEV_OPEN or DEV_CLOSE */ - dev_t dev, /* device to open or close */ - int proc_e, /* process to open/close for */ - int flags /* mode bits and flags */ -) -{ -/* Called from the dmap struct in table.c on opens & closes of special files.*/ - message dev_mess; - - dev_mess.m_type = op; - dev_mess.DEVICE = (dev >> MINOR) & BYTE; - dev_mess.USER_ENDPT = proc_e; - dev_mess.COUNT = flags; - - /* Call the task. */ - gen_io(driver_e, &dev_mess); - - return(dev_mess.REP_STATUS); -} - - -/*===========================================================================* - * gen_io * - *===========================================================================*/ -PRIVATE int gen_io(task_nr, mess_ptr) -endpoint_t task_nr; /* which task to call */ -message *mess_ptr; /* pointer to message for task */ -{ -/* All file system I/O ultimately comes down to I/O on major/minor device - * pairs. These lead to calls on the following routines via the dmap table. - */ - - int r, proc_e; - - proc_e = mess_ptr->USER_ENDPT; - - r = sendrec(task_nr, mess_ptr); - if(r == OK && mess_ptr->REP_STATUS == ERESTART) r = EDEADEPT; - if (r != OK) { - if (r == EDEADSRCDST || r == EDEADEPT) { - printf("fs: dead driver %d\n", task_nr); - panic("should handle crashed drivers"); - /* dmap_unmap_by_endpt(task_nr); */ - return r; - } - if (r == ELOCKED) { - printf("fs: ELOCKED talking to %d\n", task_nr); - return r; - } - panic("call_task: can't send/receive: %d", r); - } - - /* Did the process we did the sendrec() for get a result? */ - if (mess_ptr->REP_ENDPT != proc_e) { - printf( - "fs: strange device reply from %d, type = %d, proc = %d (not %d) (2) ignored\n", - mess_ptr->m_source, - mess_ptr->m_type, - proc_e, - mess_ptr->REP_ENDPT); - return(EIO); - } - - return(OK); -} - - -/*===========================================================================* - * dev_close * - *===========================================================================*/ -PUBLIC void dev_close(endpoint_t driver_e, dev_t dev) -{ - (void) gen_opcl(driver_e, DEV_CLOSE, dev, 0, 0); -} - diff --git a/servers/iso9660fs/drivers.h b/servers/iso9660fs/drivers.h deleted file mode 100644 index 2878aca2c..000000000 --- a/servers/iso9660fs/drivers.h +++ /dev/null @@ -1,9 +0,0 @@ -#include - -/* Driver endpoints for major devices. Only the block devices - * are mapped here, it's a subset of the mapping in the VFS */ - -EXTERN struct driver_endpoints { - endpoint_t driver_e; -} driver_endpoints[NR_DEVICES]; - diff --git a/servers/iso9660fs/inc.h b/servers/iso9660fs/inc.h index 1072bf2e0..d7559d5f2 100644 --- a/servers/iso9660fs/inc.h +++ b/servers/iso9660fs/inc.h @@ -31,4 +31,3 @@ #include "proto.h" #include "super.h" #include "glo.h" -#include "drivers.h" diff --git a/servers/iso9660fs/main.c b/servers/iso9660fs/main.c index 5ff8efe3c..cbb4df49d 100644 --- a/servers/iso9660fs/main.c +++ b/servers/iso9660fs/main.c @@ -1,5 +1,3 @@ - - /* This file contains the main directory for the server. It waits for a * request and then send a response. */ @@ -101,11 +99,7 @@ PRIVATE void sef_local_startup() PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) { /* Initialize the iso9660fs server. */ - int i; - /* Init driver mapping */ - for (i = 0; i < NR_DEVICES; ++i) - driver_endpoints[i].driver_e = NONE; /* SELF_E will contain the id of this process */ SELF_E = getprocnr(); /* hash_init(); */ /* Init the table with the ids */ diff --git a/servers/iso9660fs/misc.c b/servers/iso9660fs/misc.c index f25dba4a4..bce2b1617 100644 --- a/servers/iso9660fs/misc.c +++ b/servers/iso9660fs/misc.c @@ -1,6 +1,7 @@ #include "inc.h" #include #include +#include /*===========================================================================* @@ -12,3 +13,20 @@ PUBLIC int fs_sync() return(OK); /* sync() can't fail */ } + +/*===========================================================================* + * fs_new_driver * + *===========================================================================*/ +PUBLIC int fs_new_driver() +{ +/* Set a new driver endpoint for this device. */ + dev_t dev; + endpoint_t endpt; + + dev = (dev_t) fs_m_in.REQ_DEV; + endpt = (endpoint_t) fs_m_in.REQ_DRIVER_E; + + bdev_driver(dev, endpt); + + return(OK); +} diff --git a/servers/iso9660fs/mount.c b/servers/iso9660fs/mount.c index 4ec990c3a..95467b8e4 100644 --- a/servers/iso9660fs/mount.c +++ b/servers/iso9660fs/mount.c @@ -1,6 +1,7 @@ #include "inc.h" #include #include +#include #include "const.h" #include "glo.h" @@ -39,18 +40,19 @@ PUBLIC int fs_readsuper() { } /* Map the driver endpoint for this major */ - driver_endpoints[(fs_dev >> MAJOR) & BYTE].driver_e = driver_e; + bdev_driver(fs_dev, driver_e); /* Open the device the file system lives on */ - if (dev_open(driver_e, fs_dev, driver_e, - readonly ? R_BIT : (R_BIT|W_BIT)) != OK) { + if (bdev_open(fs_dev, readonly ? R_BIT : (R_BIT|W_BIT)) != OK) { return(EINVAL); } /* Read the superblock */ r = read_vds(&v_pri, fs_dev); - if (r != OK) + if (r != OK) { + bdev_close(fs_dev); return(r); + } /* Return some root inode properties */ fs_m_out.RES_INODE_NR = ID_DIR_RECORD(v_pri.dir_rec_root); @@ -102,7 +104,7 @@ PUBLIC int fs_mountpoint() *===========================================================================*/ PUBLIC int fs_unmount(void) { release_v_pri(&v_pri); /* Release the super block */ - dev_close(driver_endpoints[(fs_dev >> MAJOR) & BYTE].driver_e, fs_dev); + bdev_close(fs_dev); unmountdone = TRUE; return(OK); } diff --git a/servers/iso9660fs/proto.h b/servers/iso9660fs/proto.h index dcf37f240..98966f07c 100644 --- a/servers/iso9660fs/proto.h +++ b/servers/iso9660fs/proto.h @@ -13,14 +13,6 @@ _PROTOTYPE( void reply, (int who, message *m_out) ); _PROTOTYPE(struct buf *get_block,(block_t block)); _PROTOTYPE(void put_block,(struct buf *bp)); -/* device.c */ -_PROTOTYPE( int block_dev_io, (int op, dev_t dev, int proc, void *buf, - u64_t pos, int bytes, int flags) ); -_PROTOTYPE( int dev_open, (endpoint_t driver_e, dev_t dev, int proc, - int flags) ); -_PROTOTYPE( void dev_close, (endpoint_t driver_e, dev_t dev) ); -_PROTOTYPE( int fs_new_driver, (void) ); - /* inode.c */ _PROTOTYPE( int create_dir_record,(struct dir_record *dir, char *buffer, u32_t address) ); @@ -35,6 +27,7 @@ _PROTOTYPE( int release_dir_record, (struct dir_record *dir) ); /* misc.c */ _PROTOTYPE( int fs_sync, (void) ); +_PROTOTYPE( int fs_new_driver, (void) ); /* mount.c */ _PROTOTYPE( int fs_readsuper, (void) ); diff --git a/servers/iso9660fs/super.c b/servers/iso9660fs/super.c index d90b61de1..5522cea32 100644 --- a/servers/iso9660fs/super.c +++ b/servers/iso9660fs/super.c @@ -5,6 +5,7 @@ #include #include #include +#include /* This function is called when the filesystem is umounted. It releases the * super block. */ @@ -94,7 +95,7 @@ PUBLIC int read_vds( while (!vol_ok && i++ +#include #include #include #include @@ -326,7 +327,7 @@ int rw_flag; /* READING or WRITING */ * is not reported to the caller. If the error occurred while purging a block * from the cache, it is not clear what the caller could do about it anyway. */ - int r, op, op_failed; + int r, op_failed; u64_t pos; dev_t dev; @@ -334,8 +335,12 @@ int rw_flag; /* READING or WRITING */ if ( (dev = bp->b_dev) != NO_DEV) { pos = mul64u(bp->b_blocknr, fs_block_size); - op = (rw_flag == READING ? MFS_DEV_READ : MFS_DEV_WRITE); - r = block_dev_io(op, dev, SELF_E, bp->b_data, pos, fs_block_size); + if (rw_flag == READING) + r = bdev_read(dev, pos, bp->b_data, fs_block_size, + BDEV_NOFLAGS); + else + r = bdev_write(dev, pos, bp->b_data, fs_block_size, + BDEV_NOFLAGS); if (r < 0) { printf("MFS(%d) I/O error on device %d/%d, block %u\n", SELF_E, major(dev), minor(dev), bp->b_blocknr); @@ -420,6 +425,8 @@ PUBLIC void rw_scattered( register int i; register iovec_t *iop; static iovec_t *iovec = NULL; + vir_bytes size; + u64_t pos; int j, r; STATICINIT(iovec, NR_IOREQS); @@ -442,9 +449,9 @@ PUBLIC void rw_scattered( } } - /* Set up I/O vector and do I/O. The result of dev_io is OK if everything + /* Set up I/O vector and do I/O. The result of bdev I/O is OK if everything * went fine, otherwise the error code for the first failed transfer. - */ + */ while (bufqsize > 0) { for (j = 0, iop = iovec; j < NR_IOREQS && j < bufqsize; j++, iop++) { bp = bufq[j]; @@ -452,16 +459,18 @@ PUBLIC void rw_scattered( iop->iov_addr = (vir_bytes) bp->b_data; iop->iov_size = (vir_bytes) fs_block_size; } - r = block_dev_io(rw_flag == WRITING ? MFS_DEV_SCATTER : MFS_DEV_GATHER, - dev, SELF_E, iovec, - mul64u(bufq[0]->b_blocknr, fs_block_size), j); + pos = mul64u(bufq[0]->b_blocknr, fs_block_size); + if (rw_flag == READING) + r = bdev_gather(dev, pos, iovec, j, BDEV_NOFLAGS, &size); + else + r = bdev_scatter(dev, pos, iovec, j, BDEV_NOFLAGS, &size); - /* Harvest the results. Dev_io reports the first error it may have + /* Harvest the results. libbdev reports the first error it may have * encountered, but we only care if it's the first block that failed. */ for (i = 0, iop = iovec; i < j; i++, iop++) { bp = bufq[i]; - if (iop->iov_size != 0) { + if (size < iop->iov_size) { /* Transfer failed. An error? Do we care? */ if (r != OK && i == 0) { printf( @@ -478,6 +487,7 @@ PUBLIC void rw_scattered( } else { bp->b_dirt = CLEAN; } + size -= iop->iov_size; } bufq += i; bufqsize -= i; diff --git a/servers/mfs/const.h b/servers/mfs/const.h index e85d6d650..5e9bb65b4 100644 --- a/servers/mfs/const.h +++ b/servers/mfs/const.h @@ -98,11 +98,5 @@ #define NUL(str,l,m) mfs_nul_f(__FILE__,__LINE__,(str), (l), (m)) -/* Args to dev_bio/dev_io */ -#define MFS_DEV_READ 10001 -#define MFS_DEV_WRITE 10002 -#define MFS_DEV_SCATTER 10003 -#define MFS_DEV_GATHER 10004 - #endif diff --git a/servers/mfs/device.c b/servers/mfs/device.c deleted file mode 100644 index cf56c10b0..000000000 --- a/servers/mfs/device.c +++ /dev/null @@ -1,360 +0,0 @@ -#include "fs.h" -#include -#include -#include -#include -#include -#include "inode.h" -#include "super.h" -#include "const.h" -#include "drivers.h" - -#include - -FORWARD _PROTOTYPE( int safe_io_conversion, (endpoint_t driver, - cp_grant_id_t *gid, int *op, cp_grant_id_t *gids, endpoint_t *io_ept, - void **buffer, int *vec_grants, size_t bytes)); -FORWARD _PROTOTYPE( void safe_io_cleanup, (cp_grant_id_t, cp_grant_id_t *, - int)); -FORWARD _PROTOTYPE( int gen_opcl, (endpoint_t driver_e, int op, - dev_t dev, endpoint_t proc_e, int flags) ); -FORWARD _PROTOTYPE( int gen_io, (endpoint_t task_nr, message *mess_ptr) ); - - -/*===========================================================================* - * fs_new_driver * - *===========================================================================*/ -PUBLIC int fs_new_driver(void) -{ - /* New driver endpoint for this device */ - dev_t dev; - dev = (dev_t) fs_m_in.REQ_DEV; - driver_endpoints[major(dev)].driver_e = (endpoint_t) fs_m_in.REQ_DRIVER_E; - return(OK); -} - - -/*===========================================================================* - * safe_io_conversion * - *===========================================================================*/ -PRIVATE int safe_io_conversion(driver, gid, op, gids, io_ept, buffer, - vec_grants, bytes) -endpoint_t driver; -cp_grant_id_t *gid; -int *op; -cp_grant_id_t *gids; -endpoint_t *io_ept; -void **buffer; -int *vec_grants; -size_t bytes; -{ - unsigned int j; - int access; - iovec_t *v; - static iovec_t *new_iovec; - - STATICINIT(new_iovec, NR_IOREQS); - - /* Number of grants allocated in vector I/O. */ - *vec_grants = 0; - - /* Driver can handle it - change request to a safe one. */ - - *gid = GRANT_INVALID; - - switch(*op) { - case MFS_DEV_READ: - case MFS_DEV_WRITE: - /* Change to safe op. */ - *op = *op == MFS_DEV_READ ? DEV_READ_S : DEV_WRITE_S; - *gid = cpf_grant_direct(driver, (vir_bytes) *buffer, bytes, - *op == DEV_READ_S ? CPF_WRITE : CPF_READ); - if(*gid == GRANT_INVALID) { - panic("cpf_grant_magic of buffer failed"); - } - - break; - case MFS_DEV_GATHER: - case MFS_DEV_SCATTER: - /* Change to safe op. */ - *op = *op == MFS_DEV_GATHER ? DEV_GATHER_S : DEV_SCATTER_S; - - /* Grant access to my new i/o vector. */ - *gid = cpf_grant_direct(driver, (vir_bytes) new_iovec, - bytes * sizeof(iovec_t), CPF_READ|CPF_WRITE); - if(*gid == GRANT_INVALID) { - panic("cpf_grant_direct of vector failed"); - } - - v = (iovec_t *) *buffer; - - /* Grant access to i/o buffers. */ - for(j = 0; j < bytes; j++) { - if(j >= NR_IOREQS) - panic("vec too big: %u", bytes); - access = (*op == DEV_GATHER_S) ? CPF_WRITE : CPF_READ; - new_iovec[j].iov_addr = gids[j] = - cpf_grant_direct(driver, (vir_bytes) v[j].iov_addr, - (size_t) v[j].iov_size, access); - - if(!GRANT_VALID(gids[j])) { - panic("mfs: grant to iovec buf failed"); - } - new_iovec[j].iov_size = v[j].iov_size; - (*vec_grants)++; - } - - /* Set user's vector to the new one. */ - *buffer = new_iovec; - break; - default: - panic("Illegal operation %d\n", *op); - break; - } - - /* If we have converted to a safe operation, I/O - * endpoint becomes FS if it wasn't already. - */ - if(GRANT_VALID(*gid)) { - *io_ept = SELF_E; - return 1; - } - - /* Not converted to a safe operation (because there is no - * copying involved in this operation). - */ - return 0; -} - -/*===========================================================================* - * safe_io_cleanup * - *===========================================================================*/ -PRIVATE void safe_io_cleanup(gid, gids, gids_size) -cp_grant_id_t gid; -cp_grant_id_t *gids; -int gids_size; -{ -/* Free resources (specifically, grants) allocated by safe_io_conversion(). */ - int j; - - (void) cpf_revoke(gid); - - for(j = 0; j < gids_size; j++) - (void) cpf_revoke(gids[j]); - - return; -} - -/*===========================================================================* - * block_dev_io * - *===========================================================================*/ -PUBLIC int block_dev_io( - int op, /* MFS_DEV_READ, MFS_DEV_WRITE, etc. */ - dev_t dev, /* major-minor device number */ - endpoint_t proc_e, /* in whose address space is buf? */ - void *buffer, /* virtual address of the buffer */ - u64_t pos, /* byte position */ - size_t bytes /* how many bytes to transfer */ -) -{ -/* Read or write from a device. The parameter 'dev' tells which one. */ - int r, safe; - message m; - cp_grant_id_t gid = GRANT_INVALID; - int vec_grants; - int op_used; - void *buf_used; - static cp_grant_id_t *gids; - endpoint_t driver_e; - - STATICINIT(gids, NR_IOREQS); - - /* Determine driver endpoint for this device */ - driver_e = driver_endpoints[major(dev)].driver_e; - - /* See if driver is roughly valid. */ - if (driver_e == NONE) { - printf("MFS(%d) block_dev_io: no driver for dev %x\n", SELF_E, dev); - return(EDEADEPT); - } - - /* The io vector copying relies on this I/O being for FS itself. */ - if(proc_e != SELF_E) { - printf("MFS(%d) doing block_dev_io for non-self %d\n", SELF_E, proc_e); - panic("doing block_dev_io for non-self: %d", proc_e); - } - - /* By default, these are right. */ - m.USER_ENDPT = proc_e; - m.ADDRESS = buffer; - buf_used = buffer; - - /* Convert parameters to 'safe mode'. */ - op_used = op; - safe = safe_io_conversion(driver_e, &gid, &op_used, gids, &m.USER_ENDPT, - &buf_used, &vec_grants, bytes); - - /* Set up rest of the message. */ - if (safe) m.IO_GRANT = (char *) gid; - - m.m_type = op_used; - m.DEVICE = minor(dev); - m.POSITION = ex64lo(pos); - m.COUNT = bytes; - m.HIGHPOS = ex64hi(pos); - - /* Call the task. */ - r = sendrec(driver_e, &m); - if(r == OK && m.REP_STATUS == ERESTART) r = EDEADEPT; - - /* As block I/O never SUSPENDs, safe cleanup must be done whether - * the I/O succeeded or not. */ - if (safe) safe_io_cleanup(gid, gids, vec_grants); - - /* RECOVERY: - * - send back dead driver number - * - VFS unmaps it, waits for new driver - * - VFS sends the new driver endp for the FS proc and the request again - */ - if (r != OK) { - if (r == EDEADSRCDST || r == EDEADEPT) { - printf("MFS(%d) dead driver %d\n", SELF_E, driver_e); - driver_endpoints[major(dev)].driver_e = NONE; - return(r); - } else if (r == ELOCKED) { - printf("MFS(%d) ELOCKED talking to %d\n", SELF_E, driver_e); - return(r); - } else - panic("call_task: can't send/receive: %d", r); - } else { - /* Did the process we did the sendrec() for get a result? */ - if (m.REP_ENDPT != proc_e) { - printf("MFS(%d) strange device reply from %d, type = %d, proc " - "= %d (not %d) (2) ignored\n", SELF_E, m.m_source, - m.m_type, proc_e, m.REP_ENDPT); - r = EIO; - } - } - - /* Task has completed. See if call completed. */ - if (m.REP_STATUS == SUSPEND) { - panic("MFS block_dev_io: driver returned SUSPEND"); - } - - if(buffer != buf_used && r == OK) { - memcpy(buffer, buf_used, bytes * sizeof(iovec_t)); - } - - return(m.REP_STATUS); -} - -/*===========================================================================* - * dev_open * - *===========================================================================*/ -PUBLIC int dev_open( - endpoint_t driver_e, - dev_t dev, /* device to open */ - endpoint_t proc_e, /* process to open for */ - int flags /* mode bits and flags */ -) -{ - int major, r; - - /* Determine the major device number call the device class specific - * open/close routine. (This is the only routine that must check the - * device number for being in range. All others can trust this check.) - */ - major = major(dev); - if (major >= NR_DEVICES) { - printf("Major device number %d not in range\n", major(dev)); - return(EIO); - } - r = gen_opcl(driver_e, DEV_OPEN, dev, proc_e, flags); - if (r == SUSPEND) panic("suspend on open from"); - return(r); -} - - -/*===========================================================================* - * dev_close * - *===========================================================================*/ -PUBLIC void dev_close( - endpoint_t driver_e, - dev_t dev /* device to close */ -) -{ - (void) gen_opcl(driver_e, DEV_CLOSE, dev, 0, 0); -} - - -/*===========================================================================* - * gen_opcl * - *===========================================================================*/ -PRIVATE int gen_opcl( - endpoint_t driver_e, - int op, /* operation, DEV_OPEN or DEV_CLOSE */ - dev_t dev, /* device to open or close */ - endpoint_t proc_e, /* process to open/close for */ - int flags /* mode bits and flags */ -) -{ -/* Called from the dmap struct in table.c on opens & closes of special files.*/ - message dev_mess; - - dev_mess.m_type = op; - dev_mess.DEVICE = minor(dev); - dev_mess.USER_ENDPT = proc_e; - dev_mess.COUNT = flags; - - /* Call the task. */ - (void) gen_io(driver_e, &dev_mess); - - return(dev_mess.REP_STATUS); -} - - -/*===========================================================================* - * gen_io * - *===========================================================================*/ -PRIVATE int gen_io( - endpoint_t task_nr, /* which task to call */ - message *mess_ptr /* pointer to message for task */ -) -{ -/* All file system I/O ultimately comes down to I/O on major/minor device - * pairs. These lead to calls on the following routines via the dmap table. - */ - - int r, proc_e; - - proc_e = mess_ptr->USER_ENDPT; - - r = sendrec(task_nr, mess_ptr); - if(r == OK && mess_ptr->REP_STATUS == ERESTART) - r = EDEADEPT; - - if (r != OK) { - if (r == EDEADSRCDST || r == EDEADEPT) { - printf("fs: dead driver %d\n", task_nr); - panic("should handle crashed drivers"); - return(r); - } - if (r == ELOCKED) { - printf("fs: ELOCKED talking to %d\n", task_nr); - return(r); - } - panic("call_task: can't send/receive: %d", r); - } - - /* Did the process we did the sendrec() for get a result? */ - if (mess_ptr->REP_ENDPT != proc_e) { - printf("fs: strange device reply from %d, type = %d, proc = %d (not " - "%d) (2) ignored\n", mess_ptr->m_source, mess_ptr->m_type, - proc_e, - mess_ptr->REP_ENDPT); - return(EIO); - } - - return(OK); -} - diff --git a/servers/mfs/drivers.h b/servers/mfs/drivers.h deleted file mode 100644 index c83c90606..000000000 --- a/servers/mfs/drivers.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __MFS_DRIVERS_H__ -#define __MFS_DRIVERS_H__ - -/* Driver endpoints for major devices. Only the block devices - * are mapped here, it's a subset of the mapping in the VFS */ - -EXTERN struct driver_endpoints { - endpoint_t driver_e; -} driver_endpoints[NR_DEVICES]; - -#endif diff --git a/servers/mfs/main.c b/servers/mfs/main.c index 96b9c5afe..2d7d244d7 100644 --- a/servers/mfs/main.c +++ b/servers/mfs/main.c @@ -9,7 +9,6 @@ #include #include "buf.h" #include "inode.h" -#include "drivers.h" /* Declare some local functions. */ @@ -118,10 +117,6 @@ PRIVATE int sef_cb_init_fresh(int type, sef_init_info_t *info) init_inode_cache(); - /* Init driver mapping */ - for (i = 0; i < NR_DEVICES; ++i) - driver_endpoints[i].driver_e = NONE; - SELF_E = getprocnr(); buf_pool(DEFAULT_NR_BUFS); fs_block_size = _MIN_BLOCK_SIZE; diff --git a/servers/mfs/misc.c b/servers/mfs/misc.c index 2a8fabf9c..064e9138d 100644 --- a/servers/mfs/misc.c +++ b/servers/mfs/misc.c @@ -1,6 +1,7 @@ #include "fs.h" #include #include +#include #include "inode.h" @@ -46,7 +47,24 @@ PUBLIC int fs_flush() flushall(dev); invalidate(dev); - + return(OK); } + +/*===========================================================================* + * fs_new_driver * + *===========================================================================*/ +PUBLIC int fs_new_driver(void) +{ +/* Set a new driver endpoint for this device. */ + dev_t dev; + endpoint_t endpt; + + dev = (dev_t) fs_m_in.REQ_DEV; + endpt = (endpoint_t) fs_m_in.REQ_DRIVER_E; + + bdev_driver(dev, endpt); + + return(OK); +} diff --git a/servers/mfs/mount.c b/servers/mfs/mount.c index 614f9777a..a64054f86 100644 --- a/servers/mfs/mount.c +++ b/servers/mfs/mount.c @@ -1,9 +1,9 @@ #include "fs.h" #include "inode.h" #include "super.h" -#include "drivers.h" #include #include +#include /*===========================================================================* @@ -49,11 +49,10 @@ PUBLIC int fs_readsuper() } /* Map the driver endpoint for this major */ - driver_endpoints[major(fs_dev)].driver_e = driver_e; + bdev_driver(fs_dev, driver_e); /* Open the device the file system lives on. */ - if (dev_open(driver_e, fs_dev, driver_e, - readonly ? R_BIT : (R_BIT|W_BIT) ) != OK) { + if (bdev_open(fs_dev, readonly ? R_BIT : (R_BIT|W_BIT) ) != OK) { return(EINVAL); } @@ -64,7 +63,7 @@ PUBLIC int fs_readsuper() /* Is it recognized as a Minix filesystem? */ if (r != OK) { superblock.s_dev = NO_DEV; - dev_close(driver_e, fs_dev); + bdev_close(fs_dev); return(r); } @@ -72,18 +71,18 @@ PUBLIC int fs_readsuper() /* Get the root inode of the mounted file system. */ if( (root_ip = get_inode(fs_dev, ROOT_INODE)) == NULL) { - printf("MFS: couldn't get root inode\n"); - superblock.s_dev = NO_DEV; - dev_close(driver_e, fs_dev); - return(EINVAL); + printf("MFS: couldn't get root inode\n"); + superblock.s_dev = NO_DEV; + bdev_close(fs_dev); + return(EINVAL); } if(root_ip->i_mode == 0) { - printf("%s:%d zero mode for root inode?\n", __FILE__, __LINE__); - put_inode(root_ip); - superblock.s_dev = NO_DEV; - dev_close(driver_e, fs_dev); - return(EINVAL); + printf("%s:%d zero mode for root inode?\n", __FILE__, __LINE__); + put_inode(root_ip); + superblock.s_dev = NO_DEV; + bdev_close(fs_dev); + return(EINVAL); } superblock.s_rd_only = readonly; @@ -162,7 +161,7 @@ PUBLIC int fs_unmount() (void) fs_sync(); /* Close the device the file system lives on. */ - dev_close(driver_endpoints[major(fs_dev)].driver_e, fs_dev); + bdev_close(fs_dev); /* Finish off the unmount. */ superblock.s_dev = NO_DEV; diff --git a/servers/mfs/path.c b/servers/mfs/path.c index 4efffcad7..34faed7d9 100644 --- a/servers/mfs/path.c +++ b/servers/mfs/path.c @@ -19,6 +19,7 @@ #include "inode.h" #include "super.h" #include +#include PUBLIC char dot1[2] = "."; /* used for search_dir to bypass the access */ diff --git a/servers/mfs/proto.h b/servers/mfs/proto.h index b849eb5e7..a2b754a67 100644 --- a/servers/mfs/proto.h +++ b/servers/mfs/proto.h @@ -22,14 +22,6 @@ _PROTOTYPE( void set_blocksize, (struct super_block *) ); _PROTOTYPE( void rw_scattered, (dev_t dev, struct buf **bufq, int bufqsize, int rw_flag) ); -/* device.c */ -_PROTOTYPE( int block_dev_io, (int op, dev_t dev, endpoint_t proc_e, - void *buf, u64_t pos, size_t bytes) ); -_PROTOTYPE( int dev_open, (endpoint_t driver_e, dev_t dev, endpoint_t proc_e, - int flags) ); -_PROTOTYPE( void dev_close, (endpoint_t driver_e, dev_t dev) ); -_PROTOTYPE( int fs_new_driver, (void) ); - /* inode.c */ _PROTOTYPE( struct inode *alloc_inode, (dev_t dev, mode_t bits) ); _PROTOTYPE( void dup_inode, (struct inode *ip) ); @@ -52,6 +44,7 @@ _PROTOTYPE( int truncate_inode, (struct inode *rip, off_t len) ); /* misc.c */ _PROTOTYPE( int fs_flush, (void) ); _PROTOTYPE( int fs_sync, (void) ); +_PROTOTYPE( int fs_new_driver, (void) ); /* mount.c */ _PROTOTYPE( int fs_mountpoint, (void) ); diff --git a/servers/mfs/super.c b/servers/mfs/super.c index d0e6d05dc..0c97d0413 100644 --- a/servers/mfs/super.c +++ b/servers/mfs/super.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "buf.h" #include "inode.h" #include "super.h" @@ -194,8 +195,8 @@ register struct super_block *sp; /* pointer to a superblock */ if (dev == NO_DEV) panic("request for super_block of NO_DEV"); - r = block_dev_io(MFS_DEV_READ, dev, SELF_E, sbbuf, cvu64(SUPER_BLOCK_BYTES), - _MIN_BLOCK_SIZE); + r = bdev_read(dev, cvu64(SUPER_BLOCK_BYTES), sbbuf, _MIN_BLOCK_SIZE, + BDEV_NOFLAGS); if (r != _MIN_BLOCK_SIZE) return(EINVAL); diff --git a/servers/mfs/table.c b/servers/mfs/table.c index d50005f20..e8aaa4895 100644 --- a/servers/mfs/table.c +++ b/servers/mfs/table.c @@ -9,7 +9,6 @@ #include "inode.h" #include "buf.h" #include "super.h" -#include "drivers.h" PUBLIC _PROTOTYPE (int (*fs_call_vec[]), (void) ) = { no_sys, /* 0 not used */ @@ -44,6 +43,6 @@ PUBLIC _PROTOTYPE (int (*fs_call_vec[]), (void) ) = { no_sys, /* 29 */ /* Was: fs_newnode */ fs_rdlink, /* 30 */ fs_getdents, /* 31 */ - fs_statvfs, /* 32 */ + fs_statvfs, /* 32 */ };