A board/rt1051/newlib/include/sys/mount.h => board/rt1051/newlib/include/sys/mount.h +41 -0
@@ 0,0 1,41 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+#pragma once
+
+
+
+/* These are the fs-independent mount-flags: up to 16 flags are
+ supported */
+enum
+{
+ MS_RDONLY = 1, /* Mount read-only. */
+ MS_NOEXEC = 8, /* Disallow program execution. */
+ MS_SYNCHRONOUS = 16, /* Writes are synced at once. */
+ MS_REMOUNT = 32, /* Alter flags of a mounted FS. */
+ MS_MANDLOCK = 64, /* Allow mandatory locks on an FS. */
+ MS_DIRSYNC = 128, /* Directory modifications are synchronous. */
+ MS_NOATIME = 1024, /* Do not update access times. */
+ MS_NODIRATIME = 2048, /* Do not update directory access times. */
+ MS_BIND = 4096, /* Bind directory at different place. */
+};
+
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Mount a filesystem. */
+int mount (const char *special_file, const char *dir,
+ const char *fstype, unsigned long int rwflag,
+ const void *data);
+
+/* Unmount a filesystem. */
+int umount (const char *special_file);
+
+
+#ifdef __cplusplus
+}
+#endif
+
M module-vfs/drivers/src/purefs/fs/filesystem_littlefs.cpp => module-vfs/drivers/src/purefs/fs/filesystem_littlefs.cpp +13 -10
@@ 8,6 8,7 @@
#include <purefs/fs/drivers/directory_handle_littlefs.hpp>
#include <purefs/blkdev/disk_manager.hpp>
#include <purefs/blkdev/disk_handle.hpp>
+#include <purefs/fs/mount_flags.hpp>
#include <littlefs/lfs.h>
#include <log/log.hpp>
@@ 86,27 87,29 @@ namespace
return lfs_mode;
}
- auto translate_attrib_to_st_mode(uint8_t type)
+ auto translate_attrib_to_st_mode(uint8_t type, bool ro)
{
- decltype(static_cast<struct stat *>(nullptr)->st_mode) mode =
- S_IRUSR | S_IRGRP | S_IROTH | S_IWUSR | S_IWGRP | S_IWOTH;
+ decltype(static_cast<struct stat *>(nullptr)->st_mode) mode = S_IRUSR | S_IRGRP | S_IROTH;
+ if (!ro) {
+ mode |= S_IWUSR | S_IWGRP | S_IWOTH;
+ }
if (type == LFS_TYPE_REG) {
- mode |= (S_IFREG | S_IXUSR | S_IXGRP | S_IXOTH);
+ mode |= S_IFREG;
}
else if (type == LFS_TYPE_DIR) {
- mode |= S_IFDIR;
+ mode |= (S_IFDIR | S_IXUSR | S_IXGRP | S_IXOTH);
}
return mode;
}
- void translate_lfsinfo_to_stat(const ::lfs_info &fs, const lfs_config &cfg, struct stat &st)
+ void translate_lfsinfo_to_stat(const ::lfs_info &fs, const lfs_config &cfg, bool ro, struct stat &st)
{
std::memset(&st, 0, sizeof st);
st.st_nlink = 1;
st.st_size = fs.size;
st.st_blksize = cfg.block_size;
st.st_blocks = fs.size / cfg.block_count;
- st.st_mode = translate_attrib_to_st_mode(fs.type);
+ st.st_mode = translate_attrib_to_st_mode(fs.type, ro);
}
[[gnu::nonnull(1)]] int setup_lfs_config(lfs_config *cfg, size_t sector_size, size_t part_sectors_count)
@@ 338,7 341,7 @@ namespace purefs::fs::drivers
const auto err = invoke_lfs(zfile->mntpoint(), ::lfs_stat, path.c_str(), &linfo);
if (!err) {
auto vmnt = std::static_pointer_cast<mount_point_littlefs>(vfile->mntpoint());
- translate_lfsinfo_to_stat(linfo, *vmnt->lfs_config(), st);
+ translate_lfsinfo_to_stat(linfo, *vmnt->lfs_config(), vmnt->flags() & mount_flags::read_only, st);
}
return err;
}
@@ 349,7 352,7 @@ namespace purefs::fs::drivers
const auto err = invoke_lfs(mnt, file, ::lfs_stat, &linfo);
if (!err) {
auto mntp = std::static_pointer_cast<mount_point_littlefs>(mnt);
- translate_lfsinfo_to_stat(linfo, *mntp->lfs_config(), st);
+ translate_lfsinfo_to_stat(linfo, *mntp->lfs_config(), mntp->flags() & mount_flags::read_only, st);
}
return err;
}
@@ 418,7 421,7 @@ namespace purefs::fs::drivers
int err = invoke_lfs(dirstate, ::lfs_dir_read, &linfo);
if (err == 1) {
auto mntp = std::static_pointer_cast<mount_point_littlefs>(dirstate->mntpoint());
- translate_lfsinfo_to_stat(linfo, *mntp->lfs_config(), filestat);
+ translate_lfsinfo_to_stat(linfo, *mntp->lfs_config(), mntp->flags() & mount_flags::read_only, filestat);
filename = linfo.name;
err = 0;
}
M module-vfs/drivers/src/purefs/fs/filesystem_vfat.cpp => module-vfs/drivers/src/purefs/fs/filesystem_vfat.cpp +21 -8
@@ 7,6 7,7 @@
#include <purefs/blkdev/disk_handle.hpp>
#include <purefs/fs/drivers/file_handle_vfat.hpp>
#include <purefs/fs/drivers/directory_handle_vfat.hpp>
+#include <purefs/fs/mount_flags.hpp>
#include <log/log.hpp>
#include <fatfs/volume_mapper.hpp>
#include <ff.h>
@@ 82,7 83,7 @@ namespace purefs::fs::drivers
return fat_mode;
}
- auto translate_fat_attrib_to_mode(BYTE fattrib)
+ auto translate_fat_attrib_to_mode(BYTE fattrib, bool ro)
{
decltype(static_cast<struct stat *>(nullptr)->st_mode) mode = S_IRUSR | S_IRGRP | S_IROTH;
@@ 92,7 93,7 @@ namespace purefs::fs::drivers
else {
mode |= S_IFREG;
}
- if ((fattrib & AM_RDO) == 0) {
+ if ((fattrib & AM_RDO) == 0 && !ro) {
mode |= (S_IWUSR | S_IWGRP | S_IWOTH);
}
if (fattrib & AM_HID) {}
@@ 109,7 110,7 @@ namespace purefs::fs::drivers
return attr;
}
- void translate_filinfo_to_stat(const FILINFO &fs, const FIL *fil, struct stat &st)
+ void translate_filinfo_to_stat(const FILINFO &fs, const FIL *fil, bool ro, struct stat &st)
{
if (fil) {
st.st_dev = fil->obj.id;
@@ 119,7 120,7 @@ namespace purefs::fs::drivers
st.st_dev = 0;
st.st_ino = 0;
}
- st.st_mode = translate_fat_attrib_to_mode(fs.fattrib);
+ st.st_mode = translate_fat_attrib_to_mode(fs.fattrib, ro);
st.st_nlink = 1;
st.st_uid = 0;
st.st_gid = 0;
@@ 339,7 340,13 @@ namespace purefs::fs::drivers
FILINFO finfo;
const auto fres = f_stat(vfile->open_path().c_str(), &finfo);
if (fres == FR_OK) {
- translate_filinfo_to_stat(finfo, vfile->ff_filp(), st);
+ const auto vmnt = vfile->mntpoint();
+ if (vmnt) {
+ translate_filinfo_to_stat(finfo, vfile->ff_filp(), vmnt->flags() & mount_flags::read_only, st);
+ }
+ else {
+ return -EIO;
+ }
}
return translate_error(fres);
}
@@ 355,7 362,7 @@ namespace purefs::fs::drivers
const auto fspath = vmnt->native_path(file);
const int fres = f_stat(fspath.c_str(), &finfo);
if (fres == FR_OK) {
- translate_filinfo_to_stat(finfo, nullptr, st);
+ translate_filinfo_to_stat(finfo, nullptr, vmnt->flags() & mount_flags::read_only, st);
}
return translate_error(fres);
}
@@ 436,8 443,14 @@ namespace purefs::fs::drivers
return -ENODATA;
}
else {
- translate_filinfo_to_stat(ffinfo, nullptr, filestat);
- filename = ffinfo.fname;
+ const auto vmnt = dirp->mntpoint();
+ if (vmnt) {
+ translate_filinfo_to_stat(ffinfo, nullptr, vmnt->flags() & mount_flags::read_only, filestat);
+ filename = ffinfo.fname;
+ }
+ else {
+ return -EIO;
+ }
}
}
return translate_error(ferr);
A module-vfs/include/internal/purefs/fs/mount_flags.hpp => module-vfs/include/internal/purefs/fs/mount_flags.hpp +17 -0
@@ 0,0 1,17 @@
+// Copyright (c) 2017-2021, Mudita Sp. z.o.o. All rights reserved.
+// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
+
+#pragma once
+
+namespace purefs::fs
+{
+ //! Mount flags struct
+ struct mount_flags
+ {
+ enum _mount_flags
+ {
+ read_only = 1,
+ remount = 32,
+ };
+ };
+} // namespace purefs::fs
M module-vfs/include/internal/purefs/fs/mount_point.hpp => module-vfs/include/internal/purefs/fs/mount_point.hpp +5 -1
@@ 45,6 45,10 @@ namespace purefs::fs::internal
{
return m_flags;
}
+ void modify_flags(unsigned flags) noexcept
+ {
+ m_flags = flags;
+ }
auto native_path(std::string_view full_path) const noexcept -> std::string
{
const auto n1 = full_path.find(m_path);
@@ 66,6 70,6 @@ namespace purefs::fs::internal
const std::weak_ptr<blkdev::internal::disk_handle> m_diskh;
const std::string m_path; //! Mounted path
const std::weak_ptr<filesystem_operations> m_fs; //! Filesystem operation
- const unsigned m_flags;
+ unsigned m_flags;
};
} // namespace purefs::fs::internal
M module-vfs/include/user/purefs/fs/filesystem.hpp => module-vfs/include/user/purefs/fs/filesystem.hpp +13 -10
@@ 14,6 14,7 @@
#include <purefs/fs/file_handle.hpp>
#include <purefs/fs/directory_handle.hpp>
#include <purefs/fs/mount_point.hpp>
+#include <purefs/fs/mount_flags.hpp>
#include <type_traits>
struct statvfs;
@@ 41,15 42,6 @@ namespace purefs::fs
{
class directory_handle;
}
- //! Mount flags struct
- struct mount_flags
- {
- enum _mount_flags
- {
- read_only = 1U < 0U, // !Read only filesystem
- };
- };
-
class filesystem
{
static constexpr auto path_separator = '/';
@@ 173,6 165,11 @@ namespace purefs::fs
auto find_filehandle(int fds) const noexcept -> fsfile;
private:
+ enum class iaccess : bool
+ {
+ ro, //! Syscall is RO
+ rw //! Syscall is RW
+ };
template <class Base, class T, typename... Args>
inline auto invoke_fops(T Base::*method, int fds, Args &&... args)
-> decltype((static_cast<Base *>(nullptr)->*method)(0, std::forward<Args>(args)...))
@@ 197,7 194,7 @@ namespace purefs::fs
}
template <class Base, class T, typename... Args>
- inline auto invoke_fops(T Base::*method, std::string_view path, Args &&... args) const
+ inline auto invoke_fops(iaccess acc, T Base::*method, std::string_view path, Args &&... args) const
-> decltype((static_cast<Base *>(nullptr)->*method)(nullptr, {}, std::forward<Args>(args)...))
{
const auto abspath = absolute_path(path);
@@ 205,6 202,9 @@ namespace purefs::fs
if (!mountp) {
return -ENOENT;
}
+ if (acc == iaccess::rw && (mountp->flags() & mount_flags::read_only)) {
+ return -EACCES;
+ }
auto fsops = mountp->fs_ops();
if (fsops)
return (fsops.get()->*method)(mountp, abspath, std::forward<Args>(args)...);
@@ 225,6 225,9 @@ namespace purefs::fs
if (!mountp) {
return -ENOENT;
}
+ if (mountp->flags() & mount_flags::read_only) {
+ return -EACCES;
+ }
if (path.compare(0, pathpos, path2, 0, pathpos) != 0) {
// Mount points are not the same
return -EXDEV;
M module-vfs/src/purefs/fs/filesystem.cpp => module-vfs/src/purefs/fs/filesystem.cpp +9 -2
@@ 73,8 73,15 @@ namespace purefs::fs
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());
- return -EBUSY;
+ if (flags & mount_flags::remount) {
+ // NOTE: Currently only RO is supported
+ mpi->second->modify_flags(flags);
+ return {};
+ }
+ else {
+ LOG_ERROR("VFS: mount point already exists %.*s", int(target.length()), target.data());
+ return -EBUSY;
+ }
}
const auto mpp = m_partitions.find(std::string(dev_or_part));
if (mpp != std::end(m_partitions)) {
M module-vfs/src/purefs/fs/filesystem_syscalls.cpp => module-vfs/src/purefs/fs/filesystem_syscalls.cpp +12 -7
@@ 7,37 7,38 @@
#include <purefs/fs/file_handle.hpp>
#include <purefs/fs/directory_handle.hpp>
#include <purefs/fs/thread_local_cwd.hpp>
+#include <fcntl.h>
namespace purefs::fs
{
auto filesystem::stat_vfs(std::string_view path, struct ::statvfs &stat) const noexcept -> int
{
- return invoke_fops(&filesystem_operations::stat_vfs, path, stat);
+ return invoke_fops(iaccess::ro, &filesystem_operations::stat_vfs, path, stat);
}
auto filesystem::stat(std::string_view file, struct stat &st) noexcept -> int
{
- return invoke_fops(&filesystem_operations::stat, file, st);
+ return invoke_fops(iaccess::ro, &filesystem_operations::stat, file, st);
}
auto filesystem::unlink(std::string_view name) noexcept -> int
{
- return invoke_fops(&filesystem_operations::unlink, name);
+ return invoke_fops(iaccess::rw, &filesystem_operations::unlink, name);
}
auto filesystem::mkdir(std::string_view path, int mode) noexcept -> int
{
- return invoke_fops(&filesystem_operations::mkdir, path, mode);
+ return invoke_fops(iaccess::rw, &filesystem_operations::mkdir, path, mode);
}
auto filesystem::ioctl(std::string_view path, int cmd, void *arg) noexcept -> int
{
- return invoke_fops(&filesystem_operations::ioctl, path, cmd, arg);
+ return invoke_fops(iaccess::ro, &filesystem_operations::ioctl, path, cmd, arg);
}
auto filesystem::utimens(std::string_view path, std::array<timespec, 2> &tv) noexcept -> int
{
- return invoke_fops(&filesystem_operations::utimens, path, tv);
+ return invoke_fops(iaccess::ro, &filesystem_operations::utimens, path, tv);
}
auto filesystem::flock(int fd, int cmd) noexcept -> int
@@ 52,7 53,7 @@ namespace purefs::fs
auto filesystem::chmod(std::string_view path, mode_t mode) noexcept -> int
{
- return invoke_fops(&filesystem_operations::chmod, path, mode);
+ return invoke_fops(iaccess::rw, &filesystem_operations::chmod, path, mode);
}
auto filesystem::write(int fd, const char *ptr, size_t len) noexcept -> ssize_t
@@ 115,6 116,10 @@ namespace purefs::fs
}
auto fsops = mountp->fs_ops();
if (fsops) {
+ if ((flags & O_ACCMODE) != O_RDONLY && (mountp->flags() & mount_flags::read_only)) {
+ LOG_ERROR("Trying to open file %.*s with WR... flag on RO filesystem", int(path.size()), path.data());
+ return -EACCES;
+ }
auto fh = fsops->open(mountp, abspath, flags, mode);
if (!fh) {
LOG_ERROR("VFS: Unable to get fops");