~aleteoryx/muditaos

afa37eef2cc6d1255d42dea213f4d44b9a8fbe6a — Lucjan Bryndza 5 years ago a6766b2
[EGD-4758] Add block size and fs size

Add blocks size and blocks count detecting
of the file size.
M module-vfs/drivers/src/purefs/fs/filesystem_littlefs.cpp => module-vfs/drivers/src/purefs/fs/filesystem_littlefs.cpp +37 -9
@@ 6,10 6,13 @@
#include <littlefs/volume_mapper.hpp>
#include <purefs/fs/drivers/file_handle_littlefs.hpp>
#include <purefs/fs/drivers/directory_handle_littlefs.hpp>
#include <purefs/blkdev/disk_manager.hpp>
#include <purefs/blkdev/disk_handle.hpp>
#include <lfs.h>
#include <lfs_extension.h>
#include <log/log.hpp>

#include <limits.h>
#include <climits>
#include <syslimits.h>
#include <sys/statvfs.h>
#include <fcntl.h>


@@ 103,19 106,33 @@ namespace
        st.st_mode    = translate_attrib_to_st_mode(fs.type);
    }

    [[gnu::nonnull(1)]] void setup_lfs_config(lfs_config *cfg)
    [[gnu::nonnull(1)]] int setup_lfs_config(lfs_config *cfg, size_t sector_size, size_t part_sectors_count)
    {
        cfg->block_cycles   = 512;
        cfg->block_size     = 0; // Read later from superblock
        cfg->block_count    = 0; // Read later from super block
        cfg->lookahead_size = 8192;
        // TODO: Read lfs configuration from the superblock
        cfg->block_size  = 4096;
        cfg->read_size   = cfg->block_size;
        cfg->prog_size   = cfg->block_size;
        cfg->cache_size  = cfg->block_size;
        cfg->block_count = 261887;

        int err = lfs_extension_read_config_from_superblock(cfg, sector_size);
        if (err) {
            LOG_ERROR("Unable to read the superblock info %i", err);
            return lfs_to_errno(err);
        }
        if (cfg->block_size > 1024U * 1024U) {
            LOG_ERROR("Block size too big");
            return -E2BIG;
        }

        if ((uint64_t(cfg->block_count) * uint64_t(cfg->block_size)) / sector_size > part_sectors_count) {
            LOG_ERROR("Block count out of range sectors count");
            return -ERANGE;
        }
        cfg->read_size  = cfg->block_size;
        cfg->prog_size  = cfg->block_size;
        cfg->cache_size = cfg->block_size;
        return 0;
    }

} // namespace

namespace purefs::fs::drivers


@@ 227,9 244,20 @@ namespace purefs::fs::drivers
        cpp_freertos::LockGuard _lck(m_lock);
        auto err = littlefs::internal::append_volume(vmnt->lfs_config(), disk_mngr(), disk);
        if (err) {
            return lfs_to_errno(err);
        }
        {
            auto diskmm = disk_mngr();
            auto ssize  = diskmm->get_info(disk, blkdev::info_type::sector_size);
            if (ssize < 0) {
                LOG_ERROR("Unable to read sector size %i", int(ssize));
                return ssize;
            }
            err = setup_lfs_config(vmnt->lfs_config(), ssize, disk->sectors());
        }
        if (err) {
            return err;
        }
        setup_lfs_config(vmnt->lfs_config());
        err = lfs_mount(vmnt->lfs_mount(), vmnt->lfs_config());
        if (err) {
            LOG_ERROR("LFS mount error %i", err);

M module-vfs/thirdparty/lfsfs/CMakeLists.txt => module-vfs/thirdparty/lfsfs/CMakeLists.txt +5 -2
@@ 5,6 5,8 @@ project(littlefs LANGUAGES C)
include(thirdparty OPTIONAL)

set(LIBLITTLEFS_SRCDIR littlefs)
set(LIBLITTLEFS_SRCDIR_EXT lfsextension/src)
set(LIBLITTLEFS_INCDIR_EXT lfsextension/include)
set(LIBLITTLEFS_TARGET ${PROJECT_NAME})

set(LIBLITTLEFS_SOURCES


@@ 13,10 15,11 @@ set(LIBLITTLEFS_SOURCES
        ${LIBLITTLEFS_SRCDIR}/bd/lfs_filebd.c
        ${LIBLITTLEFS_SRCDIR}/bd/lfs_rambd.c
        ${LIBLITTLEFS_SRCDIR}/bd/lfs_testbd.c
        ${LIBLITTLEFS_SRCDIR_EXT}/lfs_extension.c
)

set( LIBLITTLEFS_PUBLIC_INCLUDES  ${LIBLITTLEFS_SRCDIR})
set( LIBLITTLEFS_PRIVATE_INCLUDES ${LIBLITTLEFS_SRCDIR}/bd)
set( LIBLITTLEFS_PUBLIC_INCLUDES  ${LIBLITTLEFS_SRCDIR} ${LIBLITTLEFS_INCDIR_EXT})
set( LIBLITTLEFS_PRIVATE_INCLUDES ${LIBLITTLEFS_SRCDIR}/bd )


add_library( ${LIBLITTLEFS_TARGET} STATIC ${LIBLITTLEFS_SOURCES} )

A module-vfs/thirdparty/lfsfs/lfsextension/include/lfs_extension.h => module-vfs/thirdparty/lfsfs/lfsextension/include/lfs_extension.h +21 -0
@@ 0,0 1,21 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#pragma once

#include "lfs.h"

#ifdef __cplusplus
extern "C"
{
#endif
    /**
     * Try to setup config structure based on the superblock information
     * @param cfg LFS config structure
     * @return 0 or success otherwise error
     */
    int lfs_extension_read_config_from_superblock(struct lfs_config *cfg, size_t sector_size)
        __attribute__((nonnull(1)));
#ifdef __cplusplus
}
#endif

A module-vfs/thirdparty/lfsfs/lfsextension/src/lfs_extension.c => module-vfs/thirdparty/lfsfs/lfsextension/src/lfs_extension.c +68 -0
@@ 0,0 1,68 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md

#include "lfs_extension.h"
#include "lfs_util.h"

static inline void lfs_superblock_fromle32(lfs_superblock_t *superblock)
{
    superblock->version     = lfs_fromle32(superblock->version);
    superblock->block_size  = lfs_fromle32(superblock->block_size);
    superblock->block_count = lfs_fromle32(superblock->block_count);
    superblock->name_max    = lfs_fromle32(superblock->name_max);
    superblock->file_max    = lfs_fromle32(superblock->file_max);
    superblock->attr_max    = lfs_fromle32(superblock->attr_max);
}

static void *memstr(const void *mem, size_t memsize, const char *str)
{
    const size_t findstr_len = strlen(str);
    const uint8_t *memu8p    = mem;
    if (findstr_len > memsize) {
        return NULL;
    }
    uint8_t *match = memchr(memu8p, str[0], memsize);
    if (match != NULL) {
        size_t remaining = memsize - ((uint8_t *)match - memu8p);
        if (findstr_len <= remaining) {
            if (memcmp(match, str, findstr_len) == 0) {
                return match;
            }
        }
    }
    return NULL;
}

int lfs_extension_read_config_from_superblock(struct lfs_config *cfg, size_t sector_size)
{
    uint8_t sect_buf[sector_size] __attribute__((aligned));
    if (!cfg->read) {
        return LFS_ERR_IO;
    }
    lfs_superblock_t *lfs_superblock;
    if (sector_size <= sizeof(*lfs_superblock)) {
        return LFS_ERR_IO;
    }
    lfs_size_t block_size_saved = cfg->block_size;
    int err                     = cfg->read(cfg, 0, 0, sect_buf, sector_size);
    cfg->block_size             = block_size_saved;
    if (err) {
        return err;
    }
    const uint8_t *ptr = memstr(sect_buf, sizeof sect_buf, "littlefs");
    if (!ptr) {
        return LFS_ERR_NOENT;
    }
    lfs_superblock = (lfs_superblock_t *)(ptr + 12);
    lfs_superblock_fromle32(lfs_superblock);
    // check version
    uint16_t major_version = (0xffff & (lfs_superblock->version >> 16));
    uint16_t minor_version = (0xffff & (lfs_superblock->version >> 0));
    if ((major_version != LFS_DISK_VERSION_MAJOR || minor_version > LFS_DISK_VERSION_MINOR)) {
        LFS_ERROR("Invalid version v%" PRIu16 ".%" PRIu16, major_version, minor_version);
        return LFS_ERR_INVAL;
    }
    cfg->block_size  = lfs_superblock->block_size;
    cfg->block_count = lfs_superblock->block_count;
    return LFS_ERR_OK;
}