blob: 63367d7272e005799ead7459fde86f636329668b [file] [log] [blame]
/*
* Copyright (c) 2023 Antmicro
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/ztest.h>
#include <zephyr/fs/fs.h>
#include <zephyr/fs/ext2.h>
#include "utils.h"
#include "../../common/test_fs_util.h"
uint32_t calculate_blocks(uint32_t freeb, uint32_t B)
{
uint32_t blocks = 0;
if (freeb <= 12) {
return freeb;
}
blocks += 12;
freeb -= 12 + 1; /* direct blocks + top block of first level table */
if (freeb <= B) {
return blocks + freeb;
}
blocks += B;
freeb -= B + 1; /* 1st level blocks + top block of second level table */
if (freeb <= B * (B + 1)) {
uint32_t n = freeb / (B + 1);
uint32_t r = freeb % (B + 1);
uint32_t partial = r > 0 ? 1 : 0;
return blocks + n * B + r - partial;
}
return blocks;
/* TODO: revisit this and extend when 3rd level blocks will be possible */
}
void writing_test(struct ext2_cfg *config)
{
int64_t ret = 0;
struct fs_file_t file;
struct fs_statvfs sbuf;
struct fs_dirent entry;
struct fs_mount_t *mp = &testfs_mnt;
static const char *file_path = "/sml/file";
ret = fs_mkfs(FS_EXT2, (uintptr_t)mp->storage_dev, config, 0);
zassert_equal(ret, 0, "Failed to mkfs with 2K blocks");
mp->flags = FS_MOUNT_FLAG_NO_FORMAT;
ret = fs_mount(mp);
zassert_equal(ret, 0, "Mount failed (ret=%d)", ret);
fs_file_t_init(&file);
ret = fs_open(&file, file_path, FS_O_RDWR | FS_O_CREATE);
zassert_equal(ret, 0, "File open failed (ret=%d)", ret);
ret = fs_statvfs(mp->mnt_point, &sbuf);
zassert_equal(ret, 0, "Expected success (ret=%d)", ret);
/* Calculate how many numbers will be written (use all available memory) */
uint32_t freeb = sbuf.f_bfree;
uint32_t bsize = sbuf.f_bsize;
uint32_t available_blocks = calculate_blocks(freeb, bsize / sizeof(uint32_t));
uint32_t bytes_to_write = bsize * available_blocks;
TC_PRINT("Available blocks: %d\nBlock size: %d\nBytes_to_write: %d\n",
available_blocks, bsize, bytes_to_write);
ret = testfs_write_incrementing(&file, 0, available_blocks * bsize);
zassert_equal(ret, bytes_to_write, "Different number of bytes written %ld (expected %ld)",
ret, bytes_to_write);
ret = fs_close(&file);
zassert_equal(ret, 0, "File close failed (ret=%d)", ret);
/* Check file size */
ret = fs_stat(file_path, &entry);
zassert_equal(ret, 0, "File stat failed (ret=%d)", ret);
zassert_equal(entry.size, bytes_to_write,
"Wrong file size %d (expected %d)", entry.size,
bytes_to_write);
fs_file_t_init(&file);
ret = fs_open(&file, file_path, FS_O_READ);
zassert_equal(ret, 0, "File open failed (ret=%d)", ret);
ret = testfs_verify_incrementing(&file, 0, available_blocks * bsize);
zassert_equal(ret, bytes_to_write, "Different number of bytes read %ld (expected %ld)",
ret, bytes_to_write);
ret = fs_close(&file);
zassert_equal(ret, 0, "File close failed (ret=%d)", ret);
uint32_t new_size = bytes_to_write;
while (new_size > 1) {
new_size = new_size / 8 * 3;
TC_PRINT("Truncating to %d\n", new_size);
ret = fs_open(&file, file_path, FS_O_RDWR);
zassert_equal(ret, 0, "File open failed (ret=%d)", ret);
ret = fs_truncate(&file, new_size);
zassert_equal(ret, 0, "File truncate failed (ret=%d)", ret);
ret = fs_stat(file_path, &entry);
zassert_equal(ret, 0, "File stat failed (ret=%d)", ret);
zassert_equal(entry.size, new_size,
"Wrong file size %d (expected %d)", entry.size, new_size);
ret = fs_seek(&file, 0, FS_SEEK_SET);
zassert_equal(ret, 0, "File seek failed (ret=%d)", ret);
ret = testfs_verify_incrementing(&file, 0, new_size);
zassert_equal(ret, new_size, "Different number of bytes read %ld (expected %ld)",
ret, new_size);
ret = fs_close(&file);
zassert_equal(ret, 0, "File close failed (ret=%d)", ret);
}
ret = fs_unmount(mp);
zassert_equal(ret, 0, "Unmount failed (ret=%d)", ret);
}
ZTEST(ext2tests, test_write_big_file)
{
writing_test(NULL);
}
#if defined(CONFIG_APP_TEST_BIG)
ZTEST(ext2tests, test_write_big_file_2K)
{
struct ext2_cfg config = {
.block_size = 2048,
.fs_size = 0x2000000,
.bytes_per_inode = 0,
.volume_name[0] = 0,
.set_uuid = false,
};
writing_test(&config);
}
ZTEST(ext2tests, test_write_big_file_4K)
{
struct ext2_cfg config = {
.block_size = 4096,
.fs_size = 0x8000000,
.bytes_per_inode = 0,
.volume_name[0] = 0,
.set_uuid = false,
};
writing_test(&config);
}
#endif