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 \
--- /dev/null
+#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 */
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
--- /dev/null
+# Makefile for libbdev
+.include <bsd.own.mk>
+
+LIB= bdev
+
+SRCS= bdev.c ipc.c driver.c
+
+.include <bsd.lib.mk>
--- /dev/null
+/* libbdev - block device interfacing library, by D.C. van Moolenbroek */
+
+/* This is a preliminary, bare-essentials-only version of this library. */
+
+#include <minix/drivers.h>
+#include <minix/bdev.h>
+#include <minix/ioctl.h>
+#include <assert.h>
+
+#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;
+}
--- /dev/null
+/* libbdev - driver endpoint management */
+
+#include <minix/drivers.h>
+#include <minix/bdev.h>
+#include <assert.h>
+
+#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];
+}
--- /dev/null
+/* libbdev - IPC and recovery functions */
+
+#include <minix/drivers.h>
+#include <minix/bdev.h>
+#include <assert.h>
+
+#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;
+}
--- /dev/null
+#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 */
# 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=
#include "fs.h"
#include <minix/u64.h>
+#include <minix/bdev.h>
#include <minix/libminixfs.h>
#include <stdlib.h>
#include <assert.h>
* 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);
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);
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(
} else {
bp->b_dirt = CLEAN;
}
+ size -= iop->iov_size;
}
bufq += i;
bufqsize -= i;
#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 */
+++ /dev/null
-#include "fs.h"
-#include <minix/com.h>
-#include <minix/endpoint.h>
-#include <minix/safecopies.h>
-#include <minix/u64.h>
-#include <string.h>
-#include "inode.h"
-#include "super.h"
-#include "const.h"
-#include "drivers.h"
-
-#include <minix/vfsif.h>
-
-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);
-}
+++ /dev/null
-#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 */
#include <minix/optset.h>
#include "buf.h"
#include "inode.h"
-#include "drivers.h"
/* Declare some local functions. */
FORWARD _PROTOTYPE(void get_work, (message *m_in) );
if (error == OK)
read_ahead(); /* do block read ahead */
}
+
+ return 0;
}
/*===========================================================================*
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 */
#include "fs.h"
#include <assert.h>
#include <minix/vfsif.h>
+#include <minix/bdev.h>
#include "inode.h"
#include "super.h"
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);
+}
#include "buf.h"
#include "inode.h"
#include "super.h"
-#include "drivers.h"
#include <minix/ds.h>
#include <minix/vfsif.h>
+#include <minix/bdev.h>
/*===========================================================================*
}
/* 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);
}
/* 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);
}
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);
}
/* 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) {
__FILE__, __LINE__);
put_inode(root_ip);
superblock->s_dev = NO_DEV;
- dev_close(driver_e, fs_dev);
+ bdev_close(fs_dev);
return(EINVAL);
}
}
/* 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;
#include "inode.h"
#include "super.h"
#include <minix/vfsif.h>
+#include <minix/libminixfs.h>
PUBLIC char dot1[2] = "."; /* used for search_dir to bypass the access */
PUBLIC char dot2[3] = ".."; /* permissions for . and .. */
_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) );
/* 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) );
#include <assert.h>
#include <minix/com.h>
#include <minix/u64.h>
+#include <minix/bdev.h>
#include "buf.h"
#include "inode.h"
#include "super.h"
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);
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);
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");
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");
}
#include "inode.h"
#include "buf.h"
#include "super.h"
-#include "drivers.h"
PUBLIC _PROTOTYPE (int (*fs_call_vec[]), (void) ) = {
no_sys, /* 0 not used */
# 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=
#include "inc.h"
#include <minix/com.h>
#include <minix/u64.h>
+#include <minix/bdev.h>
#include "buf.h"
FORWARD _PROTOTYPE(int read_block, (struct buf *));
PRIVATE int read_block(bp)
register struct buf *bp; /* buffer pointer */
{
- int r, op;
+ int r;
u64_t pos;
int block_size;
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)
/* 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 */
+++ /dev/null
-#include "inc.h"
-#include <minix/vfsif.h>
-
-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);
-}
-
+++ /dev/null
-#include <minix/dmap.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];
-
#include "proto.h"
#include "super.h"
#include "glo.h"
-#include "drivers.h"
-
-
/* This file contains the main directory for the server. It waits for a
* request and then send a response. */
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 */
#include "inc.h"
#include <fcntl.h>
#include <minix/vfsif.h>
+#include <minix/bdev.h>
/*===========================================================================*
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);
+}
#include "inc.h"
#include <minix/vfsif.h>
#include <minix/ds.h>
+#include <minix/bdev.h>
#include "const.h"
#include "glo.h"
}
/* 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);
*===========================================================================*/
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);
}
_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) );
/* misc.c */
_PROTOTYPE( int fs_sync, (void) );
+_PROTOTYPE( int fs_new_driver, (void) );
/* mount.c */
_PROTOTYPE( int fs_readsuper, (void) );
#include <string.h>
#include <minix/com.h>
#include <minix/u64.h>
+#include <minix/bdev.h>
/* This function is called when the filesystem is umounted. It releases the
* super block. */
while (!vol_ok && i++<MAX_ATTEMPTS) {
/* Read the sector of the super block. */
- r = block_dev_io(MFS_DEV_READ, dev, SELF_E, sbbuf, offset, ISO9660_MIN_BLOCK_SIZE, 0);
+ r = bdev_read(dev, offset, sbbuf, ISO9660_MIN_BLOCK_SIZE, BDEV_NOFLAGS);
if (r != ISO9660_MIN_BLOCK_SIZE) /* Damaged sector or what? */
continue;
# Makefile for Minix File System (MFS)
PROG= mfs
-SRCS= cache.c device.c link.c \
+SRCS= cache.c link.c \
mount.c misc.c open.c protect.c read.c \
stadir.c stats.c table.c time.c utility.c \
write.c inode.c main.c path.c super.c
DPADD+= ${LIBM} ${LIBSYS}
-LDADD+= -lminixfs -lsys
+LDADD+= -lminixfs -lbdev -lsys
MAN=
#include "fs.h"
#include <minix/u64.h>
+#include <minix/bdev.h>
#include <sys/param.h>
#include <stdlib.h>
#include <assert.h>
* 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;
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);
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);
}
}
- /* 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];
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(
} else {
bp->b_dirt = CLEAN;
}
+ size -= iop->iov_size;
}
bufq += i;
bufqsize -= i;
#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
+++ /dev/null
-#include "fs.h"
-#include <minix/com.h>
-#include <minix/endpoint.h>
-#include <minix/safecopies.h>
-#include <minix/u64.h>
-#include <string.h>
-#include "inode.h"
-#include "super.h"
-#include "const.h"
-#include "drivers.h"
-
-#include <minix/vfsif.h>
-
-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);
-}
-
+++ /dev/null
-#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
#include <minix/vfsif.h>
#include "buf.h"
#include "inode.h"
-#include "drivers.h"
/* Declare some local functions. */
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;
#include "fs.h"
#include <assert.h>
#include <minix/vfsif.h>
+#include <minix/bdev.h>
#include "inode.h"
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);
+}
#include "fs.h"
#include "inode.h"
#include "super.h"
-#include "drivers.h"
#include <minix/ds.h>
#include <minix/vfsif.h>
+#include <minix/bdev.h>
/*===========================================================================*
}
/* 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);
}
/* 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);
}
/* 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;
(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;
#include "inode.h"
#include "super.h"
#include <minix/vfsif.h>
+#include <minix/libminixfs.h>
PUBLIC char dot1[2] = "."; /* used for search_dir to bypass the access */
_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) );
/* 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) );
#include <string.h>
#include <minix/com.h>
#include <minix/u64.h>
+#include <minix/bdev.h>
#include "buf.h"
#include "inode.h"
#include "super.h"
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);
#include "inode.h"
#include "buf.h"
#include "super.h"
-#include "drivers.h"
PUBLIC _PROTOTYPE (int (*fs_call_vec[]), (void) ) = {
no_sys, /* 0 not used */
no_sys, /* 29 */ /* Was: fs_newnode */
fs_rdlink, /* 30 */
fs_getdents, /* 31 */
- fs_statvfs, /* 32 */
+ fs_statvfs, /* 32 */
};