Browse Source

:new: lseek系统调用

fslongjin 2 years ago
parent
commit
2ed8bdcfd2

+ 7 - 0
kernel/common/stdio.h

@@ -0,0 +1,7 @@
+#pragma once
+
+#define	SEEK_SET	0	/* Seek relative to start-of-file */
+#define	SEEK_CUR	1	/* Seek relative to current position */
+#define	SEEK_END	2	/* Seek relative to end-of-file */
+
+#define SEEK_MAX	3

+ 1 - 1
kernel/driver/disk/ahci/ahci.c

@@ -312,7 +312,7 @@ static bool ahci_read(HBA_PORT *port, uint32_t startl, uint32_t starth, uint32_t
 static bool ahci_write(HBA_PORT *port, uint32_t startl, uint32_t starth, uint32_t count,
                        uint64_t buf)
 {
-    kdebug("ahci write");
+    // kdebug("ahci write");
     port->is = 0xffff; // Clear pending interrupt bits
     int slot = ahci_find_cmdslot(port);
     if (slot == -1)

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

@@ -5,6 +5,7 @@
 #include <process/spinlock.h>
 #include <mm/slab.h>
 #include <common/errno.h>
+#include <common/stdio.h>
 
 struct vfs_super_block_operations_t fat32_sb_ops;
 struct vfs_dir_entry_operations_t fat32_dEntry_ops;
@@ -484,8 +485,7 @@ void fat32_write_inode(struct vfs_index_node_t *inode)
 
     // 计算目标inode对应数据区的LBA地址
     uint64_t fLBA = fsbi->first_data_sector + (finode->dEntry_location_clus - 2) * fsbi->sec_per_clus;
-    kdebug("fLBA=%d", fLBA);
-    kdebug("fsbi->first_data_sector=%d", fsbi->first_data_sector);
+
 
     struct fat32_Directory_t *buf = (struct fat32_Directory_t *)kmalloc(fsbi->bytes_per_clus, 0);
     memset(buf, 0, fsbi->bytes_per_clus);
@@ -495,13 +495,11 @@ void fat32_write_inode(struct vfs_index_node_t *inode)
     struct fat32_Directory_t *fdEntry = buf + finode->dEntry_location_clus_offset;
 
     // 写入fat32文件系统的dir_entry
-    kdebug("inode->file_size=%#018lx", inode->file_size);
-    kdebug("before   fdEntry->DIR_FileSize=%d", fdEntry->DIR_FileSize);
     fdEntry->DIR_FileSize = inode->file_size;
     fdEntry->DIR_FstClusLO = finode->first_clus & 0xffff;
     fdEntry->DIR_FstClusHI = (finode->first_clus >> 16) | (fdEntry->DIR_FstClusHI & 0xf000);
 
-    kdebug("middle   fdEntry->DIR_FileSize=%d", fdEntry->DIR_FileSize);
+
     // 将dir entry写回磁盘
     ahci_operation.transfer(AHCI_CMD_WRITE_DMA_EXT, fLBA, fsbi->sec_per_clus, (uint64_t)buf, fsbi->ahci_ctrl_num, fsbi->ahci_port_num);
 
@@ -812,9 +810,43 @@ long fat32_write(struct vfs_file_t *file_ptr, char *buf, int64_t count, long *po
     // kdebug("retval=%lld", retval);
     return retval;
 }
-// todo: lseek
-long fat32_lseek(struct vfs_file_t *file_ptr, long offset, long origin)
+
+/**
+ * @brief 调整文件的当前访问位置
+ *
+ * @param file_ptr vfs文件指针
+ * @param offset 调整的偏移量
+ * @param whence 调整方法
+ * @return long 更新后的指针位置
+ */
+long fat32_lseek(struct vfs_file_t *file_ptr, long offset, long whence)
 {
+    struct vfs_index_node_t *inode = file_ptr->dEntry->dir_inode;
+
+    long pos = 0;
+    switch (whence)
+    {
+    case SEEK_SET: // 相对于文件头
+        pos = offset;
+        break;
+    case SEEK_CUR: // 相对于当前位置
+        pos = file_ptr->position + offset;
+        break;
+    case SEEK_END: // 相对于文件末尾
+        pos = file_ptr->dEntry->dir_inode->file_size + offset;
+        break;
+
+    default:
+        return -EINVAL;
+        break;
+    }
+
+    if(pos<0||pos>file_ptr->dEntry->dir_inode->file_size)
+        return -EOVERFLOW;
+    file_ptr->position = pos;
+    
+    kdebug("fat32 lseek -> position=%d", file_ptr->position);
+    return pos;
 }
 // todo: ioctl
 long fat32_ioctl(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr, uint64_t cmd, uint64_t arg)

+ 38 - 0
kernel/process/process.c

@@ -8,6 +8,7 @@
 #include <mm/slab.h>
 #include <sched/sched.h>
 #include <filesystem/fat32/fat32.h>
+#include <common/stdio.h>
 
 extern void system_call(void);
 extern void kernel_thread_func(void);
@@ -142,6 +143,43 @@ void user_level_function()
 
         addr = (uint64_t)&test1;
         count = 19;
+        __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");
+
+        addr = 1;
+        count = SEEK_SET;
+        fd_num = 0;
+        // Test lseek
+        __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_LSEEK), "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");
+
+        // SYS_WRITE
+        char test2[] = "K123456789K";
+
+        addr = (uint64_t)&test2;
+        count = 11;
         __asm__ __volatile__(
             "movq %2, %%r8 \n\t"
             "movq %3, %%r9 \n\t"

+ 34 - 2
kernel/syscall/syscall.c

@@ -268,7 +268,6 @@ uint64_t sys_read(struct pt_regs *regs)
     return ret;
 }
 
-
 /**
  * @brief 向文件写入数据
  *
@@ -305,6 +304,38 @@ uint64_t sys_write(struct pt_regs *regs)
     return ret;
 }
 
+/**
+ * @brief 调整文件的访问位置
+ *
+ * @param fd_num 文件描述符号
+ * @param offset 偏移量
+ * @param whence 调整模式
+ * @return uint64_t
+ */
+uint64_t sys_lseek(struct pt_regs *regs)
+{
+    int fd_num = (int)regs->r8;
+    long offset = (long)regs->r9;
+    int whence = (int)regs->r10;
+
+    kdebug("sys_lseek: fd=%d", fd_num);
+    uint64_t retval = 0;
+
+    // 校验文件描述符范围
+    if (fd_num < 0 || fd_num > PROC_MAX_FD_NUM)
+        return -EBADF;
+
+    // 文件描述符不存在
+    if (current_pcb->fds[fd_num] == NULL)
+        return -EBADF;
+
+    struct vfs_file_t *file_ptr = current_pcb->fds[fd_num];
+    if (file_ptr->file_ops && file_ptr->file_ops->lseek)
+        retval = file_ptr->file_ops->lseek(file_ptr, offset, whence);
+
+    return retval;
+}
+
 ul sys_ahci_end_req(struct pt_regs *regs)
 {
     ahci_end_request();
@@ -327,5 +358,6 @@ system_call_t system_call_table[MAX_SYSTEM_CALL_NUM] =
         [3] = sys_close,
         [4] = sys_read,
         [5] = sys_write,
-        [6 ... 254] = system_call_not_exists,
+        [6] = sys_lseek,
+        [7 ... 254] = system_call_not_exists,
         [255] = sys_ahci_end_req};

+ 1 - 0
kernel/syscall/syscall_num.h

@@ -15,5 +15,6 @@
 #define SYS_CLOSE 3
 #define SYS_READ 4
 #define SYS_WRITE 5
+#define SYS_LSEEK 6
 
 #define SYS_AHCI_END_REQ 255    // AHCI DMA请求结束end_request的系统调用