Преглед изворни кода

:new: fat32_write (存在写入bug)

fslongjin пре 2 година
родитељ
комит
9db1c3f74e
4 измењених фајлова са 251 додато и 43 уклоњено
  1. 4 5
      kernel/filesystem/VFS/VFS.h
  2. 167 7
      kernel/filesystem/fat32/fat32.c
  3. 76 28
      kernel/process/process.c
  4. 4 3
      kernel/syscall/syscall.c

+ 4 - 5
kernel/filesystem/VFS/VFS.h

@@ -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 按照路径查找文件
  *

+ 167 - 7
kernel/filesystem/fat32/fat32.c

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

+ 76 - 28
kernel/process/process.c

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

+ 4 - 3
kernel/syscall/syscall.c

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