|
TARFS 0.1.5
Read-only TAR filesystem for ESP32
|
#include <stdint.h>#include <stdarg.h>#include <stdlib.h>#include <stdio.h>#include <stdbool.h>#include <stdatomic.h>#include <string.h>#include <unistd.h>#include <dirent.h>#include <sys/errno.h>#include <sys/fcntl.h>#include <sys/utime.h>#include <assert.h>#include <fcntl.h>#include <time.h>#include "config.h"#include <sys/socket.h>#include "os.h"#include "tar.h"#include "fs.h"#include "posix.h"Go to the source code of this file.
Macros | |
| #define | PROLOGUE(TYPE) |
| #define | ADD_STATS(X, Y) |
Functions | |
| static int | allocfd (struct tarfs_fs *fs) |
| Allocate a file descriptor slot. | |
| static void | freefd (struct tarfs_fs *fs, int index) |
| Marks previously allocated index as free. | |
| static bool | is_sanefd (struct tarfs_fs *fs, int fd) |
| Extra paranoia: we check fds which are passed to us by VFS layer for being in our range [0 . | |
| int | tarf_access (void *ctx, const char *path, int amode) |
| Check the accessibility of a file or directory in the TarFS filesystem. | |
| int | tarf_open (void *ctx, const char *path0, int flags, int mode) |
| Open a TARFS file or directory. | |
| int | tarf_close (void *ctx, int fd) |
| ssize_t | tarf_pread (void *ctx, int fd, void *dst, size_t size, off_t offset) |
| Read data from an open TARFS file at a specified offset. | |
| ssize_t | tarf_read (void *ctx, int fd, void *dst, size_t size) |
| Read data from an open TARFS file. | |
| off_t | tarf_lseek (void *ctx, int fd, off_t offset, int whence) |
| lseek() | |
| int | tarf_fstat (void *ctx, int fd, struct stat *st) |
| Get file status information. | |
| int | tarf_fsync (void *ctx, int fd) |
| Synchronize file contents. | |
| int | tarf_fcntl (void *ctx, int fd, int cmd, int arg) |
| Perform file descriptor control operations. | |
| int | tarf_ioctl (void *ctx, int fd, int cmd, va_list args) |
| Perform TARFS-specific I/O control operations. | |
| int | tarf_stat (void *ctx, const char *path, struct stat *st) |
| stat() system call | |
| int | tarf_dupfd (void *ctx, int fd) |
| Create an independent duplicate of a file descriptor. | |
| void * | tarf_mmap (void *ctx, void *addr, size_t length, int prot, int flags, int fd, off_t offset) |
| Mimics POSIX mmap(). | |
| int | tarf_munmap (void *ctx, void *addr, size_t length) |
| munmap(). | |
| ssize_t | tarf_sendfile (void *ctx, int sock, int fd, off_t *offset, size_t count) |
| Copy data from a TARFS file descriptor to a socket. | |
Variables | |
| static const uint32_t | s_valid_mask = ( 16 == 32) ? 0xffffffffUL : ((1UL << 16 ) - 1UL) |
| #define ADD_STATS | ( | X, | |
| Y ) |
Definition at line 104 of file file.c.
Referenced by tarf_mmap(), tarf_open(), and tarf_pread().
| #define PROLOGUE | ( | TYPE | ) |
Definition at line 82 of file file.c.
Referenced by tarf_close(), tarf_dupfd(), tarf_fcntl(), tarf_fstat(), tarf_fsync(), tarf_ioctl(), tarf_lseek(), tarf_mmap(), tarf_pread(), tarf_read(), and tarf_sendfile().
|
static |
Allocate a file descriptor slot.
File descriptors are preallocated in tarfs_fs instance; This function marks slots as used or unused
This function must be called under addref() protocol: if (tarfs_addref(fs)) { allocfd(fs); } Returns free index in range [0..TARFS_MAX_FDS-1] Returns -1 if no free indices are available
Definition at line 129 of file file.c.
References s_valid_mask.
Referenced by tarf_dupfd(), and tarf_open().
|
static |
Marks previously allocated index as free.
Function is tolerant to double free
< Max number of active opened files (per filesystem, must be < 33)
Definition at line 158 of file file.c.
References TARFS_MAX_FDS.
Referenced by tarf_close().
|
static |
Extra paranoia: we check fds which are passed to us by VFS layer for being in our range [0 .
. TARFS_MAX_FDS]. Check if that fd is alive (file is opened)
< Max number of active opened files (per filesystem, must be < 33)
Definition at line 182 of file file.c.
References TARFS_MAX_FDS.
| int tarf_access | ( | void * | ctx, |
| const char * | path, | ||
| int | amode ) |
Check the accessibility of a file or directory in the TarFS filesystem.
This function checks whether the specified path exists in the mounted TarFS filesystem and whether the requested access mode is permitted.
This function checks whether the specified path exists in the mounted TarFS filesystem and whether the requested access mode is supported.
TarFS is a read-only filesystem and does not support file execution. Therefore, requests containing X_OK always fail with EPERM, while requests containing W_OK always fail with EROFS.
| [in] | ctx | TarFS filesystem context. |
| [in] | path | Path to the file or directory to check. |
| [in] | amode | Access mode to check. May be F_OK, R_OK, W_OK, X_OK, or a combination of these flags. |
Definition at line 210 of file file.c.
References tarf_stat().
| int tarf_close | ( | void * | ctx, |
| int | fd ) |
< Max number of mounted TARFS filesystems
Definition at line 445 of file file.c.
References freefd(), log, PROLOGUE, and tarfs_unref().
Referenced by tard_closedir(), tard_opendir(), and tarf_stat().
| int tarf_dupfd | ( | void * | ctx, |
| int | fd ) |
Create an independent duplicate of a file descriptor.
This function is similar to POSIX dup(), but the file position is not shared. The new descriptor has its own independent file offset, initialized to the current position of the original descriptor.
This function is similar to POSIX dup(), but the file position is not shared. The new descriptor has its own independent file offset, initialized to the current position of the original descriptor.
Both descriptors refer to the same file, but subsequent seek/read operations affect their positions independently.
Unlike POSIX dup(), this function does not use shared open file description semantics. It is provided as a lightweight alternative suitable for read-only TARFS files.
| ctx | Filesystem context. |
| fd | File descriptor to duplicate. |
< Max number of mounted TARFS filesystems
Definition at line 817 of file file.c.
References allocfd(), ioctl_req::fd, tarfs_fs::fs_fd, log, PROLOGUE, and tarfs_addref().
Referenced by dupfd().
| int tarf_fcntl | ( | void * | ctx, |
| int | fd, | ||
| int | cmd, | ||
| int | arg ) |
Perform file descriptor control operations.
Supports a minimal subset of POSIX fcntl() commands. TARFS is inherently non-blocking, therefore F_SETFL is accepted but ignored. F_GETFL always reports O_NONBLOCK.
| ctx | Filesystem instance. |
| fd | TARFS file descriptor. |
| cmd | Control command. |
| arg | Command argument. |
| >=0 | Command-dependent result. |
| -1 | Unsupported command (errno = ENOSYS). |
< Max number of mounted TARFS filesystems
Definition at line 716 of file file.c.
References PROLOGUE.
| int tarf_fstat | ( | void * | ctx, |
| int | fd, | ||
| struct stat * | st ) |
Get file status information.
Fills a POSIX stat structure for an open TARFS file descriptor. Since TARFS is read-only, only read permission bits are reported. Directory entries additionally have execute bits set to allow traversal.
| ctx | Filesystem instance. |
| fd | TARFS file descriptor. |
| st | Output structure to receive file information. |
| 0 | Success. |
| -1 | Invalid file descriptor (errno = EBADF). |
< Max number of mounted TARFS filesystems
Definition at line 589 of file file.c.
References tarfs_fp::fp_idx, tarfs_fp::fp_size, inode_getinfo(), mtime, PROLOGUE, tart_t, and type.
Referenced by tarf_stat().
| int tarf_fsync | ( | void * | ctx, |
| int | fd ) |
Synchronize file contents.
TODO: reuse this syscall for something useful
TARFS is a read-only filesystem, therefore there is nothing to flush. This function validates the file descriptor and always succeeds.
| ctx | Filesystem instance. |
| fd | TARFS file descriptor. |
| 0 | Success. |
| -1 | Invalid file descriptor (errno = EBADF). |
< Max number of mounted TARFS filesystems
Definition at line 702 of file file.c.
References PROLOGUE.
| int tarf_ioctl | ( | void * | ctx, |
| int | fd, | ||
| int | cmd, | ||
| va_list | args ) |
Perform TARFS-specific I/O control operations.
Supported commands:
FIONREAD - returns the number of unread bytes remaining.FIONBIO - accepted for compatibility and ignored.FIOGETFD - exports the TARFS descriptor and local file descriptor.The FIOGETFD command increments the filesystem reference count before returning the filesystem pointer. The caller is responsible for releasing it with unrefx() when it is no longer needed.
| ctx | Filesystem instance. |
| fd | TARFS file descriptor. |
| cmd | I/O control command. |
| args | Command-specific arguments. |
| 0 | Success. |
| -1 | Error. Possible errno values include:
|
< Max number of mounted TARFS filesystems
< Support FIONREAD (compatibility layer)
< Support FIONBIO (compatibility layer)
< Convert global fd number to local fd number. arg=&int
Definition at line 740 of file file.c.
References ioctl_req::fd, FIOGETFD, FIONBIO, FIONREAD, tarfs_fp::fp_pos, tarfs_fp::fp_size, tarfs_fs::fs_fd, ioctl_req::fs_idx, and PROLOGUE.
| off_t tarf_lseek | ( | void * | ctx, |
| int | fd, | ||
| off_t | offset, | ||
| int | whence ) |
lseek()
Copies up to size bytes from the current file position into dst and advances the file position by the number of bytes actually read.
| ctx | Filesystem instance. |
| fd | TARFS file descriptor. |
< Max number of mounted TARFS filesystems
Definition at line 533 of file file.c.
References tarfs_fp::fp_pos, tarfs_fp::fp_size, log, and PROLOGUE.
| void * tarf_mmap | ( | void * | ctx, |
| void * | addr, | ||
| size_t | length, | ||
| int | prot, | ||
| int | flags, | ||
| int | fd, | ||
| off_t | offset ) |
Mimics POSIX mmap().
Map a file into the process address space.
Only read-only file mappings are supported. MAP_ANON(YMOUS), MAP_FIXED, PROT_EXEC, and PROT_WRITE are not supported.
Mimics POSIX mmap().
Typical usage:
The mapping remains valid after the file descriptor has been closed.
Since TARFS is a read-only filesystem, this implementation does not support the PROT_WRITE protection flag. MAP_ANONYMOUS is also not supported: mmap() is intended exclusively for mapping files.
There is no limit on the number of active mappings. Every file in TARFS may be mapped simultaneously, provided the underlying flash memory can hold it. Mappings do not consume any runtime resources. In contrast, each open file occupies one file descriptor until it is closed.
| ctx | Filesystem context. |
| addr | Must be NULL. Fixed-address mappings are not supported. |
| length | Number of bytes to map. |
| prot | Memory protection flags. Only PROT_READ is supported. |
| flags | Mapping flags. Use MAP_SHARED or MAP_PRIVATE. On a read-only filesystem both behave identically. |
| fd | Open file descriptor to map. |
| offset | File offset where the mapping begins. |
< Max number of mounted TARFS filesystems
< Ignored, no legit use for this flag :)
< Unsupported, use malloc() instead
< Ignored, if used together with PROT_READ. Alone causes mmap() error (RO filesystem!)
< Ignored
Definition at line 846 of file file.c.
References ADD_STATS, tarfs_fp::fp_size, tarfs_fp::fp_vaddr, tarfs_fs::fs_bmmap, tarfs_fs::fs_fd, log, MAP_ANONYMOUS, MAP_FAILED, MAP_FIXED, PROLOGUE, PROT_EXEC, PROT_WRITE, and tarfs_addref().
Referenced by mmap().
| int tarf_munmap | ( | void * | ctx, |
| void * | addr, | ||
| size_t | length ) |
Remove a previously created memory mapping.
The address and length arguments are ignored and are not validated. Unmapping only affects the filesystem reference count, so the same filesystem context used with tarf_mmap() must also be used with tarf_munmap().
Since mappings themselves do not allocate runtime resources, failing to call munmap() does not lead to resource leaks. However, an active mapping keeps the filesystem mounted, preventing it from being unmounted until the mapping is removed.
| ctx | Filesystem context. |
| addr | Address previously returned by mmap(). |
| length | Length of the mapped region. |
< Max number of mounted TARFS filesystems
Definition at line 898 of file file.c.
References log, tarfs_getfs(), TARFS_MAX_FS, and tarfs_unref().
Referenced by munmap().
| int tarf_open | ( | void * | ctx, |
| const char * | path, | ||
| int | flags, | ||
| int | mode ) |
Open a TARFS file or directory.
Opens an existing TAR archive entry and returns a TARFS file descriptor. Both regular files and directories may be opened.
Opens an existing TAR archive entry and returns a TARFS file descriptor. Both regular files and directories may be opened. Directories cannot be read using read(), but the returned descriptor may be used with functions such as fstat(), fcntl(), ioctl(), close(), etc.
TARFS is a read-only filesystem. Attempts to open an entry for writing or with O_TRUNC fail with EROFS.
| ctx | Filesystem instance. |
| path | Absolute path within the mounted TARFS. |
| flags | POSIX open() flags. |
| mode | Creation mode (ignored). |
| -1 | Error. Possible errno values include:
|
Definition at line 252 of file file.c.
References ADD_STATS, allocfd(), tarfs_fp::fp_idx, tarfs_fp::fp_pos, tarfs_fp::fp_size, tarfs_fp::fp_vaddr, tarfs_fs::fs_fd, tarfs_fs::fs_ino, tarfs_fs::fs_nfail, tarfs_fs::fs_nino, tarfs_fs::fs_opencrc, inode_getinfo(), inode_lookup(), log, mode, mtime, size, tar_baddata(), tar_strdup1(), tarfs_getfs_addref(), tarfs_os_free(), tarfs_unref(), tart_t, and type.
Referenced by tard_opendir(), and tarf_stat().
| ssize_t tarf_pread | ( | void * | ctx, |
| int | fd, | ||
| void * | dst, | ||
| size_t | size, | ||
| off_t | offset ) |
Read data from an open TARFS file at a specified offset.
Copies up to size bytes starting at offset into dst. Unlike read(), this function does not modify the current file position.
Copies up to size bytes starting at offset into dst. Unlike read(), this function does not modify the current file position.
< Max number of mounted TARFS filesystems
Definition at line 464 of file file.c.
References ADD_STATS, tarfs_fp::fp_size, tarfs_fp::fp_vaddr, PROLOGUE, size, and tarfs_os_memcpy().
Referenced by tarf_read().
| ssize_t tarf_read | ( | void * | ctx, |
| int | fd, | ||
| void * | dst, | ||
| size_t | size ) |
Read data from an open TARFS file.
Copies up to size bytes from the current file position into dst and advances the file position by the number of bytes actually read.
< Max number of mounted TARFS filesystems
Definition at line 512 of file file.c.
References tarfs_fp::fp_pos, PROLOGUE, size, and tarf_pread().
| ssize_t tarf_sendfile | ( | void * | ctx, |
| int | sock, | ||
| int | fd, | ||
| off_t * | offset, | ||
| size_t | count ) |
Copy data from a TARFS file descriptor to a socket.
Send TARFS file to a socket.
This function transfers data directly from in_fd to sock without requiring an intermediate user buffer;
Copy data from a TARFS file descriptor to a socket.
This function transfers data directly from in_fd to out_fd without requiring an intermediate user buffer.
| ctx | Filesystem context. |
| out_fd | Destination file descriptor. Must be a socket. |
| in_fd | Source file descriptor. A tarfs descriptor |
| offset | Optional starting offset in the input file. If NULL, the current file position is used and advanced. Otherwise, the value pointed to by offset is used and updated, while the file position of in_fd remains unchanged. |
| count | Maximum number of bytes to transfer. |
< Max number of mounted TARFS filesystems
Definition at line 926 of file file.c.
References tarfs_fp::fp_pos, tarfs_fp::fp_size, tarfs_fp::fp_vaddr, tarfs_fs::fs_fd, log, and PROLOGUE.
Referenced by sendfile().
| int tarf_stat | ( | void * | ctx, |
| const char * | path, | ||
| struct stat * | st ) |
stat() system call
Retrieve file status information.
stat() system call
This function retrieves information about the file specified by path and stores it in the struct stat structure pointed to by st.
TARFS is a read-only filesystem, therefore the returned status information describes the file as a regular file or directory without any write-related filesystem semantics.
| [in] | ctx | TARFS filesystem context. |
| [in] | path | Path to the file or directory whose status is to be retrieved. |
| [out] | st | Pointer to a struct stat structure that receives the file status information. |
errno set to indicate the error.Definition at line 790 of file file.c.
References ioctl_req::fd, log, tarf_close(), tarf_fstat(), and tarf_open().
Referenced by tarf_access().