Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

添加pread&pwrite #528

Merged
merged 16 commits into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
97 changes: 75 additions & 22 deletions kernel/src/filesystem/vfs/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,22 +169,7 @@ impl File {
/// @return Ok(usize) 成功读取的字节数
/// @return Err(SystemError) 错误码
pub fn read(&mut self, len: usize, buf: &mut [u8]) -> Result<usize, SystemError> {
// 先检查本文件在权限等规则下,是否可读取。
self.readable()?;

if buf.len() < len {
return Err(SystemError::ENOBUFS);
}

// 如果文件指针已经超过了文件大小,则返回0
if self.offset > self.inode.metadata()?.size as usize {
return Ok(0);
}
let len = self
.inode
.read_at(self.offset, len, buf, &mut self.private_data)?;
self.offset += len;
return Ok(len);
self.do_read(self.offset, len, buf, true)
}

/// @brief 从buffer向文件写入指定的字节数的数据
Expand All @@ -195,22 +180,90 @@ impl File {
/// @return Ok(usize) 成功写入的字节数
/// @return Err(SystemError) 错误码
pub fn write(&mut self, len: usize, buf: &[u8]) -> Result<usize, SystemError> {
self.do_write(self.offset, len, buf, true)
}

/// ## 从文件中指定的偏移处读取指定的字节数到buf中
///
/// ### 参数
/// - `offset`: 文件偏移量
/// - `len`: 要读取的字节数
/// - `buf`: 读出缓冲区
///
/// ### 返回值
/// - `Ok(usize)`: 成功读取的字节数
pub fn pread(
&mut self,
offset: usize,
len: usize,
buf: &mut [u8],
) -> Result<usize, SystemError> {
self.do_read(offset, len, buf, false)
}

/// ## 从buf向文件中指定的偏移处写入指定的字节数的数据
///
/// ### 参数
/// - `offset`: 文件偏移量
/// - `len`: 要写入的字节数
/// - `buf`: 写入缓冲区
///
/// ### 返回值
/// - `Ok(usize)`: 成功写入的字节数
pub fn pwrite(&mut self, offset: usize, len: usize, buf: &[u8]) -> Result<usize, SystemError> {
self.do_write(offset, len, buf, false)
}

fn do_read(
&mut self,
offset: usize,
len: usize,
buf: &mut [u8],
update_offset: bool,
) -> Result<usize, SystemError> {
// 先检查本文件在权限等规则下,是否可读取。
self.readable()?;
if buf.len() < len {
return Err(SystemError::ENOBUFS);
}

let len = self
.inode
.read_at(offset, len, buf, &mut self.private_data)?;

if update_offset {
self.offset += len;
}

Ok(len)
}

fn do_write(
&mut self,
offset: usize,
len: usize,
buf: &[u8],
update_offset: bool,
) -> Result<usize, SystemError> {
// 先检查本文件在权限等规则下,是否可写入。
self.writeable()?;
if buf.len() < len {
return Err(SystemError::ENOBUFS);
}

// 如果文件指针已经超过了文件大小,则需要扩展文件大小
let file_size = self.inode.metadata()?.size as usize;
if self.offset > file_size {
self.inode.resize(self.offset)?;
if offset > self.inode.metadata()?.size as usize {
self.inode.resize(offset)?;
}
let len = self
.inode
.write_at(self.offset, len, buf, &mut self.private_data)?;
self.offset += len;
return Ok(len);
.write_at(offset, len, buf, &mut self.private_data)?;

if update_offset {
self.offset += len;
}

Ok(len)
}

/// @brief 获取文件的元数据
Expand Down
48 changes: 46 additions & 2 deletions kernel/src/filesystem/vfs/syscall.rs
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ impl Syscall {
/// @brief 根据文件描述符,读取文件数据。尝试读取的数据长度与buf的长度相同。
///
/// @param fd 文件描述符编号
/// @param buf 输出缓冲区
/// @param buf 输出缓冲区
///
/// @return Ok(usize) 成功读取的数据的字节数
/// @return Err(SystemError) 读取失败,返回posix错误码
Expand All @@ -326,7 +326,7 @@ impl Syscall {
/// @brief 根据文件描述符,向文件写入数据。尝试写入的数据长度与buf的长度相同。
///
/// @param fd 文件描述符编号
/// @param buf 输入缓冲区
/// @param buf 输入缓冲区
///
/// @return Ok(usize) 成功写入的数据的字节数
/// @return Err(SystemError) 写入失败,返回posix错误码
Expand Down Expand Up @@ -362,6 +362,50 @@ impl Syscall {
return file.lock_no_preempt().lseek(seek);
}

/// # sys_pread64 系统调用的实际执行函数
///
/// ## 参数
/// - `fd`: 文件描述符
/// - `buf`: 读出缓冲区
/// - `len`: 要读取的字节数
/// - `offset`: 文件偏移量
pub fn pread(fd: i32, buf: &mut [u8], len: usize, offset: usize) -> Result<usize, SystemError> {
let binding = ProcessManager::current_pcb().fd_table();
let fd_table_guard = binding.read();

let file = fd_table_guard.get_file_by_fd(fd);
if file.is_none() {
return Err(SystemError::EBADF);
}
// drop guard 以避免无法调度的问题
drop(fd_table_guard);
let file = file.unwrap();

return file.lock_no_preempt().pread(offset, len, buf);
}

/// # sys_pwrite64 系统调用的实际执行函数
///
/// ## 参数
/// - `fd`: 文件描述符
/// - `buf`: 写入缓冲区
/// - `len`: 要写入的字节数
/// - `offset`: 文件偏移量
pub fn pwrite(fd: i32, buf: &[u8], len: usize, offset: usize) -> Result<usize, SystemError> {
let binding = ProcessManager::current_pcb().fd_table();
let fd_table_guard = binding.read();

let file = fd_table_guard.get_file_by_fd(fd);
if file.is_none() {
return Err(SystemError::EBADF);
}
// drop guard 以避免无法调度的问题
drop(fd_table_guard);
let file = file.unwrap();

return file.lock_no_preempt().pwrite(offset, len, buf);
}

/// @brief 切换工作目录
///
/// @param dest_path 目标路径
Expand Down
46 changes: 39 additions & 7 deletions kernel/src/syscall/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,7 @@ impl Syscall {
}
SYS_CLOSE => {
let fd = args[0];
let res = Self::close(fd);

res
Self::close(fd)
}
SYS_READ => {
let fd = args[0] as i32;
Expand All @@ -142,8 +140,7 @@ impl Syscall {
UserBufferWriter::new(buf_vaddr as *mut u8, len, from_user)?;

let user_buf = user_buffer_writer.buffer(0)?;
let res = Self::read(fd, user_buf);
res
Self::read(fd, user_buf)
}
SYS_WRITE => {
let fd = args[0] as i32;
Expand All @@ -154,8 +151,7 @@ impl Syscall {
UserBufferReader::new(buf_vaddr as *const u8, len, from_user)?;

let user_buf = user_buffer_reader.read_from_user(0)?;
let res = Self::write(fd, user_buf);
res
Self::write(fd, user_buf)
}

SYS_LSEEK => {
Expand All @@ -173,6 +169,32 @@ impl Syscall {

Self::lseek(fd, w)
}

SYS_PREAD64 => {
let fd = args[0] as i32;
let buf_vaddr = args[1];
let len = args[2];
let offset = args[3];

let mut user_buffer_writer =
UserBufferWriter::new(buf_vaddr as *mut u8, len, frame.from_user())?;
let buf = user_buffer_writer.buffer(0)?;
Self::pread(fd, buf, len, offset)
}

SYS_PWRITE64 => {
let fd = args[0] as i32;
let buf_vaddr = args[1];
let len = args[2];
let offset = args[3];

let user_buffer_reader =
UserBufferReader::new(buf_vaddr as *const u8, len, frame.from_user())?;

let buf = user_buffer_reader.read_from_user(0)?;
Self::pwrite(fd, buf, len, offset)
}

SYS_IOCTL => {
let fd = args[0];
let cmd = args[1];
Expand Down Expand Up @@ -943,6 +965,16 @@ impl Syscall {
Self::umask(mask)
}

SYS_FCHOWN => {
kwarn!("SYS_FCHOWN has not yet been implemented");
Ok(0)
}

SYS_FSYNC => {
kwarn!("SYS_FSYNC has not yet been implemented");
Ok(0)
}

#[cfg(target_arch = "x86_64")]
SYS_CHMOD => {
let pathname = args[0] as *const u8;
Expand Down