You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2016/09/13 03:42:32 UTC
[39/41] incubator-mynewt-core git commit: syscfg / sysinit
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/d98ddc1c/fs/nffs/src/test/arch/sim/nffs_test.c
----------------------------------------------------------------------
diff --git a/fs/nffs/src/test/arch/sim/nffs_test.c b/fs/nffs/src/test/arch/sim/nffs_test.c
deleted file mode 100644
index a61b4bc..0000000
--- a/fs/nffs/src/test/arch/sim/nffs_test.c
+++ /dev/null
@@ -1,3250 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-#include <stdlib.h>
-#include <errno.h>
-#include "hal/hal_flash.h"
-#include "testutil/testutil.h"
-#include "fs/fs.h"
-#include "nffs/nffs.h"
-#include "nffs/nffs_test.h"
-#include "nffs_test_priv.h"
-#include "nffs_priv.h"
-
-int flash_native_memset(uint32_t offset, uint8_t c, uint32_t len);
-
-static const struct nffs_area_desc nffs_area_descs[] = {
- { 0x00000000, 16 * 1024 },
- { 0x00004000, 16 * 1024 },
- { 0x00008000, 16 * 1024 },
- { 0x0000c000, 16 * 1024 },
- { 0x00010000, 64 * 1024 },
- { 0x00020000, 128 * 1024 },
- { 0x00040000, 128 * 1024 },
- { 0x00060000, 128 * 1024 },
- { 0x00080000, 128 * 1024 },
- { 0x000a0000, 128 * 1024 },
- { 0x000c0000, 128 * 1024 },
- { 0x000e0000, 128 * 1024 },
- { 0, 0 },
-};
-
-static void
-nffs_test_util_assert_ent_name(struct fs_dirent *dirent,
- const char *expected_name)
-{
- char name[NFFS_FILENAME_MAX_LEN + 1];
- uint8_t name_len;
- int rc;
-
- rc = fs_dirent_name(dirent, sizeof name, name, &name_len);
- TEST_ASSERT(rc == 0);
- if (rc == 0) {
- TEST_ASSERT(strcmp(name, expected_name) == 0);
- }
-}
-
-static void
-nffs_test_util_assert_file_len(struct fs_file *file, uint32_t expected)
-{
- uint32_t len;
- int rc;
-
- rc = fs_filelen(file, &len);
- TEST_ASSERT(rc == 0);
- TEST_ASSERT(len == expected);
-}
-
-static void
-nffs_test_util_assert_cache_is_sane(const char *filename)
-{
- struct nffs_cache_inode *cache_inode;
- struct nffs_cache_block *cache_block;
- struct fs_file *fs_file;
- struct nffs_file *file;
- uint32_t cache_start;
- uint32_t cache_end;
- uint32_t block_end;
- int rc;
-
- rc = fs_open(filename, FS_ACCESS_READ, &fs_file);
- TEST_ASSERT(rc == 0);
-
- file = (struct nffs_file *)fs_file;
- rc = nffs_cache_inode_ensure(&cache_inode, file->nf_inode_entry);
- TEST_ASSERT(rc == 0);
-
- nffs_cache_inode_range(cache_inode, &cache_start, &cache_end);
-
- if (TAILQ_EMPTY(&cache_inode->nci_block_list)) {
- TEST_ASSERT(cache_start == 0 && cache_end == 0);
- } else {
- block_end = 0; /* Pacify gcc. */
- TAILQ_FOREACH(cache_block, &cache_inode->nci_block_list, ncb_link) {
- if (cache_block == TAILQ_FIRST(&cache_inode->nci_block_list)) {
- TEST_ASSERT(cache_block->ncb_file_offset == cache_start);
- } else {
- /* Ensure no gap between this block and its predecessor. */
- TEST_ASSERT(cache_block->ncb_file_offset == block_end);
- }
-
- block_end = cache_block->ncb_file_offset +
- cache_block->ncb_block.nb_data_len;
- if (cache_block == TAILQ_LAST(&cache_inode->nci_block_list,
- nffs_cache_block_list)) {
-
- TEST_ASSERT(block_end == cache_end);
- }
- }
- }
-
- rc = fs_close(fs_file);
- TEST_ASSERT(rc == 0);
-}
-
-static void
-nffs_test_util_assert_contents(const char *filename, const char *contents,
- int contents_len)
-{
- struct fs_file *file;
- uint32_t bytes_read;
- void *buf;
- int rc;
-
- rc = fs_open(filename, FS_ACCESS_READ, &file);
- TEST_ASSERT(rc == 0);
-
- buf = malloc(contents_len + 1);
- TEST_ASSERT(buf != NULL);
-
- rc = fs_read(file, contents_len + 1, buf, &bytes_read);
- TEST_ASSERT(rc == 0);
- TEST_ASSERT(bytes_read == contents_len);
- TEST_ASSERT(memcmp(buf, contents, contents_len) == 0);
-
- rc = fs_close(file);
- TEST_ASSERT(rc == 0);
-
- free(buf);
-
- nffs_test_util_assert_cache_is_sane(filename);
-}
-
-static int
-nffs_test_util_block_count(const char *filename)
-{
- struct nffs_hash_entry *entry;
- struct nffs_block block;
- struct nffs_file *file;
- struct fs_file *fs_file;
- int count;
- int rc;
-
- rc = fs_open(filename, FS_ACCESS_READ, &fs_file);
- TEST_ASSERT(rc == 0);
-
- file = (struct nffs_file *)fs_file;
- count = 0;
- entry = file->nf_inode_entry->nie_last_block_entry;
- while (entry != NULL) {
- count++;
- rc = nffs_block_from_hash_entry(&block, entry);
- TEST_ASSERT(rc == 0);
- TEST_ASSERT(block.nb_prev != entry);
- entry = block.nb_prev;
- }
-
- rc = fs_close(fs_file);
- TEST_ASSERT(rc == 0);
-
- return count;
-}
-
-static void
-nffs_test_util_assert_block_count(const char *filename, int expected_count)
-{
- int actual_count;
-
- actual_count = nffs_test_util_block_count(filename);
- TEST_ASSERT(actual_count == expected_count);
-}
-
-static void
-nffs_test_util_assert_cache_range(const char *filename,
- uint32_t expected_cache_start,
- uint32_t expected_cache_end)
-{
- struct nffs_cache_inode *cache_inode;
- struct nffs_file *file;
- struct fs_file *fs_file;
- uint32_t cache_start;
- uint32_t cache_end;
- int rc;
-
- rc = fs_open(filename, FS_ACCESS_READ, &fs_file);
- TEST_ASSERT(rc == 0);
-
- file = (struct nffs_file *)fs_file;
- rc = nffs_cache_inode_ensure(&cache_inode, file->nf_inode_entry);
- TEST_ASSERT(rc == 0);
-
- nffs_cache_inode_range(cache_inode, &cache_start, &cache_end);
- TEST_ASSERT(cache_start == expected_cache_start);
- TEST_ASSERT(cache_end == expected_cache_end);
-
- rc = fs_close(fs_file);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_assert_cache_is_sane(filename);
-}
-
-static void
-nffs_test_util_create_file_blocks(const char *filename,
- const struct nffs_test_block_desc *blocks,
- int num_blocks)
-{
- struct fs_file *file;
- uint32_t total_len;
- uint32_t offset;
- char *buf;
- int num_writes;
- int rc;
- int i;
-
- rc = fs_open(filename, FS_ACCESS_WRITE | FS_ACCESS_TRUNCATE, &file);
- TEST_ASSERT(rc == 0);
-
- total_len = 0;
- if (num_blocks <= 0) {
- num_writes = 1;
- } else {
- num_writes = num_blocks;
- }
- for (i = 0; i < num_writes; i++) {
- rc = fs_write(file, blocks[i].data, blocks[i].data_len);
- TEST_ASSERT(rc == 0);
-
- total_len += blocks[i].data_len;
- }
-
- rc = fs_close(file);
- TEST_ASSERT(rc == 0);
-
- buf = malloc(total_len);
- TEST_ASSERT(buf != NULL);
-
- offset = 0;
- for (i = 0; i < num_writes; i++) {
- memcpy(buf + offset, blocks[i].data, blocks[i].data_len);
- offset += blocks[i].data_len;
- }
- TEST_ASSERT(offset == total_len);
-
- nffs_test_util_assert_contents(filename, buf, total_len);
- if (num_blocks > 0) {
- nffs_test_util_assert_block_count(filename, num_blocks);
- }
-
- free(buf);
-}
-
-static void
-nffs_test_util_create_file(const char *filename, const char *contents,
- int contents_len)
-{
- struct nffs_test_block_desc block;
-
- block.data = contents;
- block.data_len = contents_len;
-
- nffs_test_util_create_file_blocks(filename, &block, 0);
-}
-
-static void
-nffs_test_util_append_file(const char *filename, const char *contents,
- int contents_len)
-{
- struct fs_file *file;
- int rc;
-
- rc = fs_open(filename, FS_ACCESS_WRITE | FS_ACCESS_APPEND, &file);
- TEST_ASSERT(rc == 0);
-
- rc = fs_write(file, contents, contents_len);
- TEST_ASSERT(rc == 0);
-
- rc = fs_close(file);
- TEST_ASSERT(rc == 0);
-}
-
-static void
-nffs_test_copy_area(const struct nffs_area_desc *from,
- const struct nffs_area_desc *to)
-{
- void *buf;
- int rc;
-
- TEST_ASSERT(from->nad_length == to->nad_length);
-
- buf = malloc(from->nad_length);
- TEST_ASSERT(buf != NULL);
-
- rc = hal_flash_read(from->nad_flash_id, from->nad_offset, buf,
- from->nad_length);
- TEST_ASSERT(rc == 0);
-
- rc = hal_flash_erase(from->nad_flash_id, to->nad_offset, to->nad_length);
- TEST_ASSERT(rc == 0);
-
- rc = hal_flash_write(to->nad_flash_id, to->nad_offset, buf, to->nad_length);
- TEST_ASSERT(rc == 0);
-
- free(buf);
-}
-
-static void
-nffs_test_util_create_subtree(const char *parent_path,
- const struct nffs_test_file_desc *elem)
-{
- char *path;
- int rc;
- int i;
-
- if (parent_path == NULL) {
- path = malloc(1);
- TEST_ASSERT(path != NULL);
- path[0] = '\0';
- } else {
- path = malloc(strlen(parent_path) + 1 + strlen(elem->filename) + 1);
- TEST_ASSERT(path != NULL);
-
- sprintf(path, "%s/%s", parent_path, elem->filename);
- }
-
- if (elem->is_dir) {
- if (parent_path != NULL) {
- rc = fs_mkdir(path);
- TEST_ASSERT(rc == 0);
- }
-
- if (elem->children != NULL) {
- for (i = 0; elem->children[i].filename != NULL; i++) {
- nffs_test_util_create_subtree(path, elem->children + i);
- }
- }
- } else {
- nffs_test_util_create_file(path, elem->contents, elem->contents_len);
- }
-
- free(path);
-}
-
-static void
-nffs_test_util_create_tree(const struct nffs_test_file_desc *root_dir)
-{
- nffs_test_util_create_subtree(NULL, root_dir);
-}
-
-#define NFFS_TEST_TOUCHED_ARR_SZ (16 * 1024)
-static struct nffs_hash_entry
- *nffs_test_touched_entries[NFFS_TEST_TOUCHED_ARR_SZ];
-static int nffs_test_num_touched_entries;
-
-/*
- * Recursively descend directory structure
- */
-static void
-nffs_test_assert_file(const struct nffs_test_file_desc *file,
- struct nffs_inode_entry *inode_entry,
- const char *path)
-{
- const struct nffs_test_file_desc *child_file;
- struct nffs_inode inode;
- struct nffs_inode_entry *child_inode_entry;
- char *child_path;
- int child_filename_len;
- int path_len;
- int rc;
-
- /*
- * track of hash entries that have been examined
- */
- TEST_ASSERT(nffs_test_num_touched_entries < NFFS_TEST_TOUCHED_ARR_SZ);
- nffs_test_touched_entries[nffs_test_num_touched_entries] =
- &inode_entry->nie_hash_entry;
- nffs_test_num_touched_entries++;
-
- path_len = strlen(path);
-
- rc = nffs_inode_from_entry(&inode, inode_entry);
- TEST_ASSERT(rc == 0);
-
- /*
- * recursively examine each child of directory
- */
- if (nffs_hash_id_is_dir(inode_entry->nie_hash_entry.nhe_id)) {
- for (child_file = file->children;
- child_file != NULL && child_file->filename != NULL;
- child_file++) {
-
- /*
- * Construct full pathname for file
- * Not null terminated
- */
- child_filename_len = strlen(child_file->filename);
- child_path = malloc(path_len + 1 + child_filename_len + 1);
- TEST_ASSERT(child_path != NULL);
- memcpy(child_path, path, path_len);
- child_path[path_len] = '/';
- memcpy(child_path + path_len + 1, child_file->filename,
- child_filename_len);
- child_path[path_len + 1 + child_filename_len] = '\0';
-
- /*
- * Verify child inode can be found using full pathname
- */
- rc = nffs_path_find_inode_entry(child_path, &child_inode_entry);
- if (rc != 0) {
- TEST_ASSERT(rc == 0);
- }
-
- nffs_test_assert_file(child_file, child_inode_entry, child_path);
-
- free(child_path);
- }
- } else {
- nffs_test_util_assert_contents(path, file->contents,
- file->contents_len);
- }
-}
-
-static void
-nffs_test_assert_branch_touched(struct nffs_inode_entry *inode_entry)
-{
- struct nffs_inode_entry *child;
- int i;
-
- if (inode_entry == nffs_lost_found_dir) {
- return;
- }
-
- for (i = 0; i < nffs_test_num_touched_entries; i++) {
- if (nffs_test_touched_entries[i] == &inode_entry->nie_hash_entry) {
- break;
- }
- }
- TEST_ASSERT(i < nffs_test_num_touched_entries);
- nffs_test_touched_entries[i] = NULL;
-
- if (nffs_hash_id_is_dir(inode_entry->nie_hash_entry.nhe_id)) {
- SLIST_FOREACH(child, &inode_entry->nie_child_list, nie_sibling_next) {
- nffs_test_assert_branch_touched(child);
- }
- }
-}
-
-static void
-nffs_test_assert_child_inode_present(struct nffs_inode_entry *child)
-{
- const struct nffs_inode_entry *inode_entry;
- const struct nffs_inode_entry *parent;
- struct nffs_inode inode;
- int rc;
-
- /*
- * Sucessfully read inode data from flash
- */
- rc = nffs_inode_from_entry(&inode, child);
- TEST_ASSERT(rc == 0);
-
- /*
- * Validate parent
- */
- parent = inode.ni_parent;
- TEST_ASSERT(parent != NULL);
- TEST_ASSERT(nffs_hash_id_is_dir(parent->nie_hash_entry.nhe_id));
-
- /*
- * Make sure inode is in parents child list
- */
- SLIST_FOREACH(inode_entry, &parent->nie_child_list, nie_sibling_next) {
- if (inode_entry == child) {
- return;
- }
- }
-
- TEST_ASSERT(0);
-}
-
-static void
-nffs_test_assert_block_present(struct nffs_hash_entry *block_entry)
-{
- const struct nffs_inode_entry *inode_entry;
- struct nffs_hash_entry *cur;
- struct nffs_block block;
- int rc;
-
- /*
- * Successfully read block data from flash
- */
- rc = nffs_block_from_hash_entry(&block, block_entry);
- TEST_ASSERT(rc == 0);
-
- /*
- * Validate owning inode
- */
- inode_entry = block.nb_inode_entry;
- TEST_ASSERT(inode_entry != NULL);
- TEST_ASSERT(nffs_hash_id_is_file(inode_entry->nie_hash_entry.nhe_id));
-
- /*
- * Validate that block is in owning inode's block chain
- */
- cur = inode_entry->nie_last_block_entry;
- while (cur != NULL) {
- if (cur == block_entry) {
- return;
- }
-
- rc = nffs_block_from_hash_entry(&block, cur);
- TEST_ASSERT(rc == 0);
- cur = block.nb_prev;
- }
-
- TEST_ASSERT(0);
-}
-
-/*
- * Recursively verify that the children of each directory are sorted
- * on the directory children linked list by filename length
- */
-static void
-nffs_test_assert_children_sorted(struct nffs_inode_entry *inode_entry)
-{
- struct nffs_inode_entry *child_entry;
- struct nffs_inode_entry *prev_entry;
- struct nffs_inode child_inode;
- struct nffs_inode prev_inode;
- int cmp;
- int rc;
-
- prev_entry = NULL;
- SLIST_FOREACH(child_entry, &inode_entry->nie_child_list,
- nie_sibling_next) {
- rc = nffs_inode_from_entry(&child_inode, child_entry);
- TEST_ASSERT(rc == 0);
-
- if (prev_entry != NULL) {
- rc = nffs_inode_from_entry(&prev_inode, prev_entry);
- TEST_ASSERT(rc == 0);
-
- rc = nffs_inode_filename_cmp_flash(&prev_inode, &child_inode,
- &cmp);
- TEST_ASSERT(rc == 0);
- TEST_ASSERT(cmp < 0);
- }
-
- if (nffs_hash_id_is_dir(child_entry->nie_hash_entry.nhe_id)) {
- nffs_test_assert_children_sorted(child_entry);
- }
-
- prev_entry = child_entry;
- }
-}
-
-static void
-nffs_test_assert_system_once(const struct nffs_test_file_desc *root_dir)
-{
- struct nffs_inode_entry *inode_entry;
- struct nffs_hash_entry *entry;
- struct nffs_hash_entry *next;
- int i;
-
- nffs_test_num_touched_entries = 0;
- nffs_test_assert_file(root_dir, nffs_root_dir, "");
- nffs_test_assert_branch_touched(nffs_root_dir);
-
- /* Ensure no orphaned inodes or blocks. */
- NFFS_HASH_FOREACH(entry, i, next) {
- TEST_ASSERT(entry->nhe_flash_loc != NFFS_FLASH_LOC_NONE);
- if (nffs_hash_id_is_inode(entry->nhe_id)) {
- inode_entry = (void *)entry;
- TEST_ASSERT(inode_entry->nie_refcnt == 1);
- if (entry->nhe_id == NFFS_ID_ROOT_DIR) {
- TEST_ASSERT(inode_entry == nffs_root_dir);
- } else {
- nffs_test_assert_child_inode_present(inode_entry);
- }
- } else {
- nffs_test_assert_block_present(entry);
- }
- }
-
- /* Ensure proper sorting. */
- nffs_test_assert_children_sorted(nffs_root_dir);
-}
-
-static void
-nffs_test_assert_system(const struct nffs_test_file_desc *root_dir,
- const struct nffs_area_desc *area_descs)
-{
- int rc;
-
- /* Ensure files are as specified, and that there are no other files or
- * orphaned inodes / blocks.
- */
- nffs_test_assert_system_once(root_dir);
-
- /* Force a garbage collection cycle. */
- rc = nffs_gc(NULL);
- TEST_ASSERT(rc == 0);
-
- /* Ensure file system is still as expected. */
- nffs_test_assert_system_once(root_dir);
-
- /* Clear cached data and restore from flash (i.e, simulate a reboot). */
- rc = nffs_misc_reset();
- TEST_ASSERT(rc == 0);
- rc = nffs_detect(area_descs);
- TEST_ASSERT(rc == 0);
-
- /* Ensure file system is still as expected. */
- nffs_test_assert_system_once(root_dir);
-}
-
-static void
-nffs_test_assert_area_seqs(int seq1, int count1, int seq2, int count2)
-{
- struct nffs_disk_area disk_area;
- int cur1;
- int cur2;
- int rc;
- int i;
-
- cur1 = 0;
- cur2 = 0;
-
- for (i = 0; i < nffs_num_areas; i++) {
- rc = nffs_flash_read(i, 0, &disk_area, sizeof disk_area);
- TEST_ASSERT(rc == 0);
- TEST_ASSERT(nffs_area_magic_is_set(&disk_area));
- TEST_ASSERT(disk_area.nda_gc_seq == nffs_areas[i].na_gc_seq);
- if (i == nffs_scratch_area_idx) {
- TEST_ASSERT(disk_area.nda_id == NFFS_AREA_ID_NONE);
- }
-
- if (nffs_areas[i].na_gc_seq == seq1) {
- cur1++;
- } else if (nffs_areas[i].na_gc_seq == seq2) {
- cur2++;
- } else {
- TEST_ASSERT(0);
- }
- }
-
- TEST_ASSERT(cur1 == count1 && cur2 == count2);
-}
-
-static void
-nffs_test_mkdir(void)
-{
- struct fs_file *file;
- int rc;
-
-
- rc = nffs_format(nffs_area_descs);
- TEST_ASSERT(rc == 0);
-
- rc = fs_mkdir("/a/b/c/d");
- TEST_ASSERT(rc == FS_ENOENT);
-
- rc = fs_mkdir("asdf");
- TEST_ASSERT(rc == FS_EINVAL);
-
- rc = fs_mkdir("/a");
- TEST_ASSERT(rc == 0);
-
- rc = fs_mkdir("/a/b");
- TEST_ASSERT(rc == 0);
-
- rc = fs_mkdir("/a/b/c");
- TEST_ASSERT(rc == 0);
-
- rc = fs_mkdir("/a/b/c/d");
- TEST_ASSERT(rc == 0);
-
- rc = fs_open("/a/b/c/d/myfile.txt", FS_ACCESS_WRITE, &file);
- TEST_ASSERT(rc == 0);
-
- rc = fs_close(file);
- TEST_ASSERT(rc == 0);
-
- struct nffs_test_file_desc *expected_system =
- (struct nffs_test_file_desc[]) { {
- .filename = "",
- .is_dir = 1,
- .children = (struct nffs_test_file_desc[]) { {
- .filename = "a",
- .is_dir = 1,
- .children = (struct nffs_test_file_desc[]) { {
- .filename = "b",
- .is_dir = 1,
- .children = (struct nffs_test_file_desc[]) { {
- .filename = "c",
- .is_dir = 1,
- .children = (struct nffs_test_file_desc[]) { {
- .filename = "d",
- .is_dir = 1,
- .children = (struct nffs_test_file_desc[]) { {
- .filename = "myfile.txt",
- .contents = NULL,
- .contents_len = 0,
- }, {
- .filename = NULL,
- } },
- }, {
- .filename = NULL,
- } },
- }, {
- .filename = NULL,
- } },
- }, {
- .filename = NULL,
- } },
- }, {
- .filename = NULL,
- } },
- } };
-
- nffs_test_assert_system(expected_system, nffs_area_descs);
-}
-
-TEST_CASE(nffs_test_unlink)
-{
- struct fs_file *file0;
- struct fs_file *file1;
- struct fs_file *file2;
- struct nffs_file *nfs_file;
- uint8_t buf[64];
- uint32_t bytes_read;
- int initial_num_blocks;
- int initial_num_inodes;
- int rc;
-
- rc = nffs_format(nffs_area_descs);
- TEST_ASSERT_FATAL(rc == 0);
-
- initial_num_blocks = nffs_block_entry_pool.mp_num_free;
- initial_num_inodes = nffs_inode_entry_pool.mp_num_free;
-
- nffs_test_util_create_file("/file0.txt", "0", 1);
-
- rc = fs_open("/file0.txt", FS_ACCESS_READ | FS_ACCESS_WRITE, &file0);
- TEST_ASSERT(rc == 0);
- nfs_file = (struct nffs_file *)file0;
- TEST_ASSERT(nfs_file->nf_inode_entry->nie_refcnt == 2);
-
- rc = fs_unlink("/file0.txt");
- TEST_ASSERT(rc == 0);
- TEST_ASSERT(nfs_file->nf_inode_entry->nie_refcnt == 1);
-
- rc = fs_open("/file0.txt", FS_ACCESS_READ, &file2);
- TEST_ASSERT(rc == FS_ENOENT);
-
- rc = fs_write(file0, "00", 2);
- TEST_ASSERT(rc == 0);
-
- rc = fs_seek(file0, 0);
- TEST_ASSERT(rc == 0);
-
- rc = fs_read(file0, sizeof buf, buf, &bytes_read);
- TEST_ASSERT(rc == 0);
- TEST_ASSERT(bytes_read == 2);
- TEST_ASSERT(memcmp(buf, "00", 2) == 0);
-
- rc = fs_close(file0);
- TEST_ASSERT(rc == 0);
-
- rc = fs_open("/file0.txt", FS_ACCESS_READ, &file0);
- TEST_ASSERT(rc == FS_ENOENT);
-
- /* Ensure the file was fully removed from RAM. */
- TEST_ASSERT(nffs_inode_entry_pool.mp_num_free == initial_num_inodes);
- TEST_ASSERT(nffs_block_entry_pool.mp_num_free == initial_num_blocks);
-
- /*** Nested unlink. */
- rc = fs_mkdir("/mydir");
- TEST_ASSERT(rc == 0);
- nffs_test_util_create_file("/mydir/file1.txt", "1", 2);
-
- rc = fs_open("/mydir/file1.txt", FS_ACCESS_READ | FS_ACCESS_WRITE, &file1);
- TEST_ASSERT(rc == 0);
- nfs_file = (struct nffs_file *)file1;
- TEST_ASSERT(nfs_file->nf_inode_entry->nie_refcnt == 2);
-
- rc = fs_unlink("/mydir");
- TEST_ASSERT(rc == 0);
- TEST_ASSERT(nfs_file->nf_inode_entry->nie_refcnt == 1);
-
- rc = fs_open("/mydir/file1.txt", FS_ACCESS_READ, &file2);
- TEST_ASSERT(rc == FS_ENOENT);
-
- rc = fs_write(file1, "11", 2);
- TEST_ASSERT(rc == 0);
-
- rc = fs_seek(file1, 0);
- TEST_ASSERT(rc == 0);
-
- rc = fs_read(file1, sizeof buf, buf, &bytes_read);
- TEST_ASSERT(rc == 0);
- TEST_ASSERT(bytes_read == 2);
- TEST_ASSERT(memcmp(buf, "11", 2) == 0);
-
- rc = fs_close(file1);
- TEST_ASSERT(rc == 0);
-
- rc = fs_open("/mydir/file1.txt", FS_ACCESS_READ, &file1);
- TEST_ASSERT(rc == FS_ENOENT);
-
- struct nffs_test_file_desc *expected_system =
- (struct nffs_test_file_desc[]) { {
- .filename = "",
- .is_dir = 1,
- } };
-
- nffs_test_assert_system(expected_system, nffs_area_descs);
-
- /* Ensure the files and directories were fully removed from RAM. */
- TEST_ASSERT(nffs_inode_entry_pool.mp_num_free == initial_num_inodes);
- TEST_ASSERT(nffs_block_entry_pool.mp_num_free == initial_num_blocks);
-}
-
-TEST_CASE(nffs_test_rename)
-{
- struct fs_file *file;
- const char contents[] = "contents";
- int rc;
-
-
- rc = nffs_format(nffs_area_descs);
- TEST_ASSERT(rc == 0);
-
- rc = fs_rename("/nonexistent.txt", "/newname.txt");
- TEST_ASSERT(rc == FS_ENOENT);
-
- /*** Rename file. */
- nffs_test_util_create_file("/myfile.txt", contents, sizeof contents);
-
- rc = fs_rename("/myfile.txt", "badname");
- TEST_ASSERT(rc == FS_EINVAL);
-
- rc = fs_rename("/myfile.txt", "/myfile2.txt");
- TEST_ASSERT(rc == 0);
-
- rc = fs_open("/myfile.txt", FS_ACCESS_READ, &file);
- TEST_ASSERT(rc == FS_ENOENT);
-
- nffs_test_util_assert_contents("/myfile2.txt", contents, sizeof contents);
-
- rc = fs_mkdir("/mydir");
- TEST_ASSERT(rc == 0);
-
- rc = fs_mkdir("/mydir/leafdir");
- TEST_ASSERT(rc == 0);
-
- rc = fs_rename("/myfile2.txt", "/mydir/myfile2.txt");
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_assert_contents("/mydir/myfile2.txt", contents,
- sizeof contents);
-
- /*** Rename directory. */
- rc = fs_rename("/mydir", "badname");
- TEST_ASSERT(rc == FS_EINVAL);
-
- /* Don't allow a directory to be moved into a descendent directory. */
- rc = fs_rename("/mydir", "/mydir/leafdir/a");
- TEST_ASSERT(rc == FS_EINVAL);
-
- rc = fs_rename("/mydir", "/mydir2");
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_assert_contents("/mydir2/myfile2.txt", contents,
- sizeof contents);
-
- struct nffs_test_file_desc *expected_system =
- (struct nffs_test_file_desc[]) { {
- .filename = "",
- .is_dir = 1,
- .children = (struct nffs_test_file_desc[]) { {
- .filename = "mydir2",
- .is_dir = 1,
- .children = (struct nffs_test_file_desc[]) { {
- .filename = "leafdir",
- .is_dir = 1,
- }, {
- .filename = "myfile2.txt",
- .contents = "contents",
- .contents_len = 9,
- }, {
- .filename = NULL,
- } },
- }, {
- .filename = NULL,
- } },
- } };
-
- nffs_test_assert_system(expected_system, nffs_area_descs);
-}
-
-TEST_CASE(nffs_test_truncate)
-{
- struct fs_file *file;
- int rc;
-
-
- rc = nffs_format(nffs_area_descs);
- TEST_ASSERT(rc == 0);
-
- rc = fs_open("/myfile.txt", FS_ACCESS_WRITE | FS_ACCESS_TRUNCATE, &file);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 0);
- TEST_ASSERT(fs_getpos(file) == 0);
-
- rc = fs_write(file, "abcdefgh", 8);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 8);
- TEST_ASSERT(fs_getpos(file) == 8);
- rc = fs_close(file);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_assert_contents("/myfile.txt", "abcdefgh", 8);
-
- rc = fs_open("/myfile.txt", FS_ACCESS_WRITE | FS_ACCESS_TRUNCATE, &file);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 0);
- TEST_ASSERT(fs_getpos(file) == 0);
-
- rc = fs_write(file, "1234", 4);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 4);
- TEST_ASSERT(fs_getpos(file) == 4);
- rc = fs_close(file);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_assert_contents("/myfile.txt", "1234", 4);
-
- struct nffs_test_file_desc *expected_system =
- (struct nffs_test_file_desc[]) { {
- .filename = "",
- .is_dir = 1,
- .children = (struct nffs_test_file_desc[]) { {
- .filename = "myfile.txt",
- .contents = "1234",
- .contents_len = 4,
- }, {
- .filename = NULL,
- } },
- } };
-
- nffs_test_assert_system(expected_system, nffs_area_descs);
-}
-
-TEST_CASE(nffs_test_append)
-{
- struct fs_file *file;
- uint32_t len;
- char c;
- int rc;
- int i;
-
- rc = nffs_format(nffs_area_descs);
- TEST_ASSERT(rc == 0);
-
- rc = fs_open("/myfile.txt", FS_ACCESS_WRITE | FS_ACCESS_APPEND, &file);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 0);
- TEST_ASSERT(fs_getpos(file) == 0);
-
- rc = fs_write(file, "abcdefgh", 8);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 8);
- TEST_ASSERT(fs_getpos(file) == 8);
- rc = fs_close(file);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_assert_contents("/myfile.txt", "abcdefgh", 8);
-
- rc = fs_open("/myfile.txt", FS_ACCESS_WRITE | FS_ACCESS_APPEND, &file);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 8);
- TEST_ASSERT(fs_getpos(file) == 8);
-
- /* File position should always be at the end of a file after an append.
- * Seek to the middle prior to writing to test this.
- */
- rc = fs_seek(file, 2);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 8);
- TEST_ASSERT(fs_getpos(file) == 2);
-
- rc = fs_write(file, "ijklmnop", 8);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 16);
- TEST_ASSERT(fs_getpos(file) == 16);
- rc = fs_write(file, "qrstuvwx", 8);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 24);
- TEST_ASSERT(fs_getpos(file) == 24);
- rc = fs_close(file);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_assert_contents("/myfile.txt",
- "abcdefghijklmnopqrstuvwx", 24);
-
- rc = fs_mkdir("/mydir");
- TEST_ASSERT_FATAL(rc == 0);
- rc = fs_open("/mydir/gaga.txt", FS_ACCESS_WRITE | FS_ACCESS_APPEND, &file);
- TEST_ASSERT_FATAL(rc == 0);
-
- /*** Repeated appends to a large file. */
- for (i = 0; i < 1000; i++) {
- rc = fs_filelen(file, &len);
- TEST_ASSERT_FATAL(rc == 0);
- TEST_ASSERT(len == i);
-
- c = '0' + i % 10;
- rc = fs_write(file, &c, 1);
- TEST_ASSERT_FATAL(rc == 0);
- }
-
- rc = fs_close(file);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_assert_contents("/mydir/gaga.txt",
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789",
- 1000);
-
- struct nffs_test_file_desc *expected_system =
- (struct nffs_test_file_desc[]) { {
- .filename = "",
- .is_dir = 1,
- .children = (struct nffs_test_file_desc[]) { {
- .filename = "myfile.txt",
- .contents = "abcdefghijklmnopqrstuvwx",
- .contents_len = 24,
- }, {
- .filename = "mydir",
- .is_dir = 1,
- .children = (struct nffs_test_file_desc[]) { {
- .filename = "gaga.txt",
- .contents =
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- "01234567890123456789012345678901234567890123456789"
- ,
- .contents_len = 1000,
- }, {
- .filename = NULL,
- } },
- }, {
- .filename = NULL,
- } },
- } };
-
- nffs_test_assert_system(expected_system, nffs_area_descs);
-}
-
-TEST_CASE(nffs_test_read)
-{
- struct fs_file *file;
- uint8_t buf[16];
- uint32_t bytes_read;
- int rc;
-
- rc = nffs_format(nffs_area_descs);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_create_file("/myfile.txt", "1234567890", 10);
-
- rc = fs_open("/myfile.txt", FS_ACCESS_READ, &file);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 10);
- TEST_ASSERT(fs_getpos(file) == 0);
-
- rc = fs_read(file, 4, buf, &bytes_read);
- TEST_ASSERT(rc == 0);
- TEST_ASSERT(bytes_read == 4);
- TEST_ASSERT(memcmp(buf, "1234", 4) == 0);
- TEST_ASSERT(fs_getpos(file) == 4);
-
- rc = fs_read(file, sizeof buf - 4, buf + 4, &bytes_read);
- TEST_ASSERT(rc == 0);
- TEST_ASSERT(bytes_read == 6);
- TEST_ASSERT(memcmp(buf, "1234567890", 10) == 0);
- TEST_ASSERT(fs_getpos(file) == 10);
-
- rc = fs_close(file);
- TEST_ASSERT(rc == 0);
-}
-
-TEST_CASE(nffs_test_open)
-{
- struct fs_file *file;
- struct fs_dir *dir;
- int rc;
-
- rc = nffs_format(nffs_area_descs);
- TEST_ASSERT(rc == 0);
-
- /*** Fail to open an invalid path (not rooted). */
- rc = fs_open("file", FS_ACCESS_READ, &file);
- TEST_ASSERT(rc == FS_EINVAL);
-
- /*** Fail to open a directory (root directory). */
- rc = fs_open("/", FS_ACCESS_READ, &file);
- TEST_ASSERT(rc == FS_EINVAL);
-
- /*** Fail to open a nonexistent file for reading. */
- rc = fs_open("/1234", FS_ACCESS_READ, &file);
- TEST_ASSERT(rc == FS_ENOENT);
-
- /*** Fail to open a child of a nonexistent directory. */
- rc = fs_open("/dir/myfile.txt", FS_ACCESS_WRITE, &file);
- TEST_ASSERT(rc == FS_ENOENT);
- rc = fs_opendir("/dir", &dir);
- TEST_ASSERT(rc == FS_ENOENT);
-
- rc = fs_mkdir("/dir");
- TEST_ASSERT(rc == 0);
-
- /*** Fail to open a directory. */
- rc = fs_open("/dir", FS_ACCESS_READ, &file);
- TEST_ASSERT(rc == FS_EINVAL);
-
- /*** Successfully open an existing file for reading. */
- nffs_test_util_create_file("/dir/file.txt", "1234567890", 10);
- rc = fs_open("/dir/file.txt", FS_ACCESS_READ, &file);
- TEST_ASSERT(rc == 0);
- rc = fs_close(file);
- TEST_ASSERT(rc == 0);
-
- /*** Successfully open an nonexistent file for writing. */
- rc = fs_open("/dir/file2.txt", FS_ACCESS_WRITE, &file);
- TEST_ASSERT(rc == 0);
- rc = fs_close(file);
- TEST_ASSERT(rc == 0);
-
- /*** Ensure the file can be reopened. */
- rc = fs_open("/dir/file.txt", FS_ACCESS_READ, &file);
- TEST_ASSERT(rc == 0);
- rc = fs_close(file);
- TEST_ASSERT(rc == 0);
-}
-
-TEST_CASE(nffs_test_overwrite_one)
-{
- struct fs_file *file;
- int rc;
-
- /*** Setup. */
- rc = nffs_format(nffs_area_descs);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_append_file("/myfile.txt", "abcdefgh", 8);
-
- /*** Overwrite within one block (middle). */
- rc = fs_open("/myfile.txt", FS_ACCESS_WRITE, &file);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 8);
- TEST_ASSERT(fs_getpos(file) == 0);
-
- rc = fs_seek(file, 3);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 8);
- TEST_ASSERT(fs_getpos(file) == 3);
-
- rc = fs_write(file, "12", 2);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 8);
- TEST_ASSERT(fs_getpos(file) == 5);
- rc = fs_close(file);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_assert_contents("/myfile.txt", "abc12fgh", 8);
- nffs_test_util_assert_block_count("/myfile.txt", 1);
-
- /*** Overwrite within one block (start). */
- rc = fs_open("/myfile.txt", FS_ACCESS_WRITE, &file);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 8);
- TEST_ASSERT(fs_getpos(file) == 0);
-
- rc = fs_write(file, "xy", 2);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 8);
- TEST_ASSERT(fs_getpos(file) == 2);
- rc = fs_close(file);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_assert_contents("/myfile.txt", "xyc12fgh", 8);
- nffs_test_util_assert_block_count("/myfile.txt", 1);
-
- /*** Overwrite within one block (end). */
- rc = fs_open("/myfile.txt", FS_ACCESS_WRITE, &file);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 8);
- TEST_ASSERT(fs_getpos(file) == 0);
-
- rc = fs_seek(file, 6);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 8);
- TEST_ASSERT(fs_getpos(file) == 6);
-
- rc = fs_write(file, "<>", 2);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 8);
- TEST_ASSERT(fs_getpos(file) == 8);
- rc = fs_close(file);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_assert_contents("/myfile.txt", "xyc12f<>", 8);
- nffs_test_util_assert_block_count("/myfile.txt", 1);
-
- /*** Overwrite one block middle, extend. */
- rc = fs_open("/myfile.txt", FS_ACCESS_WRITE, &file);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 8);
- TEST_ASSERT(fs_getpos(file) == 0);
-
- rc = fs_seek(file, 4);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 8);
- TEST_ASSERT(fs_getpos(file) == 4);
-
- rc = fs_write(file, "abcdefgh", 8);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 12);
- TEST_ASSERT(fs_getpos(file) == 12);
- rc = fs_close(file);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_assert_contents("/myfile.txt", "xyc1abcdefgh", 12);
- nffs_test_util_assert_block_count("/myfile.txt", 1);
-
- /*** Overwrite one block start, extend. */
- rc = fs_open("/myfile.txt", FS_ACCESS_WRITE, &file);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 12);
- TEST_ASSERT(fs_getpos(file) == 0);
-
- rc = fs_write(file, "abcdefghijklmnop", 16);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 16);
- TEST_ASSERT(fs_getpos(file) == 16);
- rc = fs_close(file);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_assert_contents("/myfile.txt", "abcdefghijklmnop", 16);
- nffs_test_util_assert_block_count("/myfile.txt", 1);
-
- struct nffs_test_file_desc *expected_system =
- (struct nffs_test_file_desc[]) { {
- .filename = "",
- .is_dir = 1,
- .children = (struct nffs_test_file_desc[]) { {
- .filename = "myfile.txt",
- .contents = "abcdefghijklmnop",
- .contents_len = 16,
- }, {
- .filename = NULL,
- } },
- } };
-
- nffs_test_assert_system(expected_system, nffs_area_descs);
-}
-
-TEST_CASE(nffs_test_overwrite_two)
-{
- struct nffs_test_block_desc *blocks = (struct nffs_test_block_desc[]) { {
- .data = "abcdefgh",
- .data_len = 8,
- }, {
- .data = "ijklmnop",
- .data_len = 8,
- } };
-
- struct fs_file *file;
- int rc;
-
-
- /*** Setup. */
- rc = nffs_format(nffs_area_descs);
- TEST_ASSERT(rc == 0);
-
- /*** Overwrite two blocks (middle). */
- nffs_test_util_create_file_blocks("/myfile.txt", blocks, 2);
- rc = fs_open("/myfile.txt", FS_ACCESS_WRITE, &file);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 16);
- TEST_ASSERT(fs_getpos(file) == 0);
-
- rc = fs_seek(file, 7);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 16);
- TEST_ASSERT(fs_getpos(file) == 7);
-
- rc = fs_write(file, "123", 3);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 16);
- TEST_ASSERT(fs_getpos(file) == 10);
-
- rc = fs_close(file);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_assert_contents( "/myfile.txt", "abcdefg123klmnop", 16);
- nffs_test_util_assert_block_count("/myfile.txt", 2);
-
- /*** Overwrite two blocks (start). */
- nffs_test_util_create_file_blocks("/myfile.txt", blocks, 2);
- rc = fs_open("/myfile.txt", FS_ACCESS_WRITE, &file);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 16);
- TEST_ASSERT(fs_getpos(file) == 0);
-
- rc = fs_write(file, "ABCDEFGHIJ", 10);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 16);
- TEST_ASSERT(fs_getpos(file) == 10);
-
- rc = fs_close(file);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_assert_contents( "/myfile.txt", "ABCDEFGHIJklmnop", 16);
- nffs_test_util_assert_block_count("/myfile.txt", 2);
-
- /*** Overwrite two blocks (end). */
- nffs_test_util_create_file_blocks("/myfile.txt", blocks, 2);
- rc = fs_open("/myfile.txt", FS_ACCESS_WRITE, &file);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 16);
- TEST_ASSERT(fs_getpos(file) == 0);
-
- rc = fs_seek(file, 6);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 16);
- TEST_ASSERT(fs_getpos(file) == 6);
-
- rc = fs_write(file, "1234567890", 10);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 16);
- TEST_ASSERT(fs_getpos(file) == 16);
-
- rc = fs_close(file);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_assert_contents( "/myfile.txt", "abcdef1234567890", 16);
- nffs_test_util_assert_block_count("/myfile.txt", 2);
-
- /*** Overwrite two blocks middle, extend. */
- nffs_test_util_create_file_blocks("/myfile.txt", blocks, 2);
- rc = fs_open("/myfile.txt", FS_ACCESS_WRITE, &file);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 16);
- TEST_ASSERT(fs_getpos(file) == 0);
-
- rc = fs_seek(file, 6);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 16);
- TEST_ASSERT(fs_getpos(file) == 6);
-
- rc = fs_write(file, "1234567890!@#$", 14);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 20);
- TEST_ASSERT(fs_getpos(file) == 20);
-
- rc = fs_close(file);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_assert_contents( "/myfile.txt", "abcdef1234567890!@#$", 20);
- nffs_test_util_assert_block_count("/myfile.txt", 2);
-
- /*** Overwrite two blocks start, extend. */
- nffs_test_util_create_file_blocks("/myfile.txt", blocks, 2);
- rc = fs_open("/myfile.txt", FS_ACCESS_WRITE, &file);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 16);
- TEST_ASSERT(fs_getpos(file) == 0);
-
- rc = fs_write(file, "1234567890!@#$%^&*()", 20);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 20);
- TEST_ASSERT(fs_getpos(file) == 20);
-
- rc = fs_close(file);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_assert_contents( "/myfile.txt", "1234567890!@#$%^&*()", 20);
- nffs_test_util_assert_block_count("/myfile.txt", 2);
-
- struct nffs_test_file_desc *expected_system =
- (struct nffs_test_file_desc[]) { {
- .filename = "",
- .is_dir = 1,
- .children = (struct nffs_test_file_desc[]) { {
- .filename = "myfile.txt",
- .contents = "1234567890!@#$%^&*()",
- .contents_len = 20,
- }, {
- .filename = NULL,
- } },
- } };
-
- nffs_test_assert_system(expected_system, nffs_area_descs);
-}
-
-TEST_CASE(nffs_test_overwrite_three)
-{
- struct nffs_test_block_desc *blocks = (struct nffs_test_block_desc[]) { {
- .data = "abcdefgh",
- .data_len = 8,
- }, {
- .data = "ijklmnop",
- .data_len = 8,
- }, {
- .data = "qrstuvwx",
- .data_len = 8,
- } };
-
- struct fs_file *file;
- int rc;
-
-
- /*** Setup. */
- rc = nffs_format(nffs_area_descs);
- TEST_ASSERT(rc == 0);
-
- /*** Overwrite three blocks (middle). */
- nffs_test_util_create_file_blocks("/myfile.txt", blocks, 3);
- rc = fs_open("/myfile.txt", FS_ACCESS_WRITE, &file);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 24);
- TEST_ASSERT(fs_getpos(file) == 0);
-
- rc = fs_seek(file, 6);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 24);
- TEST_ASSERT(fs_getpos(file) == 6);
-
- rc = fs_write(file, "1234567890!@", 12);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 24);
- TEST_ASSERT(fs_getpos(file) == 18);
-
- rc = fs_close(file);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_assert_contents( "/myfile.txt",
- "abcdef1234567890!@stuvwx", 24);
- nffs_test_util_assert_block_count("/myfile.txt", 3);
-
- /*** Overwrite three blocks (start). */
- nffs_test_util_create_file_blocks("/myfile.txt", blocks, 3);
- rc = fs_open("/myfile.txt", FS_ACCESS_WRITE, &file);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 24);
- TEST_ASSERT(fs_getpos(file) == 0);
-
- rc = fs_write(file, "1234567890!@#$%^&*()", 20);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 24);
- TEST_ASSERT(fs_getpos(file) == 20);
-
- rc = fs_close(file);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_assert_contents( "/myfile.txt",
- "1234567890!@#$%^&*()uvwx", 24);
- nffs_test_util_assert_block_count("/myfile.txt", 3);
-
- /*** Overwrite three blocks (end). */
- nffs_test_util_create_file_blocks("/myfile.txt", blocks, 3);
- rc = fs_open("/myfile.txt", FS_ACCESS_WRITE, &file);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 24);
- TEST_ASSERT(fs_getpos(file) == 0);
-
- rc = fs_seek(file, 6);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 24);
- TEST_ASSERT(fs_getpos(file) == 6);
-
- rc = fs_write(file, "1234567890!@#$%^&*", 18);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 24);
- TEST_ASSERT(fs_getpos(file) == 24);
-
- rc = fs_close(file);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_assert_contents( "/myfile.txt",
- "abcdef1234567890!@#$%^&*", 24);
- nffs_test_util_assert_block_count("/myfile.txt", 3);
-
- /*** Overwrite three blocks middle, extend. */
- nffs_test_util_create_file_blocks("/myfile.txt", blocks, 3);
- rc = fs_open("/myfile.txt", FS_ACCESS_WRITE, &file);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 24);
- TEST_ASSERT(fs_getpos(file) == 0);
-
- rc = fs_seek(file, 6);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 24);
- TEST_ASSERT(fs_getpos(file) == 6);
-
- rc = fs_write(file, "1234567890!@#$%^&*()", 20);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 26);
- TEST_ASSERT(fs_getpos(file) == 26);
-
- rc = fs_close(file);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_assert_contents( "/myfile.txt",
- "abcdef1234567890!@#$%^&*()", 26);
- nffs_test_util_assert_block_count("/myfile.txt", 3);
-
- /*** Overwrite three blocks start, extend. */
- nffs_test_util_create_file_blocks("/myfile.txt", blocks, 3);
- rc = fs_open("/myfile.txt", FS_ACCESS_WRITE, &file);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 24);
- TEST_ASSERT(fs_getpos(file) == 0);
-
- rc = fs_write(file, "1234567890!@#$%^&*()abcdefghij", 30);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 30);
- TEST_ASSERT(fs_getpos(file) == 30);
-
- rc = fs_close(file);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_assert_contents( "/myfile.txt",
- "1234567890!@#$%^&*()abcdefghij", 30);
- nffs_test_util_assert_block_count("/myfile.txt", 3);
-
- struct nffs_test_file_desc *expected_system =
- (struct nffs_test_file_desc[]) { {
- .filename = "",
- .is_dir = 1,
- .children = (struct nffs_test_file_desc[]) { {
- .filename = "myfile.txt",
- .contents = "1234567890!@#$%^&*()abcdefghij",
- .contents_len = 30,
- }, {
- .filename = NULL,
- } },
- } };
-
- nffs_test_assert_system(expected_system, nffs_area_descs);
-}
-
-TEST_CASE(nffs_test_overwrite_many)
-{
- struct nffs_test_block_desc *blocks = (struct nffs_test_block_desc[]) { {
- .data = "abcdefgh",
- .data_len = 8,
- }, {
- .data = "ijklmnop",
- .data_len = 8,
- }, {
- .data = "qrstuvwx",
- .data_len = 8,
- } };
-
- struct fs_file *file;
- int rc;
-
-
- /*** Setup. */
- rc = nffs_format(nffs_area_descs);
- TEST_ASSERT(rc == 0);
-
- /*** Overwrite middle of first block. */
- nffs_test_util_create_file_blocks("/myfile.txt", blocks, 3);
- rc = fs_open("/myfile.txt", FS_ACCESS_WRITE, &file);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 24);
- TEST_ASSERT(fs_getpos(file) == 0);
-
- rc = fs_seek(file, 3);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 24);
- TEST_ASSERT(fs_getpos(file) == 3);
-
- rc = fs_write(file, "12", 2);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 24);
- TEST_ASSERT(fs_getpos(file) == 5);
-
- rc = fs_close(file);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_assert_contents( "/myfile.txt",
- "abc12fghijklmnopqrstuvwx", 24);
- nffs_test_util_assert_block_count("/myfile.txt", 3);
-
- /*** Overwrite end of first block, start of second. */
- nffs_test_util_create_file_blocks("/myfile.txt", blocks, 3);
- rc = fs_open("/myfile.txt", FS_ACCESS_WRITE, &file);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 24);
- TEST_ASSERT(fs_getpos(file) == 0);
-
- rc = fs_seek(file, 6);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 24);
- TEST_ASSERT(fs_getpos(file) == 6);
-
- rc = fs_write(file, "1234", 4);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_file_len(file, 24);
- TEST_ASSERT(fs_getpos(file) == 10);
-
- rc = fs_close(file);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_assert_contents( "/myfile.txt",
- "abcdef1234klmnopqrstuvwx", 24);
- nffs_test_util_assert_block_count("/myfile.txt", 3);
-
- struct nffs_test_file_desc *expected_system =
- (struct nffs_test_file_desc[]) { {
- .filename = "",
- .is_dir = 1,
- .children = (struct nffs_test_file_desc[]) { {
- .filename = "myfile.txt",
- .contents = "abcdef1234klmnopqrstuvwx",
- .contents_len = 24,
- }, {
- .filename = NULL,
- } },
- } };
-
- nffs_test_assert_system(expected_system, nffs_area_descs);
-}
-
-TEST_CASE(nffs_test_long_filename)
-{
- int rc;
-
-
- /*** Setup. */
- rc = nffs_format(nffs_area_descs);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_create_file("/12345678901234567890.txt", "contents", 8);
-
- rc = fs_mkdir("/longdir12345678901234567890");
- TEST_ASSERT(rc == 0);
-
- rc = fs_rename("/12345678901234567890.txt",
- "/longdir12345678901234567890/12345678901234567890.txt");
- TEST_ASSERT(rc == 0);
-
- struct nffs_test_file_desc *expected_system =
- (struct nffs_test_file_desc[]) { {
- .filename = "",
- .is_dir = 1,
- .children = (struct nffs_test_file_desc[]) { {
- .filename = "longdir12345678901234567890",
- .is_dir = 1,
- .children = (struct nffs_test_file_desc[]) { {
- .filename = "/12345678901234567890.txt",
- .contents = "contents",
- .contents_len = 8,
- }, {
- .filename = NULL,
- } },
- }, {
- .filename = NULL,
- } },
- } };
-
- nffs_test_assert_system(expected_system, nffs_area_descs);
-}
-
-TEST_CASE(nffs_test_large_write)
-{
- static char data[NFFS_BLOCK_MAX_DATA_SZ_MAX * 5];
- int rc;
- int i;
-
- static const struct nffs_area_desc area_descs_two[] = {
- { 0x00020000, 128 * 1024 },
- { 0x00040000, 128 * 1024 },
- { 0, 0 },
- };
-
-
-
- /*** Setup. */
- rc = nffs_format(area_descs_two);
- TEST_ASSERT(rc == 0);
-
- for (i = 0; i < sizeof data; i++) {
- data[i] = i;
- }
-
- nffs_test_util_create_file("/myfile.txt", data, sizeof data);
-
- /* Ensure large write was split across the appropriate number of data
- * blocks.
- */
- TEST_ASSERT(nffs_test_util_block_count("/myfile.txt") ==
- sizeof data / NFFS_BLOCK_MAX_DATA_SZ_MAX);
-
- /* Garbage collect and then ensure the large file is still properly divided
- * according to max data block size.
- */
- nffs_gc(NULL);
- TEST_ASSERT(nffs_test_util_block_count("/myfile.txt") ==
- sizeof data / NFFS_BLOCK_MAX_DATA_SZ_MAX);
-
- struct nffs_test_file_desc *expected_system =
- (struct nffs_test_file_desc[]) { {
- .filename = "",
- .is_dir = 1,
- .children = (struct nffs_test_file_desc[]) { {
- .filename = "myfile.txt",
- .contents = data,
- .contents_len = sizeof data,
- }, {
- .filename = NULL,
- } },
- } };
-
- nffs_test_assert_system(expected_system, area_descs_two);
-}
-
-TEST_CASE(nffs_test_many_children)
-{
- int rc;
-
-
- /*** Setup. */
- rc = nffs_format(nffs_area_descs);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_create_file("/zasdf", NULL, 0);
- nffs_test_util_create_file("/FfD", NULL, 0);
- nffs_test_util_create_file("/4Zvv", NULL, 0);
- nffs_test_util_create_file("/*(*2fs", NULL, 0);
- nffs_test_util_create_file("/pzzd", NULL, 0);
- nffs_test_util_create_file("/zasdf0", NULL, 0);
- nffs_test_util_create_file("/23132.bin", NULL, 0);
- nffs_test_util_create_file("/asldkfjaldskfadsfsdf.txt", NULL, 0);
- nffs_test_util_create_file("/sdgaf", NULL, 0);
- nffs_test_util_create_file("/939302**", NULL, 0);
- rc = fs_mkdir("/dir");
- nffs_test_util_create_file("/dir/itw82", NULL, 0);
- nffs_test_util_create_file("/dir/124", NULL, 0);
-
- struct nffs_test_file_desc *expected_system =
- (struct nffs_test_file_desc[]) { {
- .filename = "",
- .is_dir = 1,
- .children = (struct nffs_test_file_desc[]) {
- { "zasdf" },
- { "FfD" },
- { "4Zvv" },
- { "*(*2fs" },
- { "pzzd" },
- { "zasdf0" },
- { "23132.bin" },
- { "asldkfjaldskfadsfsdf.txt" },
- { "sdgaf" },
- { "939302**" },
- {
- .filename = "dir",
- .is_dir = 1,
- .children = (struct nffs_test_file_desc[]) {
- { "itw82" },
- { "124" },
- { NULL },
- },
- },
- { NULL },
- }
- } };
-
- nffs_test_assert_system(expected_system, nffs_area_descs);
-}
-
-TEST_CASE(nffs_test_gc)
-{
- int rc;
-
- static const struct nffs_area_desc area_descs_two[] = {
- { 0x00020000, 128 * 1024 },
- { 0x00040000, 128 * 1024 },
- { 0, 0 },
- };
-
- struct nffs_test_block_desc blocks[8] = { {
- .data = "1",
- .data_len = 1,
- }, {
- .data = "2",
- .data_len = 1,
- }, {
- .data = "3",
- .data_len = 1,
- }, {
- .data = "4",
- .data_len = 1,
- }, {
- .data = "5",
- .data_len = 1,
- }, {
- .data = "6",
- .data_len = 1,
- }, {
- .data = "7",
- .data_len = 1,
- }, {
- .data = "8",
- .data_len = 1,
- } };
-
-
- rc = nffs_format(area_descs_two);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_create_file_blocks("/myfile.txt", blocks, 8);
-
- nffs_gc(NULL);
-
- nffs_test_util_assert_block_count("/myfile.txt", 1);
-}
-
-TEST_CASE(nffs_test_wear_level)
-{
- int rc;
- int i;
- int j;
-
- static const struct nffs_area_desc area_descs_uniform[] = {
- { 0x00000000, 2 * 1024 },
- { 0x00020000, 2 * 1024 },
- { 0x00040000, 2 * 1024 },
- { 0x00060000, 2 * 1024 },
- { 0x00080000, 2 * 1024 },
- { 0, 0 },
- };
-
-
- /*** Setup. */
- rc = nffs_format(area_descs_uniform);
- TEST_ASSERT(rc == 0);
-
- /* Ensure areas rotate properly. */
- for (i = 0; i < 255; i++) {
- for (j = 0; j < nffs_num_areas; j++) {
- nffs_test_assert_area_seqs(i, nffs_num_areas - j, i + 1, j);
- nffs_gc(NULL);
- }
- }
-
- /* Ensure proper rollover of sequence numbers. */
- for (j = 0; j < nffs_num_areas; j++) {
- nffs_test_assert_area_seqs(255, nffs_num_areas - j, 0, j);
- nffs_gc(NULL);
- }
- for (j = 0; j < nffs_num_areas; j++) {
- nffs_test_assert_area_seqs(0, nffs_num_areas - j, 1, j);
- nffs_gc(NULL);
- }
-}
-
-TEST_CASE(nffs_test_corrupt_scratch)
-{
- int non_scratch_id;
- int scratch_id;
- int rc;
-
- static const struct nffs_area_desc area_descs_two[] = {
- { 0x00020000, 128 * 1024 },
- { 0x00040000, 128 * 1024 },
- { 0, 0 },
- };
-
-
- /*** Setup. */
- rc = nffs_format(area_descs_two);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_create_file("/myfile.txt", "contents", 8);
-
- /* Copy the current contents of the non-scratch area to the scratch area.
- * This will make the scratch area look like it only partially participated
- * in a garbage collection cycle.
- */
- scratch_id = nffs_scratch_area_idx;
- non_scratch_id = scratch_id ^ 1;
- nffs_test_copy_area(area_descs_two + non_scratch_id,
- area_descs_two + nffs_scratch_area_idx);
-
- /* Add some more data to the non-scratch area. */
- rc = fs_mkdir("/mydir");
- TEST_ASSERT(rc == 0);
-
- /* Ensure the file system is successfully detected and valid, despite
- * corruption.
- */
-
- rc = nffs_misc_reset();
- TEST_ASSERT(rc == 0);
-
- rc = nffs_detect(area_descs_two);
- TEST_ASSERT(rc == 0);
-
- TEST_ASSERT(nffs_scratch_area_idx == scratch_id);
-
- struct nffs_test_file_desc *expected_system =
- (struct nffs_test_file_desc[]) { {
- .filename = "",
- .is_dir = 1,
- .children = (struct nffs_test_file_desc[]) { {
- .filename = "mydir",
- .is_dir = 1,
- }, {
- .filename = "myfile.txt",
- .contents = "contents",
- .contents_len = 8,
- }, {
- .filename = NULL,
- } },
- } };
-
- nffs_test_assert_system(expected_system, area_descs_two);
-}
-
-/*
- * This test no longer works with the current implementation. The
- * expectation is that intermediate blocks can be removed and the old
- * method of finding the last current block after restore will allow the
- * file to be salvaged. Instead, the file should be removed and all data
- * declared invalid.
- */
-TEST_CASE(nffs_test_incomplete_block)
-{
- struct nffs_block block;
- struct fs_file *fs_file;
- struct nffs_file *file;
- uint32_t flash_offset;
- uint32_t area_offset;
- uint8_t area_idx;
- int rc;
-
- /*** Setup. */
- rc = nffs_format(nffs_area_descs);
- TEST_ASSERT(rc == 0);
-
- rc = fs_mkdir("/mydir");
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_create_file("/mydir/a", "aaaa", 4);
- nffs_test_util_create_file("/mydir/b", "bbbb", 4);
- nffs_test_util_create_file("/mydir/c", "cccc", 4);
-
- /* Add a second block to the 'b' file. */
- nffs_test_util_append_file("/mydir/b", "1234", 4);
-
- /* Corrupt the 'b' file; make it look like the second block only got half
- * written.
- */
- rc = fs_open("/mydir/b", FS_ACCESS_READ, &fs_file);
- TEST_ASSERT(rc == 0);
- file = (struct nffs_file *)fs_file;
-
- rc = nffs_block_from_hash_entry(&block,
- file->nf_inode_entry->nie_last_block_entry);
- TEST_ASSERT(rc == 0);
-
- nffs_flash_loc_expand(block.nb_hash_entry->nhe_flash_loc, &area_idx,
- &area_offset);
- flash_offset = nffs_areas[area_idx].na_offset + area_offset;
- /*
- * Overwrite block data - the CRC check should pick this up
- */
- rc = flash_native_memset(
- flash_offset + sizeof (struct nffs_disk_block) + 2, 0xff, 2);
- TEST_ASSERT(rc == 0);
-
- rc = nffs_misc_reset();
- TEST_ASSERT(rc == 0);
- rc = nffs_detect(nffs_area_descs);
- TEST_ASSERT(rc == 0);
-
- /* OLD: The entire second block should be removed; the file should only
- * contain the first block.
- * Unless we can salvage the block, the entire file should probably be
- * removed. This is a contrived example which generates bad data on the
- * what happens to be the last block, but corruption can actually occur
- * in any block. Sweep should be updated to search look for blocks that
- * don't have a correct prev_id and then decide whether to delete the
- * owning inode. XXX
- */
- struct nffs_test_file_desc *expected_system =
- (struct nffs_test_file_desc[]) { {
- .filename = "",
- .is_dir = 1,
- .children = (struct nffs_test_file_desc[]) { {
- .filename = "mydir",
- .is_dir = 1,
- .children = (struct nffs_test_file_desc[]) { {
- .filename = "a",
- .contents = "aaaa",
- .contents_len = 4,
-#if 0
-/* keep this out until sweep updated to capture bad blocks XXX */
- }, {
- .filename = "b",
- .contents = "bbbb",
- .contents_len = 4,
-#endif
- }, {
- .filename = "c",
- .contents = "cccc",
- .contents_len = 4,
- }, {
- .filename = NULL,
- } },
- }, {
- .filename = NULL,
- } },
- } };
-
- nffs_test_assert_system(expected_system, nffs_area_descs);
-}
-
-TEST_CASE(nffs_test_corrupt_block)
-{
- struct nffs_block block;
- struct fs_file *fs_file;
- struct nffs_file *file;
- uint32_t flash_offset;
- uint32_t area_offset;
- uint8_t area_idx;
- uint8_t off; /* offset to corrupt */
- int rc;
- struct nffs_disk_block ndb;
-
- /*** Setup. */
- rc = nffs_format(nffs_area_descs);
- TEST_ASSERT(rc == 0);
-
- rc = fs_mkdir("/mydir");
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_create_file("/mydir/a", "aaaa", 4);
- nffs_test_util_create_file("/mydir/b", "bbbb", 4);
- nffs_test_util_create_file("/mydir/c", "cccc", 4);
-
- /* Add a second block to the 'b' file. */
- nffs_test_util_append_file("/mydir/b", "1234", 4);
-
- /* Corrupt the 'b' file; overwrite the second block's magic number. */
- rc = fs_open("/mydir/b", FS_ACCESS_READ, &fs_file);
- TEST_ASSERT(rc == 0);
- file = (struct nffs_file *)fs_file;
-
- rc = nffs_block_from_hash_entry(&block,
- file->nf_inode_entry->nie_last_block_entry);
- TEST_ASSERT(rc == 0);
-
- nffs_flash_loc_expand(block.nb_hash_entry->nhe_flash_loc, &area_idx,
- &area_offset);
- flash_offset = nffs_areas[area_idx].na_offset + area_offset;
-
- /*
- * Overwriting the reserved16 field should invalidate the CRC
- */
- off = (char*)&ndb.reserved16 - (char*)&ndb;
- rc = flash_native_memset(flash_offset + off, 0x43, 1);
-
- TEST_ASSERT(rc == 0);
-
- /* Write a fourth file. This file should get restored even though the
- * previous object has an invalid magic number.
- */
- nffs_test_util_create_file("/mydir/d", "dddd", 4);
-
- rc = nffs_misc_reset();
- TEST_ASSERT(rc == 0);
- rc = nffs_detect(nffs_area_descs);
- TEST_ASSERT(rc == 0);
-
- /* The entire second block should be removed; the file should only contain
- * the first block.
- */
- struct nffs_test_file_desc *expected_system =
- (struct nffs_test_file_desc[]) { {
- .filename = "",
- .is_dir = 1,
- .children = (struct nffs_test_file_desc[]) { {
- .filename = "mydir",
- .is_dir = 1,
- .children = (struct nffs_test_file_desc[]) { {
- .filename = "a",
- .contents = "aaaa",
- .contents_len = 4,
-#if 0
- /*
- * In the newer implementation without the find_file_ends
- * corrupted inodes are deleted rather than retained with
- * partial contents
- */
- }, {
- .filename = "b",
- .contents = "bbbb",
- .contents_len = 4,
-#endif
- }, {
- .filename = "c",
- .contents = "cccc",
- .contents_len = 4,
- }, {
- .filename = "d",
- .contents = "dddd",
- .contents_len = 4,
- }, {
- .filename = NULL,
- } },
- }, {
- .filename = NULL,
- } },
- } };
-
- nffs_test_assert_system(expected_system, nffs_area_descs);
-}
-
-TEST_CASE(nffs_test_large_unlink)
-{
- static char file_contents[1024 * 4];
- char filename[256];
- int rc;
- int i;
- int j;
- int k;
-
-
- /*** Setup. */
- nffs_config.nc_num_inodes = 1024;
- nffs_config.nc_num_blocks = 1024;
-
- rc = nffs_init();
- TEST_ASSERT(rc == 0);
-
- rc = nffs_format(nffs_area_descs);
- TEST_ASSERT(rc == 0);
-
- for (i = 0; i < 5; i++) {
- snprintf(filename, sizeof filename, "/dir0_%d", i);
- rc = fs_mkdir(filename);
- TEST_ASSERT(rc == 0);
-
- for (j = 0; j < 5; j++) {
- snprintf(filename, sizeof filename, "/dir0_%d/dir1_%d", i, j);
- rc = fs_mkdir(filename);
- TEST_ASSERT(rc == 0);
-
- for (k = 0; k < 5; k++) {
- snprintf(filename, sizeof filename,
- "/dir0_%d/dir1_%d/file2_%d", i, j, k);
- nffs_test_util_create_file(filename, file_contents,
- sizeof file_contents);
- }
- }
-
- for (j = 0; j < 15; j++) {
- snprintf(filename, sizeof filename, "/dir0_%d/file1_%d", i, j);
- nffs_test_util_create_file(filename, file_contents,
- sizeof file_contents);
- }
- }
-
- for (i = 0; i < 5; i++) {
- snprintf(filename, sizeof filename, "/dir0_%d", i);
- rc = fs_unlink(filename);
- TEST_ASSERT(rc == 0);
- }
-
- /* The entire file system should be empty. */
- struct nffs_test_file_desc *expected_system =
- (struct nffs_test_file_desc[]) { {
- .filename = "",
- .is_dir = 1,
- } };
-
- nffs_test_assert_system(expected_system, nffs_area_descs);
-}
-
-TEST_CASE(nffs_test_large_system)
-{
- int rc;
-
-
- /*** Setup. */
- rc = nffs_format(nffs_area_descs);
- TEST_ASSERT(rc == 0);
- nffs_test_util_create_tree(nffs_test_system_01);
-
- nffs_test_assert_system(nffs_test_system_01, nffs_area_descs);
-
- rc = fs_unlink("/lvl1dir-0000");
- TEST_ASSERT(rc == 0);
-
- rc = fs_unlink("/lvl1dir-0004");
- TEST_ASSERT(rc == 0);
-
- rc = fs_mkdir("/lvl1dir-0000");
- TEST_ASSERT(rc == 0);
-
- nffs_test_assert_system(nffs_test_system_01_rm_1014_mk10, nffs_area_descs);
-}
-
-TEST_CASE(nffs_test_lost_found)
-{
- char buf[32];
- struct nffs_inode_entry *inode_entry;
- uint32_t flash_offset;
- uint32_t area_offset;
- uint8_t area_idx;
- int rc;
- struct nffs_disk_inode ndi;
- uint8_t off; /* calculated offset for memset */
-
- /*** Setup. */
- rc = nffs_format(nffs_area_descs);
- TEST_ASSERT(rc == 0);
-
- rc = fs_mkdir("/mydir");
- TEST_ASSERT(rc == 0);
- rc = fs_mkdir("/mydir/dir1");
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_create_file("/mydir/file1", "aaaa", 4);
- nffs_test_util_create_file("/mydir/dir1/file2", "bbbb", 4);
-
- /* Corrupt the mydir inode. */
- rc = nffs_path_find_inode_entry("/mydir", &inode_entry);
- TEST_ASSERT(rc == 0);
-
- snprintf(buf, sizeof buf, "%lu",
- (unsigned long)inode_entry->nie_hash_entry.nhe_id);
-
- nffs_flash_loc_expand(inode_entry->nie_hash_entry.nhe_flash_loc,
- &area_idx, &area_offset);
- flash_offset = nffs_areas[area_idx].na_offset + area_offset;
- /*
- * Overwrite the sequence number - should be detected as CRC corruption
- */
- off = (char*)&ndi.ndi_seq - (char*)&ndi;
- rc = flash_native_memset(flash_offset + off, 0xaa, 1);
- TEST_ASSERT(rc == 0);
-
- /* Clear cached data and restore from flash (i.e, simulate a reboot). */
- rc = nffs_misc_reset();
- TEST_ASSERT(rc == 0);
- rc = nffs_detect(nffs_area_descs);
- TEST_ASSERT(rc == 0);
-
- /* All contents should now be in the lost+found dir. */
- struct nffs_test_file_desc *expected_system =
- (struct nffs_test_file_desc[]) { {
- .filename = "",
- .is_dir = 1,
- .children = (struct nffs_test_file_desc[]) { {
- .filename = "lost+found",
- .is_dir = 1,
-#if 0
- .children = (struct nffs_test_file_desc[]) { {
- .filename = buf,
- .is_dir = 1,
- .children = (struct nffs_test_file_desc[]) { {
- .filename = "file1",
- .contents = "aaaa",
- .contents_len = 4,
- }, {
- .filename = "dir1",
- .is_dir = 1,
- .children = (struct nffs_test_file_desc[]) { {
- .filename = "file2",
- .contents = "bbbb",
- .contents_len = 4,
- }, {
- .filename = NULL,
- } },
- }, {
- .filename = NULL,
- } },
- }, {
- .filename = NULL,
- } },
-#endif
- }, {
- .filename = NULL,
- } }
- } };
-
- nffs_test_assert_system(expected_system, nffs_area_descs);
-}
-
-TEST_CASE(nffs_test_cache_large_file)
-{
- static char data[NFFS_BLOCK_MAX_DATA_SZ_MAX * 5];
- struct fs_file *file;
- uint8_t b;
- int rc;
-
- /*** Setup. */
- rc = nffs_format(nffs_area_descs);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_create_file("/myfile.txt", data, sizeof data);
- nffs_cache_clear();
-
- /* Opening a file should not cause any blocks to get cached. */
- rc = fs_open("/myfile.txt", FS_ACCESS_READ, &file);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_cache_range("/myfile.txt", 0, 0);
-
- /* Cache first block. */
- rc = fs_seek(file, nffs_block_max_data_sz * 0);
- TEST_ASSERT(rc == 0);
- rc = fs_read(file, 1, &b, NULL);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_cache_range("/myfile.txt",
- nffs_block_max_data_sz * 0,
- nffs_block_max_data_sz * 1);
-
- /* Cache second block. */
- rc = fs_seek(file, nffs_block_max_data_sz * 1);
- TEST_ASSERT(rc == 0);
- rc = fs_read(file, 1, &b, NULL);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_cache_range("/myfile.txt",
- nffs_block_max_data_sz * 0,
- nffs_block_max_data_sz * 2);
-
-
- /* Cache fourth block; prior cache should get erased. */
- rc = fs_seek(file, nffs_block_max_data_sz * 3);
- TEST_ASSERT(rc == 0);
- rc = fs_read(file, 1, &b, NULL);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_cache_range("/myfile.txt",
- nffs_block_max_data_sz * 3,
- nffs_block_max_data_sz * 4);
-
- /* Cache second and third blocks. */
- rc = fs_seek(file, nffs_block_max_data_sz * 1);
- TEST_ASSERT(rc == 0);
- rc = fs_read(file, 1, &b, NULL);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_cache_range("/myfile.txt",
- nffs_block_max_data_sz * 1,
- nffs_block_max_data_sz * 4);
-
- /* Cache fifth block. */
- rc = fs_seek(file, nffs_block_max_data_sz * 4);
- TEST_ASSERT(rc == 0);
- rc = fs_read(file, 1, &b, NULL);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_cache_range("/myfile.txt",
- nffs_block_max_data_sz * 1,
- nffs_block_max_data_sz * 5);
-
- rc = fs_close(file);
- TEST_ASSERT(rc == 0);
-}
-
-TEST_CASE(nffs_test_readdir)
-{
- struct fs_dirent *dirent;
- struct fs_dir *dir;
- int rc;
-
- /*** Setup. */
- rc = nffs_format(nffs_area_descs);
- TEST_ASSERT_FATAL(rc == 0);
-
- rc = fs_mkdir("/mydir");
- TEST_ASSERT_FATAL(rc == 0);
-
- nffs_test_util_create_file("/mydir/b", "bbbb", 4);
- nffs_test_util_create_file("/mydir/a", "aaaa", 4);
- rc = fs_mkdir("/mydir/c");
- TEST_ASSERT_FATAL(rc == 0);
-
- /* Nonexistent directory. */
- rc = fs_opendir("/asdf", &dir);
- TEST_ASSERT(rc == FS_ENOENT);
-
- /* Fail to opendir a file. */
- rc = fs_opendir("/mydir/a", &dir);
- TEST_ASSERT(rc == FS_EINVAL);
-
- /* Real directory (with trailing slash). */
- rc = fs_opendir("/mydir/", &dir);
- TEST_ASSERT_FATAL(rc == 0);
-
- rc = fs_readdir(dir, &dirent);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_ent_name(dirent, "a");
- TEST_ASSERT(fs_dirent_is_dir(dirent) == 0);
-
- rc = fs_readdir(dir, &dirent);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_ent_name(dirent, "b");
- TEST_ASSERT(fs_dirent_is_dir(dirent) == 0);
-
- rc = fs_readdir(dir, &dirent);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_ent_name(dirent, "c");
- TEST_ASSERT(fs_dirent_is_dir(dirent) == 1);
-
- rc = fs_readdir(dir, &dirent);
- TEST_ASSERT(rc == FS_ENOENT);
-
- rc = fs_closedir(dir);
- TEST_ASSERT(rc == 0);
-
- /* Root directory. */
- rc = fs_opendir("/", &dir);
- TEST_ASSERT(rc == 0);
- rc = fs_readdir(dir, &dirent);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_assert_ent_name(dirent, "lost+found");
- TEST_ASSERT(fs_dirent_is_dir(dirent) == 1);
-
- rc = fs_readdir(dir, &dirent);
- TEST_ASSERT(rc == 0);
- nffs_test_util_assert_ent_name(dirent, "mydir");
- TEST_ASSERT(fs_dirent_is_dir(dirent) == 1);
-
- rc = fs_closedir(dir);
- TEST_ASSERT(rc == 0);
-
- /* Delete entries while iterating. */
- rc = fs_opendir("/mydir", &dir);
- TEST_ASSERT_FATAL(rc == 0);
-
- rc = fs_readdir(dir, &dirent);
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_assert_ent_name(dirent, "a");
- TEST_ASSERT(fs_dirent_is_dir(dirent) == 0);
-
- rc = fs_unlink("/mydir/b");
- TEST_ASSERT(rc == 0);
-
- rc = fs_readdir(dir, &dirent);
- TEST_ASSERT(rc == 0);
-
- rc = fs_unlink("/mydir/c");
- TEST_ASSERT(rc == 0);
-
- rc = fs_unlink("/mydir");
- TEST_ASSERT(rc == 0);
-
- nffs_test_util_assert_ent_name(dirent, "c");
- TEST_ASSERT(fs_dirent_is_dir(dirent) == 1);
-
- rc = fs_readdir(dir, &dirent);
- TEST_ASSERT(rc == FS_ENOENT);
-
- rc = fs_closedir(dir);
- TEST_ASSERT(rc == 0);
-
- /* Ensure directory is gone. */
- rc = fs_opendir("/mydir", &dir);
- TEST_ASSERT(rc == FS_ENOENT);
-}
-
-TEST_CASE(nffs_test_split_file)
-{
- static char data[24 * 1024];
- int rc;
- int i;
-
- /*** Setup. */
- static const struct nffs_area_desc area_descs_two[] = {
- { 0x00000000, 16 * 1024 },
- { 0x00004000, 16 * 1024 },
- { 0x00008000, 16 * 1024 },
- { 0, 0 },
- };
-
- rc = nffs_format(area_descs_two);
- TEST_ASSERT(rc == 0);
-
- for (i = 0; i < sizeof data; i++) {
- data[i] = i;
- }
-
- for (i = 0; i < 256; i++) {
- nffs_test_util_create_file("/myfile.txt", data, sizeof data);
- rc = fs_unlink("/myfile.txt");
- TEST_ASSERT(rc == 0);
- }
-
- nffs_test_util_create_file("/myfile.txt", data, sizeof data);
-
- struct nffs_test_file_desc *expected_system =
- (struct nffs_test_file_desc[]) { {
- .filename = "",
- .is_dir = 1,
- .children = (struct nffs_test_file_desc[]) { {
- .filename = "myfile.txt",
- .contents = data,
- .contents_len = sizeof data,
- }, {
- .filename = NULL,
- } },
- } };
-
- nffs_test_assert_system(expected_system, area_descs_two);
-}
-
-TEST_CASE(nffs_test_gc_on_oom)
-{
- int rc;
-
- /*** Setup. */
- /* Ensure all areas are the same size. */
- static const struct nffs_area_desc area_descs_two[] = {
- { 0x00000000, 16 * 1024 },
- { 0x00004000, 16 * 1024 },
- { 0x00008000, 16 * 1024 },
- { 0, 0 },
- };
-
- rc = nffs_format(area_descs_two);
- TEST_ASSERT_FATAL(rc == 0);
-
- /* Leak block entries until only four are left. */
- /* XXX: This is ridiculous. Need to fix nffs configuration so that the
- * caller passes a config object rather than writing to a global variable.
- */
- while (nffs_block_entry_pool.mp_num_free != 4) {
- nffs_block_entry_alloc();
- }
-
- /*** Write 4 data blocks. */
- struct nffs_test_block_desc blocks[4] = { {
- .data = "1",
- .data_len = 1,
- }, {
- .data = "2",
- .data_len = 1,
- }, {
- .data = "3",
- .data_len = 1,
- }, {
- .data = "4",
- .data_len = 1,
- } };
-
- nffs_test_util_create_file_blocks("/myfile.txt", blocks, 4);
-
- TEST_ASSERT_FATAL(nffs_block_entry_pool.mp_num_free == 0);
-
- /* Attempt another one-byte write. This should trigger a garbage
- * collection cycle, resulting in the four blocks being collated. The
- * fifth write consumes an additional block, resulting in 2 out of 4 blocks
- * in use.
- */
- nffs_test_util_append_file("/myfile.txt", "5", 1);
-
- TEST_ASSERT_FATAL(nffs_block_entry_pool.mp_num_free == 2);
-
- struct nffs_test_file_desc *expected_system =
- (struct nffs_test_file_desc[]) { {
- .filename = "",
- .is_dir = 1,
- .children = (struct nffs_test_file_desc[]) { {
- .filename = "myfile.txt",
- .contents = "12345",
- .contents_len = 5,
- }, {
- .filename = NULL,
- } },
- } };
-
- nffs_test_assert_system(expected_system, area_descs_two);
-}
-
-TEST_SUITE(nffs_suite_cache)
-{
- int rc;
-
- memset(&nffs_config, 0, sizeof nffs_config);
- nffs_config.nc_num_cache_inodes = 4;
- nffs_config.nc_num_cache_blocks = 64;
-
- rc = nffs_init();
- TEST_ASSERT(rc == 0);
-
- nffs_test_cache_large_file();
-}
-
-static void
-nffs_test_gen(void)
-{
- int rc;
-
- rc = nffs_init();
- TEST_ASSERT(rc == 0);
-
- nffs_test_unlink();
- nffs_test_mkdir();
- nffs_test_rename();
- nffs_test_truncate();
- nffs_test_append();
- nffs_test_read();
- nffs_test_open();
- nffs_test_overwrite_one();
- nffs_test_overwrite_two();
- nffs_test_overwrite_three();
- nffs_test_overwrite_many();
- nffs_test_long_filename();
- nffs_test_large_write();
- nffs_test_many_children();
- nffs_test_gc();
- nffs_test_wear_level();
- nffs_test_corrupt_scratch();
- nffs_test_incomplete_block();
- nffs_test_corrupt_block();
- nffs_test_large_unlink();
- nffs_test_large_system();
- nffs_test_lost_found();
- nffs_test_readdir();
- nffs_test_split_file();
- nffs_test_gc_on_oom();
-}
-
-TEST_SUITE(gen_1_1)
-{
- nffs_config.nc_num_cache_inodes = 1;
- nffs_config.nc_num_cache_blocks = 1;
- nffs_test_gen();
-}
-
-TEST_SUITE(gen_4_32)
-{
- nffs_config.nc_num_cache_inodes = 4;
- nffs_config.nc_num_cache_blocks = 32;
- nffs_test_gen();
-}
-
-TEST_SUITE(gen_32_1024)
-{
- nffs_config.nc_num_cache_inodes = 32;
- nffs_config.nc_num_cache_blocks = 1024;
- nffs_test_gen();
-}
-
-int
-nffs_test_all(void)
-{
- nffs_config.nc_num_inodes = 1024 * 8;
- nffs_config.nc_num_blocks = 1024 * 20;
-
- gen_1_1();
- gen_4_32();
- gen_32_1024();
- nffs_suite_cache();
-
- return tu_any_failed;
-}
-
-void
-print_inode_entry(struct nffs_inode_entry *inode_entry, int indent)
-{
- struct nffs_inode inode;
- char name[NFFS_FILENAME_MAX_LEN + 1];
- uint32_t area_offset;
- uint8_t area_idx;
- int rc;
-
- if (inode_entry == nffs_root_dir) {
- printf("%*s/\n", indent, "");
- return;
- }
-
- rc = nffs_inode_from_entry(&inode, inode_entry);
- /*
- * Dummy inode
- */
- if (rc == FS_ENOENT) {
- printf(" DUMMY %d\n", rc);
- return;
- }
-
- nffs_flash_loc_expand(inode_entry->nie_hash_entry.nhe_flash_loc,
- &area_idx, &area_offset);
-
- rc = nffs_flash_read(area_idx,
- area_offset + sizeof (struct nffs_disk_inode),
- name, inode.ni_filename_len);
-
- name[inode.ni_filename_len] = '\0';
-
- printf("%*s%s\n", indent, "", name[0] == '\0' ? "/" : name);
-}
-
-void
-process_inode_entry(struct nffs_inode_entry *inode_entry, int indent)
-{
- struct nffs_inode_entry *child;
-
- print_inode_entry(inode_entry, indent);
-
- if (nffs_hash_id_is_dir(inode_entry->nie_hash_entry.nhe_id)) {
- SLIST_FOREACH(child, &inode_entry->nie_child_list, nie_sibling_next) {
- process_inode_entry(child, indent + 2);
- }
- }
-}
-
-int
-print_nffs_flash_inode(struct nffs_area *area, uint32_t off)
-{
- struct nffs_disk_inode ndi;
- char filename[128];
- int len;
- int rc;
-
- rc = hal_flash_read(area->na_flash_id, area->na_offset + off,
- &ndi, sizeof(ndi));
- assert(rc == 0);
-
- memset(filename, 0, sizeof(filename));
- len = min(sizeof(filename) - 1, ndi.ndi_filename_len);
- rc = hal_flash_read(area->na_flash_id, area->na_offset + off + sizeof(ndi),
- filename, len);
-
- printf(" off %x %s id %x flen %d seq %d last %x prnt %x flgs %x %s\n",
- off,
- (nffs_hash_id_is_file(ndi.ndi_id) ? "File" :
- (nffs_hash_id_is_dir(ndi.ndi_id) ? "Dir" : "???")),
- ndi.ndi_id,
- ndi.ndi_filename_len,
- ndi.ndi_seq,
- ndi.ndi_lastblock_id,
- ndi.ndi_parent_id,
- ndi.ndi_flags,
- filename);
- return sizeof(ndi) + ndi.ndi_filename_len;
-}
-
-int
-print_nffs_flash_block(struct nffs_area *area, uint32_t off)
-{
- struct nffs_disk_block ndb;
- int rc;
-
- rc = hal_flash_read(area->na_flash_id, area->na_offset + off,
- &ndb, sizeof(ndb));
- assert(rc == 0);
-
- printf(" off %x Block id %x len %d seq %d prev %x own ino %x\n",
- off,
- ndb.ndb_id,
- ndb.ndb_data_len,
- ndb.ndb_seq,
- ndb.ndb_prev_id,
- ndb.ndb_inode_id);
- return sizeof(ndb) + ndb.ndb_data_len;
-}
-
-int
-print_nffs_flash_object(struct nffs_area *area, uint32_t off)
-{
- struct nffs_disk_object ndo;
-
- hal_flash_read(area->na_flash_id, area->na_offset + off,
- &ndo.ndo_un_obj, sizeof(ndo.ndo_un_obj));
-
- if (nffs_hash_id_is_inode(ndo.ndo_disk_inode.ndi_id)) {
- return print_nffs_flash_inode(area, off);
-
- } else if (nffs_hash_id_is_block(ndo.ndo_disk_block.ndb_id)) {
- return print_nffs_flash_block(area, off);
-
- } else if (ndo.ndo_disk_block.ndb_id == 0xffffffff) {
- return area->na_length;
-
- } else {
- return 1;
- }
-}
-
-void
-print_nffs_flash_areas(int verbose)
-{
- struct nffs_area area;
- struct nffs_disk_area darea;
- int off;
- int i;
-
- for (i = 0; nffs_current_area_descs[i].nad_length != 0; i++) {
- if (i > NFFS_MAX_AREAS) {
- return;
- }
- area.na_offset = nffs_current_area_descs[i].nad_offset;
- area.na_length = nffs_current_area_descs[i].nad_length;
- area.na_flash_id = nffs_current_area_descs[i].nad_flash_id;
- hal_flash_read(area.na_flash_id, area.na_offset, &darea, sizeof(darea));
- area.na_id = darea.nda_id;
- area.na_cur = nffs_areas[i].na_cur;
- if (!nffs_area_magic_is_set(&darea)) {
- printf("Area header corrupt!\n");
- }
- printf("area %d: id %d %x-%x cur %x len %d flashid %x gc-seq %d %s%s\n",
- i, area.na_id, area.na_offset, area.na_offset + area.na_length,
- area.na_cur, area.na_length, area.na_flash_id, darea.nda_gc_seq,
- nffs_scratch_area_idx == i ? "(scratch)" : "",
- !nffs_area_magic_is_set(&darea) ? "corrupt" : "");
- if (verbose < 2) {
- off = sizeof (struct nffs_disk_area);
- while (off < area.na_length) {
- off += print_nffs_flash_object(&area, off);
- }
- }
- }
-}
-
-static int
-nffs_hash_fn(uint32_t id)
-{
- return id % NFFS_HASH_SIZE;
-}
-
-void
-print_hashlist(struct nffs_hash_entry *he)
-{
- struct nffs_hash_list *list;
- int idx = nffs_hash_fn(he->nhe_id);
- list = nffs_hash + idx;
-
- SLIST_FOREACH(he, list, nhe_next) {
- printf("hash_entry %s 0x%x: id 0x%x flash_loc 0x%x next 0x%x\n",
- nffs_hash_id_is_inode(he->nhe_id) ? "inode" : "block",
- (unsigned int)he,
- he->nhe_id, he->nhe_flash_loc,
- (unsigned int)he->nhe_next.sle_next);
- }
-}
-
-void
-print_hash(void)
-{
- int i;
- struct nffs_hash_entry *he;
- struct nffs_hash_entry *next;
- struct nffs_inode ni;
- struct nffs_disk_inode di;
- struct nffs_block nb;
- struct nffs_disk_block db;
- uint32_t area_offset;
- uint8_t area_idx;
- int rc;
-
- NFFS_HASH_FOREACH(he, i, next) {
- if (nffs_hash_id_is_inode(he->nhe_id)) {
- printf("hash_entry inode %d 0x%x: id 0x%x flash_loc 0x%x next 0x%x\n",
- i, (unsigned int)he,
- he->nhe_id, he->nhe_flash_loc,
- (unsigned int)he->nhe_next.sle_next);
- if (he->nhe_id == NFFS_ID_ROOT_DIR) {
- continue;
- }
- nffs_flash_loc_expand(he->nhe_flash_loc,
- &area_idx, &area_offset);
- rc = nffs_inode_read_disk(area_idx, area_offset, &di);
- if (rc) {
- printf("%d: fail inode read id 0x%x rc %d\n",
- i, he->nhe_id, rc);
<TRUNCATED>