M module-vfs/CMakeLists.txt => module-vfs/CMakeLists.txt +3 -0
@@ 36,6 36,7 @@ set(FF_FAT_SOURCES
${FF_FAT_SOURCES_THIRDPARTY}
${CMAKE_CURRENT_SOURCE_DIR}/drivers/src/thirdparty/fatfs/ffsystem.cpp
${CMAKE_CURRENT_SOURCE_DIR}/drivers/src/thirdparty/fatfs/ff_glue.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/drivers/src/thirdparty/littlefs/lfs_glue.cpp
)
@@ 73,6 74,7 @@ set(SOURCES ""
src/purefs/fs/filesystem_cwd.cpp
src/purefs/vfs_subsystem.cpp
drivers/src/purefs/fs/filesystem_vfat.cpp
+ drivers/src/purefs/fs/filesystem_littlefs.cpp
src/deprecated/vfs-utils.cpp
src/deprecated/vfs.cpp
src/deprecated/vfsNotifier.cpp
@@ 119,6 121,7 @@ target_include_directories(${PROJECT_NAME}
target_include_directories(${PROJECT_NAME}
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/drivers/include/thirdparty/fatfs
+ ${CMAKE_CURRENT_SOURCE_DIR}/drivers/include/thirdparty
${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/fatfs/source
)
A module-vfs/drivers/include/purefs/fs/drivers/filesystem_littlefs.hpp => module-vfs/drivers/include/purefs/fs/drivers/filesystem_littlefs.hpp +64 -0
@@ 0,0 1,64 @@
+// 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 <purefs/fs/filesystem_operations.hpp>
+
+namespace purefs::fs::drivers
+{
+
+ /** Filesystem specific driver base class */
+ class filesystem_littlefs final : public filesystem_operations
+ {
+ public:
+ using fsfile = std::shared_ptr<internal::file_handle>;
+ using fsdir = std::shared_ptr<internal::directory_handle>;
+ using fsmount = std::shared_ptr<internal::mount_point>;
+ filesystem_littlefs() = default;
+ filesystem_littlefs(const filesystem_operations &) = delete;
+ virtual ~filesystem_littlefs() = default;
+ auto operator=(const filesystem_operations &) = delete;
+ /** Allocate mount point class specify to the VFS
+ * @return Allocated mount point structure
+ */
+ auto mount_prealloc(std::shared_ptr<blkdev::internal::disk_handle> diskh, std::string_view path, unsigned flags)
+ -> fsmount override;
+ auto mount(fsmount mnt) noexcept -> int override;
+ auto umount(fsmount mnt) noexcept -> int override;
+ auto stat_vfs(fsmount mnt, std::string_view path, statvfs &stat) const noexcept -> int override;
+
+ /** Standard file access API */
+ auto open(fsmount mnt, std::string_view path, int flags, int mode) noexcept -> fsfile override;
+ auto close(fsfile zfile) noexcept -> int override;
+ auto write(fsfile zfile, const char *ptr, size_t len) noexcept -> ssize_t override;
+ auto read(fsfile zfile, char *ptr, size_t len) noexcept -> ssize_t override;
+ auto seek(fsfile zfile, off_t pos, int dir) noexcept -> off_t override;
+ auto fstat(fsfile zfile, struct stat &st) noexcept -> int override;
+ auto stat(fsmount mnt, std::string_view file, struct stat &st) noexcept -> int override;
+ auto link(fsmount mnt, std::string_view existing, std::string_view newlink) noexcept -> int override;
+ auto symlink(fsmount mnt, std::string_view existing, std::string_view newlink) noexcept -> int override;
+ auto unlink(fsmount mnt, std::string_view name) noexcept -> int override;
+ auto rename(fsmount mnt, std::string_view oldname, std::string_view newname) noexcept -> int override;
+ auto mkdir(fsmount mnt, std::string_view path, int mode) noexcept -> int override;
+
+ /** Directory support API */
+ auto diropen(fsmount mnt, std::string_view path) noexcept -> fsdir override;
+ auto dirreset(fsdir dirstate) noexcept -> int override;
+ auto dirnext(fsdir dirstate, std::string &filename, struct stat &filestat) -> int override;
+ auto dirclose(fsdir dirstate) noexcept -> int override;
+
+ /** Other fops API */
+ auto ftruncate(fsfile zfile, off_t len) noexcept -> int override;
+ auto fsync(fsfile zfile) noexcept -> int override;
+ auto ioctl(fsmount mnt, std::string_view path, int cmd, void *arg) noexcept -> int override;
+ auto utimens(fsmount mnt, std::string_view path, std::array<timespec, 2> &tv) noexcept -> int override;
+ auto flock(fsfile zfile, int cmd) noexcept -> int;
+ auto isatty(fsfile zfile) noexcept -> int override;
+
+ auto chmod(fsmount mnt, std::string_view path, mode_t mode) noexcept -> int override;
+ auto fchmod(fsfile zfile, mode_t mode) noexcept -> int override;
+
+ auto filesystem_register_completed() const noexcept -> int override;
+ };
+} // namespace purefs::fs::drivers
A module-vfs/drivers/include/purefs/fs/drivers/mount_point_littlefs.hpp => module-vfs/drivers/include/purefs/fs/drivers/mount_point_littlefs.hpp +39 -0
@@ 0,0 1,39 @@
+// 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 <purefs/fs/mount_point.hpp>
+#include <lfs.h>
+
+namespace purefs::fs::drivers
+{
+
+ class mount_point_littlefs final : public purefs::fs::internal::mount_point
+ {
+ public:
+ mount_point_littlefs(std::shared_ptr<blkdev::internal::disk_handle> diskh,
+ std::string_view path,
+ unsigned flags,
+ std::shared_ptr<filesystem_operations> fs)
+ : mount_point(diskh, path, flags, fs)
+ {}
+ virtual ~mount_point_littlefs() = default;
+
+ [[nodiscard]] auto lfs_config() noexcept
+ {
+ return &m_lfs_conf;
+ }
+ [[nodiscard]] auto lfs_mount() noexcept
+ {
+ return &m_lfs_mount;
+ }
+
+ private:
+ auto native_root() const noexcept -> std::string_view override
+ {
+ return "/";
+ }
+ struct lfs_config m_lfs_conf
+ {};
+ lfs_t m_lfs_mount{};
+ };
+} // namespace purefs::fs::drivers
M module-vfs/drivers/include/purefs/fs/drivers/mount_point_vfat.hpp => module-vfs/drivers/include/purefs/fs/drivers/mount_point_vfat.hpp +3 -1
@@ 18,7 18,7 @@ namespace purefs::fs::drivers
: mount_point(diskh, path, flags, fs)
{}
virtual ~mount_point_vfat() = default;
- auto fatfs() noexcept
+ [[nodiscard]] auto fatfs() noexcept
{
return &m_fatfs;
}
@@ 41,6 41,8 @@ namespace purefs::fs::drivers
{
return (m_ff_drive[0] == ' ') ? (-1) : (m_ff_drive[0] - '0');
}
+
+ private:
auto native_root() const noexcept -> std::string_view override
{
return ff_drive();
A module-vfs/drivers/include/thirdparty/littlefs/volume_mapper.hpp => module-vfs/drivers/include/thirdparty/littlefs/volume_mapper.hpp +33 -0
@@ 0,0 1,33 @@
+// 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 <purefs/blkdev/defs.hpp>
+#include <memory>
+
+namespace purefs::blkdev
+{
+ class disk_manager;
+}
+struct lfs_config;
+
+namespace purefs::fs::drivers::littlefs::internal
+{
+
+ /**
+ * Append volume and configure LFS
+ * @param lfs Lfs structure in the mount point
+ * @param diskmm Disk manager
+ * @param diskh Disk handle in manager
+ * @return Error code or success
+ */
+ int append_volume(lfs_config &lfsc, std::shared_ptr<blkdev::disk_manager> diskmm, blkdev::disk_fd diskh);
+
+ /** Deconfigure volume
+ *
+ * @param lfsc LFs configuration structure
+ */
+ void remove_volume(lfs_config &lfsc);
+
+} // namespace purefs::fs::drivers::littlefs::internal
A module-vfs/drivers/src/purefs/fs/filesystem_littlefs.cpp => module-vfs/drivers/src/purefs/fs/filesystem_littlefs.cpp +23 -0
@@ 0,0 1,23 @@
+// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include <purefs/fs/drivers/filesystem_littlefs.hpp>
+#include <purefs/fs/drivers/mount_point_littlefs.hpp>
+#include <lfs.h>
+
+namespace purefs::fs::drivers
+{
+
+ auto filesystem_littlefs::mount_prealloc(std::shared_ptr<blkdev::internal::disk_handle> diskh,
+ std::string_view path,
+ unsigned int flags) -> fsmount
+ {
+ return std::make_shared<mount_point_littlefs>(diskh, path, flags, shared_from_this());
+ }
+
+ auto filesystem_littlefs::mount(fsmount mnt) noexcept -> int
+ {
+ return -1;
+ }
+
+} // namespace purefs::fs::drivers
M module-vfs/drivers/src/purefs/fs/filesystem_vfat.cpp => module-vfs/drivers/src/purefs/fs/filesystem_vfat.cpp +1 -1
@@ 8,7 8,7 @@
#include <purefs/fs/drivers/file_handle_vfat.hpp>
#include <purefs/fs/drivers/directory_handle_vfat.hpp>
#include <log/log.hpp>
-#include <volume_mapper.hpp>
+#include <fatfs/volume_mapper.hpp>
#include <ff.h>
#include <sys/statvfs.h>
#include <limits.h>
A module-vfs/drivers/src/thirdparty/littlefs/lfs_glue.cpp => module-vfs/drivers/src/thirdparty/littlefs/lfs_glue.cpp +142 -0
@@ 0,0 1,142 @@
+// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+#include <littlefs/volume_mapper.hpp>
+#include <lfs.h>
+#include <purefs/blkdev/disk_handle.hpp>
+#include <purefs/blkdev/disk_manager.hpp>
+#include <log/log.hpp>
+
+namespace purefs::fs::drivers::littlefs::internal
+{
+
+ // LFS io API
+ namespace
+ {
+ namespace lfs_io
+ {
+
+ class io_context
+ {
+ public:
+ io_context(std::shared_ptr<blkdev::disk_manager> diskmm, blkdev::disk_fd diskh, size_t _sector_size)
+ : disk(diskmm), disk_h(diskh), sector_size(_sector_size)
+ {}
+ const std::weak_ptr<blkdev::disk_manager> disk;
+ const blkdev::disk_fd disk_h;
+ const size_t sector_size;
+ };
+
+ int read(const struct lfs_config *lfsc, lfs_block_t block, lfs_off_t off, void *buffer, lfs_size_t size)
+ {
+ auto ctx = reinterpret_cast<io_context *>(lfsc->context);
+ if (!ctx) {
+ return LFS_ERR_IO;
+ }
+ auto diskmm = ctx->disk.lock();
+ if (!diskmm) {
+ return LFS_ERR_IO;
+ }
+ const auto lba = (uint64_t(lfsc->block_size) * block + off) / ctx->sector_size;
+ if (off % ctx->sector_size) {
+ LOG_ERROR("Partial offset not supported");
+ return LFS_ERR_IO;
+ }
+ const std::size_t lba_sz = (size * lfsc->block_size) / ctx->sector_size;
+ const auto err = diskmm->read(ctx->disk_h, buffer, lba, lba_sz);
+ if (err) {
+ LOG_ERROR("Sector read error %i", err);
+ }
+ return err;
+ }
+
+ int prog(
+ const struct lfs_config *lfsc, lfs_block_t block, lfs_off_t off, const void *buffer, lfs_size_t size)
+ {
+ auto ctx = reinterpret_cast<io_context *>(lfsc->context);
+ if (!ctx) {
+ return LFS_ERR_IO;
+ }
+ auto diskmm = ctx->disk.lock();
+ if (!diskmm) {
+ return LFS_ERR_IO;
+ }
+ const auto lba = (uint64_t(lfsc->block_size) * block + off) / ctx->sector_size;
+ if (off % ctx->sector_size) {
+ LOG_ERROR("Partial offset not supported");
+ return LFS_ERR_IO;
+ }
+ const std::size_t lba_sz = (size * lfsc->block_size) / ctx->sector_size;
+ const auto err = diskmm->write(ctx->disk_h, buffer, lba, lba_sz);
+ if (err) {
+ LOG_ERROR("Sector read error %i", err);
+ }
+ return err;
+ }
+
+ int erase(const struct lfs_config *lfsc, lfs_block_t block)
+ {
+ auto ctx = reinterpret_cast<io_context *>(lfsc->context);
+ if (!ctx) {
+ return LFS_ERR_IO;
+ }
+ auto diskmm = ctx->disk.lock();
+ if (!diskmm) {
+ return LFS_ERR_IO;
+ }
+ const auto lba = (uint64_t(lfsc->block_size) * block) / ctx->sector_size;
+ const auto lba_sz = lfsc->block_size / ctx->sector_size;
+ int err = diskmm->erase(ctx->disk_h, lba, lba_sz);
+ if (err) {
+ LOG_ERROR("Unable to erase area ret: %i", err);
+ }
+ return err;
+ }
+
+ int sync(const struct lfs_config *lfsc)
+ {
+ auto ctx = reinterpret_cast<io_context *>(lfsc->context);
+ if (!ctx) {
+ return LFS_ERR_IO;
+ }
+ auto diskmm = ctx->disk.lock();
+ if (!diskmm) {
+ return LFS_ERR_IO;
+ }
+ int err = diskmm->sync(ctx->disk_h);
+ if (err) {
+ LOG_ERROR("Unable to sync %i", err);
+ }
+ return err;
+ }
+ } // namespace lfs_io
+ } // namespace
+
+ int append_volume(lfs_config &lfsc, std::shared_ptr<blkdev::disk_manager> diskmm, blkdev::disk_fd diskh)
+ {
+ const auto sect_size = diskmm->get_info(diskh, blkdev::info_type::sector_size);
+ if (sect_size < 0) {
+ LOG_ERROR("Unable to get sector size %li", sect_size);
+ return sect_size;
+ }
+ if (sect_size % lfsc.block_size || lfsc.block_size < sect_size) {
+ LOG_ERROR("Sector size doesn't match block size");
+ return -ERANGE;
+ }
+ auto ctx = new lfs_io::io_context(diskmm, diskh, sect_size);
+ lfsc.context = ctx;
+ lfsc.read = lfs_io::read;
+ lfsc.prog = lfs_io::prog;
+ lfsc.erase = lfs_io::erase;
+ lfsc.sync = lfs_io::sync;
+ lfsc.context = ctx;
+ return 0;
+ }
+
+ void remove_volume(lfs_config &lfsc)
+ {
+ if (lfsc.context) {
+ delete reinterpret_cast<lfs_io::io_context *>(lfsc.context);
+ }
+ }
+
+} // namespace purefs::fs::drivers::littlefs::internal