From d5b8e2843a91bb26cad61cf8a05bdeb04f1099f2 Mon Sep 17 00:00:00 2001 From: geniusgogo <2041245+geniusgogo@users.noreply.github.com> Date: Wed, 13 Sep 2023 10:37:00 +0800 Subject: [PATCH] fix dfsv2 tmpfs lock fault. (#8027) --- .../dfs/dfs_v1/filesystems/tmpfs/dfs_tmpfs.c | 27 +++++---- .../dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c | 55 ++++++++++--------- .../dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.h | 1 + 3 files changed, 46 insertions(+), 37 deletions(-) diff --git a/components/dfs/dfs_v1/filesystems/tmpfs/dfs_tmpfs.c b/components/dfs/dfs_v1/filesystems/tmpfs/dfs_tmpfs.c index 7422685fd1..e59721a714 100644 --- a/components/dfs/dfs_v1/filesystems/tmpfs/dfs_tmpfs.c +++ b/components/dfs/dfs_v1/filesystems/tmpfs/dfs_tmpfs.c @@ -120,19 +120,26 @@ int dfs_tmpfs_mount(struct dfs_filesystem *fs, struct tmpfs_sb *superblock; superblock = rt_calloc(1, sizeof(struct tmpfs_sb)); - superblock->df_size = sizeof(struct tmpfs_sb); - superblock->magic = TMPFS_MAGIC; - rt_list_init(&superblock->sibling); + if (superblock) + { + superblock->df_size = sizeof(struct tmpfs_sb); + superblock->magic = TMPFS_MAGIC; + rt_list_init(&superblock->sibling); - superblock->root.name[0] = '/'; - superblock->root.sb = superblock; - superblock->root.type = TMPFS_TYPE_DIR; - rt_list_init(&superblock->root.sibling); - rt_list_init(&superblock->root.subdirs); + superblock->root.name[0] = '/'; + superblock->root.sb = superblock; + superblock->root.type = TMPFS_TYPE_DIR; + rt_list_init(&superblock->root.sibling); + rt_list_init(&superblock->root.subdirs); - rt_spin_lock_init(&superblock->lock); + rt_spin_lock_init(&superblock->lock); - fs->data = superblock; + fs->data = superblock; + } + else + { + return -1; + } return RT_EOK; } diff --git a/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c b/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c index 801b6120c2..7e1182b784 100644 --- a/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c +++ b/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c @@ -86,8 +86,7 @@ static int _free_subdir(struct tmpfs_file *dfile) { struct tmpfs_file *file; rt_list_t *list, *temp_list; - - RT_DEFINE_SPINLOCK(lock); + struct tmpfs_sb *superblock; RT_ASSERT(dfile->type == TMPFS_TYPE_DIR); @@ -103,9 +102,14 @@ static int _free_subdir(struct tmpfs_file *dfile) /* TODO: fix for rt-smart */ rt_free(file->data); } - rt_hw_spin_lock(&lock); + + superblock = file->sb; + RT_ASSERT(superblock != NULL); + + rt_spin_lock(&superblock->lock); rt_list_remove(&(file->sibling)); - rt_hw_spin_unlock(&lock); + rt_spin_unlock(&superblock->lock); + rt_free(file); } return 0; @@ -130,6 +134,8 @@ static int dfs_tmpfs_mount(struct dfs_mnt *mnt, rt_list_init(&superblock->root.sibling); rt_list_init(&superblock->root.subdirs); + rt_spin_lock_init(&superblock->lock); + mnt->data = superblock; } else @@ -137,21 +143,21 @@ static int dfs_tmpfs_mount(struct dfs_mnt *mnt, return -1; } - return 0; + return RT_EOK; } static int dfs_tmpfs_unmount(struct dfs_mnt *mnt) { struct tmpfs_sb *superblock; + /* FIXME: don't unmount on busy. */ superblock = (struct tmpfs_sb *)mnt->data; RT_ASSERT(superblock != NULL); + mnt->data = NULL; _free_subdir(&(superblock->root)); rt_free(superblock); - mnt->data = NULL; - return RT_EOK; } @@ -217,8 +223,6 @@ struct tmpfs_file *dfs_tmpfs_lookup(struct tmpfs_sb *superblock, struct tmpfs_file *file, *curfile; rt_list_t *list; - RT_DEFINE_SPINLOCK(lock); - subpath = path; while (*subpath == '/' && *subpath) subpath ++; @@ -243,7 +247,7 @@ find_subpath: memset(subdir_name, 0, TMPFS_NAME_MAX); _get_subdir(curpath, subdir_name); - rt_hw_spin_lock(&lock); + rt_spin_lock(&superblock->lock); rt_list_for_each(list, &curfile->subdirs) { @@ -254,7 +258,7 @@ find_subpath: { *size = file->size; - rt_hw_spin_unlock(&lock); + rt_spin_unlock(&superblock->lock); return file; } } @@ -263,11 +267,11 @@ find_subpath: *size = file->size; curpath = subpath; curfile = file; - rt_hw_spin_unlock(&lock); + rt_spin_unlock(&superblock->lock); goto find_subpath; } } - rt_hw_spin_unlock(&lock); + rt_spin_unlock(&superblock->lock); /* not found */ return NULL; } @@ -315,7 +319,9 @@ static ssize_t dfs_tmpfs_write(struct dfs_file *file, const void *buf, size_t co return 0; } + rt_spin_lock(&superblock->lock); superblock->df_size += (*pos - d_file->size + count); + rt_spin_unlock(&superblock->lock); /* update d_file and file size */ d_file->data = ptr; d_file->size = *pos + count; @@ -489,8 +495,6 @@ static int dfs_tmpfs_unlink(struct dfs_dentry *dentry) struct tmpfs_sb *superblock; struct tmpfs_file *d_file; - RT_DEFINE_SPINLOCK(lock); - superblock = (struct tmpfs_sb *)dentry->mnt->data; RT_ASSERT(superblock != NULL); @@ -498,9 +502,9 @@ static int dfs_tmpfs_unlink(struct dfs_dentry *dentry) if (d_file == NULL) return -ENOENT; - rt_hw_spin_lock(&lock); + rt_spin_lock(&superblock->lock); rt_list_remove(&(d_file->sibling)); - rt_hw_spin_unlock(&lock); + rt_spin_unlock(&superblock->lock); if (d_file->data != NULL) rt_free(d_file->data); @@ -516,8 +520,6 @@ static int dfs_tmpfs_rename(struct dfs_dentry *old_dentry, struct dfs_dentry *ne rt_size_t size; char parent_path[DFS_PATH_MAX], file_name[TMPFS_NAME_MAX]; - RT_DEFINE_SPINLOCK(lock); - superblock = (struct tmpfs_sb *)old_dentry->mnt->data; RT_ASSERT(superblock != NULL); @@ -537,15 +539,15 @@ static int dfs_tmpfs_rename(struct dfs_dentry *old_dentry, struct dfs_dentry *ne p_file = dfs_tmpfs_lookup(superblock, parent_path, &size); RT_ASSERT(p_file != NULL); - rt_hw_spin_lock(&lock); + rt_spin_lock(&superblock->lock); rt_list_remove(&(d_file->sibling)); - rt_hw_spin_unlock(&lock); + rt_spin_unlock(&superblock->lock); strncpy(d_file->name, file_name, TMPFS_NAME_MAX); - rt_hw_spin_lock(&lock); + rt_spin_lock(&superblock->lock); rt_list_insert_after(&(p_file->subdirs), &(d_file->sibling)); - rt_hw_spin_unlock(&lock); + rt_spin_unlock(&superblock->lock); return RT_EOK; } @@ -598,14 +600,13 @@ static struct dfs_vnode *dfs_tmpfs_create_vnode(struct dfs_dentry *dentry, int t struct tmpfs_file *d_file, *p_file; char parent_path[DFS_PATH_MAX], file_name[TMPFS_NAME_MAX]; - RT_DEFINE_SPINLOCK(lock); - if (dentry == NULL || dentry->mnt == NULL || dentry->mnt->data == NULL) { return NULL; } superblock = (struct tmpfs_sb *)dentry->mnt->data; + RT_ASSERT(superblock != NULL); vnode = dfs_vnode_create(); if (vnode) @@ -655,9 +656,9 @@ static struct dfs_vnode *dfs_tmpfs_create_vnode(struct dfs_dentry *dentry, int t vnode->mode = S_IFREG | mode; vnode->type = FT_REGULAR; } - rt_hw_spin_lock(&lock); + rt_spin_lock(&superblock->lock); rt_list_insert_after(&(p_file->subdirs), &(d_file->sibling)); - rt_hw_spin_unlock(&lock); + rt_spin_unlock(&superblock->lock); vnode->mnt = dentry->mnt; vnode->data = d_file; diff --git a/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.h b/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.h index 37911bfd1b..1c9fbbb648 100644 --- a/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.h +++ b/components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.h @@ -39,6 +39,7 @@ struct tmpfs_sb struct tmpfs_file root; /* root dir */ rt_size_t df_size; /* df size */ rt_list_t sibling; /* sb sibling list */ + struct rt_spinlock lock; /* tmpfs lock */ }; int dfs_tmpfs_init(void);