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 <dominik.ermel@nordicsemi.no>
This commit is contained in:
Dominik Ermel 2020-10-08 11:36:57 +00:00 committed by Anas Nashif
commit aa0fd027fc
4 changed files with 34 additions and 3 deletions

View file

@ -73,6 +73,11 @@ enum {
FS_TYPE_EXTERNAL_BASE, 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 * @brief File system mount info structure
* *
@ -83,6 +88,7 @@ enum {
* @param storage_dev Pointer to backend storage device * @param storage_dev Pointer to backend storage device
* @param mountp_len Length of Mount point string * @param mountp_len Length of Mount point string
* @param fs Pointer to File system interface of the mount point * @param fs Pointer to File system interface of the mount point
* @param flags Mount flags
*/ */
struct fs_mount_t { struct fs_mount_t {
sys_dnode_t node; sys_dnode_t node;
@ -93,6 +99,7 @@ struct fs_mount_t {
/* fields filled by file system core */ /* fields filled by file system core */
size_t mountp_len; size_t mountp_len;
const struct fs_file_system_t *fs; const struct fs_file_system_t *fs;
uint8_t flags;
}; };
/** /**
@ -201,6 +208,9 @@ struct fs_statvfs {
* *
* @retval 0 on success; * @retval 0 on success;
* @retval -EINVAL when a bad file name is given; * @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 -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. * @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 * @param path Path to the file or directory to delete
* *
* @retval 0 on success; * @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 -ENOTSUP when not implemented by underlying file system driver;
* @retval <0 an other negative errno code on error. * @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 0 on success;
* @retval -ENOENT when file system type has not been registered; * @retval -ENOENT when file system type has not been registered;
* @retval -ENOTSUP when not supported by underlying file system driver; * @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); int fs_mount(struct fs_mount_t *mp);

View file

@ -410,7 +410,8 @@ static int fatfs_mount(struct fs_mount_t *mountp)
#if defined(CONFIG_FS_FATFS_MOUNT_MKFS) #if defined(CONFIG_FS_FATFS_MOUNT_MKFS)
/* If no file system found then create one */ /* 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]; uint8_t work[_MAX_SS];
res = f_mkfs(&mountp->mnt_point[1], res = f_mkfs(&mountp->mnt_point[1],

View file

@ -150,6 +150,10 @@ int fs_open(struct fs_file_t *zfp, const char *file_name, fs_mode_t flags)
} }
zfp->mp = mp; 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) { CHECKIF(zfp->mp->fs->open == NULL) {
return -ENOTSUP; return -ENOTSUP;
@ -473,6 +477,10 @@ int fs_mkdir(const char *abs_path)
return rc; return rc;
} }
if (mp->flags & FS_MOUNT_FLAG_READ_ONLY) {
return -EROFS;
}
CHECKIF(mp->fs->mkdir == NULL) { CHECKIF(mp->fs->mkdir == NULL) {
return -ENOTSUP; return -ENOTSUP;
} }
@ -502,6 +510,10 @@ int fs_unlink(const char *abs_path)
return rc; return rc;
} }
if (mp->flags & FS_MOUNT_FLAG_READ_ONLY) {
return -EROFS;
}
CHECKIF(mp->fs->unlink == NULL) { CHECKIF(mp->fs->unlink == NULL) {
return -ENOTSUP; return -ENOTSUP;
} }
@ -532,6 +544,10 @@ int fs_rename(const char *from, const char *to)
return rc; return rc;
} }
if (mp->flags & FS_MOUNT_FLAG_READ_ONLY) {
return -EROFS;
}
/* Make sure both files are mounted on the same path */ /* Make sure both files are mounted on the same path */
if (strncmp(from, to, match_len) != 0) { if (strncmp(from, to, match_len) != 0) {
LOG_ERR("mount point not same!!"); LOG_ERR("mount point not same!!");

View file

@ -677,7 +677,7 @@ static int littlefs_mount(struct fs_mount_t *mountp)
/* Mount it, formatting if needed. */ /* Mount it, formatting if needed. */
ret = lfs_mount(&fs->lfs, &fs->cfg); 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); LOG_WRN("can't mount (LFS %d); formatting", ret);
ret = lfs_format(&fs->lfs, &fs->cfg); ret = lfs_format(&fs->lfs, &fs->cfg);
if (ret < 0) { if (ret < 0) {