summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tests/ubi-tests/io_paral.c118
1 files changed, 98 insertions, 20 deletions
diff --git a/tests/ubi-tests/io_paral.c b/tests/ubi-tests/io_paral.c
index cbdea43..935f46a 100644
--- a/tests/ubi-tests/io_paral.c
+++ b/tests/ubi-tests/io_paral.c
@@ -20,6 +20,7 @@
* This test does a lot of I/O to volumes in parallel.
*/
+#define _XOPEN_SOURCE 500
#include <stdio.h>
#include <errno.h>
#include <string.h>
@@ -34,18 +35,19 @@
#include "common.h"
#define THREADS_NUM 4
-#define ITERATIONS 409
+#define ITERATIONS (1024 * 1)
+#define VOL_LEBS 10
static libubi_t libubi;
static struct ubi_dev_info dev_info;
static const char *node;
static int vol_size;
-static struct ubi_mkvol_request reqests[THREADS_NUM];
-static char vol_name[THREADS_NUM][100];
-static char vol_nodes[THREADS_NUM][strlen(UBI_VOLUME_PATTERN) + 100];
-static unsigned char *wbufs[THREADS_NUM];
-static unsigned char *rbufs[THREADS_NUM];
+static struct ubi_mkvol_request reqests[THREADS_NUM + 1];
+static char vol_name[THREADS_NUM + 1][100];
+static char vol_nodes[THREADS_NUM + 1][strlen(UBI_VOLUME_PATTERN) + 100];
+static unsigned char *wbufs[THREADS_NUM + 1];
+static unsigned char *rbufs[THREADS_NUM + 1];
static int update_volume(int vol_id, int bytes)
{
@@ -65,14 +67,12 @@ static int update_volume(int vol_id, int bytes)
wbuf[i] = random() % 255;
memset(rbuf, '\0', bytes);
- do {
- ret = ubi_update_start(libubi, fd, bytes);
- if (ret && errno != EBUSY) {
- failed("ubi_update_start");
- err_msg("volume id is %d", vol_id);
- goto err_close;
- }
- } while (ret);
+ ret = ubi_update_start(libubi, fd, bytes);
+ if (ret) {
+ failed("ubi_update_start");
+ err_msg("volume id is %d", vol_id);
+ goto err_close;
+ }
while (written < bytes) {
int to_write = random() % (bytes - written);
@@ -80,7 +80,7 @@ static int update_volume(int vol_id, int bytes)
if (to_write == 0)
to_write = 1;
- ret = write(fd, wbuf, to_write);
+ ret = write(fd, wbuf + written, to_write);
if (ret != to_write) {
failed("write");
err_msg("failed to write %d bytes at offset %d "
@@ -109,7 +109,7 @@ static int update_volume(int vol_id, int bytes)
if (to_read == 0)
to_read = 1;
- ret = read(fd, rbuf, to_read);
+ ret = read(fd, rbuf + rd, to_read);
if (ret != to_read) {
failed("read");
err_msg("failed to read %d bytes at offset %d "
@@ -120,6 +120,11 @@ static int update_volume(int vol_id, int bytes)
rd += to_read;
}
+ if (memcmp(wbuf, rbuf, bytes)) {
+ err_msg("written and read data are different");
+ goto err_close;
+ }
+
close(fd);
return 0;
@@ -160,6 +165,69 @@ static void *update_thread(void *ptr)
return NULL;
}
+static void *write_thread(void *ptr)
+{
+ int ret, fd, vol_id = (long)ptr, i;
+ char *vol_node = vol_nodes[vol_id];
+ unsigned char *wbuf = wbufs[vol_id];
+ unsigned char *rbuf = rbufs[vol_id];
+
+ fd = open(vol_node, O_RDWR);
+ if (fd == -1) {
+ failed("open");
+ err_msg("cannot open \"%s\"\n", vol_node);
+ return NULL;
+ }
+
+ ret = ubi_set_property(fd, UBI_PROP_DIRECT_WRITE, 1);
+ if (ret) {
+ failed("ubi_set_property");
+ err_msg("cannot set property for \"%s\"\n", vol_node);
+ }
+
+ for (i = 0; i < ITERATIONS * VOL_LEBS; i++) {
+ int j, leb = random() % VOL_LEBS;
+ off_t offs = dev_info.leb_size * leb;
+
+ ret = ubi_leb_unmap(fd, leb);
+ if (ret) {
+ failed("ubi_leb_unmap");
+ err_msg("cannot unmap LEB %d", leb);
+ break;
+ }
+
+ for (j = 0; j < dev_info.leb_size; j++)
+ wbuf[j] = random() % 255;
+ memset(rbuf, '\0', dev_info.leb_size);
+
+ ret = pwrite(fd, wbuf, dev_info.leb_size, offs);
+ if (ret != dev_info.leb_size) {
+ failed("pwrite");
+ err_msg("cannot write %d bytes to offs %lld, wrote %d",
+ dev_info.leb_size, offs, ret);
+ break;
+ }
+
+ /* read data back and check */
+ ret = pread(fd, rbuf, dev_info.leb_size, offs);
+ if (ret != dev_info.leb_size) {
+ failed("read");
+ err_msg("failed to read %d bytes at offset %d "
+ "of volume %d", dev_info.leb_size, offs,
+ vol_id);
+ break;
+ }
+
+ if (memcmp(wbuf, rbuf, dev_info.leb_size)) {
+ err_msg("written and read data are different");
+ break;
+ }
+ }
+
+ close(fd);
+ return NULL;
+}
+
int main(int argc, char * const argv[])
{
int i, ret;
@@ -185,14 +253,16 @@ int main(int argc, char * const argv[])
* Create 1 volume more than threads count. The last volume
* will not change to let WL move more stuff.
*/
- vol_size = dev_info.leb_size * 10;
- for (i = 0; i < THREADS_NUM + 1; i++) {
+ vol_size = dev_info.leb_size * VOL_LEBS;
+ for (i = 0; i <= THREADS_NUM; i++) {
reqests[i].alignment = 1;
reqests[i].bytes = vol_size;
reqests[i].vol_id = i;
sprintf(vol_name[i], TESTNAME":%d", i);
reqests[i].name = vol_name[i];
- reqests[i].vol_type = (i & 1) ? UBI_STATIC_VOLUME : UBI_DYNAMIC_VOLUME;
+ reqests[i].vol_type = UBI_DYNAMIC_VOLUME;
+ if (i == THREADS_NUM)
+ reqests[i].vol_type = UBI_STATIC_VOLUME;
sprintf(vol_nodes[i], UBI_VOLUME_PATTERN, dev_info.dev_num, i);
if (ubi_mkvol(libubi, node, &reqests[i])) {
@@ -212,7 +282,15 @@ int main(int argc, char * const argv[])
goto remove;
}
- for (i = 0; i < THREADS_NUM; i++) {
+ for (i = 0; i < THREADS_NUM / 2; i++) {
+ ret = pthread_create(&threads[i], NULL, &write_thread, (void *)(long)i);
+ if (ret) {
+ failed("pthread_create");
+ goto remove;
+ }
+ }
+
+ for (i = THREADS_NUM / 2; i < THREADS_NUM; i++) {
ret = pthread_create(&threads[i], NULL, &update_thread, (void *)(long)i);
if (ret) {
failed("pthread_create");