Virtual File System (VFS) layer

Provides an interface for accessing files and directories from different devices and file systems. More...

Detailed Description

This layer is modeled as a mix between POSIX syscalls (e.g. open) and the Linux VFS layer implementation, with major reductions in the feature set, in order to fit the resource constrained platforms that RIOT targets.

The overall design goals are:

The API should be easy to understand for users who are familiar with the POSIX file functions (open, close, read, write, fstat, lseek etc.)

The VFS layer keeps track of mounted file systems and open files, the vfs_open function searches the array of mounted file systems and dispatches the call to the file system instance with the longest matching mount point prefix. Subsequent calls to vfs_read, vfs_write, etc will do a look up in the table of open files and dispatch the call to the correct file system driver for handling.

vfs_mount takes a string containing the mount point, a file system driver specification (struct file_system), and an opaque pointer that only the FS driver knows how to use, which can be used to keep driver parameters in order to allow dynamic handling of multiple devices.

Todo:
VFS layer reference counting and locking for open files and simultaneous access.

Files

file  vfs.h
 VFS layer API declarations.
 

Data Structures

struct  vfs_file_system_t
 A file system driver. More...
 
struct  vfs_mount_struct
 A mounted file system. More...
 
struct  vfs_file_t
 Information about an open file. More...
 
struct  vfs_DIR
 Internal representation of a file system directory entry. More...
 
struct  vfs_dirent_t
 User facing directory entry. More...
 
struct  vfs_file_ops
 Operations on open files. More...
 
struct  vfs_dir_ops
 Operations on open directories. More...
 
struct  vfs_file_system_ops
 Operations on mounted file systems. More...
 

Macros

#define VFS_MAX_OPEN_FILES   (16)
 Maximum number of simultaneous open files.
 
#define VFS_DIR_BUFFER_SIZE   (12)
 Size of buffer space in vfs_DIR. More...
 
#define VFS_NAME_MAX   (31)
 Maximum length of the name in a vfs_dirent_t (not including terminating null) More...
 
#define VFS_ANY_FD   (-1)
 Used with vfs_bind to bind to any available fd number.
 

Typedefs

typedef struct vfs_file_ops vfs_file_ops_t
 struct vfs_file_ops typedef
 
typedef struct vfs_dir_ops vfs_dir_ops_t
 struct vfs_dir_ops typedef
 
typedef struct vfs_file_system_ops vfs_file_system_ops_t
 struct vfs_file_system_ops typedef
 
typedef struct vfs_mount_struct vfs_mount_t
 struct vfs_mount_struct typedef
 

Functions

int vfs_close (int fd)
 Close an open file. More...
 
int vfs_fcntl (int fd, int cmd, int arg)
 Query/set options on an open file. More...
 
int vfs_fstat (int fd, struct stat *buf)
 Get status of an open file. More...
 
int vfs_fstatvfs (int fd, struct statvfs *buf)
 Get file system status of the file system containing an open file. More...
 
off_t vfs_lseek (int fd, off_t off, int whence)
 Seek to position in file. More...
 
int vfs_open (const char *name, int flags, mode_t mode)
 Open a file. More...
 
ssize_t vfs_read (int fd, void *dest, size_t count)
 Read bytes from an open file. More...
 
ssize_t vfs_write (int fd, const void *src, size_t count)
 Write bytes to an open file. More...
 
int vfs_opendir (vfs_DIR *dirp, const char *dirname)
 Open a directory for reading with readdir. More...
 
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. More...
 
int vfs_closedir (vfs_DIR *dirp)
 Close an open directory. More...
 
int vfs_mount (vfs_mount_t *mountp)
 Mount a file system. More...
 
int vfs_rename (const char *from_path, const char *to_path)
 Rename a file. More...
 
int vfs_umount (vfs_mount_t *mountp)
 Unmount a mounted file system. More...
 
int vfs_unlink (const char *name)
 Unlink (delete) a file from a mounted file system. More...
 
int vfs_mkdir (const char *name, mode_t mode)
 Create a directory on the file system. More...
 
int vfs_rmdir (const char *name)
 Remove a directory from the file system. More...
 
int vfs_stat (const char *restrict path, struct stat *restrict buf)
 Get file status. More...
 
int vfs_statvfs (const char *restrict path, struct statvfs *restrict buf)
 Get file system status. More...
 
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. More...
 
int vfs_normalize_path (char *buf, const char *path, size_t buflen)
 Normalize a path. More...
 
const vfs_mount_tvfs_iterate_mounts (const vfs_mount_t *cur)
 Iterate through all mounted file systems. More...
 

Macro Definition Documentation

◆ VFS_DIR_BUFFER_SIZE

#define VFS_DIR_BUFFER_SIZE   (12)

This space is needed to avoid dynamic memory allocations for some file systems where a single pointer is not enough space for its directory stream state, e.g. SPIFFS.

Guidelines:

SPIFFS requires a sizeof(spiffs_DIR) (6-16 bytes, depending on target platform and configuration) buffer for its DIR struct.

Attention
File system developers: If your file system requires a buffer for DIR streams that is larger than a single pointer or int variable, ensure that you have a preprocessor check in your header file (so that it is impossible to attempt to mount the file system without running into a compiler error):
#if VFS_DIR_BUFFER_SIZE < 123
#error VFS_DIR_BUFFER_SIZE is too small, at least 123 bytes is required
#endif
Put the check in the public header file (.h), do not put the check in the implementation (.c) file.

Definition at line 119 of file vfs.h.

◆ VFS_NAME_MAX

#define VFS_NAME_MAX   (31)

Maximum number of bytes in a filename (not including terminating null).

Similar to the POSIX macro NAME_MAX

Definition at line 130 of file vfs.h.

Function Documentation

◆ vfs_bind()

int vfs_bind ( int  fd,
int  flags,
const vfs_file_ops_t f_op,
void *  private_data 
)

The new fd will be initialized with pointers to the given f_op file operations table and private_data.

This function can be used to give file-like functionality to devices, e.g. UART.

private_data can be used for passing instance information to the file operation handlers in f_op.

Parameters
[in]fdDesired fd number, use VFS_ANY_FD for any available fd
[in]flagsnot implemented yet
[in]f_oppointer to file operations table
[in]private_dataopaque pointer to private data
Returns
fd number on success (>= 0)
<0 on error

◆ vfs_close()

int vfs_close ( int  fd)
Parameters
[in]fdfd number to close
Returns
0 on success
<0 on error

◆ vfs_closedir()

int vfs_closedir ( vfs_DIR dirp)
Attention
Calling vfs_closedir on an uninitialized vfs_DIR is forbidden and may lead to file system corruption and random system failures.
Parameters
[in]dirppointer to open directory
Returns
0 on success
<0 on error, the directory stream dirp should be considered invalid

◆ vfs_fcntl()

int vfs_fcntl ( int  fd,
int  cmd,
int  arg 
)
Parameters
[in]fdfd number to operate on
[in]cmdfcntl command, see man 3p fcntl
[in]argargument to fcntl command, see man 3p fcntl
Returns
0 on success
<0 on error

◆ vfs_fstat()

int vfs_fstat ( int  fd,
struct stat *  buf 
)
Parameters
[in]fdfd number obtained from vfs_open
[out]bufpointer to stat struct to fill
Returns
0 on success
<0 on error

◆ vfs_fstatvfs()

int vfs_fstatvfs ( int  fd,
struct statvfs buf 
)
Parameters
[in]fdfd number obtained from vfs_open
[out]bufpointer to statvfs struct to fill
Returns
0 on success
<0 on error

◆ vfs_iterate_mounts()

const vfs_mount_t* vfs_iterate_mounts ( const vfs_mount_t cur)
Attention
Not thread safe! Do not mix calls to this function with other calls which modify the mount table, such as vfs_mount() and vfs_umount()

Set cur to NULL to start from the beginning

See also
sc_vfs.c (df command) for a usage example
Parameters
[in]curcurrent iterator value
Returns
Pointer to next mounted file system in list after cur
NULL if cur is the last element in the list

◆ vfs_lseek()

off_t vfs_lseek ( int  fd,
off_t  off,
int  whence 
)

whence determines the function of the seek and should be set to one of the following values:

  • SEEK_SET: Seek to absolute offset off
  • SEEK_CUR: Seek to current location + off
  • SEEK_END: Seek to end of file + off
Parameters
[in]fdfd number obtained from vfs_open
[in]offseek offset
[in]whencedetermines the seek method, see detailed description
Returns
the new seek location in the file on success
<0 on error

◆ vfs_mkdir()

int vfs_mkdir ( const char *  name,
mode_t  mode 
)
Parameters
[in]namename of the directory to create
[in]modefile creation mode bits
Returns
0 on success
<0 on error

◆ vfs_mount()

int vfs_mount ( vfs_mount_t mountp)

mountp should have been populated in advance with a file system driver, a mount point, and private_data (if the file system driver uses one).

Parameters
[in]mountppointer to the mount structure of the file system to mount
Returns
0 on success
<0 on error

◆ vfs_normalize_path()

int vfs_normalize_path ( char *  buf,
const char *  path,
size_t  buflen 
)

Normalizing a path means to remove all relative components ("..", ".") and any double slashes.

Note
buf is allowed to overlap path if &buf[0] <= &path[0]
Attention
path must be an absolute path (starting with / )
Parameters
[out]bufbuffer to store normalized path
[in]pathpath to normalize
[in]buflenavailable space in buf
Returns
number of path components in the normalized path on success
<0 on error

◆ vfs_open()

int vfs_open ( const char *  name,
int  flags,
mode_t  mode 
)
Parameters
[in]namefile name to open
[in]flagsflags for opening, see man 3p open
[in]modefile mode
Returns
fd number on success (>= 0)
<0 on error

◆ vfs_opendir()

int vfs_opendir ( vfs_DIR dirp,
const char *  dirname 
)

The data in *dirp will be initialized by vfs_opendir

Parameters
[out]dirppointer to directory stream struct for storing the state
[in]dirnamenull-terminated name of the dir to open, absolute file system path
Returns
0 on success
<0 on error

◆ vfs_read()

ssize_t vfs_read ( int  fd,
void *  dest,
size_t  count 
)
Parameters
[in]fdfd number obtained from vfs_open
[out]destdestination buffer to hold the file contents
[in]countmaximum number of bytes to read
Returns
number of bytes read on success
<0 on error

◆ vfs_readdir()

int vfs_readdir ( vfs_DIR dirp,
vfs_dirent_t entry 
)

entry will be populated with information about the next entry in the directory stream dirp

Attention
Calling vfs_readdir on an uninitialized vfs_DIR is forbidden and may lead to file system corruption and random system failures.
Parameters
[in]dirppointer to open directory
[out]entrydirectory entry information
Returns
1 if entry was updated
0 if dirp has reached the end of the directory index
<0 on error

◆ vfs_rename()

int vfs_rename ( const char *  from_path,
const char *  to_path 
)

The file from_path will be renamed to to_path

Note
it is not possible to rename files across different file system
Parameters
[in]from_pathabsolute path to existing file
[in]to_pathabsolute path to destination
Returns
0 on success
<0 on error

◆ vfs_rmdir()

int vfs_rmdir ( const char *  name)

Only empty directories may be removed.

Parameters
[in]namename of the directory to remove
Returns
0 on success
<0 on error

◆ vfs_stat()

int vfs_stat ( const char *restrict  path,
struct stat *restrict  buf 
)
Parameters
[in]pathpath to file being queried
[out]bufpointer to stat struct to fill
Returns
0 on success
<0 on error

◆ vfs_statvfs()

int vfs_statvfs ( const char *restrict  path,
struct statvfs *restrict  buf 
)

path can be any path that resolves to the file system being queried, it does not have to be an existing file.

Parameters
[in]pathpath to a file on the file system being queried
[out]bufpointer to statvfs struct to fill
Returns
0 on success
<0 on error

◆ vfs_umount()

int vfs_umount ( vfs_mount_t mountp)

This will fail if there are any open files on the mounted file system

Parameters
[in]mountppointer to the mount structure of the file system to unmount
Returns
0 on success
<0 on error

◆ vfs_unlink()

int vfs_unlink ( const char *  name)
Parameters
[in]namename of file to delete
Returns
0 on success
<0 on error

◆ vfs_write()

ssize_t vfs_write ( int  fd,
const void *  src,
size_t  count 
)
Parameters
[in]fdfd number obtained from vfs_open
[in]srcpointer to source buffer
[in]countmaximum number of bytes to write
Returns
number of bytes written on success
<0 on error