From aa0fd027fce25ef151465b46244a52b9b5174298 Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Thu, 8 Oct 2020 11:36:57 +0000 Subject: [PATCH] fs: Add support for mount flags The flags field has been added to fs_mount_t structure, accompanied with two new flags: FS_MOUNT_FLAG_READ_ONLY -- mount fs as read only FS_MOUNT_FLAG_NO_FORMAT -- do not format volume when system not found Code supporting the flags has been added to FS layer and drivers for LittleFS and FAT FS. Signed-off-by: Dominik Ermel --- include/fs/fs.h | 16 +++++++++++++++- subsys/fs/fat_fs.c | 3 ++- subsys/fs/fs.c | 16 ++++++++++++++++ subsys/fs/littlefs_fs.c | 2 +- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/include/fs/fs.h b/include/fs/fs.h index e90fffa8c81..6d19505b832 100644 --- a/include/fs/fs.h +++ b/include/fs/fs.h @@ -73,6 +73,11 @@ enum { FS_TYPE_EXTERNAL_BASE, }; +/** Flag prevents formatting device if requested file system not found */ +#define FS_MOUNT_FLAG_NO_FORMAT BIT(0) +/** Flag makes mounted file system read-only */ +#define FS_MOUNT_FLAG_READ_ONLY BIT(1) + /** * @brief File system mount info structure * @@ -83,6 +88,7 @@ enum { * @param storage_dev Pointer to backend storage device * @param mountp_len Length of Mount point string * @param fs Pointer to File system interface of the mount point + * @param flags Mount flags */ struct fs_mount_t { sys_dnode_t node; @@ -93,6 +99,7 @@ struct fs_mount_t { /* fields filled by file system core */ size_t mountp_len; const struct fs_file_system_t *fs; + uint8_t flags; }; /** @@ -201,6 +208,9 @@ struct fs_statvfs { * * @retval 0 on success; * @retval -EINVAL when a bad file name is given; + * @retval -EROFS when opening read-only file for write, or attempting to + * create a file on a system that has been mounted with the + * FS_MOUNT_FLAG_READ_ONLY flag; * @retval -ENOENT when the file path is not possible (bad mount point); * @retval <0 an other negative errno code, depending on a file system back-end. */ @@ -226,6 +236,8 @@ int fs_close(struct fs_file_t *zfp); * @param path Path to the file or directory to delete * * @retval 0 on success; + * @retval -EROFS if file is read-only, or when file system has been mounted + * with the FS_MOUNT_FLAG_READ_ONLY flag; * @retval -ENOTSUP when not implemented by underlying file system driver; * @retval <0 an other negative errno code on error. */ @@ -435,7 +447,9 @@ int fs_closedir(struct fs_dir_t *zdp); * @retval 0 on success; * @retval -ENOENT when file system type has not been registered; * @retval -ENOTSUP when not supported by underlying file system driver; - * @retval <0 a other negative errno code on error. + * @retval -EROFS if system requires formatting but @c FS_MOUNT_FLAG_READ_ONLY + * has been set; + * @retval <0 an other negative errno code on error. */ int fs_mount(struct fs_mount_t *mp); diff --git a/subsys/fs/fat_fs.c b/subsys/fs/fat_fs.c index c05f4236ed7..267b67cc5c8 100644 --- a/subsys/fs/fat_fs.c +++ b/subsys/fs/fat_fs.c @@ -410,7 +410,8 @@ static int fatfs_mount(struct fs_mount_t *mountp) #if defined(CONFIG_FS_FATFS_MOUNT_MKFS) /* If no file system found then create one */ - if (res == FR_NO_FILESYSTEM) { + if (res == FR_NO_FILESYSTEM && + !(mountp->flags & FS_MOUNT_FLAG_NO_FORMAT)) { uint8_t work[_MAX_SS]; res = f_mkfs(&mountp->mnt_point[1], diff --git a/subsys/fs/fs.c b/subsys/fs/fs.c index a1a08c1b8e2..463a437f870 100644 --- a/subsys/fs/fs.c +++ b/subsys/fs/fs.c @@ -150,6 +150,10 @@ int fs_open(struct fs_file_t *zfp, const char *file_name, fs_mode_t flags) } zfp->mp = mp; + if (((mp->flags & FS_MOUNT_FLAG_READ_ONLY) != 0) && + (flags & FS_O_CREATE || flags & FS_O_WRITE)) { + return -EROFS; + } CHECKIF(zfp->mp->fs->open == NULL) { return -ENOTSUP; @@ -473,6 +477,10 @@ int fs_mkdir(const char *abs_path) return rc; } + if (mp->flags & FS_MOUNT_FLAG_READ_ONLY) { + return -EROFS; + } + CHECKIF(mp->fs->mkdir == NULL) { return -ENOTSUP; } @@ -502,6 +510,10 @@ int fs_unlink(const char *abs_path) return rc; } + if (mp->flags & FS_MOUNT_FLAG_READ_ONLY) { + return -EROFS; + } + CHECKIF(mp->fs->unlink == NULL) { return -ENOTSUP; } @@ -532,6 +544,10 @@ int fs_rename(const char *from, const char *to) return rc; } + if (mp->flags & FS_MOUNT_FLAG_READ_ONLY) { + return -EROFS; + } + /* Make sure both files are mounted on the same path */ if (strncmp(from, to, match_len) != 0) { LOG_ERR("mount point not same!!"); diff --git a/subsys/fs/littlefs_fs.c b/subsys/fs/littlefs_fs.c index ab47f3379ef..fcd4106b5d9 100644 --- a/subsys/fs/littlefs_fs.c +++ b/subsys/fs/littlefs_fs.c @@ -677,7 +677,7 @@ static int littlefs_mount(struct fs_mount_t *mountp) /* Mount it, formatting if needed. */ ret = lfs_mount(&fs->lfs, &fs->cfg); - if (ret < 0) { + if (ret < 0 && !(mountp->flags & FS_MOUNT_FLAG_NO_FORMAT)) { LOG_WRN("can't mount (LFS %d); formatting", ret); ret = lfs_format(&fs->lfs, &fs->cfg); if (ret < 0) {