[rtems commit] libblock: Fix continuous blocks write request

Sebastian Huber sebh at rtems.org
Mon Jul 2 14:13:15 UTC 2012


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

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Mon Jul  2 15:08:08 2012 +0200

libblock: Fix continuous blocks write request

---

 cpukit/libblock/src/bdbuf.c             |   19 +--
 testsuites/libtests/Makefile.am         |    1 +
 testsuites/libtests/block15/Makefile.am |   19 +++
 testsuites/libtests/block15/block15.doc |   12 ++
 testsuites/libtests/block15/block15.scn |   14 +++
 testsuites/libtests/block15/init.c      |  183 +++++++++++++++++++++++++++++++
 testsuites/libtests/configure.ac        |    1 +
 7 files changed, 236 insertions(+), 13 deletions(-)

diff --git a/cpukit/libblock/src/bdbuf.c b/cpukit/libblock/src/bdbuf.c
index 0b84260..034e5a8 100644
--- a/cpukit/libblock/src/bdbuf.c
+++ b/cpukit/libblock/src/bdbuf.c
@@ -2296,15 +2296,10 @@ rtems_bdbuf_swapout_write (rtems_bdbuf_swapout_transfer* transfer)
      */
     uint32_t last_block = 0;
 
-    /*
-     * Number of buffers per bd. This is used to detect the next
-     * block.
-     */
-    uint32_t bufs_per_bd = 0;
-
     rtems_disk_device *dd = transfer->dd;
-
-    bufs_per_bd = dd->block_size / bdbuf_config.buffer_min;
+    uint32_t media_blocks_per_block = dd->media_blocks_per_block;
+    bool need_continuous_blocks =
+      (dd->phys_dev->capabilities & RTEMS_BLKDEV_CAP_MULTISECTOR_CONT) != 0;
 
     /*
      * Take as many buffers as configured and pass to the driver. Note, the
@@ -2333,12 +2328,10 @@ rtems_bdbuf_swapout_write (rtems_bdbuf_swapout_transfer* transfer)
       if (rtems_bdbuf_tracer)
         printf ("bdbuf:swapout write: bd:%" PRIu32 ", bufnum:%" PRIu32 " mode:%s\n",
                 bd->block, transfer->write_req->bufnum,
-                dd->phys_dev->capabilities &
-                RTEMS_BLKDEV_CAP_MULTISECTOR_CONT ? "MULIT" : "SCAT");
+                need_continuous_blocks ? "MULTI" : "SCAT");
 
-      if ((dd->phys_dev->capabilities & RTEMS_BLKDEV_CAP_MULTISECTOR_CONT) &&
-          transfer->write_req->bufnum &&
-          (bd->block != (last_block + bufs_per_bd)))
+      if (need_continuous_blocks && transfer->write_req->bufnum &&
+          bd->block != last_block + media_blocks_per_block)
       {
         rtems_chain_prepend_unprotected (&transfer->bds, &bd->link);
         write = true;
diff --git a/testsuites/libtests/Makefile.am b/testsuites/libtests/Makefile.am
index 6a0d20f..3710ad8 100644
--- a/testsuites/libtests/Makefile.am
+++ b/testsuites/libtests/Makefile.am
@@ -1,6 +1,7 @@
 ACLOCAL_AMFLAGS = -I ../aclocal
 
 SUBDIRS = POSIX
+SUBDIRS += block15
 SUBDIRS += block14
 SUBDIRS += block13
 SUBDIRS += rbheap01
diff --git a/testsuites/libtests/block15/Makefile.am b/testsuites/libtests/block15/Makefile.am
new file mode 100644
index 0000000..1acef6e
--- /dev/null
+++ b/testsuites/libtests/block15/Makefile.am
@@ -0,0 +1,19 @@
+rtems_tests_PROGRAMS = block15
+block15_SOURCES = init.c
+
+dist_rtems_tests_DATA = block15.scn block15.doc
+
+include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP at .cfg
+include $(top_srcdir)/../automake/compile.am
+include $(top_srcdir)/../automake/leaf.am
+
+AM_CPPFLAGS += -I$(top_srcdir)/../support/include
+
+LINK_OBJS = $(block15_OBJECTS)
+LINK_LIBS = $(block15_LDLIBS)
+
+block15$(EXEEXT): $(block15_OBJECTS) $(block15_DEPENDENCIES)
+	@rm -f block15$(EXEEXT)
+	$(make-exe)
+
+include $(top_srcdir)/../automake/local.am
diff --git a/testsuites/libtests/block15/block15.doc b/testsuites/libtests/block15/block15.doc
new file mode 100644
index 0000000..ea4b879
--- /dev/null
+++ b/testsuites/libtests/block15/block15.doc
@@ -0,0 +1,12 @@
+This file describes the directives and concepts tested by this test set.
+
+test set name: block15
+
+directives:
+
+  TBD
+
+concepts:
+
+  - Ensure that write requests are continuous and do not exceed the maximum
+    write transfer block count
diff --git a/testsuites/libtests/block15/block15.scn b/testsuites/libtests/block15/block15.scn
new file mode 100644
index 0000000..9888e5b
--- /dev/null
+++ b/testsuites/libtests/block15/block15.scn
@@ -0,0 +1,14 @@
+*** TEST BLOCK 15 ***
+REQ 3
+W 0
+W 2
+W 4
+REQ 3
+W 8
+W 10
+W 12
+REQ 1
+W 14
+REQ 1
+W 18
+*** END OF TEST BLOCK 15 ***
diff --git a/testsuites/libtests/block15/init.c b/testsuites/libtests/block15/init.c
new file mode 100644
index 0000000..3cefd6c
--- /dev/null
+++ b/testsuites/libtests/block15/init.c
@@ -0,0 +1,183 @@
+/*
+ * 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+  #include "config.h"
+#endif
+
+#include "tmacros.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include <inttypes.h>
+
+#include <rtems/blkdev.h>
+#include <rtems/bdbuf.h>
+
+#define BLOCK_COUNT 20
+
+#define ACTION_COUNT 8
+
+#define REQUEST_COUNT 4
+
+#define WRITE_COUNT 16
+
+#define MAX_WRITE_BLOCKS 3
+
+#define MEDIA_BLOCK_SIZE 2
+
+#define BLOCK_SIZE 4
+
+static const rtems_blkdev_bnum action_sequence [ACTION_COUNT] = {
+  2, 1, 0, 4, 5, 6, 7, 9
+};
+
+static size_t request_index;
+
+static const uint32_t expected_request_bufnums [REQUEST_COUNT] = {
+  3, 3, 1, 1
+};
+
+static size_t write_index;
+
+static const rtems_blkdev_bnum expected_write_blocks [WRITE_COUNT] = {
+  0, 1, 2, 3, 4, 5, 8, 9, 10, 11, 12, 13, 14, 15, 18, 19
+};
+
+static int test_disk_ioctl(rtems_disk_device *dd, uint32_t req, void *arg)
+{
+  int rv = 0;
+
+  if (req == RTEMS_BLKIO_REQUEST) {
+    rtems_blkdev_request *breq = arg;
+    uint32_t i;
+
+    printf("REQ %" PRIu32 "\n", breq->bufnum);
+
+    rtems_test_assert(breq->req == RTEMS_BLKDEV_REQ_WRITE);
+    rtems_test_assert(breq->bufnum == expected_request_bufnums [request_index]);
+    ++request_index;
+
+    for (i = 0; i < breq->bufnum; ++i) {
+      rtems_blkdev_sg_buffer *sg = &breq->bufs [i];
+      rtems_blkdev_bnum j;
+
+      printf("W %" PRIu32 "\n", sg->block);
+
+      rtems_test_assert(sg->block < BLOCK_COUNT);
+      rtems_test_assert(sg->length == BLOCK_SIZE);
+
+      for (j = 0; j < BLOCK_SIZE / MEDIA_BLOCK_SIZE; ++j) {
+        rtems_test_assert(expected_write_blocks [write_index] == sg->block + j);
+        ++write_index;
+      }
+    }
+
+    (*breq->req_done)(breq->done_arg, RTEMS_SUCCESSFUL);
+  } else if (req == RTEMS_BLKIO_CAPABILITIES) {
+    *(uint32_t *) arg = RTEMS_BLKDEV_CAP_MULTISECTOR_CONT;
+  } else {
+    errno = EINVAL;
+    rv = -1;
+  }
+
+  return rv;
+}
+
+static void test_write_requests(rtems_disk_device *dd)
+{
+  rtems_status_code sc;
+  int i;
+
+  sc = rtems_bdbuf_set_block_size(dd, BLOCK_SIZE);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  for (i = 0; i < ACTION_COUNT; ++i) {
+    rtems_blkdev_bnum block = action_sequence [i];
+    rtems_bdbuf_buffer *bd;
+
+    sc = rtems_bdbuf_get(dd, block, &bd);
+    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+    sc = rtems_bdbuf_release_modified(bd);
+    rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+  }
+
+  sc = rtems_bdbuf_syncdev(dd);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  rtems_test_assert(request_index == REQUEST_COUNT);
+  rtems_test_assert(write_index == WRITE_COUNT);
+}
+
+static void test(void)
+{
+  rtems_status_code sc;
+  dev_t dev = 0;
+  rtems_disk_device *dd;
+
+  sc = rtems_disk_io_initialize();
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_disk_create_phys(
+    dev,
+    MEDIA_BLOCK_SIZE,
+    BLOCK_COUNT,
+    test_disk_ioctl,
+    NULL,
+    NULL
+  );
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  dd = rtems_disk_obtain(dev);
+  rtems_test_assert(dd != NULL);
+
+  test_write_requests(dd);
+
+  sc = rtems_disk_release(dd);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+
+  sc = rtems_disk_delete(dev);
+  rtems_test_assert(sc == RTEMS_SUCCESSFUL);
+}
+
+static void Init(rtems_task_argument arg)
+{
+  puts("\n\n*** TEST BLOCK 15 ***");
+
+  test();
+
+  puts("*** END OF TEST BLOCK 15 ***");
+
+  rtems_test_exit(0);
+}
+
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_LIBBLOCK
+
+#define CONFIGURE_BDBUF_BUFFER_MIN_SIZE 1
+#define CONFIGURE_BDBUF_BUFFER_MAX_SIZE 4
+#define CONFIGURE_BDBUF_CACHE_MEMORY_SIZE (BLOCK_COUNT * BLOCK_SIZE)
+#define CONFIGURE_BDBUF_MAX_WRITE_BLOCKS MAX_WRITE_BLOCKS
+
+#define CONFIGURE_USE_IMFS_AS_BASE_FILESYSTEM
+
+#define CONFIGURE_MAXIMUM_TASKS 1
+
+#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
+
+#define CONFIGURE_INIT
+
+#include <rtems/confdefs.h>
diff --git a/testsuites/libtests/configure.ac b/testsuites/libtests/configure.ac
index f383ac1..b58c4a8 100644
--- a/testsuites/libtests/configure.ac
+++ b/testsuites/libtests/configure.ac
@@ -41,6 +41,7 @@ AM_CONDITIONAL(NETTESTS,test "$rtems_cv_RTEMS_NETWORKING" = "yes")
 
 # Explicitly list all Makefiles here
 AC_CONFIG_FILES([Makefile
+block15/Makefile
 block14/Makefile
 block13/Makefile
 rbheap01/Makefile




More information about the vc mailing list