删除文件夹时回收dentry缓存

This commit is contained in:
fslongjin 2022-09-13 16:17:35 +08:00
parent 9f2b080cda
commit 26eebaf03a
10 changed files with 132 additions and 63 deletions

View File

@ -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": ""

View File

@ -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
*

View File

@ -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
*

View File

@ -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;
}

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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)); \
})

View File

@ -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;

View File

@ -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);