lib: posix: fs: Convert to use generic fdtable

All the handling of POSIX file descriptors is now done by fdtable.c.
fs.c still manages its own table of file structures of the underlying
fs lib.

Signed-off-by: Paul Sokolovsky <paul.sokolovsky@linaro.org>
This commit is contained in:
Paul Sokolovsky 2018-10-08 14:01:46 +03:00 committed by Carles Cufí
commit b6e58d54c9
2 changed files with 83 additions and 124 deletions

View file

@ -16,7 +16,7 @@ extern "C" {
#ifdef CONFIG_POSIX_FS #ifdef CONFIG_POSIX_FS
#include <fs.h> #include <fs.h>
typedef struct fs_dir_t DIR; typedef void DIR;
struct dirent { struct dirent {
unsigned int d_ino; unsigned int d_ino;

View file

@ -10,17 +10,16 @@
#include <posix/unistd.h> #include <posix/unistd.h>
#include <posix/dirent.h> #include <posix/dirent.h>
#include <string.h> #include <string.h>
#include <misc/fdtable.h>
BUILD_ASSERT_MSG(PATH_MAX > MAX_FILE_NAME, BUILD_ASSERT_MSG(PATH_MAX > MAX_FILE_NAME,
"PATH_MAX is less than MAX_FILE_NAME"); "PATH_MAX is less than MAX_FILE_NAME");
union file_desc { struct posix_fs_desc {
union {
struct fs_file_t file; struct fs_file_t file;
struct fs_dir_t dir; struct fs_dir_t dir;
}; };
struct posix_fs_desc {
union file_desc desc;
bool is_dir; bool is_dir;
bool used; bool used;
}; };
@ -30,63 +29,30 @@ static struct posix_fs_desc desc_array[CONFIG_POSIX_MAX_OPEN_FILES];
static struct fs_dirent fdirent; static struct fs_dirent fdirent;
static struct dirent pdirent; static struct dirent pdirent;
static int posix_fs_alloc_fd(union file_desc **ptr, bool is_dir) static struct fd_op_vtable fs_fd_op_vtable;
static struct posix_fs_desc *posix_fs_alloc_obj(bool is_dir)
{ {
int fd; int i;
struct posix_fs_desc *ptr = NULL;
unsigned int key = irq_lock(); unsigned int key = irq_lock();
for (fd = 0; fd < CONFIG_POSIX_MAX_OPEN_FILES; fd++) { for (i = 0; i < CONFIG_POSIX_MAX_OPEN_FILES; i++) {
if (desc_array[fd].used == false) { if (desc_array[i].used == false) {
*ptr = &desc_array[fd].desc; ptr = &desc_array[i];
desc_array[fd].used = true; ptr->used = true;
desc_array[fd].is_dir = is_dir; ptr->is_dir = is_dir;
break; break;
} }
} }
irq_unlock(key); irq_unlock(key);
if (fd >= CONFIG_POSIX_MAX_OPEN_FILES) { return ptr;
return -1;
}
return fd;
} }
static int posix_fs_get_ptr(int fd, union file_desc **ptr, bool is_dir) static inline void posix_fs_free_obj(struct posix_fs_desc *ptr)
{ {
int rc = 0; ptr->used = false;
unsigned int key;
if (fd < 0 || fd >= CONFIG_POSIX_MAX_OPEN_FILES) {
return -1;
}
key = irq_lock();
if ((desc_array[fd].used == true) &&
(desc_array[fd].is_dir == is_dir)) {
*ptr = &desc_array[fd].desc;
} else {
rc = -1;
}
irq_unlock(key);
return rc;
}
static inline void posix_fs_free_ptr(struct posix_fs_desc *ptr)
{
struct posix_fs_desc *desc = ptr;
unsigned int key = irq_lock();
desc->used = false;
desc->is_dir = false;
irq_unlock(key);
}
static inline void posix_fs_free_fd(int fd)
{
posix_fs_free_ptr(&desc_array[fd]);
} }
/** /**
@ -97,46 +63,65 @@ static inline void posix_fs_free_fd(int fd)
int open(const char *name, int flags) int open(const char *name, int flags)
{ {
int rc, fd; int rc, fd;
struct fs_file_t *ptr = NULL; struct posix_fs_desc *ptr = NULL;
ARG_UNUSED(flags); ARG_UNUSED(flags);
fd = posix_fs_alloc_fd((union file_desc **)&ptr, false); fd = z_reserve_fd();
if ((fd < 0) || (ptr == NULL)) { if (fd < 0) {
errno = ENFILE;
return -1; return -1;
} }
(void)memset(ptr, 0, sizeof(struct fs_file_t));
rc = fs_open(ptr, name); ptr = posix_fs_alloc_obj(false);
if (ptr == NULL) {
z_free_fd(fd);
errno = EMFILE;
return -1;
}
(void)memset(&ptr->file, 0, sizeof(ptr->file));
rc = fs_open(&ptr->file, name);
if (rc < 0) { if (rc < 0) {
posix_fs_free_fd(fd); posix_fs_free_obj(ptr);
z_free_fd(fd);
errno = -rc; errno = -rc;
return -1; return -1;
} }
z_finalize_fd(fd, ptr, &fs_fd_op_vtable);
return fd; return fd;
} }
/** static int fs_ioctl_vmeth(void *obj, unsigned int request, ...)
* @brief Close a file descriptor.
*
* See IEEE 1003.1
*/
int close(int fd)
{ {
int rc; int rc;
struct fs_file_t *ptr = NULL; struct posix_fs_desc *ptr = obj;
if (posix_fs_get_ptr(fd, (union file_desc **)&ptr, false)) { switch (request) {
errno = EBADF; case ZFD_IOCTL_CLOSE:
return -1; rc = fs_close(&ptr->file);
break;
case ZFD_IOCTL_LSEEK: {
va_list args;
off_t offset;
int whence;
va_start(args, request);
offset = va_arg(args, off_t);
whence = va_arg(args, int);
va_end(args);
rc = fs_seek(&ptr->file, offset, whence);
break;
} }
rc = fs_close(ptr); default:
errno = EOPNOTSUPP;
/* Free file ptr memory */ return -1;
posix_fs_free_fd(fd); }
if (rc < 0) { if (rc < 0) {
errno = -rc; errno = -rc;
@ -151,17 +136,12 @@ int close(int fd)
* *
* See IEEE 1003.1 * See IEEE 1003.1
*/ */
ssize_t write(int fd, const void *buffer, size_t count) static ssize_t fs_write_vmeth(void *obj, const void *buffer, size_t count)
{ {
ssize_t rc; ssize_t rc;
struct fs_file_t *ptr = NULL; struct posix_fs_desc *ptr = obj;
if (posix_fs_get_ptr(fd, (union file_desc **)&ptr, false)) { rc = fs_write(&ptr->file, buffer, count);
errno = EBADF;
return -1;
}
rc = fs_write(ptr, buffer, count);
if (rc < 0) { if (rc < 0) {
errno = -rc; errno = -rc;
return -1; return -1;
@ -175,17 +155,12 @@ ssize_t write(int fd, const void *buffer, size_t count)
* *
* See IEEE 1003.1 * See IEEE 1003.1
*/ */
ssize_t read(int fd, void *buffer, size_t count) static ssize_t fs_read_vmeth(void *obj, void *buffer, size_t count)
{ {
ssize_t rc; ssize_t rc;
struct fs_file_t *ptr = NULL; struct posix_fs_desc *ptr = obj;
if (posix_fs_get_ptr(fd, (union file_desc **)&ptr, false)) { rc = fs_read(&ptr->file, buffer, count);
errno = EBADF;
return -1;
}
rc = fs_read(ptr, buffer, count);
if (rc < 0) { if (rc < 0) {
errno = -rc; errno = -rc;
return -1; return -1;
@ -194,29 +169,11 @@ ssize_t read(int fd, void *buffer, size_t count)
return rc; return rc;
} }
/** static struct fd_op_vtable fs_fd_op_vtable = {
* @brief Move read/write file offset. .read = fs_read_vmeth,
* .write = fs_write_vmeth,
* See IEEE 1003.1 .ioctl = fs_ioctl_vmeth,
*/ };
off_t lseek(int fd, off_t offset, int whence)
{
int rc;
struct fs_file_t *ptr = NULL;
if (posix_fs_get_ptr(fd, (union file_desc **)&ptr, false)) {
errno = EBADF;
return -1;
}
rc = fs_seek(ptr, offset, whence);
if (rc < 0) {
errno = -rc;
return -1;
}
return 0;
}
/** /**
* @brief Open a directory stream. * @brief Open a directory stream.
@ -225,19 +182,20 @@ off_t lseek(int fd, off_t offset, int whence)
*/ */
DIR *opendir(const char *dirname) DIR *opendir(const char *dirname)
{ {
int rc, fd; int rc;
struct fs_dir_t *ptr = NULL; struct posix_fs_desc *ptr;
fd = posix_fs_alloc_fd((union file_desc **)&ptr, true); ptr = posix_fs_alloc_obj(true);
if ((fd < 0) || (ptr == NULL)) { if (ptr == NULL) {
errno = EMFILE; errno = EMFILE;
return NULL; return NULL;
} }
(void)memset(ptr, 0, sizeof(struct fs_dir_t));
rc = fs_opendir(ptr, dirname); (void)memset(&ptr->dir, 0, sizeof(ptr->dir));
rc = fs_opendir(&ptr->dir, dirname);
if (rc < 0) { if (rc < 0) {
posix_fs_free_fd(fd); posix_fs_free_obj(ptr);
errno = -rc; errno = -rc;
return NULL; return NULL;
} }
@ -253,16 +211,16 @@ DIR *opendir(const char *dirname)
int closedir(DIR *dirp) int closedir(DIR *dirp)
{ {
int rc; int rc;
struct posix_fs_desc *ptr = dirp;
if (dirp == NULL) { if (dirp == NULL) {
errno = EBADF; errno = EBADF;
return -1; return -1;
} }
rc = fs_closedir(dirp); rc = fs_closedir(&ptr->dir);
/* Free file ptr memory */ posix_fs_free_obj(ptr);
posix_fs_free_ptr((struct posix_fs_desc *)dirp);
if (rc < 0) { if (rc < 0) {
errno = -rc; errno = -rc;
@ -280,13 +238,14 @@ int closedir(DIR *dirp)
struct dirent *readdir(DIR *dirp) struct dirent *readdir(DIR *dirp)
{ {
int rc; int rc;
struct posix_fs_desc *ptr = dirp;
if (dirp == NULL) { if (dirp == NULL) {
errno = EBADF; errno = EBADF;
return NULL; return NULL;
} }
rc = fs_readdir(dirp, &fdirent); rc = fs_readdir(&ptr->dir, &fdirent);
if (rc < 0) { if (rc < 0) {
errno = -rc; errno = -rc;
return NULL; return NULL;