添加pread&pwrite (#528)

添加pread&pwrite
This commit is contained in:
裕依 2024-02-19 14:53:34 +08:00 committed by GitHub
parent 701589559f
commit 27b967a38a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 160 additions and 31 deletions

View File

@ -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向文件写入指定的字节数的数据
@ -195,6 +180,71 @@ 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 {
@ -202,15 +252,18 @@ impl File {
}
// 如果文件指针已经超过了文件大小,则需要扩展文件大小
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)?;
.write_at(offset, len, buf, &mut self.private_data)?;
if update_offset {
self.offset += len;
return Ok(len);
}
Ok(len)
}
/// @brief 获取文件的元数据

View File

@ -304,7 +304,7 @@ impl Syscall {
/// @brief 根据文件描述符读取文件数据。尝试读取的数据长度与buf的长度相同。
///
/// @param fd 文件描述符编号
/// @param buf 输出缓冲区
/// @param buf 输出缓冲区
///
/// @return Ok(usize) 成功读取的数据的字节数
/// @return Err(SystemError) 读取失败返回posix错误码
@ -326,7 +326,7 @@ impl Syscall {
/// @brief 根据文件描述符向文件写入数据。尝试写入的数据长度与buf的长度相同。
///
/// @param fd 文件描述符编号
/// @param buf 输入缓冲区
/// @param buf 输入缓冲区
///
/// @return Ok(usize) 成功写入的数据的字节数
/// @return Err(SystemError) 写入失败返回posix错误码
@ -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 目标路径

View File

@ -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;
@ -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;
@ -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 => {
@ -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];
@ -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;