Optimize the lock usage in RamInode's read/write

This commit is contained in:
Shaowei Song
2024-09-02 13:23:46 +00:00
committed by Tate, Hongliang Tian
parent 4fb4cb4c4a
commit 8bfbdf6642

View File

@ -307,6 +307,13 @@ impl Inner {
_ => None, _ => None,
} }
} }
fn as_named_pipe(&self) -> Option<&NamedPipe> {
match self {
Inner::NamedPipe(pipe) => Some(pipe),
_ => None,
}
}
} }
struct DirEntry { struct DirEntry {
@ -536,29 +543,32 @@ impl Inode for RamInode {
} }
fn read_at(&self, offset: usize, writer: &mut VmWriter) -> Result<usize> { fn read_at(&self, offset: usize, writer: &mut VmWriter) -> Result<usize> {
let self_inode = self.node.upread(); let read_len = {
let self_inode = self.node.read();
let read_len = match &self_inode.inner { match &self_inode.inner {
Inner::File(page_cache) => { Inner::File(page_cache) => {
let (offset, read_len) = { let (offset, read_len) = {
let file_size = self_inode.metadata.size; let file_size = self_inode.metadata.size;
let start = file_size.min(offset); let start = file_size.min(offset);
let end = file_size.min(offset + writer.avail()); let end = file_size.min(offset + writer.avail());
(start, end - start) (start, end - start)
}; };
page_cache.pages().read(offset, writer)?; page_cache.pages().read(offset, writer)?;
self_inode.upgrade().set_atime(now()); read_len
read_len }
Inner::Device(device) => {
device.read(writer)?
// Typically, devices like "/dev/zero" or "/dev/null" do not require modifying
// timestamps here. Please adjust this behavior accordingly if there are special devices.
}
Inner::NamedPipe(named_pipe) => named_pipe.read(writer)?,
_ => return_errno_with_message!(Errno::EISDIR, "read is not supported"),
} }
// TODO: Optimize the lock control (use `read()` rather `upread()`) on device
Inner::Device(device) => {
device.read(writer)?
// Typically, devices like "/dev/zero" or "/dev/null" do not require modifying
// timestamps here. Please adjust this behavior accordingly if there are special devices.
}
Inner::NamedPipe(named_pipe) => named_pipe.read(writer)?,
_ => return_errno_with_message!(Errno::EISDIR, "read is not supported"),
}; };
if self.typ == InodeType::File {
self.set_atime(now());
}
Ok(read_len) Ok(read_len)
} }
@ -567,10 +577,11 @@ impl Inode for RamInode {
} }
fn write_at(&self, offset: usize, reader: &mut VmReader) -> Result<usize> { fn write_at(&self, offset: usize, reader: &mut VmReader) -> Result<usize> {
let self_inode = self.node.upread(); let written_len = match self.typ {
InodeType::File => {
let self_inode = self.node.upread();
let page_cache = self_inode.inner.as_file().unwrap();
let written_len = match &self_inode.inner {
Inner::File(page_cache) => {
let file_size = self_inode.metadata.size; let file_size = self_inode.metadata.size;
let write_len = reader.remain(); let write_len = reader.remain();
let new_size = offset + write_len; let new_size = offset + write_len;
@ -589,13 +600,18 @@ impl Inode for RamInode {
} }
write_len write_len
} }
// TODO: Optimize the lock control (use `read()` rather `upread()`) on device InodeType::CharDevice | InodeType::BlockDevice => {
Inner::Device(device) => { let self_inode = self.node.read();
let device = self_inode.inner.as_device().unwrap();
device.write(reader)? device.write(reader)?
// Typically, devices like "/dev/zero" or "/dev/null" do not require modifying // Typically, devices like "/dev/zero" or "/dev/null" do not require modifying
// timestamps here. Please adjust this behavior accordingly if there are special devices. // timestamps here. Please adjust this behavior accordingly if there are special devices.
} }
Inner::NamedPipe(named_pipe) => named_pipe.write(reader)?, InodeType::NamedPipe => {
let self_inode = self.node.read();
let named_pipe = self_inode.inner.as_named_pipe().unwrap();
named_pipe.write(reader)?
}
_ => return_errno_with_message!(Errno::EISDIR, "write is not supported"), _ => return_errno_with_message!(Errno::EISDIR, "write is not supported"),
}; };
Ok(written_len) Ok(written_len)