]> Zhao Yanbai Git Server - minix.git/commitdiff
libbdev: initial version
authorDavid van Moolenbroek <david@minix3.org>
Wed, 9 Nov 2011 13:29:12 +0000 (14:29 +0100)
committerDavid van Moolenbroek <david@minix3.org>
Wed, 9 Nov 2011 13:43:25 +0000 (14:43 +0100)
The "bdev" library provides basic primitives for file systems to talk
to block device drivers, hiding the details of the underlying protocol
and interaction model.

This version of libbdev is rather basic. It is planned to support the
following features in the long run:

 - asynchronous requests and replies;
 - recovery support for underlying block drivers;
 - retrying of failed I/O requests.

The commit also changes our block-based file systems (mfs, ext2, isofs)
to make use of libbdev.

43 files changed:
common/include/Makefile.inc
common/include/minix/bdev.h [new file with mode: 0644]
lib/Makefile
lib/libbdev/Makefile [new file with mode: 0644]
lib/libbdev/bdev.c [new file with mode: 0644]
lib/libbdev/driver.c [new file with mode: 0644]
lib/libbdev/ipc.c [new file with mode: 0644]
lib/libbdev/proto.h [new file with mode: 0644]
servers/ext2/Makefile
servers/ext2/cache.c
servers/ext2/const.h
servers/ext2/device.c [deleted file]
servers/ext2/drivers.h [deleted file]
servers/ext2/main.c
servers/ext2/misc.c
servers/ext2/mount.c
servers/ext2/path.c
servers/ext2/proto.h
servers/ext2/super.c
servers/ext2/table.c
servers/iso9660fs/Makefile
servers/iso9660fs/cache.c
servers/iso9660fs/const.h
servers/iso9660fs/device.c [deleted file]
servers/iso9660fs/drivers.h [deleted file]
servers/iso9660fs/inc.h
servers/iso9660fs/main.c
servers/iso9660fs/misc.c
servers/iso9660fs/mount.c
servers/iso9660fs/proto.h
servers/iso9660fs/super.c
servers/mfs/Makefile
servers/mfs/cache.c
servers/mfs/const.h
servers/mfs/device.c [deleted file]
servers/mfs/drivers.h [deleted file]
servers/mfs/main.c
servers/mfs/misc.c
servers/mfs/mount.c
servers/mfs/path.c
servers/mfs/proto.h
servers/mfs/super.c
servers/mfs/table.c

index 24a39355ded945676a76e06406069eba35db4f4b..25df3fa0aa62997f2a5a562c8859205aa177562e 100644 (file)
@@ -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 (file)
index 0000000..e0ef806
--- /dev/null
@@ -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 */
index 3e9dc86d978a9fe2e8871633fb1d0672200ef1bb..16cdf1382a12c1179d44df70dd0c02f8637d67bc 100644 (file)
@@ -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 (file)
index 0000000..37e4021
--- /dev/null
@@ -0,0 +1,8 @@
+# Makefile for libbdev
+.include <bsd.own.mk>
+
+LIB=   bdev
+
+SRCS=  bdev.c ipc.c driver.c
+
+.include <bsd.lib.mk>
diff --git a/lib/libbdev/bdev.c b/lib/libbdev/bdev.c
new file mode 100644 (file)
index 0000000..8182dcd
--- /dev/null
@@ -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 <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;
+}
diff --git a/lib/libbdev/driver.c b/lib/libbdev/driver.c
new file mode 100644 (file)
index 0000000..f4a8be4
--- /dev/null
@@ -0,0 +1,58 @@
+/* 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];
+}
diff --git a/lib/libbdev/ipc.c b/lib/libbdev/ipc.c
new file mode 100644 (file)
index 0000000..941d2e1
--- /dev/null
@@ -0,0 +1,89 @@
+/* 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;
+}
diff --git a/lib/libbdev/proto.h b/lib/libbdev/proto.h
new file mode 100644 (file)
index 0000000..31b3ee4
--- /dev/null
@@ -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 */
index 599355c96ad22d84c1bb479e4a1fec57db0ab91a..dcc1bea64a1a84636ff5cb95c6b1a801a7e480b1 100644 (file)
@@ -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=
 
index 2b0305d85b92816cbc16eaa9a3ed1960441e766c..9fb27ff4fb25ee43d8f14144e89c3243445e9c48 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "fs.h"
 #include <minix/u64.h>
+#include <minix/bdev.h>
 #include <minix/libminixfs.h>
 #include <stdlib.h>
 #include <assert.h>
@@ -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;
index 6a511cafdf492d326bdbd441d1fbfeffb597c0ed..a6d415e8bab5d660fda23a24b631e2a42d988098 100644 (file)
 
 #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 (file)
index d29d393..0000000
+++ /dev/null
@@ -1,359 +0,0 @@
-#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);
-}
diff --git a/servers/ext2/drivers.h b/servers/ext2/drivers.h
deleted file mode 100644 (file)
index 24eaeec..0000000
+++ /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 */
index 0561877ecd702eaba45ddf328989754bc061646c..f7f58199160076d057823b9d9e7fd0066504a1d3 100644 (file)
@@ -11,7 +11,6 @@
 #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)                      );
@@ -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 */
index 435637ebf55c8f460f354e1bd977028366451d42..faa184b40696a1826fec8dfb9fe6768292aaefe3 100644 (file)
@@ -5,6 +5,7 @@
 #include "fs.h"
 #include <assert.h>
 #include <minix/vfsif.h>
+#include <minix/bdev.h>
 #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);
+}
index a062e4e6bf9eb2b9157399fcfa0cc2e63e1009bf..ceb562e658fcf089b1f86a73547469ec9ca1d800 100644 (file)
@@ -10,9 +10,9 @@
 #include "buf.h"
 #include "inode.h"
 #include "super.h"
-#include "drivers.h"
 #include <minix/ds.h>
 #include <minix/vfsif.h>
+#include <minix/bdev.h>
 
 
 /*===========================================================================*
@@ -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;
index ee054ac64ed1942577ed6c883a4452d2b6a3944a..9394520190a9b6b04898f8bc5fe8f4ce9b070403 100644 (file)
@@ -21,6 +21,7 @@
 #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 ..                 */
index a76d0657e0654696fe9d9e3c10522cb268877485..093aecd62fc18fa59817cbc1fdd4235ae2a2e261 100644 (file)
@@ -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)                                  );
index fd2b5d97ab2ce2e9c290f3da9228ca0f72924bb5..c1fc4279a046a21c664696053a73b48272656ed8 100644 (file)
@@ -14,6 +14,7 @@
 #include <assert.h>
 #include <minix/com.h>
 #include <minix/u64.h>
+#include <minix/bdev.h>
 #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");
        }
index 222bd6d03d9634b69b69b8ed1b57f50f1f8d55c7..28330864a82edd17786f0a4cb61311312817343c 100644 (file)
@@ -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 */
index 3e79a43eb3eaa6d8ea11f4df4e468799d454cace..aa1a4edb2ae255ce0b478685fa4ae47be5452063 100644 (file)
@@ -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=
 
index d58e93e4f6843baaaf1c7f31679410d883848e7d..b8f1e9a98581cbf0cc7c1081cfe41f0523cebea4 100644 (file)
@@ -14,6 +14,7 @@
 #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 *));
@@ -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)
index f6cde19948ff9c89e62b088f3eefc7e902aac4a8..3dfd35317ff71977a088d997639911aff5c87527 100644 (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 */
diff --git a/servers/iso9660fs/device.c b/servers/iso9660fs/device.c
deleted file mode 100644 (file)
index 440d258..0000000
+++ /dev/null
@@ -1,337 +0,0 @@
-#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);
-}
-
diff --git a/servers/iso9660fs/drivers.h b/servers/iso9660fs/drivers.h
deleted file mode 100644 (file)
index 2878aca..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-#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];
-
index 1072bf2e01d69134267c109650e65b3cfd8ae877..d7559d5f23f88aa877b493377070e3141742111f 100644 (file)
@@ -31,4 +31,3 @@
 #include "proto.h"
 #include "super.h"
 #include "glo.h"
-#include "drivers.h"
index 5ff8efe3cf6b07af0b6f6111992a0cd0672c4b28..cbb4df49db23b975f22373ec62e856276624d318 100644 (file)
@@ -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 */
index f25dba4a411e400eab695e2a52155737a2ff7b78..bce2b1617bce3754bab0ebc91d8d3855950680d9 100644 (file)
@@ -1,6 +1,7 @@
 #include "inc.h"
 #include <fcntl.h>
 #include <minix/vfsif.h>
+#include <minix/bdev.h>
 
 
 /*===========================================================================*
@@ -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);
+}
index 4ec990c3aa8d815994d646ae45eb5b8fa9eee453..95467b8e4e88d9ed6c78e6f598489267cb092fb6 100644 (file)
@@ -1,6 +1,7 @@
 #include "inc.h"
 #include <minix/vfsif.h>
 #include <minix/ds.h>
+#include <minix/bdev.h>
 #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);
 }
index dcf37f240cf5e02ac09e2813417479b81e067474..98966f07cb7bfd8d3f82a8cde1d50800db1ad164 100644 (file)
@@ -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)                                   );
index d90b61de109ec7e5ec71c34e092b5cb7085b2d98..5522cea32b9865b47d34c3d8fcb192d003fc0a77 100644 (file)
@@ -5,6 +5,7 @@
 #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. */
@@ -94,7 +95,7 @@ PUBLIC int read_vds(
   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;
index a937b97f346efd80ffffa5cb6e14f6c792bdcba7..90806d3ded8e3c3c4d35be63c56ee7cc8b8424a6 100644 (file)
@@ -1,12 +1,12 @@
 # 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=
 
index 49a82ebdd5735898c2ef10137e0d28540c4cbe75..a4f7c7adb81f7b0049d3de522e55544613e4cb30 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "fs.h"
 #include <minix/u64.h>
+#include <minix/bdev.h>
 #include <sys/param.h>
 #include <stdlib.h>
 #include <assert.h>
@@ -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;
index e85d6d650eee7e98159f8c1fb30311e37a6abf2b..5e9bb65b45e064917ac49f7402e52d928abbf097 100644 (file)
 
 #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 (file)
index cf56c10..0000000
+++ /dev/null
@@ -1,360 +0,0 @@
-#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);
-}
-
diff --git a/servers/mfs/drivers.h b/servers/mfs/drivers.h
deleted file mode 100644 (file)
index c83c906..0000000
+++ /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
index 96b9c5afebbad630e5038438097e43f5a6efb193..2d7d244d77da8ed0afa96e81d0452d82e734cbc1 100644 (file)
@@ -9,7 +9,6 @@
 #include <minix/vfsif.h>
 #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;
index 2a8fabf9c9b07f13f469cde9ec63d081190d2bc0..064e9138db45a596cafee96b090d06ee03b9bd29 100644 (file)
@@ -1,6 +1,7 @@
 #include "fs.h"
 #include <assert.h>
 #include <minix/vfsif.h>
+#include <minix/bdev.h>
 #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);
+}
index 614f9777aeb6cfd3e77e10e9ce1847e4a29745bd..a64054f86069eddff3ddd0e8bf9244e1bd2d55d1 100644 (file)
@@ -1,9 +1,9 @@
 #include "fs.h"
 #include "inode.h"
 #include "super.h"
-#include "drivers.h"
 #include <minix/ds.h>
 #include <minix/vfsif.h>
+#include <minix/bdev.h>
 
 
 /*===========================================================================*
@@ -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;
index 4efffcad75df9e1b8af0aa150f26314e148aa591..34faed7d9aec233bb5a45fd21813792d6df4228d 100644 (file)
@@ -19,6 +19,7 @@
 #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 */
index b849eb5e708478094f8070e287c8080c2105706b..a2b754a67953f335056df6e539742fb5911b95d5 100644 (file)
@@ -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)                                  );
index d0e6d05dc7595f1b78a0528e41f4ea1faafec5b5..0c97d04135eb88ee37ce1656e2772009ab7dee07 100644 (file)
@@ -15,6 +15,7 @@
 #include <string.h>
 #include <minix/com.h>
 #include <minix/u64.h>
+#include <minix/bdev.h>
 #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);
   
index d50005f204bf05f98482b0440989f13cde8c5921..e8aaa4895b724c896077817037992c75db544614 100644 (file)
@@ -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  */
 };