diff --git a/kernel/filesystem/VFS/VFS.h b/kernel/filesystem/VFS/VFS.h index d3a6b655..a31c0dbb 100644 --- a/kernel/filesystem/VFS/VFS.h +++ b/kernel/filesystem/VFS/VFS.h @@ -34,7 +34,7 @@ extern struct vfs_superblock_t *vfs_root_sb; #define VFS_IF_FILE (1UL << 0) #define VFS_IF_DIR (1UL << 1) #define VFS_IF_DEVICE (1UL << 2) -#define VFS_IF_DEAD (1UL<<3) /* removed, but still open directory */ +#define VFS_IF_DEAD (1UL << 3) /* removed, but still open directory */ struct vfs_super_block_operations_t; struct vfs_inode_operations_t; @@ -42,7 +42,7 @@ struct vfs_inode_operations_t; struct vfs_index_node_t; struct vfs_dir_entry_operations_t; -#define VFS_DF_MOUNTED (1 << 0) // 当前dentry是一个挂载点 +#define VFS_DF_MOUNTED (1 << 0) // 当前dentry是一个挂载点 #define VFS_DF_CANNOT_MOUNT (1 << 1) // 当前dentry是一个挂载点 struct vfs_dir_entry_t { @@ -84,6 +84,18 @@ struct vfs_index_node_t void *private_inode_info; }; +/** + * @brief 文件的mode + * + */ +#define VFS_FILE_MODE_READ (1 << 0) +#define VFS_FILE_MODE_WRITE (1 << 1) +#define VFS_FILE_MODE_RW (VFS_FILE_MODE_READ | VFS_FILE_MODE_WRITE) + +#define vfs_file_can_read(file) (((file)->mode) & VFS_FILE_MODE_READ) +#define vfs_file_can_write(file) (((file)->mode) & VFS_FILE_MODE_WRITE) +#define vfs_file_can_rw(file) ((((file)->mode) & VFS_FILE_MODE_RW) == VFS_FILE_MODE_RW) + /** * @brief 文件描述符 * @@ -223,10 +235,10 @@ struct vfs_dir_entry_t *vfs_alloc_dentry(const int name_size); /** * @brief 分配inode并将引用计数初始化为1 - * + * * @return struct vfs_index_node_t * 分配得到的inode */ -struct vfs_index_node_t * vfs_alloc_inode(); +struct vfs_index_node_t *vfs_alloc_inode(); /** * @brief 打开文件 diff --git a/kernel/ipc/pipe.c b/kernel/ipc/pipe.c index bf0fb05f..905731f0 100644 --- a/kernel/ipc/pipe.c +++ b/kernel/ipc/pipe.c @@ -7,16 +7,24 @@ #include #include -#define MAX_PIPE_BUFF_SIZE 512 - -struct pipe_t { +struct pipe_data_t +{ volatile unsigned int valid_cnt; unsigned int read_pos; unsigned int write_pos; wait_queue_node_t read_wait_queue; wait_queue_node_t write_wait_queue; - char buf[MAX_PIPE_BUFF_SIZE]; spinlock_t lock; +} __attribute__((packed)); + +// 由于kmalloc分配的内存是按照2^n对齐的,因此我们需要这样来确定pipe的buffer大小以消除内部碎片 +// 我们设定pipe的总大小为1024字节 +#define PIPE_BUFF_SIZE (1024 - sizeof(struct pipe_data_t)) + +struct pipe_t +{ + struct pipe_data_t data; + char buf[PIPE_BUFF_SIZE]; }; long pipe_read(struct vfs_file_t *file_ptr, char *buf, @@ -27,24 +35,27 @@ long pipe_read(struct vfs_file_t *file_ptr, char *buf, kdebug("pipe_read into!\n"); pipe_ptr = (struct pipe_t *)file_ptr->private_data; - spin_lock(&pipe_ptr->lock); - while (pipe_ptr->valid_cnt == 0) { + spin_lock(&pipe_ptr->data.lock); + while (pipe_ptr->data.valid_cnt == 0) + { /* pipe 空 */ kdebug("pipe_read empty!\n"); - wait_queue_wakeup(&pipe_ptr->write_wait_queue, PROC_UNINTERRUPTIBLE); - wait_queue_sleep_on_unlock(&pipe_ptr->read_wait_queue, (void *)&pipe_ptr->lock); - spin_lock(&pipe_ptr->lock); + wait_queue_wakeup(&pipe_ptr->data.write_wait_queue, PROC_UNINTERRUPTIBLE); + wait_queue_sleep_on_unlock(&pipe_ptr->data.read_wait_queue, (void *)&pipe_ptr->data.lock); + spin_lock(&pipe_ptr->data.lock); } - for (i = 0; i < pipe_ptr->valid_cnt; i++) { - if (i == count) { + for (i = 0; i < pipe_ptr->data.valid_cnt; i++) + { + if (i == count) + { break; } - copy_to_user(buf + i, &pipe_ptr->buf[pipe_ptr->read_pos], sizeof(char)); - pipe_ptr->read_pos = (pipe_ptr->read_pos + 1) % MAX_PIPE_BUFF_SIZE; + copy_to_user(buf + i, &pipe_ptr->buf[pipe_ptr->data.read_pos], sizeof(char)); + pipe_ptr->data.read_pos = (pipe_ptr->data.read_pos + 1) % PIPE_BUFF_SIZE; } - pipe_ptr->valid_cnt = pipe_ptr->valid_cnt - i; - spin_unlock(&pipe_ptr->lock); - wait_queue_wakeup(&pipe_ptr->write_wait_queue, PROC_UNINTERRUPTIBLE); + pipe_ptr->data.valid_cnt = pipe_ptr->data.valid_cnt - i; + spin_unlock(&pipe_ptr->data.lock); + wait_queue_wakeup(&pipe_ptr->data.write_wait_queue, PROC_UNINTERRUPTIBLE); kdebug("pipe_read end!\n"); return i; @@ -57,24 +68,27 @@ long pipe_write(struct vfs_file_t *file_ptr, char *buf, kdebug("pipe_write into!\n"); pipe_ptr = (struct pipe_t *)file_ptr->private_data; - spin_lock(&pipe_ptr->lock); - while (pipe_ptr->valid_cnt + count >= MAX_PIPE_BUFF_SIZE) { + spin_lock(&pipe_ptr->data.lock); + while (pipe_ptr->data.valid_cnt + count >= PIPE_BUFF_SIZE) + { /* pipe 满 */ kdebug("pipe_write pipe full!\n"); - wait_queue_wakeup(&pipe_ptr->read_wait_queue, PROC_UNINTERRUPTIBLE); - wait_queue_sleep_on_unlock(&pipe_ptr->write_wait_queue, (void *)&pipe_ptr->lock); - spin_lock(&pipe_ptr->lock); + wait_queue_wakeup(&pipe_ptr->data.read_wait_queue, PROC_UNINTERRUPTIBLE); + wait_queue_sleep_on_unlock(&pipe_ptr->data.write_wait_queue, (void *)&pipe_ptr->data.lock); + spin_lock(&pipe_ptr->data.lock); } - for (i = pipe_ptr->valid_cnt; i < MAX_PIPE_BUFF_SIZE; i++) { - if (i - pipe_ptr->valid_cnt == count) { + for (i = pipe_ptr->data.valid_cnt; i < PIPE_BUFF_SIZE; i++) + { + if (i - pipe_ptr->data.valid_cnt == count) + { break; } - copy_from_user(&pipe_ptr->buf[pipe_ptr->write_pos], buf + i, sizeof(char)); - pipe_ptr->write_pos = (pipe_ptr->write_pos + 1) % MAX_PIPE_BUFF_SIZE; + copy_from_user(&pipe_ptr->buf[pipe_ptr->data.write_pos], buf + i, sizeof(char)); + pipe_ptr->data.write_pos = (pipe_ptr->data.write_pos + 1) % PIPE_BUFF_SIZE; } - pipe_ptr->valid_cnt += count; - spin_unlock(&pipe_ptr->lock); - wait_queue_wakeup(&pipe_ptr->read_wait_queue, PROC_UNINTERRUPTIBLE); + pipe_ptr->data.valid_cnt += count; + spin_unlock(&pipe_ptr->data.lock); + wait_queue_wakeup(&pipe_ptr->data.read_wait_queue, PROC_UNINTERRUPTIBLE); kdebug("pipe_write out!\n"); return count; @@ -86,27 +100,27 @@ long pipe_close(struct vfs_index_node_t *inode, struct vfs_file_t *file_ptr) } struct vfs_file_operations_t g_pipe_file_ops = { - .open = NULL, - .close = pipe_close, - .read = pipe_read, - .write = pipe_write, - .lseek = NULL, - .ioctl = NULL, - .readdir = NULL, + .open = NULL, + .close = pipe_close, + .read = pipe_read, + .write = pipe_write, + .lseek = NULL, + .ioctl = NULL, + .readdir = NULL, }; static struct pipe_t *pipe_alloc() { struct pipe_t *pipe_ptr = NULL; - - pipe_ptr = (struct pipe_t *)kmalloc(sizeof(struct pipe_t), 0); - spin_init(&pipe_ptr->lock); - pipe_ptr->read_pos = 0; - pipe_ptr->write_pos = 0; - pipe_ptr->valid_cnt = 0; - memset(pipe_ptr->buf, 0, MAX_PIPE_BUFF_SIZE); - wait_queue_init(&pipe_ptr->read_wait_queue, NULL); - wait_queue_init(&pipe_ptr->write_wait_queue, NULL); + + pipe_ptr = (struct pipe_t *)kzalloc(sizeof(struct pipe_t), 0); + spin_init(&pipe_ptr->data.lock); + pipe_ptr->data.read_pos = 0; + pipe_ptr->data.write_pos = 0; + pipe_ptr->data.valid_cnt = 0; + memset(pipe_ptr->buf, 0, PIPE_BUFF_SIZE); + wait_queue_init(&pipe_ptr->data.read_wait_queue, NULL); + wait_queue_init(&pipe_ptr->data.write_wait_queue, NULL); return pipe_ptr; } @@ -116,7 +130,7 @@ static struct pipe_t *pipe_alloc() * * @param fd(r8) 文件句柄指针 * @param num(r9) 文件句柄个数 - * @return uint64_t + * @return uint64_t */ uint64_t sys_pipe(struct pt_regs *regs) { @@ -130,19 +144,19 @@ uint64_t sys_pipe(struct pt_regs *regs) /* step1 申请pipe结构体、初始化 */ pipe_ptr = pipe_alloc(); /* step2 申请2个fd文件句柄,1个作为读端、1个作为写端 */ - read_file = (struct vfs_file_t *)kmalloc(sizeof(struct vfs_file_t), 0); - memset(read_file, 0, sizeof(struct vfs_file_t)); + read_file = (struct vfs_file_t *)kzalloc(sizeof(struct vfs_file_t), 0); fd[0] = process_fd_alloc(read_file); - if (fd[0] == -1) { + if (fd[0] == -1) + { kdebug("pipe alloc read fd fail!\n"); kfree(pipe_ptr); kfree(read_file); return -1; } - write_file = (struct vfs_file_t *)kmalloc(sizeof(struct vfs_file_t), 0); - memset(write_file, 0, sizeof(struct vfs_file_t)); + write_file = (struct vfs_file_t *)kzalloc(sizeof(struct vfs_file_t), 0); fd[1] = process_fd_alloc(write_file); - if (fd[1] == -1) { + if (fd[1] == -1) + { kdebug("pipe alloc write fd fail!\n"); kfree(pipe_ptr); kfree(read_file); @@ -150,12 +164,12 @@ uint64_t sys_pipe(struct pt_regs *regs) return -1; } /* step3 绑定pipe和file */ - read_file->private_data = (void *)pipe_ptr; - read_file->file_ops = &g_pipe_file_ops; - read_file->mode = ATTR_READ_ONLY; - write_file->private_data = (void *)pipe_ptr; - write_file->file_ops = &g_pipe_file_ops; - write_file->mode = O_WRONLY; + read_file->private_data = (void *)pipe_ptr; + read_file->file_ops = &g_pipe_file_ops; + read_file->mode = VFS_FILE_MODE_READ; + write_file->private_data = (void *)pipe_ptr; + write_file->file_ops = &g_pipe_file_ops; + write_file->mode = VFS_FILE_MODE_WRITE; kdebug("pipe creat end!\n"); return 0;