mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 19:36:47 +00:00
new: 将sys_rmdir更改为sys_unlink,.且完成删除文件操作的vfs部分 (#69)
This commit is contained in:
parent
e002152383
commit
8a080f3cce
@ -29,3 +29,27 @@
|
||||
#define O_SEARCH 00020000 // Open the directory for search only
|
||||
#define O_DIRECTORY 00040000 // 打开的必须是一个目录
|
||||
#define O_NOFOLLOW 00100000 // Do not follow symbolic links
|
||||
|
||||
/*
|
||||
* The constants AT_REMOVEDIR and AT_EACCESS have the same value. AT_EACCESS is
|
||||
* meaningful only to faccessat, while AT_REMOVEDIR is meaningful only to
|
||||
* unlinkat. The two functions do completely different things and therefore,
|
||||
* the flags can be allowed to overlap. For example, passing AT_REMOVEDIR to
|
||||
* faccessat would be undefined behavior and thus treating it equivalent to
|
||||
* AT_EACCESS is valid undefined behavior.
|
||||
*/
|
||||
// 作为当前工作目录的文件描述符(用于指代cwd)
|
||||
#define AT_FDCWD -100
|
||||
#define AT_SYMLINK_NOFOLLOW 0x100 /* Do not follow symbolic links. */
|
||||
#define AT_EACCESS 0x200 /* Test access permitted for effective IDs, not real IDs. */
|
||||
#define AT_REMOVEDIR 0x200 /* Remove directory instead of unlinking file. */
|
||||
#define AT_SYMLINK_FOLLOW 0x400 /* Follow symbolic links. */
|
||||
#define AT_NO_AUTOMOUNT 0x800 /* Suppress terminal automount traversal */
|
||||
#define AT_EMPTY_PATH 0x1000 /* Allow empty relative pathname */
|
||||
|
||||
#define AT_STATX_SYNC_TYPE 0x6000 /* Type of synchronisation required from statx() */
|
||||
#define AT_STATX_SYNC_AS_STAT 0x0000 /* - Do whatever stat() does */
|
||||
#define AT_STATX_FORCE_SYNC 0x2000 /* - Force the attributes to be sync'd with the server */
|
||||
#define AT_STATX_DONT_SYNC 0x4000 /* - Don't sync attributes with the server */
|
||||
|
||||
#define AT_RECURSIVE 0x8000 /* Apply to the entire subtree */
|
7
kernel/common/user_namespace.h
Normal file
7
kernel/common/user_namespace.h
Normal file
@ -0,0 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
// todo: 引入用户命名空间
|
||||
struct user_namespace
|
||||
{
|
||||
|
||||
};
|
@ -2,6 +2,7 @@
|
||||
#include "internal.h"
|
||||
#include "mount.h"
|
||||
#include <common/dirent.h>
|
||||
#include <common/err.h>
|
||||
#include <common/errno.h>
|
||||
#include <common/kprint.h>
|
||||
#include <common/string.h>
|
||||
@ -306,11 +307,8 @@ int64_t vfs_mkdir(const char *path, mode_t mode, bool from_userland)
|
||||
subdir_dentry->name_length = pathlen - last_slash - 1;
|
||||
|
||||
for (int i = last_slash + 1, cnt = 0; i < pathlen && cnt < subdir_dentry->name_length; ++i, ++cnt)
|
||||
{
|
||||
subdir_dentry->name[cnt] = path[i];
|
||||
}
|
||||
// kdebug("last_slash=%d", last_slash);
|
||||
// kdebug("name=%s", path + last_slash + 1);
|
||||
// 设置subdir的dentry的父路径
|
||||
subdir_dentry->parent = parent_dir;
|
||||
|
||||
// kdebug("to mkdir, parent name=%s", parent_dir->name);
|
||||
@ -511,20 +509,7 @@ uint64_t do_open(const char *filename, int flags)
|
||||
else
|
||||
file_ptr->position = 0;
|
||||
|
||||
struct vfs_file_t **f = current_pcb->fds;
|
||||
|
||||
int fd_num = -1;
|
||||
|
||||
// 在指针数组中寻找空位
|
||||
// todo: 当pcb中的指针数组改为动态指针数组之后,需要更改这里(目前还是静态指针数组)
|
||||
for (int i = 0; i < PROC_MAX_FD_NUM; ++i)
|
||||
{
|
||||
if (f[i] == NULL) // 找到指针数组中的空位
|
||||
{
|
||||
fd_num = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
int fd_num = process_fd_alloc(file_ptr);
|
||||
|
||||
// 指针数组没有空位了
|
||||
if (fd_num == -1)
|
||||
@ -533,8 +518,6 @@ uint64_t do_open(const char *filename, int flags)
|
||||
spin_unlock(&dentry->lockref.lock);
|
||||
return -ENFILE;
|
||||
}
|
||||
// 保存文件描述符
|
||||
f[fd_num] = file_ptr;
|
||||
spin_unlock(&dentry->lockref.lock);
|
||||
return fd_num;
|
||||
}
|
||||
@ -613,6 +596,7 @@ int vfs_may_delete(struct vfs_dir_entry_t *dentry, bool isdir)
|
||||
int64_t vfs_rmdir(const char *path, bool from_userland)
|
||||
{
|
||||
uint32_t pathlen;
|
||||
int retval = 0;
|
||||
if (from_userland)
|
||||
pathlen = strnlen_user(path, PAGE_4K_SIZE - 1);
|
||||
else
|
||||
@ -650,47 +634,203 @@ int64_t vfs_rmdir(const char *path, bool from_userland)
|
||||
|
||||
struct vfs_dir_entry_t *dentry = vfs_path_walk(buf, 0);
|
||||
|
||||
if (dentry == NULL)
|
||||
return -ENOENT;
|
||||
kfree(buf);
|
||||
|
||||
if (dentry == NULL)
|
||||
{
|
||||
retval = -ENOENT;
|
||||
kdebug("noent");
|
||||
goto out0;
|
||||
}
|
||||
|
||||
// todo: 检查文件夹是否为空
|
||||
|
||||
int retval = vfs_may_delete(dentry, true);
|
||||
if (retval != 0)
|
||||
return retval;
|
||||
// todo: 对dentry和inode加锁
|
||||
spin_lock(&dentry->lockref.lock);
|
||||
retval = vfs_may_delete(dentry, true);
|
||||
if (retval != 0)
|
||||
goto out1;
|
||||
// todo: 对dentry和inode加锁
|
||||
retval = -EBUSY;
|
||||
if (is_local_mountpoint(dentry))
|
||||
goto out;
|
||||
goto out1;
|
||||
// todo:
|
||||
retval = dentry->dir_inode->inode_ops->rmdir(dentry->dir_inode, dentry);
|
||||
if (retval != 0)
|
||||
goto out;
|
||||
{
|
||||
BUG_ON(1);
|
||||
goto out1;
|
||||
}
|
||||
|
||||
dentry->dir_inode->attribute |= VFS_IF_DEAD; // 将当前inode标记为dead
|
||||
dont_mount(dentry); // 将当前dentry标记为不可被挂载
|
||||
detach_mounts(dentry); // 清理同样挂载在该路径的所有挂载点的挂载树
|
||||
|
||||
if (vfs_dentry_put(dentry) != 0)
|
||||
goto out; // 释放dentry
|
||||
return retval;
|
||||
out:;
|
||||
// 释放dentry
|
||||
retval = vfs_dentry_put(dentry);
|
||||
|
||||
if (retval != 0)
|
||||
goto out1;
|
||||
goto out0;
|
||||
out2:;
|
||||
spin_unlock(&dentry->dir_inode->lockref.lock);
|
||||
out1:;
|
||||
spin_unlock(&dentry->lockref.lock);
|
||||
// todo: 对dentry和inode放锁
|
||||
out0:;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 删除文件夹的系统调用函数
|
||||
* @brief unlink a filesystem object
|
||||
*
|
||||
* @param r8 文件夹路径
|
||||
* 调用者必须持有parent_inode->lockref.lock
|
||||
*
|
||||
* @param mnt_userns 暂时未使用 用户命名空间. 请置为NULL
|
||||
* @param parent_inode 父目录项的inode
|
||||
* @param dentry 要被删除的目录项
|
||||
* @param delegated_inode 暂未使用,请置为NULL
|
||||
* @return int
|
||||
*/
|
||||
int vfs_unlink(struct user_namespace *mnt_userns, struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t *dentry,
|
||||
struct vfs_index_node_t **delegated_inode)
|
||||
{
|
||||
// 暂时不支持用户命名空间,因此发出警告
|
||||
if (unlikely(mnt_userns != NULL))
|
||||
{
|
||||
WARN_ON(1);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int retval = 0;
|
||||
struct vfs_index_node_t *target = dentry->dir_inode;
|
||||
|
||||
retval = vfs_may_delete(dentry, false);
|
||||
if (unlikely(retval != 0))
|
||||
return retval;
|
||||
|
||||
// 没有unlink方法,则不允许删除
|
||||
if (!parent_inode->inode_ops->unlink)
|
||||
return -EPERM;
|
||||
|
||||
// 对inode加锁
|
||||
spin_lock(&target->lockref.lock);
|
||||
|
||||
if (is_local_mountpoint(dentry))
|
||||
retval = -EBUSY;
|
||||
else
|
||||
{
|
||||
retval = parent_inode->inode_ops->unlink(parent_inode, dentry);
|
||||
if (retval == 0)
|
||||
{
|
||||
dont_mount(dentry);
|
||||
detach_mounts(dentry);
|
||||
}
|
||||
}
|
||||
|
||||
spin_unlock(&target->lockref.lock);
|
||||
|
||||
out:;
|
||||
return retval;
|
||||
}
|
||||
/**
|
||||
* @brief 取消dentry和inode之间的链接
|
||||
*
|
||||
* @param dfd 进程相对路径基准目录的文件描述符(fcntl.h)
|
||||
* @param pathname 路径
|
||||
* @param from_userland 请求是否来自用户态
|
||||
* @return int 错误码
|
||||
*/
|
||||
int do_unlink_at(int dfd, const char *pathname, bool from_userland)
|
||||
{
|
||||
// 暂时不支持相对路径,只支持绝对路径
|
||||
if (dfd & AT_FDCWD)
|
||||
{
|
||||
kwarn("Not support: AT_FDCWD");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
uint32_t pathlen;
|
||||
int retval = 0;
|
||||
if (from_userland)
|
||||
pathlen = strnlen_user(pathname, PAGE_4K_SIZE - 1);
|
||||
else
|
||||
pathlen = strnlen(pathname, PAGE_4K_SIZE - 1);
|
||||
|
||||
if (pathlen == 0)
|
||||
return -ENOENT;
|
||||
|
||||
int last_slash = -1;
|
||||
|
||||
// 去除末尾的'/'
|
||||
for (int i = pathlen - 1; i >= 0; --i)
|
||||
{
|
||||
if (pathname[i] != '/')
|
||||
{
|
||||
last_slash = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 路径格式不合法
|
||||
if (last_slash < 0)
|
||||
return -ENOTDIR;
|
||||
else if (pathname[0] != '/')
|
||||
return -EINVAL;
|
||||
|
||||
char *buf = (char *)kzalloc(last_slash + 2, 0);
|
||||
|
||||
// 拷贝字符串(不包含要被创建的部分)
|
||||
if (from_userland)
|
||||
strncpy_from_user(buf, pathname, last_slash);
|
||||
else
|
||||
strncpy(buf, pathname, last_slash);
|
||||
buf[last_slash + 1] = '\0';
|
||||
|
||||
struct vfs_dir_entry_t *dentry = vfs_path_walk(buf, 0);
|
||||
kfree(buf);
|
||||
|
||||
if (dentry == NULL || dentry->parent == NULL)
|
||||
{
|
||||
retval = -ENOENT;
|
||||
goto out;
|
||||
}
|
||||
|
||||
struct vfs_index_node_t *p_inode = dentry->parent->dir_inode;
|
||||
// 对父inode加锁
|
||||
spin_lock(&p_inode);
|
||||
retval = vfs_unlink(NULL, dentry->parent->dir_inode, dentry, NULL);
|
||||
|
||||
spin_lock(&dentry->lockref.lock);
|
||||
retval = vfs_dentry_put(dentry);
|
||||
spin_unlock(&p_inode);
|
||||
|
||||
if (IS_ERR(retval))
|
||||
kwarn("In do_unlink_at: dentry put failed; retval=%d", retval);
|
||||
else
|
||||
retval = 0;
|
||||
out:;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 删除文件夹、取消文件的链接、删除文件的系统调用
|
||||
*
|
||||
* @param regs->r8 dfd 进程相对路径基准目录的文件描述符(见fcntl.h)
|
||||
* @param regs->r9 路径名称字符串
|
||||
* @param regs->r10 flag 预留的标志位,暂时未使用,请置为0。
|
||||
* @return uint64_t 错误码
|
||||
*/
|
||||
uint64_t sys_rmdir(struct pt_regs *regs)
|
||||
uint64_t sys_unlink_at(struct pt_regs *regs)
|
||||
{
|
||||
if (SYSCALL_FROM_USER(regs))
|
||||
return vfs_rmdir((char *)regs->r8, true);
|
||||
else
|
||||
return vfs_rmdir((char *)regs->r8, false);
|
||||
int dfd = regs->r8;
|
||||
const char *pathname = regs->r9;
|
||||
int flag = regs->r10;
|
||||
bool from_user = SYSCALL_FROM_USER(regs) ? true : false;
|
||||
if ((flag & (~AT_REMOVEDIR)) != 0)
|
||||
return -EINVAL;
|
||||
if (flag & AT_REMOVEDIR)
|
||||
return vfs_rmdir(pathname, from_user);
|
||||
|
||||
return do_unlink_at(dfd, pathname, from_user);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <common/fcntl.h>
|
||||
#include <common/glib.h>
|
||||
#include <common/lockref.h>
|
||||
#include <common/user_namespace.h>
|
||||
#include <mm/slab.h>
|
||||
|
||||
extern struct vfs_superblock_t *vfs_root_sb;
|
||||
@ -156,6 +157,14 @@ struct vfs_inode_operations_t
|
||||
struct vfs_index_node_t *new_inode, struct vfs_dir_entry_t *new_dEntry);
|
||||
long (*getAttr)(struct vfs_dir_entry_t *dEntry, uint64_t *attr);
|
||||
long (*setAttr)(struct vfs_dir_entry_t *dEntry, uint64_t *attr);
|
||||
|
||||
/**
|
||||
* @brief 取消inode和dentry之间的链接关系(删除文件)
|
||||
*
|
||||
* @param inode 要被取消关联关系的目录项的【父目录项】
|
||||
* @param dentry 要被取消关联关系的子目录项
|
||||
*/
|
||||
long (*unlink)(struct vfs_index_node_t * inode, struct vfs_dir_entry_t * dentry);
|
||||
};
|
||||
|
||||
struct vfs_dir_entry_operations_t
|
||||
@ -277,3 +286,8 @@ int64_t vfs_rmdir(const char *path, bool from_userland);
|
||||
* 注意,当dentry指向文件时,如果返回值为正数,则表示在释放了该dentry后,该dentry指向的inode的引用计数。
|
||||
*/
|
||||
int vfs_dentry_put(struct vfs_dir_entry_t *dentry);
|
||||
|
||||
int vfs_unlink(struct user_namespace *mnt_userns, struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_t *dentry,
|
||||
struct vfs_index_node_t **delegated_inode);
|
||||
|
||||
int do_unlink_at(int dfd, const char *pathname, bool name);
|
@ -15,9 +15,10 @@ int vfs_dentry_put(struct vfs_dir_entry_t *dentry)
|
||||
int retval = 0;
|
||||
uint64_t in_value = 0;
|
||||
struct kfifo_t fifo = {0};
|
||||
const struct vfs_dir_entry_t *start_dentry = dentry;
|
||||
|
||||
// 引用计数大于1时,尝试释放dentry的话,抛出错误信息
|
||||
if (unlikely(dentry->lockref.lock_count > 1))
|
||||
if (unlikely(dentry->lockref.count > 1))
|
||||
{
|
||||
BUG_ON(1);
|
||||
retval = -EBUSY;
|
||||
@ -58,9 +59,11 @@ int vfs_dentry_put(struct vfs_dir_entry_t *dentry)
|
||||
|
||||
} while (list_next(list) != (&dentry->subdirs_list));
|
||||
}
|
||||
if (unlikely(dentry != start_dentry))
|
||||
spin_lock(&dentry->lockref.lock);
|
||||
if(dentry->lockref.count>1)
|
||||
if (dentry->lockref.count > 1)
|
||||
{
|
||||
if (unlikely(dentry != start_dentry))
|
||||
spin_unlock(&dentry->lockref.lock);
|
||||
continue;
|
||||
}
|
||||
|
@ -969,8 +969,6 @@ int64_t fat32_mkdir(struct vfs_index_node_t *parent_inode, struct vfs_dir_entry_
|
||||
// todo: 填写完全fat32_inode_info的信息
|
||||
|
||||
// 初始化dentry信息
|
||||
list_init(&dEntry->child_node_list);
|
||||
list_init(&dEntry->subdirs_list);
|
||||
dEntry->dir_ops = &fat32_dEntry_ops;
|
||||
dEntry->dir_inode = inode;
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
#include "fat_ent.h"
|
||||
#include <driver/disk/ahci/ahci.h>
|
||||
#include <common/errno.h>
|
||||
#include <driver/disk/ahci/ahci.h>
|
||||
#include <mm/slab.h>
|
||||
|
||||
static const char unavailable_character_in_short_name[] = {0x22, 0x2a, 0x2b, 0x2c, 0x2e, 0x2f, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x5b, 0x5c, 0x5d, 0x7c};
|
||||
static const char unavailable_character_in_short_name[] = {0x22, 0x2a, 0x2b, 0x2c, 0x2e, 0x2f, 0x3a, 0x3b,
|
||||
0x3c, 0x3d, 0x3e, 0x3f, 0x5b, 0x5c, 0x5d, 0x7c};
|
||||
/**
|
||||
* @brief 请求分配指定数量的簇
|
||||
*
|
||||
@ -133,8 +134,8 @@ uint32_t fat32_read_FAT_entry(struct block_device *blk, fat32_sb_info_t *fsbi, u
|
||||
memset(buf, 0, fsbi->bytes_per_sec);
|
||||
|
||||
// 读取一个sector的数据,
|
||||
blk->bd_disk->fops->transfer(blk->bd_disk, AHCI_CMD_READ_DMA_EXT, fsbi->FAT1_base_sector + (cluster / fat_ent_per_sec), 1,
|
||||
(uint64_t)&buf);
|
||||
blk->bd_disk->fops->transfer(blk->bd_disk, AHCI_CMD_READ_DMA_EXT,
|
||||
fsbi->FAT1_base_sector + (cluster / fat_ent_per_sec), 1, (uint64_t)&buf);
|
||||
|
||||
// 返回下一个fat表项的值(也就是下一个cluster)
|
||||
return buf[cluster & (fat_ent_per_sec - 1)] & 0x0fffffff;
|
||||
@ -156,15 +157,15 @@ uint32_t fat32_write_FAT_entry(struct block_device *blk, fat32_sb_info_t *fsbi,
|
||||
uint32_t fat_ent_per_sec = (fsbi->bytes_per_sec >> 2); // 该值应为2的n次幂
|
||||
uint32_t *buf = kzalloc(fsbi->bytes_per_sec, 0);
|
||||
|
||||
blk->bd_disk->fops->transfer(blk->bd_disk, AHCI_CMD_READ_DMA_EXT, fsbi->FAT1_base_sector + (cluster / fat_ent_per_sec), 1,
|
||||
(uint64_t)buf);
|
||||
blk->bd_disk->fops->transfer(blk->bd_disk, AHCI_CMD_READ_DMA_EXT,
|
||||
fsbi->FAT1_base_sector + (cluster / fat_ent_per_sec), 1, (uint64_t)buf);
|
||||
|
||||
buf[cluster & (fat_ent_per_sec - 1)] = (buf[cluster & (fat_ent_per_sec - 1)] & 0xf0000000) | (value & 0x0fffffff);
|
||||
// 向FAT1和FAT2写入数据
|
||||
blk->bd_disk->fops->transfer(blk->bd_disk, AHCI_CMD_WRITE_DMA_EXT, fsbi->FAT1_base_sector + (cluster / fat_ent_per_sec), 1,
|
||||
(uint64_t)buf);
|
||||
blk->bd_disk->fops->transfer(blk->bd_disk, AHCI_CMD_WRITE_DMA_EXT, fsbi->FAT2_base_sector + (cluster / fat_ent_per_sec), 1,
|
||||
(uint64_t)buf);
|
||||
blk->bd_disk->fops->transfer(blk->bd_disk, AHCI_CMD_WRITE_DMA_EXT,
|
||||
fsbi->FAT1_base_sector + (cluster / fat_ent_per_sec), 1, (uint64_t)buf);
|
||||
blk->bd_disk->fops->transfer(blk->bd_disk, AHCI_CMD_WRITE_DMA_EXT,
|
||||
fsbi->FAT2_base_sector + (cluster / fat_ent_per_sec), 1, (uint64_t)buf);
|
||||
|
||||
kfree(buf);
|
||||
return 0;
|
||||
@ -179,9 +180,12 @@ uint32_t fat32_write_FAT_entry(struct block_device *blk, fat32_sb_info_t *fsbi,
|
||||
* @param res_sector 返回信息:缓冲区对应的扇区号
|
||||
* @param res_cluster 返回信息:缓冲区对应的簇号
|
||||
* @param res_data_buf_base 返回信息:缓冲区的内存基地址(记得要释放缓冲区内存!!!!)
|
||||
* @return struct fat32_Directory_t* 符合要求的entry的指针(指向地址高处的空目录项,也就是说,有连续num个≤这个指针的空目录项)
|
||||
* @return struct fat32_Directory_t*
|
||||
* 符合要求的entry的指针(指向地址高处的空目录项,也就是说,有连续num个≤这个指针的空目录项)
|
||||
*/
|
||||
struct fat32_Directory_t *fat32_find_empty_dentry(struct vfs_index_node_t *parent_inode, uint32_t num, uint32_t mode, uint32_t *res_sector, uint64_t *res_cluster, uint64_t *res_data_buf_base)
|
||||
struct fat32_Directory_t *fat32_find_empty_dentry(struct vfs_index_node_t *parent_inode, uint32_t num, uint32_t mode,
|
||||
uint32_t *res_sector, uint64_t *res_cluster,
|
||||
uint64_t *res_data_buf_base)
|
||||
{
|
||||
// kdebug("find empty_dentry");
|
||||
struct fat32_inode_info_t *finode = (struct fat32_inode_info_t *)parent_inode->private_inode_info;
|
||||
@ -251,7 +255,8 @@ struct fat32_Directory_t *fat32_find_empty_dentry(struct vfs_index_node_t *paren
|
||||
// 将这个新的簇清空
|
||||
sector = fsbi->first_data_sector + (cluster - 2) * fsbi->sec_per_clus;
|
||||
void *tmp_buf = kzalloc(fsbi->bytes_per_clus, 0);
|
||||
blk->bd_disk->fops->transfer(blk->bd_disk, AHCI_CMD_WRITE_DMA_EXT, sector, fsbi->sec_per_clus, (uint64_t)tmp_buf);
|
||||
blk->bd_disk->fops->transfer(blk->bd_disk, AHCI_CMD_WRITE_DMA_EXT, sector, fsbi->sec_per_clus,
|
||||
(uint64_t)tmp_buf);
|
||||
kfree(tmp_buf);
|
||||
}
|
||||
}
|
||||
@ -327,6 +332,12 @@ void fat32_fill_shortname(struct vfs_dir_entry_t *dEntry, struct fat32_Directory
|
||||
else
|
||||
target->DIR_Name[tmp_index] = 0x20;
|
||||
}
|
||||
// 在字符串末尾加入\0
|
||||
if (tmp_index < 8 && tmp_index == dEntry->name_length)
|
||||
{
|
||||
target->DIR_Name[tmp_index] = '\0';
|
||||
++tmp_index;
|
||||
}
|
||||
|
||||
// 不满的部分使用0x20填充
|
||||
while (tmp_index < 8)
|
||||
@ -373,7 +384,8 @@ void fat32_fill_shortname(struct vfs_dir_entry_t *dEntry, struct fat32_Directory
|
||||
* @param checksum 短目录项的校验和
|
||||
* @param cnt_longname 总的长目录项的个数
|
||||
*/
|
||||
void fat32_fill_longname(struct vfs_dir_entry_t *dEntry, struct fat32_LongDirectory_t *target, uint8_t checksum, uint32_t cnt_longname)
|
||||
void fat32_fill_longname(struct vfs_dir_entry_t *dEntry, struct fat32_LongDirectory_t *target, uint8_t checksum,
|
||||
uint32_t cnt_longname)
|
||||
{
|
||||
uint32_t current_name_index = 0;
|
||||
struct fat32_LongDirectory_t *Ldentry = (struct fat32_LongDirectory_t *)(target + 1);
|
||||
@ -387,6 +399,8 @@ void fat32_fill_longname(struct vfs_dir_entry_t *dEntry, struct fat32_LongDirect
|
||||
{
|
||||
if (current_name_index < dEntry->name_length)
|
||||
Ldentry->LDIR_Name1[j] = dEntry->name[current_name_index];
|
||||
else if (current_name_index == dEntry->name_length)
|
||||
Ldentry->LDIR_Name1[j] = '\0';
|
||||
else
|
||||
Ldentry->LDIR_Name1[j] = 0xffff;
|
||||
}
|
||||
@ -394,6 +408,8 @@ void fat32_fill_longname(struct vfs_dir_entry_t *dEntry, struct fat32_LongDirect
|
||||
{
|
||||
if (current_name_index < dEntry->name_length)
|
||||
Ldentry->LDIR_Name2[j] = dEntry->name[current_name_index];
|
||||
else if (current_name_index == dEntry->name_length)
|
||||
Ldentry->LDIR_Name1[j] = '\0';
|
||||
else
|
||||
Ldentry->LDIR_Name2[j] = 0xffff;
|
||||
}
|
||||
@ -401,6 +417,8 @@ void fat32_fill_longname(struct vfs_dir_entry_t *dEntry, struct fat32_LongDirect
|
||||
{
|
||||
if (current_name_index < dEntry->name_length)
|
||||
Ldentry->LDIR_Name3[j] = dEntry->name[current_name_index];
|
||||
else if (current_name_index == dEntry->name_length)
|
||||
Ldentry->LDIR_Name1[j] = '\0';
|
||||
else
|
||||
Ldentry->LDIR_Name3[j] = 0xffff;
|
||||
}
|
||||
|
@ -18,7 +18,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);
|
||||
extern uint64_t sys_unlink_at(struct pt_regs *regs);
|
||||
|
||||
/**
|
||||
* @brief 导出系统调用处理函数的符号
|
||||
@ -607,7 +607,7 @@ system_call_t system_call_table[MAX_SYSTEM_CALL_NUM] = {
|
||||
[19] = sys_clock,
|
||||
[20] = sys_pipe,
|
||||
[21] = sys_mstat,
|
||||
[22] = sys_rmdir,
|
||||
[22] = sys_unlink_at,
|
||||
[23 ... 254] = system_call_not_exists,
|
||||
[255] = sys_ahci_end_req,
|
||||
};
|
||||
|
@ -33,7 +33,7 @@
|
||||
#define SYS_PIPE 20
|
||||
|
||||
#define SYS_MSTAT 21 // 获取系统的内存状态信息
|
||||
#define SYS_RMDIR 22 // 删除文件夹
|
||||
#define SYS_UNLINK_AT 22 // 删除文件夹/删除文件链接
|
||||
|
||||
|
||||
#define SYS_AHCI_END_REQ 255 // AHCI DMA请求结束end_request的系统调用
|
@ -30,6 +30,29 @@
|
||||
#define O_DIRECTORY 00040000 // 打开的必须是一个目录
|
||||
#define O_NOFOLLOW 00100000 // Do not follow symbolic links
|
||||
|
||||
/*
|
||||
* The constants AT_REMOVEDIR and AT_EACCESS have the same value. AT_EACCESS is
|
||||
* meaningful only to faccessat, while AT_REMOVEDIR is meaningful only to
|
||||
* unlinkat. The two functions do completely different things and therefore,
|
||||
* the flags can be allowed to overlap. For example, passing AT_REMOVEDIR to
|
||||
* faccessat would be undefined behavior and thus treating it equivalent to
|
||||
* AT_EACCESS is valid undefined behavior.
|
||||
*/
|
||||
// 作为当前工作目录的文件描述符(用于指代cwd)
|
||||
#define AT_FDCWD -100
|
||||
#define AT_SYMLINK_NOFOLLOW 0x100 /* Do not follow symbolic links. */
|
||||
#define AT_EACCESS 0x200 /* Test access permitted for effective IDs, not real IDs. */
|
||||
#define AT_REMOVEDIR 0x200 /* Remove directory instead of unlinking file. */
|
||||
#define AT_SYMLINK_FOLLOW 0x400 /* Follow symbolic links. */
|
||||
#define AT_NO_AUTOMOUNT 0x800 /* Suppress terminal automount traversal */
|
||||
#define AT_EMPTY_PATH 0x1000 /* Allow empty relative pathname */
|
||||
|
||||
#define AT_STATX_SYNC_TYPE 0x6000 /* Type of synchronisation required from statx() */
|
||||
#define AT_STATX_SYNC_AS_STAT 0x0000 /* - Do whatever stat() does */
|
||||
#define AT_STATX_FORCE_SYNC 0x2000 /* - Force the attributes to be sync'd with the server */
|
||||
#define AT_STATX_DONT_SYNC 0x4000 /* - Don't sync attributes with the server */
|
||||
|
||||
#define AT_RECURSIVE 0x8000 /* Apply to the entire subtree */
|
||||
|
||||
/**
|
||||
* @brief 打开文件的接口
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include <libc/stdio.h>
|
||||
#include <libc/stddef.h>
|
||||
#include <libc/string.h>
|
||||
#include <libc/fcntl.h>
|
||||
|
||||
/**
|
||||
* @brief 关闭文件接口
|
||||
@ -157,7 +158,7 @@ int execv(const char *path, char *const argv[])
|
||||
*/
|
||||
int rmdir(const char *path)
|
||||
{
|
||||
return syscall_invoke(SYS_RMDIR, (uint64_t)path, 0, 0, 0, 0, 0, 0, 0);
|
||||
return syscall_invoke(SYS_UNLINK_AT, 0, (uint64_t)path, AT_REMOVEDIR, 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -27,7 +27,7 @@
|
||||
#define SYS_PIPE 20
|
||||
|
||||
#define SYS_MSTAT 21 // 获取系统的内存状态信息
|
||||
#define SYS_RMDIR 22 // 删除文件夹
|
||||
#define SYS_UNLINK_AT 22 // 删除文件夹/删除文件链接
|
||||
|
||||
/**
|
||||
* @brief 用户态系统调用函数
|
||||
|
Loading…
x
Reference in New Issue
Block a user