Skip to content

Commit 735f0d7

Browse files
Jakub Klimczaknashif
authored andcommitted
zvfs: Move file operations from POSIX into ZVFS
This commit moves all operations on single files into ZVFS and makes the POSIX subsystem call into ZVFS to perform them. It was necessary to define a `struct zvfs_stat` to avoid a dependency cycle. Functions used internally for file i/o operations are publicised since they won't require any changes between various subsystems. This allows ZVFS to actually fulfill its purpose of facilitating cooperation of different file APIs. Signed-off-by: Jakub Klimczak <[email protected]>
1 parent 52f2686 commit 735f0d7

File tree

11 files changed

+385
-319
lines changed

11 files changed

+385
-319
lines changed

include/zephyr/sys/fdtable.h

Lines changed: 98 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
/*
22
* Copyright (c) 2018 Linaro Limited
3+
* Copyright (c) 2025 Antmicro
34
*
45
* SPDX-License-Identifier: Apache-2.0
56
*/
@@ -56,10 +57,6 @@
5657
#define ZVFS_POLLHUP BIT(4)
5758
#define ZVFS_POLLNVAL BIT(5)
5859

59-
#ifdef __cplusplus
60-
extern "C" {
61-
#endif
62-
6360
/* FIXME: use k_off_t and k_ssize_t to avoid the POSIX->Zephyr->POSIX dependency cycle */
6461
#ifdef CONFIG_NEWLIB_LIBC
6562
#ifndef _OFF_T_DECLARED
@@ -72,6 +69,12 @@ typedef _ssize_t ssize_t;
7269
#endif
7370
#endif
7471

72+
#include <zephyr/fs/fs.h>
73+
74+
#ifdef __cplusplus
75+
extern "C" {
76+
#endif
77+
7578
/**
7679
* File descriptor virtual method table.
7780
* Currently all operations beyond read/write/close go thru ioctl method.
@@ -236,6 +239,15 @@ static inline int zvfs_fdtable_call_ioctl(const struct fd_op_vtable *vtable, voi
236239
return res;
237240
}
238241

242+
/**
243+
* Structure for result of the ZFD_IOCTL_STAT ioctl call.
244+
* Contains fields for all currently supported details. Defined to avoid POSIX dependency.
245+
*/
246+
struct zvfs_stat {
247+
off_t size;
248+
uint32_t mode;
249+
};
250+
239251
struct zvfs_pollfd {
240252
int fd;
241253
short events;
@@ -286,6 +298,88 @@ enum {
286298
ZFD_IOCTL_FIONBIO = 0x5421,
287299
};
288300

301+
/**
302+
* @brief Open a file with a given name.
303+
*
304+
* @param name Name of the file
305+
* @param flags Access modes for @ref fs_open
306+
* @param vtable Pointer to structure with appropriate i/o functions
307+
*
308+
* @return Index of newly created file descriptor on success, -1 on error with errno set.
309+
*/
310+
int zvfs_open(const char *name, int flags, struct fd_op_vtable *vtable);
311+
312+
/**
313+
* @brief Get information about file.
314+
*
315+
* @param fd File descriptor index
316+
* @param buf Pointer to result structure
317+
*
318+
* @return 0 on success, -1 with errno set on error.
319+
*/
320+
int zvfs_fstat(int fd, struct zvfs_stat *buf);
321+
322+
/**
323+
* @brief Close file.
324+
*
325+
* @param fd File descriptor index
326+
*
327+
* @return 0 on success, -1 with errno set on error.
328+
*/
329+
int zvfs_close(int fd);
330+
331+
/**
332+
* @brief Read bytes from file.
333+
*
334+
* @param fd File descriptor index
335+
* @param buf Destination buffer
336+
* @param sz Number of bytes to read
337+
* @param from_offset Pointer to variable specifying starting position;
338+
* current offset will be used if NULL
339+
*
340+
* @return Number of bytes read successfully, or -1 with errno set on failure
341+
*/
342+
ssize_t zvfs_read(int fd, void *buf, size_t sz, const size_t *from_offset);
343+
344+
/**
345+
* @brief Write bytes to file.
346+
*
347+
* @param fd File descriptor index
348+
* @param buf Source buffer
349+
* @param sz Number of bytes to write
350+
* @param from_offset Pointer to variable specifying starting position;
351+
* current offset will be used if NULL
352+
*
353+
* @return Number of bytes written successfully, or -1 with errno set on failure
354+
*/
355+
ssize_t zvfs_write(int fd, const void *buf, size_t sz, const size_t *from_offset);
356+
357+
#ifdef CONFIG_ZVFS_DEFAULT_FILE_VMETHODS
358+
int zvfs_ioctl_vmeth(void *obj, unsigned int request, va_list args);
359+
int zvfs_close_vmeth(void *obj);
360+
ssize_t zvfs_write_vmeth(void *obj, const void *buffer, size_t count);
361+
ssize_t zvfs_read_vmeth(void *obj, void *buffer, size_t count);
362+
#endif
363+
364+
/**
365+
* @brief Delete file or directory.
366+
*
367+
* @param path Path or name of file to be removed.
368+
*
369+
* @return 0 on success, -1 with errno set on error.
370+
*/
371+
int zvfs_unlink(const char *path);
372+
373+
/**
374+
* @brief Rename file or directory, moving it if necessary.
375+
*
376+
* @param old Current name
377+
* @param newp Target name
378+
*
379+
* @return 0 on success, -1 with errno set on error.
380+
*/
381+
int zvfs_rename(const char *old, const char *newp);
382+
289383
#ifdef __cplusplus
290384
}
291385
#endif

lib/os/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,17 @@ config FDTABLE
1010
for any I/O object implementing POSIX I/O semantics (i.e. read/write +
1111
aux operations).
1212

13+
if FDTABLE
14+
15+
config ZVFS_DEFAULT_FILE_VMETHODS
16+
bool "ZVFS default virtual methods for files"
17+
default y
18+
help
19+
Provide typical file operations, which can be referenced in a struct fd_op_vtable
20+
and subsequently called by ZVFS functions.
21+
22+
endif
23+
1324
config ZVFS_OPEN_MAX
1425
int "Maximum number of open file descriptors"
1526
default 0

lib/os/fdtable.c

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/*
22
* Copyright (c) 2018 Linaro Limited
33
* Copyright (c) 2024 Tenstorrent AI ULC
4+
* Copyright (c) 2025 Antmicro
45
*
56
* SPDX-License-Identifier: Apache-2.0
67
*/
@@ -23,8 +24,9 @@
2324
#include <zephyr/sys/speculation.h>
2425
#include <zephyr/internal/syscall_handler.h>
2526
#include <zephyr/sys/atomic.h>
27+
#include <zephyr/fs/fs.h>
2628

27-
struct stat;
29+
K_MEM_SLAB_DEFINE(file_desc_slab, sizeof(struct fs_file_t), ZVFS_OPEN_SIZE, 4);
2830

2931
struct fd_entry {
3032
void *obj;
@@ -73,6 +75,46 @@ static struct fd_entry fdtable[ZVFS_OPEN_SIZE] = {
7375
#endif
7476
};
7577

78+
int zvfs_open(const char *name, int flags, struct fd_op_vtable *vtable)
79+
{
80+
int rc, fd;
81+
struct fs_file_t *ptr = NULL;
82+
83+
fd = zvfs_reserve_fd();
84+
if (fd < 0) {
85+
return -1;
86+
}
87+
88+
rc = k_mem_slab_alloc(&file_desc_slab, (void **)&ptr, K_NO_WAIT);
89+
if (rc < 0) {
90+
rc = -EMFILE;
91+
goto out_err;
92+
}
93+
94+
fs_file_t_init(ptr);
95+
96+
rc = fs_open(ptr, name, flags);
97+
if (rc < 0) {
98+
goto out_err;
99+
}
100+
101+
zvfs_finalize_fd(fd, ptr, vtable);
102+
103+
goto out;
104+
105+
out_err:
106+
if (ptr != NULL) {
107+
k_mem_slab_free(&file_desc_slab, ptr);
108+
}
109+
110+
zvfs_free_fd(fd);
111+
errno = -rc;
112+
return -1;
113+
114+
out:
115+
return fd;
116+
}
117+
76118
static K_MUTEX_DEFINE(fdtable_lock);
77119

78120
static int z_fd_ref(int fd)
@@ -432,7 +474,7 @@ int zvfs_fileno(FILE *file)
432474
return (struct fd_entry *)file - fdtable;
433475
}
434476

435-
int zvfs_fstat(int fd, struct stat *buf)
477+
int zvfs_fstat(int fd, struct zvfs_stat *buf)
436478
{
437479
if (_check_fd(fd) < 0) {
438480
return -1;
@@ -535,6 +577,27 @@ int zvfs_ioctl(int fd, unsigned long request, va_list args)
535577
return fdtable[fd].vtable->ioctl(fdtable[fd].obj, request, args);
536578
}
537579

580+
int zvfs_unlink(const char *path)
581+
{
582+
int res = fs_unlink(path);
583+
584+
if (res < 0) {
585+
errno = -res;
586+
return -1;
587+
}
588+
return 0;
589+
}
590+
591+
int zvfs_rename(const char *old, const char *newp)
592+
{
593+
int res = fs_rename(old, newp);
594+
595+
if (res < 0) {
596+
errno = -res;
597+
return -1;
598+
}
599+
return 0;
600+
}
538601

539602
#if defined(CONFIG_POSIX_DEVICE_IO)
540603
/*

lib/os/zvfs/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# SPDX-License-Identifier: Apache-2.0
22

33
zephyr_library()
4+
zephyr_library_sources_ifdef(CONFIG_ZVFS_DEFAULT_FILE_VMETHODS zvfs_file_vmethods.c)
45
zephyr_library_sources_ifdef(CONFIG_ZVFS_EVENTFD zvfs_eventfd.c)
56
zephyr_library_sources_ifdef(CONFIG_ZVFS_POLL zvfs_poll.c)
67
zephyr_library_sources_ifdef(CONFIG_ZVFS_SELECT zvfs_select.c)

0 commit comments

Comments
 (0)