From: gkostka Date: Fri, 13 Nov 2015 21:14:03 +0000 (+0100) Subject: Move all test modules to fs_test directory X-Git-Tag: v1.0.0~265 X-Git-Url: https://git.carlh.net/gitweb/?a=commitdiff_plain;ds=inline;h=14c9ded75eb5ae8be70369effb7f946637de3843;p=lwext4.git Move all test modules to fs_test directory --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 95380db..a8b519d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,8 +14,7 @@ if (CMAKE_SYSTEM_PROCESSOR STREQUAL cortex-m0) elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL cortex-m3) #... elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL arm-sim) - add_subdirectory(blockdev) - add_subdirectory(demos/generic) + #... elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL cortex-m4) #... elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL bf518) @@ -38,7 +37,6 @@ else() add_definitions(-DCONFIG_HAVE_OWN_ASSERT=0) add_definitions(-DCONFIG_BLOCK_DEV_CACHE_SIZE=16) add_subdirectory(fs_test) - add_subdirectory(demos/generic) endif() add_subdirectory(blockdev) diff --git a/README.md b/README.md index d070748..72080a9 100644 --- a/README.md +++ b/README.md @@ -141,9 +141,9 @@ Simple lwext4 library presentation: How to use for images/blockdevices: ```bash cd build_generic - generic -i ext_images/ext2 - generic -i ext_images/ext3 - generic -i ext_images/ext4 + lwext4_generic -i ext_images/ext2 + lwext4_generic -i ext_images/ext3 + lwext4_generic -i ext_images/ext4 ``` diff --git a/blockdev/test_lwext4.c b/blockdev/test_lwext4.c deleted file mode 100644 index f6e76d3..0000000 --- a/blockdev/test_lwext4.c +++ /dev/null @@ -1,371 +0,0 @@ -/* - * Copyright (c) 2014 Grzegorz Kostka (kostka.grzegorz@gmail.com) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include -#include -#include - -#include "test_lwext4.h" - -/**@brief Block device handle.*/ -static struct ext4_blockdev *bd; - -/**@brief Block cache handle.*/ -static struct ext4_bcache *bc; - -static char *entry_to_str(uint8_t type) -{ - switch (type) { - case EXT4_DIRENTRY_UNKNOWN: - return "[unk] "; - case EXT4_DIRENTRY_REG_FILE: - return "[fil] "; - case EXT4_DIRENTRY_DIR: - return "[dir] "; - case EXT4_DIRENTRY_CHRDEV: - return "[cha] "; - case EXT4_DIRENTRY_BLKDEV: - return "[blk] "; - case EXT4_DIRENTRY_FIFO: - return "[fif] "; - case EXT4_DIRENTRY_SOCK: - return "[soc] "; - case EXT4_DIRENTRY_SYMLINK: - return "[sym] "; - default: - break; - } - return "[???]"; -} - -static long int get_ms(void) { return tim_get_ms(); } - -static void printf_io_timings(long int diff) -{ - const struct ext4_io_stats *stats = io_timings_get(diff); - if (!stats) - return; - - printf("io_timings:\n"); - printf(" io_read: %.3f%%\n", (double)stats->io_read); - printf(" io_write: %.3f%%\n", (double)stats->io_write); - printf(" io_cpu: %.3f%%\n", (double)stats->cpu); -} - -void test_lwext4_dir_ls(const char *path) -{ - char sss[255]; - ext4_dir d; - const ext4_direntry *de; - - printf("ls %s\n", path); - - ext4_dir_open(&d, path); - de = ext4_dir_entry_next(&d); - - while (de) { - memcpy(sss, de->name, de->name_length); - sss[de->name_length] = 0; - printf(" %s%s\n", entry_to_str(de->inode_type), sss); - de = ext4_dir_entry_next(&d); - } - ext4_dir_close(&d); -} - -void test_lwext4_mp_stats(void) -{ - struct ext4_mount_stats stats; - ext4_mount_point_stats("/mp/", &stats); - - printf("********************\n"); - printf("ext4_mount_point_stats\n"); - printf("inodes_count = %" PRIu32 "\n", stats.inodes_count); - printf("free_inodes_count = %" PRIu32 "\n", stats.free_inodes_count); - printf("blocks_count = %" PRIu32 "\n", (uint32_t)stats.blocks_count); - printf("free_blocks_count = %" PRIu32 "\n", - (uint32_t)stats.free_blocks_count); - printf("block_size = %" PRIu32 "\n", stats.block_size); - printf("block_group_count = %" PRIu32 "\n", stats.block_group_count); - printf("blocks_per_group= %" PRIu32 "\n", stats.blocks_per_group); - printf("inodes_per_group = %" PRIu32 "\n", stats.inodes_per_group); - printf("volume_name = %s\n", stats.volume_name); - printf("********************\n"); -} - -void test_lwext4_block_stats(void) -{ - if (!bd) - return; - - printf("********************\n"); - printf("ext4 blockdev stats\n"); - printf("bdev->bread_ctr = %" PRIu32 "\n", bd->bread_ctr); - printf("bdev->bwrite_ctr = %" PRIu32 "\n", bd->bwrite_ctr); - - printf("bcache->ref_blocks = %" PRIu32 "\n", bc->ref_blocks); - printf("bcache->max_ref_blocks = %" PRIu32 "\n", bc->max_ref_blocks); - printf("bcache->lru_ctr = %" PRIu32 "\n", bc->lru_ctr); - - printf("\n"); - - uint32_t i; - for (i = 0; i < bc->cnt; ++i) { - printf("bcache->refctr[%" PRIu32 "]= %" PRIu32 "\n", i, - bc->refctr[i]); - } - - printf("\n"); - for (i = 0; i < bc->cnt; ++i) { - printf("bcache->lru_id[%" PRIu32 "] = %" PRIu32 "\n", i, - bc->lru_id[i]); - } - - printf("\n"); - for (i = 0; i < bc->cnt; ++i) { - printf("bcache->free_delay[%" PRIu32 "] = %d\n", i, - bc->free_delay[i]); - } - - printf("\n"); - for (i = 0; i < bc->cnt; ++i) { - printf("bcache->lba[%" PRIu32 "] = %" PRIu32 "\n", i, - (uint32_t)bc->lba[i]); - } - - printf("********************\n"); -} - -bool test_lwext4_dir_test(int len) -{ - ext4_file f; - int r; - int i; - char path[64]; - long int diff; - long int stop; - long int start; - - printf("test_lwext4_dir_test: %d\n", len); - io_timings_clear(); - start = get_ms(); - - printf("directory create: /mp/dir1\n"); - r = ext4_dir_mk("/mp/dir1"); - if (r != EOK) { - printf("ext4_dir_mk: rc = %d\n", r); - return false; - } - - printf("add files to: /mp/dir1\n"); - for (i = 0; i < len; ++i) { - sprintf(path, "/mp/dir1/f%d", i); - r = ext4_fopen(&f, path, "wb"); - if (r != EOK) { - printf("ext4_fopen: rc = %d\n", r); - return false; - } - } - - stop = get_ms(); - diff = stop - start; - test_lwext4_dir_ls("/mp/dir1"); - printf("test_lwext4_dir_test: time: %d ms\n", (int)diff); - printf("test_lwext4_dir_test: av: %d ms/entry\n", (int)diff / (len + 1)); - printf_io_timings(diff); - return true; -} - -static int verify_buf(const unsigned char *b, size_t len, unsigned char c) -{ - size_t i; - for (i = 0; i < len; ++i) { - if (b[i] != c) - return c - b[i]; - } - - return 0; -} - -bool test_lwext4_file_test(uint8_t *rw_buff, uint32_t rw_size, uint32_t rw_count) -{ - int r; - size_t size; - uint32_t i; - long int start; - long int stop; - long int diff; - uint32_t kbps; - uint64_t size_bytes; - - ext4_file f; - - printf("file_test:\n"); - printf(" rw size: %" PRIu32 "\n", rw_size); - printf(" rw count: %" PRIu32 "\n", rw_count); - - /*Add hello world file.*/ - r = ext4_fopen(&f, "/mp/hello.txt", "wb"); - r = ext4_fwrite(&f, "Hello World !\n", strlen("Hello World !\n"), 0); - r = ext4_fclose(&f); - - io_timings_clear(); - start = get_ms(); - r = ext4_fopen(&f, "/mp/test1", "wb"); - if (r != EOK) { - printf("ext4_fopen ERROR = %d\n", r); - return false; - } - - printf("ext4_write: %" PRIu32 " * %" PRIu32 " ...\n", rw_size, - rw_count); - for (i = 0; i < rw_count; ++i) { - - memset(rw_buff, i % 10 + '0', rw_size); - - r = ext4_fwrite(&f, rw_buff, rw_size, &size); - - if ((r != EOK) || (size != rw_size)) - break; - } - - if (i != rw_count) { - printf(" file_test: rw_count = %" PRIu32 "\n", i); - return false; - } - - stop = get_ms(); - diff = stop - start; - size_bytes = rw_size * rw_count; - size_bytes = (size_bytes * 1000) / 1024; - kbps = (size_bytes) / (diff + 1); - printf(" write time: %d ms\n", (int)diff); - printf(" write speed: %" PRIu32 " KB/s\n", kbps); - printf_io_timings(diff); - r = ext4_fclose(&f); - - io_timings_clear(); - start = get_ms(); - r = ext4_fopen(&f, "/mp/test1", "r+"); - if (r != EOK) { - printf("ext4_fopen ERROR = %d\n", r); - return false; - } - - printf("ext4_read: %" PRIu32 " * %" PRIu32 " ...\n", rw_size, rw_count); - - for (i = 0; i < rw_count; ++i) { - r = ext4_fread(&f, rw_buff, rw_size, &size); - - if ((r != EOK) || (size != rw_size)) - break; - - if (verify_buf(rw_buff, rw_size, i % 10 + '0')) - break; - } - - if (i != rw_count) { - printf(" file_test: rw_count = %" PRIu32 "\n", i); - return false; - } - - stop = get_ms(); - diff = stop - start; - size_bytes = rw_size * rw_count; - size_bytes = (size_bytes * 1000) / 1024; - kbps = (size_bytes) / (diff + 1); - printf(" read time: %d ms\n", (int)diff); - printf(" read speed: %d KB/s\n", (int)kbps); - printf_io_timings(diff); - - r = ext4_fclose(&f); - return true; -} -void test_lwext4_cleanup(void) -{ - long int start; - long int stop; - long int diff; - - printf("\ncleanup:\n"); - ext4_fremove("/mp/hello.txt"); - - printf("remove /mp/test1\n"); - ext4_fremove("/mp/test1"); - - printf("remove /mp/dir1\n"); - io_timings_clear(); - start = get_ms(); - ext4_dir_rm("/mp/dir1"); - stop = get_ms(); - diff = stop - start; - printf("cleanup: time: %d ms\n", (int)diff); - printf_io_timings(diff); -} - -bool test_lwext4_mount(struct ext4_blockdev *bdev, struct ext4_bcache *bcache) -{ - int r; - - bc = bcache; - bd = bdev; - - if (!bd) { - printf("test_lwext4_mount: no block device\n"); - return false; - } - - ext4_dmask_set(DEBUG_ALL); - - r = ext4_device_register(bd, bc ? bc : 0, "ext4_fs"); - if (r != EOK) { - printf("ext4_device_register: rc = %d\n", r); - return false; - } - - r = ext4_mount("ext4_fs", "/mp/"); - if (r != EOK) { - printf("ext4_mount: rc = %d\n", r); - return false; - } - - ext4_cache_write_back("/mp/", 1); - return true; -} - -bool test_lwext4_umount(void) -{ - ext4_cache_write_back("/mp/", 0); - int r = ext4_umount("/mp/"); - if (r != EOK) { - printf("ext4_umount: fail %d", r); - return false; - } - return true; -} diff --git a/blockdev/test_lwext4.h b/blockdev/test_lwext4.h deleted file mode 100644 index eca904c..0000000 --- a/blockdev/test_lwext4.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2014 Grzegorz Kostka (kostka.grzegorz@gmail.com) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TEST_LWEXT4_H_ -#define TEST_LWEXT4_H_ - -#include -#include - -void test_lwext4_dir_ls(const char *path); -void test_lwext4_mp_stats(void); -void test_lwext4_block_stats(void); -bool test_lwext4_dir_test(int len); -bool test_lwext4_file_test(uint8_t *rw_buff, uint32_t rw_size, uint32_t rw_count); -void test_lwext4_cleanup(void); - -bool test_lwext4_mount(struct ext4_blockdev *bdev, struct ext4_bcache *bcache); -bool test_lwext4_umount(void); - -void tim_wait_ms(uint32_t v); - -uint32_t tim_get_ms(void); -uint64_t tim_get_us(void); - -struct ext4_io_stats { - float io_read; - float io_write; - float cpu; -}; - -void io_timings_clear(void); -const struct ext4_io_stats *io_timings_get(uint32_t time_sum_ms); - -#endif /* TEST_LWEXT4_H_ */ diff --git a/demos/generic/CMakeLists.txt b/demos/generic/CMakeLists.txt deleted file mode 100644 index 9651e4d..0000000 --- a/demos/generic/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -#Generic demo -add_executable(generic generic.c) -target_link_libraries(generic blockdev) -target_link_libraries(generic lwext4) diff --git a/demos/generic/generic.c b/demos/generic/generic.c deleted file mode 100644 index bf7de19..0000000 --- a/demos/generic/generic.c +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "../../blockdev/linux/ext4_filedev.h" -#include "../../blockdev/windows/io_raw.h" -#include "../../blockdev/test_lwext4.h" - -#ifdef WIN32 -#include -#endif - -/**@brief Input stream name.*/ -char input_name[128] = "ext2"; - -/**@brief Read-write size*/ -static int rw_szie = 1024 * 1024; - -/**@brief Read-write size*/ -static int rw_count = 10; - -/**@brief Directory test count*/ -static int dir_cnt = 0; - -/**@brief Static or dynamic cache mode*/ -static bool cache_mode = true; - -/**@brief Cleanup after test.*/ -static bool cleanup_flag = false; - -/**@brief Block device stats.*/ -static bool bstat = false; - -/**@brief Superblock stats.*/ -static bool sbstat = false; - -/**@brief Indicates that input is windows partition.*/ -static bool winpart = false; - -/**@brief Block device handle.*/ -static struct ext4_blockdev *bd; - -/**@brief Static cache instance*/ -EXT4_BCACHE_STATIC_INSTANCE(_lwext4_cache, CONFIG_BLOCK_DEV_CACHE_SIZE, 1024); - -/**@brief Block cache handle.*/ -static struct ext4_bcache *bc = &_lwext4_cache; - -static const char *usage = " \n\ -Welcome in ext4 generic demo. \n\ -Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com) \n\ -Usage: \n\ -[-i] --input - input file (default = ext2) \n\ -[-w] --rw_size - single R/W size (default = 1024 * 1024) \n\ -[-c] --rw_count - R/W count (default = 10) \n\ -[-a] --cache - 0 static, 1 dynamic (default = 1) \n\ -[-d] --dirs - directory test count (default = 0) \n\ -[-l] --clean - clean up after test \n\ -[-b] --bstat - block device stats \n\ -[-t] --sbstat - superblock stats \n\ -[-w] --wpart - windows partition mode \n\ -\n"; - -void io_timings_clear(void) -{ -} - -const struct ext4_io_stats *io_timings_get(uint32_t time_sum_ms) -{ - return NULL; -} - -uint32_t tim_get_ms(void) -{ - struct timeval t; - gettimeofday(&t, NULL); - return (t.tv_sec * 1000) + (t.tv_usec / 1000); -} - -uint64_t tim_get_us(void) -{ - struct timeval t; - gettimeofday(&t, NULL); - return (t.tv_sec * 1000000) + (t.tv_usec); -} - -static bool open_linux(void) -{ - ext4_filedev_filename(input_name); - bd = ext4_filedev_get(); - if (!bd) { - printf("open_filedev: fail\n"); - return false; - } - return true; -} - -static bool open_windows(void) -{ -#ifdef WIN32 - ext4_io_raw_filename(input_name); - bd = ext4_io_raw_dev_get(); - if (!bd) { - printf("open_winpartition: fail\n"); - return false; - } - return true; -#else - printf("open_winpartition: this mode should be used only under windows " - "!\n"); - return false; -#endif -} - - -static bool parse_opt(int argc, char **argv) -{ - int option_index = 0; - int c; - - static struct option long_options[] = { - {"input", required_argument, 0, 'i'}, - {"rw_size", required_argument, 0, 's'}, - {"rw_count", required_argument, 0, 'c'}, - {"cache", required_argument, 0, 'a'}, - {"dirs", required_argument, 0, 'd'}, - {"clean", no_argument, 0, 'l'}, - {"bstat", no_argument, 0, 'b'}, - {"sbstat", no_argument, 0, 't'}, - {"wpart", no_argument, 0, 'w'}, - {0, 0, 0, 0}}; - - while (-1 != (c = getopt_long(argc, argv, "i:s:c:q:d:lbtw", - long_options, &option_index))) { - - switch (c) { - case 'i': - strcpy(input_name, optarg); - break; - case 's': - rw_szie = atoi(optarg); - break; - case 'c': - rw_count = atoi(optarg); - break; - case 'a': - cache_mode = atoi(optarg); - break; - case 'd': - dir_cnt = atoi(optarg); - break; - case 'l': - cleanup_flag = true; - break; - case 'b': - bstat = true; - break; - case 't': - sbstat = true; - break; - case 'w': - winpart = true; - break; - default: - printf("%s", usage); - return false; - } - } - return true; -} - -int main(int argc, char **argv) -{ - if (!parse_opt(argc, argv)) - return EXIT_FAILURE; - - printf("test conditions:\n"); - printf("\timput name: %s\n", input_name); - printf("\trw size: %d\n", rw_szie); - printf("\trw count: %d\n", rw_count); - printf("\tcache mode: %s\n", cache_mode ? "dynamic" : "static"); - - if (winpart) { - if (!open_windows()) - return EXIT_FAILURE; - } else { - if (!open_linux()) - return EXIT_FAILURE; - } - - - if (!test_lwext4_mount(bd, bc)) - return EXIT_FAILURE; - - test_lwext4_cleanup(); - - if (sbstat) - test_lwext4_mp_stats(); - - test_lwext4_dir_ls("/mp/"); - fflush(stdout); - if (!test_lwext4_dir_test(dir_cnt)) - return EXIT_FAILURE; - - fflush(stdout); - uint8_t *rw_buff = malloc(rw_szie); - if (!rw_buff) - return EXIT_FAILURE; - if (!test_lwext4_file_test(rw_buff, rw_szie, rw_count)) - return EXIT_FAILURE; - - fflush(stdout); - test_lwext4_dir_ls("/mp/"); - - if (sbstat) - test_lwext4_mp_stats(); - - if (cleanup_flag) - test_lwext4_cleanup(); - - if (bstat) - test_lwext4_block_stats(); - - if (!test_lwext4_umount()) - return EXIT_FAILURE; - - printf("\ntest finished\n"); - return EXIT_SUCCESS; -} diff --git a/fs_test/CMakeLists.txt b/fs_test/CMakeLists.txt index 52d1fbc..fe9680f 100644 --- a/fs_test/CMakeLists.txt +++ b/fs_test/CMakeLists.txt @@ -10,3 +10,9 @@ target_link_libraries(lwext4_client lwext4) if(WIN32) target_link_libraries(lwext4_client ws2_32) endif(WIN32) + +aux_source_directory(common COMMON_SRC) +add_executable(lwext4_generic lwext4_generic.c ${COMMON_SRC}) +target_link_libraries(lwext4_generic blockdev) +target_link_libraries(lwext4_generic lwext4) + diff --git a/fs_test/common/test_lwext4.c b/fs_test/common/test_lwext4.c new file mode 100644 index 0000000..aa822f5 --- /dev/null +++ b/fs_test/common/test_lwext4.c @@ -0,0 +1,372 @@ +/* + * Copyright (c) 2014 Grzegorz Kostka (kostka.grzegorz@gmail.com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "../common/test_lwext4.h" + +#include + +#include +#include +#include + + +/**@brief Block device handle.*/ +static struct ext4_blockdev *bd; + +/**@brief Block cache handle.*/ +static struct ext4_bcache *bc; + +static char *entry_to_str(uint8_t type) +{ + switch (type) { + case EXT4_DIRENTRY_UNKNOWN: + return "[unk] "; + case EXT4_DIRENTRY_REG_FILE: + return "[fil] "; + case EXT4_DIRENTRY_DIR: + return "[dir] "; + case EXT4_DIRENTRY_CHRDEV: + return "[cha] "; + case EXT4_DIRENTRY_BLKDEV: + return "[blk] "; + case EXT4_DIRENTRY_FIFO: + return "[fif] "; + case EXT4_DIRENTRY_SOCK: + return "[soc] "; + case EXT4_DIRENTRY_SYMLINK: + return "[sym] "; + default: + break; + } + return "[???]"; +} + +static long int get_ms(void) { return tim_get_ms(); } + +static void printf_io_timings(long int diff) +{ + const struct ext4_io_stats *stats = io_timings_get(diff); + if (!stats) + return; + + printf("io_timings:\n"); + printf(" io_read: %.3f%%\n", (double)stats->io_read); + printf(" io_write: %.3f%%\n", (double)stats->io_write); + printf(" io_cpu: %.3f%%\n", (double)stats->cpu); +} + +void test_lwext4_dir_ls(const char *path) +{ + char sss[255]; + ext4_dir d; + const ext4_direntry *de; + + printf("ls %s\n", path); + + ext4_dir_open(&d, path); + de = ext4_dir_entry_next(&d); + + while (de) { + memcpy(sss, de->name, de->name_length); + sss[de->name_length] = 0; + printf(" %s%s\n", entry_to_str(de->inode_type), sss); + de = ext4_dir_entry_next(&d); + } + ext4_dir_close(&d); +} + +void test_lwext4_mp_stats(void) +{ + struct ext4_mount_stats stats; + ext4_mount_point_stats("/mp/", &stats); + + printf("********************\n"); + printf("ext4_mount_point_stats\n"); + printf("inodes_count = %" PRIu32 "\n", stats.inodes_count); + printf("free_inodes_count = %" PRIu32 "\n", stats.free_inodes_count); + printf("blocks_count = %" PRIu32 "\n", (uint32_t)stats.blocks_count); + printf("free_blocks_count = %" PRIu32 "\n", + (uint32_t)stats.free_blocks_count); + printf("block_size = %" PRIu32 "\n", stats.block_size); + printf("block_group_count = %" PRIu32 "\n", stats.block_group_count); + printf("blocks_per_group= %" PRIu32 "\n", stats.blocks_per_group); + printf("inodes_per_group = %" PRIu32 "\n", stats.inodes_per_group); + printf("volume_name = %s\n", stats.volume_name); + printf("********************\n"); +} + +void test_lwext4_block_stats(void) +{ + if (!bd) + return; + + printf("********************\n"); + printf("ext4 blockdev stats\n"); + printf("bdev->bread_ctr = %" PRIu32 "\n", bd->bread_ctr); + printf("bdev->bwrite_ctr = %" PRIu32 "\n", bd->bwrite_ctr); + + printf("bcache->ref_blocks = %" PRIu32 "\n", bc->ref_blocks); + printf("bcache->max_ref_blocks = %" PRIu32 "\n", bc->max_ref_blocks); + printf("bcache->lru_ctr = %" PRIu32 "\n", bc->lru_ctr); + + printf("\n"); + + uint32_t i; + for (i = 0; i < bc->cnt; ++i) { + printf("bcache->refctr[%" PRIu32 "]= %" PRIu32 "\n", i, + bc->refctr[i]); + } + + printf("\n"); + for (i = 0; i < bc->cnt; ++i) { + printf("bcache->lru_id[%" PRIu32 "] = %" PRIu32 "\n", i, + bc->lru_id[i]); + } + + printf("\n"); + for (i = 0; i < bc->cnt; ++i) { + printf("bcache->free_delay[%" PRIu32 "] = %d\n", i, + bc->free_delay[i]); + } + + printf("\n"); + for (i = 0; i < bc->cnt; ++i) { + printf("bcache->lba[%" PRIu32 "] = %" PRIu32 "\n", i, + (uint32_t)bc->lba[i]); + } + + printf("********************\n"); +} + +bool test_lwext4_dir_test(int len) +{ + ext4_file f; + int r; + int i; + char path[64]; + long int diff; + long int stop; + long int start; + + printf("test_lwext4_dir_test: %d\n", len); + io_timings_clear(); + start = get_ms(); + + printf("directory create: /mp/dir1\n"); + r = ext4_dir_mk("/mp/dir1"); + if (r != EOK) { + printf("ext4_dir_mk: rc = %d\n", r); + return false; + } + + printf("add files to: /mp/dir1\n"); + for (i = 0; i < len; ++i) { + sprintf(path, "/mp/dir1/f%d", i); + r = ext4_fopen(&f, path, "wb"); + if (r != EOK) { + printf("ext4_fopen: rc = %d\n", r); + return false; + } + } + + stop = get_ms(); + diff = stop - start; + test_lwext4_dir_ls("/mp/dir1"); + printf("test_lwext4_dir_test: time: %d ms\n", (int)diff); + printf("test_lwext4_dir_test: av: %d ms/entry\n", (int)diff / (len + 1)); + printf_io_timings(diff); + return true; +} + +static int verify_buf(const unsigned char *b, size_t len, unsigned char c) +{ + size_t i; + for (i = 0; i < len; ++i) { + if (b[i] != c) + return c - b[i]; + } + + return 0; +} + +bool test_lwext4_file_test(uint8_t *rw_buff, uint32_t rw_size, uint32_t rw_count) +{ + int r; + size_t size; + uint32_t i; + long int start; + long int stop; + long int diff; + uint32_t kbps; + uint64_t size_bytes; + + ext4_file f; + + printf("file_test:\n"); + printf(" rw size: %" PRIu32 "\n", rw_size); + printf(" rw count: %" PRIu32 "\n", rw_count); + + /*Add hello world file.*/ + r = ext4_fopen(&f, "/mp/hello.txt", "wb"); + r = ext4_fwrite(&f, "Hello World !\n", strlen("Hello World !\n"), 0); + r = ext4_fclose(&f); + + io_timings_clear(); + start = get_ms(); + r = ext4_fopen(&f, "/mp/test1", "wb"); + if (r != EOK) { + printf("ext4_fopen ERROR = %d\n", r); + return false; + } + + printf("ext4_write: %" PRIu32 " * %" PRIu32 " ...\n", rw_size, + rw_count); + for (i = 0; i < rw_count; ++i) { + + memset(rw_buff, i % 10 + '0', rw_size); + + r = ext4_fwrite(&f, rw_buff, rw_size, &size); + + if ((r != EOK) || (size != rw_size)) + break; + } + + if (i != rw_count) { + printf(" file_test: rw_count = %" PRIu32 "\n", i); + return false; + } + + stop = get_ms(); + diff = stop - start; + size_bytes = rw_size * rw_count; + size_bytes = (size_bytes * 1000) / 1024; + kbps = (size_bytes) / (diff + 1); + printf(" write time: %d ms\n", (int)diff); + printf(" write speed: %" PRIu32 " KB/s\n", kbps); + printf_io_timings(diff); + r = ext4_fclose(&f); + + io_timings_clear(); + start = get_ms(); + r = ext4_fopen(&f, "/mp/test1", "r+"); + if (r != EOK) { + printf("ext4_fopen ERROR = %d\n", r); + return false; + } + + printf("ext4_read: %" PRIu32 " * %" PRIu32 " ...\n", rw_size, rw_count); + + for (i = 0; i < rw_count; ++i) { + r = ext4_fread(&f, rw_buff, rw_size, &size); + + if ((r != EOK) || (size != rw_size)) + break; + + if (verify_buf(rw_buff, rw_size, i % 10 + '0')) + break; + } + + if (i != rw_count) { + printf(" file_test: rw_count = %" PRIu32 "\n", i); + return false; + } + + stop = get_ms(); + diff = stop - start; + size_bytes = rw_size * rw_count; + size_bytes = (size_bytes * 1000) / 1024; + kbps = (size_bytes) / (diff + 1); + printf(" read time: %d ms\n", (int)diff); + printf(" read speed: %d KB/s\n", (int)kbps); + printf_io_timings(diff); + + r = ext4_fclose(&f); + return true; +} +void test_lwext4_cleanup(void) +{ + long int start; + long int stop; + long int diff; + + printf("\ncleanup:\n"); + ext4_fremove("/mp/hello.txt"); + + printf("remove /mp/test1\n"); + ext4_fremove("/mp/test1"); + + printf("remove /mp/dir1\n"); + io_timings_clear(); + start = get_ms(); + ext4_dir_rm("/mp/dir1"); + stop = get_ms(); + diff = stop - start; + printf("cleanup: time: %d ms\n", (int)diff); + printf_io_timings(diff); +} + +bool test_lwext4_mount(struct ext4_blockdev *bdev, struct ext4_bcache *bcache) +{ + int r; + + bc = bcache; + bd = bdev; + + if (!bd) { + printf("test_lwext4_mount: no block device\n"); + return false; + } + + ext4_dmask_set(DEBUG_ALL); + + r = ext4_device_register(bd, bc ? bc : 0, "ext4_fs"); + if (r != EOK) { + printf("ext4_device_register: rc = %d\n", r); + return false; + } + + r = ext4_mount("ext4_fs", "/mp/"); + if (r != EOK) { + printf("ext4_mount: rc = %d\n", r); + return false; + } + + ext4_cache_write_back("/mp/", 1); + return true; +} + +bool test_lwext4_umount(void) +{ + ext4_cache_write_back("/mp/", 0); + int r = ext4_umount("/mp/"); + if (r != EOK) { + printf("ext4_umount: fail %d", r); + return false; + } + return true; +} diff --git a/fs_test/common/test_lwext4.h b/fs_test/common/test_lwext4.h new file mode 100644 index 0000000..bc0c446 --- /dev/null +++ b/fs_test/common/test_lwext4.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2014 Grzegorz Kostka (kostka.grzegorz@gmail.com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef TEST_LWEXT4_H_ +#define TEST_LWEXT4_H_ + +#include +#include +#include + +void test_lwext4_dir_ls(const char *path); +void test_lwext4_mp_stats(void); +void test_lwext4_block_stats(void); +bool test_lwext4_dir_test(int len); +bool test_lwext4_file_test(uint8_t *rw_buff, uint32_t rw_size, uint32_t rw_count); +void test_lwext4_cleanup(void); + +bool test_lwext4_mount(struct ext4_blockdev *bdev, struct ext4_bcache *bcache); +bool test_lwext4_umount(void); + +void tim_wait_ms(uint32_t v); + +uint32_t tim_get_ms(void); +uint64_t tim_get_us(void); + +struct ext4_io_stats { + float io_read; + float io_write; + float cpu; +}; + +void io_timings_clear(void); +const struct ext4_io_stats *io_timings_get(uint32_t time_sum_ms); + +#endif /* TEST_LWEXT4_H_ */ diff --git a/fs_test/lwext4_generic.c b/fs_test/lwext4_generic.c new file mode 100644 index 0000000..4e3cf63 --- /dev/null +++ b/fs_test/lwext4_generic.c @@ -0,0 +1,265 @@ +/* + * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "../blockdev/linux/ext4_filedev.h" +#include "../blockdev/windows/io_raw.h" +#include "common/test_lwext4.h" + +#ifdef WIN32 +#include +#endif + +/**@brief Input stream name.*/ +char input_name[128] = "ext2"; + +/**@brief Read-write size*/ +static int rw_szie = 1024 * 1024; + +/**@brief Read-write size*/ +static int rw_count = 10; + +/**@brief Directory test count*/ +static int dir_cnt = 0; + +/**@brief Static or dynamic cache mode*/ +static bool cache_mode = true; + +/**@brief Cleanup after test.*/ +static bool cleanup_flag = false; + +/**@brief Block device stats.*/ +static bool bstat = false; + +/**@brief Superblock stats.*/ +static bool sbstat = false; + +/**@brief Indicates that input is windows partition.*/ +static bool winpart = false; + +/**@brief Block device handle.*/ +static struct ext4_blockdev *bd; + +/**@brief Static cache instance*/ +EXT4_BCACHE_STATIC_INSTANCE(_lwext4_cache, CONFIG_BLOCK_DEV_CACHE_SIZE, 1024); + +/**@brief Block cache handle.*/ +static struct ext4_bcache *bc = &_lwext4_cache; + +static const char *usage = " \n\ +Welcome in ext4 generic demo. \n\ +Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com) \n\ +Usage: \n\ +[-i] --input - input file (default = ext2) \n\ +[-w] --rw_size - single R/W size (default = 1024 * 1024) \n\ +[-c] --rw_count - R/W count (default = 10) \n\ +[-a] --cache - 0 static, 1 dynamic (default = 1) \n\ +[-d] --dirs - directory test count (default = 0) \n\ +[-l] --clean - clean up after test \n\ +[-b] --bstat - block device stats \n\ +[-t] --sbstat - superblock stats \n\ +[-w] --wpart - windows partition mode \n\ +\n"; + +void io_timings_clear(void) +{ +} + +const struct ext4_io_stats *io_timings_get(uint32_t time_sum_ms) +{ + return NULL; +} + +uint32_t tim_get_ms(void) +{ + struct timeval t; + gettimeofday(&t, NULL); + return (t.tv_sec * 1000) + (t.tv_usec / 1000); +} + +uint64_t tim_get_us(void) +{ + struct timeval t; + gettimeofday(&t, NULL); + return (t.tv_sec * 1000000) + (t.tv_usec); +} + +static bool open_linux(void) +{ + ext4_filedev_filename(input_name); + bd = ext4_filedev_get(); + if (!bd) { + printf("open_filedev: fail\n"); + return false; + } + return true; +} + +static bool open_windows(void) +{ +#ifdef WIN32 + ext4_io_raw_filename(input_name); + bd = ext4_io_raw_dev_get(); + if (!bd) { + printf("open_winpartition: fail\n"); + return false; + } + return true; +#else + printf("open_winpartition: this mode should be used only under windows " + "!\n"); + return false; +#endif +} + + +static bool parse_opt(int argc, char **argv) +{ + int option_index = 0; + int c; + + static struct option long_options[] = { + {"input", required_argument, 0, 'i'}, + {"rw_size", required_argument, 0, 's'}, + {"rw_count", required_argument, 0, 'c'}, + {"cache", required_argument, 0, 'a'}, + {"dirs", required_argument, 0, 'd'}, + {"clean", no_argument, 0, 'l'}, + {"bstat", no_argument, 0, 'b'}, + {"sbstat", no_argument, 0, 't'}, + {"wpart", no_argument, 0, 'w'}, + {0, 0, 0, 0}}; + + while (-1 != (c = getopt_long(argc, argv, "i:s:c:q:d:lbtw", + long_options, &option_index))) { + + switch (c) { + case 'i': + strcpy(input_name, optarg); + break; + case 's': + rw_szie = atoi(optarg); + break; + case 'c': + rw_count = atoi(optarg); + break; + case 'a': + cache_mode = atoi(optarg); + break; + case 'd': + dir_cnt = atoi(optarg); + break; + case 'l': + cleanup_flag = true; + break; + case 'b': + bstat = true; + break; + case 't': + sbstat = true; + break; + case 'w': + winpart = true; + break; + default: + printf("%s", usage); + return false; + } + } + return true; +} + +int main(int argc, char **argv) +{ + if (!parse_opt(argc, argv)) + return EXIT_FAILURE; + + printf("test conditions:\n"); + printf("\timput name: %s\n", input_name); + printf("\trw size: %d\n", rw_szie); + printf("\trw count: %d\n", rw_count); + printf("\tcache mode: %s\n", cache_mode ? "dynamic" : "static"); + + if (winpart) { + if (!open_windows()) + return EXIT_FAILURE; + } else { + if (!open_linux()) + return EXIT_FAILURE; + } + + + if (!test_lwext4_mount(bd, bc)) + return EXIT_FAILURE; + + test_lwext4_cleanup(); + + if (sbstat) + test_lwext4_mp_stats(); + + test_lwext4_dir_ls("/mp/"); + fflush(stdout); + if (!test_lwext4_dir_test(dir_cnt)) + return EXIT_FAILURE; + + fflush(stdout); + uint8_t *rw_buff = malloc(rw_szie); + if (!rw_buff) + return EXIT_FAILURE; + if (!test_lwext4_file_test(rw_buff, rw_szie, rw_count)) + return EXIT_FAILURE; + + fflush(stdout); + test_lwext4_dir_ls("/mp/"); + + if (sbstat) + test_lwext4_mp_stats(); + + if (cleanup_flag) + test_lwext4_cleanup(); + + if (bstat) + test_lwext4_block_stats(); + + if (!test_lwext4_umount()) + return EXIT_FAILURE; + + printf("\ntest finished\n"); + return EXIT_SUCCESS; +}