M .gitmodules => .gitmodules +3 -3
@@ 53,9 53,6 @@
[submodule "module-utils/magic_enum"]
path = module-utils/magic_enum
url = git@github.com:Neargye/magic_enum.git
-[submodule "module-vfs/board/freeRTOS_FAT"]
- path = module-vfs/board/freeRTOS_FAT
- url = ../Lab-Project-FreeRTOS-FAT.git
[submodule "module-utils/tinyexpr"]
path = module-utils/tinyexpr
url = https://github.com/codeplea/tinyexpr.git
@@ 71,3 68,6 @@
[submodule "module-vfs/thirdparty/lfsfs/littlefs"]
path = module-vfs/thirdparty/lfsfs/littlefs
url = https://github.com/littlefs-project/littlefs.git
+[submodule "module-utils/parallel-hashmap"]
+ path = module-utils/parallel-hashmap
+ url = https://github.com/greg7mdp/parallel-hashmap.git
M board/linux/libiosyscalls/CMakeLists.txt => board/linux/libiosyscalls/CMakeLists.txt +11 -8
@@ 5,26 5,29 @@ project(iosyscalls VERSION 1.0
set(SOURCES
- ${CMAKE_CURRENT_SOURCE_DIR}/src/syscalls_stdio.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/src/syscalls_scan_family.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/src/syscalls_posix.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/src/dirent_support.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/src/dirent.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/syscalls_stdio.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/syscalls_scan_family.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/syscalls_posix.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/iosyscalls.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/src/dirent.cpp
)
+
set(INCLUDES
"${CMAKE_CURRENT_SOURCE_DIR}/include"
- "${CMAKE_SOURCE_DIR}/module-vfs/board/freeRTOS_FAT/include"
- "${CMAKE_SOURCE_DIR}/module-os/FreeRTOS/include"
"${CMAKE_SOURCE_DIR}/module-os/board/linux"
- "${CMAKE_SOURCE_DIR}/module-vfs/board/free_rtos_custom/include"
+ "${CMAKE_SOURCE_DIR}/module-os/RTOSWrapper/include"
+ "${CMAKE_SOURCE_DIR}/module-utils/parallel-hashmap"
"${CMAKE_SOURCE_DIR}/module-utils"
+ "${CMAKE_SOURCE_DIR}/module-vfs/include/user"
+ "${CMAKE_SOURCE_DIR}/module-vfs/include/internal"
)
add_library(${PROJECT_NAME} SHARED ${SOURCES})
+target_compile_options( ${PROJECT_NAME} PRIVATE "-Wno-nonnull-compare" )
get_target_property( target_options ${PROJECT_NAME} COMPILE_OPTIONS)
list(REMOVE_ITEM target_options "-fsanitize=address")
set_property(TARGET ${PROJECT_NAME} PROPERTY COMPILE_OPTIONS ${target_options} )
M board/linux/libiosyscalls/include/debug.hpp => board/linux/libiosyscalls/include/debug.hpp +6 -12
@@ 3,19 3,13 @@
#pragma once
-#include <stdio.h>
-#include <dlfcn.h>
-
-namespace vfsn::debug::internal {
- static inline void trace_syscall( const char* fn)
- {
- int (*real_fprintf)(FILE *__restrict __stream, const char *__restrict __format, ...);
- real_fprintf = reinterpret_cast<decltype(real_fprintf)>(dlsym(RTLD_NEXT, "fprintf"));
- real_fprintf(stderr,">>>>>>> CALL FUNC [%s] <<<<<<<\n", fn );
- }
-}
#ifdef DEBUG_SHARED_LIBRARY_FS_LIB
-#define TRACE_SYSCALL() vfsn::debug::internal::trace_syscall(__PRETTY_FUNCTION__)
+namespace vfsn::linux::internal {
+ void debug_trace_syscall(const char* fn, const char* format, ...);
+}
+#define TRACE_SYSCALL() vfsn::linux::internal::debug_trace_syscall(__PRETTY_FUNCTION__,"")
+#define TRACE_SYSCALLN(format,...) vfsn::linux::internal::debug_trace_syscall(__PRETTY_FUNCTION__,format,__VA_ARGS__)
#else
#define TRACE_SYSCALL() do {} while(0)
+#define TRACE_SYSCALLN(format,...) do {} while(0)
#endif
D board/linux/libiosyscalls/include/dirent_support.hpp => board/linux/libiosyscalls/include/dirent_support.hpp +0 -19
@@ 1,19 0,0 @@
-// 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 <dirent.h>
-
-
-namespace vfsn::linux::internal::diren
-{
- struct DIR_ITER {
- void *dir_state = nullptr;
- char name_state[NAME_MAX+1] = { '\0' };
- };
-
- DIR_ITER *diropen(int &_errno_, const char *path);
- int dirreset(int &_errno_, DIR_ITER *state);
- int dirnext(int &_errno_, DIR_ITER *state);
- int dirclose(int &_errno_, DIR_ITER *state);
-} // namespace vfsn::internal::dirent
D board/linux/libiosyscalls/include/internal.hpp => board/linux/libiosyscalls/include/internal.hpp +0 -17
@@ 1,17 0,0 @@
-// 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 <stddef.h>
-
-struct _FF_FILE;
-struct _IO_FILE;
-
-namespace vfsn::linux::internal
-{
- int ff_file_to_fd(_FF_FILE *fil);
- _FF_FILE * fd_to_ff_file(int fd);
- const char* relative_to_root( char *out_path, size_t out_path_len, const char *inpath );
- bool is_ff_handle(_IO_FILE* descriptor);
- bool vfs_is_initialized();
-}
A board/linux/libiosyscalls/include/iosyscalls.hpp => board/linux/libiosyscalls/include/iosyscalls.hpp +45 -0
@@ 0,0 1,45 @@
+// 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 <stddef.h>
+#include <stdio.h>
+#include <purefs/vfs_subsystem.hpp>
+
+namespace vfsn::linux::internal
+{
+ bool redirect_to_image();
+ bool is_image_handle(const FILE* fil);
+ int native_fd_to_image_fd(int fd);
+ int image_fd_to_native_fd(int fd);
+ bool is_image_fd(int fd);
+ bool redirect_to_image(const char* inpath);
+ const char* npath_translate(const char* inpath, char *buffer);
+
+ struct FILEX {
+ int fd {0};
+ int error {0};
+ int ungetchar {-1};
+ };
+ FILEX* allocate_filex(int fd);
+ bool is_filex(const void* fd);
+ void remove_filex(FILEX *fil);
+
+ template <class Base, typename T, typename... Args>
+ auto invoke_fs( T Base::*lfs_fun, Args&& ... args)
+ -> decltype((static_cast<Base *>(nullptr)->*lfs_fun)(std::forward<Args>(args)...))
+ {
+ auto vfs = purefs::subsystem::vfs_core();
+ if(!vfs) {
+ errno = EIO;
+ return 0;
+ }
+ auto ret = (vfs.get()->*lfs_fun)(std::forward<Args>(args)...);
+ if(ret < 0) {
+ errno = -ret;
+ ret = -1;
+ }
+ return ret;
+ }
+}
+
M board/linux/libiosyscalls/src/dirent.cpp => board/linux/libiosyscalls/src/dirent.cpp +198 -110
@@ 1,99 1,156 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#include <ff_stdio.h>
+
+#include <iosyscalls.hpp>
+#include <purefs/vfs_subsystem.hpp>
+#include "debug.hpp"
+
#include <dirent.h>
#include <errno.h>
#include <cstring>
-#include "dirent_support.hpp"
-#include "debug.hpp"
-#include <internal.hpp>
+#include <dlfcn.h>
+#include <sys/stat.h>
struct __dirstream {
- long int position;
- vfsn::linux::internal::diren::DIR_ITER* dir_data;
- struct dirent file_data;
+ purefs::fs::filesystem::fsdir dirh;
+ struct dirent dir_data;
+ size_t position;
};
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wnonnull-compare"
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
extern "C" {
using namespace vfsn::linux::internal;
DIR *opendir(const char *dirname)
{
- TRACE_SYSCALL();
- if(!dirname) {
+ __dirstream* ret {};
+ if(!dirname)
+ {
errno = EINVAL;
- return nullptr;
- }
- if(!vfs_is_initialized()) {
- errno = EIO;
- return nullptr;
}
- auto dir = new DIR;
- char dirbuf[ffconfigMAX_FILENAME];
- dir->dir_data = diren::diropen(errno, relative_to_root(dirbuf,sizeof dirbuf,dirname));
- if (!dir->dir_data) {
- delete dir;
- return nullptr;
+ else
+ {
+ if( redirect_to_image() )
+ {
+ auto vfs = purefs::subsystem::vfs_core();
+ if(!vfs)
+ {
+ errno = EIO;
+ }
+ else
+ {
+ ret = new(std::nothrow)__dirstream;
+ if(!ret)
+ {
+ errno = ENOMEM;
+ }
+ else
+ {
+ ret->position = 0;
+ ret->dirh = vfs->diropen(dirname);
+ if(!ret->dirh)
+ {
+ delete ret;
+ errno = EIO;
+ ret = nullptr;
+ }
+ else if(ret->dirh->error())
+ {
+ errno = -ret->dirh->error();
+ delete ret;
+ ret = nullptr;
+ }
+ }
+ }
+ }
+ else
+ {
+ char tmp[PATH_MAX];
+ const auto newpath = npath_translate(dirname,tmp);
+ auto r_opendir = reinterpret_cast<DIR* (*)(const char *)>(dlsym(RTLD_NEXT,"opendir"));
+ ret = r_opendir(newpath);
+ }
}
- dir->position = 0;
- dir->file_data.d_ino = -1;
- dir->file_data.d_name[0] = '\0';
- return dir;
+ TRACE_SYSCALLN("(%s)=%p errno=%i",dirname,ret,errno);
+ return ret;
}
+
__asm__(".symver diropen,diropen@GLIBC_2.2.5");
int closedir(DIR *dirp)
{
- TRACE_SYSCALL();
- if (!dirp) {
- errno = EBADF;
- return -1;
- }
- if(!vfs_is_initialized()) {
- errno = EIO;
- return -1;
- }
- auto res = diren::dirclose(errno, dirp->dir_data);
- delete dirp;
- return res;
+ int ret {};
+ do {
+ if (!dirp) {
+ errno = EBADF;
+ ret = -1;
+ break;
+ }
+ if(redirect_to_image()) {
+ auto vfs = purefs::subsystem::vfs_core();
+ if(!vfs) {
+ errno = EIO;
+ ret = -1;
+ break;
+ }
+ ret = vfs->dirclose(dirp->dirh);
+ if(ret < 0) {
+ errno = -ret;
+ ret = -1;
+ }
+ delete dirp;
+ } else {
+ auto r_closedir = reinterpret_cast<int (*)(DIR*)>(dlsym(RTLD_NEXT,"closedir"));
+ ret = r_closedir(dirp);
+ }
+ } while(0);
+ TRACE_SYSCALLN("(%p)=%i errno=%i", dirp, ret, errno);
+ return ret;
}
__asm__(".symver closedir,closedir@GLIBC_2.2.5");
struct dirent *readdir(DIR *dirp)
{
- TRACE_SYSCALL();
- if (!dirp) {
- errno = EBADF;
- return nullptr;
- }
- if(!vfs_is_initialized()) {
- errno = EIO;
- return nullptr;
- }
- auto olderrno{errno};
- auto res = diren::dirnext(errno, dirp->dir_data);
- auto fff = reinterpret_cast<FF_FindData_t *>(dirp->dir_data->dir_state);
- if (res < 0) {
- if (errno == pdFREERTOS_ERRNO_ENMFILE) {
- errno = olderrno;
+ dirent* ret {};
+ do {
+ if (!dirp) {
+ errno = EBADF;
+ break;
}
- return nullptr;
- }
- dirp->position += 1;
- if (strnlen(fff->pcFileName, NAME_MAX) >= sizeof(dirp->file_data.d_name)) {
- errno = EOVERFLOW;
- return nullptr;
- }
- dirp->file_data.d_ino = fff->xDirectoryEntry.ulObjectCluster;
- dirp->file_data.d_type = (fff->ucAttributes & FF_FAT_ATTR_DIR) ? DT_DIR : DT_REG;
- dirp->file_data.d_reclen = std::strlen( fff->pcFileName );
- std::strncpy(dirp->file_data.d_name, fff->pcFileName, sizeof(dirp->file_data.d_name));
- return &dirp->file_data;
+ if(redirect_to_image()) {
+ auto vfs = purefs::subsystem::vfs_core();
+ if(!vfs) {
+ errno = EIO;
+ break;
+ }
+ std::string fname;
+ struct stat stdata;
+ auto res = vfs->dirnext(dirp->dirh, fname, stdata);
+ if(res < 0) {
+ if(res != -ENODATA) {
+ errno = -res;
+ }
+ break;
+ } else {
+ if (fname.size() >= sizeof(dirp->dir_data.d_name)) {
+ errno = EOVERFLOW;
+ break;
+ }
+ dirp->position += 1;
+ dirp->dir_data.d_ino = stdata.st_ino;
+ dirp->dir_data.d_type = S_ISREG(stdata.st_mode)?DT_REG:DT_DIR;
+ dirp->dir_data.d_reclen = fname.size();
+ std::strncpy(dirp->dir_data.d_name,fname.c_str(), sizeof(dirp->dir_data.d_name));
+ ret = &dirp->dir_data;
+ }
+ } else {
+ auto r_readdir = reinterpret_cast<struct dirent* (*)(DIR*)>(dlsym(RTLD_NEXT,"readdir"));
+ ret = r_readdir(dirp);
+ }
+ } while(0);
+ TRACE_SYSCALLN("(%p)=%p errno=%i", dirp,ret,errno);
+ return ret;
}
__asm__(".symver readdir,readdir@GLIBC_2.2.5");
@@ 104,30 161,36 @@ extern "C" {
errno = EBADF;
return -1;
}
- if(!vfs_is_initialized()) {
- errno = EIO;
- return -1;
- }
- auto olderrno{errno};
- auto res = diren::dirnext(errno, dirp->dir_data);
- auto fff = reinterpret_cast<FF_FindData_t *>(dirp->dir_data->dir_state);
- if (res < 0) {
- res = errno;
- if (errno == pdFREERTOS_ERRNO_ENMFILE) {
- res = 0;
+ if(redirect_to_image()) {
+ auto vfs = purefs::subsystem::vfs_core();
+ if(!vfs) {
+ errno = EIO;
+ return -1;
}
- errno = olderrno;
- return res;
- }
- dirp->position += 1;
- if (strnlen(fff->pcFileName, NAME_MAX) >= sizeof(entry->d_name)) {
- return EOVERFLOW;
+ std::string fname;
+ struct stat stdata;
+ auto res = vfs->dirnext(dirp->dirh, fname, stdata);
+ if(res < 0) {
+ errno = -res;
+ res = -1;
+ return res;
+ } else {
+ if (fname.size() >= sizeof(entry->d_name)) {
+ errno = EOVERFLOW;
+ return -1;
+ }
+ dirp->position += 1;
+ entry->d_ino = stdata.st_ino;
+ entry->d_type = S_ISREG(stdata.st_mode)?DT_REG:DT_DIR;
+ entry->d_reclen = fname.size();
+ std::strncpy(entry->d_name,fname.c_str(), sizeof(entry->d_name));
+ *result = entry;
+ return 0;
+ }
+ } else {
+ auto r_readdir_r = reinterpret_cast<int (*)(DIR*, struct dirent*, struct dirent**)>(dlsym(RTLD_NEXT,"readdir_r"));
+ return r_readdir_r(dirp,entry,result);
}
- entry->d_ino = fff->xDirectoryEntry.ulObjectCluster;
- entry->d_type = (fff->ucAttributes & FF_FAT_ATTR_DIR) ? DT_DIR : DT_REG;
- std::strncpy(entry->d_name, fff->pcFileName, sizeof(entry->d_name));
- *result = entry;
- return 0;
}
__asm__(".symver readdir_r,readdir_r@GLIBC_2.2.5");
@@ 138,12 201,23 @@ extern "C" {
errno = EBADF;
return;
}
- if(!vfs_is_initialized()) {
- errno = EIO;
- return;
+ if(redirect_to_image())
+ {
+ auto vfs = purefs::subsystem::vfs_core();
+ if(!vfs) {
+ return;
+ }
+ auto res = vfs->dirreset(dirp->dirh);
+ if(res < 0) {
+ return;
+ }
+ dirp->position = 0;
+ }
+ else
+ {
+ auto r_rewinddir = reinterpret_cast<void (*)(DIR*)>(dlsym(RTLD_NEXT,"rewinddir"));
+ r_rewinddir(dirp);
}
- diren::dirreset(errno, dirp->dir_data);
- dirp->position = 0;
}
__asm__(".symver rewinddir,rewinddir@GLIBC_2.2.5");
@@ 154,19 228,29 @@ extern "C" {
errno = EBADF;
return;
}
- if(!vfs_is_initialized()) {
- errno = EIO;
- return;
- }
- if (loc < 0) {
- return;
- }
- if (dirp->position > loc) {
- diren::dirreset(errno, dirp->dir_data);
- dirp->position = 0;
+ if( redirect_to_image() )
+ {
+ if (loc < 0) {
+ return;
+ }
+ auto vfs = purefs::subsystem::vfs_core();
+ if(!vfs) {
+ return;
+ }
+ if (long(dirp->position) > loc) {
+ vfs->dirreset(dirp->dirh);
+ dirp->position = 0;
+ }
+ std::string name;
+ struct stat st;
+ while ((long(dirp->position) < loc) && (vfs->dirnext(dirp->dirh,name,st))>=0) {
+ dirp->position += 1;
+ }
}
- while ((dirp->position < loc) && (diren::dirnext(errno, dirp->dir_data) >= 0)) {
- dirp->position += 1;
+ else
+ {
+ auto r_seekdir = reinterpret_cast<void (*)(DIR*,long int)>(dlsym(RTLD_NEXT,"seekdir"));
+ r_seekdir(dirp,loc);
}
}
__asm__(".symver seekdir,seekdir@GLIBC_2.2.5");
@@ 178,13 262,17 @@ extern "C" {
errno = EBADF;
return -1;
}
- if(!vfs_is_initialized()) {
- errno = EIO;
- return -1;
+ if( redirect_to_image() )
+ {
+ return dirp->position;
+ }
+ else
+ {
+ auto r_telldir = reinterpret_cast<long int(*)(DIR*)>(dlsym(RTLD_NEXT,"telldir"));
+ return r_telldir(dirp);
}
- return dirp->position;
}
__asm__(".symver telldir,telldir@GLIBC_2.2.5");
}
-#pragma GCC diagnostic pop
+
D board/linux/libiosyscalls/src/dirent_support.cpp => board/linux/libiosyscalls/src/dirent_support.cpp +0 -93
@@ 1,93 0,0 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#include "dirent_support.hpp"
-#include <cstring>
-#include <ff_stdio.h>
-#include <errno.h>
-#include <new>
-#include <dirent.h>
-
-
-namespace vfsn::linux::internal::diren
-{
- DIR_ITER *diropen(int &_errno_, const char *path)
- {
- FF_Stat_t fs;
- if (ff_stat(path, &fs)) {
- _errno_ = stdioGET_ERRNO();
- if (_errno_ == EFAULT)
- _errno_ = ENOENT;
- return nullptr;
- }
- if (!(fs.st_mode & FF_IFDIR)) {
- _errno_ = ENOTDIR;
- return nullptr;
- }
- auto ret = new (std::nothrow) DIR_ITER;
- if (!ret) {
- _errno_ = ENOMEM;
- return nullptr;
- }
- ret->dir_state = nullptr;
- std::strncpy(ret->name_state, path, sizeof(ret->name_state));
- return ret;
- }
-
- int dirreset(int &_errno_, DIR_ITER *state)
- {
- if( !state ) {
- _errno_ = EINVAL;
- return -1;
- }
- if (state->dir_state) {
- delete reinterpret_cast<FF_FindData_t *>(state->dir_state);
- state->dir_state = nullptr;
- _errno_ = 0;
- return 0;
- }
- else {
- _errno_ = EBADF;
- return -1;
- }
- }
- int dirnext(int &_errno_, DIR_ITER *state)
- {
- int ret;
- if(!state) {
- _errno_ = EINVAL;
- return -1;
- }
- if (!state->dir_state) {
- auto fdd = new (std::nothrow) FF_FindData_t;
- if (!fdd) {
- _errno_ = ENOMEM;
- return -1;
- }
- std::memset(fdd, 0, sizeof(*fdd));
- ret = ff_findfirst(state->name_state, fdd);
- state->dir_state = fdd;
- }
- else {
- auto fdd = static_cast<FF_FindData_t *>(state->dir_state);
- ret = ff_findnext(fdd);
- }
- _errno_ = stdioGET_ERRNO();
- if (_errno_ == EFAULT)
- _errno_ = ENOENT;
- return ret;
- }
-
- int dirclose(int &_errno_, DIR_ITER *state)
- {
- if(!state) {
- _errno_ = 0;
- return 0;
- }
- if (state->dir_state) {
- delete reinterpret_cast<FF_FindData_t *>(state->dir_state);
- }
- delete state;
- _errno_ = 0;
- return 0;
- }
-} // namespace vfsn::internal::dirent
A board/linux/libiosyscalls/src/iosyscalls.cpp => board/linux/libiosyscalls/src/iosyscalls.cpp +164 -0
@@ 0,0 1,164 @@
+// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#include <iosyscalls.hpp>
+#include <cstdlib>
+#include <cstring>
+#include <pthread.h>
+#include <parallel_hashmap/phmap.h>
+#include <stdio.h>
+#include <dlfcn.h>
+#include <stdarg.h>
+#include <debug.hpp>
+
+namespace {
+ constexpr auto ENV_NAME = "IOSYSCALLS_REDIRECT_TO_IMAGE";
+ constexpr auto FIRST_FILEDESC = 64'566'756;
+ bool g_readed = false ;
+ bool g_redirect = false;
+ constexpr const char * ALLOWED_PATHS[] = {
+ "/dev/",
+ "/etc/",
+ "/sys/",
+ "PurePhone.img",
+ nullptr,
+ };
+ constexpr const char * EXCLUDED_PATHS[] = {
+ "/sys/user",
+ "/sys/factory-test",
+ "/sys/current/assets",
+ "/sys/updates",
+ nullptr,
+ };
+
+ constexpr const char * TRANSLATION_PATHS[] =
+ {
+ "sys/user",
+ "sys/factory-test",
+ "assets",
+ "sys/updates",
+ nullptr
+ };
+
+ pthread_mutex_t g_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+ phmap::flat_hash_set<vfsn::linux::internal::FILEX*> g_fdlist;
+}
+
+namespace vfsn::linux::internal
+{
+ bool redirect_to_image()
+ {
+ if(!g_readed) {
+ const auto env = std::getenv(ENV_NAME);
+ g_redirect = env && !std::strcmp(env,"1");
+ g_readed = true;
+ }
+ return g_redirect;
+ }
+
+ bool redirect_to_image(const char* inpath)
+ {
+ auto native_redirect = redirect_to_image();
+ auto redirect = native_redirect;
+ if(native_redirect) {
+ for(auto path=ALLOWED_PATHS; *path; ++path) {
+ if( std::strstr(inpath,*path)==inpath) {
+ redirect = false;
+ break;
+ }
+ }
+ }
+ if(native_redirect && !redirect)
+ {
+ for(auto path=EXCLUDED_PATHS; *path; ++path) {
+ if( std::strstr(inpath,*path)==inpath) {
+ redirect = true;
+ break;
+ }
+ }
+ }
+ return redirect;
+ }
+
+ const char* npath_translate(const char* inpath, char *buffer)
+ {
+ for(size_t trans_pos=0; EXCLUDED_PATHS[trans_pos]; ++trans_pos) {
+ if( std::strstr(inpath,EXCLUDED_PATHS[trans_pos])==inpath) {
+ std::strncpy(buffer,TRANSLATION_PATHS[trans_pos],PATH_MAX);
+ std::strncat(buffer,inpath+std::strlen(EXCLUDED_PATHS[trans_pos]), PATH_MAX);
+ return buffer;
+ }
+ }
+ return inpath;
+ }
+
+ bool is_image_handle(const FILE* fil)
+ {
+ return false;
+ }
+
+ int native_fd_to_image_fd(int fd)
+ {
+ return FIRST_FILEDESC + fd;
+ }
+
+ int image_fd_from_native_fd(int fd)
+ {
+ if(fd < FIRST_FILEDESC ) {
+ return -1;
+ } else {
+ return fd - FIRST_FILEDESC;
+ }
+ }
+
+ bool is_image_fd(int fd)
+ {
+ return fd >= FIRST_FILEDESC;
+ }
+
+ FILEX* allocate_filex(int fd)
+ {
+ auto ret = new FILEX;
+ ret->fd = fd;
+ pthread_mutex_lock(&g_lock);
+ g_fdlist.emplace( ret );
+ pthread_mutex_unlock(&g_lock);
+ return ret;
+ }
+
+ bool is_filex(const void* fd)
+ {
+ if(fd==nullptr) {
+ return false;
+ }
+ pthread_mutex_lock(&g_lock);
+ auto fres = g_fdlist.find(reinterpret_cast<const FILEX*>(fd));
+ auto isfilex = ( fres != g_fdlist.end() );
+ pthread_mutex_unlock(&g_lock);
+ return isfilex;
+ }
+
+ void remove_filex(FILEX *fil)
+ {
+ pthread_mutex_lock(&g_lock);
+ auto fres = g_fdlist.find(fil);
+ if(fres != g_fdlist.end())
+ {
+ g_fdlist.erase(fres);
+ delete fil;
+ }
+ pthread_mutex_unlock(&g_lock);
+ }
+
+ void debug_trace_syscall(const char* fn, const char* format, ...)
+ {
+ auto rvprint = reinterpret_cast<decltype(&vfprintf)>(dlsym(RTLD_NEXT, "vfprintf"));
+ auto rprint = reinterpret_cast<decltype(&fprintf)>(dlsym(RTLD_NEXT, "fprintf"));
+ rprint(stderr,">>>>>>> IOFUNC: [%s] ", fn);
+ va_list args;
+ va_start(args, format);
+ rvprint(stderr, format, args);
+ va_end(args);
+ rprint(stderr," >>>>>>>>>>>\n");
+ }
+}
M board/linux/libiosyscalls/src/syscalls_posix.cpp => board/linux/libiosyscalls/src/syscalls_posix.cpp +229 -204
@@ 1,8 1,7 @@
// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-#include "internal.hpp"
-#include <ff_stdio.h>
+#include <iosyscalls.hpp>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
@@ 10,159 9,136 @@
#include <dlfcn.h>
#include <fcntl.h>
#include <stdio.h>
+#include <stdlib.h>
#include <cstring>
+#include <stdarg.h>
+#include <limits.h>
+
#include "debug.hpp"
+#include <purefs/fs/filesystem.hpp>
-//NOTE: It will be removed in later stage
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
namespace
{
int (*real_fprintf)(FILE *__restrict __stream, const char *__restrict __format, ...);
- int (*real_xstat)(int ver, const char * path, struct stat * stat_buf);
- int (*real_lxstat)(int ver, const char * path, struct stat * stat_buf);
- int (*real_fxstat)(int ver, int fildes, struct stat * stat_buf);
- int (*real_fcntl)(int __fd, int __cmd, ...);
- int (*real_fcntl64) (int __fd, int __cmd, ...);
void __attribute__((constructor)) _lib_posix_initialize()
{
real_fprintf = reinterpret_cast<decltype(real_fprintf)>(dlsym(RTLD_NEXT, "fprintf"));
- real_xstat = reinterpret_cast<decltype(real_xstat)>(dlsym(RTLD_NEXT, "__xstat"));
- real_lxstat = reinterpret_cast<decltype(real_lxstat)>(dlsym(RTLD_NEXT, "__lxstat"));
- real_fxstat = reinterpret_cast<decltype(real_fxstat)>(dlsym(RTLD_NEXT, "__fxstat"));
- real_fcntl = reinterpret_cast<decltype(real_fcntl)>(dlsym(RTLD_NEXT, "fcntl"));
- real_fcntl64 = reinterpret_cast<decltype(real_fcntl64)>(dlsym(RTLD_NEXT, "fcntl64"));
- if(!real_fprintf || !real_xstat || !real_lxstat || !real_fxstat
- || !real_fcntl || !real_fcntl64 )
+ if(!real_fprintf)
{
abort();
}
}
- int ff_cstat(const char *file, struct stat *pstat)
- {
- namespace vfs = vfsn::linux::internal;
- char filebuf[ffconfigMAX_FILENAME];
- FF_Stat_t stat_ff;
- auto ret = ff_stat(vfs::relative_to_root(filebuf,sizeof filebuf,file), &stat_ff);
- std::memset(pstat, 0, sizeof(*pstat));
- if (!ret && pstat) {
- pstat->st_ino = stat_ff.st_ino;
- pstat->st_size = stat_ff.st_size;
- pstat->st_dev = stat_ff.st_dev;
- // Linux mode compat
- if (stat_ff.st_mode == FF_IFREG)
- pstat->st_mode = S_IFREG | 0666;
- if (stat_ff.st_mode == FF_IFDIR)
- pstat->st_mode = S_IFDIR | 0777;
- }
- errno = stdioGET_ERRNO();
- // NOTE: ff_stdio uses wrong errno NOADDRESS
- if (errno == EFAULT)
- errno = ENOENT;
- return ret;
- }
}
+
extern "C" {
- namespace vfs = vfsn::linux::internal;
+ using namespace vfsn::linux::internal;
int link(const char *oldpath, const char *newpath)
{
TRACE_SYSCALL();
- errno = ENOSYS;
- real_fprintf(stderr, "Unsupported syscall %s\n", __PRETTY_FUNCTION__ );
- return -1;
+ if(redirect_to_image(oldpath))
+ {
+ errno = ENOSYS;
+ real_fprintf(stderr, "Unsupported syscall %s\n", __PRETTY_FUNCTION__ );
+ return -1;
+ }
+ else
+ {
+ auto r_link = reinterpret_cast<int (*)(const char*,const char*)>(dlsym(RTLD_NEXT,"link"));
+ char tmp[PATH_MAX], tmp2[PATH_MAX];
+ const auto oldp = npath_translate(oldpath,tmp);
+ const auto newp = npath_translate(newpath,tmp2);
+ return r_link(oldp,newp);
+ }
}
__asm__(".symver link,link@GLIBC_2.2.5");
int unlink(const char *name)
{
TRACE_SYSCALL();
- if(!vfs::vfs_is_initialized()) {
- errno = EIO;
- return -1;
+ if(redirect_to_image(name))
+ {
+ return invoke_fs(&purefs::fs::filesystem::unlink, name);
+ }
+ else
+ {
+ char tmp[PATH_MAX];
+ const auto path = npath_translate(name,tmp);
+ auto r_unlink = reinterpret_cast<int (*)(const char*)>(dlsym(RTLD_NEXT,"unlink"));
+ return r_unlink(path);
}
- char namebuf[ffconfigMAX_FILENAME];
- auto ret = ff_remove(vfs::relative_to_root(namebuf,sizeof namebuf, name));
- if (ret && stdioGET_ERRNO() == EISDIR)
- ret = ff_deltree(vfs::relative_to_root(namebuf,sizeof namebuf,name), nullptr, nullptr);
- errno = stdioGET_ERRNO();
- return ret;
}
__asm__(".symver unlink,unlink@GLIBC_2.2.5");
- int stat(const char *file, struct stat *pstat) {
+ int stat(const char *file, struct stat *pstat)
+ {
TRACE_SYSCALL();
- int ret {};
- if(!vfs::vfs_is_initialized()) {
- ret = -1;
- } else {
- ret = ff_cstat(file, pstat);
+ if(redirect_to_image(file))
+ {
+ return invoke_fs(&purefs::fs::filesystem::stat, file, *pstat);
}
- if(ret) {
- real_fprintf(stderr,"WARNING: redirecting stat(%s) to the linux fs\n",file);
- ret = real_xstat(1,file,pstat);
+ else
+ {
+ char tmp[PATH_MAX];
+ const auto newfile = npath_translate(file,tmp);
+ auto r_xstat = reinterpret_cast<int (*)(int, const char*,struct stat*)>(dlsym(RTLD_NEXT, "__xstat"));
+ return r_xstat(1,newfile,pstat);
}
- return ret;
}
__asm__(".symver stat,stat@GLIBC_2.2.5");
int fstat(int fd, struct stat *pstat)
{
TRACE_SYSCALL();
- FF_FILE* fil;
- if(!vfs::vfs_is_initialized()) {
- fil = nullptr;
- } else {
- fil = vfsn::linux::internal::fd_to_ff_file(fd);
- }
- if(!fil) {
- real_fprintf(stderr,"WARNING: redirecting fstat(%i) to the linux fs\n",fd);
- return real_fxstat(1,fd,pstat);
- }
- std::memset(pstat, 0, sizeof(*pstat));
- pstat->st_ino = fil->ulObjectCluster;
- pstat->st_size = fil->ulFileSize;
- pstat->st_dev = 0;
- pstat->st_mode = S_IFREG | 0666;
- errno = 0;
- return 0;
+ if(is_image_fd(fd))
+ {
+ return invoke_fs(&purefs::fs::filesystem::fstat,fd,*pstat);
+ }
+ else
+ {
+ auto r_fxstat = reinterpret_cast<int (*)(int, int, struct stat*)>(dlsym(RTLD_NEXT, "__fxstat"));
+ return r_fxstat(1,fd,pstat);
+ }
}
__asm__(".symver fstat,fstat@GLIBC_2.2.5");
int lstat(const char *pathname, struct stat *statbuf)
{
TRACE_SYSCALL();
- int ret;
- if(!vfs::vfs_is_initialized()) {
- ret = -1;
- } else {
- ret = ff_cstat(pathname, statbuf);
+ if(redirect_to_image(pathname))
+ {
+ return invoke_fs(&purefs::fs::filesystem::stat, pathname, *statbuf);
}
- if(ret) {
- real_fprintf(stderr,"WARNING: redirecting lstat(%s) to the linux fs\n",pathname);
- ret = real_lxstat(1,pathname,statbuf);
+ else
+ {
+ char tmp[PATH_MAX];
+ const auto newpath = npath_translate(pathname,tmp);
+ auto r_lxstat = reinterpret_cast<int (*)(int, const char*,struct stat*)>(dlsym(RTLD_NEXT, "__lxstat"));
+ return r_lxstat(1,newpath,statbuf);
}
- return ret;
}
__asm__(".symver lstat,lstat@GLIBC_2.2.5");
int fcntl(int fd, int cmd, ... /* arg */ )
{
TRACE_SYSCALL();
- if( vfs::fd_to_ff_file(fd) ) {
+ if(is_image_fd(fd))
+ {
TRACE_SYSCALL();
errno = ENOSYS;
real_fprintf(stderr, "Unsupported syscall %s\n", __PRETTY_FUNCTION__ );
return -1;
- } else {
+ }
+ else
+ {
uintptr_t param;
va_list args;
+ auto r_fcntl = reinterpret_cast<int (*)(int,int,...)>(dlsym(RTLD_NEXT, "fcntl"));
va_start(args,cmd);
param = va_arg(args,uintptr_t);
- auto ret = real_fcntl(fd, cmd, param );
+ auto ret = r_fcntl(fd, cmd, param );
va_end(args);
- real_fprintf(stderr,"WARNING: redirecting fcntl (%i) to the linux fs\n",fd);
return ret;
}
}
@@ 171,7 147,8 @@ extern "C" {
int fcntl64(int fd, int cmd, ... /* arg */ )
{
TRACE_SYSCALL();
- if( vfs::fd_to_ff_file(fd) ) {
+ if(is_image_fd(fd))
+ {
TRACE_SYSCALL();
real_fprintf(stderr, "Unsupported syscall %s\n", __PRETTY_FUNCTION__ );
errno = ENOSYS;
@@ 179,11 156,11 @@ extern "C" {
} else {
uintptr_t param;
va_list args;
+ auto r_fcntl = reinterpret_cast<int (*)(int,int,...)>(dlsym(RTLD_NEXT, "fcntl64"));
va_start(args,cmd);
param = va_arg(args,uintptr_t);
- auto ret = real_fcntl(fd, cmd, param );
+ auto ret = r_fcntl(fd, cmd, param);
va_end(args);
- real_fprintf(stderr,"WARNING: redirecting fcntl (%i) to the linux fs\n",fd);
return ret;
}
}
@@ 192,52 169,78 @@ extern "C" {
int chdir(const char *path)
{
TRACE_SYSCALL();
- char pathbuf[ffconfigMAX_FILENAME];
- int ret;
- if(!vfs::vfs_is_initialized())
+ if(redirect_to_image(path))
{
- ret = -1;
- errno = -EIO;
+ return invoke_fs(&purefs::fs::filesystem::chdir, path);
}
- else {
- ret = ff_chdir(vfs::relative_to_root(pathbuf,sizeof pathbuf,path));
- errno = stdioGET_ERRNO();
+ else
+ {
+ char tmp[PATH_MAX];
+ const auto newpath = npath_translate(path,tmp);
+ auto r_chdir = reinterpret_cast<int(*)(const char*)>(dlsym(RTLD_NEXT,"chdir"));
+ return r_chdir(newpath);
}
- return ret;
}
__asm__(".symver chdir,chdir@GLIBC_2.2.5");
+
int fchdir(int fd)
{
TRACE_SYSCALL();
- errno = ENOSYS;
- real_fprintf(stderr, "Unsupported syscall %s\n", __PRETTY_FUNCTION__ );
- return -1;
+ if(is_image_fd(fd))
+ {
+ errno = ENOSYS;
+ real_fprintf(stderr, "Unsupported syscall %s\n", __PRETTY_FUNCTION__ );
+ return -1;
+ }
+ else
+ {
+ auto r_fchdir = reinterpret_cast<int(*)(int)>(dlsym(RTLD_NEXT,"fchdir"));
+ return r_fchdir(fd);
+ }
}
__asm__(".symver fchdir,fchdir@GLIBC_2.2.5");
char *getcwd(char *buf, size_t size)
{
TRACE_SYSCALL();
- if(!vfs::vfs_is_initialized()) {
- errno = EIO;
- return nullptr;
+ if(redirect_to_image())
+ {
+ auto vfs = purefs::subsystem::vfs_core();
+ if(!vfs) {
+ errno = EIO;
+ return nullptr;
+ }
+ auto xwd = vfs->getcwd();
+ xwd.copy(buf,size);
+ return buf;
+ }
+ else
+ {
+ auto r_getcwd = reinterpret_cast<char*(*)(char*,size_t)>(dlsym(RTLD_NEXT,"getcwd"));
+ return r_getcwd(buf,size);
}
- auto cwd = ff_getcwd(buf, size);
- errno = stdioGET_ERRNO();
- return cwd;
}
__asm__(".symver getcwd,getcwd@GLIBC_2.2.5");
char *getwd(char *buf)
{
TRACE_SYSCALL();
- if(!vfs::vfs_is_initialized()) {
- errno = EIO;
- return nullptr;
+ if(redirect_to_image())
+ {
+ auto vfs = purefs::subsystem::vfs_core();
+ if(!vfs) {
+ errno = EIO;
+ return nullptr;
+ }
+ auto xwd = vfs->getcwd();
+ xwd.copy(buf,xwd.size());
+ return buf;
+ }
+ else
+ {
+ auto r_getwd = reinterpret_cast<char*(*)(char*)>(dlsym(RTLD_NEXT,"getwd"));
+ return r_getwd(buf);
}
- auto cwd = ff_getcwd(buf, ffconfigMAX_FILENAME );
- errno = stdioGET_ERRNO();
- return cwd;
}
__asm__(".symver getwd,getwd@GLIBC_2.2.5");
@@ 245,14 248,24 @@ extern "C" {
char *get_current_dir_name(void)
{
TRACE_SYSCALL();
- if(!vfs::vfs_is_initialized()) {
- errno = EIO;
- return nullptr;
- }
- auto buf = new char[ffconfigMAX_FILENAME];
- auto cwd = ff_getcwd(buf, ffconfigMAX_FILENAME );
- errno = stdioGET_ERRNO();
- return cwd;
+ if(redirect_to_image())
+ {
+ auto vfs = purefs::subsystem::vfs_core();
+ if(!vfs) {
+ errno = EIO;
+ return nullptr;
+ }
+ auto xwd = vfs->getcwd();
+ auto ret = new char[xwd.size()+1];
+ xwd.copy(ret,xwd.size());
+ ret[xwd.size()] = '\0';
+ return ret;
+ }
+ else
+ {
+ auto r_getrd = reinterpret_cast<char*(*)()>(dlsym(RTLD_NEXT,"get_current_dir_name"));
+ return r_getrd();
+ }
}
__asm__(".symver get_current_dir_name,get_current_dir_name@GLIBC_2.2.5");
@@ 260,67 273,81 @@ extern "C" {
int rename(const char *oldpath, const char *newpath)
{
TRACE_SYSCALL();
- if(!vfs::vfs_is_initialized()) {
- errno = EIO;
- return -1;
+ if(redirect_to_image(oldpath))
+ {
+ return invoke_fs(&purefs::fs::filesystem::rename, oldpath, newpath);
+ }
+ else
+ {
+ char tmp[PATH_MAX], tmp2[PATH_MAX];
+ const auto oldp = npath_translate(oldpath,tmp);
+ const auto newp = npath_translate(newpath,tmp2);
+ auto r_rename = reinterpret_cast<int(*)(const char*,const char*)>(dlsym(RTLD_NEXT,"rename"));
+ return r_rename(oldp,newp);
}
- char oldpbuf[ffconfigMAX_FILENAME];
- char newpbuf[ffconfigMAX_FILENAME];
- auto ret = ff_rename(vfs::relative_to_root(oldpbuf,sizeof oldpbuf, oldpath),
- vfs::relative_to_root(newpbuf,sizeof newpbuf,newpath), true);
- errno = stdioGET_ERRNO();
- return ret;
}
__asm__(".symver rename,rename@GLIBC_2.2.5");
- int mkdir(const char *pathname, mode_t )
+ int mkdir(const char *pathname, mode_t mode)
{
- TRACE_SYSCALL();
- if(!vfs::vfs_is_initialized()) {
- errno = EIO;
- return -1;
+ if(redirect_to_image(pathname))
+ {
+ return invoke_fs(&purefs::fs::filesystem::mkdir, pathname, mode);
+ }
+ else
+ {
+ char tmp[PATH_MAX];
+ const auto path = npath_translate(pathname,tmp);
+ auto r_mkdir = reinterpret_cast<int(*)(const char*,mode_t)>(dlsym(RTLD_NEXT,"mkdir"));
+ return r_mkdir(path,mode);
}
- char pathbuf[ffconfigMAX_FILENAME];
- auto ret = ff_mkdir(vfs::relative_to_root(pathbuf,sizeof pathbuf,pathname));
- errno = stdioGET_ERRNO();
- return ret;
}
__asm__(".symver mkdir,mkdir@GLIBC_2.2.5");
int chmod(const char *pathname, mode_t mode)
{
TRACE_SYSCALL();
- errno = ENOSYS;
- real_fprintf(stderr, "Unsupported syscall %s\n", __PRETTY_FUNCTION__ );
- return -1;
+ if(redirect_to_image(pathname))
+ {
+ return invoke_fs(&purefs::fs::filesystem::chmod,pathname,mode);
+ }
+ else
+ {
+ char tmp[PATH_MAX];
+ const auto path = npath_translate(pathname,tmp);
+ auto r_chmod = reinterpret_cast<int(*)(const char*,mode_t)>(dlsym(RTLD_NEXT,"chmod"));
+ return r_chmod(path,mode);
+ }
}
__asm__(".symver chmod,chmod@GLIBC_2.2.5");
int fchmod(int fd, mode_t mode)
{
TRACE_SYSCALL();
- errno = ENOSYS;
- real_fprintf(stderr, "Unsupported syscall %s\n", __PRETTY_FUNCTION__ );
- return -1;
+ if(is_image_fd(fd))
+ {
+ return invoke_fs(&purefs::fs::filesystem::fchmod,fd,mode);
+ }
+ else
+ {
+ auto r_fchmod = reinterpret_cast<int(*)(int,mode_t)>(dlsym(RTLD_NEXT,"fchmod"));
+ return r_fchmod(fd,mode);
+ }
}
__asm__(".symver fchmod,fchmod@GLIBC_2.2.5");
int fsync(int fd)
{
TRACE_SYSCALL();
- if(!vfs::vfs_is_initialized()) {
- errno = EIO;
- return -1;
+ if(is_image_fd(fd))
+ {
+ return invoke_fs(&purefs::fs::filesystem::fsync, fd);
}
- auto fil = vfsn::linux::internal::fd_to_ff_file(fd);
- if (!fil) {
- LOG_ERROR("Unable to find handle %i", fd);
- errno = EBADF;
- return -1;
+ else
+ {
+ auto r_fsync = reinterpret_cast<int(*)(int)>(dlsym(RTLD_NEXT,"fsync"));
+ return r_fsync(fd);
}
- auto ret = ff_fflush(fil);
- errno = stdioGET_ERRNO();
- return ret;
}
__asm__(".symver fsync,fsync@GLIBC_2.2.5");
@@ 334,9 361,18 @@ extern "C" {
int symlink(const char *target, const char *linkpath)
{
TRACE_SYSCALL();
- errno = ENOSYS;
- real_fprintf(stderr, "Unsupported syscall %s\n", __PRETTY_FUNCTION__ );
- return -1;
+ if(redirect_to_image(target))
+ {
+ return invoke_fs(&purefs::fs::filesystem::symlink,target,linkpath);
+ }
+ else
+ {
+ char tmp[PATH_MAX], tmp2[PATH_MAX];
+ const auto tgtp = npath_translate(target,tmp);
+ const auto linp = npath_translate(linkpath,tmp2);
+ auto r_symlink = reinterpret_cast<int(*)(const char*,const char*)>(dlsym(RTLD_NEXT,"symlink"));
+ return r_symlink(tgtp,linp);
+ }
}
__asm__(".symver symlink,symlink@GLIBC_2.2.5");
@@ 359,55 395,44 @@ extern "C" {
int __xstat(int ver, const char * path, struct stat * stat_buf)
{
- TRACE_SYSCALL();
- if(!dlsym(RTLD_DEFAULT, "ff_stat")) {
- return real_xstat( ver,path,stat_buf );
- }
- else {
- int ret = stat( path, stat_buf );
- if(ret) {
- real_fprintf(stderr,"WARNING: redirecting __xstat(%s) to the linux fs\n",path);
- ret = real_xstat( ver,path,stat_buf );
- }
- return ret;
+ if( redirect_to_image(path) )
+ {
+ return invoke_fs(&purefs::fs::filesystem::stat, path, *stat_buf);
+ }
+ else
+ {
+ char tmp[PATH_MAX];
+ const auto newp = npath_translate(path,tmp);
+ auto r_xstat = reinterpret_cast<int (*)(int,const char*,struct stat*)>(dlsym(RTLD_NEXT, "__xstat"));
+ return r_xstat(ver,newp,stat_buf);
}
}
int __lxstat(int ver, const char * path, struct stat * stat_buf)
{
- TRACE_SYSCALL();
- if(!dlsym(RTLD_DEFAULT, "ff_stat")) {
- return real_xstat( ver,path,stat_buf );
+ if( redirect_to_image(path) )
+ {
+ return invoke_fs(&purefs::fs::filesystem::stat, path, *stat_buf);
}
- else {
- if(!vfs::vfs_is_initialized()) {
- errno = EIO;
- return -1;
- }
- int ret = ff_cstat(path, stat_buf);
- if(ret) {
- real_fprintf(stderr,"WARNING: redirecting __lxstat(%s) to the linux fs\n",path);
- ret = real_lxstat(ver,path,stat_buf );
- }
- return ret;
+ else
+ {
+ char tmp[PATH_MAX];
+ const auto newp = npath_translate(path,tmp);
+ auto r_xstat = reinterpret_cast<int (*)(int,const char*,struct stat*)>(dlsym(RTLD_NEXT, "__lxstat"));
+ return r_xstat(ver,newp,stat_buf);
}
}
int __fxstat(int ver, int fildes, struct stat * stat_buf)
{
- TRACE_SYSCALL();
- if(!dlsym(RTLD_DEFAULT, "ff_stat")) {
- return real_fxstat( ver,fildes,stat_buf );
- }
- else {
- int ret = fstat(fildes, stat_buf);
- if(ret) {
- real_fprintf(stderr,"WARNING: redirecting __fxstat(%i) to the linux fs\n",fildes);
- ret = real_fxstat( ver,fildes,stat_buf );
- }
- return ret;
+ if( is_image_fd(fildes) )
+ {
+ return invoke_fs(&purefs::fs::filesystem::fstat, fildes, *stat_buf);
+ }
+ else
+ {
+ auto r_fxstat = reinterpret_cast<int (*)(int,int,struct stat*)>(dlsym(RTLD_NEXT, "__fxstat"));
+ return r_fxstat(ver,fildes,stat_buf);
}
}
-
}
-#pragma GCC diagnostic pop
M board/linux/libiosyscalls/src/syscalls_scan_family.cpp => board/linux/libiosyscalls/src/syscalls_scan_family.cpp +41 -40
@@ 1,12 1,11 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-//#include <stdio.h>
-#include <ff_stdio.h>
+#include <stdlib.h>
#include <errno.h>
#include <ctype.h>
+#include <stdarg.h>
#include "debug.hpp"
-#include "internal.hpp"
+#include <iosyscalls.hpp>
#include <dlfcn.h>
namespace
@@ 26,13 25,28 @@ namespace
}
}
-namespace {
- int ic(FF_FILE *fp)
+namespace
+{
+
+ using namespace vfsn::linux::internal;
+ int ic(FILEX *fp)
{
char ch;
- return ff_fread( &ch, 1, 1, fp);
+ if(fp->ungetchar>0)
+ {
+ ch = fp->ungetchar;
+ fp->ungetchar = -1;
+ return 0;
+ }
+ else
+ {
+ auto ret = invoke_fs(&purefs::fs::filesystem::read,fp->fd,&ch,1);
+ fp->error = errno;
+ return ret==1?0:ret;
+ }
}
- int istr(FF_FILE *fp, char *dst, int wid)
+
+ int istr(FILEX *fp, char *dst, int wid)
{
char *d = dst;
int c;
@@ 40,11 54,11 @@ namespace {
*d++ = c;
}
*d = '\0';
- ungetc(c, reinterpret_cast<FILE*>(fp));
+ //ungetc(c, fp);
return d == dst;
}
/* t is 1 for char, 2 for short, 4 for int, and 8 for long */
- int iint(FF_FILE *fp, void *dst, int t, int wid)
+ int iint(FILEX *fp, void *dst, int t, int wid)
{
long n = 0;
int c;
@@ 79,60 93,47 @@ namespace {
return 0;
}
}
-extern "C" {
+extern "C"
+{
- namespace vfs = vfsn::linux::internal;
+ using namespace vfsn::linux::internal;
int ungetc (int __c, FILE *__stream)
{
TRACE_SYSCALL();
- if(!vfs::is_ff_handle(__stream)) {
- real_fprintf(stderr,"WARNING: redirecting ungetc(%p) to the linux fs\n",__stream);
+ if(!is_filex(__stream))
+ {
return real_ungetc(__c,__stream);
}
- if(!vfs::vfs_is_initialized()) {
- errno = EIO;
- return -1;
- }
- int ret = ff_fseek(reinterpret_cast<FF_FILE*>(__stream), -1, SEEK_CUR );
- if( ret ) {
- errno = stdioGET_ERRNO();
- return ret;
- }
- char ch = __c;
- ret = ff_fwrite(&ch, 1, 1, reinterpret_cast<FF_FILE*>(__stream) );
- if(ret!=1) {
- errno = stdioGET_ERRNO();
- return -1;
+ else
+ {
+ auto fx = reinterpret_cast<FILEX*>(__stream);
+ fx->ungetchar = __c;
+ return 0;
}
- errno = stdioGET_ERRNO();
- return 0;
}
__asm__(".symver ungetc,vfscanf@GLIBC_2.2.5");
int vfscanf (FILE *__restrict fp, const char *__restrict fmt,
__gnuc_va_list ap)
{
- if(!vfs::is_ff_handle(fp)) {
- real_fprintf(stderr,"WARNING: redirecting fscanf(%p) to the linux fs\n",fp);
+ if(!is_filex(fp))
+ {
return real_vfscanf(fp,fmt,ap);
}
TRACE_SYSCALL();
- if(!vfs::vfs_is_initialized()) {
- errno = EIO;
- return -1;
- }
int ret = 0;
int t, c;
int wid = 1 << 20;
+ auto fx = reinterpret_cast<FILEX*>(fp);
while (*fmt) {
while (isspace(static_cast<unsigned char>(*fmt))) {
fmt++;
}
- while (isspace(c = ic(reinterpret_cast<FF_FILE*>(fp))))
+ while (isspace(c = ic(fx)))
;
ungetc(c, fp);
while (*fmt && *fmt != '%' && !isspace((unsigned char) *fmt))
- if (*fmt++ != ic(reinterpret_cast<FF_FILE*>(fp)))
+ if (*fmt++ != ic(fx))
return ret;
if (*fmt != '%')
continue;
@@ 154,12 155,12 @@ extern "C" {
switch (*fmt++) {
case 'u':
case 'd':
- if (iint(reinterpret_cast<FF_FILE*>(fp), va_arg(ap, long *), t, wid))
+ if (iint((fx), va_arg(ap, long *), t, wid))
return ret;
ret++;
break;
case 's':
- if (istr(reinterpret_cast<FF_FILE*>(fp), va_arg(ap, char *), wid))
+ if (istr((fx), va_arg(ap, char *), wid))
return ret;
ret++;
break;
M board/linux/libiosyscalls/src/syscalls_stdio.cpp => board/linux/libiosyscalls/src/syscalls_stdio.cpp +338 -271
@@ 3,18 3,16 @@
#include <dlfcn.h>
#include <stdio.h>
-#include "ff_stdio.h"
#include <errno.h>
+#include <string.h>
#include <mutex>
#include <unordered_map>
#include <handle_mapper.hpp>
-#include "internal.hpp"
+#include <iosyscalls.hpp>
#include "debug.hpp"
-
-
-//NOTE: It will be removed in later stage
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
+#include <fcntl.h>
+#include <stdarg.h>
+#include <limits.h>
namespace
{
@@ 43,9 41,6 @@ namespace
long int (*real_ftell) (FILE *__stream) __wur;
void (*real_rewind) (FILE *__stream);
- std::unordered_map<FF_FILE*,size_t> g_fd_map;
- std::recursive_mutex g_mutex;
- internal::handle_mapper<FF_FILE*> g_handles;
void __attribute__((constructor)) _lib_stdio_initialize()
{
@@ 83,73 78,63 @@ namespace
abort();
}
}
-}
-
-namespace vfsn::linux::internal {
- namespace {
- constexpr auto FIRST_FILEDESC = 64'566'756;
- }
- // Convert ff_file to standard fd
- int ff_file_to_fd( FF_FILE* fil )
+ auto fopen_to_open_flags(std::string_view flags)
{
- std::lock_guard<std::recursive_mutex> _lck(g_mutex);
- const auto it = g_fd_map.find(fil);
- return ( it != g_fd_map.end() )?(it->second):(-1);
- }
- // Convert standard fd for ff file
- FF_FILE* fd_to_ff_file( int fd )
- {
- std::lock_guard<std::recursive_mutex> _lck(g_mutex);
- if (fd < FIRST_FILEDESC) {
- return nullptr;
+ int ret = 0;
+ if(!flags.compare("r")) {
+ ret = O_RDONLY;
}
- if( !g_handles.exists(fd-FIRST_FILEDESC) ) {
- return nullptr;
+ else if(!flags.compare("w")) {
+ ret = O_WRONLY | O_CREAT | O_TRUNC;
}
- return g_handles[fd-FIRST_FILEDESC];
- }
- // Check if it is our internal FILE* object
- bool is_ff_handle(FILE* descriptor) {
- std::lock_guard<std::recursive_mutex> _lck(g_mutex);
- const auto it = g_fd_map.find(reinterpret_cast<FF_FILE*>(descriptor));
- return it != g_fd_map.end();
+ else if(!flags.compare("a"))
+ {
+ ret = O_WRONLY | O_CREAT | O_APPEND;
+ }
+ else if(!flags.compare("r+"))
+ {
+ ret = O_RDWR;
+ }
+ else if(!flags.compare("w+"))
+ {
+ ret = O_RDWR | O_CREAT | O_TRUNC;
+ }
+ else if(!flags.compare("a+"))
+ {
+ ret = O_RDWR | O_CREAT | O_APPEND;
+ }
+ return ret;
}
-
}
+
extern "C"
{
- namespace vfs = vfsn::linux::internal;
+ using namespace vfsn::linux::internal;
+
FILE *fopen(const char *pathname, const char *mode)
{
- TRACE_SYSCALL();
- char pathbuf[ffconfigMAX_FILENAME];
- FF_FILE* ret {};
- if(!vfs::vfs_is_initialized()) {
- ret = nullptr;
- } else {
- ret = ff_fopen(vfs::relative_to_root(pathbuf,sizeof pathbuf,pathname), mode);
- }
- if(ret) {
- std::lock_guard<std::recursive_mutex> _lck(g_mutex);
- const auto fd = g_handles.insert(ret) + vfs::FIRST_FILEDESC;
- g_fd_map.insert(std::make_pair(ret,fd));
- } else {
- auto ret = real_fopen(pathname,mode);
- real_fprintf(stderr,
- "WARNING: redirecting fopen(%s) to the Linux fs. Native FILE*: %p\n",
- pathname, ret
- );
- return ret;
+ FILE* ret {};
+ if(redirect_to_image(pathname))
+ {
+ const auto fd = invoke_fs(&purefs::fs::filesystem::open, pathname, fopen_to_open_flags(mode),0644);
+ if(fd >= 0) {
+ ret = reinterpret_cast<FILE*>(allocate_filex(fd));
+ }
+ }
+ else
+ {
+ char tmp[PATH_MAX];
+ const auto path = npath_translate(pathname,tmp);
+ ret = real_fopen(path,mode);
}
- errno = stdioGET_ERRNO();
- return reinterpret_cast<FILE*>(ret);
+ TRACE_SYSCALLN("(%s,%s)=%p", pathname, mode, ret);
+ return ret;
}
__asm__(".symver fopen,fopen@GLIBC_2.2.5");
FILE *fopen64(const char *pathname, const char *mode)
{
- TRACE_SYSCALL();
return fopen(pathname,mode);
}
__asm__(".symver fopen64,fopen64@GLIBC_2.2.5");
@@ 157,32 142,31 @@ extern "C"
int fclose(FILE *__stream)
{
TRACE_SYSCALL();
- if(!vfs::is_ff_handle(__stream)) {
- real_fprintf(stderr,"WARNING: redirecting fclose(%p) to the Linux fs.\n", __stream);
- return real_fclose(__stream);
- }
- if(!vfs::vfs_is_initialized()) {
- errno = EIO;
- return -1;
- }
- auto ret = ff_fclose(reinterpret_cast<FF_FILE *>(__stream));
+ if(is_filex(__stream))
{
- std::lock_guard<std::recursive_mutex> _lck(g_mutex);
- const auto it = g_fd_map.find(reinterpret_cast<FF_FILE *>(__stream));
- if( it != g_fd_map.end() ) {
- g_handles.remove(it->second - vfs::FIRST_FILEDESC);
- g_fd_map.erase(it);
+ auto fx = reinterpret_cast<FILEX*>(__stream);
+ auto ret = invoke_fs(&purefs::fs::filesystem::close, fx->fd);
+ if(!ret)
+ {
+ remove_filex(fx);
+ }
+ else
+ {
+ fx->error = errno;
}
+ return ret;
+ }
+ else
+ {
+ return real_fclose(__stream);
}
- errno = stdioGET_ERRNO();
- return ret;
}
__asm__(".symver fclose,fclose@GLIBC_2.2.5");
FILE *fdopen(int __fd, const char *__modes) __THROW
{
TRACE_SYSCALL();
- real_fprintf(stderr, "unimplemented call %s\n", __PRETTY_FUNCTION__ );
+ real_fprintf(stderr, "unimplemented call %s\n", __PRETTY_FUNCTION__);
errno = ENOTSUP;
return nullptr;
}
@@ 190,16 174,34 @@ extern "C"
int feof(FILE *__stream) __THROW
{
- TRACE_SYSCALL();
- if(!vfs::is_ff_handle(__stream)) {
- return real_feof(__stream);
+ int ret {};
+ if(is_filex(__stream))
+ {
+ auto fx = reinterpret_cast<FILEX*>(__stream);
+ do {
+ const auto curr = invoke_fs(&purefs::fs::filesystem::seek,fx->fd,0,SEEK_CUR);
+ if(curr<0) {
+ ret = curr;
+ break;
+ }
+ const auto ends = invoke_fs(&purefs::fs::filesystem::seek,fx->fd,0,SEEK_END);
+ if(ends<0) {
+ ret = ends;
+ break;
+ }
+ const auto restored = invoke_fs(&purefs::fs::filesystem::seek,fx->fd,curr,SEEK_SET);
+ if(restored<0) {
+ ret = restored;
+ break;
+ }
+ ret = curr >= ends;
+ } while(0);
}
- if(!vfs::vfs_is_initialized()) {
- errno = EIO;
- return -1;
+ else
+ {
+ ret = real_feof(__stream);
}
- auto ret = ff_feof(reinterpret_cast<FF_FILE *>(__stream));
- errno = stdioGET_ERRNO();
+ TRACE_SYSCALLN("(%p)=%i",__stream,ret);
return ret;
}
__asm__(".symver feof,feof@GLIBC_2.2.5");
@@ 207,9 209,13 @@ extern "C"
int ferror(FILE * stream) __THROW
{
TRACE_SYSCALL();
- if(vfs::is_ff_handle(stream)) {
- return vfs::vfs_is_initialized()?stdioGET_ERRNO():EIO;
- } else {
+ if(is_filex(stream))
+ {
+ auto fx = reinterpret_cast<FILEX*>(stream);
+ return fx->error;
+ }
+ else
+ {
return real_ferror(stream);
}
}
@@ 217,16 223,18 @@ extern "C"
int fflush(FILE *__stream)
{
- TRACE_SYSCALL();
- if(!vfs::is_ff_handle(__stream)) {
- return real_fflush(__stream);
+ int ret {};
+ if(is_filex(__stream))
+ {
+ auto fx = reinterpret_cast<FILEX*>(__stream);
+ ret = invoke_fs(&purefs::fs::filesystem::fsync, fx->fd);
+ fx->error = errno;
}
- if(!vfs::vfs_is_initialized()) {
- errno = EIO;
- return -1;
+ else
+ {
+ ret = real_fflush(__stream);
}
- auto ret = ff_fflush(reinterpret_cast<FF_FILE *>(__stream));
- errno = stdioGET_ERRNO();
+ TRACE_SYSCALLN("(%p)=%i",__stream,ret);
return ret;
}
__asm__(".symver fflush,fflush@GLIBC_2.2.5");
@@ 234,95 242,120 @@ extern "C"
int fgetc(FILE *__stream)
{
TRACE_SYSCALL();
- if(!vfs::is_ff_handle(__stream)) {
- return real_fgetc(__stream);
+ if(is_filex(__stream))
+ {
+ auto fx = reinterpret_cast<FILEX*>(__stream);
+ char ch;
+ auto ret = invoke_fs(&purefs::fs::filesystem::read,fx->fd,&ch,1);
+ fx->error = errno;
+ return ret;
}
- if(!vfs::vfs_is_initialized()) {
- errno = EIO;
- return -1;
+ else
+ {
+ return real_fgetc(__stream);
}
- auto ret = ff_fgetc(reinterpret_cast<FF_FILE *>(__stream));
- errno = stdioGET_ERRNO();
- return ret;
}
__asm__(".symver fgetc,fgetc@GLIBC_2.2.5");
int fgetpos(FILE *__restrict __stream, fpos_t *__restrict __pos)
{
TRACE_SYSCALL();
- if(!vfs::is_ff_handle(__stream)) {
- return real_fgetpos(__stream, __pos);
- }
- if(!vfs::vfs_is_initialized()) {
- errno = EIO;
- return -1;
- }
- auto ret = ff_ftell(reinterpret_cast<FF_FILE *>(__stream));
- if (ret > 0 && __pos) {
- __pos->__pos = ret;
- return 0;
+ if(is_filex(__stream))
+ {
+ auto fx = reinterpret_cast<FILEX*>(__stream);
+ auto ret = invoke_fs(&purefs::fs::filesystem::seek,fx->fd,0,SEEK_CUR);
+ fx->error = errno;
+ if(__pos) {
+ __pos->__pos = ret;
+ }
+ return (ret>=0)?(0):(-1);
}
else
- return ret;
+ {
+ return real_fgetpos(__stream, __pos);
+ }
}
__asm__(".symver fgetpos,fgetpos@GLIBC_2.2.5");
int fgetpos64(FILE *__restrict __stream, fpos64_t *__restrict __pos)
{
TRACE_SYSCALL();
- if(!vfs::is_ff_handle(__stream)) {
- return real_fgetpos64(__stream,__pos);
- }
- if(!vfs::vfs_is_initialized()) {
- errno = EIO;
- return -1;
- }
- auto ret = ff_ftell(reinterpret_cast<FF_FILE *>(__stream));
- if (ret > 0 && __pos) {
- __pos->__pos = ret;
- return 0;
+ if(is_filex(__stream))
+ {
+ auto fx = reinterpret_cast<FILEX*>(__stream);
+ auto ret = invoke_fs(&purefs::fs::filesystem::seek,fx->fd,0,SEEK_CUR);
+ fx->error = errno;
+ if(__pos) {
+ __pos->__pos = ret;
+ }
+ return (ret>=0)?(0):(-1);
}
else
- return ret;
+ {
+ return real_fgetpos64(__stream, __pos);
+ }
}
__asm__(".symver fgetpos64,fgetpos64@GLIBC_2.2.5");
char *fgets(char *__restrict __s, int __n, FILE *__restrict __stream)
{
TRACE_SYSCALL();
- if(!vfs::is_ff_handle(__stream)) {
- return real_fgets(__s,__n,__stream);
+ if(is_filex(__s))
+ {
+ auto fx = reinterpret_cast<FILEX*>(__stream);
+ char ch;
+ size_t pos = 0;
+ do {
+ auto ret = invoke_fs(&purefs::fs::filesystem::read,fx->fd,&ch,1);
+ if(ret == 0)
+ {
+ fx->error = 0;
+ return nullptr;
+ }
+ else if(ret<0)
+ {
+ fx->error = errno;
+ return nullptr;
+ } else {
+ __s[pos++] = ch;
+ }
+ } while(ch == '\n');
+ return __s;
}
- if(!vfs::vfs_is_initialized()) {
- errno = EIO;
- return nullptr;
+ else
+ {
+ return real_fgets(__s,__n,__stream);
}
- auto ret = ff_fgets(__s, __n, reinterpret_cast<FF_FILE *>(__stream));
- errno = stdioGET_ERRNO();
- return ret;
}
__asm__(".symver fgets,fgets@GLIBC_2.2.5");
int fileno(FILE *__stream) __THROW
{
- auto ret = vfsn::linux::internal::ff_file_to_fd(reinterpret_cast<FF_FILE*>(__stream));
- if(ret<0) {
- return real_fileno(__stream);
- } else {
- TRACE_SYSCALL();
- return ret;
+ int ret {};
+ if(is_filex(__stream))
+ {
+ auto fx = reinterpret_cast<FILEX*>(__stream);
+ ret = native_fd_to_image_fd(fx->fd);
}
+ else
+ {
+ ret = real_fileno(__stream);
+ }
+ TRACE_SYSCALLN("(%p)=%i",__stream,ret);
+ return ret;
}
__asm__(".symver fileno,fileno@GLIBC_2.2.5");
int fprintf(FILE *__restrict __stream, const char *__restrict __format, ...)
{
+ constexpr auto buf_len = 4096;
int iCount;
size_t xResult;
char *pcBuffer;
va_list xArgs;
- if(!vfs::is_ff_handle(__stream)) {
+ if(!is_filex(__stream))
+ {
va_list arglist;
va_start( arglist, __format );
auto ret = real_vfprintf( __stream, __format, arglist );
@@ 330,85 363,95 @@ extern "C"
return ret;
}
TRACE_SYSCALL();
- if(!vfs::vfs_is_initialized()) {
- errno = EIO;
- return -1;
- }
- pcBuffer = (char *)ffconfigMALLOC(ffconfigFPRINTF_BUFFER_LENGTH);
+ pcBuffer = new char[buf_len];
+ auto fx = reinterpret_cast<FILEX*>(__stream);
if (pcBuffer == NULL) {
/* Store the errno to thread local storage. */
- stdioSET_ERRNO(pdFREERTOS_ERRNO_ENOMEM);
+ fx->error = ENOMEM;
iCount = -1;
}
else {
va_start(xArgs, __format);
- iCount = vsnprintf(pcBuffer, ffconfigFPRINTF_BUFFER_LENGTH, __format, xArgs);
+ iCount = vsnprintf(pcBuffer, buf_len, __format, xArgs);
va_end(xArgs);
/* ff_fwrite() will set ff_errno. */
if (iCount > 0) {
- xResult = ff_fwrite(pcBuffer, (size_t)1, (size_t)iCount, reinterpret_cast<FF_FILE *>(__stream));
+ xResult = invoke_fs(&purefs::fs::filesystem::write, fx->fd, pcBuffer, iCount);
if (xResult < (size_t)iCount) {
iCount = -1;
}
}
- ffconfigFREE(pcBuffer);
+ delete [] pcBuffer;
}
- errno = stdioGET_ERRNO();
+ fx->error = errno;
return iCount;
}
__asm__(".symver fprintf,fprintf@GLIBC_2.2.5");
int fputc(int __c, FILE *__stream)
{
- if(!vfs::is_ff_handle(__stream)) {
+ if(!is_filex(__stream))
+ {
return real_fputc( __c, __stream );
}
- TRACE_SYSCALL();
- if(!vfs::vfs_is_initialized()) {
- errno = EIO;
- return -1;
+ else
+ {
+ TRACE_SYSCALL();
+ auto fx = reinterpret_cast<FILEX*>(__stream);
+ char ch = __c;
+ int ret = invoke_fs(&purefs::fs::filesystem::write,fx->fd, &ch, sizeof ch);
+ fx->error = errno;
+ return ret==1?0:ret;
}
- real_fprintf(stderr,"PUTC FILE %p\n", __stream );
- auto ret = ff_fputc(__c, reinterpret_cast<FF_FILE *>(__stream));
- errno = stdioGET_ERRNO();
- return ret;
}
__asm__(".symver fputc,fputc@GLIBC_2.2.5");
int fputs(const char *__restrict __s, FILE *__restrict __stream)
{
- if(!vfs::is_ff_handle(__stream)) {
- return real_fputs( __s, __stream );
- }
- TRACE_SYSCALL();
- if(!vfs::vfs_is_initialized()) {
- errno = EIO;
- return -1;
+ int ret {};
+ if(is_filex(__stream))
+ {
+ auto fx = reinterpret_cast<FILEX*>(__stream);
+ const auto len = strlen(__s);
+ ret = invoke_fs(&purefs::fs::filesystem::write,fx->fd, __s, len);
+ fx->error = errno;
+ ret = ret==int(len)?0:-1;
}
- int ret{-1};
- while (*__s) {
- ret = ff_fputc(*__s++, reinterpret_cast<FF_FILE *>(__stream));
- if (ret < 0)
- break;
+ else
+ {
+ ret = real_fputs( __s, __stream );
}
- errno = stdioGET_ERRNO();
+ TRACE_SYSCALLN("(%s, %p)=%i",__s, __stream, ret);
return ret;
}
__asm__(".symver fputs,fputs@GLIBC_2.2.5");
size_t fread(void *__restrict __ptr, size_t __size, size_t __n, FILE *__restrict __stream)
{
- TRACE_SYSCALL();
- if(!vfs::is_ff_handle(__stream)) {
- return real_fread(__ptr,__size,__n,__stream);
- }
- if(!vfs::vfs_is_initialized()) {
- errno = EIO;
- return -1;
+ size_t ret {};
+ if(__size!=0 && __n!=0)
+ {
+ if(is_filex(__stream))
+ {
+ auto fx = reinterpret_cast<FILEX*>(__stream);
+ char* p = reinterpret_cast<char*>(__ptr);
+ do {
+ auto res = invoke_fs(&purefs::fs::filesystem::read, fx->fd, p, __size);
+ const auto eof = res>0 && size_t(res)<__size;
+ fx->error = errno;
+ if(res<0 || eof) break;
+ p += __size;
+ --__n;
+ ++ret;
+ } while(__n > 0 );
+ }
+ else
+ {
+ ret = real_fread(__ptr,__size,__n,__stream);
+ }
}
- auto ret = ff_fread(__ptr, __size, __n, reinterpret_cast<FF_FILE *>(__stream));
- errno = stdioGET_ERRNO();
+ TRACE_SYSCALLN("(%p, %lu, %lu, %p)=%i",__ptr,__size,__n,__stream, ret);
return ret;
}
__asm__(".symver fread,fread@GLIBC_2.2.5");
@@ 419,36 462,33 @@ extern "C"
FILE *__restrict __stream)
{
TRACE_SYSCALL();
- if(!vfs::is_ff_handle(__stream)) {
- auto ret = real_freopen(__filename,__modes,__stream);
- real_fprintf(stderr,
- "WARNING: redirecting freopen(%s,%s,%p) to the Linux fs. Native FILE*: %p\n",
- __filename, __modes,__stream, ret);
- return ret;
- }
- if(!vfs::vfs_is_initialized()) {
- errno = EIO;
- return nullptr;
+ if(!is_filex(__filename))
+ {
+ return real_freopen(__filename,__modes,__stream);
}
- if( fclose(__stream) < 0) {
- return nullptr;
+ else {
+ if( fclose(__stream) < 0) {
+ return nullptr;
+ }
+ return fopen(__filename, __modes );
}
- return fopen(__filename, __modes );
}
__asm__(".symver freopen,freopen@GLIBC_2.2.5");
int fseek (FILE *__stream, long int __off, int __whence)
{
- TRACE_SYSCALL();
- if(!vfs::is_ff_handle(__stream)) {
- return real_fseek(__stream,__off,__whence);
+ int ret {};
+ if(is_filex(__stream))
+ {
+ auto fx = reinterpret_cast<FILEX*>(__stream);
+ ret = invoke_fs(&purefs::fs::filesystem::seek, fx->fd, __off, __whence);
+ ret = ret>0?0:ret;
}
- if(!vfs::vfs_is_initialized()) {
- errno = EIO;
- return -1;
+ else
+ {
+ ret = real_fseek(__stream,__off,__whence);
}
- auto ret = ff_fseek(reinterpret_cast<FF_FILE*>(__stream), __off, __whence );
- errno = stdioGET_ERRNO();
+ TRACE_SYSCALLN("(%p, %li, %i)=%i",__stream,__off,__whence,ret);
return ret;
}
__asm__(".symver fseek,fseek@GLIBC_2.2.5");
@@ 456,48 496,48 @@ extern "C"
int fsetpos (FILE *__stream, const fpos_t *__pos)
{
TRACE_SYSCALL();
- if(!vfs::is_ff_handle(__stream)) {
+ if(!is_filex(__stream))
+ {
return real_fsetpos(__stream,__pos);
}
- if(!vfs::vfs_is_initialized()) {
- errno = EIO;
- return -1;
+ else
+ {
+ auto fx = reinterpret_cast<FILEX*>(__stream);
+ auto ret = invoke_fs(&purefs::fs::filesystem::seek, fx->fd, __pos->__pos, SEEK_SET);
+ return ret>0?0:ret;
}
- auto ret = ff_fseek( reinterpret_cast<FF_FILE*>(__stream), __pos->__pos, SEEK_SET );
- errno = stdioGET_ERRNO();
- return ret;
}
__asm__(".symver fsetpos,fsetpos@GLIBC_2.2.5");
int fsetpos64 (FILE *__stream, const fpos64_t *__pos)
{
TRACE_SYSCALL();
- if(!vfs::is_ff_handle(__stream)) {
+ if(!is_filex(__stream)) {
return real_fsetpos64(__stream,__pos);
}
- if(!vfs::vfs_is_initialized()) {
- errno = EIO;
- return -1;
+ else
+ {
+ auto fx = reinterpret_cast<FILEX*>(__stream);
+ auto ret = invoke_fs(&purefs::fs::filesystem::seek, fx->fd, __pos->__pos, SEEK_SET);
+ return ret>0?0:ret;
}
- auto ret = ff_fseek( reinterpret_cast<FF_FILE*>(__stream), __pos->__pos, SEEK_SET );
- errno = stdioGET_ERRNO();
- return ret;
}
__asm__(".symver fsetpos64,fsetpos64@GLIBC_2.2.5");
long int ftell (FILE *__stream)
{
- TRACE_SYSCALL();
- if(!vfs::is_ff_handle(__stream)) {
- return real_ftell(__stream);
+ long int ret {};
+ if(is_filex(__stream))
+ {
+ auto fx = reinterpret_cast<FILEX*>(__stream);
+ ret = invoke_fs(&purefs::fs::filesystem::seek,fx->fd,0,SEEK_CUR);
}
- if(!vfs::vfs_is_initialized()) {
- errno = EIO;
- return -1;
+ else
+ {
+ ret = real_ftell(__stream);
}
- auto ret = ff_ftell(reinterpret_cast<FF_FILE*>(__stream));
- errno = stdioGET_ERRNO();
+ TRACE_SYSCALLN("(%p)=%i",__stream, ret);
return ret;
}
__asm__(".symver ftell,ftell@GLIBC_2.2.5");
@@ 505,79 545,107 @@ extern "C"
size_t fwrite (const void *__restrict __ptr, size_t __size,
size_t __n, FILE *__restrict __s)
{
- if(!vfs::is_ff_handle(__s)) {
- return real_fwrite( __ptr, __size, __n, __s );
- }
- TRACE_SYSCALL();
- if(!vfs::vfs_is_initialized()) {
- errno = EIO;
- return -1;
+ int ret {};
+ if(__size != 0 && __n != 0)
+ {
+ if(is_filex(__s))
+ {
+ auto fx = reinterpret_cast<FILEX*>(__s);
+ const char* p = reinterpret_cast<const char*>(__ptr);
+ size_t items {};
+ do {
+ auto ret = invoke_fs(&purefs::fs::filesystem::write, fx->fd, p, __size);
+ const auto eof = ret>=0 && size_t(ret)!=__size;
+ fx->error = errno;
+ if(ret<0 || eof) return ret;
+ p += __size;
+ --__n;
+ ++items;
+ } while(__n > 0 );
+ ret = ret<0?(-1):(items);
+ }
+ else
+ {
+ ret = real_fwrite( __ptr, __size, __n, __s );
+ }
}
- auto ret = ff_fwrite(__ptr, __size, __n, reinterpret_cast<FF_FILE*>(__s));
- errno = stdioGET_ERRNO();
+ TRACE_SYSCALLN("(ptr: %p,size: %lu, n: %lu, fil: %p)=%i",__ptr,__size,__n,__s,ret);
return ret;
}
__asm__(".symver fwrite,fwrite@GLIBC_2.2.5");
int getc(FILE *__stream)
{
- TRACE_SYSCALL();
- if(!vfs::is_ff_handle(__stream)) {
- return real_getc(__stream);
+ int ret {};
+ if(is_filex(__stream))
+ {
+ auto fx = reinterpret_cast<FILEX*>(__stream);
+ char ch;
+ ret = invoke_fs(&purefs::fs::filesystem::read,fx->fd,&ch,1);
+ fx->error = errno;
+ ret = (ret==1)?(ch):(ret);
}
- if(!vfs::vfs_is_initialized()) {
- errno = EIO;
- return -1;
+ else
+ {
+ ret = real_getc(__stream);
}
- auto ret = ff_fgetc(reinterpret_cast<FF_FILE *>(__stream));
- errno = stdioGET_ERRNO();
+ TRACE_SYSCALLN("(%p)=%i",__stream, ret);
return ret;
}
__asm__(".symver getc,getc@GLIBC_2.2.5");
int putc(int __c, FILE *__stream)
{
- TRACE_SYSCALL();
- if(!vfs::is_ff_handle(__stream)) {
- return real_putc(__c,__stream);
+ int ret {};
+ if(is_filex(__stream))
+ {
+ auto fx = reinterpret_cast<FILEX*>(__stream);
+ char ch = __c;
+ ret = invoke_fs(&purefs::fs::filesystem::write,fx->fd, &ch, sizeof ch);
+ fx->error = errno;
+ ret = (ret==1)?(__c):(EOF);
}
- if(!vfs::vfs_is_initialized()) {
- errno = EIO;
- return -1;
+ else
+ {
+ ret = real_fputc( __c, __stream );
}
- auto ret = ff_fputc(__c, reinterpret_cast<FF_FILE *>(__stream));
- errno = stdioGET_ERRNO();
+ TRACE_SYSCALLN("(%i %p)=%i",__c,__stream, ret);
return ret;
}
__asm__(".symver putc,putc@GLIBC_2.2.5");
int remove (const char *__filename) __THROW
{
- TRACE_SYSCALL();
- if(!vfs::vfs_is_initialized()) {
- errno = EIO;
- return -1;
- }
- char namebuf[ffconfigMAX_FILENAME];
- auto ret = ff_remove(vfs::relative_to_root(namebuf,sizeof namebuf, __filename));
- if (ret && stdioGET_ERRNO() == EISDIR)
- ret = ff_deltree(vfs::relative_to_root(namebuf,sizeof namebuf,__filename), nullptr, nullptr);
- errno = stdioGET_ERRNO();
+ int ret {};
+ if(redirect_to_image(__filename))
+ {
+ ret = invoke_fs(&purefs::fs::filesystem::unlink, __filename);
+ }
+ else
+ {
+ char tmp[PATH_MAX];
+ const auto npath = npath_translate(__filename,tmp);
+ auto r_remove = reinterpret_cast<int (*)(const char*)>(dlsym(RTLD_NEXT,"remove"));
+ ret = r_remove(npath);
+ }
+ TRACE_SYSCALLN("(%s)=%i",__filename, ret);
return ret;
}
__asm__(".symver remove,remove@GLIBC_2.2.5");
void rewind (FILE *__stream)
{
- TRACE_SYSCALL();
- if(!vfs::is_ff_handle(__stream)) {
- real_rewind(__stream);
+ TRACE_SYSCALLN("(%p)",__stream);
+ if(is_filex(__stream))
+ {
+ auto fx = reinterpret_cast<FILEX*>(__stream);
+ invoke_fs(&purefs::fs::filesystem::seek,fx->fd,0,SEEK_SET);
+ fx->error = errno;
}
- if(!vfs::vfs_is_initialized()) {
- errno = EIO;
- return;
+ else
+ {
+ real_rewind(__stream);
}
- ff_fseek(reinterpret_cast<FF_FILE*>(__stream), 0L, SEEK_SET);
}
__asm__(".symver rewind,rewind@GLIBC_2.2.5");
@@ 620,4 688,3 @@ extern "C"
__asm__(".symver setlinebuf,setlinebuf@GLIBC_2.2.5");
}
-#pragma GCC diagnostic pop
M module-services/service-fileindexer/ServiceFileIndexer.cpp => module-services/service-fileindexer/ServiceFileIndexer.cpp +4 -0
@@ 55,6 55,7 @@ namespace service
// Initialize data notification handler
sys::ReturnCodes ServiceFileIndexer::InitHandler()
{
+ /*
vfs.registerNotificationHandler(
[_this = shared_from_this()](std::string_view new_path, vfs::FsEvent event, std::string_view old_path) {
namespace fs = std::filesystem;
@@ 63,12 64,15 @@ namespace service
sys::Bus::SendUnicast(msg, std::string(service::name::file_indexer), _this.get());
});
mStartupIndexer.start(shared_from_this(), service::name::file_indexer);
+ */
return sys::ReturnCodes::Success;
}
sys::ReturnCodes ServiceFileIndexer::DeinitHandler()
{
+ /*
vfs.registerNotificationHandler(nullptr);
+ */
return sys::ReturnCodes::Success;
}
M module-services/service-fileindexer/StartupIndexer.cpp => module-services/service-fileindexer/StartupIndexer.cpp +3 -1
@@ 4,7 4,7 @@
#include "StartupIndexer.hpp"
#include "messages/FileChangeMessage.hpp"
#include <filesystem>
-#include <ff_stdio_listdir_recursive.h>
+//#include <ff_stdio_listdir_recursive.h>
#include <purefs/filesystem_paths.hpp>
#include <Service/Bus.hpp>
#include "Constants.hpp"
@@ 37,6 37,7 @@ namespace service::detail
// Collect startup files when service starts
auto StartupIndexer::collectStartupFiles() -> void
{
+ /*
using namespace std::string_literals;
auto searcher_cb = [](void *ctx, const char *path, bool isDir) {
auto _this = reinterpret_cast<StartupIndexer *>(ctx);
@@ 53,6 54,7 @@ namespace service::detail
for (const auto &path : start_dirs) {
ff_stdio_listdir_recursive(path.c_str(), searcher_cb, this);
}
+ */
}
// Setup timers for notification
auto StartupIndexer::setupTimers(std::shared_ptr<sys::Service> svc, std::string_view svc_name) -> void
A module-utils/parallel-hashmap => module-utils/parallel-hashmap +1 -0
@@ 0,0 1,1 @@
+Subproject commit e77a448e95643a4cf9a0efdaa8fe91d44d97869c
M module-utils/test/unittest_utils.cpp => module-utils/test/unittest_utils.cpp +1 -1
@@ 305,7 305,7 @@ class ScopedDir
TEST_CASE("Read file length")
{
- ScopedDir dir(USER_PATH("test"));
+ ScopedDir dir("mytest");
auto *file = std::fopen(dir("test.txt").c_str(), "w");
REQUIRE(file != nullptr);
std::array<int, 3> v = {42, -1, 7};
M module-vfs/CMakeLists.txt => module-vfs/CMakeLists.txt +1 -48
@@ 1,36 1,15 @@
cmake_minimum_required(VERSION 3.12)
-include(thirdparty)
-
project(module-vfs VERSION 1.0
DESCRIPTION "VFS module library")
add_subdirectory(thirdparty/lfsfs)
-set(FREERTOS_FAT_SOURCES
- ${CMAKE_CURRENT_SOURCE_DIR}/board/freeRTOS_FAT/ff_crc.c
- ${CMAKE_CURRENT_SOURCE_DIR}/board/freeRTOS_FAT/ff_dir.c
- ${CMAKE_CURRENT_SOURCE_DIR}/board/freeRTOS_FAT/ff_error.c
- ${CMAKE_CURRENT_SOURCE_DIR}/board/freeRTOS_FAT/ff_fat.c
- ${CMAKE_CURRENT_SOURCE_DIR}/board/freeRTOS_FAT/ff_file.c
- ${CMAKE_CURRENT_SOURCE_DIR}/board/freeRTOS_FAT/ff_format.c
- ${CMAKE_CURRENT_SOURCE_DIR}/board/freeRTOS_FAT/ff_ioman.c
- ${CMAKE_CURRENT_SOURCE_DIR}/board/freeRTOS_FAT/ff_locking.c
- ${CMAKE_CURRENT_SOURCE_DIR}/board/freeRTOS_FAT/ff_memory.c
- ${CMAKE_CURRENT_SOURCE_DIR}/board/freeRTOS_FAT/ff_stdio.c
- ${CMAKE_CURRENT_SOURCE_DIR}/board/freeRTOS_FAT/ff_string.c
- ${CMAKE_CURRENT_SOURCE_DIR}/board/freeRTOS_FAT/ff_sys.c
- ${CMAKE_CURRENT_SOURCE_DIR}/board/freeRTOS_FAT/ff_time.c
- )
-
-third_party_source_optimization(${FREERTOS_FAT_SOURCES})
-
set(FF_FAT_SOURCES_THIRDPARTY
${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/fatfs/source/ff.c
${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/fatfs/source/ffunicode.c
)
-third_party_source_optimization(${FREERTOS_FAT_SOURCES_THIRDPARTY})
set(FF_FAT_SOURCES
${FF_FAT_SOURCES_THIRDPARTY}
@@ 39,29 18,7 @@ set(FF_FAT_SOURCES
${CMAKE_CURRENT_SOURCE_DIR}/drivers/src/thirdparty/littlefs/lfs_glue.cpp
)
-
-# Disable some warnings due to ugly embedded hacks
-# in the FREERTOS FAT implementation
-if(${PROJECT_TARGET} STREQUAL "TARGET_Linux")
-set_property(SOURCE ${FREERTOS_FAT_SOURCES} APPEND_STRING PROPERTY COMPILE_FLAGS
-" -Wno-overflow -Wno-type-limits -Wno-format -Wno-int-to-pointer-cast -Wno-pointer-to-int-cast -Wno-stringop-truncation")
-endif()
-
-set(PROJECT_INCLUDES
- ${CMAKE_CURRENT_SOURCE_DIR}/board/freeRTOS_FAT/include
- ${CMAKE_CURRENT_SOURCE_DIR}/board/free_rtos_custom/include
- ${CMAKE_CURRENT_SOURCE_DIR}/freertos-fat-custom/include
-)
-
-set(FREERTOS_FAT_EXTSOURCES
- ${CMAKE_CURRENT_SOURCE_DIR}/freertos-fat-custom/src/ff_stdio_flush.c
- ${CMAKE_CURRENT_SOURCE_DIR}/freertos-fat-custom/src/ff_file_flush.c
- ${CMAKE_CURRENT_SOURCE_DIR}/freertos-fat-custom/src/ff_stdio_listdir_recursive.c
-)
-
-set(SOURCES ""
- ${FREERTOS_FAT_SOURCES}
- ${FREERTOS_FAT_EXTSOURCES}
+set(SOURCES
${FF_FAT_SOURCES}
src/purefs/filesystem_paths.cpp
src/purefs/blkdev/disk_manager.cpp
@@ 76,12 33,8 @@ set(SOURCES ""
drivers/src/purefs/fs/filesystem_vfat.cpp
drivers/src/purefs/fs/filesystem_littlefs.cpp
src/deprecated/vfs.cpp
- src/deprecated/vfsNotifier.cpp
)
-if(NOT ${PROJECT_TARGET} STREQUAL "TARGET_Linux")
- include(targets/Target_Cross.cmake)
-endif()
if(${PROJECT_TARGET} STREQUAL "TARGET_RT1051")
include(targets/Target_RT1051.cmake)
D module-vfs/board/cross/free_rtos_custom/include/ff_eMMC_user_disk.hpp => module-vfs/board/cross/free_rtos_custom/include/ff_eMMC_user_disk.hpp +0 -16
@@ 1,16 0,0 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#ifndef FREERTOS_PLUS_FAT_PORTABLE_FF_EMMC_USER_DISK_H_
-#define FREERTOS_PLUS_FAT_PORTABLE_FF_EMMC_USER_DISK_H_
-
-#include "vfs.hpp"
-#include "board/cross/eMMC/eMMC.hpp"
-
-FF_Disk_t *FF_eMMC_user_DiskInit(const char *pcName, bsp::eMMC *emmc);
-BaseType_t FF_eMMC_user_DiskDelete(FF_Disk_t *pxDisk);
-BaseType_t FF_eMMC_user_DiskShowPartition(FF_Disk_t *pxDisk);
-void FF_eMMC_user_DiskFlush(FF_Disk_t *pxDisk);
-uint8_t FF_eMMC_user_DiskIsPresent(void);
-
-#endif /* FREERTOS_PLUS_FAT_PORTABLE_FF_EMMC_USER_DISK_H_ */
D module-vfs/board/cross/free_rtos_custom/portable/common.cpp => module-vfs/board/cross/free_rtos_custom/portable/common.cpp +0 -28
@@ 1,28 0,0 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-/*
- * common.c
- *
- * Created on: 2 Feb 2018
- * Author: mati
- */
-#include <stdint.h>
-#include <string.h>
-#include <time.h>
-#include <time/time_conversion.hpp>
-#if 0
-struct tm *gmtime_r( const time_t *pxTime, struct tm *tmStruct )
-{
- // Dummy time functions to keep the file system happy in the absence of
- //target support.
- memcpy( tmStruct, gmtime( pxTime ), sizeof( * tmStruct ) );
- return tmStruct;
-}
-#endif
-/*-----------------------------------------------------------*/
-
-time_t FreeRTOS_time(time_t *pxTime)
-{
- return utils::time::Time().getTime();
-}
D module-vfs/board/cross/free_rtos_custom/portable/ff_eMMC_user_disk.cpp => module-vfs/board/cross/free_rtos_custom/portable/ff_eMMC_user_disk.cpp +0 -385
@@ 1,385 0,0 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-/* Standard includes. */
-#include "module-vfs/board/cross/free_rtos_custom/include/ff_eMMC_user_disk.hpp"
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdio.h>
-
-/* Scheduler include files. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "semphr.h"
-#include "portmacro.h"
-
-/* FreeRTOS+FAT includes. */
-#include "ff_headers.h"
-#include "ff_sys.h"
-
-#include "fsl_cache.h"
-#include "macros.h"
-
-#include "log/log.hpp"
-
-#define eMMCHIDDEN_SECTOR_COUNT 8
-#define eMMCPRIMARY_PARTITIONS 1
-#define eMMCHUNDRED_64_BIT 100ULL
-#define eMMCPARTITION_NUMBER 0 /* Only a single partition is used. */
-#define eMMCBYTES_PER_MB (1024ull * 1024ull)
-#define eMMCSECTORS_PER_MB (eMMCBYTES_PER_MB / 512ull)
-
-/* Used as a magic number to indicate that an FF_Disk_t structure is a RAM
-disk. */
-#define eMMCSIGNATURE 0x61606362
-#define mainIO_MANAGER_CACHE_SIZE (15UL * FSL_SDMMC_DEFAULT_BLOCK_SIZE)
-
-static ALIGN_(32) uint8_t emmc_user_CacheBuffer[mainIO_MANAGER_CACHE_SIZE];
-
-/*
- * The function that writes to the media.
- */
-static int32_t prvWriteeMMC(uint8_t *pucBuffer, uint32_t ulSectorNumber, uint32_t ulSectorCount, FF_Disk_t *pxDisk);
-
-/*
- * The function that reads from the media - as this is implementing a RAM disk
- * the media is just a RAM buffer.
- */
-static int32_t prvReadeMMC(uint8_t *pucBuffer, uint32_t ulSectorNumber, uint32_t ulSectorCount, FF_Disk_t *pxDisk);
-
-static FF_Error_t prvPartitionAndFormatDisk(FF_Disk_t *pxDisk);
-
-/**
- * TODO: M.Piesta: This function was added by me based on sample provided by Hein from FreeRTOS Discussion forum.
- * It is needed for invalidating/flushing cache when using USB Mass Storage Class.
- * If someday FAT source will be updated I have to remember to copy this function unless it will be provided in official
- * sources(who knows ?)
- */
-static FF_Error_t FF_InvalidateCache(FF_IOManager_t *pxIOManager)
-{
- BaseType_t xIndex;
- FF_Error_t xError;
-
- if (pxIOManager == NULL) {
- xError = FF_ERR_NULL_POINTER | FF_FLUSHCACHE;
- }
- else {
- xError = FF_ERR_NONE;
-
- FF_PendSemaphore(pxIOManager->pvSemaphore);
- {
- for (xIndex = 0; xIndex < pxIOManager->usCacheSize; xIndex++) {
- /* If a buffers has no users and if it has been modified... */
- if ((pxIOManager->pxBuffers[xIndex].usNumHandles != 0) ||
- (pxIOManager->pxBuffers[xIndex].bModified == pdTRUE)) {
- /* Can not flush all caches. */
- xError++;
- }
- else {
- /* Mark the buffer as invalid so that it won't be used again. */
- pxIOManager->pxBuffers[xIndex].bValid = pdFALSE;
- }
- }
- }
-
- FF_ReleaseSemaphore(pxIOManager->pvSemaphore);
- }
-
- /* Function successful if it returns 0. */
- return xError;
-}
-
-FF_Disk_t *FF_eMMC_user_DiskInit(const char *pcName, bsp::eMMC *emmc)
-{
- FF_Error_t xError;
- FF_Disk_t *pxDisk = NULL;
- FF_CreationParameters_t xParameters;
-
- /* Attempt to allocated the FF_Disk_t structure. */
- pxDisk = (FF_Disk_t *)malloc(sizeof(FF_Disk_t));
-
- if (pxDisk != NULL) {
- /* Start with every member of the structure set to zero. */
- memset(pxDisk, '\0', sizeof(FF_Disk_t));
-
- /* The signature is used by the disk read and disk write functions to
- ensure the disk being accessed is a eMMC disk. */
- pxDisk->ulSignature = eMMCSIGNATURE;
-
- /* The number of sectors is recorded for bounds checking in the read and
- write functions. */
- pxDisk->ulNumberOfSectors = emmc->userPartitionBlocks;
- /* Store pointer to mmc_card_t structure */
- pxDisk->pvTag = emmc;
-
- /* Create the IO manager that will be used to control the eMMC disk. */
- memset(&xParameters, '\0', sizeof(xParameters));
- xParameters.pucCacheMemory = emmc_user_CacheBuffer;
- xParameters.ulMemorySize = mainIO_MANAGER_CACHE_SIZE;
- xParameters.ulSectorSize = FSL_SDMMC_DEFAULT_BLOCK_SIZE;
- xParameters.fnWriteBlocks = prvWriteeMMC;
- xParameters.fnReadBlocks = prvReadeMMC;
- xParameters.pxDisk = pxDisk;
-
- /* Driver is reentrant so xBlockDeviceIsReentrant can be set to pdTRUE.
- In this case the semaphore is only used to protect FAT data
- structures. */
- xParameters.pvSemaphore = (void *)xSemaphoreCreateRecursiveMutex();
- xParameters.xBlockDeviceIsReentrant = pdFALSE;
-
- /* Check the validity of the xIOManagerCacheSize parameter. */
- configASSERT((mainIO_MANAGER_CACHE_SIZE % xParameters.ulSectorSize) == 0);
- configASSERT((mainIO_MANAGER_CACHE_SIZE >= (size_t)(2 * xParameters.ulSectorSize)));
-
- pxDisk->pxIOManager = FF_CreateIOManger(&xParameters, &xError);
-
- if ((pxDisk->pxIOManager != NULL) && (FF_isERR(xError) == pdFALSE)) {
- /* Record that the eMMC disk has been initialised. */
- pxDisk->xStatus.bIsInitialised = pdTRUE;
-
- /* Record the partition number the FF_Disk_t structure is, then
- mount the partition. */
- pxDisk->xStatus.bPartitionNumber = eMMCPARTITION_NUMBER;
-
-#if 1
- /* Mount the partition. */
- xError = FF_Mount(pxDisk, pxDisk->xStatus.bPartitionNumber);
- LOG_PRINTF("FF_eMMC_user_DiskInit: FF_Mount: %s\r\n", (const char *)FF_GetErrMessage(xError));
-
- if (FF_isERR(xError) == pdFALSE) {
- /* The partition mounted successfully, add it to the virtual
- file system - where it will appear as a directory off the file
- system's root directory. */
- FF_FS_Add(pcName, pxDisk);
- }
- else
-#endif
- {
- /* This is completely new eMMC disk so at first it needs proper formatting. */
- xError = prvPartitionAndFormatDisk(pxDisk);
-
- /* Mount the partition again, it should complete without fault. */
- if (FF_isERR(xError) == pdFALSE) {
- /* Record the partition number the FF_Disk_t structure is, then
- mount the partition. */
- pxDisk->xStatus.bPartitionNumber = eMMCPARTITION_NUMBER;
-
- /* Mount the partition. */
- xError = FF_Mount(pxDisk, eMMCPARTITION_NUMBER);
- LOG_PRINTF("FF_eMMC_user_DiskInit: FF_Mount: %s\r\n", (const char *)FF_GetErrMessage(xError));
- }
-
- if (FF_isERR(xError) == pdFALSE) {
- /* The partition mounted successfully, add it to the virtual
- file system - where it will appear as a directory off the file
- system's root directory. */
- FF_FS_Add(pcName, pxDisk);
- }
- }
- }
- else {
- LOG_PRINTF("FF_eMMC_user_DiskInit: FF_CreateIOManger: %s\r\n", (const char *)FF_GetErrMessage(xError));
-
- /* The disk structure was allocated, but the disk's IO manager could
- not be allocated, so free the disk again. */
- FF_eMMC_user_DiskDelete(pxDisk);
- pxDisk = NULL;
- }
- }
- else {
- LOG_PRINTF("FF_eMMC_user_DiskInit: Malloc failed\r\n");
- }
-
- return pxDisk;
-}
-
-BaseType_t FF_eMMC_user_DiskDelete(FF_Disk_t *pxDisk)
-{
- if (pxDisk != NULL) {
- pxDisk->ulSignature = 0;
- pxDisk->xStatus.bIsInitialised = 0;
- if (pxDisk->pxIOManager != NULL) {
- FF_DeleteIOManager(pxDisk->pxIOManager);
- }
-
- vPortFree(pxDisk);
- }
-
- return pdPASS;
-}
-
-BaseType_t FF_eMMC_user_DiskShowPartition(FF_Disk_t *pxDisk)
-{
- FF_Error_t xError;
- uint64_t ullFreeSectors;
- uint32_t ulTotalSizeMB, ulFreeSizeMB;
- int iPercentageFree;
- FF_IOManager_t *pxIOManager;
- const char *pcTypeName = "unknown type";
- BaseType_t xReturn = pdPASS;
-
- if (pxDisk == NULL) {
- xReturn = pdFAIL;
- }
- else {
- pxIOManager = pxDisk->pxIOManager;
-
- LOG_PRINTF("Reading FAT and calculating Free Space\r\n");
-
- switch (pxIOManager->xPartition.ucType) {
- case FF_T_FAT12:
- pcTypeName = "FAT12";
- break;
-
- case FF_T_FAT16:
- pcTypeName = "FAT16";
- break;
-
- case FF_T_FAT32:
- pcTypeName = "FAT32";
- break;
-
- default:
- pcTypeName = "UNKOWN";
- break;
- }
-
- FF_GetFreeSize(pxIOManager, &xError);
-
- ullFreeSectors = pxIOManager->xPartition.ulFreeClusterCount * pxIOManager->xPartition.ulSectorsPerCluster;
- iPercentageFree = (int)((eMMCHUNDRED_64_BIT * ullFreeSectors + pxIOManager->xPartition.ulDataSectors / 2) /
- ((uint64_t)pxIOManager->xPartition.ulDataSectors));
-
- ulTotalSizeMB = pxIOManager->xPartition.ulDataSectors / eMMCSECTORS_PER_MB;
- ulFreeSizeMB = (uint32_t)(ullFreeSectors / eMMCSECTORS_PER_MB);
-
- /* It is better not to use the 64-bit format such as %Lu because it
- might not be implemented. */
- LOG_PRINTF("Type %8u (%s)\r\n", pxIOManager->xPartition.ucType, pcTypeName);
- LOG_PRINTF("VolLabel '%8s' \r\n", pxIOManager->xPartition.pcVolumeLabel);
- LOG_PRINTF("TotalSectors %8lu\r\n", pxIOManager->xPartition.ulTotalSectors);
- LOG_PRINTF("SecsPerCluster %8lu\r\n", pxIOManager->xPartition.ulSectorsPerCluster);
- LOG_PRINTF("Size %8lu MB\r\n", ulTotalSizeMB);
- LOG_PRINTF("FreeSize %8lu MB ( %d perc free )\r\n", ulFreeSizeMB, iPercentageFree);
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-void FF_eMMC_user_DiskFlush(FF_Disk_t *pxDisk)
-{
- if ((pxDisk != NULL) && (pxDisk->xStatus.bIsInitialised != 0) && (pxDisk->pxIOManager != NULL)) {
- FF_FlushCache(pxDisk->pxIOManager);
-
- if (FF_InvalidateCache(pxDisk->pxIOManager) != 0) {
- /* Not all buffers could be invalidated. */
- }
- }
-}
-
-uint8_t FF_eMMC_user_DiskIsPresent(void)
-{
- return 1;
-}
-
-static int32_t prvReadeMMC(uint8_t *pucDestination, uint32_t ulSectorNumber, uint32_t ulSectorCount, FF_Disk_t *pxDisk)
-{
- int32_t lReturn = FF_ERR_NONE;
-
- bsp::eMMC *mmc_card = static_cast<bsp::eMMC *>(pxDisk->pvTag);
-
- if (pxDisk != NULL) {
- if (pxDisk->ulSignature != eMMCSIGNATURE) {
- /* The disk structure is not valid because it doesn't contain a
- magic number written to the disk when it was created. */
- lReturn = FF_ERR_IOMAN_DRIVER_FATAL_ERROR | FF_ERRFLAG;
- }
- else if (pxDisk->xStatus.bIsInitialised == pdFALSE) {
- /* The disk has not been initialised. */
- lReturn = FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE | FF_ERRFLAG;
- }
- else if (ulSectorNumber >= pxDisk->ulNumberOfSectors) {
- /* The start sector is not within the bounds of the disk. */
- lReturn = (FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE | FF_ERRFLAG);
- }
- else if ((pxDisk->ulNumberOfSectors - ulSectorNumber) < ulSectorCount) {
- /* The end sector is not within the bounds of the disk. */
- lReturn = (FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE | FF_ERRFLAG);
- }
- else {
- if (mmc_card->ReadBlocks(pucDestination, ulSectorNumber, ulSectorCount) != bsp::RetCode::Success) {
- lReturn = FF_ERR_DEVICE_DRIVER_FAILED;
- }
- }
- }
- else {
- lReturn = FF_ERR_NULL_POINTER | FF_ERRFLAG;
- }
-
- return lReturn;
-}
-/*-----------------------------------------------------------*/
-
-static int32_t prvWriteeMMC(uint8_t *pucSource, uint32_t ulSectorNumber, uint32_t ulSectorCount, FF_Disk_t *pxDisk)
-{
- int32_t lReturn = FF_ERR_NONE;
- bsp::eMMC *mmc_card = static_cast<bsp::eMMC *>(pxDisk->pvTag);
-
- if (pxDisk != NULL) {
-
- if (pxDisk->ulSignature != eMMCSIGNATURE) {
- /* The disk structure is not valid because it doesn't contain a
- magic number written to the disk when it was created. */
- lReturn = FF_ERR_IOMAN_DRIVER_FATAL_ERROR | FF_ERRFLAG;
- }
- else if (pxDisk->xStatus.bIsInitialised == pdFALSE) {
- /* The disk has not been initialised. */
- lReturn = FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE | FF_ERRFLAG;
- }
- else if (ulSectorNumber >= pxDisk->ulNumberOfSectors) {
- /* The start sector is not within the bounds of the disk. */
- lReturn = (FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE | FF_ERRFLAG);
- }
- else if ((pxDisk->ulNumberOfSectors - ulSectorNumber) < ulSectorCount) {
- /* The end sector is not within the bounds of the disk. */
- lReturn = (FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE | FF_ERRFLAG);
- }
- else {
- if (mmc_card->WriteBlocks(pucSource, ulSectorNumber, ulSectorCount) != bsp::RetCode::Success) {
- lReturn = FF_ERR_DEVICE_DRIVER_FAILED;
- }
- }
- }
- else {
- lReturn = FF_ERR_NULL_POINTER | FF_ERRFLAG;
- }
-
- return lReturn;
-}
-
-static FF_Error_t prvPartitionAndFormatDisk(FF_Disk_t *pxDisk)
-{
- FF_PartitionParameters_t xPartition;
- FF_Error_t xError;
-
- /* Create a single partition that fills all available space on the disk. */
- memset(&xPartition, '\0', sizeof(xPartition));
- xPartition.ulSectorCount = pxDisk->ulNumberOfSectors;
- xPartition.ulHiddenSectors = eMMCHIDDEN_SECTOR_COUNT;
- xPartition.xPrimaryCount = eMMCPRIMARY_PARTITIONS;
- xPartition.eSizeType = eSizeIsQuota;
-
- /* Partition the disk */
- xError = FF_Partition(pxDisk, &xPartition);
- LOG_PRINTF("FF_Partition: %s\r\n", (const char *)FF_GetErrMessage(xError));
-
- if (FF_isERR(xError) == pdFALSE) {
- /* Format the partition. */
- xError = FF_Format(pxDisk, eMMCPARTITION_NUMBER, pdFALSE, pdFALSE);
- LOG_PRINTF("FF_eMMC_user_DiskInit: FF_Format: %s\r\n", (const char *)FF_GetErrMessage(xError));
- }
-
- return xError;
-}
D module-vfs/board/cross/free_rtos_custom/portable/vfs.cpp => module-vfs/board/cross/free_rtos_custom/portable/vfs.cpp +0 -52
@@ 1,52 0,0 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#include "vfs.hpp"
-#include <purefs/filesystem_paths.hpp>
-#include "ff_eMMC_user_disk.hpp"
-
-vfs::vfs() : emmc()
-{}
-
-vfs::~vfs()
-{
- FF_eMMC_user_DiskDelete(emmcFFDisk);
- emmc.DeInit();
-}
-
-void vfs::Init()
-{
- emmc.Init();
-
- emmcFFDisk = FF_eMMC_user_DiskInit(purefs::dir::getRootDiskPath().c_str(), &emmc);
-
- /* Print out information on the disk. */
- FF_eMMC_user_DiskShowPartition(emmcFFDisk);
-
- initDone = true;
- int err = bootConfig.load();
- if (!err) {
- LOG_INFO("vfs::Init osType %s root:%s", bootConfig.os_type().c_str(), bootConfig.os_root_path().c_str());
- if (ff_chdir(bootConfig.os_root_path().c_str()) != 0) {
- LOG_ERROR("vfs::Init can't chdir to %s", bootConfig.os_root_path().c_str());
- }
- }
- else {
- LOG_ERROR("vfs::Init unable to determine OS type, fallback to %s", bootConfig.os_root_path().c_str());
- }
-
- chnNotifier.onFileSystemInitialized();
- LOG_INFO("vfs::Init running on ARM osRootPath: %s", bootConfig.os_root_path().c_str());
-
- // this should already exist and have user data in it
- // if it does not create an exmpty directory so that sqlite3 does not fault
- if (const auto userDiskPath = purefs::dir::getUserDiskPath(); isDir(userDiskPath.c_str()) == false) {
- LOG_ERROR("vfs::Init looks like %s does not exist, try to create it", userDiskPath.c_str());
- if (ff_mkdir(userDiskPath.c_str()) != 0) {
- LOG_ERROR("vfs::Init can't create %s directory", userDiskPath.c_str());
- }
- }
- else {
- LOG_INFO("vfs::Init looks like %s exists", userDiskPath.c_str());
- }
-}
D module-vfs/board/freeRTOS_FAT => module-vfs/board/freeRTOS_FAT +0 -1
@@ 1,1 0,0 @@
-Subproject commit 8d868f6bbb5deeeb7846dea77fb529a22be779c1
D module-vfs/board/free_rtos_custom/include/FreeRTOSFATConfig.h => module-vfs/board/free_rtos_custom/include/FreeRTOSFATConfig.h +0 -322
@@ 1,322 0,0 @@
-/*
- FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.
- All rights reserved
-
- VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.
-
- This file is part of the FreeRTOS distribution.
-
- FreeRTOS is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License (version 2) as published by the
- Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.
-
- ***************************************************************************
- >>! NOTE: The modification to the GPL is included to allow you to !<<
- >>! distribute a combined work that includes FreeRTOS without being !<<
- >>! obliged to provide the source code for proprietary components !<<
- >>! outside of the FreeRTOS kernel. !<<
- ***************************************************************************
-
- FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- FOR A PARTICULAR PURPOSE. Full license text is available on the following
- link: http://www.freertos.org/a00114.html
-
- ***************************************************************************
- * *
- * FreeRTOS provides completely free yet professionally developed, *
- * robust, strictly quality controlled, supported, and cross *
- * platform software that is more than just the market leader, it *
- * is the industry's de facto standard. *
- * *
- * Help yourself get started quickly while simultaneously helping *
- * to support the FreeRTOS project by purchasing a FreeRTOS *
- * tutorial book, reference manual, or both: *
- * http://www.FreeRTOS.org/Documentation *
- * *
- ***************************************************************************
-
- http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading
- the FAQ page "My application does not run, what could be wrong?". Have you
- defined configASSERT()?
-
- http://www.FreeRTOS.org/support - In return for receiving this top quality
- embedded software for free we request you assist our global community by
- participating in the support forum.
-
- http://www.FreeRTOS.org/training - Investing in training allows your team to
- be as productive as possible as early as possible. Now you can receive
- FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers
- Ltd, and the world's leading authority on the world's leading RTOS.
-
- http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
- including FreeRTOS+Trace - an indispensable productivity tool, a DOS
- compatible FAT file system, and our tiny thread aware UDP/IP stack.
-
- http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.
- Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.
-
- http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High
- Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS
- licenses offer ticketed support, indemnification and commercial middleware.
-
- http://www.SafeRTOS.com - High Integrity Systems also provide a safety
- engineered and independently SIL3 certified version for use in safety and
- mission critical applications that require provable dependability.
-
- 1 tab == 4 spaces!
-*/
-
-#ifndef _FF_CONFIG_H_
-#define _FF_CONFIG_H_
-
-/* Must be set to either pdFREERTOS_LITTLE_ENDIAN or pdFREERTOS_BIG_ENDIAN,
-depending on the endian of the architecture on which FreeRTOS is running. */
-#define ffconfigBYTE_ORDER pdFREERTOS_LITTLE_ENDIAN
-
-/* Set to 1 to maintain a current working directory (CWD) for each task that
-accesses the file system, allowing relative paths to be used.
-
-Set to 0 not to use a CWD, in which case full paths must be used for each
-file access. */
-#define ffconfigHAS_CWD 1
-
-/* Set to an index within FreeRTOS's thread local storage array that is free for
-use by FreeRTOS+FAT. FreeRTOS+FAT will use two consecutive indexes from this
-that set by ffconfigCWD_THREAD_LOCAL_INDEX. The number of thread local storage
-pointers provided by FreeRTOS is set by configNUM_THREAD_LOCAL_STORAGE_POINTERS
-in FreeRTOSConfig.h */
-#define ffconfigCWD_THREAD_LOCAL_INDEX 0
-
-/* Set to 1 to include long file name support. Set to 0 to exclude long
-file name support.
-
-If long file name support is excluded then only 8.3 file names can be used.
-Long file names will be recognised but ignored.
-
-Users should familiarise themselves with any patent issues that may
-potentially exist around the use of long file names in FAT file systems
-before enabling long file name support. */
-#define ffconfigLFN_SUPPORT 1
-
-/* Only used when ffconfigLFN_SUPPORT is set to 1.
-
-Set to 1 to include a file's short name when listing a directory, i.e. when
-calling findfirst()/findnext(). The short name will be stored in the
-'pcShortName' field of FF_DirEnt_t.
-
-Set to 0 to only include a file's long name. */
-#define ffconfigINCLUDE_SHORT_NAME 0
-
-/* Set to 1 to recognise and apply the case bits used by Windows XP+ when
-using short file names - storing file names such as "readme.TXT" or
-"SETUP.exe" in a short-name entry. This is the recommended setting for
-maximum compatibility.
-
-Set to 0 to ignore the case bits. */
-#define ffconfigSHORTNAME_CASE 1
-
-/* Only used when ffconfigLFN_SUPPORT is set to 1.
-
-Set to 1 to use UTF-16 (wide-characters) for file and directory names.
-
-Set to 0 to use either 8-bit ASCII or UTF-8 for file and directory names
-(see the ffconfigUNICODE_UTF8_SUPPORT). */
-#define ffconfigUNICODE_UTF16_SUPPORT 0
-
-/* Only used when ffconfigLFN_SUPPORT is set to 1.
-
-Set to 1 to use UTF-8 encoding for file and directory names.
-
-Set to 0 to use either 8-bit ASCII or UTF-16 for file and directory
-names (see the ffconfig_UTF_16_SUPPORT setting). */
-#define ffconfigUNICODE_UTF8_SUPPORT 0
-
-/* Set to 1 to include FAT12 support.
-
-Set to 0 to exclude FAT12 support.
-
-FAT16 and FAT32 are always enabled. */
-#define ffconfigFAT12_SUPPORT 0
-
-/* When writing and reading data, i/o becomes less efficient if sizes other
-than 512 bytes are being used. When set to 1 each file handle will
-allocate a 512-byte character buffer to facilitate "unaligned access". */
-#define ffconfigOPTIMISE_UNALIGNED_ACCESS 0
-
-/* Input and output to a disk uses buffers that are only flushed at the
-following times:
-
-- When a new buffer is needed and no other buffers are available.
-- When opening a buffer in READ mode for a sector that has just been changed.
-- After creating, removing or closing a file or a directory.
-
-Normally this is quick enough and it is efficient. If
-ffconfigCACHE_WRITE_THROUGH is set to 1 then buffers will also be flushed each
-time a buffer is released - which is less efficient but more secure. */
-#define ffconfigCACHE_WRITE_THROUGH 1
-
-/* In most cases, the FAT table has two identical copies on the disk,
-allowing the second copy to be used in the case of a read error. If
-
-Set to 1 to use both FATs - this is less efficient but more secure.
-
-Set to 0 to use only one FAT - the second FAT will never be written to. */
-#define ffconfigWRITE_BOTH_FATS 1
-
-/* Set to 1 to have the number of free clusters and the first free cluster
-to be written to the FS info sector each time one of those values changes.
-
-Set to 0 not to store these values in the FS info sector, making booting
-slower, but making changes faster. */
-#define ffconfigWRITE_FREE_COUNT 1
-
-/* Set to 1 to maintain file and directory time stamps for creation, modify
-and last access.
-
-Set to 0 to exclude time stamps.
-
-If time support is used, the following function must be supplied:
-
- time_t FreeRTOS_time( time_t *pxTime );
-
-FreeRTOS_time has the same semantics as the standard time() function. */
-#define ffconfigTIME_SUPPORT 1
-
-/* Set to 1 if the media is removable (such as a memory card).
-
-Set to 0 if the media is not removable.
-
-When set to 1 all file handles will be "invalidated" if the media is
-extracted. If set to 0 then file handles will not be invalidated.
-In that case the user will have to confirm that the media is still present
-before every access. */
-#define ffconfigREMOVABLE_MEDIA 1
-
-/* Set to 1 to determine the disk's free space and the disk's first free
-cluster when a disk is mounted.
-
-Set to 0 to find these two values when they are first needed. Determining
-the values can take some time. */
-#define ffconfigMOUNT_FIND_FREE 1
-
-/* Set to 1 to 'trust' the contents of the 'ulLastFreeCluster' and
-ulFreeClusterCount fields.
-
-Set to 0 not to 'trust' these fields.*/
-#define ffconfigFSINFO_TRUSTED 1
-
-/* Set to 1 to store recent paths in a cache, enabling much faster access
-when the path is deep within a directory structure at the expense of
-additional RAM usage.
-
-Set to 0 to not use a path cache. */
-#define ffconfigPATH_CACHE 1
-
-/* Only used if ffconfigPATH_CACHE is 1.
-
-Sets the maximum number of paths that can exist in the patch cache at any
-one time. */
-#define ffconfigPATH_CACHE_DEPTH 8
-
-/* Set to 1 to calculate a HASH value for each existing short file name.
-Use of HASH values can improve performance when working with large
-directories, or with files that have a similar name.
-
-Set to 0 not to calculate a HASH value. */
-#define ffconfigHASH_CACHE 0
-
-/* Only used if ffconfigHASH_CACHE is set to 1
-
-Set to CRC8 or CRC16 to use 8-bit or 16-bit HASH values respectively. */
-#define ffconfigHASH_FUNCTION CRC16
-
-/*_RB_ Not in FreeRTOSFFConfigDefaults.h. */
-#define ffconfigHASH_CACHE_DEPTH 64
-
-/* Set to 1 to add a parameter to ff_mkdir() that allows an entire directory
-tree to be created in one go, rather than having to create one directory in
-the tree at a time. For example mkdir( "/etc/settings/network", pdTRUE );.
-
-Set to 0 to use the normal mkdir() semantics (without the additional
-parameter). */
-#define ffconfigMKDIR_RECURSIVE 0
-
-// TODO: Correct it when sysmgr will be added #include "sysmgr/sysmgr_memalloc.h"
-/* Set to a function that will be used for all dynamic memory allocations.*/
-#define ffconfigMALLOC(size) malloc(size) // sysmgr_memalloc( size )
-
-/* Set to a function that matches the above allocator defined with
-ffconfigMALLOC. Setting to vPortFree() will use the same memory free
-function as FreeRTOS. */
-#define ffconfigFREE(ptr) free(ptr) // sysmgr_memdealloc( ptr )
-
-/* Set to 1 to calculate the free size and volume size as a 64-bit number.
-
-Set to 0 to calculate these values as a 32-bit number. */
-#define ffconfig64_NUM_SUPPORT 1
-
-/* Defines the maximum number of partitions (and also logical partitions)
-that can be recognised. */
-#define ffconfigMAX_PARTITIONS 2
-
-/* Defines how many drives can be combined in total. Should be set to at
-least 2. */
-#define ffconfigMAX_FILE_SYS 4
-
-/* In case the low-level driver returns an error 'FF_ERR_DRIVER_BUSY',
-the library will pause for a number of ms, defined in
-ffconfigDRIVER_BUSY_SLEEP_MS before re-trying. */
-#define ffconfigDRIVER_BUSY_SLEEP_MS 20
-
-/* Set to 1 to include the ff_fprintf() function.
-
-Set to 0 to exclude the ff_fprintf() function.
-
-ff_fprintf() is quite a heavy function because it allocates RAM and
-brings in a lot of string and variable argument handling code. If
-ff_fprintf() is not being used then the code size can be reduced by setting
-ffconfigFPRINTF_SUPPORT to 0. */
-#define ffconfigFPRINTF_SUPPORT 1
-
-/* ff_fprintf() will allocate a buffer of this size in which it will create
-its formatted string. The buffer will be freed before the function
-exits. */
-#define ffconfigFPRINTF_BUFFER_LENGTH 1024
-
-/* Set to 1 to inline some internal memory access functions.
-
-Set to 0 to not inline the memory access functions. */
-#define ffconfigINLINE_MEMORY_ACCESS 1
-
-/* Officially the only criteria to determine the FAT type (12, 16, or 32
-bits) is the total number of clusters:
-if( ulNumberOfClusters < 4085 ) : Volume is FAT12
-if( ulNumberOfClusters < 65525 ) : Volume is FAT16
-if( ulNumberOfClusters >= 65525 ) : Volume is FAT32
-Not every formatted device follows the above rule.
-
-Set to 1 to perform additional checks over and above inspecting the
-number of clusters on a disk to determine the FAT type.
-
-Set to 0 to only look at the number of clusters on a disk to determine the
-FAT type. */
-#define ffconfigFAT_CHECK 1
-
-/* Sets the maximum length for file names, including the path.
-Note that the value of this define is directly related to the maximum stack
-use of the +FAT library. In some API's, a character buffer of size
-'ffconfigMAX_FILENAME' will be declared on stack. */
-#define ffconfigMAX_FILENAME 128
-
-/* Ensure the SDIO driver uses and interrupt, rather than polled mode. */
-#define ffconfigSDIO_DRIVER_USES_INTERRUPT 1
-
-#include "log/log.hpp"
-#define FF_PRINTF LOG_PRINTF
-
-/* Include the recursive function ff_deltree(). The use of recursion does not
-conform with the coding standard, so use this function with care! */
-#define ffconfigUSE_DELTREE 1
-
-#endif /* _FF_CONFIG_H_ */
D module-vfs/board/linux/free_rtos_custom/include/ff_image_user_disk.hpp => module-vfs/board/linux/free_rtos_custom/include/ff_image_user_disk.hpp +0 -14
@@ 1,14 0,0 @@
-// 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 "vfs.hpp"
-
-namespace freertos_fat::internals
-{
- FF_Disk_t *diskInit(const char *pcName, const char img_path[]);
- BaseType_t diskDelete(FF_Disk_t *pxDisk);
- BaseType_t diskShowPartition(FF_Disk_t *pxDisk);
- void diskFlush(FF_Disk_t *pxDisk);
- uint8_t diskIsPresent(void);
-} // namespace freertos_fat::internals
D module-vfs/board/linux/free_rtos_custom/portable/common.cpp => module-vfs/board/linux/free_rtos_custom/portable/common.cpp +0 -12
@@ 1,12 0,0 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#include <ctime>
-
-extern "C"
-{
- time_t FreeRTOS_time(time_t *pxTime)
- {
- return std::time(pxTime);
- }
-}
D module-vfs/board/linux/free_rtos_custom/portable/ff_image_user_disk.cpp => module-vfs/board/linux/free_rtos_custom/portable/ff_image_user_disk.cpp +0 -426
@@ 1,426 0,0 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-//
-#include <vfs.hpp>
-#include <ff_image_user_disk.hpp>
-#include <filesystem>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-namespace
-{
- constexpr auto FSL_SDMMC_DEFAULT_BLOCK_SIZE = 512UL;
- constexpr auto eMMCSIGNATURE = 0x61606362;
- constexpr auto mainIO_MANAGER_CACHE_SIZE = 15UL * FSL_SDMMC_DEFAULT_BLOCK_SIZE;
- constexpr auto eMMCPARTITION_NUMBER = 0;
-
- constexpr auto eMMCHIDDEN_SECTOR_COUNT = 8;
- constexpr auto eMMCPRIMARY_PARTITIONS = 1;
-
- constexpr auto eMMCHUNDRED_64_BIT = 100ULL;
-
- constexpr auto eMMCBYTES_PER_MB = 1024ull * 1024ull;
- constexpr auto eMMCSECTORS_PER_MB = eMMCBYTES_PER_MB / 512ull;
-
- alignas(32) uint8_t emmc_user_CacheBuffer[mainIO_MANAGER_CACHE_SIZE];
-} // namespace
-
-namespace
-{
- class file_operation
- {
- static constexpr auto SECT_SIZE = 512;
-
- public:
- file_operation(const file_operation &) = delete;
- file_operation &operator=(const file_operation &) = delete;
- // Constructor
- file_operation(const char file_name[])
- {
- m_fd = ::open(file_name, O_RDWR, O_SYNC);
- if (m_fd < 0) {
- throw std::system_error();
- }
- }
- // Destructor
- ~file_operation()
- {
- if (m_fd) {
- ::close(m_fd);
- }
- }
- // Read sector
- int read(void *buf, unsigned sector_number, unsigned sector_count)
- {
- int ret = ::lseek(m_fd, sector_number * SECT_SIZE, SEEK_SET);
- if (ret < 0) {
- return ret;
- }
- auto to_read = sector_count * SECT_SIZE;
- auto buf_b = reinterpret_cast<uint8_t *>(buf);
- do {
- ret = ::read(m_fd, buf_b, to_read);
- if (ret < 0) {
- return ret;
- }
- to_read -= ret;
- buf_b += ret;
- } while (to_read > 0);
- return 0;
- }
- // Write sector
- int write(const void *buf, unsigned sector_number, unsigned sector_count)
- {
- int ret = ::lseek(m_fd, sector_number * SECT_SIZE, SEEK_SET);
- if (ret < 0) {
- return ret;
- }
- auto to_write = sector_count * SECT_SIZE;
- auto buf_b = reinterpret_cast<const uint8_t *>(buf);
- do {
- ret = ::write(m_fd, buf_b, to_write);
- if (ret < 0) {
- return ret;
- }
- to_write -= ret;
- buf_b += ret;
- } while (to_write > 0);
- return 0;
- }
-
- private:
- int m_fd{};
- };
-
- int32_t writeBlocks(uint8_t *pucSource, uint32_t ulSectorNumber, uint32_t ulSectorCount, FF_Disk_t *pxDisk)
- {
- int32_t lReturn = FF_ERR_NONE;
- auto mmc_card = static_cast<file_operation *>(pxDisk->pvTag);
-
- if (pxDisk != NULL) {
-
- if (pxDisk->ulSignature != eMMCSIGNATURE) {
- /* The disk structure is not valid because it doesn't contain a
- magic number written to the disk when it was created. */
- lReturn = FF_ERR_IOMAN_DRIVER_FATAL_ERROR | FF_ERRFLAG;
- }
- else if (pxDisk->xStatus.bIsInitialised == pdFALSE) {
- /* The disk has not been initialised. */
- lReturn = FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE | FF_ERRFLAG;
- }
- else if (ulSectorNumber >= pxDisk->ulNumberOfSectors) {
- /* The start sector is not within the bounds of the disk. */
- lReturn = (FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE | FF_ERRFLAG);
- }
- else if ((pxDisk->ulNumberOfSectors - ulSectorNumber) < ulSectorCount) {
- /* The end sector is not within the bounds of the disk. */
- lReturn = (FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE | FF_ERRFLAG);
- }
- else {
- if (mmc_card->write(pucSource, ulSectorNumber, ulSectorCount) < 0) {
- lReturn = FF_ERR_DEVICE_DRIVER_FAILED;
- }
- }
- }
- else {
- lReturn = FF_ERR_NULL_POINTER | FF_ERRFLAG;
- }
-
- return lReturn;
- }
-
- int32_t readBlocks(uint8_t *pucDestination, uint32_t ulSectorNumber, uint32_t ulSectorCount, FF_Disk_t *pxDisk)
- {
- int32_t lReturn = FF_ERR_NONE;
-
- auto mmc_card = static_cast<file_operation *>(pxDisk->pvTag);
-
- if (pxDisk != NULL) {
- if (pxDisk->ulSignature != eMMCSIGNATURE) {
- /* The disk structure is not valid because it doesn't contain a
- magic number written to the disk when it was created. */
- lReturn = FF_ERR_IOMAN_DRIVER_FATAL_ERROR | FF_ERRFLAG;
- }
- else if (pxDisk->xStatus.bIsInitialised == pdFALSE) {
- /* The disk has not been initialised. */
- lReturn = FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE | FF_ERRFLAG;
- }
- else if (ulSectorNumber >= pxDisk->ulNumberOfSectors) {
- /* The start sector is not within the bounds of the disk. */
- lReturn = (FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE | FF_ERRFLAG);
- }
- else if ((pxDisk->ulNumberOfSectors - ulSectorNumber) < ulSectorCount) {
- /* The end sector is not within the bounds of the disk. */
- lReturn = (FF_ERR_IOMAN_OUT_OF_BOUNDS_WRITE | FF_ERRFLAG);
- }
- else {
- if (mmc_card->read(pucDestination, ulSectorNumber, ulSectorCount) < 0) {
- lReturn = FF_ERR_DEVICE_DRIVER_FAILED;
- }
- }
- }
- else {
- lReturn = FF_ERR_NULL_POINTER | FF_ERRFLAG;
- }
-
- return lReturn;
- }
-
- FF_Error_t prvPartitionAndFormatDisk(FF_Disk_t *pxDisk)
- {
- FF_PartitionParameters_t xPartition;
- FF_Error_t xError;
-
- /* Create a single partition that fills all available space on the disk. */
- memset(&xPartition, '\0', sizeof(xPartition));
- xPartition.ulSectorCount = pxDisk->ulNumberOfSectors;
- xPartition.ulHiddenSectors = eMMCHIDDEN_SECTOR_COUNT;
- xPartition.xPrimaryCount = eMMCPRIMARY_PARTITIONS;
- xPartition.eSizeType = eSizeIsQuota;
-
- /* Partition the disk */
- xError = FF_Partition(pxDisk, &xPartition);
- LOG_PRINTF("FF_Partition: %s\r\n", (const char *)FF_GetErrMessage(xError));
-
- if (FF_isERR(xError) == pdFALSE) {
- /* Format the partition. */
- xError = FF_Format(pxDisk, eMMCPARTITION_NUMBER, pdFALSE, pdFALSE);
- LOG_PRINTF("FF_eMMC_user_DiskInit: FF_Format: %s\r\n", (const char *)FF_GetErrMessage(xError));
- }
-
- return xError;
- }
-
- FF_Error_t FF_InvalidateCache(FF_IOManager_t *pxIOManager)
- {
- BaseType_t xIndex;
- FF_Error_t xError;
-
- if (pxIOManager == NULL) {
- xError = FF_ERR_NULL_POINTER | FF_FLUSHCACHE;
- }
- else {
- xError = FF_ERR_NONE;
-
- FF_PendSemaphore(pxIOManager->pvSemaphore);
- {
- for (xIndex = 0; xIndex < pxIOManager->usCacheSize; xIndex++) {
- /* If a buffers has no users and if it has been modified... */
- if ((pxIOManager->pxBuffers[xIndex].usNumHandles != 0) ||
- (pxIOManager->pxBuffers[xIndex].bModified == pdTRUE)) {
- /* Can not flush all caches. */
- xError++;
- }
- else {
- /* Mark the buffer as invalid so that it won't be used again. */
- pxIOManager->pxBuffers[xIndex].bValid = pdFALSE;
- }
- }
- }
-
- FF_ReleaseSemaphore(pxIOManager->pvSemaphore);
- }
-
- /* Function successful if it returns 0. */
- return xError;
- }
-} // namespace
-
-namespace freertos_fat::internals
-{
- // *** ***
- FF_Disk_t *diskInit(const char *pcName, const char img_path[])
- {
- FF_Error_t xError;
- FF_Disk_t *pxDisk = NULL;
- FF_CreationParameters_t xParameters;
-
- /* Attempt to allocated the FF_Disk_t structure. */
- pxDisk = (FF_Disk_t *)malloc(sizeof(FF_Disk_t));
-
- if (pxDisk != NULL) {
- /* Start with every member of the structure set to zero. */
- memset(pxDisk, '\0', sizeof(FF_Disk_t));
-
- /* The signature is used by the disk read and disk write functions to
- ensure the disk being accessed is a eMMC disk. */
- pxDisk->ulSignature = eMMCSIGNATURE;
-
- /* The number of sectors is recorded for bounds checking in the read and
- write functions. */
- pxDisk->ulNumberOfSectors = std::filesystem::file_size(img_path) / FSL_SDMMC_DEFAULT_BLOCK_SIZE;
- /* Store pointer to mmc_card_t structure */
- pxDisk->pvTag = new file_operation(img_path);
-
- /* Create the IO manager that will be used to control the eMMC disk. */
- memset(&xParameters, '\0', sizeof(xParameters));
- xParameters.pucCacheMemory = emmc_user_CacheBuffer;
- xParameters.ulMemorySize = mainIO_MANAGER_CACHE_SIZE;
- xParameters.ulSectorSize = FSL_SDMMC_DEFAULT_BLOCK_SIZE;
- xParameters.fnWriteBlocks = writeBlocks;
- xParameters.fnReadBlocks = readBlocks;
- xParameters.pxDisk = pxDisk;
-
- /* Driver is reentrant so xBlockDeviceIsReentrant can be set to pdTRUE.
- In this case the semaphore is only used to protect FAT data
- structures. */
- xParameters.pvSemaphore = (void *)xSemaphoreCreateRecursiveMutex();
- xParameters.xBlockDeviceIsReentrant = pdFALSE;
-
- /* Check the validity of the xIOManagerCacheSize parameter. */
- configASSERT((mainIO_MANAGER_CACHE_SIZE % xParameters.ulSectorSize) == 0);
- configASSERT((mainIO_MANAGER_CACHE_SIZE >= (size_t)(2 * xParameters.ulSectorSize)));
-
- pxDisk->pxIOManager = FF_CreateIOManger(&xParameters, &xError);
-
- if ((pxDisk->pxIOManager != NULL) && (FF_isERR(xError) == pdFALSE)) {
- /* Record that the eMMC disk has been initialised. */
- pxDisk->xStatus.bIsInitialised = pdTRUE;
-
- /* Record the partition number the FF_Disk_t structure is, then
- mount the partition. */
- pxDisk->xStatus.bPartitionNumber = eMMCPARTITION_NUMBER;
-
-#if 1
- /* Mount the partition. */
- xError = FF_Mount(pxDisk, pxDisk->xStatus.bPartitionNumber);
- LOG_PRINTF("FF_eMMC_user_DiskInit: FF_Mount: %s\r\n", (const char *)FF_GetErrMessage(xError));
-
- if (FF_isERR(xError) == pdFALSE) {
- /* The partition mounted successfully, add it to the virtual
- file system - where it will appear as a directory off the file
- system's root directory. */
- FF_FS_Add(pcName, pxDisk);
- }
- else
-#endif
- {
- /* This is completely new eMMC disk so at first it needs proper formatting. */
- xError = prvPartitionAndFormatDisk(pxDisk);
-
- /* Mount the partition again, it should complete without fault. */
- if (FF_isERR(xError) == pdFALSE) {
- /* Record the partition number the FF_Disk_t structure is, then
- mount the partition. */
- pxDisk->xStatus.bPartitionNumber = eMMCPARTITION_NUMBER;
-
- /* Mount the partition. */
- xError = FF_Mount(pxDisk, eMMCPARTITION_NUMBER);
- LOG_PRINTF("FF_eMMC_user_DiskInit: FF_Mount: %s\r\n", (const char *)FF_GetErrMessage(xError));
- }
-
- if (FF_isERR(xError) == pdFALSE) {
- /* The partition mounted successfully, add it to the virtual
- file system - where it will appear as a directory off the file
- system's root directory. */
- FF_FS_Add(pcName, pxDisk);
- }
- }
- }
- else {
- LOG_PRINTF("FF_eMMC_user_DiskInit: FF_CreateIOManger: %s\r\n", (const char *)FF_GetErrMessage(xError));
-
- /* The disk structure was allocated, but the disk's IO manager could
- not be allocated, so free the disk again. */
- diskDelete(pxDisk);
- pxDisk = NULL;
- }
- }
- else {
- LOG_PRINTF("FF_eMMC_user_DiskInit: Malloc failed\r\n");
- }
-
- return pxDisk;
- }
- BaseType_t diskDelete(FF_Disk_t *pxDisk)
- {
- if (pxDisk != NULL) {
- pxDisk->ulSignature = 0;
- pxDisk->xStatus.bIsInitialised = 0;
- if (pxDisk->pvTag) {
- auto fops = reinterpret_cast<file_operation *>(pxDisk->pvTag);
- delete fops;
- }
- if (pxDisk->pxIOManager != NULL) {
- FF_DeleteIOManager(pxDisk->pxIOManager);
- }
- // TODO: Fixme in the laters stage
- free(pxDisk);
- }
- return pdPASS;
- }
-
- BaseType_t diskShowPartition(FF_Disk_t *pxDisk)
- {
-
- FF_Error_t xError;
- uint64_t ullFreeSectors;
- uint32_t ulTotalSizeMB, ulFreeSizeMB;
- int iPercentageFree;
- FF_IOManager_t *pxIOManager;
- const char *pcTypeName = "unknown type";
- BaseType_t xReturn = pdPASS;
-
- if (pxDisk == NULL) {
- xReturn = pdFAIL;
- }
- else {
- pxIOManager = pxDisk->pxIOManager;
-
- LOG_PRINTF("Reading FAT and calculating Free Space\r\n");
-
- switch (pxIOManager->xPartition.ucType) {
- case FF_T_FAT12:
- pcTypeName = "FAT12";
- break;
-
- case FF_T_FAT16:
- pcTypeName = "FAT16";
- break;
-
- case FF_T_FAT32:
- pcTypeName = "FAT32";
- break;
-
- default:
- pcTypeName = "UNKOWN";
- break;
- }
-
- FF_GetFreeSize(pxIOManager, &xError);
-
- ullFreeSectors = pxIOManager->xPartition.ulFreeClusterCount * pxIOManager->xPartition.ulSectorsPerCluster;
- iPercentageFree = (int)((eMMCHUNDRED_64_BIT * ullFreeSectors + pxIOManager->xPartition.ulDataSectors / 2) /
- ((uint64_t)pxIOManager->xPartition.ulDataSectors));
-
- ulTotalSizeMB = pxIOManager->xPartition.ulDataSectors / eMMCSECTORS_PER_MB;
- ulFreeSizeMB = (uint32_t)(ullFreeSectors / eMMCSECTORS_PER_MB);
-
- /* It is better not to use the 64-bit format such as %Lu because it
- might not be implemented. */
-
- LOG_PRINTF("Type %8u (%s)\r\n", pxIOManager->xPartition.ucType, pcTypeName);
- LOG_PRINTF("VolLabel '%8s' \r\n", pxIOManager->xPartition.pcVolumeLabel);
- LOG_PRINTF("TotalSectors %8u\r\n", pxIOManager->xPartition.ulTotalSectors);
- LOG_PRINTF("SecsPerCluster %8u\r\n", pxIOManager->xPartition.ulSectorsPerCluster);
- LOG_PRINTF("Size %8u MB\r\n", ulTotalSizeMB);
- LOG_PRINTF("FreeSize %8u MB ( %d perc free )\r\n", ulFreeSizeMB, iPercentageFree);
- }
-
- return xReturn;
- }
- void diskFlush(FF_Disk_t *pxDisk)
- {
- FF_FlushCache(pxDisk->pxIOManager);
-
- if (FF_InvalidateCache(pxDisk->pxIOManager) != 0) {
- /* Not all buffers could be invalidated. */
- }
- }
- uint8_t diskIsPresent(void)
- {
- return 1;
- }
-} // namespace freertos_fat::internals
D module-vfs/board/linux/free_rtos_custom/portable/vfs.cpp => module-vfs/board/linux/free_rtos_custom/portable/vfs.cpp +0 -80
@@ 1,80 0,0 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-//
-#include "vfs.hpp"
-#include <purefs/filesystem_paths.hpp>
-#include "ff_image_user_disk.hpp"
-#include <cstring>
-
-namespace
-{
- constexpr auto image_name = "PurePhone.img";
-}
-
-// NOTE: Ugly hack relative to root we don't want to use C++ in linking
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-
-//! Ugly hack for preload will be removed later
-namespace vfsn::linux::internal
-{
- const char *relative_to_root(char *out_path, size_t out_path_len, const char *inpath)
- {
- return std::strncpy(out_path, vfs.relativeToRoot(inpath).c_str(), out_path_len);
- }
- bool vfs_is_initialized()
- {
- return vfs.isInitialized();
- }
-} // namespace vfsn::linux::internal
-
-vfs::vfs()
-{}
-
-vfs::~vfs()
-{
- freertos_fat::internals::diskDelete(emmcFFDisk);
-}
-
-void vfs::Init()
-{
- if (emmcFFDisk) {
- LOG_WARN("Disk manager already initialized");
- return;
- }
- emmcFFDisk = freertos_fat::internals::diskInit(purefs::dir::getRootDiskPath().c_str(), image_name);
-
- /* Print out information on the disk. */
- freertos_fat::internals::diskShowPartition(emmcFFDisk);
-
- initDone = true;
- int err = bootConfig.load();
- if (!err) {
- if (ff_chdir(bootConfig.os_root_path().c_str()) != 0) {
- LOG_ERROR("vfs::Init can't chdir to %s", bootConfig.os_root_path().c_str());
- }
- LOG_INFO("vfs::Init osType %s root:%s", bootConfig.os_type().c_str(), bootConfig.os_root_path().c_str());
- if (ff_chdir(bootConfig.os_root_path().c_str()) != 0) {
- LOG_ERROR("vfs::Init can't chdir to %s", bootConfig.os_root_path().c_str());
- }
- }
- else {
- LOG_ERROR("vfs::Init unable to determine OS type, fallback to %s", bootConfig.os_root_path().c_str());
- }
-
- LOG_INFO("vfs::Init running on ARM osRootPath: %s", bootConfig.os_root_path().c_str());
-
- // this should already exist and have user data in it
- // if it does not create an exmpty directory so that sqlite3 does not fault
- if (const auto userDiskPath = purefs::dir::getUserDiskPath(); isDir(userDiskPath.c_str()) == false) {
- LOG_ERROR("vfs::Init looks like %s does not exist, try to create it", userDiskPath.c_str());
- if (ff_mkdir(userDiskPath.c_str()) != 0) {
- LOG_ERROR("vfs::Init can't create %s directory", userDiskPath.c_str());
- }
- }
- else {
- LOG_INFO("vfs::Init looks like %s exists", userDiskPath.c_str());
- }
- chnNotifier.onFileSystemInitialized();
-}
-#pragma GCC diagnostic pop
M module-vfs/drivers/include/thirdparty/fatfs/ffconf.h => module-vfs/drivers/include/thirdparty/fatfs/ffconf.h +1 -1
@@ 232,7 232,7 @@
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
*/
-#define FF_FS_LOCK 1
+#define FF_FS_LOCK 128
/* The option FF_FS_LOCK switches file lock function to control duplicated file open
/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY
/ is 1.
M module-vfs/drivers/src/purefs/fs/filesystem_vfat.cpp => module-vfs/drivers/src/purefs/fs/filesystem_vfat.cpp +5 -2
@@ 322,8 322,11 @@ namespace purefs::fs::drivers
if (newpos < 0) {
return -ENXIO;
}
- const auto fres = f_lseek(fp, newpos);
- return translate_error(fres);
+ FRESULT fres{FR_OK};
+ if (f_tell(fp) != newpos) {
+ fres = f_lseek(fp, newpos);
+ }
+ return (fres == FR_OK) ? (f_tell(fp)) : translate_error(fres);
}
auto filesystem_vfat::fstat(fsfile zfile, struct stat &st) noexcept -> int
D module-vfs/freertos-fat-custom/include/ff_stdio_listdir_recursive.h => module-vfs/freertos-fat-custom/include/ff_stdio_listdir_recursive.h +0 -24
@@ 1,24 0,0 @@
-// 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 <ff_stdio.h>
-#include <stdbool.h>
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
- /**
- * List all directories recursive
- * @param startPath Starting directory
- * @param callback Callback handler (ctx, path, isDir)
- * @param context private context
- * @return Error code
- */
- int ff_stdio_listdir_recursive(const char *startPath, void (*callback)(void *, const char *, bool), void *context);
-
-#ifdef __cplusplus
-}
-#endif
D module-vfs/freertos-fat-custom/src/ff_file_flush.c => module-vfs/freertos-fat-custom/src/ff_file_flush.c +0 -100
@@ 1,100 0,0 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#include "ff_headers.h"
-#include "ff_file_flush.h"
-
-#if (ffconfigUNICODE_UTF16_SUPPORT != 0)
-#include <wchar.h>
-#endif
-
-FF_Error_t FF_Flush(FF_FILE *pxFile)
-{
-
- FF_FILE *pxFileChain;
- FF_DirEnt_t xOriginalEntry;
- FF_Error_t xError;
-
- /* Opening a do {} while( 0 )
- * loop to allow the use of the break statement. */
- do {
- if (pxFile == NULL) {
- xError = (FF_Error_t)(FF_ERR_NULL_POINTER | FF_CLOSE);
- break;
- }
- /* It is important to check that user doesn't supply invalid
- handle or a handle invalid because of "media removed" */
- xError = FF_CheckValid(pxFile);
-#if (ffconfigREMOVABLE_MEDIA != 0)
- if (FF_GETERROR(xError) == FF_ERR_FILE_MEDIA_REMOVED) {
- FF_PendSemaphore(pxFile->pxIOManager->pvSemaphore);
- pxFileChain = (FF_FILE *)pxFile->pxIOManager->FirstFile;
- if (pxFileChain == pxFile) {
- pxFile->pxIOManager->FirstFile = pxFile->pxNext;
- }
- else {
- while (pxFileChain) {
- if (pxFileChain->pxNext == pxFile) {
- pxFileChain->pxNext = pxFile->pxNext;
- break;
- }
- pxFileChain = pxFileChain->pxNext; /* Forgot this one */
- }
- }
- FF_ReleaseSemaphore(pxFile->pxIOManager->pvSemaphore);
-#if (ffconfigOPTIMISE_UNALIGNED_ACCESS != 0)
- ffconfigFREE(pxFile->pucBuffer);
-#endif /* ffconfigOPTIMISE_UNALIGNED_ACCESS */
- ffconfigFREE(pxFile); /* So at least we have freed the pointer. */
- xError = FF_ERR_NONE;
- break;
- }
-#endif /* ffconfigREMOVABLE_MEDIA */
-
- if (FF_isERR(xError)) {
- /* FF_ERR_FILE_BAD_HANDLE or FF_ERR_NULL_POINTER */
- break;
- }
-
- /* So here we have a normal valid file handle. */
- if (((pxFile->ulValidFlags & FF_VALID_FLAG_DELETED) == 0) &&
- ((pxFile->ucMode & (FF_MODE_WRITE | FF_MODE_APPEND | FF_MODE_CREATE)) != 0)) {
- /* Get the directory entry and update it to show the new file size */
- if (FF_isERR(xError) == pdFALSE) {
- xError = FF_GetEntry(pxFile->pxIOManager, pxFile->usDirEntry, pxFile->ulDirCluster, &xOriginalEntry);
-
- /* Now update the directory entry */
- if ((FF_isERR(xError) == pdFALSE) &&
- ((pxFile->ulFileSize != xOriginalEntry.ulFileSize) || (pxFile->ulFileSize == 0UL))) {
- if (pxFile->ulFileSize == 0UL) {
- xOriginalEntry.ulObjectCluster = 0;
- }
-
- xOriginalEntry.ulFileSize = pxFile->ulFileSize;
- xError = FF_PutEntry(
- pxFile->pxIOManager, pxFile->usDirEntry, pxFile->ulDirCluster, &xOriginalEntry, NULL);
- }
- }
- }
-#if (ffconfigOPTIMISE_UNALIGNED_ACCESS != 0)
- {
- if (pxFile->pucBuffer != NULL) {
- /* Ensure any unaligned points are pushed to the disk! */
- if (pxFile->ucState & FF_BUFSTATE_WRITTEN) {
- FF_Error_t xTempError;
-
- xTempError = FF_BlockWrite(pxFile->pxIOManager, FF_FileLBA(pxFile), 1, pxFile->pucBuffer, pdFALSE);
- if (FF_isERR(xError) == pdFALSE) {
- xError = xTempError;
- }
- }
- pxFile->ucState = FF_BUFSTATE_INVALID;
- }
- }
-#endif
- if (FF_isERR(xError) == pdFALSE) {
- xError = FF_FlushCache(pxFile->pxIOManager); /* Ensure all modified blocks are flushed to disk! */
- }
- } while (pdFALSE);
- return xError;
-}
D module-vfs/freertos-fat-custom/src/ff_file_flush.h => module-vfs/freertos-fat-custom/src/ff_file_flush.h +0 -7
@@ 1,7 0,0 @@
-// 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 "ff_file.h"
-
-FF_Error_t FF_Flush(FF_FILE *pxFile);
D module-vfs/freertos-fat-custom/src/ff_stdio_flush.c => module-vfs/freertos-fat-custom/src/ff_stdio_flush.c +0 -52
@@ 1,52 0,0 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "portable.h"
-
-/* FreeRTOS+FAT includes. */
-#include "ff_headers.h"
-#include "ff_stdio.h"
-
-#if (ffconfigTIME_SUPPORT != 0)
-#include <time.h>
-#endif
-
-#include "ff_file_flush.h"
-
-int prvFFErrorToErrno(FF_Error_t xError);
-
-int ff_fflush(FF_FILE *pxStream)
-{
- FF_Error_t xError;
- int iReturn, ff_errno;
-
-#if (ffconfigDEV_SUPPORT != 0)
- {
- /* Currently device support is in an experimental state. It will allow
- to create virtual files. The I/O data to those files will be redirected
- to their connected "drivers". */
- if (pxStream != NULL) {
- FF_Device_Flush(pxStream);
- }
- }
-#endif
-
- xError = FF_Flush(pxStream);
- ff_errno = prvFFErrorToErrno(xError);
-
- if (ff_errno == 0) {
- iReturn = 0;
- }
- else {
- /* Return -1 for error as per normal fclose() semantics. */
- iReturn = -1;
- }
-
- /* Store the errno to thread local storage. */
- stdioSET_ERRNO(ff_errno);
-
- return iReturn;
-}
D module-vfs/freertos-fat-custom/src/ff_stdio_listdir_recursive.c => module-vfs/freertos-fat-custom/src/ff_stdio_listdir_recursive.c +0 -121
@@ 1,121 0,0 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#include <ff_stdio_listdir_recursive.h>
-
-const char *prvABSPath(const char *pcPath);
-
-static int ff_stdio_listdir_recursive_prv(char *startPath, void (*callback)(void *, const char *, bool), void *context)
-
-{
- FF_FindData_t *pxFindData;
- BaseType_t xIsDir, xIsDotDir;
- int iResult, iNext, iNameLength, pass, iCount = 0;
-
- pxFindData = (FF_FindData_t *)ffconfigMALLOC(sizeof(*pxFindData));
- if (pxFindData != NULL) {
- iNameLength = (int)strlen(startPath);
- for (pass = 0; pass < 2; pass++) {
- for (iResult = ff_findfirst(startPath, pxFindData); iResult == 0; iResult = iNext) {
- xIsDir = (pxFindData->xDirectoryEntry.ucAttrib & FF_FAT_ATTR_DIR) != 0;
- if ((pass == 0) && (xIsDir != pdFALSE)) {
- /* This entry is a directory. Don't traverse '.' or '..' */
- xIsDotDir = 0;
-
- if (pxFindData->pcFileName[0] == '.') {
- if ((pxFindData->pcFileName[1] == '.') && (pxFindData->pcFileName[2] == '\0')) {
- xIsDotDir = 2;
- }
- else if (pxFindData->pcFileName[1] == '\0') {
- xIsDotDir = 1;
- }
- }
- if (xIsDotDir == 0) {
- snprintf(startPath + iNameLength,
- (size_t)(ffconfigMAX_FILENAME - iNameLength),
- "%s%s",
- startPath[iNameLength - 1] == '/' ? "" : "/",
- pxFindData->pcFileName);
-
- /* Let pxFindData point to the next element before
- the current will get removed. */
- iNext = ff_findnext(pxFindData);
-
- /* Remove the contents of this directory. */
- iResult = ff_stdio_listdir_recursive_prv(startPath, callback, context);
- if (iResult < 0) {
- iCount = -1;
- break;
- }
- iCount += iResult;
- iCount++;
- if (callback)
- callback(context, startPath, true);
- }
- else {
- iNext = ff_findnext(pxFindData);
- }
- }
- else if ((pass == 1) && (xIsDir == pdFALSE)) {
- snprintf(startPath + iNameLength,
- (size_t)(ffconfigMAX_FILENAME - iNameLength),
- "%s%s",
- startPath[iNameLength - 1] == '/' ? "" : "/",
- pxFindData->pcFileName);
- iNext = ff_findnext(pxFindData);
- iCount++;
- if (callback)
- callback(context, startPath, false);
- }
- else {
- iNext = ff_findnext(pxFindData);
- }
- startPath[iNameLength] = '\0';
- }
-
- if (FF_GETERROR(iResult) == FF_ERR_DIR_INVALID_PATH) {
- break;
- }
- if ((FF_GETERROR(iResult) != FF_ERR_DIR_END_OF_DIR) && (FF_GETERROR(iResult) != FF_ERR_FILE_INVALID_PATH)) {
- FF_PRINTF("ff_listdir_recurse[%s]: %s\n", startPath, (const char *)FF_GetErrMessage(iResult));
- }
- }
- ffconfigFREE(pxFindData);
- }
- else {
- iCount = -1;
- stdioSET_ERRNO(pdFREERTOS_ERRNO_ENOMEM);
- }
- return iCount;
-}
-
-/**
- * List all directories recursive
- * @param startPath Starting directory
- * @param callback Callback handler
- * @param context private context
- * @return Error code
- */
-int ff_stdio_listdir_recursive(const char *startPath, void (*callback)(void *, const char *, bool), void *context)
-{
- int iResult;
- char *pcPath;
- pcPath = (char *)ffconfigMALLOC(ffconfigMAX_FILENAME);
- if (pcPath != NULL) {
- /* In case a CWD is used, get the absolute path */
- startPath = prvABSPath(startPath);
- snprintf(pcPath, ffconfigMAX_FILENAME, "%s", startPath);
- /* This recursive function will do all the work */
- iResult = ff_stdio_listdir_recursive_prv(pcPath, callback, context);
- if (iResult >= 0) {
- if (callback)
- callback(context, pcPath, true);
- }
- ffconfigFREE(pcPath);
- }
- else {
- iResult = -1;
- stdioSET_ERRNO(pdFREERTOS_ERRNO_ENOMEM);
- }
- return iResult;
-}
M module-vfs/include/user/deprecated/vfs.hpp => module-vfs/include/user/deprecated/vfs.hpp +5 -6
@@ 11,14 11,12 @@
#include <log/log.hpp>
#include <atomic>
#include <boot/bootconfig.hpp>
-#include "vfsNotifier.hpp"
#include "vfs_globals.hpp"
#ifndef TARGET_Linux
#include "board/cross/eMMC/eMMC.hpp"
#endif
-#include "ff_stdio.h"
namespace fs = std::filesystem;
@@ 67,8 65,7 @@ namespace purefs
class vfs
{
public:
- using FILE = FF_FILE;
- using FsEvent = vfsn::utility::vfsNotifier::FsEvent;
+ // using FsEvent = vfsn::utility::vfsNotifier::FsEvent;
enum class FileAttributes
{
ReadOnly,
@@ 122,17 119,19 @@ class vfs
[[deprecated]] int deltree(const char *path);
[[deprecated]] int mkdir(const char *dir);
[[deprecated]] int rename(const char *oldname, const char *newname);
+ /*
[[deprecated]] void registerNotificationHandler(vfsn::utility::vfsNotifier::NotifyHandler handler)
{
chnNotifier.registerNotificationHandler(handler);
}
+ */
[[deprecated]] auto getAbsolutePath(std::string_view path) const -> std::string;
#ifndef TARGET_Linux
bsp::eMMC emmc;
#endif
- FF_Disk_t *emmcFFDisk{};
+ /// FF_Disk_t *emmcFFDisk{};
auto isInitialized() const noexcept
{
@@ 140,7 139,7 @@ class vfs
}
private:
- vfsn::utility::vfsNotifier chnNotifier;
+ // vfsn::utility::vfsNotifier chnNotifier;
static std::atomic<bool> initDone;
boot::BootConfig bootConfig;
};
M module-vfs/include/user/deprecated/vfsNotifier.hpp => module-vfs/include/user/deprecated/vfsNotifier.hpp +1 -1
@@ 2,7 2,6 @@
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
//
#pragma once
-#include "ff_stdio.h"
#include <unordered_map>
#include <mutex.hpp>
#include <functional>
@@ 13,6 12,7 @@ namespace vfsn::utility
{
class vfsNotifier
{
+ struct FF_FILE;
using FILE = FF_FILE;
public:
M module-vfs/include/user/purefs/blkdev/disk_manager.hpp => module-vfs/include/user/purefs/blkdev/disk_manager.hpp +8 -3
@@ 7,11 7,15 @@
#include <string>
#include <vector>
#include <unordered_map>
-#include <mutex.hpp>
#include <tuple>
#include "defs.hpp"
#include "partition.hpp"
+namespace cpp_freertos
+{
+ class MutexRecursive;
+}
+
namespace purefs::blkdev
{
class disk;
@@ 23,7 27,8 @@ namespace purefs::blkdev
public:
disk_manager(const disk_manager &) = delete;
auto operator=(const disk_manager &) -> disk_manager & = delete;
- disk_manager() = default;
+ disk_manager();
+ ~disk_manager();
/** Register a new disc
* @param[in] disk Block device register
* @param[in] device_name Disk friendly name
@@ 130,6 135,6 @@ namespace purefs::blkdev
private:
std::unordered_map<std::string, std::shared_ptr<disk>> m_dev_map;
- mutable cpp_freertos::MutexRecursive m_lock;
+ std::unique_ptr<cpp_freertos::MutexRecursive> m_lock;
};
} // namespace purefs::blkdev
M module-vfs/include/user/purefs/fs/filesystem.hpp => module-vfs/include/user/purefs/fs/filesystem.hpp +7 -4
@@ 6,8 6,6 @@
#include <memory>
#include <list>
#include <array>
-#include <mutex.hpp>
-#include <unordered_map>
#include <map>
#include <functional>
#include <ctime>
@@ 26,6 24,11 @@ namespace purefs::blkdev
class disk_manager;
}
+namespace cpp_freertos
+{
+ class MutexRecursive;
+}
+
namespace purefs::fs
{
/** This is the filesystem class layer
@@ 61,6 64,7 @@ namespace purefs::fs
using fsdir = std::shared_ptr<internal::directory_handle>;
using fsfile = std::shared_ptr<internal::file_handle>;
explicit filesystem(std::shared_ptr<blkdev::disk_manager> diskmm);
+ ~filesystem();
filesystem(const filesystem &) = delete;
auto operator=(const filesystem &) = delete;
/** Utility API */
@@ 72,7 76,6 @@ namespace purefs::fs
template <typename T> auto register_filesystem(std::string_view fsname, std::shared_ptr<T> fops) -> int
{
if (!fops || !std::is_convertible_v<T *, filesystem_operations *>) {
- LOG_ERROR("Filesystem not valid");
return -EINVAL;
}
return register_filesystem(fsname, std::shared_ptr<filesystem_operations>(fops));
@@ 261,6 264,6 @@ namespace purefs::fs
std::map<std::string, std::shared_ptr<internal::mount_point>> m_mounts;
std::unordered_set<std::string> m_partitions;
internal::handle_mapper<fsfile> m_fds;
- mutable cpp_freertos::MutexRecursive m_lock;
+ std::unique_ptr<cpp_freertos::MutexRecursive> m_lock;
};
} // namespace purefs::fs
M module-vfs/include/user/purefs/vfs_subsystem.hpp => module-vfs/include/user/purefs/vfs_subsystem.hpp +2 -1
@@ 8,7 8,8 @@
namespace purefs::subsystem
{
- auto initialize() -> std::tuple<std::shared_ptr<blkdev::disk_manager>, std::shared_ptr<fs::filesystem>>;
+ using vfs_handle_t = std::tuple<std::shared_ptr<blkdev::disk_manager>, std::shared_ptr<fs::filesystem>>;
+ auto initialize() -> vfs_handle_t;
auto disk_mgr() -> std::shared_ptr<blkdev::disk_manager>;
auto vfs_core() -> std::shared_ptr<fs::filesystem>;
auto mount_defaults() -> int;
M module-vfs/src/deprecated/vfs.cpp => module-vfs/src/deprecated/vfs.cpp +57 -321
@@ 5,6 5,7 @@
#include <purefs/filesystem_paths.hpp>
#include <memory>
#include <cstring>
+#include <log/log.hpp>
#define eMMCHIDDEN_SECTOR_COUNT 8
#define eMMCPRIMARY_PARTITIONS 2
@@ 23,424 24,159 @@
std::atomic<bool> vfs::initDone{false};
-vfs::FILE *vfs::fopen(const char *filename, const char *mode)
+FILE *vfs::fopen(const char *filename, const char *mode)
{
- if (!initDone) {
- stdioSET_ERRNO(pdFREERTOS_ERRNO_EIO);
- return nullptr;
- }
- const auto filename_rel = relativeToRoot(filename);
- const auto handle = ff_fopen(filename_rel.c_str(), mode);
- chnNotifier.onFileOpen(filename_rel, mode, handle);
- return handle;
+ LOG_FATAL("Unupported call [%s] !!!!", __PRETTY_FUNCTION__);
+ return nullptr;
}
int vfs::fclose(FILE *stream)
{
- if (!initDone) {
- stdioSET_ERRNO(pdFREERTOS_ERRNO_EIO);
- return -1;
- }
- const auto ret = ff_fclose(stream);
- chnNotifier.onFileClose(stream);
- return ret;
+ LOG_FATAL("Unupported call [%s] !!!!", __PRETTY_FUNCTION__);
+ return -1;
}
int vfs::remove(const char *name)
{
- if (!initDone) {
- stdioSET_ERRNO(pdFREERTOS_ERRNO_EIO);
- return -1;
- }
- const auto abs_name = relativeToRoot(name);
- const auto ret = ff_remove(abs_name.c_str());
- if (!ret)
- chnNotifier.onFileRemove(abs_name);
- return ret;
+ LOG_FATAL("Unupported call [%s] !!!!", __PRETTY_FUNCTION__);
+ return -1;
}
size_t vfs::fread(void *ptr, size_t size, size_t count, FILE *stream)
{
- if (!initDone) {
- stdioSET_ERRNO(pdFREERTOS_ERRNO_EIO);
- return ssize_t(-1);
- }
- return ff_fread(ptr, size, count, stream);
+ LOG_FATAL("Unupported call [%s] !!!!", __PRETTY_FUNCTION__);
+ return -1;
}
size_t vfs::fwrite(const void *ptr, size_t size, size_t count, FILE *stream)
{
- if (!initDone) {
- stdioSET_ERRNO(pdFREERTOS_ERRNO_EIO);
- return size_t(0);
- }
- return ff_fwrite(ptr, size, count, stream);
+ LOG_FATAL("Unupported call [%s] !!!!", __PRETTY_FUNCTION__);
+ return -1;
}
int vfs::fseek(FILE *stream, long int offset, int origin)
{
- if (!initDone) {
- stdioSET_ERRNO(pdFREERTOS_ERRNO_EIO);
- return -1;
- }
- return ff_fseek(stream, offset, origin);
+ LOG_FATAL("Unupported call [%s] !!!!", __PRETTY_FUNCTION__);
+ return -1;
}
long int vfs::ftell(FILE *stream)
{
- if (!initDone) {
- stdioSET_ERRNO(pdFREERTOS_ERRNO_EIO);
- return -1;
- }
- return ff_ftell(stream);
+ LOG_FATAL("Unupported call [%s] !!!!", __PRETTY_FUNCTION__);
+ return -1;
}
void vfs::rewind(FILE *stream)
{
- if (!initDone) {
- stdioSET_ERRNO(pdFREERTOS_ERRNO_EIO);
- }
- ff_rewind(stream);
+ LOG_FATAL("Unupported call [%s] !!!!", __PRETTY_FUNCTION__);
}
size_t vfs::filelength(FILE *stream)
{
- if (!initDone) {
- stdioSET_ERRNO(pdFREERTOS_ERRNO_EIO);
- return 0;
- }
- return ff_filelength(stream);
+ LOG_FATAL("Unupported call [%s] !!!!", __PRETTY_FUNCTION__);
+ return 0;
}
char *vfs::fgets(char *buff, size_t count, FILE *stream)
{
- if (!initDone) {
- stdioSET_ERRNO(pdFREERTOS_ERRNO_EIO);
- return nullptr;
- }
- return ff_fgets(buff, count, stream);
+ LOG_FATAL("Unupported call [%s] !!!!", __PRETTY_FUNCTION__);
+ return nullptr;
}
std::string vfs::getcurrdir()
{
- if (!initDone) {
- stdioSET_ERRNO(pdFREERTOS_ERRNO_EIO);
- return {};
- }
- char buff[64] = {};
- ff_getcwd(buff, sizeof buff);
- return std::string{buff};
+ LOG_FATAL("Unupported call [%s] !!!!", __PRETTY_FUNCTION__);
+ return {};
}
static inline bool hasEnding(std::string const &fullString, std::string const &ending)
{
- if (fullString.length() >= ending.length()) {
- return (0 == fullString.compare(fullString.length() - ending.length(), ending.length(), ending));
- }
- else {
- return false;
- }
+ LOG_FATAL("Unupported call [%s] !!!!", __PRETTY_FUNCTION__);
+ return false;
}
std::vector<vfs::DirectoryEntry> vfs::listdir(const char *path, const std::string &ext, const bool bypassRootCheck)
{
- if (!initDone) {
- stdioSET_ERRNO(pdFREERTOS_ERRNO_EIO);
- return {};
- }
- std::vector<DirectoryEntry> dir_list;
-
- FileAttributes attribute;
-
- /* FF_FindData_t can be large, so it is best to allocate the structure
- dynamically, rather than declare it as a stack variable. */
- auto pxFindStruct = std::make_unique<FF_FindData_t>();
-
- /* FF_FindData_t must be cleared to 0. */
- memset(pxFindStruct.get(), 0x00, sizeof(FF_FindData_t));
-
- /* The first parameter to ff_findfist() is the directory being searched. Do
- not add wildcards to the end of the directory name. */
- if (ff_findfirst(bypassRootCheck ? path : relativeToRoot(path).c_str(), pxFindStruct.get()) == 0 &&
- pxFindStruct != nullptr) {
- do {
- if ((pxFindStruct->ucAttributes & FF_FAT_ATTR_HIDDEN) ||
- (pxFindStruct->ucAttributes & FF_FAT_ATTR_SYSTEM) || (pxFindStruct->ucAttributes & FF_FAT_ATTR_VOLID) ||
- (pxFindStruct->ucAttributes & FF_FAT_ATTR_LFN)) {
- continue;
- }
- /* Point pcAttrib to a string that describes the file. */
- else if ((pxFindStruct->ucAttributes & FF_FAT_ATTR_DIR) != 0) {
- attribute = FileAttributes::Directory;
- }
- else if ((pxFindStruct->ucAttributes & FF_FAT_ATTR_ARCHIVE) || (pxFindStruct->ucAttributes == 0)) {
- attribute = FileAttributes::Writable;
- }
- else {
- attribute = FileAttributes::ReadOnly;
- }
-
- if (ext.empty()) {
- dir_list.push_back(DirectoryEntry{pxFindStruct->pcFileName, attribute, pxFindStruct->ulFileSize});
- }
- else {
- if (hasEnding(pxFindStruct->pcFileName, ext))
- dir_list.push_back(DirectoryEntry{pxFindStruct->pcFileName, attribute, pxFindStruct->ulFileSize});
- }
-
- } while (ff_findnext(pxFindStruct.get()) == 0);
- }
-
- return dir_list;
+
+ LOG_FATAL("Unupported call [%s] !!!!", __PRETTY_FUNCTION__);
+ return {};
}
bool vfs::eof(FILE *stream)
{
- if (!initDone) {
- stdioSET_ERRNO(pdFREERTOS_ERRNO_EIO);
- return true;
- }
- return ff_feof(stream);
+ LOG_FATAL("Unupported call [%s] !!!!", __PRETTY_FUNCTION__);
+ return false;
}
std::string vfs::getline(FILE *stream, uint32_t length)
{
- if (!initDone) {
- stdioSET_ERRNO(pdFREERTOS_ERRNO_EIO);
- return {};
- }
- uint32_t currentPosition = ftell(stream);
-
- // allocate memory to read number of signs defined by length param. Size of buffer is increased by 1 to add string's
- // null terminator.
- std::unique_ptr<char[]> buffer(new char[length + 1]);
- memset(buffer.get(), 0, length + 1);
-
- uint32_t bytesRead = ff_fread(buffer.get(), 1, length, stream);
-
- // search buffer for /n sign
- for (uint32_t i = 0; i < bytesRead; ++i) {
- if (buffer[i] == 0x0A) {
- buffer[i] = 0;
- ff_fseek(stream, currentPosition + i + 1, SEEK_SET);
- break;
- }
- }
-
- std::string ret = std::string(buffer.get());
-
- return ret;
+ LOG_FATAL("Unupported call [%s] !!!!", __PRETTY_FUNCTION__);
+ return {};
}
vfs::FilesystemStats vfs::getFilesystemStats()
{
-
- if (!initDone) {
- stdioSET_ERRNO(pdFREERTOS_ERRNO_EIO);
- return {};
- }
- FF_Error_t xError;
- uint64_t ullFreeSectors;
- uint32_t ulTotalSizeMB, ulFreeSizeMB;
- int iPercentageFree;
- FF_IOManager_t *pxIOManager;
- vfs::FilesystemStats filesystemStats;
-
- if (emmcFFDisk != NULL) {
- pxIOManager = emmcFFDisk->pxIOManager;
-
- switch (pxIOManager->xPartition.ucType) {
- case FF_T_FAT12:
- filesystemStats.type = "FAT12";
- break;
-
- case FF_T_FAT16:
- filesystemStats.type = "FAT16";
- break;
-
- case FF_T_FAT32:
- filesystemStats.type = "FAT32";
- break;
-
- default:
- filesystemStats.type = "UNKOWN";
- break;
- }
-
- FF_GetFreeSize(pxIOManager, &xError);
-
- ullFreeSectors = pxIOManager->xPartition.ulFreeClusterCount * pxIOManager->xPartition.ulSectorsPerCluster;
- iPercentageFree = (int)((eMMCHUNDRED_64_BIT * ullFreeSectors + pxIOManager->xPartition.ulDataSectors / 2) /
- ((uint64_t)pxIOManager->xPartition.ulDataSectors));
-
- ulTotalSizeMB = pxIOManager->xPartition.ulDataSectors / eMMCSECTORS_PER_MB;
- ulFreeSizeMB = (uint32_t)(ullFreeSectors / eMMCSECTORS_PER_MB);
-
- filesystemStats.freeMbytes = ulFreeSizeMB;
- filesystemStats.totalMbytes = ulTotalSizeMB;
- filesystemStats.freePercent = iPercentageFree;
- }
-
- return filesystemStats;
+ LOG_FATAL("Unupported call [%s] !!!!", __PRETTY_FUNCTION__);
+ return {};
}
std::string vfs::relativeToRoot(const std::string path)
{
- fs::path fsPath(path);
-
- if (fsPath.is_absolute()) {
- if (bootConfig.os_root_path().root_directory() == fsPath.root_directory())
- return fsPath;
- else
- return purefs::createPath(purefs::dir::getRootDiskPath(), fsPath.relative_path()).c_str();
- }
-
- if (path.empty())
- return bootConfig.os_root_path();
- else
- return bootConfig.os_root_path() / fsPath;
+ return path;
}
bool vfs::isDir(const char *path)
{
- if (!initDone) {
- stdioSET_ERRNO(pdFREERTOS_ERRNO_EIO);
- return false;
- }
- if (path == nullptr)
- return false;
-
- FF_Stat_t fileStatus;
-
- const int ret = ff_stat(relativeToRoot(path).c_str(), &fileStatus);
- if (ret == 0) {
- return (fileStatus.st_mode == FF_IFDIR);
- }
- else {
- return false;
- }
+ LOG_FATAL("Unupported call [%s] !!!!", __PRETTY_FUNCTION__);
+ return false;
}
bool vfs::fileExists(const char *path)
{
-
- if (!initDone) {
- stdioSET_ERRNO(pdFREERTOS_ERRNO_EIO);
- return false;
- }
- if (path == nullptr)
- return false;
-
- FF_Stat_t fileStatus;
- const int ret = ff_stat(relativeToRoot(path).c_str(), &fileStatus);
- if (ret == 0) {
- return true;
- }
+ LOG_FATAL("Unupported call [%s] !!!!", __PRETTY_FUNCTION__);
return false;
}
int vfs::deltree(const char *path)
{
- if (!initDone) {
- stdioSET_ERRNO(pdFREERTOS_ERRNO_EIO);
- return -1;
- }
- if (path != nullptr)
- return ff_deltree(
- relativeToRoot(path).c_str(),
- [](void *ctx, const char *path) {
- auto _this = reinterpret_cast<vfs *>(ctx);
- _this->chnNotifier.onFileRemove(path);
- },
- this);
- else
- return -1;
+ LOG_FATAL("Unupported call [%s] !!!!", __PRETTY_FUNCTION__);
+ return -1;
}
int vfs::mkdir(const char *dir)
{
- if (!initDone) {
- stdioSET_ERRNO(pdFREERTOS_ERRNO_EIO);
- return -1;
- }
- if (dir != nullptr)
- return ff_mkdir(relativeToRoot(dir).c_str());
- else
- return -1;
+ LOG_FATAL("Unupported call [%s] !!!!", __PRETTY_FUNCTION__);
+ return -1;
}
int vfs::rename(const char *oldname, const char *newname)
{
-
- if (!initDone) {
- stdioSET_ERRNO(pdFREERTOS_ERRNO_EIO);
- return -1;
- }
- if (oldname != nullptr && newname != nullptr) {
- const auto old_rel = relativeToRoot(oldname);
- const auto new_rel = relativeToRoot(newname);
- const auto ret = ff_rename(old_rel.c_str(), new_rel.c_str(), true);
- if (!ret)
- chnNotifier.onFileRename(new_rel, old_rel);
- return ret;
- }
- else
- return -1;
+ LOG_FATAL("Unupported call [%s] !!!!", __PRETTY_FUNCTION__);
+ return -1;
}
std::string vfs::lastErrnoToStr()
{
- return (strerror(stdioGET_ERRNO()));
+ return {};
}
size_t vfs::fprintf(FILE *stream, const char *format, ...)
{
- size_t count;
- size_t result;
- char *buffer = nullptr;
- va_list args;
-
- if (!initDone) {
- stdioSET_ERRNO(pdFREERTOS_ERRNO_EIO);
- return 0;
- }
- buffer = static_cast<char *>(ffconfigMALLOC(ffconfigFPRINTF_BUFFER_LENGTH));
- if (buffer == nullptr) {
- stdioSET_ERRNO(pdFREERTOS_ERRNO_ENOMEM);
- return -1;
- }
-
- va_start(args, format);
- count = vsnprintf(buffer, ffconfigFPRINTF_BUFFER_LENGTH, format, args);
- va_end(args);
-
- if (count > 0) {
- result = ff_fwrite(buffer, 1, count, stream);
- if (result < count) {
- count = -1;
- }
- }
-
- ffconfigFREE(buffer);
- return count;
+ LOG_FATAL("Unupported call [%s] !!!!", __PRETTY_FUNCTION__);
+ return -1;
}
auto vfs::getAbsolutePath(std::string_view path) const -> std::string
{
- namespace fs = std::filesystem;
- if (!initDone) {
- stdioSET_ERRNO(pdFREERTOS_ERRNO_EIO);
- return {};
- }
- fs::path fs_path(path);
- if (fs_path.is_relative()) {
- char cwd_path[ffconfigMAX_FILENAME];
- ff_getcwd(cwd_path, sizeof cwd_path);
- fs::path fs_cwd(cwd_path);
- return fs_cwd / fs_path;
- }
- else {
- return std::string(path);
- }
+ return std::string(path);
}
+vfs::~vfs()
+{}
+
+vfs::vfs()
+{}
+
+void vfs::Init()
+{}
+
#pragma GCC diagnostic pop
M module-vfs/src/purefs/blkdev/disk_manager.cpp => module-vfs/src/purefs/blkdev/disk_manager.cpp +11 -3
@@ 4,6 4,7 @@
#include <purefs/blkdev/disk_manager.hpp>
#include <purefs/blkdev/disk.hpp>
#include <log/log.hpp>
+#include <mutex.hpp>
#include <errno.h>
#include <charconv>
#include <tuple>
@@ 19,13 20,20 @@ namespace purefs::blkdev
using namespace std::literals;
static constexpr auto part_suffix = "part"sv;
} // namespace
+
+ disk_manager::disk_manager() : m_lock(std::make_unique<cpp_freertos::MutexRecursive>())
+ {}
+
+ disk_manager::~disk_manager()
+ {}
+
auto disk_manager::register_device(std::shared_ptr<disk> disk, std::string_view device_name, unsigned flags) -> int
{
if (!disk) {
LOG_ERROR("Disk doesn't exists");
return -EINVAL;
}
- cpp_freertos::LockGuard _lck(m_lock);
+ cpp_freertos::LockGuard _lck(*m_lock);
const auto ret = m_dev_map.find(std::string(device_name));
if (ret != std::end(m_dev_map)) {
LOG_ERROR("Disc: %.*s already registered.", int(device_name.length()), device_name.data());
@@ 43,7 51,7 @@ namespace purefs::blkdev
}
auto disk_manager::unregister_device(std::string_view device_name) -> int
{
- cpp_freertos::LockGuard _lck(m_lock);
+ cpp_freertos::LockGuard _lck(*m_lock);
auto it = m_dev_map.find(std::string(device_name));
if (it == std::end(m_dev_map)) {
LOG_ERROR("Disc: %.*s doesn't exists in manager.", int(device_name.length()), device_name.data());
@@ 65,7 73,7 @@ namespace purefs::blkdev
ret = nullptr;
}
else {
- cpp_freertos::LockGuard _lck(m_lock);
+ cpp_freertos::LockGuard _lck(*m_lock);
const auto it = m_dev_map.find(std::string(dev));
if (it == std::end(m_dev_map)) {
ret = nullptr;
M module-vfs/src/purefs/fs/filesystem.cpp => module-vfs/src/purefs/fs/filesystem.cpp +15 -10
@@ 9,10 9,15 @@
#include <log/log.hpp>
#include <split_sv.hpp>
#include <errno.h>
+#include <mutex.hpp>
namespace purefs::fs
{
- filesystem::filesystem(std::shared_ptr<blkdev::disk_manager> diskmm) : m_diskmm(diskmm)
+ filesystem::filesystem(std::shared_ptr<blkdev::disk_manager> diskmm)
+ : m_diskmm(diskmm), m_lock(new cpp_freertos::MutexRecursive)
+ {}
+
+ filesystem::~filesystem()
{}
auto filesystem::register_filesystem(std::string_view fsname, std::shared_ptr<filesystem_operations> fops) -> int
@@ 21,7 26,7 @@ namespace purefs::fs
LOG_ERROR("Filesystem operations doesn't exists");
return -EINVAL;
}
- cpp_freertos::LockGuard _lck(m_lock);
+ cpp_freertos::LockGuard _lck(*m_lock);
const auto it = m_fstypes.find(std::string(fsname));
if (it != std::end(m_fstypes)) {
LOG_ERROR("Disc: %.*s already registered.", int(fsname.length()), fsname.data());
@@ 40,7 45,7 @@ namespace purefs::fs
auto filesystem::unregister_filesystem(std::string_view fsname) -> int
{
- cpp_freertos::LockGuard _lck(m_lock);
+ cpp_freertos::LockGuard _lck(*m_lock);
const auto it = m_fstypes.find(std::string(fsname));
if (it == std::end(m_fstypes)) {
LOG_ERROR("VFS: filesystem %.*s doesn't exists in manager.", int(fsname.length()), fsname.data());
@@ 65,7 70,7 @@ namespace purefs::fs
return -EINVAL;
}
{
- cpp_freertos::LockGuard _lock(m_lock);
+ cpp_freertos::LockGuard _lock(*m_lock);
const auto mpi = m_mounts.find(std::string(target));
if (mpi != std::end(m_mounts)) {
LOG_ERROR("VFS: mount point already exists %.*s", int(target.length()), target.data());
@@ 114,7 119,7 @@ namespace purefs::fs
auto filesystem::umount(std::string_view mount_point) -> int
{
- cpp_freertos::LockGuard _lck(m_lock);
+ cpp_freertos::LockGuard _lck(*m_lock);
auto mnti = m_mounts.find(std::string(mount_point));
if (mnti == std::end(m_mounts)) {
return -ENOENT;
@@ 138,7 143,7 @@ namespace purefs::fs
auto filesystem::read_mountpoints(std::list<std::string> &mountpoints) const -> int
{
- cpp_freertos::LockGuard _lck(m_lock);
+ cpp_freertos::LockGuard _lck(*m_lock);
for (const auto &mntp : m_mounts) {
mountpoints.push_back(mntp.first);
}
@@ 150,7 155,7 @@ namespace purefs::fs
{
size_t longest_match{};
std::shared_ptr<internal::mount_point> mount_pnt;
- cpp_freertos::LockGuard _lck(m_lock);
+ cpp_freertos::LockGuard _lck(*m_lock);
for (const auto &mntp : m_mounts) {
const auto slen = mntp.first.size();
if ((slen < longest_match) || (slen > path.size())) {
@@ 215,7 220,7 @@ namespace purefs::fs
auto filesystem::add_filehandle(fsfile file) noexcept -> int
{
- cpp_freertos::LockGuard _lck(m_lock);
+ cpp_freertos::LockGuard _lck(*m_lock);
return m_fds.insert(file) + first_file_descriptor;
}
@@ 225,7 230,7 @@ namespace purefs::fs
return nullptr;
}
fds -= first_file_descriptor;
- cpp_freertos::LockGuard _lck(m_lock);
+ cpp_freertos::LockGuard _lck(*m_lock);
fsfile ret{};
if (m_fds.exists(fds)) {
ret = m_fds[fds];
@@ 241,7 246,7 @@ namespace purefs::fs
return ret;
}
fds -= first_file_descriptor;
- cpp_freertos::LockGuard _lck(m_lock);
+ cpp_freertos::LockGuard _lck(*m_lock);
if (m_fds.exists(fds)) {
ret = m_fds[fds];
}
D module-vfs/targets/Target_Cross.cmake => module-vfs/targets/Target_Cross.cmake +0 -9
@@ 1,9 0,0 @@
-
-set( BOARD_SOURCES
- ${CMAKE_CURRENT_SOURCE_DIR}/board/cross/free_rtos_custom/portable/ff_eMMC_user_disk.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/board/cross/free_rtos_custom/portable/common.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/board/cross/free_rtos_custom/portable/vfs.cpp
- CACHE INTERNAL ""
-)
-
-set(BOARD_DIR_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/board/cross/free_rtos_custom/include CACHE INTERNAL "")
M module-vfs/targets/Target_Linux.cmake => module-vfs/targets/Target_Linux.cmake +0 -4
@@ 1,7 1,4 @@
set(BOARD_SOURCES
- ${CMAKE_CURRENT_SOURCE_DIR}/board/linux/free_rtos_custom/portable/ff_image_user_disk.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/board/linux/free_rtos_custom/portable/common.cpp
- ${CMAKE_CURRENT_SOURCE_DIR}/board/linux/free_rtos_custom/portable/vfs.cpp
${CMAKE_CURRENT_SOURCE_DIR}/board/linux/purefs/src/blkdev/disk_image.cpp
${CMAKE_CURRENT_SOURCE_DIR}/board/linux/purefs/src/fs/thread_local_cwd.cpp
${CMAKE_CURRENT_SOURCE_DIR}/board/linux/purefs/src/vfs_subsystem_internal.cpp
@@ 9,7 6,6 @@ set(BOARD_SOURCES
)
set(BOARD_DIR_INCLUDES
- ${CMAKE_CURRENT_SOURCE_DIR}/board/linux/free_rtos_custom/include
${CMAKE_CURRENT_SOURCE_DIR}/board/linux/purefs/include/
CACHE INTERNAL ""
)
M module-vfs/tests/CMakeLists.txt => module-vfs/tests/CMakeLists.txt +0 -10
@@ 1,15 1,5 @@
cmake_minimum_required(VERSION 3.12)
-# vfs tests
-add_catch2_executable(
- NAME
- vfs
- SRCS
- ${CMAKE_CURRENT_LIST_DIR}/unittest_vfs.cpp
- LIBS
- module-vfs module-utils
-)
-
add_catch2_executable(
NAME vfs-disk
SRCS
M module-vfs/tests/unittest_filesystem_core.cpp => module-vfs/tests/unittest_filesystem_core.cpp +1 -1
@@ 149,7 149,7 @@ TEST_CASE("Corefs: Create new file, write, read from it")
REQUIRE(hwnd >= 3);
char buf[4096]{};
REQUIRE(fscore.read(hwnd, buf, sizeof(buf)) == 4);
- REQUIRE(fscore.seek(hwnd, 0, SEEK_END) == 0);
+ REQUIRE(fscore.seek(hwnd, 0, SEEK_END) == 4);
REQUIRE(fscore.read(hwnd, buf, sizeof(buf)) == 0);
REQUIRE(fscore.seek(hwnd, 0, SEEK_SET) == 0);
fscore.close(hwnd);
D module-vfs/tests/unittest_vfs.cpp => module-vfs/tests/unittest_vfs.cpp +0 -171
@@ 1,171 0,0 @@
-// Copyright (c) 2017-2020, Mudita Sp. z.o.o. All rights reserved.
-// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
-
-#define CATCH_CONFIG_MAIN
-
-#include <catch2/catch.hpp>
-
-#include "vfs.hpp"
-
-#include <ticks.hpp>
-
-#include <algorithm>
-
-#include <cstdint>
-
-#include <thread.hpp>
-
-#include <vector>
-
-#include <algorithm>
-
-class vfs vfs;
-
-struct vfs_initializer
-{
- vfs_initializer()
- {
- vfs.Init();
- }
-} vfs_initializer;
-
-TEST_CASE("Test vfs case 1")
-{
-
-
- const size_t testBufferSize = 1024 * 1024;
-
- uint8_t testBuffer[testBufferSize] = {0};
-
- auto fd = vfs.fopen("testFile.txt", "w");
- REQUIRE(fd != nullptr);
-
- auto bytesWritten = vfs.fwrite(testBuffer, 1, testBufferSize, fd);
- REQUIRE(bytesWritten == testBufferSize);
-
- auto currFilePos = vfs.ftell(fd);
- REQUIRE(currFilePos == testBufferSize);
-
- auto fileSize = vfs.filelength(fd);
- REQUIRE(fileSize == testBufferSize);
-
- currFilePos = vfs.ftell(fd);
- REQUIRE(currFilePos == testBufferSize);
-
- REQUIRE(vfs.fclose(fd) == 0);
-
- // current directory is the build dir
- // vfs adds sys/ to the path we need to got outside sys (bad!)
- // and look for some files there
- vfs.mkdir("module-vfs");
- vfs.mkdir("module-vfs/test_dir2");
-
- fd = vfs.fopen("module-vfs/test1.txt", "a");
- REQUIRE(fd != nullptr);
- REQUIRE(vfs.fclose(fd) == 0);
-
- fd = vfs.fopen("module-vfs/test2.txt", "a");
- REQUIRE(fd != nullptr);
- REQUIRE(vfs.fclose(fd) == 0);
-
- auto dirList = vfs.listdir("module-vfs");
- REQUIRE(dirList.size() >= 4);
- for (auto &dir : dirList) {
- if (dir.fileName == "test_dir2") {
- REQUIRE(dir.attributes == vfs::FileAttributes::Directory);
- }
- if (dir.fileName == "test1.txt" || dir.fileName == "test2.txt") {
- REQUIRE(dir.attributes == vfs::FileAttributes::Writable);
- }
- }
-}
-
-
-
-
-
-TEST_CASE("VFS lseek check")
-{
- static constexpr auto seek_filename = "lseek_test.fil";
- static constexpr auto buf_elems_size = 1024U;
- static constexpr auto buf_elems = buf_elems_size / sizeof(int);
- static constexpr auto buf_items = 1024U;
- auto fd = vfs.fopen(seek_filename, "w+");
- REQUIRE(fd != nullptr);
- std::vector<int> buffer(buf_elems);
- for (auto record = 0U; record < buf_items; ++record) {
- std::iota(std::begin(buffer), std::end(buffer), record * buf_elems);
- REQUIRE(vfs.fwrite(buffer.data(), buffer.size() * sizeof(buffer[0]), 1, fd) == 1);
- }
- REQUIRE(vfs.fclose(fd) == 0);
- fd = vfs.fopen(seek_filename, "r");
- REQUIRE(fd != nullptr);
- std::vector<int> buf_out(buf_elems);
- static constexpr auto offs_elems1 = 256U;
- static constexpr auto offs_seek1 = offs_elems1 * sizeof(int);
- REQUIRE(vfs.fseek(fd, offs_seek1, SEEK_SET) == 0);
- REQUIRE(vfs.ftell(fd) == offs_seek1);
- REQUIRE(vfs.fread(buf_out.data(), buf_out.size() * sizeof(buf_out[0]), 1, fd) == 1);
- std::iota(std::begin(buffer), std::end(buffer), offs_elems1);
- REQUIRE(buffer == buf_out);
-
- REQUIRE(vfs.fseek(fd, 0UL, SEEK_END) == 0);
- REQUIRE(vfs.ftell(fd) == buf_elems_size * buf_items);
- REQUIRE(vfs.fseek(fd, buf_elems_size * buf_items + 10, SEEK_SET) < 0);
- REQUIRE(vfs.ftell(fd) == buf_elems_size * buf_items);
-
- REQUIRE(vfs.fseek(fd, 0UL, SEEK_SET) == 0);
- REQUIRE(vfs.fread(buf_out.data(), buf_out.size() * sizeof(buf_out[0]), 1, fd) == 1);
- std::iota(std::begin(buffer), std::end(buffer), 0);
- REQUIRE(buffer == buf_out);
- REQUIRE(vfs.fclose(fd) == 0);
-}
-
-TEST_CASE("Simple file notifier init")
-{
- vfs.registerNotificationHandler(
- [](std::string_view file, vfsn::utility::vfsNotifier::FsEvent ev, std::string_view old_file) {
- using namespace std::string_literals;
- REQUIRE(file == "/"s);
- REQUIRE(ev == vfsn::utility::vfsNotifier::FsEvent::initialized);
- REQUIRE(old_file.empty());
- });
- vfs.registerNotificationHandler(nullptr);
-}
-
-TEST_CASE("Simple file notifier write")
-{
- vfs.registerNotificationHandler(
- [](std::string_view file, vfsn::utility::vfsNotifier::FsEvent ev, std::string_view old_file) {
- using namespace std::string_literals;
- namespace fs = std::filesystem;
- fs::path fspath(file);
- REQUIRE(fspath.is_absolute());
- REQUIRE(fspath.filename() == "testFileLB.txt"s);
- REQUIRE(ev == vfsn::utility::vfsNotifier::FsEvent::modified);
- REQUIRE(old_file.empty());
- });
-
- const size_t testBufferSize = 1024 * 1024;
-
- uint8_t testBuffer[testBufferSize] = {0};
-
- auto fd = vfs.fopen("testFileLB.txt", "w");
- REQUIRE(fd != nullptr);
-
- auto bytesWritten = vfs.fwrite(testBuffer, 1, testBufferSize, fd);
- REQUIRE(bytesWritten == testBufferSize);
-
- auto currFilePos = vfs.ftell(fd);
- REQUIRE(currFilePos == testBufferSize);
-
- auto fileSize = vfs.filelength(fd);
- REQUIRE(fileSize == testBufferSize);
-
- currFilePos = vfs.ftell(fd);
- REQUIRE(currFilePos == testBufferSize);
-
- REQUIRE(vfs.fclose(fd) == 0);
-
- vfs.registerNotificationHandler(nullptr);
-}
M source/main.cpp => source/main.cpp +9 -5
@@ 47,6 47,7 @@
#include <SystemManager/SystemManager.hpp>
#include <thread.hpp>
#include <vfs.hpp>
+#include <purefs/vfs_subsystem.hpp>
#include <memory>
#include <vector>
@@ 68,17 69,20 @@ int main()
bsp::BoardInit();
auto sysmgr = std::make_shared<sys::SystemManager>(5000);
+ purefs::subsystem::vfs_handle_t vfs;
- sysmgr->StartSystem([sysmgr]() {
+ sysmgr->StartSystem([sysmgr, &vfs]() {
/// force initialization of PhonenumberUtil because of its stack usage
/// otherwise we would end up with an init race and PhonenumberUtil could
/// be initiated in a task with stack not big enough to handle it
i18n::phonenumbers::PhoneNumberUtil::GetInstance();
-
- vfs.Init();
-
+ vfs = purefs::subsystem::initialize();
+ int err = purefs::subsystem::mount_defaults();
+ if (err) {
+ LOG_FATAL("VFS subystem fatal error %i", err);
+ std::abort();
+ }
auto ret = true;
-
ret &=
sys::SystemManager::CreateService(std::make_shared<EventManager>(service::name::evt_manager), sysmgr.get());
#if ENABLE_FILEINDEXER_SERVICE