[rtems commit] libblock: Simplify disk management

Sebastian Huber sebh at rtems.org
Thu May 31 09:03:03 UTC 2012


Module:    rtems
Branch:    master
Commit:    73c09b3b8efc52831e80295e010fd7bfbd8c4b0c
Changeset: http://git.rtems.org/rtems/commit/?id=73c09b3b8efc52831e80295e010fd7bfbd8c4b0c

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Wed May 30 13:40:34 2012 +0200

libblock: Simplify disk management

Add block_count and media_blocks_per_block to rtems_disk_device.  Add
and use rtems_disk_init_phys() and rtems_disk_init_log().

---

 cpukit/libblock/Makefile.am              |    1 +
 cpukit/libblock/include/rtems/bdbuf.h    |   11 ++--
 cpukit/libblock/include/rtems/diskdevs.h |   54 +++++++++++++++----
 cpukit/libblock/src/bdbuf.c              |   27 ++++++----
 cpukit/libblock/src/blkdev-imfs.c        |   83 ++++++++++++----------------
 cpukit/libblock/src/diskdevs-init.c      |   88 ++++++++++++++++++++++++++++++
 cpukit/libblock/src/diskdevs.c           |   83 ++++++++++++++--------------
 testsuites/libtests/block01/init.c       |    2 +-
 8 files changed, 230 insertions(+), 119 deletions(-)

diff --git a/cpukit/libblock/Makefile.am b/cpukit/libblock/Makefile.am
index 242c44e..6ddc524 100644
--- a/cpukit/libblock/Makefile.am
+++ b/cpukit/libblock/Makefile.am
@@ -8,6 +8,7 @@ libblock_a_SOURCES = src/bdbuf.c \
     src/blkdev-ioctl.c \
     src/blkdev-ops.c \
     src/diskdevs.c \
+    src/diskdevs-init.c \
     src/flashdisk.c \
     src/ramdisk-driver.c \
     src/ramdisk-init.c \
diff --git a/cpukit/libblock/include/rtems/bdbuf.h b/cpukit/libblock/include/rtems/bdbuf.h
index c065f4e..43a95df 100644
--- a/cpukit/libblock/include/rtems/bdbuf.h
+++ b/cpukit/libblock/include/rtems/bdbuf.h
@@ -141,7 +141,7 @@ extern "C" {
  * A block being accessed is given to the file system layer and not accessible
  * to another requester until released back to the cache.  The same goes to a
  * buffer in the transfer state.  The transfer state means being read or
- * written.  If the file system has modifed the block and releases it as
+ * written.  If the file system has modified the block and releases it as
  * modified it placed on the cache's modified list and a hold timer
  * initialised.  The buffer is held for the hold time before being written to
  * disk.  Buffers are held for a configurable period of time on the modified
@@ -462,7 +462,7 @@ rtems_bdbuf_init (void);
 
 /**
  * Get block buffer for data to be written into. The buffers is set to the
- * access or modifed access state. If the buffer is in the cache and modified
+ * access or modified access state. If the buffer is in the cache and modified
  * the state is access modified else the state is access. This buffer contents
  * are not initialised if the buffer is not already in the cache. If the block
  * is already resident in memory it is returned how-ever if not in memory the
@@ -498,7 +498,7 @@ rtems_bdbuf_get (
 /**
  * Get the block buffer and if not already in the cache read from the disk. If
  * specified block already cached return. The buffer is set to the access or
- * modifed access state. If the buffer is in the cache and modified the state
+ * modified access state. If the buffer is in the cache and modified the state
  * is access modified else the state is access. If block is already being read
  * from disk for being written to disk this call blocks. If the buffer is
  * waiting to be written it is removed from modified queue and returned to the
@@ -601,7 +601,7 @@ rtems_bdbuf_sync (rtems_bdbuf_buffer* bd);
 /**
  * Synchronize all modified buffers for this device with the disk and wait
  * until the transfers have completed. The sync mutex for the cache is locked
- * stopping the addition of any further modifed buffers. It is only the
+ * stopping the addition of any further modified buffers. It is only the
  * currently modified buffers that are written.
  *
  * @note Nesting calls to sync multiple devices will be handled sequentially. A
@@ -635,8 +635,7 @@ rtems_bdbuf_purge_dev (rtems_disk_device *dd);
 /**
  * @brief Sets the block size of a disk device.
  *
- * This will also change the block_to_media_block_shift and bds_per_group
- * fields of the disk device.
+ * This will set the block size derived fields of the disk device.
  *
  * Before you can use this function, the rtems_bdbuf_init() routine must be
  * called at least once to initialize the cache, otherwise a fatal error will
diff --git a/cpukit/libblock/include/rtems/diskdevs.h b/cpukit/libblock/include/rtems/diskdevs.h
index 2e3f753..fe931f8 100644
--- a/cpukit/libblock/include/rtems/diskdevs.h
+++ b/cpukit/libblock/include/rtems/diskdevs.h
@@ -92,33 +92,48 @@ struct rtems_disk_device {
   unsigned uses;
 
   /**
-   * @brief Start block number.
+   * @brief Start media block number.
    *
-   * Equals zero for physical devices.  It is a block offset to the related
-   * physical device for logical device.
+   * Equals zero for physical devices.  It is a media block offset to the
+   * related physical device for logical device.
    */
   rtems_blkdev_bnum start;
 
   /**
-   * @brief Size of the physical or logical disk in blocks.
+   * @brief Size of the physical or logical disk in media blocks.
    */
   rtems_blkdev_bnum size;
 
   /**
-   * @brief Device block size in bytes.
+   * @brief Media block size in bytes.
    *
-   * This is the minimum transfer unit.  It must be positive.
+   * This is the media transfer unit the hardware defaults to.
+   */
+  uint32_t media_block_size;
+
+  /**
+   * @brief Block size in bytes.
+   *
+   * This is the minimum transfer unit.  It may be a multiple of the media
+   * block size. It must be positive.
    *
    * @see rtems_bdbuf_set_block_size().
    */
   uint32_t block_size;
 
   /**
-   * @brief Device media block size in bytes.
+   * @brief Block count.
    *
-   * This is the media transfer unit the hardware defaults to.
+   * @see rtems_bdbuf_set_block_size().
    */
-  uint32_t media_block_size;
+  rtems_blkdev_bnum block_count;
+
+  /**
+   * @brief Media blocks per device blocks.
+   *
+   * @see rtems_bdbuf_set_block_size().
+   */
+  uint32_t media_blocks_per_block;
 
   /**
    * @brief Block to media block shift.
@@ -259,7 +274,7 @@ rtems_status_code rtems_disk_create_phys(
  *
  * A logical disk manages a subset of consecutive blocks contained in the
  * physical disk with identifier @a phys.  The start block index of the logical
- * disk device is @a begin_block.  The block count of the logcal disk will be
+ * disk device is @a block_begin.  The block count of the logcal disk will be
  * @a block_count.  The blocks must be within the range of blocks managed by
  * the associated physical disk device.  A device node will be registered in
  * the file system with absolute path @a name, if @a name is not @c NULL.  The
@@ -278,7 +293,7 @@ rtems_status_code rtems_disk_create_phys(
 rtems_status_code rtems_disk_create_log(
   dev_t dev,
   dev_t phys,
-  rtems_blkdev_bnum begin_block,
+  rtems_blkdev_bnum block_begin,
   rtems_blkdev_bnum block_count,
   const char *name
 );
@@ -373,6 +388,23 @@ rtems_status_code rtems_disk_io_done(void);
  */
 rtems_disk_device *rtems_disk_next(dev_t dev);
 
+/* Internal function, do not use */
+rtems_status_code rtems_disk_init_phys(
+  rtems_disk_device *dd,
+  uint32_t block_size,
+  rtems_blkdev_bnum block_count,
+  rtems_block_device_ioctl handler,
+  void *driver_data
+);
+
+/* Internal function, do not use */
+rtems_status_code rtems_disk_init_log(
+  rtems_disk_device *dd,
+  rtems_disk_device *phys_dd,
+  rtems_blkdev_bnum block_begin,
+  rtems_blkdev_bnum block_count
+);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/cpukit/libblock/src/bdbuf.c b/cpukit/libblock/src/bdbuf.c
index 4985dc1..c0744c6 100644
--- a/cpukit/libblock/src/bdbuf.c
+++ b/cpukit/libblock/src/bdbuf.c
@@ -1754,20 +1754,23 @@ rtems_bdbuf_get_media_block (const rtems_disk_device *dd,
                              rtems_blkdev_bnum        block,
                              rtems_blkdev_bnum       *media_block_ptr)
 {
-  /*
-   * Compute the media block number. Drivers work with media block number not
-   * the block number a BD may have as this depends on the block size set by
-   * the user.
-   */
-  rtems_blkdev_bnum mb = rtems_bdbuf_media_block (dd, block);
-  if (mb >= dd->size)
+  rtems_status_code sc = RTEMS_SUCCESSFUL;
+
+  if (block < dd->block_count)
+  {
+    /*
+     * Compute the media block number. Drivers work with media block number not
+     * the block number a BD may have as this depends on the block size set by
+     * the user.
+     */
+    *media_block_ptr = rtems_bdbuf_media_block (dd, block) + dd->start;
+  }
+  else
   {
-    return RTEMS_INVALID_ID;
+    sc = RTEMS_INVALID_ID;
   }
 
-  *media_block_ptr = mb + dd->start;
-
-  return RTEMS_SUCCESSFUL;
+  return sc;
 }
 
 rtems_status_code
@@ -2909,6 +2912,8 @@ rtems_bdbuf_set_block_size (rtems_disk_device *dd, uint32_t block_size)
         block_to_media_block_shift = -1;
 
       dd->block_size = block_size;
+      dd->block_count = dd->size / media_blocks_per_block;
+      dd->media_blocks_per_block = media_blocks_per_block;
       dd->block_to_media_block_shift = block_to_media_block_shift;
       dd->bds_per_group = bds_per_group;
     }
diff --git a/cpukit/libblock/src/blkdev-imfs.c b/cpukit/libblock/src/blkdev-imfs.c
index c159ca3..e3c76a1 100644
--- a/cpukit/libblock/src/blkdev-imfs.c
+++ b/cpukit/libblock/src/blkdev-imfs.c
@@ -269,46 +269,36 @@ rtems_status_code rtems_blkdev_create(
 )
 {
   rtems_status_code sc = RTEMS_SUCCESSFUL;
+  rtems_blkdev_imfs_context *ctx = malloc(sizeof(*ctx));
 
-  if (block_count > 0) {
-    rtems_blkdev_imfs_context *ctx = calloc(1, sizeof(*ctx));
+  if (ctx != NULL) {
+    sc = rtems_disk_init_phys(
+      &ctx->dd,
+      block_size,
+      block_count,
+      handler,
+      driver_data
+    );
 
-    if (ctx != NULL) {
-      rtems_disk_device *dd = &ctx->dd;
+    ctx->fd = -1;
 
-      ctx->fd = -1;
-
-      dd->phys_dev = dd;
-      dd->size = block_count;
-      dd->media_block_size = block_size;
-      dd->ioctl = handler;
-      dd->driver_data = driver_data;
-
-      if ((*handler)(dd, RTEMS_BLKIO_CAPABILITIES, &dd->capabilities) != 0) {
-        dd->capabilities = 0;
-      }
-
-      sc = rtems_bdbuf_set_block_size(dd, block_size);
-      if (sc == RTEMS_SUCCESSFUL) {
-        int rv = IMFS_make_generic_node(
-          device,
-          S_IFBLK | S_IRWXU | S_IRWXG | S_IRWXO,
-          &rtems_blkdev_imfs_control,
-          ctx
-        );
-
-        if (rv != 0) {
-          free(ctx);
-          sc = RTEMS_UNSATISFIED;
-        }
-      } else {
+    if (sc == RTEMS_SUCCESSFUL) {
+      int rv = IMFS_make_generic_node(
+        device,
+        S_IFBLK | S_IRWXU | S_IRWXG | S_IRWXO,
+        &rtems_blkdev_imfs_control,
+        ctx
+      );
+
+      if (rv != 0) {
         free(ctx);
+        sc = RTEMS_UNSATISFIED;
       }
     } else {
-      sc = RTEMS_NO_MEMORY;
+      free(ctx);
     }
   } else {
-    sc = RTEMS_INVALID_NUMBER;
+    sc = RTEMS_NO_MEMORY;
   }
 
   return sc;
@@ -330,24 +320,21 @@ rtems_status_code rtems_blkdev_create_partition(
 
     rv = fstat(fd, &st);
     if (rv == 0 && S_ISBLK(st.st_mode)) {
-      rtems_disk_device *dd;
+      rtems_disk_device *phys_dd;
 
-      rv = rtems_disk_fd_get_disk_device(fd, &dd);
+      rv = rtems_disk_fd_get_disk_device(fd, &phys_dd);
       if (rv == 0) {
-        rtems_blkdev_bnum device_block_count = rtems_disk_get_block_count(dd);
-
-        if (
-          block_begin < device_block_count
-            && block_count > 0
-            && block_count <= device_block_count - block_begin
-        ) {
-          rtems_blkdev_imfs_context *ctx = malloc(sizeof(*ctx));
+        rtems_blkdev_imfs_context *ctx = malloc(sizeof(*ctx));
 
-          if (ctx != NULL) {
-            memcpy(&ctx->dd, dd, sizeof(ctx->dd));
+        if (ctx != NULL) {
+          sc = rtems_disk_init_log(
+            &ctx->dd,
+            phys_dd,
+            block_begin,
+            block_count
+          );
 
-            ctx->dd.start = block_begin;
-            ctx->dd.size = block_count;
+          if (sc == RTEMS_SUCCESSFUL) {
             ctx->fd = fd;
 
             rv = IMFS_make_generic_node(
@@ -362,10 +349,10 @@ rtems_status_code rtems_blkdev_create_partition(
               sc = RTEMS_UNSATISFIED;
             }
           } else {
-            sc = RTEMS_NO_MEMORY;
+            free(ctx);
           }
         } else {
-          sc = RTEMS_INVALID_NUMBER;
+          sc = RTEMS_NO_MEMORY;
         }
       } else {
         sc = RTEMS_NOT_IMPLEMENTED;
diff --git a/cpukit/libblock/src/diskdevs-init.c b/cpukit/libblock/src/diskdevs-init.c
new file mode 100644
index 0000000..ccf954a
--- /dev/null
+++ b/cpukit/libblock/src/diskdevs-init.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2012 embedded brains GmbH.  All rights reserved.
+ *
+ *  embedded brains GmbH
+ *  Obere Lagerstr. 30
+ *  82178 Puchheim
+ *  Germany
+ *  <rtems at embedded-brains.de>
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rtems.com/license/LICENSE.
+ */
+
+#if HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include <rtems/blkdev.h>
+#include <rtems/bdbuf.h>
+
+rtems_status_code rtems_disk_init_phys(
+  rtems_disk_device *dd,
+  uint32_t block_size,
+  rtems_blkdev_bnum block_count,
+  rtems_block_device_ioctl handler,
+  void *driver_data
+)
+{
+  rtems_status_code sc;
+
+  dd = memset(dd, 0, sizeof(*dd));
+
+  dd->phys_dev = dd;
+  dd->size = block_count;
+  dd->media_block_size = block_size;
+  dd->ioctl = handler;
+  dd->driver_data = driver_data;
+
+  if (block_count > 0) {
+    if ((*handler)(dd, RTEMS_BLKIO_CAPABILITIES, &dd->capabilities) != 0) {
+      dd->capabilities = 0;
+    }
+
+    sc = rtems_bdbuf_set_block_size(dd, block_size);
+  } else {
+    sc = RTEMS_INVALID_NUMBER;
+  }
+
+  return sc;
+}
+
+rtems_status_code rtems_disk_init_log(
+  rtems_disk_device *dd,
+  rtems_disk_device *phys_dd,
+  rtems_blkdev_bnum block_begin,
+  rtems_blkdev_bnum block_count
+)
+{
+  rtems_status_code sc;
+
+  dd = memset(dd, 0, sizeof(*dd));
+
+  dd->phys_dev = phys_dd;
+  dd->start = block_begin;
+  dd->size = block_count;
+  dd->media_block_size = phys_dd->media_block_size;
+  dd->ioctl = phys_dd->ioctl;
+  dd->driver_data = phys_dd->driver_data;
+
+  if (phys_dd->phys_dev == phys_dd) {
+    rtems_blkdev_bnum phys_block_count = phys_dd->size;
+
+    if (
+      block_begin < phys_block_count
+        && block_count > 0
+        && block_count <= phys_block_count - block_begin
+    ) {
+      sc = rtems_bdbuf_set_block_size(dd, phys_dd->media_block_size);
+    } else {
+      sc = RTEMS_INVALID_NUMBER;
+    }
+  } else {
+    sc = RTEMS_INVALID_ID;
+  }
+
+  return sc;
+}
diff --git a/cpukit/libblock/src/diskdevs.c b/cpukit/libblock/src/diskdevs.c
index 285bc05..96bcf88 100644
--- a/cpukit/libblock/src/diskdevs.c
+++ b/cpukit/libblock/src/diskdevs.c
@@ -10,7 +10,7 @@
  * Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
  * Author: Victor V. Vengerov <vvv at oktet.ru>
  *
- * Copyright (c) 2009 embedded brains GmbH.
+ * Copyright (c) 2009-2012 embedded brains GmbH.
  */
 
 #if HAVE_CONFIG_H
@@ -170,7 +170,12 @@ create_disk_table_entry(dev_t dev)
 }
 
 static rtems_status_code
-create_disk(dev_t dev, const char *name, rtems_disk_device **dd_ptr)
+create_disk(
+  dev_t dev,
+  const char *name,
+  rtems_disk_device **dd_ptr,
+  char **alloc_name_ptr
+)
 {
   rtems_disk_device **dd_entry = create_disk_table_entry(dev);
   rtems_disk_device *dd = NULL;
@@ -207,13 +212,9 @@ create_disk(dev_t dev, const char *name, rtems_disk_device **dd_ptr)
     }
   }
 
-  dd->dev = dev;
-  dd->name = alloc_name;
-  dd->uses = 0;
-  dd->deleted = false;
-
   *dd_entry = dd;
   *dd_ptr = dd;
+  *alloc_name_ptr = alloc_name;
 
   return RTEMS_SUCCESSFUL;
 }
@@ -238,6 +239,7 @@ rtems_status_code rtems_disk_create_phys(
 {
   rtems_disk_device *dd = NULL;
   rtems_status_code sc = RTEMS_SUCCESSFUL;
+  char *alloc_name = NULL;
 
   if (handler == NULL) {
     return RTEMS_INVALID_ADDRESS;
@@ -248,25 +250,24 @@ rtems_status_code rtems_disk_create_phys(
     return sc;
   }
 
-  sc = create_disk(dev, name, &dd);
+  sc = create_disk(dev, name, &dd, &alloc_name);
   if (sc != RTEMS_SUCCESSFUL) {
     disk_unlock();
 
     return sc;
   }
 
-  dd->phys_dev = dd;
-  dd->start = 0;
-  dd->size = block_count;
-  dd->media_block_size = block_size;
-  dd->ioctl = handler;
-  dd->driver_data = driver_data;
+  sc = rtems_disk_init_phys(
+    dd,
+    block_size,
+    block_count,
+    handler,
+    driver_data
+  );
 
-  if ((*handler)(dd, RTEMS_BLKIO_CAPABILITIES, &dd->capabilities) < 0) {
-    dd->capabilities = 0;
-  }
+  dd->dev = dev;
+  dd->name = alloc_name;
 
-  sc = rtems_bdbuf_set_block_size(dd, block_size);
   if (sc != RTEMS_SUCCESSFUL) {
     dd->ioctl = null_handler;
     rtems_disk_delete(dev);
@@ -289,57 +290,55 @@ is_physical_disk(const rtems_disk_device *dd)
 rtems_status_code rtems_disk_create_log(
   dev_t dev,
   dev_t phys,
-  rtems_blkdev_bnum begin_block,
+  rtems_blkdev_bnum block_begin,
   rtems_blkdev_bnum block_count,
   const char *name
 )
 {
   rtems_status_code sc = RTEMS_SUCCESSFUL;
-  rtems_disk_device *physical_disk = NULL;
+  rtems_disk_device *phys_dd = NULL;
   rtems_disk_device *dd = NULL;
-  rtems_blkdev_bnum end_block = begin_block + block_count;
+  char *alloc_name = NULL;
 
   sc = disk_lock();
   if (sc != RTEMS_SUCCESSFUL) {
     return sc;
   }
 
-  physical_disk = get_disk_entry(phys, true);
-  if (physical_disk == NULL || !is_physical_disk(physical_disk)) {
+  phys_dd = get_disk_entry(phys, true);
+  if (phys_dd == NULL) {
     disk_unlock();
 
     return RTEMS_INVALID_ID;
   }
 
-  if (
-    begin_block >= physical_disk->size
-      || end_block <= begin_block
-      || end_block > physical_disk->size
-  ) {
+  sc = create_disk(dev, name, &dd, &alloc_name);
+  if (sc != RTEMS_SUCCESSFUL) {
     disk_unlock();
 
-    return RTEMS_INVALID_NUMBER;
+    return sc;
   }
 
-  sc = create_disk(dev, name, &dd);
+  sc = rtems_disk_init_log(
+    dd,
+    phys_dd,
+    block_begin,
+    block_count
+  );
+
+  dd->dev = dev;
+  dd->name = alloc_name;
+
+  ++phys_dd->uses;
+
   if (sc != RTEMS_SUCCESSFUL) {
+    dd->ioctl = null_handler;
+    rtems_disk_delete(dev);
     disk_unlock();
 
     return sc;
   }
 
-  dd->phys_dev = physical_disk;
-  dd->start = begin_block;
-  dd->size = block_count;
-  dd->block_size = physical_disk->block_size;
-  dd->media_block_size = physical_disk->media_block_size;
-  dd->block_to_media_block_shift = physical_disk->block_to_media_block_shift;
-  dd->bds_per_group = physical_disk->bds_per_group;
-  dd->ioctl = physical_disk->ioctl;
-  dd->driver_data = physical_disk->driver_data;
-
-  ++physical_disk->uses;
-
   disk_unlock();
 
   return RTEMS_SUCCESSFUL;
diff --git a/testsuites/libtests/block01/init.c b/testsuites/libtests/block01/init.c
index 03ff097..c26f18a 100644
--- a/testsuites/libtests/block01/init.c
+++ b/testsuites/libtests/block01/init.c
@@ -183,7 +183,7 @@ static void test_diskdevs(void)
   sc = rtems_disk_create_log(logical_dev, physical_dev, 0, 1, "/dev/rda1");
   ASSERT_SC_EQ(sc, RTEMS_RESOURCE_IN_USE);
 
-  sc = rtems_disk_create_log(logical_2_dev, logical_dev, 0, 1, "/dev/rda1");
+  sc = rtems_disk_create_log(logical_2_dev, logical_dev, 0, 1, "/dev/rda2");
   ASSERT_SC_EQ(sc, RTEMS_INVALID_ID);
 
   sc = rtems_disk_delete(logical_dev);




More information about the vc mailing list