mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-21 16:33:24 +00:00
Enable read and write operations of the attribute to handle offset
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
3b1248ba7c
commit
1dd1c8c775
@ -76,6 +76,8 @@ pub enum Error {
|
||||
PermissionDenied,
|
||||
/// Other internal error
|
||||
InternalError(&'static str),
|
||||
/// Arithmetic overflow occurred
|
||||
Overflow,
|
||||
}
|
||||
|
||||
impl core::fmt::Display for Error {
|
||||
@ -88,6 +90,7 @@ impl core::fmt::Display for Error {
|
||||
Error::AttributeError => write!(f, "Attribute error"),
|
||||
Error::PermissionDenied => write!(f, "Permission denied for operation"),
|
||||
Error::InternalError(msg) => write!(f, "Internal error: {}", msg),
|
||||
Error::Overflow => write!(f, "Numerical overflow occurred"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -118,6 +118,33 @@ pub trait SysNode: SysObj {
|
||||
/// Writes the value of an attribute.
|
||||
fn write_attr(&self, name: &str, reader: &mut VmReader) -> Result<usize>;
|
||||
|
||||
/// Reads the value of an attribute from the specified `offset`.
|
||||
fn read_attr_at(&self, name: &str, offset: usize, writer: &mut VmWriter) -> Result<usize> {
|
||||
let (attr_buffer, attr_len) = {
|
||||
let attr_buffer_len = writer.avail().checked_add(offset).ok_or(Error::Overflow)?;
|
||||
let mut buffer = vec![0; attr_buffer_len];
|
||||
let len = self.read_attr(
|
||||
name,
|
||||
&mut VmWriter::from(buffer.as_mut_slice()).to_fallible(),
|
||||
)?;
|
||||
(buffer, len)
|
||||
};
|
||||
|
||||
if attr_len <= offset {
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
writer
|
||||
.write_fallible(VmReader::from(attr_buffer.as_slice()).skip(offset))
|
||||
.map_err(|_| Error::AttributeError)
|
||||
}
|
||||
|
||||
/// Writes the value of an attribute at the specified `offset`.
|
||||
fn write_attr_at(&self, name: &str, _offset: usize, reader: &mut VmReader) -> Result<usize> {
|
||||
// In general, the `offset` for attribute write operations is ignored directly.
|
||||
self.write_attr(name, reader)
|
||||
}
|
||||
|
||||
/// Shows the string value of an attribute.
|
||||
///
|
||||
/// Most attributes are textual, rather binary (see `SysAttrFlags::IS_BINARY`).
|
||||
|
@ -339,6 +339,7 @@ impl From<aster_systree::Error> for Error {
|
||||
AttributeError => Error::new(Errno::EIO),
|
||||
PermissionDenied => Error::new(Errno::EACCES),
|
||||
InternalError(msg) => Error::with_message(Errno::EIO, msg),
|
||||
Overflow => Error::new(Errno::EOVERFLOW),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -376,29 +376,38 @@ impl Inode for SysFsInode {
|
||||
self.read_direct_at(offset, buf)
|
||||
}
|
||||
|
||||
fn read_direct_at(&self, _offset: usize, buf: &mut VmWriter) -> Result<usize> {
|
||||
// TODO: it is unclear whether we should simply ignore the offset
|
||||
// or report errors if it is non-zero.
|
||||
|
||||
fn read_direct_at(&self, offset: usize, buf: &mut VmWriter) -> Result<usize> {
|
||||
let InnerNode::Attr(attr, leaf) = &self.inner_node else {
|
||||
return Err(Error::new(Errno::EINVAL));
|
||||
};
|
||||
|
||||
// TODO: check read permission
|
||||
Ok(leaf.read_attr(attr.name(), buf)?)
|
||||
let len = if offset == 0 {
|
||||
leaf.read_attr(attr.name(), buf)?
|
||||
} else {
|
||||
// The `read_attr_at` method is more general than `read_attr`,
|
||||
// but it could be less efficient. So we only use the more general form when necessary.
|
||||
leaf.read_attr_at(attr.name(), offset, buf)?
|
||||
};
|
||||
|
||||
Ok(len)
|
||||
}
|
||||
|
||||
fn write_at(&self, offset: usize, buf: &mut VmReader) -> Result<usize> {
|
||||
self.write_direct_at(offset, buf)
|
||||
}
|
||||
|
||||
fn write_direct_at(&self, _offset: usize, buf: &mut VmReader) -> Result<usize> {
|
||||
fn write_direct_at(&self, offset: usize, buf: &mut VmReader) -> Result<usize> {
|
||||
let InnerNode::Attr(attr, leaf) = &self.inner_node else {
|
||||
return Err(Error::new(Errno::EINVAL));
|
||||
};
|
||||
|
||||
// TODO: check write permission
|
||||
Ok(leaf.write_attr(attr.name(), buf)?)
|
||||
let len = if offset == 0 {
|
||||
leaf.write_attr(attr.name(), buf)?
|
||||
} else {
|
||||
leaf.write_attr_at(attr.name(), offset, buf)?
|
||||
};
|
||||
|
||||
Ok(len)
|
||||
}
|
||||
|
||||
fn create(&self, _name: &str, _type_: InodeType, _mode: InodeMode) -> Result<Arc<dyn Inode>> {
|
||||
|
Reference in New Issue
Block a user