mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-27 11:23:25 +00:00
Minor improvements to ext2 inode
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
0799976018
commit
4d5d0942ad
@ -95,16 +95,18 @@ impl Inode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn resize(&self, new_size: usize) -> Result<()> {
|
pub fn resize(&self, new_size: usize) -> Result<()> {
|
||||||
let inner = self.inner.upread();
|
if self.type_ != InodeType::File {
|
||||||
if inner.inode_type() != InodeType::File {
|
|
||||||
return_errno!(Errno::EISDIR);
|
return_errno!(Errno::EISDIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let inner = self.inner.upread();
|
||||||
if new_size == inner.file_size() {
|
if new_size == inner.file_size() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut inner = inner.upgrade();
|
let mut inner = inner.upgrade();
|
||||||
inner.resize(new_size)?;
|
inner.resize(new_size)?;
|
||||||
|
|
||||||
let now = now();
|
let now = now();
|
||||||
inner.set_mtime(now);
|
inner.set_mtime(now);
|
||||||
inner.set_ctime(now);
|
inner.set_ctime(now);
|
||||||
@ -121,11 +123,11 @@ impl Inode {
|
|||||||
if name.len() > MAX_FNAME_LEN {
|
if name.len() > MAX_FNAME_LEN {
|
||||||
return_errno!(Errno::ENAMETOOLONG);
|
return_errno!(Errno::ENAMETOOLONG);
|
||||||
}
|
}
|
||||||
|
if self.type_ != InodeType::Dir {
|
||||||
let inner = self.inner.upread();
|
|
||||||
if inner.inode_type() != InodeType::Dir {
|
|
||||||
return_errno!(Errno::ENOTDIR);
|
return_errno!(Errno::ENOTDIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let inner = self.inner.upread();
|
||||||
if inner.hard_links() == 0 {
|
if inner.hard_links() == 0 {
|
||||||
return_errno_with_message!(Errno::ENOENT, "dir removed");
|
return_errno_with_message!(Errno::ENOENT, "dir removed");
|
||||||
}
|
}
|
||||||
@ -171,11 +173,11 @@ impl Inode {
|
|||||||
if name.len() > MAX_FNAME_LEN {
|
if name.len() > MAX_FNAME_LEN {
|
||||||
return_errno!(Errno::ENAMETOOLONG);
|
return_errno!(Errno::ENAMETOOLONG);
|
||||||
}
|
}
|
||||||
|
if self.type_ != InodeType::Dir {
|
||||||
let inner = self.inner.read();
|
|
||||||
if inner.inode_type() != InodeType::Dir {
|
|
||||||
return_errno!(Errno::ENOTDIR);
|
return_errno!(Errno::ENOTDIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let inner = self.inner.read();
|
||||||
if inner.hard_links() == 0 {
|
if inner.hard_links() == 0 {
|
||||||
return_errno_with_message!(Errno::ENOENT, "dir removed");
|
return_errno_with_message!(Errno::ENOENT, "dir removed");
|
||||||
}
|
}
|
||||||
@ -192,11 +194,11 @@ impl Inode {
|
|||||||
if name.len() > MAX_FNAME_LEN {
|
if name.len() > MAX_FNAME_LEN {
|
||||||
return_errno!(Errno::ENAMETOOLONG);
|
return_errno!(Errno::ENAMETOOLONG);
|
||||||
}
|
}
|
||||||
|
if self.type_ != InodeType::Dir {
|
||||||
let inner = self.inner.upread();
|
|
||||||
if inner.inode_type() != InodeType::Dir {
|
|
||||||
return_errno!(Errno::ENOTDIR);
|
return_errno!(Errno::ENOTDIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let inner = self.inner.upread();
|
||||||
if inner.hard_links() == 0 {
|
if inner.hard_links() == 0 {
|
||||||
return_errno_with_message!(Errno::ENOENT, "dir removed");
|
return_errno_with_message!(Errno::ENOENT, "dir removed");
|
||||||
}
|
}
|
||||||
@ -315,10 +317,11 @@ impl Inode {
|
|||||||
|
|
||||||
/// Rename within its own directory.
|
/// Rename within its own directory.
|
||||||
fn rename_within(&self, old_name: &str, new_name: &str) -> Result<()> {
|
fn rename_within(&self, old_name: &str, new_name: &str) -> Result<()> {
|
||||||
let self_inner = self.inner.upread();
|
if self.type_ != InodeType::Dir {
|
||||||
if self_inner.inode_type() != InodeType::Dir {
|
|
||||||
return_errno!(Errno::ENOTDIR);
|
return_errno!(Errno::ENOTDIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let self_inner = self.inner.upread();
|
||||||
if self_inner.hard_links() == 0 {
|
if self_inner.hard_links() == 0 {
|
||||||
return_errno_with_message!(Errno::ENOENT, "dir removed");
|
return_errno_with_message!(Errno::ENOENT, "dir removed");
|
||||||
}
|
}
|
||||||
@ -598,11 +601,12 @@ impl Inode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn readdir_at(&self, offset: usize, visitor: &mut dyn DirentVisitor) -> Result<usize> {
|
pub fn readdir_at(&self, offset: usize, visitor: &mut dyn DirentVisitor) -> Result<usize> {
|
||||||
|
if self.type_ != InodeType::Dir {
|
||||||
|
return_errno!(Errno::ENOTDIR);
|
||||||
|
}
|
||||||
|
|
||||||
let offset_read = {
|
let offset_read = {
|
||||||
let inner = self.inner.read();
|
let inner = self.inner.read();
|
||||||
if inner.inode_type() != InodeType::Dir {
|
|
||||||
return_errno!(Errno::ENOTDIR);
|
|
||||||
}
|
|
||||||
if inner.hard_links() == 0 {
|
if inner.hard_links() == 0 {
|
||||||
return_errno_with_message!(Errno::ENOENT, "dir removed");
|
return_errno_with_message!(Errno::ENOENT, "dir removed");
|
||||||
}
|
}
|
||||||
@ -635,53 +639,48 @@ impl Inode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_link(&self, target: &str) -> Result<()> {
|
pub fn write_link(&self, target: &str) -> Result<()> {
|
||||||
let mut inner = self.inner.write();
|
if self.type_ != InodeType::SymLink {
|
||||||
if inner.inode_type() != InodeType::SymLink {
|
|
||||||
return_errno!(Errno::EISDIR);
|
return_errno!(Errno::EISDIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
inner.write_link(target)?;
|
let mut inner = self.inner.write();
|
||||||
Ok(())
|
inner.write_link(target)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_link(&self) -> Result<String> {
|
pub fn read_link(&self) -> Result<String> {
|
||||||
let inner = self.inner.read();
|
if self.type_ != InodeType::SymLink {
|
||||||
if inner.inode_type() != InodeType::SymLink {
|
|
||||||
return_errno!(Errno::EISDIR);
|
return_errno!(Errno::EISDIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let inner = self.inner.read();
|
||||||
inner.read_link()
|
inner.read_link()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_device_id(&self, device_id: u64) -> Result<()> {
|
pub fn set_device_id(&self, device_id: u64) -> Result<()> {
|
||||||
let mut inner = self.inner.write();
|
if self.type_ != InodeType::BlockDevice && self.type_ != InodeType::CharDevice {
|
||||||
let inode_type = inner.inode_type();
|
|
||||||
if inode_type != InodeType::BlockDevice && inode_type != InodeType::CharDevice {
|
|
||||||
return_errno!(Errno::EISDIR);
|
return_errno!(Errno::EISDIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut inner = self.inner.write();
|
||||||
inner.set_device_id(device_id);
|
inner.set_device_id(device_id);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn device_id(&self) -> u64 {
|
pub fn device_id(&self) -> u64 {
|
||||||
let inner = self.inner.read();
|
if self.type_ != InodeType::BlockDevice && self.type_ != InodeType::CharDevice {
|
||||||
let inode_type = inner.inode_type();
|
|
||||||
if inode_type != InodeType::BlockDevice && inode_type != InodeType::CharDevice {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let inner = self.inner.read();
|
||||||
inner.device_id()
|
inner.device_id()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_at(&self, offset: usize, writer: &mut VmWriter) -> Result<usize> {
|
pub fn read_at(&self, offset: usize, writer: &mut VmWriter) -> Result<usize> {
|
||||||
let bytes_read = {
|
if self.type_ != InodeType::File {
|
||||||
let inner = self.inner.read();
|
return_errno!(Errno::EISDIR);
|
||||||
if inner.inode_type() != InodeType::File {
|
}
|
||||||
return_errno!(Errno::EISDIR);
|
|
||||||
}
|
|
||||||
|
|
||||||
inner.read_at(offset, writer)?
|
let bytes_read = self.inner.read().read_at(offset, writer)?;
|
||||||
};
|
|
||||||
|
|
||||||
self.set_atime(now());
|
self.set_atime(now());
|
||||||
|
|
||||||
@ -690,17 +689,14 @@ impl Inode {
|
|||||||
|
|
||||||
// The offset and the length of buffer must be multiples of the block size.
|
// The offset and the length of buffer must be multiples of the block size.
|
||||||
pub fn read_direct_at(&self, offset: usize, writer: &mut VmWriter) -> Result<usize> {
|
pub fn read_direct_at(&self, offset: usize, writer: &mut VmWriter) -> Result<usize> {
|
||||||
let bytes_read = {
|
if self.type_ != InodeType::File {
|
||||||
let inner = self.inner.read();
|
return_errno!(Errno::EISDIR);
|
||||||
if inner.inode_type() != InodeType::File {
|
}
|
||||||
return_errno!(Errno::EISDIR);
|
if !is_block_aligned(offset) || !is_block_aligned(writer.avail()) {
|
||||||
}
|
return_errno_with_message!(Errno::EINVAL, "not block-aligned");
|
||||||
if !is_block_aligned(offset) || !is_block_aligned(writer.avail()) {
|
}
|
||||||
return_errno_with_message!(Errno::EINVAL, "not block-aligned");
|
|
||||||
}
|
|
||||||
|
|
||||||
inner.read_direct_at(offset, writer)?
|
let bytes_read = self.inner.read().read_direct_at(offset, writer)?;
|
||||||
};
|
|
||||||
|
|
||||||
self.set_atime(now());
|
self.set_atime(now());
|
||||||
|
|
||||||
@ -708,47 +704,45 @@ impl Inode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn write_at(&self, offset: usize, reader: &mut VmReader) -> Result<usize> {
|
pub fn write_at(&self, offset: usize, reader: &mut VmReader) -> Result<usize> {
|
||||||
let bytes_written = {
|
if self.type_ != InodeType::File {
|
||||||
let inner = self.inner.upread();
|
return_errno!(Errno::EISDIR);
|
||||||
if inner.inode_type() != InodeType::File {
|
}
|
||||||
return_errno!(Errno::EISDIR);
|
|
||||||
}
|
|
||||||
|
|
||||||
let file_size = inner.file_size();
|
let inner = self.inner.upread();
|
||||||
let new_size = offset + reader.remain();
|
let file_size = inner.file_size();
|
||||||
if new_size > file_size {
|
let new_size = offset + reader.remain();
|
||||||
let mut inner = inner.upgrade();
|
|
||||||
inner.extend_write_at(offset, reader)?
|
let (bytes_written, mut upgraded_inner) = if new_size > file_size {
|
||||||
} else {
|
let mut inner = inner.upgrade();
|
||||||
inner.write_at(offset, reader)?
|
let len = inner.extend_write_at(offset, reader)?;
|
||||||
}
|
(len, inner)
|
||||||
|
} else {
|
||||||
|
let len = inner.write_at(offset, reader)?;
|
||||||
|
(len, inner.upgrade())
|
||||||
};
|
};
|
||||||
|
|
||||||
let now = now();
|
let now = now();
|
||||||
self.set_mtime(now);
|
upgraded_inner.set_mtime(now);
|
||||||
self.set_ctime(now);
|
upgraded_inner.set_ctime(now);
|
||||||
|
|
||||||
Ok(bytes_written)
|
Ok(bytes_written)
|
||||||
}
|
}
|
||||||
|
|
||||||
// The offset and the length of buffer must be multiples of the block size.
|
// The offset and the length of buffer must be multiples of the block size.
|
||||||
pub fn write_direct_at(&self, offset: usize, reader: &mut VmReader) -> Result<usize> {
|
pub fn write_direct_at(&self, offset: usize, reader: &mut VmReader) -> Result<usize> {
|
||||||
let bytes_written = {
|
if self.type_ != InodeType::File {
|
||||||
let inner = self.inner.upread();
|
return_errno!(Errno::EISDIR);
|
||||||
if inner.inode_type() != InodeType::File {
|
}
|
||||||
return_errno!(Errno::EISDIR);
|
if !is_block_aligned(offset) || !is_block_aligned(reader.remain()) {
|
||||||
}
|
return_errno_with_message!(Errno::EINVAL, "not block aligned");
|
||||||
if !is_block_aligned(offset) || !is_block_aligned(reader.remain()) {
|
}
|
||||||
return_errno_with_message!(Errno::EINVAL, "not block aligned");
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut inner = inner.upgrade();
|
let mut inner = self.inner.write();
|
||||||
inner.write_direct_at(offset, reader)?
|
let bytes_written = inner.write_direct_at(offset, reader)?;
|
||||||
};
|
|
||||||
|
|
||||||
let now = now();
|
let now = now();
|
||||||
self.set_mtime(now);
|
inner.set_mtime(now);
|
||||||
self.set_ctime(now);
|
inner.set_ctime(now);
|
||||||
|
|
||||||
Ok(bytes_written)
|
Ok(bytes_written)
|
||||||
}
|
}
|
||||||
@ -783,7 +777,7 @@ impl Inode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn fallocate(&self, mode: FallocMode, offset: usize, len: usize) -> Result<()> {
|
pub fn fallocate(&self, mode: FallocMode, offset: usize, len: usize) -> Result<()> {
|
||||||
if self.inode_type() != InodeType::File {
|
if self.type_ != InodeType::File {
|
||||||
return_errno_with_message!(Errno::EISDIR, "not regular file");
|
return_errno_with_message!(Errno::EISDIR, "not regular file");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -880,10 +874,15 @@ fn write_lock_two_inodes<'a>(
|
|||||||
RwMutexWriteGuard<'a, InodeInner>,
|
RwMutexWriteGuard<'a, InodeInner>,
|
||||||
RwMutexWriteGuard<'a, InodeInner>,
|
RwMutexWriteGuard<'a, InodeInner>,
|
||||||
) {
|
) {
|
||||||
let mut write_guards = write_lock_multiple_inodes(vec![this, other]);
|
if this.ino < other.ino {
|
||||||
let other_guard = write_guards.pop().unwrap();
|
let this = this.inner.write();
|
||||||
let this_guard = write_guards.pop().unwrap();
|
let other = other.inner.write();
|
||||||
(this_guard, other_guard)
|
(this, other)
|
||||||
|
} else {
|
||||||
|
let other = other.inner.write();
|
||||||
|
let this = this.inner.write();
|
||||||
|
(this, other)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_lock_multiple_inodes(inodes: Vec<&Inode>) -> Vec<RwMutexWriteGuard<'_, InodeInner>> {
|
fn write_lock_multiple_inodes(inodes: Vec<&Inode>) -> Vec<RwMutexWriteGuard<'_, InodeInner>> {
|
||||||
|
Reference in New Issue
Block a user