mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 18:26:48 +00:00
删除文件夹时回收dentry缓存
This commit is contained in:
parent
9f2b080cda
commit
26eebaf03a
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -136,7 +136,8 @@
|
||||
"mount.h": "c",
|
||||
"internal.h": "c",
|
||||
"devfs.h": "c",
|
||||
"devfs-types.h": "c"
|
||||
"devfs-types.h": "c",
|
||||
"chardev.h": "c"
|
||||
},
|
||||
"C_Cpp.errorSquiggles": "Enabled",
|
||||
"esbonio.sphinx.confDir": ""
|
||||
|
@ -155,18 +155,19 @@ struct vfs_dir_entry_t *vfs_path_walk(const char *path, uint64_t flags)
|
||||
while (true)
|
||||
{
|
||||
// 提取出下一级待搜索的目录名或文件名,并保存在dEntry_name中
|
||||
char *tmp_path = path;
|
||||
const char *tmp_path = path;
|
||||
while ((*path && *path != '\0') && (*path != '/'))
|
||||
++path;
|
||||
int tmp_path_len = path - tmp_path;
|
||||
// 搜索是否有dentry缓存
|
||||
{
|
||||
char bk = *(tmp_path + tmp_path_len);
|
||||
*(tmp_path + tmp_path_len) = '\0';
|
||||
// kdebug("to search:%s", tmp_path);
|
||||
dentry = vfs_search_dentry_list(parent, tmp_path);
|
||||
// kdebug("search done, dentry=%#018lx", dentry);
|
||||
*(tmp_path + tmp_path_len) = bk;
|
||||
char *tmpname = kzalloc(tmp_path_len + 1, 0);
|
||||
strncpy(tmpname, tmp_path, tmp_path_len);
|
||||
tmpname[tmp_path_len] = '\0';
|
||||
|
||||
dentry = vfs_search_dentry_list(parent, tmpname);
|
||||
|
||||
kfree(tmpname);
|
||||
}
|
||||
|
||||
// 如果没有找到dentry缓存,则申请新的dentry
|
||||
@ -301,8 +302,8 @@ int64_t vfs_mkdir(const char *path, mode_t mode, bool from_userland)
|
||||
return -EEXIST;
|
||||
}
|
||||
|
||||
struct vfs_dir_entry_t *subdir_dentry = (struct vfs_dir_entry_t *)kmalloc(sizeof(struct vfs_dir_entry_t), 0);
|
||||
memset((void *)subdir_dentry, 0, sizeof(struct vfs_dir_entry_t));
|
||||
struct vfs_dir_entry_t *subdir_dentry = (struct vfs_dir_entry_t *)kzalloc(sizeof(struct vfs_dir_entry_t), 0);
|
||||
|
||||
list_init(&subdir_dentry->subdirs_list);
|
||||
list_init(&subdir_dentry->child_node_list);
|
||||
if (path[pathlen - 1] == '/')
|
||||
@ -450,23 +451,6 @@ uint64_t do_open(const char *filename, int flags)
|
||||
if ((flags & O_DIRECTORY) && (dentry->dir_inode->attribute != VFS_IF_DIR))
|
||||
return -ENOTDIR;
|
||||
|
||||
// // 要找的目标是文件夹
|
||||
// if ((flags & O_DIRECTORY) && dentry->dir_inode->attribute == VFS_IF_DIR)
|
||||
// return -EISDIR;
|
||||
|
||||
// // todo: 引入devfs后删除这段代码
|
||||
// // 暂时遇到设备文件的话,就将其first clus设置为特定值
|
||||
// if (path_len >= 5 && filename[0] == '/' && filename[1] == 'd' && filename[2] == 'e' && filename[3] == 'v' && filename[4] == '/')
|
||||
// {
|
||||
// if (dentry->dir_inode->attribute & VFS_IF_FILE)
|
||||
// {
|
||||
// // 对于fat32文件系统上面的设备文件,设置其起始扇区
|
||||
// ((struct fat32_inode_info_t *)(dentry->dir_inode->private_inode_info))->first_clus |= 0xf0000000;
|
||||
// dentry->dir_inode->sb->sb_ops->write_inode(dentry->dir_inode);
|
||||
// dentry->dir_inode->attribute |= VFS_IF_DEVICE;
|
||||
// }
|
||||
// }
|
||||
|
||||
// 创建文件描述符
|
||||
struct vfs_file_t *file_ptr = (struct vfs_file_t *)kzalloc(sizeof(struct vfs_file_t), 0);
|
||||
|
||||
@ -662,6 +646,19 @@ uint64_t sys_rmdir(struct pt_regs *regs)
|
||||
else
|
||||
return vfs_rmdir((char *)regs->r8, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 分配inode并将引用计数初始化为1
|
||||
*
|
||||
* @return struct vfs_index_node_t * 分配得到的inode
|
||||
*/
|
||||
struct vfs_index_node_t *vfs_alloc_inode()
|
||||
{
|
||||
struct vfs_index_node_t *inode = kzalloc(sizeof(struct vfs_index_node_t), 0);
|
||||
inode->ref_count = 1; // 初始化引用计数为1
|
||||
return inode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 初始化vfs
|
||||
*
|
||||
|
@ -75,6 +75,7 @@ struct vfs_index_node_t
|
||||
uint64_t file_size; // 文件大小
|
||||
uint64_t blocks; // 占用的扇区数
|
||||
uint64_t attribute;
|
||||
int32_t ref_count; // 引用计数
|
||||
|
||||
struct vfs_superblock_t *sb;
|
||||
struct vfs_file_operations_t *file_ops;
|
||||
@ -220,6 +221,13 @@ int vfs_init();
|
||||
*/
|
||||
struct vfs_dir_entry_t *vfs_alloc_dentry(const int name_size);
|
||||
|
||||
/**
|
||||
* @brief 分配inode并将引用计数初始化为1
|
||||
*
|
||||
* @return struct vfs_index_node_t * 分配得到的inode
|
||||
*/
|
||||
struct vfs_index_node_t * vfs_alloc_inode();
|
||||
|
||||
/**
|
||||
* @brief 打开文件
|
||||
*
|
||||
|
@ -1,19 +1,83 @@
|
||||
#include "internal.h"
|
||||
#include <common/kfifo.h>
|
||||
#include <debug/bug.h>
|
||||
|
||||
/**
|
||||
* @brief 释放dentry
|
||||
*
|
||||
*
|
||||
* @param dentry 目标dentry
|
||||
*/
|
||||
void vfs_dentry_put(struct vfs_dir_entry_t * dentry)
|
||||
void vfs_dentry_put(struct vfs_dir_entry_t *dentry)
|
||||
{
|
||||
int retval = 0;
|
||||
uint64_t in_value = 0;
|
||||
// todo: 加锁、放锁
|
||||
|
||||
list_del(&dentry->child_node_list);// 从父dentry中删除
|
||||
// 创建一个用来存放指向dentry的指针的fifo队列
|
||||
struct kfifo_t fifo;
|
||||
// 暂时假设队列大小为1024个元素
|
||||
// todo: 实现队列的自动扩容功能
|
||||
retval = kfifo_alloc(&fifo, 1024 * sizeof(uint64_t), 0);
|
||||
|
||||
// todo: 清除子目录的dentry
|
||||
if (retval != 0)
|
||||
goto failed;
|
||||
|
||||
dentry->dir_ops->release(dentry);
|
||||
// 将根dentry加入队列
|
||||
in_value = (uint64_t)dentry;
|
||||
kfifo_in(&fifo, &in_value, sizeof(uint64_t));
|
||||
list_del(&dentry->child_node_list); // 从父dentry中删除
|
||||
|
||||
kfree(dentry);
|
||||
while (!kfifo_empty(&fifo))
|
||||
{
|
||||
// 取出队列中的下一个元素
|
||||
kfifo_out(&fifo, &dentry, sizeof(uint64_t));
|
||||
BUG_ON(dentry == NULL);
|
||||
struct List *list = &dentry->subdirs_list;
|
||||
if (!list_empty(list))
|
||||
{
|
||||
// 将当前dentry下的所有dentry加入队列
|
||||
do
|
||||
{
|
||||
list = list_next(list);
|
||||
in_value = (uint64_t)container_of(list, struct vfs_dir_entry_t, child_node_list);
|
||||
if (in_value != NULL)
|
||||
kfifo_in(&fifo, &in_value, sizeof(uint64_t));
|
||||
|
||||
} while (list_next(list) != (&dentry->subdirs_list));
|
||||
}
|
||||
|
||||
// 释放inode
|
||||
vfs_free_inode(dentry->dir_inode);
|
||||
|
||||
// 若当前dentry是否为挂载点,则umount
|
||||
if (is_local_mountpoint(dentry))
|
||||
do_umount(dentry);
|
||||
|
||||
dentry->dir_ops->release(dentry);
|
||||
kfree(dentry);
|
||||
}
|
||||
kfifo_free_alloc(&fifo);
|
||||
return;
|
||||
failed:;
|
||||
if (fifo.buffer != NULL)
|
||||
kfifo_free_alloc(&fifo);
|
||||
kerror("dentry_put failed.");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 释放inode
|
||||
*
|
||||
* @param inode 待释放的inode
|
||||
* @return int 错误码
|
||||
*/
|
||||
int vfs_free_inode(struct vfs_index_node_t *inode)
|
||||
{
|
||||
--inode->ref_count;
|
||||
BUG_ON(inode->ref_count < 0);
|
||||
if (inode->ref_count == 0)
|
||||
{
|
||||
kfree(inode->private_inode_info);
|
||||
kfree(inode);
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -38,4 +38,12 @@ static inline bool is_local_mountpoint(struct vfs_dir_entry_t *dentry)
|
||||
*
|
||||
* @param dentry 目标dentry
|
||||
*/
|
||||
void vfs_dentry_put(struct vfs_dir_entry_t * dentry);
|
||||
void vfs_dentry_put(struct vfs_dir_entry_t * dentry);
|
||||
|
||||
/**
|
||||
* @brief 释放inode
|
||||
*
|
||||
* @param inode 待释放的inode
|
||||
* @return int 错误码
|
||||
*/
|
||||
int vfs_free_inode(struct vfs_index_node_t * inode);
|
@ -1,5 +1,7 @@
|
||||
#include "chardev.h"
|
||||
#include "internal.h"
|
||||
#include <filesystem/VFS/VFS.h>
|
||||
|
||||
#include <common/mutex.h>
|
||||
#include <common/stdlib.h>
|
||||
#include <common/string.h>
|
||||
@ -55,7 +57,7 @@ int __devfs_chardev_register(struct devfs_private_inode_info_t *private_info, st
|
||||
|
||||
struct vfs_dir_entry_t *dentry = vfs_alloc_dentry(namelen + 1);
|
||||
__devfs_fill_dentry(dentry, devname);
|
||||
__devfs_fill_inode(dentry, __devfs_alloc_inode(), VFS_IF_DEVICE, private_info);
|
||||
__devfs_fill_inode(dentry, vfs_alloc_inode(), VFS_IF_DEVICE, private_info);
|
||||
|
||||
// 将dentry挂载到char文件夹下
|
||||
__devfs_dentry_bind_parent(chardev_folder_dentry, dentry);
|
||||
|
@ -33,11 +33,11 @@ struct vfs_superblock_t *devfs_read_superblock(struct block_device *blk)
|
||||
return &devfs_sb;
|
||||
}
|
||||
|
||||
static void devfs_write_superblock(struct vfs_superblock_t *sb) {return 0; }
|
||||
static void devfs_write_superblock(struct vfs_superblock_t *sb) {return ; }
|
||||
|
||||
static void devfs_put_superblock(struct vfs_superblock_t *sb) {return 0; }
|
||||
static void devfs_put_superblock(struct vfs_superblock_t *sb) {return ; }
|
||||
|
||||
static void devfs_write_inode(struct vfs_index_node_t *inode) {return 0; }
|
||||
static void devfs_write_inode(struct vfs_index_node_t *inode) {return ; }
|
||||
struct vfs_super_block_operations_t devfs_sb_ops =
|
||||
{
|
||||
.write_superblock = &devfs_write_superblock,
|
||||
@ -146,7 +146,7 @@ static struct vfs_dir_entry_t *devfs_lookup(struct vfs_index_node_t *parent_inod
|
||||
*/
|
||||
static long devfs_mkdir(struct vfs_index_node_t *inode, struct vfs_dir_entry_t *dEntry, int mode)
|
||||
{
|
||||
dEntry->dir_inode = (struct vfs_index_node_t *)kzalloc(sizeof(struct vfs_index_node_t), 0);
|
||||
dEntry->dir_inode = vfs_alloc_inode();
|
||||
dEntry->dir_inode->file_ops = &devfs_file_ops;
|
||||
dEntry->dir_inode->inode_ops = &devfs_inode_ops;
|
||||
dEntry->dir_ops = &devfs_dentry_ops;
|
||||
@ -181,7 +181,7 @@ struct vfs_filesystem_type_t devfs_fs_type =
|
||||
|
||||
static __always_inline void __devfs_init_root_inode()
|
||||
{
|
||||
devfs_root_dentry->dir_inode = (struct vfs_index_node_t *)kzalloc(sizeof(struct vfs_index_node_t), 0);
|
||||
devfs_root_dentry->dir_inode = vfs_alloc_inode();
|
||||
devfs_root_dentry->dir_inode->file_ops = &devfs_file_ops;
|
||||
devfs_root_dentry->dir_inode->inode_ops = &devfs_inode_ops;
|
||||
|
||||
|
@ -9,9 +9,6 @@ extern struct vfs_file_operations_t devfs_file_ops;
|
||||
extern struct vfs_inode_operations_t devfs_inode_ops;
|
||||
extern struct vfs_superblock_t devfs_sb;
|
||||
|
||||
// 分配inode
|
||||
#define __devfs_alloc_inode() ((struct vfs_index_node_t *)kzalloc(sizeof(struct vfs_index_node_t), 0))
|
||||
|
||||
/**
|
||||
* @brief 在devfs中注册字符设备(该函数只应被devfs调用)
|
||||
*
|
||||
@ -101,9 +98,7 @@ static inline void __devfs_fill_dentry(struct vfs_dir_entry_t *dentry, const cha
|
||||
* @param parent 父目录项
|
||||
* @param dentry 子目录项
|
||||
*/
|
||||
#define __devfs_dentry_bind_parent(parent_dentry, dentry) \
|
||||
do \
|
||||
{ \
|
||||
(dentry)->parent = (parent_dentry); \
|
||||
list_append(&((parent_dentry)->subdirs_list), &((dentry)->child_node_list)); \
|
||||
} while (0)
|
||||
#define __devfs_dentry_bind_parent(parent_dentry, dentry) ({ \
|
||||
(dentry)->parent = (parent_dentry); \
|
||||
list_append(&((parent_dentry)->subdirs_list), &((dentry)->child_node_list)); \
|
||||
})
|
||||
|
@ -287,8 +287,7 @@ struct vfs_dir_entry_t *fat32_lookup(struct vfs_index_node_t *parent_inode, stru
|
||||
}
|
||||
}
|
||||
find_lookup_success:; // 找到目标dentry
|
||||
struct vfs_index_node_t *p = (struct vfs_index_node_t *)kmalloc(sizeof(struct vfs_index_node_t), 0);
|
||||
memset(p, 0, sizeof(struct vfs_index_node_t));
|
||||
struct vfs_index_node_t *p = vfs_alloc_inode();
|
||||
|
||||
p->file_size = tmp_dEntry->DIR_FileSize;
|
||||
// 计算文件占用的扇区数, 由于最小存储单位是簇,因此需要按照簇的大小来对齐扇区
|
||||
@ -299,8 +298,7 @@ find_lookup_success:; // 找到目标dentry
|
||||
p->inode_ops = &fat32_inode_ops;
|
||||
|
||||
// 为inode的与文件系统相关的信息结构体分配空间
|
||||
p->private_inode_info = (void *)kmalloc(sizeof(fat32_inode_info_t), 0);
|
||||
memset(p->private_inode_info, 0, sizeof(fat32_inode_info_t));
|
||||
p->private_inode_info = (void *)kzalloc(sizeof(fat32_inode_info_t), 0);
|
||||
finode = (fat32_inode_info_t *)p->private_inode_info;
|
||||
|
||||
finode->first_clus = ((tmp_dEntry->DIR_FstClusHI << 16) | tmp_dEntry->DIR_FstClusLO) & 0x0fffffff;
|
||||
@ -387,8 +385,7 @@ struct vfs_superblock_t *fat32_read_superblock(struct block_device *blk)
|
||||
sb_ptr->root->name_length = 1;
|
||||
|
||||
// 为root目录项分配index node
|
||||
sb_ptr->root->dir_inode = (struct vfs_index_node_t *)kmalloc(sizeof(struct vfs_index_node_t), 0);
|
||||
memset(sb_ptr->root->dir_inode, 0, sizeof(struct vfs_index_node_t));
|
||||
sb_ptr->root->dir_inode = vfs_alloc_inode();
|
||||
sb_ptr->root->dir_inode->inode_ops = &fat32_inode_ops;
|
||||
sb_ptr->root->dir_inode->file_ops = &fat32_file_ops;
|
||||
sb_ptr->root->dir_inode->file_size = 0;
|
||||
@ -819,13 +816,11 @@ long fat32_create(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t
|
||||
if (dest_dEntry->dir_inode != NULL)
|
||||
return -EEXIST;
|
||||
|
||||
struct vfs_index_node_t *inode = (struct vfs_index_node_t *)kmalloc(sizeof(struct vfs_index_node_t), 0);
|
||||
memset((void *)inode, 0, sizeof(struct vfs_index_node_t));
|
||||
struct vfs_index_node_t *inode = vfs_alloc_inode();
|
||||
dest_dEntry->dir_inode = inode;
|
||||
dest_dEntry->dir_ops = &fat32_dEntry_ops;
|
||||
|
||||
struct fat32_inode_info_t *finode = (struct fat32_inode_info_t *)kmalloc(sizeof(struct fat32_inode_info_t), 0);
|
||||
memset((void *)finode, 0, sizeof(struct fat32_inode_info_t));
|
||||
struct fat32_inode_info_t *finode = (struct fat32_inode_info_t *)kzalloc(sizeof(struct fat32_inode_info_t), 0);
|
||||
inode->attribute = VFS_IF_FILE;
|
||||
inode->file_ops = &fat32_file_ops;
|
||||
inode->file_size = 0;
|
||||
@ -931,8 +926,7 @@ int64_t fat32_mkdir(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_
|
||||
struct fat32_Directory_t *empty_fat32_dentry = fat32_find_empty_dentry(parent_inode, cnt_longname + 1, 0, &tmp_dentry_sector, &tmp_parent_dentry_clus, &tmp_dentry_clus_buf_addr);
|
||||
|
||||
// ====== 初始化inode =======
|
||||
struct vfs_index_node_t *inode = (struct vfs_index_node_t *)kmalloc(sizeof(struct vfs_index_node_t), 0);
|
||||
memset(inode, 0, sizeof(struct vfs_index_node_t));
|
||||
struct vfs_index_node_t *inode = vfs_alloc_inode();
|
||||
inode->attribute = VFS_IF_DIR;
|
||||
inode->blocks = fsbi->sec_per_clus;
|
||||
inode->file_ops = &fat32_file_ops;
|
||||
|
@ -388,7 +388,7 @@ int shell_cmd_mkdir(int argc, char **argv)
|
||||
{
|
||||
full_path = get_target_filepath(argv[1], &result_path_len);
|
||||
}
|
||||
printf("mkdir: full_path = %s\n", full_path);
|
||||
// printf("mkdir: full_path = %s\n", full_path);
|
||||
int retval = mkdir(full_path, 0);
|
||||
|
||||
if (argv != NULL)
|
||||
@ -414,7 +414,7 @@ int shell_cmd_rmdir(int argc, char **argv)
|
||||
else
|
||||
full_path = get_target_filepath(argv[1], &result_path_len);
|
||||
int retval = rmdir(full_path);
|
||||
printf("rmdir: path=%s, retval=%d", full_path, retval);
|
||||
// printf("rmdir: path=%s, retval=%d\n", full_path, retval);
|
||||
if (argv != NULL)
|
||||
free(argv);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user