[rtems commit] libblock: rtems_bdbuf_set_block_size() API change

Sebastian Huber sebh at rtems.org
Fri Oct 26 20:16:18 UTC 2012


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

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Fri Oct 26 21:31:45 2012 +0200

libblock: rtems_bdbuf_set_block_size() API change

The set block size must synchronize and purge the disk to avoid an
inconsistent cache state and data corruption.  The synchronization is
optional depending on the new sync parameter.  In some contexts a
synchronization must not be performed, e.g. during disk creation.

---

 cpukit/libblock/include/rtems/bdbuf.h |   18 ++++++++++++++----
 cpukit/libblock/src/bdbuf.c           |   13 +++++++++++--
 cpukit/libblock/src/blkdev-ioctl.c    |    2 +-
 cpukit/libblock/src/diskdevs-init.c   |    4 ++--
 testsuites/libtests/block15/init.c    |    2 +-
 testsuites/libtests/block16/init.c    |    2 +-
 6 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/cpukit/libblock/include/rtems/bdbuf.h b/cpukit/libblock/include/rtems/bdbuf.h
index 05e324c..8a4631b 100644
--- a/cpukit/libblock/include/rtems/bdbuf.h
+++ b/cpukit/libblock/include/rtems/bdbuf.h
@@ -644,21 +644,31 @@ rtems_bdbuf_purge_dev (rtems_disk_device *dd);
 /**
  * @brief Sets the block size of a disk device.
  *
- * This will set the block size derived fields of the disk device.  The
- * read-ahead state of this device is reset.
+ * This will set the block size derived fields of the disk device.  If
+ * requested the disk device is synchronized before the block size change
+ * occurs.  Since the cache is unlocked during the synchronization operation
+ * some tasks may access the disk device in the meantime.  This may result in
+ * loss of data.  After the synchronization the disk device is purged to ensure
+ * a consistent cache state and the block size change occurs.  This also resets
+ * the read-ahead state of this disk device.  Due to the purge operation this
+ * may result in loss of data.
  *
  * 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
  * occur.
  *
  * @param dd [in, out] The disk device.
- * @param dd [in] The new block size.
+ * @param block_size [in] The new block size.
+ * @param sync [in] If @c true, then synchronize the disk device before the
+ * block size change.
  *
  * @retval RTEMS_SUCCESSFUL Successful operation. 
  * @retval RTEMS_INVALID_NUMBER Invalid block size.
  */
 rtems_status_code
-rtems_bdbuf_set_block_size (rtems_disk_device *dd, uint32_t block_size);
+rtems_bdbuf_set_block_size (rtems_disk_device *dd,
+                            uint32_t           block_size,
+                            bool               sync);
 
 /**
  * @brief Returns the block device statistics.
diff --git a/cpukit/libblock/src/bdbuf.c b/cpukit/libblock/src/bdbuf.c
index 3f4915b..c4336cd 100644
--- a/cpukit/libblock/src/bdbuf.c
+++ b/cpukit/libblock/src/bdbuf.c
@@ -2948,10 +2948,19 @@ rtems_bdbuf_purge_dev (rtems_disk_device *dd)
 }
 
 rtems_status_code
-rtems_bdbuf_set_block_size (rtems_disk_device *dd, uint32_t block_size)
+rtems_bdbuf_set_block_size (rtems_disk_device *dd,
+                            uint32_t           block_size,
+                            bool               sync)
 {
   rtems_status_code sc = RTEMS_SUCCESSFUL;
 
+  /*
+   * We do not care about the synchronization status since we will purge the
+   * device later.
+   */
+  if (sync)
+    rtems_bdbuf_syncdev (dd);
+
   rtems_bdbuf_lock_cache ();
 
   if (block_size > 0)
@@ -2978,7 +2987,7 @@ rtems_bdbuf_set_block_size (rtems_disk_device *dd, uint32_t block_size)
       dd->block_to_media_block_shift = block_to_media_block_shift;
       dd->bds_per_group = bds_per_group;
 
-      rtems_bdbuf_read_ahead_reset (dd);
+      rtems_bdbuf_purge_dev (dd);
     }
     else
     {
diff --git a/cpukit/libblock/src/blkdev-ioctl.c b/cpukit/libblock/src/blkdev-ioctl.c
index b2215f1..54360b3 100644
--- a/cpukit/libblock/src/blkdev-ioctl.c
+++ b/cpukit/libblock/src/blkdev-ioctl.c
@@ -37,7 +37,7 @@ rtems_blkdev_ioctl(rtems_disk_device *dd, uint32_t req, void *argp)
             break;
 
         case RTEMS_BLKIO_SETBLKSIZE:
-            sc = rtems_bdbuf_set_block_size(dd, *(uint32_t *) argp);
+            sc = rtems_bdbuf_set_block_size(dd, *(uint32_t *) argp, true);
             if (sc != RTEMS_SUCCESSFUL) {
                 errno = EIO;
                 rc = -1;
diff --git a/cpukit/libblock/src/diskdevs-init.c b/cpukit/libblock/src/diskdevs-init.c
index 5ec96b2..02ef392 100644
--- a/cpukit/libblock/src/diskdevs-init.c
+++ b/cpukit/libblock/src/diskdevs-init.c
@@ -43,7 +43,7 @@ rtems_status_code rtems_disk_init_phys(
       dd->capabilities = 0;
     }
 
-    sc = rtems_bdbuf_set_block_size(dd, block_size);
+    sc = rtems_bdbuf_set_block_size(dd, block_size, false);
   } else {
     sc = RTEMS_INVALID_NUMBER;
   }
@@ -78,7 +78,7 @@ rtems_status_code rtems_disk_init_log(
         && block_count > 0
         && block_count <= phys_block_count - block_begin
     ) {
-      sc = rtems_bdbuf_set_block_size(dd, phys_dd->media_block_size);
+      sc = rtems_bdbuf_set_block_size(dd, phys_dd->media_block_size, false);
     } else {
       sc = RTEMS_INVALID_NUMBER;
     }
diff --git a/testsuites/libtests/block15/init.c b/testsuites/libtests/block15/init.c
index 3cefd6c..e6de9c3 100644
--- a/testsuites/libtests/block15/init.c
+++ b/testsuites/libtests/block15/init.c
@@ -100,7 +100,7 @@ static void test_write_requests(rtems_disk_device *dd)
   rtems_status_code sc;
   int i;
 
-  sc = rtems_bdbuf_set_block_size(dd, BLOCK_SIZE);
+  sc = rtems_bdbuf_set_block_size(dd, BLOCK_SIZE, true);
   rtems_test_assert(sc == RTEMS_SUCCESSFUL);
 
   for (i = 0; i < ACTION_COUNT; ++i) {
diff --git a/testsuites/libtests/block16/init.c b/testsuites/libtests/block16/init.c
index e115227..5c7033f 100644
--- a/testsuites/libtests/block16/init.c
+++ b/testsuites/libtests/block16/init.c
@@ -92,7 +92,7 @@ static void test(void)
     rtems_test_assert(media_bd [i]->buffer [0] == buf [i] + media_block_count);
   }
 
-  sc = rtems_bdbuf_set_block_size(dd, media_size);
+  sc = rtems_bdbuf_set_block_size(dd, media_size, true);
   ASSERT_SC(sc);
 
   for (i = 0; i < media_block_count; i += 2) {




More information about the vc mailing list