vfs.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2016 Eistec AB
3  *
4  * This file is subject to the terms and conditions of the GNU Lesser
5  * General Public License v2.1. See the file LICENSE in the top level
6  * directory for more details.
7  */
8 
53 #ifndef VFS_H
54 #define VFS_H
55 
56 #include <stdint.h>
57 #include <sys/stat.h> /* for struct stat */
58 #include <sys/types.h> /* for off_t etc. */
59 #include <sys/statvfs.h> /* for struct statvfs */
60 
61 #include "sched.h"
62 #include "clist.h"
63 #include "iolist.h"
64 #include "macros/utils.h"
65 #include "mtd.h"
66 #ifdef MODULE_NANOCOAP_FS
67 #include "net/sock/config.h"
68 #endif
69 #include "xfa.h"
70 
71 #ifdef __cplusplus
72 extern "C" {
73 /* restrict is a C99 keyword, not valid in C++, but GCC and Clang have the
74  * __restrict__ extension keyword which can be used instead */
75 #define restrict __restrict__
76 /* If the above is not supported by the compiler, you can replace it with an
77  * empty definition instead: */
78 /* #define restrict */
79 #endif
80 
84 #ifndef MAX6
85 #define MAX6(a, b, c, d, e, f) MAX(MAX(MAX(MAX((a), (b)), MAX((c), (d))), (e)), (f))
86 #endif
87 
92 #ifdef MODULE_FATFS_VFS
93 #include "ffconf.h"
94 
95 # if FF_FS_TINY
96 # define _FATFS_FILE_CACHE (0)
97 # else
98 # define _FATFS_FILE_CACHE FF_MAX_SS
99 # endif
100 
101 # if FF_USE_FASTSEEK
102 # if (__SIZEOF_POINTER__ == 8)
103 # define _FATFS_FILE_SEEK_PTR (8)
104 # else
105 # define _FATFS_FILE_SEEK_PTR (4)
106 # endif
107 # else
108 # define _FATFS_FILE_SEEK_PTR (0)
109 # endif
110 
111 # if FF_FS_EXFAT
112 # define _FATFS_FILE_EXFAT (48)
113 # define _FATFS_DIR_EXFAT (32)
114 # else
115 # define _FATFS_FILE_EXFAT (0)
116 # define _FATFS_DIR_EXFAT (0)
117 # endif
118 
119 # if FF_USE_LFN
120 # if (__SIZEOF_POINTER__ == 8)
121 # define _FATFS_DIR_LFN (8)
122 # else
123 # define _FATFS_DIR_LFN (4)
124 # endif
125 # else
126 # define _FATFS_DIR_LFN (0)
127 # endif
128 
129 # if (__SIZEOF_POINTER__ == 8)
130 # define FATFS_VFS_DIR_BUFFER_SIZE (64 + _FATFS_DIR_LFN + _FATFS_DIR_EXFAT)
131 # define FATFS_VFS_FILE_BUFFER_SIZE (64 + VFS_NAME_MAX + _FATFS_FILE_CACHE + \
132  _FATFS_FILE_SEEK_PTR + _FATFS_FILE_EXFAT)
133 # else
134 # define FATFS_VFS_DIR_BUFFER_SIZE (44 + _FATFS_DIR_LFN + _FATFS_DIR_EXFAT)
135 # define FATFS_VFS_FILE_BUFFER_SIZE (44 + VFS_NAME_MAX + _FATFS_FILE_CACHE + \
136  _FATFS_FILE_SEEK_PTR + _FATFS_FILE_EXFAT)
137 # endif
138 #else
139 # define FATFS_VFS_DIR_BUFFER_SIZE (1)
140 # define FATFS_VFS_FILE_BUFFER_SIZE (1)
141 #endif
148 #ifdef MODULE_LITTLEFS
149 # if (__SIZEOF_POINTER__ == 8)
150 # define LITTLEFS_VFS_DIR_BUFFER_SIZE (48)
151 # define LITTLEFS_VFS_FILE_BUFFER_SIZE (72)
152 # else
153 # define LITTLEFS_VFS_DIR_BUFFER_SIZE (44)
154 # define LITTLEFS_VFS_FILE_BUFFER_SIZE (56)
155 # endif
156 #else
157 # define LITTLEFS_VFS_DIR_BUFFER_SIZE (1)
158 # define LITTLEFS_VFS_FILE_BUFFER_SIZE (1)
159 #endif
166 #ifdef MODULE_LITTLEFS2
167 # if (__SIZEOF_POINTER__ == 8)
168 # define LITTLEFS2_VFS_DIR_BUFFER_SIZE (56)
169 # define LITTLEFS2_VFS_FILE_BUFFER_SIZE (104)
170 # else
171 # define LITTLEFS2_VFS_DIR_BUFFER_SIZE (52)
172 # define LITTLEFS2_VFS_FILE_BUFFER_SIZE (84)
173 # endif
174 #else
175 # define LITTLEFS2_VFS_DIR_BUFFER_SIZE (1)
176 # define LITTLEFS2_VFS_FILE_BUFFER_SIZE (1)
177 #endif
184 #ifdef MODULE_SPIFFS
185 # define SPIFFS_VFS_DIR_BUFFER_SIZE (12)
186 # define SPIFFS_VFS_FILE_BUFFER_SIZE (1)
187 #else
188 # define SPIFFS_VFS_DIR_BUFFER_SIZE (1)
189 # define SPIFFS_VFS_FILE_BUFFER_SIZE (1)
190 #endif
197 #if defined(MODULE_LWEXT4) || DOXYGEN
198 # define LWEXT4_VFS_DIR_BUFFER_SIZE (308)
199 # define LWEXT4_VFS_FILE_BUFFER_SIZE (32)
200 #else
201 # define LWEXT4_VFS_DIR_BUFFER_SIZE (1)
202 # define LWEXT4_VFS_FILE_BUFFER_SIZE (1)
203 #endif
210 #if defined(MODULE_NANOCOAP_FS) || DOXYGEN
211 # define NANOCOAP_FS_VFS_DIR_BUFFER_SIZE \
212  (4 + CONFIG_SOCK_URLPATH_MAXLEN)
213 # define NANOCOAP_FS_VFS_FILE_BUFFER_SIZE \
214  (4 + CONFIG_SOCK_URLPATH_MAXLEN)
215 #else
216 # define NANOCOAP_FS_VFS_DIR_BUFFER_SIZE (1)
217 # define NANOCOAP_FS_VFS_FILE_BUFFER_SIZE (1)
218 #endif
221 #ifndef VFS_MAX_OPEN_FILES
225 #define VFS_MAX_OPEN_FILES (16)
226 #endif
227 
228 #ifndef VFS_DIR_BUFFER_SIZE
256 #define VFS_DIR_BUFFER_SIZE MAX6(FATFS_VFS_DIR_BUFFER_SIZE, \
257  LITTLEFS_VFS_DIR_BUFFER_SIZE, \
258  LITTLEFS2_VFS_DIR_BUFFER_SIZE, \
259  SPIFFS_VFS_DIR_BUFFER_SIZE, \
260  LWEXT4_VFS_DIR_BUFFER_SIZE, \
261  NANOCOAP_FS_VFS_DIR_BUFFER_SIZE \
262  )
263 #endif
264 
265 #ifndef VFS_FILE_BUFFER_SIZE
285 #define VFS_FILE_BUFFER_SIZE MAX6(FATFS_VFS_FILE_BUFFER_SIZE, \
286  LITTLEFS_VFS_FILE_BUFFER_SIZE, \
287  LITTLEFS2_VFS_FILE_BUFFER_SIZE, \
288  SPIFFS_VFS_FILE_BUFFER_SIZE, \
289  LWEXT4_VFS_FILE_BUFFER_SIZE, \
290  NANOCOAP_FS_VFS_FILE_BUFFER_SIZE \
291  )
292 #endif
293 
294 #ifndef VFS_NAME_MAX
302 #define VFS_NAME_MAX (31)
303 #endif
304 
308 #define VFS_ANY_FD (-1)
309 
315 #define VFS_MTD(mtd) { .dev = &mtd.base }
316 
330 #define VFS_AUTO_MOUNT(type, mtd, path, idx) \
331  static type ## _desc_t fs_desc_ ## idx = mtd; \
332  \
333  XFA(vfs_mount_t, vfs_mountpoints_xfa, 0) \
334  _mount_mtd_ ## idx = { \
335  .fs = &type ## _file_system, \
336  .mount_point = path, \
337  .private_data = &fs_desc_ ## idx, \
338  }
339 
340 /* Forward declarations */
344 typedef struct vfs_file_ops vfs_file_ops_t;
345 
349 typedef struct vfs_dir_ops vfs_dir_ops_t;
350 
355 
359 /* not struct vfs_mount because of name collision with the function */
360 typedef struct vfs_mount_struct vfs_mount_t;
361 
365 extern const vfs_file_ops_t mtd_vfs_ops;
366 
370 #define VFS_FS_FLAG_WANT_ABS_PATH (1 << 0)
371 
375 typedef struct {
379  const uint32_t flags;
381 
388  const char *mount_point;
390  uint16_t open_files;
391  void *private_data;
392 };
393 
399 typedef struct {
402  int flags;
403  off_t pos;
405  union {
406  void *ptr;
407  int value;
408  uint8_t buffer[VFS_FILE_BUFFER_SIZE];
409  } private_data;
410 } vfs_file_t;
411 
420 typedef struct {
423  union {
424  void *ptr;
425  int value;
426  uint8_t buffer[VFS_DIR_BUFFER_SIZE];
427  } private_data;
428 } vfs_DIR;
429 
438 typedef struct {
439  ino_t d_ino;
440  char d_name[VFS_NAME_MAX + 1];
441 } vfs_dirent_t;
442 
448 struct vfs_file_ops {
467  int (*close) (vfs_file_t *filp);
468 
479  int (*fcntl) (vfs_file_t *filp, int cmd, int arg);
480 
490  int (*fstat) (vfs_file_t *filp, struct stat *buf);
491 
509  off_t (*lseek) (vfs_file_t *filp, off_t off, int whence);
510 
537  int (*open) (vfs_file_t *filp, const char *name, int flags, mode_t mode);
538 
549  ssize_t (*read) (vfs_file_t *filp, void *dest, size_t nbytes);
550 
561  ssize_t (*write) (vfs_file_t *filp, const void *src, size_t nbytes);
562 
572  int (*fsync) (vfs_file_t *filp);
573 };
574 
578 struct vfs_dir_ops {
588  int (*opendir) (vfs_DIR *dirp, const char *dirname);
589 
609  int (*readdir) (vfs_DIR *dirp, vfs_dirent_t *entry);
610 
619  int (*closedir) (vfs_DIR *dirp);
620 };
621 
636  int (*format) (vfs_mount_t *mountp);
637 
652  int (*mount) (vfs_mount_t *mountp);
653 
662  int (*umount) (vfs_mount_t *mountp);
663 
678  int (*rename) (vfs_mount_t *mountp, const char *from_path, const char *to_path);
679 
689  int (*unlink) (vfs_mount_t *mountp, const char *name);
690 
701  int (*mkdir) (vfs_mount_t *mountp, const char *name, mode_t mode);
702 
714  int (*rmdir) (vfs_mount_t *mountp, const char *name);
715 
726  int (*stat) (vfs_mount_t *mountp, const char *restrict path, struct stat *restrict buf);
727 
743  int (*statvfs) (vfs_mount_t *mountp, const char *restrict path, struct statvfs *restrict buf);
744 };
745 
753 void vfs_bind_stdio(void);
754 
763 int vfs_close(int fd);
764 
775 int vfs_fcntl(int fd, int cmd, int arg);
776 
786 int vfs_fstat(int fd, struct stat *buf);
787 
797 int vfs_fstatvfs(int fd, struct statvfs *buf);
798 
808 int vfs_dstatvfs(vfs_DIR *dirp, struct statvfs *buf);
809 
827 off_t vfs_lseek(int fd, off_t off, int whence);
828 
839 int vfs_open(const char *name, int flags, mode_t mode);
840 
854 ssize_t vfs_read(int fd, void *dest, size_t count);
855 
868 ssize_t vfs_readline(int fd, char *dest, size_t count);
869 
883 ssize_t vfs_write(int fd, const void *src, size_t count);
884 
894 ssize_t vfs_write_iol(int fd, const iolist_t *iolist);
895 
905 int vfs_fsync(int fd);
906 
918 int vfs_opendir(vfs_DIR *dirp, const char *dirname);
919 
937 int vfs_readdir(vfs_DIR *dirp, vfs_dirent_t *entry);
938 
951 
965 int vfs_format(vfs_mount_t *mountp);
966 
980 int vfs_format_by_path(const char *path);
981 
993 int vfs_mount(vfs_mount_t *mountp);
994 
1008 int vfs_mount_by_path(const char *path);
1009 
1021 int vfs_unmount_by_path(const char *path, bool force);
1022 
1036 int vfs_rename(const char *from_path, const char *to_path);
1037 
1049 int vfs_umount(vfs_mount_t *mountp, bool force);
1050 
1059 int vfs_unlink(const char *name);
1060 
1070 int vfs_mkdir(const char *name, mode_t mode);
1071 
1082 int vfs_rmdir(const char *name);
1083 
1093 int vfs_stat(const char *restrict path, struct stat *restrict buf);
1094 
1107 int vfs_statvfs(const char *restrict path, struct statvfs *restrict buf);
1108 
1128 int vfs_bind(int fd, int flags, const vfs_file_ops_t *f_op, void *private_data);
1129 
1147 int vfs_normalize_path(char *buf, const char *path, size_t buflen);
1148 
1166 
1197 
1211 const vfs_file_t *vfs_file_get(int fd);
1212 
1224  const char *restrict path,
1225  struct stat *restrict buf);
1226 
1227 #ifdef __cplusplus
1228 }
1229 #endif
1230 
1231 #endif /* VFS_H */
1232 
Circular linked list.
Various helper macros.
int16_t kernel_pid_t
Unique process identifier.
Definition: sched.h:139
#define VFS_DIR_BUFFER_SIZE
Size of buffer space in vfs_DIR.
Definition: vfs.h:256
int vfs_mount(vfs_mount_t *mountp)
Mount a file system.
int vfs_normalize_path(char *buf, const char *path, size_t buflen)
Normalize a path.
int vfs_open(const char *name, int flags, mode_t mode)
Open a file.
int vfs_statvfs(const char *restrict path, struct statvfs *restrict buf)
Get file system status.
ssize_t vfs_write(int fd, const void *src, size_t count)
Write bytes to an open file.
int vfs_mkdir(const char *name, mode_t mode)
Create a directory on the file system.
int vfs_umount(vfs_mount_t *mountp, bool force)
Unmount a mounted file system.
int vfs_close(int fd)
Close an open file.
#define VFS_FILE_BUFFER_SIZE
Size of buffer space in vfs_file_t.
Definition: vfs.h:285
int vfs_sysop_stat_from_fstat(vfs_mount_t *mountp, const char *restrict path, struct stat *restrict buf)
Implementation of stat using fstat
#define VFS_NAME_MAX
Maximum length of the name in a vfs_dirent_t (not including terminating null)
Definition: vfs.h:302
int vfs_readdir(vfs_DIR *dirp, vfs_dirent_t *entry)
Read a single entry from the open directory dirp and advance the read position by one.
off_t vfs_lseek(int fd, off_t off, int whence)
Seek to position in file.
int vfs_format(vfs_mount_t *mountp)
Format a file system.
int vfs_bind(int fd, int flags, const vfs_file_ops_t *f_op, void *private_data)
Allocate a new file descriptor and give it file operations.
int vfs_format_by_path(const char *path)
Format a file system.
int vfs_rename(const char *from_path, const char *to_path)
Rename a file.
ssize_t vfs_write_iol(int fd, const iolist_t *iolist)
Write bytes from an iolist to an open file.
int vfs_stat(const char *restrict path, struct stat *restrict buf)
Get file status.
void vfs_bind_stdio(void)
Allocate and bind file descriptors for STDIN, STDERR, and STDOUT.
ssize_t vfs_readline(int fd, char *dest, size_t count)
Read a line from an open text file.
const vfs_file_t * vfs_file_get(int fd)
Get information about the file for internal purposes.
int vfs_unlink(const char *name)
Unlink (delete) a file from a mounted file system.
int vfs_fsync(int fd)
Synchronize a file on storage Any pending writes are written out to storage.
int vfs_opendir(vfs_DIR *dirp, const char *dirname)
Open a directory for reading with readdir.
const vfs_file_ops_t mtd_vfs_ops
MTD driver for VFS.
int vfs_dstatvfs(vfs_DIR *dirp, struct statvfs *buf)
Get file system status of the file system containing an open directory.
int vfs_rmdir(const char *name)
Remove a directory from the file system.
int vfs_fcntl(int fd, int cmd, int arg)
Query/set options on an open file.
int vfs_fstat(int fd, struct stat *buf)
Get status of an open file.
ssize_t vfs_read(int fd, void *dest, size_t count)
Read bytes from an open file.
bool vfs_iterate_mount_dirs(vfs_DIR *dir)
Iterate through all mounted file systems by their root directories.
int vfs_closedir(vfs_DIR *dirp)
Close an open directory.
int vfs_fstatvfs(int fd, struct statvfs *buf)
Get file system status of the file system containing an open file.
const vfs_mount_t * vfs_iterate_mounts(const vfs_mount_t *cur)
Iterate through all mounted file systems.
int vfs_mount_by_path(const char *path)
Mount a file system with a pre-configured mount path.
int vfs_unmount_by_path(const char *path, bool force)
Unmount a file system with a pre-configured mount path.
iolist scatter / gather IO
Scheduler API definition.
POSIX compatible sys/statvfs.h definitions.
iolist structure definition
Definition: iolist.h:39
List node structure.
Definition: list.h:40
File system information.
Definition: statvfs.h:46
Internal representation of a file system directory entry.
Definition: vfs.h:420
const vfs_dir_ops_t * d_op
Directory operations table.
Definition: vfs.h:421
int value
alternatively, you can use private_data as an int
Definition: vfs.h:425
vfs_mount_t * mp
Pointer to mount table entry.
Definition: vfs.h:422
void * ptr
pointer to private data
Definition: vfs.h:424
Operations on open directories.
Definition: vfs.h:578
int(* readdir)(vfs_DIR *dirp, vfs_dirent_t *entry)
Read a single entry from the open directory dirp and advance the read position by one.
Definition: vfs.h:609
int(* opendir)(vfs_DIR *dirp, const char *dirname)
Open a directory for reading with readdir.
Definition: vfs.h:588
int(* closedir)(vfs_DIR *dirp)
Close an open directory.
Definition: vfs.h:619
User facing directory entry.
Definition: vfs.h:438
ino_t d_ino
file serial number, unique for the file system ("inode" in Linux)
Definition: vfs.h:439
Operations on open files.
Definition: vfs.h:448
int(* fcntl)(vfs_file_t *filp, int cmd, int arg)
Query/set options on an open file.
Definition: vfs.h:479
int(* close)(vfs_file_t *filp)
Close an open file.
Definition: vfs.h:467
int(* fstat)(vfs_file_t *filp, struct stat *buf)
Get status of an open file.
Definition: vfs.h:490
int(* fsync)(vfs_file_t *filp)
Synchronize a file on storage Any pending writes are written out to storage.
Definition: vfs.h:572
off_t(* lseek)(vfs_file_t *filp, off_t off, int whence)
Seek to position in file.
Definition: vfs.h:509
int(* open)(vfs_file_t *filp, const char *name, int flags, mode_t mode)
Attempt to open a file in the file system at rel_path.
Definition: vfs.h:537
ssize_t(* read)(vfs_file_t *filp, void *dest, size_t nbytes)
Read bytes from an open file.
Definition: vfs.h:549
ssize_t(* write)(vfs_file_t *filp, const void *src, size_t nbytes)
Write bytes to an open file.
Definition: vfs.h:561
Operations on mounted file systems.
Definition: vfs.h:627
int(* mount)(vfs_mount_t *mountp)
Perform any extra processing needed after mounting a file system.
Definition: vfs.h:652
int(* unlink)(vfs_mount_t *mountp, const char *name)
Unlink (delete) a file from the file system.
Definition: vfs.h:689
int(* rename)(vfs_mount_t *mountp, const char *from_path, const char *to_path)
Rename a file.
Definition: vfs.h:678
int(* stat)(vfs_mount_t *mountp, const char *restrict path, struct stat *restrict buf)
Get file status.
Definition: vfs.h:726
int(* mkdir)(vfs_mount_t *mountp, const char *name, mode_t mode)
Create a directory on the file system.
Definition: vfs.h:701
int(* format)(vfs_mount_t *mountp)
Format the file system on the given mount point.
Definition: vfs.h:636
int(* rmdir)(vfs_mount_t *mountp, const char *name)
Remove a directory from the file system.
Definition: vfs.h:714
int(* umount)(vfs_mount_t *mountp)
Perform the necessary clean up for unmounting a file system.
Definition: vfs.h:662
A file system driver.
Definition: vfs.h:375
const vfs_file_system_ops_t * fs_op
File system operations table.
Definition: vfs.h:378
const vfs_dir_ops_t * d_op
Directory operations table.
Definition: vfs.h:377
const vfs_file_ops_t * f_op
File operations table.
Definition: vfs.h:376
const uint32_t flags
File system flags.
Definition: vfs.h:379
Information about an open file.
Definition: vfs.h:399
void * ptr
pointer to private data
Definition: vfs.h:406
vfs_mount_t * mp
Pointer to mount table entry.
Definition: vfs.h:401
kernel_pid_t pid
PID of the process that opened the file.
Definition: vfs.h:404
int value
alternatively, you can use private_data as an int
Definition: vfs.h:407
int flags
File flags.
Definition: vfs.h:402
const vfs_file_ops_t * f_op
File operations table.
Definition: vfs.h:400
off_t pos
Current position in the file.
Definition: vfs.h:403
A mounted file system.
Definition: vfs.h:385
const vfs_file_system_t * fs
The file system driver for the mount point.
Definition: vfs.h:387
clist_node_t list_entry
List entry for the _vfs_mount_list list.
Definition: vfs.h:386
size_t mount_point_len
Length of mount_point string (set by vfs_mount)
Definition: vfs.h:389
uint16_t open_files
Number of currently open files and directories.
Definition: vfs.h:390
void * private_data
File system driver private data, implementation defined.
Definition: vfs.h:391
const char * mount_point
Mount point, e.g.
Definition: vfs.h:388
Cross File Arrays.