summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgeniusgogo <[email protected]>2023-09-13 10:37:00 +0800
committerGitHub <[email protected]>2023-09-13 10:37:00 +0800
commitd5b8e2843a91bb26cad61cf8a05bdeb04f1099f2 (patch)
treed228722add923e300476689fac67bb81e0cb146f
parent6deab5e93da5e32497f739fb1d2540d1800189e9 (diff)
fix dfsv2 tmpfs lock fault. (#8027)
-rw-r--r--components/dfs/dfs_v1/filesystems/tmpfs/dfs_tmpfs.c27
-rw-r--r--components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.c55
-rw-r--r--components/dfs/dfs_v2/filesystems/tmpfs/dfs_tmpfs.h1
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);