Browse Source

fix dfsv2 tmpfs lock fault. (#8027)

geniusgogo 1 year ago
parent
commit
d5b8e2843a

+ 17 - 10
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;
 }

+ 28 - 27
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;

+ 1 - 0
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);