mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 11:16:47 +00:00
new: devfs删除文件夹
This commit is contained in:
parent
d60f1a8f80
commit
9f2b080cda
6
.vscode/settings.json
vendored
6
.vscode/settings.json
vendored
@ -132,7 +132,11 @@
|
||||
"limits.h": "c",
|
||||
"block.h": "c",
|
||||
"blk_types.h": "c",
|
||||
"mutex.h": "c"
|
||||
"mutex.h": "c",
|
||||
"mount.h": "c",
|
||||
"internal.h": "c",
|
||||
"devfs.h": "c",
|
||||
"devfs-types.h": "c"
|
||||
},
|
||||
"C_Cpp.errorSquiggles": "Enabled",
|
||||
"esbonio.sphinx.confDir": ""
|
||||
|
@ -173,11 +173,11 @@ struct vfs_index_node_t
|
||||
|
||||
  inode的属性。可选值如下:
|
||||
|
||||
> - VFS_ATTR_FILE
|
||||
> - VFS_IF_FILE
|
||||
>
|
||||
> - VFS_ATTR_DIR
|
||||
> - VFS_IF_DIR
|
||||
>
|
||||
> - VFS_ATTR_DEVICE
|
||||
> - VFS_IF_DEVICE
|
||||
|
||||
**sb**
|
||||
|
||||
|
@ -48,11 +48,11 @@
|
||||
|
||||
文件夹类型:
|
||||
|
||||
``#define VFS_ATTR_FILE (1UL << 0)``
|
||||
``#define VFS_IF_FILE (1UL << 0)``
|
||||
|
||||
``#define VFS_ATTR_DIR (1UL << 1)``
|
||||
``#define VFS_IF_DIR (1UL << 1)``
|
||||
|
||||
``#define VFS_ATTR_DEVICE (1UL << 2)``
|
||||
``#define VFS_IF_DEVICE (1UL << 2)``
|
||||
|
||||
缓冲区长度的默认值
|
||||
|
||||
|
@ -4,6 +4,18 @@
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize("O0")
|
||||
|
||||
/**
|
||||
* @brief 当condition为true时,认为产生了bug
|
||||
*
|
||||
*/
|
||||
#define BUG_ON(condition) ({ \
|
||||
int __ret_bug_on = !!(condition); \
|
||||
if (unlikely(__ret_bug_on)) \
|
||||
kBUG("BUG at %s:%d", __FILE__, __LINE__); \
|
||||
unlikely(__ret_bug_on); \
|
||||
})
|
||||
|
||||
/**
|
||||
* @brief 当condition为true时输出警告信息
|
||||
*
|
||||
|
@ -1,6 +1,8 @@
|
||||
#include "VFS.h"
|
||||
#include "mount.h"
|
||||
#include "internal.h"
|
||||
#include <common/kprint.h>
|
||||
#include <debug/bug.h>
|
||||
#include <common/dirent.h>
|
||||
#include <common/string.h>
|
||||
#include <common/errno.h>
|
||||
@ -46,7 +48,9 @@ struct vfs_superblock_t *vfs_mount_fs(const char *path, char *name, struct block
|
||||
{
|
||||
struct vfs_superblock_t *sb = p->read_superblock(blk);
|
||||
if (strcmp(path, "/") == 0) // 如果挂载到的是'/'挂载点,则让其成为最顶层的文件系统
|
||||
{
|
||||
vfs_root_sb = sb;
|
||||
}
|
||||
else
|
||||
{
|
||||
kdebug("to mount %s", name);
|
||||
@ -168,7 +172,7 @@ struct vfs_dir_entry_t *vfs_path_walk(const char *path, uint64_t flags)
|
||||
// 如果没有找到dentry缓存,则申请新的dentry
|
||||
if (dentry == NULL)
|
||||
{
|
||||
dentry = vfs_alloc_dentry(tmp_path_len+1);
|
||||
dentry = vfs_alloc_dentry(tmp_path_len + 1);
|
||||
|
||||
memcpy(dentry->name, (void *)tmp_path, tmp_path_len);
|
||||
dentry->name[tmp_path_len] = '\0';
|
||||
@ -236,13 +240,13 @@ int vfs_fill_dirent(void *buf, ino_t d_ino, char *name, int namelen, unsigned ch
|
||||
|
||||
/**
|
||||
* @brief 创建文件夹
|
||||
*
|
||||
*
|
||||
* @param path 文件夹路径
|
||||
* @param mode 创建模式
|
||||
* @param from_userland 该创建请求是否来自用户态
|
||||
* @param from_userland 该创建请求是否来自用户态
|
||||
* @return int64_t 错误码
|
||||
*/
|
||||
int64_t vfs_mkdir(const char* path, mode_t mode, bool from_userland)
|
||||
int64_t vfs_mkdir(const char *path, mode_t mode, bool from_userland)
|
||||
{
|
||||
uint32_t pathlen;
|
||||
if (from_userland)
|
||||
@ -267,10 +271,9 @@ int64_t vfs_mkdir(const char* path, mode_t mode, bool from_userland)
|
||||
|
||||
// 路径格式不合法(必须使用绝对路径)
|
||||
if (last_slash < 0)
|
||||
return ENOTDIR;
|
||||
return -ENOTDIR;
|
||||
|
||||
char *buf = (char *)kmalloc(last_slash + 1, 0);
|
||||
memset(buf, 0, pathlen + 1);
|
||||
char *buf = (char *)kzalloc(last_slash + 2, 0);
|
||||
|
||||
// 拷贝字符串(不包含要被创建的部分)
|
||||
if (from_userland)
|
||||
@ -341,13 +344,12 @@ uint64_t sys_mkdir(struct pt_regs *regs)
|
||||
return vfs_mkdir(path, mode, true);
|
||||
else
|
||||
return vfs_mkdir(path, mode, false);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 打开文件
|
||||
*
|
||||
* @param filename 文件路径
|
||||
*
|
||||
* @param filename 文件路径
|
||||
* @param flags 标志位
|
||||
* @return uint64_t 错误码
|
||||
*/
|
||||
@ -445,23 +447,23 @@ uint64_t do_open(const char *filename, int flags)
|
||||
return -ENOENT;
|
||||
|
||||
// 要求打开文件夹而目标不是文件夹
|
||||
if ((flags & O_DIRECTORY) && (dentry->dir_inode->attribute != VFS_ATTR_DIR))
|
||||
if ((flags & O_DIRECTORY) && (dentry->dir_inode->attribute != VFS_IF_DIR))
|
||||
return -ENOTDIR;
|
||||
|
||||
// // 要找的目标是文件夹
|
||||
// if ((flags & O_DIRECTORY) && dentry->dir_inode->attribute == VFS_ATTR_DIR)
|
||||
// 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_ATTR_FILE)
|
||||
// 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_ATTR_DEVICE;
|
||||
// dentry->dir_inode->attribute |= VFS_IF_DEVICE;
|
||||
// }
|
||||
// }
|
||||
|
||||
@ -544,6 +546,122 @@ struct vfs_dir_entry_t *vfs_alloc_dentry(const int name_size)
|
||||
return dentry;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 判断是否可以删除指定的dentry
|
||||
*
|
||||
* 1、我们不能删除一个只读的dentry
|
||||
* 2、我们应当对这个dentry的inode拥有写、执行权限(暂时还没有实现权限)
|
||||
* 3、如果dentry指向的是文件夹,而isdir为false,则不能删除
|
||||
* 3、如果dentry指向的是文件,而isdir为true,则不能删除
|
||||
* @param dentry 将要被删除的dentry
|
||||
* @param isdir 是否要删除文件夹
|
||||
* @return int 错误码
|
||||
*/
|
||||
int vfs_may_delete(struct vfs_dir_entry_t *dentry, bool isdir)
|
||||
{
|
||||
// 当dentry没有inode的时候,认为是bug
|
||||
BUG_ON(dentry->dir_inode == NULL);
|
||||
|
||||
// todo: 进行权限检查
|
||||
|
||||
if (isdir) // 要删除文件夹
|
||||
{
|
||||
if (!D_ISDIR(dentry))
|
||||
return -ENOTDIR;
|
||||
else if (IS_ROOT(dentry))
|
||||
return -EBUSY;
|
||||
}
|
||||
else if (D_ISDIR(dentry)) // 要删除文件但是当前是文件夹
|
||||
return -EISDIR;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 删除文件夹
|
||||
*
|
||||
* @param path 文件夹路径
|
||||
* @param from_userland 请求是否来自用户态
|
||||
* @return int64_t 错误码
|
||||
*/
|
||||
int64_t vfs_rmdir(const char *path, bool from_userland)
|
||||
{
|
||||
uint32_t pathlen;
|
||||
if (from_userland)
|
||||
pathlen = strnlen_user(path, PAGE_4K_SIZE - 1);
|
||||
else
|
||||
pathlen = strnlen(path, PAGE_4K_SIZE - 1);
|
||||
|
||||
if (pathlen == 0)
|
||||
return -ENOENT;
|
||||
|
||||
int last_slash = -1;
|
||||
|
||||
// 去除末尾的'/'
|
||||
for (int i = pathlen - 1; i >= 0; --i)
|
||||
{
|
||||
if (path[i] != '/')
|
||||
{
|
||||
last_slash = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 路径格式不合法
|
||||
if (last_slash < 0)
|
||||
return -ENOTDIR;
|
||||
else if (path[0] != '/')
|
||||
return -EINVAL;
|
||||
|
||||
char *buf = (char *)kzalloc(last_slash + 2, 0);
|
||||
|
||||
// 拷贝字符串(不包含要被创建的部分)
|
||||
if (from_userland)
|
||||
strncpy_from_user(buf, path, last_slash);
|
||||
else
|
||||
strncpy(buf, path, last_slash);
|
||||
buf[last_slash + 1] = '\0';
|
||||
|
||||
struct vfs_dir_entry_t *dentry = vfs_path_walk(buf, 0);
|
||||
|
||||
if (dentry == NULL)
|
||||
return -ENOENT;
|
||||
|
||||
int retval = vfs_may_delete(dentry, true);
|
||||
if (retval != 0)
|
||||
return retval;
|
||||
// todo: 对dentry和inode加锁
|
||||
retval = -EBUSY;
|
||||
if (is_local_mountpoint(dentry))
|
||||
goto out;
|
||||
// todo:
|
||||
retval = dentry->dir_inode->inode_ops->rmdir(dentry->dir_inode, dentry);
|
||||
if (retval != 0)
|
||||
goto out;
|
||||
|
||||
dentry->dir_inode->attribute |= VFS_IF_DEAD; // 将当前inode标记为dead
|
||||
dont_mount(dentry); // 将当前dentry标记为不可被挂载
|
||||
detach_mounts(dentry); // 清理同样挂载在该路径的所有挂载点的挂载树
|
||||
|
||||
vfs_dentry_put(dentry); // 释放dentry
|
||||
out:;
|
||||
// todo: 对dentry和inode放锁
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 删除文件夹的系统调用函数
|
||||
*
|
||||
* @param r8 文件夹路径
|
||||
* @return uint64_t 错误码
|
||||
*/
|
||||
uint64_t sys_rmdir(struct pt_regs *regs)
|
||||
{
|
||||
if (SYSCALL_FROM_USER(regs))
|
||||
return vfs_rmdir((char *)regs->r8, true);
|
||||
else
|
||||
return vfs_rmdir((char *)regs->r8, false);
|
||||
}
|
||||
/**
|
||||
* @brief 初始化vfs
|
||||
*
|
||||
|
@ -28,12 +28,13 @@ extern struct vfs_superblock_t *vfs_root_sb;
|
||||
#define VFS_MAX_PATHLEN 1024
|
||||
|
||||
/**
|
||||
* @brief 目录项的属性
|
||||
* @brief inode的属性
|
||||
*
|
||||
*/
|
||||
#define VFS_ATTR_FILE (1UL << 0)
|
||||
#define VFS_ATTR_DIR (1UL << 1)
|
||||
#define VFS_ATTR_DEVICE (1UL << 2)
|
||||
#define VFS_IF_FILE (1UL << 0)
|
||||
#define VFS_IF_DIR (1UL << 1)
|
||||
#define VFS_IF_DEVICE (1UL << 2)
|
||||
#define VFS_IF_DEAD (1UL<<3) /* removed, but still open directory */
|
||||
|
||||
struct vfs_super_block_operations_t;
|
||||
struct vfs_inode_operations_t;
|
||||
@ -41,10 +42,13 @@ struct vfs_inode_operations_t;
|
||||
struct vfs_index_node_t;
|
||||
struct vfs_dir_entry_operations_t;
|
||||
|
||||
#define VFS_DF_MOUNTED (1 << 0) // 当前dentry是一个挂载点
|
||||
#define VFS_DF_CANNOT_MOUNT (1 << 1) // 当前dentry是一个挂载点
|
||||
struct vfs_dir_entry_t
|
||||
{
|
||||
char *name;
|
||||
int name_length;
|
||||
uint32_t d_flags; // dentry标志位
|
||||
struct List child_node_list;
|
||||
struct List subdirs_list;
|
||||
|
||||
@ -218,8 +222,8 @@ struct vfs_dir_entry_t *vfs_alloc_dentry(const int name_size);
|
||||
|
||||
/**
|
||||
* @brief 打开文件
|
||||
*
|
||||
* @param filename 文件路径
|
||||
*
|
||||
* @param filename 文件路径
|
||||
* @param flags 标志位
|
||||
* @return uint64_t 错误码
|
||||
*/
|
||||
@ -227,10 +231,19 @@ uint64_t do_open(const char *filename, int flags);
|
||||
|
||||
/**
|
||||
* @brief 创建文件夹
|
||||
*
|
||||
*
|
||||
* @param path 文件夹路径
|
||||
* @param mode 创建模式
|
||||
* @param from_userland 该创建请求是否来自用户态
|
||||
* @param from_userland 该创建请求是否来自用户态
|
||||
* @return int64_t 错误码
|
||||
*/
|
||||
int64_t vfs_mkdir(const char* path, mode_t mode, bool from_userland);
|
||||
int64_t vfs_mkdir(const char *path, mode_t mode, bool from_userland);
|
||||
|
||||
/**
|
||||
* @brief 删除文件夹
|
||||
*
|
||||
* @param path 文件夹路径
|
||||
* @param from_userland 请求是否来自用户态
|
||||
* @return int64_t 错误码
|
||||
*/
|
||||
int64_t vfs_rmdir(const char *path, bool from_userland);
|
19
kernel/filesystem/VFS/dcache.c
Normal file
19
kernel/filesystem/VFS/dcache.c
Normal file
@ -0,0 +1,19 @@
|
||||
#include "internal.h"
|
||||
|
||||
/**
|
||||
* @brief 释放dentry
|
||||
*
|
||||
* @param dentry 目标dentry
|
||||
*/
|
||||
void vfs_dentry_put(struct vfs_dir_entry_t * dentry)
|
||||
{
|
||||
// todo: 加锁、放锁
|
||||
|
||||
list_del(&dentry->child_node_list);// 从父dentry中删除
|
||||
|
||||
// todo: 清除子目录的dentry
|
||||
|
||||
dentry->dir_ops->release(dentry);
|
||||
|
||||
kfree(dentry);
|
||||
}
|
41
kernel/filesystem/VFS/internal.h
Normal file
41
kernel/filesystem/VFS/internal.h
Normal file
@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
#include "VFS.h"
|
||||
#include "mount.h"
|
||||
|
||||
/**
|
||||
* @brief 判断是否可以删除指定的dentry
|
||||
*
|
||||
* 1、我们不能删除一个只读的dentry
|
||||
* 2、我们应当对这个dentry拥有写、执行权限(暂时还没有实现权限)
|
||||
* 3、如果dentry指向的是文件夹,而isdir为false,则不能删除
|
||||
* 3、如果dentry指向的是文件,而isdir为true,则不能删除
|
||||
* @param dentry 将要被删除的dentry
|
||||
* @param isdir 是否要删除文件夹
|
||||
* @return int 错误码
|
||||
*/
|
||||
int vfs_may_delete(struct vfs_dir_entry_t *dentry, bool isdir);
|
||||
|
||||
#define D_ISDIR(dentry) ((dentry)->dir_inode->attribute & VFS_IF_DIR)
|
||||
|
||||
// 判断是否为根目录
|
||||
#define IS_ROOT(x) ((x) == (x)->parent)
|
||||
|
||||
/**
|
||||
* @brief 判断当前dentry是否为挂载点
|
||||
*
|
||||
* @param dentry
|
||||
*/
|
||||
static inline bool is_local_mountpoint(struct vfs_dir_entry_t *dentry)
|
||||
{
|
||||
if (D_MOUNTED(dentry))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 释放dentry
|
||||
*
|
||||
* @param dentry 目标dentry
|
||||
*/
|
||||
void vfs_dentry_put(struct vfs_dir_entry_t * dentry);
|
@ -29,16 +29,17 @@ int do_mount(struct vfs_dir_entry_t *old_dentry, struct vfs_dir_entry_t *new_den
|
||||
list_init(&mp->mnt_list);
|
||||
mp->dentry = old_dentry;
|
||||
mp->parent_dentry = old_dentry->parent;
|
||||
|
||||
|
||||
// kdebug("&new_dentry->name=%#018lx, &old_dentry->name=%#018lx", &new_dentry->name, &old_dentry->name);
|
||||
// 拷贝名称
|
||||
strncpy(new_dentry->name, old_dentry->name, old_dentry->name_length);
|
||||
|
||||
new_dentry->d_flags |= VFS_DF_MOUNTED; // 标记新的dentry是一个挂载点
|
||||
|
||||
list_init(&new_dentry->child_node_list);
|
||||
list_init(&new_dentry->subdirs_list);
|
||||
new_dentry->parent = old_dentry->parent;
|
||||
|
||||
|
||||
// 将新的dentry的list结点替换掉父dentry的列表中的old_dentry的list结点
|
||||
list_replace(&old_dentry->child_node_list, &new_dentry->child_node_list);
|
||||
|
||||
@ -50,11 +51,11 @@ int do_mount(struct vfs_dir_entry_t *old_dentry, struct vfs_dir_entry_t *new_den
|
||||
|
||||
/**
|
||||
* @brief 取消某个文件系统的挂载
|
||||
*
|
||||
*
|
||||
* @param dentry 对应文件系统的根dentry
|
||||
* @return int 错误码
|
||||
*/
|
||||
int do_umount(struct vfs_dir_entry_t* dentry)
|
||||
int do_umount(struct vfs_dir_entry_t *dentry)
|
||||
{
|
||||
// todo: 实现umount(主要是结点的恢复问题)
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
#include <common/glib.h>
|
||||
|
||||
#include "VFS.h"
|
||||
/**
|
||||
* @brief 挂载点结构体(用来表示dentry被挂载其他文件系统之后,原先存在的数据)
|
||||
*
|
||||
@ -30,8 +30,31 @@ int do_mount(struct vfs_dir_entry_t *old_dentry, struct vfs_dir_entry_t *new_den
|
||||
|
||||
/**
|
||||
* @brief 取消某个文件系统的挂载
|
||||
*
|
||||
*
|
||||
* @param dentry 对应文件系统的根dentry
|
||||
* @return int 错误码
|
||||
*/
|
||||
int do_umount(struct vfs_dir_entry_t* dentry);
|
||||
int do_umount(struct vfs_dir_entry_t *dentry);
|
||||
|
||||
// 判断dentry是否是一个挂载点
|
||||
#define D_MOUNTED(x) ((x)->d_flags & VFS_DF_MOUNTED)
|
||||
|
||||
/**
|
||||
* @brief 将给定的dentry标记为“不可挂载”
|
||||
*
|
||||
* @param dentry 目标dentry
|
||||
*/
|
||||
static inline void dont_mount(struct vfs_dir_entry_t *dentry)
|
||||
{
|
||||
// todo: 对dentry加锁
|
||||
dentry->d_flags |= VFS_DF_CANNOT_MOUNT;
|
||||
}
|
||||
|
||||
static inline void detach_mounts(struct vfs_dir_entry_t *dentry)
|
||||
{
|
||||
if (!D_MOUNTED(dentry))
|
||||
return; // 如果当前文件夹不是一个挂载点,则直接返回
|
||||
|
||||
// todo:如果当前文件夹是一个挂载点,则对同样挂载在当前文件夹下的dentry进行清理。以免造成内存泄露
|
||||
// 可参考 linux5.17或以上的detach_mounts()函数
|
||||
}
|
@ -55,7 +55,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_ATTR_DEVICE, private_info);
|
||||
__devfs_fill_inode(dentry, __devfs_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) {}
|
||||
static void devfs_write_superblock(struct vfs_superblock_t *sb) {return 0; }
|
||||
|
||||
static void devfs_put_superblock(struct vfs_superblock_t *sb) {}
|
||||
static void devfs_put_superblock(struct vfs_superblock_t *sb) {return 0; }
|
||||
|
||||
static void devfs_write_inode(struct vfs_index_node_t *inode) {}
|
||||
static void devfs_write_inode(struct vfs_index_node_t *inode) {return 0; }
|
||||
struct vfs_super_block_operations_t devfs_sb_ops =
|
||||
{
|
||||
.write_superblock = &devfs_write_superblock,
|
||||
@ -45,13 +45,13 @@ struct vfs_super_block_operations_t devfs_sb_ops =
|
||||
.write_inode = &devfs_write_inode,
|
||||
};
|
||||
|
||||
static long devfs_compare(struct vfs_dir_entry_t *parent_dEntry, char *source_filename, char *dest_filename) {}
|
||||
static long devfs_compare(struct vfs_dir_entry_t *parent_dEntry, char *source_filename, char *dest_filename) {return 0; }
|
||||
|
||||
static long devfs_hash(struct vfs_dir_entry_t *dEntry, char *filename) {}
|
||||
static long devfs_hash(struct vfs_dir_entry_t *dEntry, char *filename) {return 0; }
|
||||
|
||||
static long devfs_release(struct vfs_dir_entry_t *dEntry) {}
|
||||
static long devfs_release(struct vfs_dir_entry_t *dEntry) { return 0; }
|
||||
|
||||
static long devfs_iput(struct vfs_dir_entry_t *dEntry, struct vfs_index_node_t *inode) {}
|
||||
static long devfs_iput(struct vfs_dir_entry_t *dEntry, struct vfs_index_node_t *inode) {return 0; }
|
||||
|
||||
struct vfs_dir_entry_operations_t devfs_dentry_ops =
|
||||
{
|
||||
@ -65,10 +65,10 @@ static long devfs_open(struct vfs_index_node_t *inode, struct vfs_file_t *file_p
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static long devfs_close(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr) {}
|
||||
static long devfs_read(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *position) {}
|
||||
static long devfs_write(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *position) {}
|
||||
static long devfs_lseek(struct vfs_file_t *file_ptr, long offset, long origin) {}
|
||||
static long devfs_close(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr) {return 0; }
|
||||
static long devfs_read(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *position) {return 0; }
|
||||
static long devfs_write(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *position) {return 0; }
|
||||
static long devfs_lseek(struct vfs_file_t *file_ptr, long offset, long origin) {return 0; }
|
||||
static long devfs_ioctl(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr, uint64_t cmd, uint64_t arg) { return 0; }
|
||||
|
||||
static long devfs_readdir(struct vfs_file_t *file_ptr, void *dirent, vfs_filldir_t filler)
|
||||
@ -94,10 +94,10 @@ static long devfs_readdir(struct vfs_file_t *file_ptr, void *dirent, vfs_filldir
|
||||
char *name = (char *)kzalloc(target_dent->name_length + 1, 0);
|
||||
strncpy(name, target_dent->name, target_dent->name_length);
|
||||
uint32_t dentry_type;
|
||||
if (target_dent->dir_inode->attribute & VFS_ATTR_DIR)
|
||||
dentry_type = VFS_ATTR_DIR;
|
||||
if (target_dent->dir_inode->attribute & VFS_IF_DIR)
|
||||
dentry_type = VFS_IF_DIR;
|
||||
else
|
||||
dentry_type = VFS_ATTR_DEVICE;
|
||||
dentry_type = VFS_IF_DEVICE;
|
||||
|
||||
return filler(dirent, file_ptr->position - 1, name, target_dent->name_length, dentry_type, file_ptr->position - 1);
|
||||
failed:;
|
||||
@ -123,6 +123,7 @@ struct vfs_file_operations_t devfs_file_ops =
|
||||
*/
|
||||
static long devfs_create(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t *dest_dEntry, int mode)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct vfs_dir_entry_t *devfs_lookup(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t *dest_dEntry)
|
||||
@ -148,18 +149,18 @@ static long devfs_mkdir(struct vfs_index_node_t *inode, struct vfs_dir_entry_t *
|
||||
dEntry->dir_inode = (struct vfs_index_node_t *)kzalloc(sizeof(struct vfs_index_node_t), 0);
|
||||
dEntry->dir_inode->file_ops = &devfs_file_ops;
|
||||
dEntry->dir_inode->inode_ops = &devfs_inode_ops;
|
||||
|
||||
dEntry->dir_ops = &devfs_dentry_ops;
|
||||
// todo: 增加private inode info
|
||||
dEntry->dir_inode->private_inode_info = NULL;
|
||||
dEntry->dir_inode->sb = &devfs_sb;
|
||||
dEntry->dir_inode->attribute = VFS_ATTR_DIR;
|
||||
dEntry->dir_inode->attribute = VFS_IF_DIR;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long devfs_rmdir(struct vfs_index_node_t *inode, struct vfs_dir_entry_t *dEntry) {}
|
||||
static long devfs_rename(struct vfs_index_node_t *old_inode, struct vfs_dir_entry_t *old_dEntry, struct vfs_index_node_t *new_inode, struct vfs_dir_entry_t *new_dEntry) {}
|
||||
static long devfs_getAttr(struct vfs_dir_entry_t *dEntry, uint64_t *attr) {}
|
||||
static long devfs_setAttr(struct vfs_dir_entry_t *dEntry, uint64_t *attr) {}
|
||||
static long devfs_rmdir(struct vfs_index_node_t *inode, struct vfs_dir_entry_t *dEntry) { return 0; }
|
||||
static long devfs_rename(struct vfs_index_node_t *old_inode, struct vfs_dir_entry_t *old_dEntry, struct vfs_index_node_t *new_inode, struct vfs_dir_entry_t *new_dEntry) {return 0; }
|
||||
static long devfs_getAttr(struct vfs_dir_entry_t *dEntry, uint64_t *attr) {return 0; }
|
||||
static long devfs_setAttr(struct vfs_dir_entry_t *dEntry, uint64_t *attr) {return 0; }
|
||||
struct vfs_inode_operations_t devfs_inode_ops = {
|
||||
.create = &devfs_create,
|
||||
.lookup = &devfs_lookup,
|
||||
@ -187,7 +188,7 @@ static __always_inline void __devfs_init_root_inode()
|
||||
// todo: 增加private inode info
|
||||
devfs_root_dentry->dir_inode->private_inode_info = NULL;
|
||||
devfs_root_dentry->dir_inode->sb = &devfs_sb;
|
||||
devfs_root_dentry->dir_inode->attribute = VFS_ATTR_DIR;
|
||||
devfs_root_dentry->dir_inode->attribute = VFS_IF_DIR;
|
||||
}
|
||||
/**
|
||||
* @brief 初始化devfs的根dentry
|
||||
@ -251,7 +252,6 @@ void devfs_init()
|
||||
vfs_register_filesystem(&devfs_fs_type);
|
||||
vfs_mount_fs(__devfs_mount_path, "DEVFS", NULL);
|
||||
|
||||
|
||||
__devfs_chardev_init();
|
||||
|
||||
// todo: 当rootfs实现后,将ps/2键盘的注册改为在驱动程序中进行(目前没有rootfs,因此还不能在不依赖fat32的情况下,挂载设备)
|
||||
|
@ -58,7 +58,7 @@ static inline struct vfs_dir_entry_t *__devfs_find_dentry(struct vfs_dir_entry_t
|
||||
static inline struct vfs_dir_entry_t *__devfs_find_dir(struct vfs_dir_entry_t *parent_dentry, const char *name)
|
||||
{
|
||||
struct vfs_dir_entry_t *target_dent = __devfs_find_dentry(parent_dentry, name);
|
||||
if (target_dent->dir_inode->attribute & VFS_ATTR_DIR) // 名称相符且为目录,则返回dentry
|
||||
if (target_dent->dir_inode->attribute & VFS_IF_DIR) // 名称相符且为目录,则返回dentry
|
||||
return target_dent;
|
||||
else
|
||||
return NULL; // 否则直接返回空
|
||||
|
@ -293,7 +293,7 @@ find_lookup_success:; // 找到目标dentry
|
||||
p->file_size = tmp_dEntry->DIR_FileSize;
|
||||
// 计算文件占用的扇区数, 由于最小存储单位是簇,因此需要按照簇的大小来对齐扇区
|
||||
p->blocks = (p->file_size + fsbi->bytes_per_clus - 1) / fsbi->bytes_per_sec;
|
||||
p->attribute = (tmp_dEntry->DIR_Attr & ATTR_DIRECTORY) ? VFS_ATTR_DIR : VFS_ATTR_FILE;
|
||||
p->attribute = (tmp_dEntry->DIR_Attr & ATTR_DIRECTORY) ? VFS_IF_DIR : VFS_IF_FILE;
|
||||
p->sb = parent_inode->sb;
|
||||
p->file_ops = &fat32_file_ops;
|
||||
p->inode_ops = &fat32_inode_ops;
|
||||
@ -315,8 +315,8 @@ find_lookup_success:; // 找到目标dentry
|
||||
|
||||
// 暂时使用fat32的高4bit来标志设备文件
|
||||
// todo: 引入devfs后删除这段代码
|
||||
if ((tmp_dEntry->DIR_FstClusHI >> 12) && (p->attribute & VFS_ATTR_FILE))
|
||||
p->attribute |= VFS_ATTR_DEVICE;
|
||||
if ((tmp_dEntry->DIR_FstClusHI >> 12) && (p->attribute & VFS_IF_FILE))
|
||||
p->attribute |= VFS_IF_DEVICE;
|
||||
|
||||
dest_dentry->dir_inode = p;
|
||||
dest_dentry->dir_ops = &fat32_dEntry_ops;
|
||||
@ -394,7 +394,7 @@ struct vfs_superblock_t *fat32_read_superblock(struct block_device *blk)
|
||||
sb_ptr->root->dir_inode->file_size = 0;
|
||||
// 计算文件占用的扇区数, 由于最小存储单位是簇,因此需要按照簇的大小来对齐扇区
|
||||
sb_ptr->root->dir_inode->blocks = (sb_ptr->root->dir_inode->file_size + fsbi->bytes_per_clus - 1) / fsbi->bytes_per_sec;
|
||||
sb_ptr->root->dir_inode->attribute = VFS_ATTR_DIR;
|
||||
sb_ptr->root->dir_inode->attribute = VFS_IF_DIR;
|
||||
sb_ptr->root->dir_inode->sb = sb_ptr; // 反向绑定对应的超级块
|
||||
|
||||
// 初始化inode信息
|
||||
@ -826,7 +826,7 @@ long fat32_create(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t
|
||||
|
||||
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));
|
||||
inode->attribute = VFS_ATTR_FILE;
|
||||
inode->attribute = VFS_IF_FILE;
|
||||
inode->file_ops = &fat32_file_ops;
|
||||
inode->file_size = 0;
|
||||
inode->sb = parent_inode->sb;
|
||||
@ -933,7 +933,7 @@ int64_t fat32_mkdir(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_
|
||||
// ====== 初始化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));
|
||||
inode->attribute = VFS_ATTR_DIR;
|
||||
inode->attribute = VFS_IF_DIR;
|
||||
inode->blocks = fsbi->sec_per_clus;
|
||||
inode->file_ops = &fat32_file_ops;
|
||||
inode->file_size = 0;
|
||||
@ -1230,9 +1230,9 @@ find_dir_success:;
|
||||
file_ptr->position += 32;
|
||||
// todo: 计算ino_t
|
||||
if (dentry_type & ATTR_DIRECTORY)
|
||||
dentry_type = VFS_ATTR_DIR;
|
||||
dentry_type = VFS_IF_DIR;
|
||||
else
|
||||
dentry_type = VFS_ATTR_FILE;
|
||||
dentry_type = VFS_IF_FILE;
|
||||
|
||||
return filler(dirent, 0, dir_name, name_len, dentry_type, 0);
|
||||
}
|
||||
|
@ -335,7 +335,7 @@ void fat32_fill_shortname(struct vfs_dir_entry_t *dEntry, struct fat32_Directory
|
||||
target->DIR_Name[tmp_index] = 0x20;
|
||||
++tmp_index;
|
||||
}
|
||||
if (dEntry->dir_inode->attribute & VFS_ATTR_DIR)
|
||||
if (dEntry->dir_inode->attribute & VFS_IF_DIR)
|
||||
{
|
||||
while (tmp_index < 11)
|
||||
{
|
||||
@ -355,7 +355,7 @@ void fat32_fill_shortname(struct vfs_dir_entry_t *dEntry, struct fat32_Directory
|
||||
|
||||
struct vfs_index_node_t *inode = dEntry->dir_inode;
|
||||
target->DIR_Attr = 0;
|
||||
if (inode->attribute & VFS_ATTR_DIR)
|
||||
if (inode->attribute & VFS_IF_DIR)
|
||||
target->DIR_Attr |= ATTR_DIRECTORY;
|
||||
|
||||
target->DIR_FileSize = dEntry->dir_inode->file_size;
|
||||
|
@ -154,7 +154,7 @@ struct vfs_file_t *process_open_exec_file(char *path)
|
||||
if (dentry == NULL)
|
||||
return (void *)-ENOENT;
|
||||
|
||||
if (dentry->dir_inode->attribute == VFS_ATTR_DIR)
|
||||
if (dentry->dir_inode->attribute == VFS_IF_DIR)
|
||||
return (void *)-ENOTDIR;
|
||||
|
||||
filp = (struct vfs_file_t *)kmalloc(sizeof(struct vfs_file_t), 0);
|
||||
|
@ -19,6 +19,7 @@ extern void syscall_int(void);
|
||||
extern uint64_t sys_clock(struct pt_regs *regs);
|
||||
extern uint64_t sys_mstat(struct pt_regs *regs);
|
||||
extern uint64_t sys_open(struct pt_regs *regs);
|
||||
extern uint64_t sys_rmdir(struct pt_regs *regs);
|
||||
|
||||
/**
|
||||
* @brief 导出系统调用处理函数的符号
|
||||
@ -415,7 +416,7 @@ uint64_t sys_chdir(struct pt_regs *regs)
|
||||
return -ENOENT;
|
||||
// kdebug("dentry->name=%s, namelen=%d", dentry->name, dentry->name_length);
|
||||
// 目标不是目录
|
||||
if (dentry->dir_inode->attribute != VFS_ATTR_DIR)
|
||||
if (dentry->dir_inode->attribute != VFS_IF_DIR)
|
||||
return -ENOTDIR;
|
||||
|
||||
return 0;
|
||||
@ -602,5 +603,6 @@ system_call_t system_call_table[MAX_SYSTEM_CALL_NUM] =
|
||||
[19] = sys_clock,
|
||||
[20] = sys_pipe,
|
||||
[21] = sys_mstat,
|
||||
[22 ... 254] = system_call_not_exists,
|
||||
[22] = sys_rmdir,
|
||||
[23 ... 254] = system_call_not_exists,
|
||||
[255] = sys_ahci_end_req};
|
||||
|
@ -15,6 +15,11 @@ extern void ret_from_system_call(void); // 导出从系统调用返回的函数
|
||||
|
||||
extern system_call_t system_call_table[MAX_SYSTEM_CALL_NUM];
|
||||
|
||||
// 判断系统调用是否来自用户态
|
||||
#define SYSCALL_FROM_USER(regs) ((regs)->cs & USER_CS)
|
||||
// 判断系统调用是否来自内核态
|
||||
#define SYSCALL_FROM_KERNEL(regs) (!SYSCALL_FROM_USER(regs))
|
||||
|
||||
/**
|
||||
* @brief 初始化系统调用模块
|
||||
*
|
||||
|
@ -33,6 +33,7 @@
|
||||
#define SYS_PIPE 20
|
||||
|
||||
#define SYS_MSTAT 21 // 获取系统的内存状态信息
|
||||
#define SYS_RMDIR 22 // 删除文件夹
|
||||
|
||||
|
||||
#define SYS_AHCI_END_REQ 255 // AHCI DMA请求结束end_request的系统调用
|
@ -210,7 +210,7 @@ int shell_cmd_cd(int argc, char **argv)
|
||||
new_path[current_dir_len] = '/';
|
||||
strcat(new_path, argv[1] + dest_offset);
|
||||
int x = chdir(new_path);
|
||||
|
||||
|
||||
if (x == 0) // 成功切换目录
|
||||
{
|
||||
free(shell_current_path);
|
||||
@ -257,12 +257,12 @@ int shell_cmd_ls(int argc, char **argv)
|
||||
break;
|
||||
|
||||
int color = COLOR_WHITE;
|
||||
if (buf->d_type & VFS_ATTR_DIR)
|
||||
if (buf->d_type & VFS_IF_DIR)
|
||||
color = COLOR_YELLOW;
|
||||
else if (buf->d_type & VFS_ATTR_FILE)
|
||||
else if (buf->d_type & VFS_IF_FILE)
|
||||
color = COLOR_INDIGO;
|
||||
else if(buf->d_type & VFS_ATTR_DEVICE)
|
||||
color= COLOR_GREEN;
|
||||
else if (buf->d_type & VFS_IF_DEVICE)
|
||||
color = COLOR_GREEN;
|
||||
|
||||
char output_buf[256] = {0};
|
||||
|
||||
@ -405,7 +405,21 @@ int shell_cmd_mkdir(int argc, char **argv)
|
||||
* @return int
|
||||
*/
|
||||
// todo:
|
||||
int shell_cmd_rmdir(int argc, char **argv) {}
|
||||
int shell_cmd_rmdir(int argc, char **argv)
|
||||
{
|
||||
const char *full_path = NULL;
|
||||
int result_path_len = -1;
|
||||
if (argv[1][0] == '/')
|
||||
full_path = argv[1];
|
||||
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);
|
||||
if (argv != NULL)
|
||||
free(argv);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 执行新的程序的命令
|
||||
@ -483,7 +497,7 @@ int shell_cmd_free(int argc, char **argv)
|
||||
|
||||
struct mstat_t mst = {0};
|
||||
retval = mstat(&mst);
|
||||
if(retval!=0)
|
||||
if (retval != 0)
|
||||
{
|
||||
printf("Failed: retval=%d", retval);
|
||||
goto done;
|
||||
@ -491,15 +505,15 @@ int shell_cmd_free(int argc, char **argv)
|
||||
|
||||
printf("\ttotal\tused\tfree\tshared\tcache\tavailable\n");
|
||||
printf("Mem:\t");
|
||||
if(argc==1) // 按照kb显示
|
||||
if (argc == 1) // 按照kb显示
|
||||
{
|
||||
printf("%ld\t%ld\t%ld\t%ld\t%ld\t%ld\t\n", mst.total>>10,mst.used>>10,mst.free>>10, mst.shared>>10, mst.cache_used>>10, mst.available>>10);
|
||||
printf("%ld\t%ld\t%ld\t%ld\t%ld\t%ld\t\n", mst.total >> 10, mst.used >> 10, mst.free >> 10, mst.shared >> 10, mst.cache_used >> 10, mst.available >> 10);
|
||||
}
|
||||
else // 按照MB显示
|
||||
else // 按照MB显示
|
||||
{
|
||||
printf("%ld\t%ld\t%ld\t%ld\t%ld\t%ld\t\n", mst.total>>20,mst.used>>20,mst.free>>20, mst.shared>>20, mst.cache_used>>20, mst.available>>20);
|
||||
printf("%ld\t%ld\t%ld\t%ld\t%ld\t%ld\t\n", mst.total >> 20, mst.used >> 20, mst.free >> 20, mst.shared >> 20, mst.cache_used >> 20, mst.available >> 20);
|
||||
}
|
||||
|
||||
|
||||
done:;
|
||||
if (argv != NULL)
|
||||
free(argv);
|
||||
|
@ -3,12 +3,12 @@
|
||||
|
||||
|
||||
/**
|
||||
* @brief 目录项的属性(copy from vfs.h)
|
||||
* @brief inode的属性(copy from vfs.h)
|
||||
*
|
||||
*/
|
||||
#define VFS_ATTR_FILE (1UL << 0)
|
||||
#define VFS_ATTR_DIR (1UL << 1)
|
||||
#define VFS_ATTR_DEVICE (1UL << 2)
|
||||
#define VFS_IF_FILE (1UL << 0)
|
||||
#define VFS_IF_DIR (1UL << 1)
|
||||
#define VFS_IF_DEVICE (1UL << 2)
|
||||
|
||||
#define DIR_BUF_SIZE 256
|
||||
/**
|
||||
|
@ -142,7 +142,19 @@ int execv(const char *path, char *const argv[])
|
||||
return -1;
|
||||
}
|
||||
int retval = syscall_invoke(SYS_EXECVE, (uint64_t)path, (uint64_t)argv, 0, 0, 0, 0, 0, 0);
|
||||
if(retval != 0)
|
||||
if (retval != 0)
|
||||
return -1;
|
||||
else return 0;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 删除文件夹
|
||||
*
|
||||
* @param path 绝对路径
|
||||
* @return int 错误码
|
||||
*/
|
||||
int rmdir(const char *path)
|
||||
{
|
||||
return syscall_invoke(SYS_RMDIR, (uint64_t)path, 0, 0, 0, 0, 0, 0, 0);
|
||||
}
|
@ -97,3 +97,11 @@ int execv(const char* path, char * const argv[]);
|
||||
* @return int
|
||||
*/
|
||||
extern int usleep(useconds_t usec);
|
||||
|
||||
/**
|
||||
* @brief 删除文件夹
|
||||
*
|
||||
* @param path 绝对路径
|
||||
* @return int 错误码
|
||||
*/
|
||||
int rmdir(const char* path);
|
@ -27,6 +27,7 @@
|
||||
#define SYS_PIPE 20
|
||||
|
||||
#define SYS_MSTAT 21 // 获取系统的内存状态信息
|
||||
#define SYS_RMDIR 22 // 删除文件夹
|
||||
|
||||
/**
|
||||
* @brief 用户态系统调用函数
|
||||
|
Loading…
x
Reference in New Issue
Block a user