mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 07:06: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",
|
"limits.h": "c",
|
||||||
"block.h": "c",
|
"block.h": "c",
|
||||||
"blk_types.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",
|
"C_Cpp.errorSquiggles": "Enabled",
|
||||||
"esbonio.sphinx.confDir": ""
|
"esbonio.sphinx.confDir": ""
|
||||||
|
@ -173,11 +173,11 @@ struct vfs_index_node_t
|
|||||||
|
|
||||||
  inode的属性。可选值如下:
|
  inode的属性。可选值如下:
|
||||||
|
|
||||||
> - VFS_ATTR_FILE
|
> - VFS_IF_FILE
|
||||||
>
|
>
|
||||||
> - VFS_ATTR_DIR
|
> - VFS_IF_DIR
|
||||||
>
|
>
|
||||||
> - VFS_ATTR_DEVICE
|
> - VFS_IF_DEVICE
|
||||||
|
|
||||||
**sb**
|
**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 push_options
|
||||||
#pragma GCC optimize("O0")
|
#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时输出警告信息
|
* @brief 当condition为true时输出警告信息
|
||||||
*
|
*
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#include "VFS.h"
|
#include "VFS.h"
|
||||||
#include "mount.h"
|
#include "mount.h"
|
||||||
|
#include "internal.h"
|
||||||
#include <common/kprint.h>
|
#include <common/kprint.h>
|
||||||
|
#include <debug/bug.h>
|
||||||
#include <common/dirent.h>
|
#include <common/dirent.h>
|
||||||
#include <common/string.h>
|
#include <common/string.h>
|
||||||
#include <common/errno.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);
|
struct vfs_superblock_t *sb = p->read_superblock(blk);
|
||||||
if (strcmp(path, "/") == 0) // 如果挂载到的是'/'挂载点,则让其成为最顶层的文件系统
|
if (strcmp(path, "/") == 0) // 如果挂载到的是'/'挂载点,则让其成为最顶层的文件系统
|
||||||
|
{
|
||||||
vfs_root_sb = sb;
|
vfs_root_sb = sb;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
kdebug("to mount %s", name);
|
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
|
// 如果没有找到dentry缓存,则申请新的dentry
|
||||||
if (dentry == NULL)
|
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);
|
memcpy(dentry->name, (void *)tmp_path, tmp_path_len);
|
||||||
dentry->name[tmp_path_len] = '\0';
|
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 创建文件夹
|
* @brief 创建文件夹
|
||||||
*
|
*
|
||||||
* @param path 文件夹路径
|
* @param path 文件夹路径
|
||||||
* @param mode 创建模式
|
* @param mode 创建模式
|
||||||
* @param from_userland 该创建请求是否来自用户态
|
* @param from_userland 该创建请求是否来自用户态
|
||||||
* @return int64_t 错误码
|
* @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;
|
uint32_t pathlen;
|
||||||
if (from_userland)
|
if (from_userland)
|
||||||
@ -267,10 +271,9 @@ int64_t vfs_mkdir(const char* path, mode_t mode, bool from_userland)
|
|||||||
|
|
||||||
// 路径格式不合法(必须使用绝对路径)
|
// 路径格式不合法(必须使用绝对路径)
|
||||||
if (last_slash < 0)
|
if (last_slash < 0)
|
||||||
return ENOTDIR;
|
return -ENOTDIR;
|
||||||
|
|
||||||
char *buf = (char *)kmalloc(last_slash + 1, 0);
|
char *buf = (char *)kzalloc(last_slash + 2, 0);
|
||||||
memset(buf, 0, pathlen + 1);
|
|
||||||
|
|
||||||
// 拷贝字符串(不包含要被创建的部分)
|
// 拷贝字符串(不包含要被创建的部分)
|
||||||
if (from_userland)
|
if (from_userland)
|
||||||
@ -341,13 +344,12 @@ uint64_t sys_mkdir(struct pt_regs *regs)
|
|||||||
return vfs_mkdir(path, mode, true);
|
return vfs_mkdir(path, mode, true);
|
||||||
else
|
else
|
||||||
return vfs_mkdir(path, mode, false);
|
return vfs_mkdir(path, mode, false);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 打开文件
|
* @brief 打开文件
|
||||||
*
|
*
|
||||||
* @param filename 文件路径
|
* @param filename 文件路径
|
||||||
* @param flags 标志位
|
* @param flags 标志位
|
||||||
* @return uint64_t 错误码
|
* @return uint64_t 错误码
|
||||||
*/
|
*/
|
||||||
@ -445,23 +447,23 @@ uint64_t do_open(const char *filename, int flags)
|
|||||||
return -ENOENT;
|
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;
|
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;
|
// return -EISDIR;
|
||||||
|
|
||||||
// // todo: 引入devfs后删除这段代码
|
// // todo: 引入devfs后删除这段代码
|
||||||
// // 暂时遇到设备文件的话,就将其first clus设置为特定值
|
// // 暂时遇到设备文件的话,就将其first clus设置为特定值
|
||||||
// if (path_len >= 5 && filename[0] == '/' && filename[1] == 'd' && filename[2] == 'e' && filename[3] == 'v' && filename[4] == '/')
|
// 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文件系统上面的设备文件,设置其起始扇区
|
// // 对于fat32文件系统上面的设备文件,设置其起始扇区
|
||||||
// ((struct fat32_inode_info_t *)(dentry->dir_inode->private_inode_info))->first_clus |= 0xf0000000;
|
// ((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->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;
|
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
|
* @brief 初始化vfs
|
||||||
*
|
*
|
||||||
|
@ -28,12 +28,13 @@ extern struct vfs_superblock_t *vfs_root_sb;
|
|||||||
#define VFS_MAX_PATHLEN 1024
|
#define VFS_MAX_PATHLEN 1024
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 目录项的属性
|
* @brief inode的属性
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#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)
|
||||||
|
#define VFS_IF_DEAD (1UL<<3) /* removed, but still open directory */
|
||||||
|
|
||||||
struct vfs_super_block_operations_t;
|
struct vfs_super_block_operations_t;
|
||||||
struct vfs_inode_operations_t;
|
struct vfs_inode_operations_t;
|
||||||
@ -41,10 +42,13 @@ struct vfs_inode_operations_t;
|
|||||||
struct vfs_index_node_t;
|
struct vfs_index_node_t;
|
||||||
struct vfs_dir_entry_operations_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
|
struct vfs_dir_entry_t
|
||||||
{
|
{
|
||||||
char *name;
|
char *name;
|
||||||
int name_length;
|
int name_length;
|
||||||
|
uint32_t d_flags; // dentry标志位
|
||||||
struct List child_node_list;
|
struct List child_node_list;
|
||||||
struct List subdirs_list;
|
struct List subdirs_list;
|
||||||
|
|
||||||
@ -218,8 +222,8 @@ struct vfs_dir_entry_t *vfs_alloc_dentry(const int name_size);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 打开文件
|
* @brief 打开文件
|
||||||
*
|
*
|
||||||
* @param filename 文件路径
|
* @param filename 文件路径
|
||||||
* @param flags 标志位
|
* @param flags 标志位
|
||||||
* @return uint64_t 错误码
|
* @return uint64_t 错误码
|
||||||
*/
|
*/
|
||||||
@ -227,10 +231,19 @@ uint64_t do_open(const char *filename, int flags);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 创建文件夹
|
* @brief 创建文件夹
|
||||||
*
|
*
|
||||||
* @param path 文件夹路径
|
* @param path 文件夹路径
|
||||||
* @param mode 创建模式
|
* @param mode 创建模式
|
||||||
* @param from_userland 该创建请求是否来自用户态
|
* @param from_userland 该创建请求是否来自用户态
|
||||||
* @return int64_t 错误码
|
* @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);
|
list_init(&mp->mnt_list);
|
||||||
mp->dentry = old_dentry;
|
mp->dentry = old_dentry;
|
||||||
mp->parent_dentry = old_dentry->parent;
|
mp->parent_dentry = old_dentry->parent;
|
||||||
|
|
||||||
// kdebug("&new_dentry->name=%#018lx, &old_dentry->name=%#018lx", &new_dentry->name, &old_dentry->name);
|
// 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);
|
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->child_node_list);
|
||||||
list_init(&new_dentry->subdirs_list);
|
list_init(&new_dentry->subdirs_list);
|
||||||
new_dentry->parent = old_dentry->parent;
|
new_dentry->parent = old_dentry->parent;
|
||||||
|
|
||||||
|
|
||||||
// 将新的dentry的list结点替换掉父dentry的列表中的old_dentry的list结点
|
// 将新的dentry的list结点替换掉父dentry的列表中的old_dentry的list结点
|
||||||
list_replace(&old_dentry->child_node_list, &new_dentry->child_node_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 取消某个文件系统的挂载
|
* @brief 取消某个文件系统的挂载
|
||||||
*
|
*
|
||||||
* @param dentry 对应文件系统的根dentry
|
* @param dentry 对应文件系统的根dentry
|
||||||
* @return int 错误码
|
* @return int 错误码
|
||||||
*/
|
*/
|
||||||
int do_umount(struct vfs_dir_entry_t* dentry)
|
int do_umount(struct vfs_dir_entry_t *dentry)
|
||||||
{
|
{
|
||||||
// todo: 实现umount(主要是结点的恢复问题)
|
// todo: 实现umount(主要是结点的恢复问题)
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <common/glib.h>
|
#include <common/glib.h>
|
||||||
|
#include "VFS.h"
|
||||||
/**
|
/**
|
||||||
* @brief 挂载点结构体(用来表示dentry被挂载其他文件系统之后,原先存在的数据)
|
* @brief 挂载点结构体(用来表示dentry被挂载其他文件系统之后,原先存在的数据)
|
||||||
*
|
*
|
||||||
@ -30,8 +30,31 @@ int do_mount(struct vfs_dir_entry_t *old_dentry, struct vfs_dir_entry_t *new_den
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 取消某个文件系统的挂载
|
* @brief 取消某个文件系统的挂载
|
||||||
*
|
*
|
||||||
* @param dentry 对应文件系统的根dentry
|
* @param dentry 对应文件系统的根dentry
|
||||||
* @return int 错误码
|
* @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);
|
struct vfs_dir_entry_t *dentry = vfs_alloc_dentry(namelen + 1);
|
||||||
__devfs_fill_dentry(dentry, devname);
|
__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文件夹下
|
// 将dentry挂载到char文件夹下
|
||||||
__devfs_dentry_bind_parent(chardev_folder_dentry, dentry);
|
__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;
|
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 =
|
struct vfs_super_block_operations_t devfs_sb_ops =
|
||||||
{
|
{
|
||||||
.write_superblock = &devfs_write_superblock,
|
.write_superblock = &devfs_write_superblock,
|
||||||
@ -45,13 +45,13 @@ struct vfs_super_block_operations_t devfs_sb_ops =
|
|||||||
.write_inode = &devfs_write_inode,
|
.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 =
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
static long devfs_close(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr) {}
|
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) {}
|
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) {}
|
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) {}
|
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_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)
|
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);
|
char *name = (char *)kzalloc(target_dent->name_length + 1, 0);
|
||||||
strncpy(name, target_dent->name, target_dent->name_length);
|
strncpy(name, target_dent->name, target_dent->name_length);
|
||||||
uint32_t dentry_type;
|
uint32_t dentry_type;
|
||||||
if (target_dent->dir_inode->attribute & VFS_ATTR_DIR)
|
if (target_dent->dir_inode->attribute & VFS_IF_DIR)
|
||||||
dentry_type = VFS_ATTR_DIR;
|
dentry_type = VFS_IF_DIR;
|
||||||
else
|
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);
|
return filler(dirent, file_ptr->position - 1, name, target_dent->name_length, dentry_type, file_ptr->position - 1);
|
||||||
failed:;
|
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)
|
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)
|
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 = (struct vfs_index_node_t *)kzalloc(sizeof(struct vfs_index_node_t), 0);
|
||||||
dEntry->dir_inode->file_ops = &devfs_file_ops;
|
dEntry->dir_inode->file_ops = &devfs_file_ops;
|
||||||
dEntry->dir_inode->inode_ops = &devfs_inode_ops;
|
dEntry->dir_inode->inode_ops = &devfs_inode_ops;
|
||||||
|
dEntry->dir_ops = &devfs_dentry_ops;
|
||||||
// todo: 增加private inode info
|
// todo: 增加private inode info
|
||||||
dEntry->dir_inode->private_inode_info = NULL;
|
dEntry->dir_inode->private_inode_info = NULL;
|
||||||
dEntry->dir_inode->sb = &devfs_sb;
|
dEntry->dir_inode->sb = &devfs_sb;
|
||||||
dEntry->dir_inode->attribute = VFS_ATTR_DIR;
|
dEntry->dir_inode->attribute = VFS_IF_DIR;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static long devfs_rmdir(struct vfs_index_node_t *inode, struct vfs_dir_entry_t *dEntry) {}
|
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) {}
|
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) {}
|
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) {}
|
static long devfs_setAttr(struct vfs_dir_entry_t *dEntry, uint64_t *attr) {return 0; }
|
||||||
struct vfs_inode_operations_t devfs_inode_ops = {
|
struct vfs_inode_operations_t devfs_inode_ops = {
|
||||||
.create = &devfs_create,
|
.create = &devfs_create,
|
||||||
.lookup = &devfs_lookup,
|
.lookup = &devfs_lookup,
|
||||||
@ -187,7 +188,7 @@ static __always_inline void __devfs_init_root_inode()
|
|||||||
// todo: 增加private inode info
|
// todo: 增加private inode info
|
||||||
devfs_root_dentry->dir_inode->private_inode_info = NULL;
|
devfs_root_dentry->dir_inode->private_inode_info = NULL;
|
||||||
devfs_root_dentry->dir_inode->sb = &devfs_sb;
|
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
|
* @brief 初始化devfs的根dentry
|
||||||
@ -251,7 +252,6 @@ void devfs_init()
|
|||||||
vfs_register_filesystem(&devfs_fs_type);
|
vfs_register_filesystem(&devfs_fs_type);
|
||||||
vfs_mount_fs(__devfs_mount_path, "DEVFS", NULL);
|
vfs_mount_fs(__devfs_mount_path, "DEVFS", NULL);
|
||||||
|
|
||||||
|
|
||||||
__devfs_chardev_init();
|
__devfs_chardev_init();
|
||||||
|
|
||||||
// todo: 当rootfs实现后,将ps/2键盘的注册改为在驱动程序中进行(目前没有rootfs,因此还不能在不依赖fat32的情况下,挂载设备)
|
// 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)
|
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);
|
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;
|
return target_dent;
|
||||||
else
|
else
|
||||||
return NULL; // 否则直接返回空
|
return NULL; // 否则直接返回空
|
||||||
|
@ -293,7 +293,7 @@ find_lookup_success:; // 找到目标dentry
|
|||||||
p->file_size = tmp_dEntry->DIR_FileSize;
|
p->file_size = tmp_dEntry->DIR_FileSize;
|
||||||
// 计算文件占用的扇区数, 由于最小存储单位是簇,因此需要按照簇的大小来对齐扇区
|
// 计算文件占用的扇区数, 由于最小存储单位是簇,因此需要按照簇的大小来对齐扇区
|
||||||
p->blocks = (p->file_size + fsbi->bytes_per_clus - 1) / fsbi->bytes_per_sec;
|
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->sb = parent_inode->sb;
|
||||||
p->file_ops = &fat32_file_ops;
|
p->file_ops = &fat32_file_ops;
|
||||||
p->inode_ops = &fat32_inode_ops;
|
p->inode_ops = &fat32_inode_ops;
|
||||||
@ -315,8 +315,8 @@ find_lookup_success:; // 找到目标dentry
|
|||||||
|
|
||||||
// 暂时使用fat32的高4bit来标志设备文件
|
// 暂时使用fat32的高4bit来标志设备文件
|
||||||
// todo: 引入devfs后删除这段代码
|
// todo: 引入devfs后删除这段代码
|
||||||
if ((tmp_dEntry->DIR_FstClusHI >> 12) && (p->attribute & VFS_ATTR_FILE))
|
if ((tmp_dEntry->DIR_FstClusHI >> 12) && (p->attribute & VFS_IF_FILE))
|
||||||
p->attribute |= VFS_ATTR_DEVICE;
|
p->attribute |= VFS_IF_DEVICE;
|
||||||
|
|
||||||
dest_dentry->dir_inode = p;
|
dest_dentry->dir_inode = p;
|
||||||
dest_dentry->dir_ops = &fat32_dEntry_ops;
|
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->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->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; // 反向绑定对应的超级块
|
sb_ptr->root->dir_inode->sb = sb_ptr; // 反向绑定对应的超级块
|
||||||
|
|
||||||
// 初始化inode信息
|
// 初始化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);
|
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));
|
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_ops = &fat32_file_ops;
|
||||||
inode->file_size = 0;
|
inode->file_size = 0;
|
||||||
inode->sb = parent_inode->sb;
|
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 =======
|
// ====== 初始化inode =======
|
||||||
struct vfs_index_node_t *inode = (struct vfs_index_node_t *)kmalloc(sizeof(struct vfs_index_node_t), 0);
|
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));
|
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->blocks = fsbi->sec_per_clus;
|
||||||
inode->file_ops = &fat32_file_ops;
|
inode->file_ops = &fat32_file_ops;
|
||||||
inode->file_size = 0;
|
inode->file_size = 0;
|
||||||
@ -1230,9 +1230,9 @@ find_dir_success:;
|
|||||||
file_ptr->position += 32;
|
file_ptr->position += 32;
|
||||||
// todo: 计算ino_t
|
// todo: 计算ino_t
|
||||||
if (dentry_type & ATTR_DIRECTORY)
|
if (dentry_type & ATTR_DIRECTORY)
|
||||||
dentry_type = VFS_ATTR_DIR;
|
dentry_type = VFS_IF_DIR;
|
||||||
else
|
else
|
||||||
dentry_type = VFS_ATTR_FILE;
|
dentry_type = VFS_IF_FILE;
|
||||||
|
|
||||||
return filler(dirent, 0, dir_name, name_len, dentry_type, 0);
|
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;
|
target->DIR_Name[tmp_index] = 0x20;
|
||||||
++tmp_index;
|
++tmp_index;
|
||||||
}
|
}
|
||||||
if (dEntry->dir_inode->attribute & VFS_ATTR_DIR)
|
if (dEntry->dir_inode->attribute & VFS_IF_DIR)
|
||||||
{
|
{
|
||||||
while (tmp_index < 11)
|
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;
|
struct vfs_index_node_t *inode = dEntry->dir_inode;
|
||||||
target->DIR_Attr = 0;
|
target->DIR_Attr = 0;
|
||||||
if (inode->attribute & VFS_ATTR_DIR)
|
if (inode->attribute & VFS_IF_DIR)
|
||||||
target->DIR_Attr |= ATTR_DIRECTORY;
|
target->DIR_Attr |= ATTR_DIRECTORY;
|
||||||
|
|
||||||
target->DIR_FileSize = dEntry->dir_inode->file_size;
|
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)
|
if (dentry == NULL)
|
||||||
return (void *)-ENOENT;
|
return (void *)-ENOENT;
|
||||||
|
|
||||||
if (dentry->dir_inode->attribute == VFS_ATTR_DIR)
|
if (dentry->dir_inode->attribute == VFS_IF_DIR)
|
||||||
return (void *)-ENOTDIR;
|
return (void *)-ENOTDIR;
|
||||||
|
|
||||||
filp = (struct vfs_file_t *)kmalloc(sizeof(struct vfs_file_t), 0);
|
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_clock(struct pt_regs *regs);
|
||||||
extern uint64_t sys_mstat(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_open(struct pt_regs *regs);
|
||||||
|
extern uint64_t sys_rmdir(struct pt_regs *regs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 导出系统调用处理函数的符号
|
* @brief 导出系统调用处理函数的符号
|
||||||
@ -415,7 +416,7 @@ uint64_t sys_chdir(struct pt_regs *regs)
|
|||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
// kdebug("dentry->name=%s, namelen=%d", dentry->name, dentry->name_length);
|
// 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 -ENOTDIR;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -602,5 +603,6 @@ system_call_t system_call_table[MAX_SYSTEM_CALL_NUM] =
|
|||||||
[19] = sys_clock,
|
[19] = sys_clock,
|
||||||
[20] = sys_pipe,
|
[20] = sys_pipe,
|
||||||
[21] = sys_mstat,
|
[21] = sys_mstat,
|
||||||
[22 ... 254] = system_call_not_exists,
|
[22] = sys_rmdir,
|
||||||
|
[23 ... 254] = system_call_not_exists,
|
||||||
[255] = sys_ahci_end_req};
|
[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];
|
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 初始化系统调用模块
|
* @brief 初始化系统调用模块
|
||||||
*
|
*
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#define SYS_PIPE 20
|
#define SYS_PIPE 20
|
||||||
|
|
||||||
#define SYS_MSTAT 21 // 获取系统的内存状态信息
|
#define SYS_MSTAT 21 // 获取系统的内存状态信息
|
||||||
|
#define SYS_RMDIR 22 // 删除文件夹
|
||||||
|
|
||||||
|
|
||||||
#define SYS_AHCI_END_REQ 255 // AHCI DMA请求结束end_request的系统调用
|
#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] = '/';
|
new_path[current_dir_len] = '/';
|
||||||
strcat(new_path, argv[1] + dest_offset);
|
strcat(new_path, argv[1] + dest_offset);
|
||||||
int x = chdir(new_path);
|
int x = chdir(new_path);
|
||||||
|
|
||||||
if (x == 0) // 成功切换目录
|
if (x == 0) // 成功切换目录
|
||||||
{
|
{
|
||||||
free(shell_current_path);
|
free(shell_current_path);
|
||||||
@ -257,12 +257,12 @@ int shell_cmd_ls(int argc, char **argv)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
int color = COLOR_WHITE;
|
int color = COLOR_WHITE;
|
||||||
if (buf->d_type & VFS_ATTR_DIR)
|
if (buf->d_type & VFS_IF_DIR)
|
||||||
color = COLOR_YELLOW;
|
color = COLOR_YELLOW;
|
||||||
else if (buf->d_type & VFS_ATTR_FILE)
|
else if (buf->d_type & VFS_IF_FILE)
|
||||||
color = COLOR_INDIGO;
|
color = COLOR_INDIGO;
|
||||||
else if(buf->d_type & VFS_ATTR_DEVICE)
|
else if (buf->d_type & VFS_IF_DEVICE)
|
||||||
color= COLOR_GREEN;
|
color = COLOR_GREEN;
|
||||||
|
|
||||||
char output_buf[256] = {0};
|
char output_buf[256] = {0};
|
||||||
|
|
||||||
@ -405,7 +405,21 @@ int shell_cmd_mkdir(int argc, char **argv)
|
|||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
// todo:
|
// 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 执行新的程序的命令
|
* @brief 执行新的程序的命令
|
||||||
@ -483,7 +497,7 @@ int shell_cmd_free(int argc, char **argv)
|
|||||||
|
|
||||||
struct mstat_t mst = {0};
|
struct mstat_t mst = {0};
|
||||||
retval = mstat(&mst);
|
retval = mstat(&mst);
|
||||||
if(retval!=0)
|
if (retval != 0)
|
||||||
{
|
{
|
||||||
printf("Failed: retval=%d", retval);
|
printf("Failed: retval=%d", retval);
|
||||||
goto done;
|
goto done;
|
||||||
@ -491,15 +505,15 @@ int shell_cmd_free(int argc, char **argv)
|
|||||||
|
|
||||||
printf("\ttotal\tused\tfree\tshared\tcache\tavailable\n");
|
printf("\ttotal\tused\tfree\tshared\tcache\tavailable\n");
|
||||||
printf("Mem:\t");
|
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:;
|
done:;
|
||||||
if (argv != NULL)
|
if (argv != NULL)
|
||||||
free(argv);
|
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_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)
|
||||||
|
|
||||||
#define DIR_BUF_SIZE 256
|
#define DIR_BUF_SIZE 256
|
||||||
/**
|
/**
|
||||||
|
@ -142,7 +142,19 @@ int execv(const char *path, char *const argv[])
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int retval = syscall_invoke(SYS_EXECVE, (uint64_t)path, (uint64_t)argv, 0, 0, 0, 0, 0, 0);
|
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;
|
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
|
* @return int
|
||||||
*/
|
*/
|
||||||
extern int usleep(useconds_t usec);
|
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_PIPE 20
|
||||||
|
|
||||||
#define SYS_MSTAT 21 // 获取系统的内存状态信息
|
#define SYS_MSTAT 21 // 获取系统的内存状态信息
|
||||||
|
#define SYS_RMDIR 22 // 删除文件夹
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 用户态系统调用函数
|
* @brief 用户态系统调用函数
|
||||||
|
Loading…
x
Reference in New Issue
Block a user