mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 18:26:48 +00:00
🆕 fat32_write (存在写入bug)
This commit is contained in:
parent
3e101d71ff
commit
9db1c3f74e
@ -24,7 +24,7 @@ struct vfs_superblock_t *vfs_root_sb = NULL;
|
||||
|
||||
/**
|
||||
* @brief 目录项的属性
|
||||
*
|
||||
*
|
||||
*/
|
||||
#define VFS_ATTR_FILE (1UL << 0)
|
||||
#define VFS_ATTR_DIR (1UL << 1)
|
||||
@ -73,7 +73,7 @@ struct vfs_index_node_t
|
||||
|
||||
/**
|
||||
* @brief 文件描述符
|
||||
*
|
||||
*
|
||||
*/
|
||||
struct vfs_file_t
|
||||
{
|
||||
@ -95,9 +95,9 @@ struct vfs_filesystem_type_t
|
||||
|
||||
struct vfs_super_block_operations_t
|
||||
{
|
||||
void (*write_superblock)(struct vfs_superblock_t *sb);
|
||||
void (*write_superblock)(struct vfs_superblock_t *sb); // 将超级块信息写入磁盘
|
||||
void (*put_superblock)(struct vfs_superblock_t *sb);
|
||||
void (*write_inode)(struct vfs_index_node_t *inode);
|
||||
void (*write_inode)(struct vfs_index_node_t *inode); // 将inode信息写入磁盘
|
||||
};
|
||||
|
||||
/**
|
||||
@ -153,7 +153,6 @@ uint64_t vfs_unregister_filesystem(struct vfs_filesystem_type_t *fs);
|
||||
*/
|
||||
struct vfs_superblock_t *vfs_mount_fs(char *name, void *DPTE, uint8_t DPT_type, void *buf, int8_t ahci_ctrl_num, int8_t ahci_port_num, int8_t part_num);
|
||||
|
||||
|
||||
/**
|
||||
* @brief 按照路径查找文件
|
||||
*
|
||||
|
@ -49,7 +49,7 @@ uint32_t fat32_read_FAT_entry(fat32_sb_info_t *fsbi, uint32_t cluster)
|
||||
// 计算每个扇区内含有的FAT表项数
|
||||
// FAT每项4bytes
|
||||
uint32_t fat_ent_per_sec = (fsbi->bytes_per_sec >> 2); // 该值应为2的n次幂
|
||||
|
||||
|
||||
uint32_t buf[256];
|
||||
memset(buf, 0, fsbi->bytes_per_sec);
|
||||
|
||||
@ -551,7 +551,7 @@ long fat32_close(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr)
|
||||
|
||||
/**
|
||||
* @brief 从fat32文件系统读取数据
|
||||
*
|
||||
*
|
||||
* @param file_ptr 文件描述符
|
||||
* @param buf 输出缓冲区
|
||||
* @param count 要读取的字节数
|
||||
@ -570,7 +570,7 @@ long fat32_read(struct vfs_file_t *file_ptr, char *buf, uint64_t count, long *po
|
||||
// kdebug("fsbi->bytes_per_clus=%d", fsbi->bytes_per_clus);
|
||||
|
||||
// clus offset in file
|
||||
uint64_t total_clus_of_file = (*position) / fsbi->bytes_per_clus;
|
||||
uint64_t clus_offset_in_file = (*position) / fsbi->bytes_per_clus;
|
||||
// bytes offset in clus
|
||||
uint64_t bytes_offset = (*position) % fsbi->bytes_per_clus;
|
||||
|
||||
@ -578,7 +578,7 @@ long fat32_read(struct vfs_file_t *file_ptr, char *buf, uint64_t count, long *po
|
||||
return -EFAULT;
|
||||
|
||||
// find the actual cluster on disk of the specified position
|
||||
for (int i = 0; i < total_clus_of_file; ++i)
|
||||
for (int i = 0; i < clus_offset_in_file; ++i)
|
||||
cluster = fat32_read_FAT_entry(fsbi, cluster);
|
||||
|
||||
// 如果需要读取的数据边界大于文件大小
|
||||
@ -615,7 +615,7 @@ long fat32_read(struct vfs_file_t *file_ptr, char *buf, uint64_t count, long *po
|
||||
if (((uint64_t)buf) < USER_MAX_LINEAR_ADDR)
|
||||
copy_to_user(buf, tmp_buffer + bytes_offset, step_trans_len);
|
||||
else
|
||||
memcpy(buf, tmp_buffer, step_trans_len);
|
||||
memcpy(buf, tmp_buffer + bytes_offset, step_trans_len);
|
||||
|
||||
bytes_remain -= step_trans_len;
|
||||
buf += step_trans_len;
|
||||
@ -628,14 +628,174 @@ long fat32_read(struct vfs_file_t *file_ptr, char *buf, uint64_t count, long *po
|
||||
|
||||
kfree(tmp_buffer);
|
||||
|
||||
if(!bytes_remain)
|
||||
if (!bytes_remain)
|
||||
retval = count;
|
||||
|
||||
return retval;
|
||||
}
|
||||
// todo: write
|
||||
|
||||
/**
|
||||
* @brief 在磁盘中寻找一个空闲的簇
|
||||
*
|
||||
* @param fsbi fat32超级块信息结构体
|
||||
* @return uint64_t 空闲簇号(找不到则返回0)
|
||||
*/
|
||||
uint64_t fat32_find_available_cluster(fat32_sb_info_t *fsbi)
|
||||
{
|
||||
uint64_t sec_per_fat = fsbi->sec_per_FAT;
|
||||
|
||||
// 申请1扇区的缓冲区
|
||||
uint32_t *buf = (uint32_t *)kmalloc(fsbi->bytes_per_sec, 0);
|
||||
int ent_per_sec = (fsbi->bytes_per_sec >> 2);
|
||||
for (int i = 0; i < sec_per_fat; ++i)
|
||||
{
|
||||
memset(buf, 0, fsbi->bytes_per_sec);
|
||||
|
||||
ahci_operation.transfer(AHCI_CMD_READ_DMA_EXT, fsbi->FAT1_base_sector + i, 1, (uint64_t)buf, fsbi->ahci_ctrl_num, fsbi->ahci_port_num);
|
||||
// 依次检查簇是否空闲
|
||||
for (int j = 0; j < ent_per_sec; ++j)
|
||||
{
|
||||
// 找到空闲簇
|
||||
if ((buf[j] & 0x0fffffff) == 0)
|
||||
return i * ent_per_sec + j;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 向fat32文件系统写入数据
|
||||
*
|
||||
* @param file_ptr 文件描述符
|
||||
* @param buf 输入写入的字节数
|
||||
* @param position 文件指针位置
|
||||
* @return long 执行成功:传输的字节数量 执行失败:错误码(小于0)
|
||||
*/
|
||||
long fat32_write(struct vfs_file_t *file_ptr, char *buf, uint64_t count, long *position)
|
||||
{
|
||||
struct fat32_inode_info_t *finode = (struct fat32_inode_info_t *)file_ptr->dEntry->dir_inode->private_inode_info;
|
||||
fat32_sb_info_t *fsbi = (fat32_sb_info_t *)(file_ptr->dEntry->dir_inode->sb->private_sb_info);
|
||||
|
||||
// First cluster num of the file
|
||||
uint64_t cluster = finode->first_clus;
|
||||
int64_t flags = 0;
|
||||
|
||||
kdebug("fsbi->bytes_per_clus=%d", fsbi->bytes_per_clus);
|
||||
// clus offset in file
|
||||
uint64_t clus_offset_in_file = (*position) / fsbi->bytes_per_clus;
|
||||
// bytes offset in clus
|
||||
uint64_t bytes_offset = (*position) % fsbi->bytes_per_clus;
|
||||
|
||||
if (!cluster) // 起始簇号为0,说明是空文件
|
||||
{
|
||||
// 找一个可用的簇
|
||||
cluster = fat32_find_available_cluster(fsbi);
|
||||
flags = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 跳转到position所在的簇
|
||||
for (uint64_t i = 0; i < clus_offset_in_file; ++i)
|
||||
cluster = fat32_read_FAT_entry(fsbi, cluster);
|
||||
}
|
||||
kdebug("hhhhhhhh");
|
||||
// 没有可用的磁盘空间
|
||||
if (!cluster)
|
||||
return -ENOSPC;
|
||||
|
||||
if (flags) // 空文件
|
||||
{
|
||||
finode->first_clus = cluster;
|
||||
// 写入目录项
|
||||
file_ptr->dEntry->dir_inode->sb->sb_ops->write_inode(file_ptr->dEntry->dir_inode);
|
||||
fat32_write_FAT_entry(fsbi, cluster, 0x0fffffff8); // 写入fat表项
|
||||
}
|
||||
|
||||
uint64_t bytes_remain = count;
|
||||
uint64_t sector;
|
||||
int64_t retval = 0;
|
||||
|
||||
void *tmp_buffer = kmalloc(fsbi->bytes_per_clus, 0);
|
||||
kdebug("ggggg");
|
||||
do
|
||||
{
|
||||
memset(tmp_buffer, 0, fsbi->bytes_per_clus);
|
||||
sector = fsbi->first_data_sector + (cluster - 2) * fsbi->sec_per_clus; // 计算对应的扇区
|
||||
|
||||
if (!flags) // 当前簇已分配
|
||||
{
|
||||
// 读取一个簇的数据
|
||||
int errno = ahci_operation.transfer(AHCI_CMD_READ_DMA_EXT, sector, fsbi->sec_per_clus, (uint64_t)tmp_buffer, fsbi->ahci_ctrl_num, fsbi->ahci_port_num);
|
||||
if (errno != AHCI_SUCCESS)
|
||||
{
|
||||
kerror("FAT32 FS(write) read disk error!");
|
||||
retval = -EIO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t step_trans_len = 0; // 当前循环传输的字节数
|
||||
if (bytes_remain > (fsbi->bytes_per_clus - bytes_offset))
|
||||
step_trans_len = (fsbi->bytes_per_clus - bytes_offset);
|
||||
else
|
||||
step_trans_len = bytes_remain;
|
||||
|
||||
if (((uint64_t)buf) < USER_MAX_LINEAR_ADDR)
|
||||
copy_from_user(tmp_buffer + bytes_offset, buf, step_trans_len);
|
||||
else
|
||||
memcpy(tmp_buffer + bytes_offset, buf, step_trans_len);
|
||||
|
||||
// 写入数据到对应的簇
|
||||
int errno = ahci_operation.transfer(AHCI_CMD_WRITE_DMA_EXT, sector, fsbi->sec_per_clus, (uint64_t)tmp_buffer, fsbi->ahci_ctrl_num, fsbi->ahci_port_num);
|
||||
if (errno != AHCI_SUCCESS)
|
||||
{
|
||||
kerror("FAT32 FS(write) read disk error!");
|
||||
retval = -EIO;
|
||||
break;
|
||||
}
|
||||
|
||||
bytes_remain -= step_trans_len;
|
||||
buf += step_trans_len;
|
||||
bytes_offset -= bytes_offset;
|
||||
|
||||
*position += step_trans_len; // 更新文件指针
|
||||
kdebug("step_trans_len=%d", step_trans_len);
|
||||
|
||||
int next_clus = 0;
|
||||
if (bytes_remain)
|
||||
next_clus = fat32_read_FAT_entry(fsbi, cluster);
|
||||
else
|
||||
break;
|
||||
if (next_clus >= 0x0ffffff8) // 已经到达了最后一个簇,需要分配新簇
|
||||
{
|
||||
next_clus = fat32_find_available_cluster(fsbi);
|
||||
if (!next_clus) // 没有空闲簇
|
||||
{
|
||||
kfree(tmp_buffer);
|
||||
return -ENOSPC;
|
||||
}
|
||||
// 将簇加入到文件末尾
|
||||
fat32_write_FAT_entry(fsbi, cluster, next_clus);
|
||||
fat32_write_FAT_entry(fsbi, next_clus, 0x0ffffff8);
|
||||
cluster = next_clus; // 切换当前簇
|
||||
flags = 1; // 标记当前簇是新分配的簇
|
||||
}
|
||||
|
||||
} while (bytes_remain);
|
||||
|
||||
// 文件大小有增长
|
||||
if (*position > (file_ptr->dEntry->dir_inode->file_size))
|
||||
{
|
||||
file_ptr->dEntry->dir_inode->file_size = *position;
|
||||
file_ptr->dEntry->dir_inode->sb->sb_ops->write_inode(file_ptr->dEntry->dir_inode);
|
||||
kdebug("new file size=%ld", *position);
|
||||
}
|
||||
|
||||
kfree(tmp_buffer);
|
||||
if (!bytes_remain)
|
||||
retval = count;
|
||||
kdebug("retval=%lld", retval);
|
||||
return retval;
|
||||
}
|
||||
// todo: lseek
|
||||
long fat32_lseek(struct vfs_file_t *file_ptr, long offset, long origin)
|
||||
|
@ -109,34 +109,79 @@ void user_level_function()
|
||||
int fd_num = err_code;
|
||||
|
||||
int count = 16;
|
||||
while (count)
|
||||
{
|
||||
uchar buf[128] = {0};
|
||||
// Test sys_read
|
||||
addr = (uint64_t)&buf;
|
||||
__asm__ __volatile__(
|
||||
"movq %2, %%r8 \n\t"
|
||||
"movq %3, %%r9 \n\t"
|
||||
"movq %4, %%r10 \n\t"
|
||||
"movq %5, %%r11 \n\t"
|
||||
"movq %6, %%r12 \n\t"
|
||||
"movq %7, %%r13 \n\t"
|
||||
"movq %8, %%r14 \n\t"
|
||||
"movq %9, %%r15 \n\t"
|
||||
"int $0x80 \n\t"
|
||||
: "=a"(err_code)
|
||||
: "a"(SYS_READ), "m"(fd_num), "m"(addr), "m"(count), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero)
|
||||
: "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rcx", "rdx");
|
||||
count = err_code;
|
||||
// 将读取到的数据打印出来
|
||||
addr = (ul)buf;
|
||||
__asm__ __volatile__(
|
||||
"movq %2, %%r8 \n\t"
|
||||
"int $0x80 \n\t"
|
||||
: "=a"(err_code)
|
||||
: "a"(SYS_PUT_STRING), "m"(addr)
|
||||
: "memory", "r8");
|
||||
}
|
||||
// while (count)
|
||||
//{
|
||||
uchar buf[128] = {0};
|
||||
// Test sys_read
|
||||
addr = (uint64_t)&buf;
|
||||
__asm__ __volatile__(
|
||||
"movq %2, %%r8 \n\t"
|
||||
"movq %3, %%r9 \n\t"
|
||||
"movq %4, %%r10 \n\t"
|
||||
"movq %5, %%r11 \n\t"
|
||||
"movq %6, %%r12 \n\t"
|
||||
"movq %7, %%r13 \n\t"
|
||||
"movq %8, %%r14 \n\t"
|
||||
"movq %9, %%r15 \n\t"
|
||||
"int $0x80 \n\t"
|
||||
: "=a"(err_code)
|
||||
: "a"(SYS_READ), "m"(fd_num), "m"(addr), "m"(count), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero)
|
||||
: "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rcx", "rdx");
|
||||
count = err_code;
|
||||
// 将读取到的数据打印出来
|
||||
addr = (ul)buf;
|
||||
__asm__ __volatile__(
|
||||
"movq %2, %%r8 \n\t"
|
||||
"int $0x80 \n\t"
|
||||
: "=a"(err_code)
|
||||
: "a"(SYS_PUT_STRING), "m"(addr)
|
||||
: "memory", "r8");
|
||||
// SYS_WRITE
|
||||
char test1[] = "Test11111111jdjdjdjdjdjd\n";
|
||||
|
||||
addr = (uint64_t)&test1;
|
||||
count = 26;
|
||||
__asm__ __volatile__(
|
||||
"movq %2, %%r8 \n\t"
|
||||
"movq %3, %%r9 \n\t"
|
||||
"movq %4, %%r10 \n\t"
|
||||
"movq %5, %%r11 \n\t"
|
||||
"movq %6, %%r12 \n\t"
|
||||
"movq %7, %%r13 \n\t"
|
||||
"movq %8, %%r14 \n\t"
|
||||
"movq %9, %%r15 \n\t"
|
||||
"int $0x80 \n\t"
|
||||
: "=a"(err_code)
|
||||
: "a"(SYS_WRITE), "m"(fd_num), "m"(addr), "m"(count), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero)
|
||||
: "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rcx", "rdx");
|
||||
|
||||
// Test sys_read
|
||||
addr = (uint64_t)&buf;
|
||||
__asm__ __volatile__(
|
||||
"movq %2, %%r8 \n\t"
|
||||
"movq %3, %%r9 \n\t"
|
||||
"movq %4, %%r10 \n\t"
|
||||
"movq %5, %%r11 \n\t"
|
||||
"movq %6, %%r12 \n\t"
|
||||
"movq %7, %%r13 \n\t"
|
||||
"movq %8, %%r14 \n\t"
|
||||
"movq %9, %%r15 \n\t"
|
||||
"int $0x80 \n\t"
|
||||
: "=a"(err_code)
|
||||
: "a"(SYS_READ), "m"(fd_num), "m"(addr), "m"(count), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero)
|
||||
: "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rcx", "rdx");
|
||||
count = err_code;
|
||||
// 将读取到的数据打印出来
|
||||
addr = (ul)buf+20;
|
||||
__asm__ __volatile__(
|
||||
"movq %2, %%r8 \n\t"
|
||||
"int $0x80 \n\t"
|
||||
: "=a"(err_code)
|
||||
: "a"(SYS_PUT_STRING), "m"(addr)
|
||||
: "memory", "r8");
|
||||
|
||||
// Test Sys
|
||||
//}
|
||||
|
||||
// Test sys_close
|
||||
__asm__ __volatile__(
|
||||
@ -152,6 +197,9 @@ void user_level_function()
|
||||
: "=a"(err_code)
|
||||
: "a"(SYS_CLOSE), "m"(fd_num), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero), "m"(zero)
|
||||
: "memory", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", "rcx", "rdx");
|
||||
|
||||
while (1)
|
||||
pause();
|
||||
}
|
||||
while (1)
|
||||
pause();
|
||||
|
@ -46,7 +46,7 @@ void syscall_init()
|
||||
{
|
||||
kinfo("Initializing syscall...");
|
||||
|
||||
set_system_intr_gate(0x80, 0, syscall_int); // 系统调用门
|
||||
set_system_trap_gate(0x80, 0, syscall_int); // 系统调用门
|
||||
}
|
||||
|
||||
/**
|
||||
@ -284,7 +284,7 @@ uint64_t sys_write(struct pt_regs *regs)
|
||||
void *buf = (void *)regs->r9;
|
||||
int64_t count = (int64_t)regs->r10;
|
||||
|
||||
// kdebug("sys read: fd=%d", fd_num);
|
||||
kdebug("sys write: fd=%d", fd_num);
|
||||
|
||||
// 校验文件描述符范围
|
||||
if (fd_num < 0 || fd_num > PROC_MAX_FD_NUM)
|
||||
@ -326,5 +326,6 @@ system_call_t system_call_table[MAX_SYSTEM_CALL_NUM] =
|
||||
[2] = sys_open,
|
||||
[3] = sys_close,
|
||||
[4] = sys_read,
|
||||
[5 ... 254] = system_call_not_exists,
|
||||
[5] = sys_write,
|
||||
[6 ... 254] = system_call_not_exists,
|
||||
[255] = sys_ahci_end_req};
|
||||
|
Loading…
x
Reference in New Issue
Block a user