mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-23 01:13:23 +00:00
Add read_at and write_at for FileLike and InodeHandle
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
6e9516daa4
commit
14ada9000a
@ -23,6 +23,23 @@ pub trait FileLike: Send + Sync + Any {
|
||||
return_errno_with_message!(Errno::EINVAL, "write is not supported");
|
||||
}
|
||||
|
||||
/// Read at the given file offset.
|
||||
///
|
||||
/// The file must be seekable to support `read_at`.
|
||||
/// Unlike [`read`], `read_at` will not change the file offset.
|
||||
fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize> {
|
||||
return_errno_with_message!(Errno::EINVAL, "read_at is not supported");
|
||||
}
|
||||
|
||||
/// Write at the given file offset.
|
||||
///
|
||||
/// The file must be seekable to support `write_at`.
|
||||
/// Unlike [`write`], `write_at` will not change the file offset.
|
||||
/// If the file is append-only, the `offset` will be ignored.
|
||||
fn write_at(&self, offset: usize, buf: &[u8]) -> Result<usize> {
|
||||
return_errno_with_message!(Errno::EINVAL, "write_at is not supported");
|
||||
}
|
||||
|
||||
fn ioctl(&self, cmd: IoctlCmd, arg: usize) -> Result<i32> {
|
||||
return_errno_with_message!(Errno::EINVAL, "ioctl is not supported");
|
||||
}
|
||||
|
@ -98,6 +98,20 @@ impl FileLike for InodeHandle<Rights> {
|
||||
self.0.write(buf)
|
||||
}
|
||||
|
||||
fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize> {
|
||||
if !self.1.contains(Rights::READ) {
|
||||
return_errno_with_message!(Errno::EBADF, "file is not readable");
|
||||
}
|
||||
self.0.read_at(offset, buf)
|
||||
}
|
||||
|
||||
fn write_at(&self, offset: usize, buf: &[u8]) -> Result<usize> {
|
||||
if !self.1.contains(Rights::WRITE) {
|
||||
return_errno_with_message!(Errno::EBADF, "file is not writable");
|
||||
}
|
||||
self.0.write_at(offset, buf)
|
||||
}
|
||||
|
||||
fn resize(&self, new_size: usize) -> Result<()> {
|
||||
if !self.1.contains(Rights::WRITE) {
|
||||
return_errno_with_message!(Errno::EINVAL, "File is not writable");
|
||||
|
@ -41,42 +41,64 @@ struct InodeHandle_ {
|
||||
|
||||
impl InodeHandle_ {
|
||||
pub fn read(&self, buf: &mut [u8]) -> Result<usize> {
|
||||
let mut offset = self.offset.lock();
|
||||
|
||||
if let Some(ref file_io) = self.file_io {
|
||||
return file_io.read(buf);
|
||||
}
|
||||
|
||||
let len = if self.status_flags().contains(StatusFlags::O_DIRECT) {
|
||||
self.dentry.inode().read_direct_at(*offset, buf)?
|
||||
} else {
|
||||
self.dentry.inode().read_at(*offset, buf)?
|
||||
};
|
||||
let mut offset = self.offset.lock();
|
||||
|
||||
let len = self.read_at(*offset, buf)?;
|
||||
|
||||
*offset += len;
|
||||
Ok(len)
|
||||
}
|
||||
|
||||
pub fn write(&self, buf: &[u8]) -> Result<usize> {
|
||||
let mut offset = self.offset.lock();
|
||||
|
||||
if let Some(ref file_io) = self.file_io {
|
||||
return file_io.write(buf);
|
||||
}
|
||||
|
||||
let mut offset = self.offset.lock();
|
||||
|
||||
if self.status_flags().contains(StatusFlags::O_APPEND) {
|
||||
*offset = self.dentry.size();
|
||||
}
|
||||
let len = if self.status_flags().contains(StatusFlags::O_DIRECT) {
|
||||
self.dentry.inode().write_direct_at(*offset, buf)?
|
||||
} else {
|
||||
self.dentry.inode().write_at(*offset, buf)?
|
||||
};
|
||||
|
||||
let len = self.write_at(*offset, buf)?;
|
||||
|
||||
*offset += len;
|
||||
Ok(len)
|
||||
}
|
||||
|
||||
pub fn read_at(&self, offset: usize, buf: &mut [u8]) -> Result<usize> {
|
||||
if let Some(ref file_io) = self.file_io {
|
||||
todo!("support read_at for FileIo");
|
||||
}
|
||||
|
||||
if self.status_flags().contains(StatusFlags::O_DIRECT) {
|
||||
self.dentry.inode().read_direct_at(offset, buf)
|
||||
} else {
|
||||
self.dentry.inode().read_at(offset, buf)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_at(&self, mut offset: usize, buf: &[u8]) -> Result<usize> {
|
||||
if let Some(ref file_io) = self.file_io {
|
||||
todo!("support write_at for FileIo");
|
||||
}
|
||||
|
||||
if self.status_flags().contains(StatusFlags::O_APPEND) {
|
||||
// If the file has the O_APPEND flag, the offset is ignored
|
||||
offset = self.dentry.size();
|
||||
}
|
||||
|
||||
if self.status_flags().contains(StatusFlags::O_DIRECT) {
|
||||
self.dentry.inode().write_direct_at(offset, buf)
|
||||
} else {
|
||||
self.dentry.inode().write_at(offset, buf)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn read_to_end(&self, buf: &mut Vec<u8>) -> Result<usize> {
|
||||
if self.file_io.is_some() {
|
||||
return_errno_with_message!(Errno::EINVAL, "file io does not support read to end");
|
||||
|
Reference in New Issue
Block a user