From 75b4f3d83a473c761fb1b08e6f1e08284d944d57 Mon Sep 17 00:00:00 2001 From: zhouminquan Date: Wed, 20 Sep 2023 15:22:09 +0800 Subject: [PATCH] tmpfs adds truncate functionality and unlink adaptations --- .../dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c | 73 ++++++++++++++++++- .../dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.h | 1 + components/dfs/dfs_v2/src/dfs_file.c | 2 +- components/lwp/lwp_ipc.c | 8 +- 4 files changed, 79 insertions(+), 5 deletions(-) diff --git a/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c b/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c index 7e1182b784..3db3823926 100644 --- a/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c +++ b/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c @@ -7,6 +7,7 @@ * Date Author Notes * 2022-10-24 flybreak the first version * 2023-02-01 xqyjlj fix cannot open the same file repeatedly in 'w' mode + * 2023-09-20 zmq810150896 adds truncate functionality and standardized unlink adaptations */ #include @@ -367,7 +368,28 @@ static off_t dfs_tmpfs_lseek(struct dfs_file *file, off_t offset, int wherece) static int dfs_tmpfs_close(struct dfs_file *file) { + struct tmpfs_file *d_file; + RT_ASSERT(file->vnode->ref_count > 0); + if (file->vnode->ref_count != 1) + return 0; + + d_file = (struct tmpfs_file *)file->vnode->data; + + if (d_file == NULL) + return -ENOENT; + + if (d_file->fre_memory == RT_TRUE) + { + if (d_file->data != NULL) + { + rt_free(d_file->data); + d_file->data = RT_NULL; + } + + rt_free(d_file); + } + return RT_EOK; } @@ -506,9 +528,20 @@ static int dfs_tmpfs_unlink(struct dfs_dentry *dentry) rt_list_remove(&(d_file->sibling)); rt_spin_unlock(&superblock->lock); - if (d_file->data != NULL) - rt_free(d_file->data); - rt_free(d_file); + if (rt_atomic_load(&(dentry->ref_count)) == 1) + { + if (d_file->data != NULL) + { + rt_free(d_file->data); + d_file->data = RT_NULL; + } + + rt_free(d_file); + } + else + { + d_file->fre_memory = RT_TRUE; + } return RT_EOK; } @@ -644,6 +677,7 @@ static struct dfs_vnode *dfs_tmpfs_create_vnode(struct dfs_dentry *dentry, int t d_file->data = NULL; d_file->size = 0; d_file->sb = superblock; + d_file->fre_memory = RT_FALSE; if (type == FT_DIRECTORY) { d_file->type = TMPFS_TYPE_DIR; @@ -679,6 +713,38 @@ static int dfs_tmpfs_free_vnode(struct dfs_vnode *vnode) return 0; } +static int dfs_tmpfs_truncate(struct dfs_file *file, off_t offset) +{ + struct tmpfs_file *d_file = RT_NULL; + struct tmpfs_sb *superblock = RT_NULL; + rt_uint8_t *ptr = RT_NULL; + + d_file = (struct tmpfs_file *)file->vnode->data; + RT_ASSERT(d_file != RT_NULL); + + superblock = d_file->sb; + RT_ASSERT(superblock != RT_NULL); + + ptr = rt_realloc(d_file->data, offset); + if (ptr == RT_NULL) + { + rt_set_errno(-ENOMEM); + return 0; + } + + rt_spin_lock(&superblock->lock); + superblock->df_size = offset; + rt_spin_unlock(&superblock->lock); + + /* update d_file and file size */ + d_file->data = ptr; + d_file->size = offset; + file->vnode->size = d_file->size; + LOG_D("tmpfile ptr:%x, size:%d", ptr, d_file->size); + + return 0; +} + static const struct dfs_file_ops _tmp_fops = { .open = dfs_tmpfs_open, @@ -688,6 +754,7 @@ static const struct dfs_file_ops _tmp_fops = .write = dfs_tmpfs_write, .lseek = dfs_tmpfs_lseek, .getdents = dfs_tmpfs_getdents, + .truncate = dfs_tmpfs_truncate, }; static const struct dfs_filesystem_ops _tmpfs_ops = diff --git a/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.h b/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.h index 1c9fbbb648..365f1e0d42 100644 --- a/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.h +++ b/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.h @@ -30,6 +30,7 @@ struct tmpfs_file struct tmpfs_sb *sb; /* superblock ptr */ rt_uint8_t *data; /* file date ptr */ rt_size_t size; /* file size */ + rt_bool_t fre_memory;/* Whether to release memory upon close */ }; diff --git a/components/dfs/dfs_v2/src/dfs_file.c b/components/dfs/dfs_v2/src/dfs_file.c index 664777e082..c3f5e8061c 100644 --- a/components/dfs/dfs_v2/src/dfs_file.c +++ b/components/dfs/dfs_v2/src/dfs_file.c @@ -1082,7 +1082,7 @@ int dfs_file_unlink(const char *path) rt_bool_t has_child = RT_FALSE; has_child = dfs_mnt_has_child_mnt(mnt, fullpath); - if (has_child == RT_FALSE && rt_atomic_load(&(dentry->ref_count)) == 1) + if (has_child == RT_FALSE) { /* no child mnt point, unlink it */ ret = -RT_ERROR; diff --git a/components/lwp/lwp_ipc.c b/components/lwp/lwp_ipc.c index 4536c9d6fa..0b36306057 100644 --- a/components/lwp/lwp_ipc.c +++ b/components/lwp/lwp_ipc.c @@ -18,6 +18,10 @@ #include #include +#ifdef RT_USING_DFS_V2 +#include +#endif + /** * the IPC channel states */ @@ -371,7 +375,6 @@ static void *_ipc_msg_get_file(int fd) if (!d->vnode) return RT_NULL; - d->vnode->ref_count++; return (void *)d; } @@ -408,6 +411,7 @@ static int _ipc_msg_fd_new(void *file) d->fops = df->fops; d->mode = df->mode; d->dentry = df->dentry; + d->dentry->ref_count ++; #endif d->vnode = df->vnode; @@ -415,6 +419,8 @@ static int _ipc_msg_fd_new(void *file) d->data = df->data; d->magic = df->magic; + d->vnode->ref_count ++; + return fd; }