Add support for truncate syscall

This commit is contained in:
LI Qing
2024-01-05 14:44:19 +08:00
committed by Tate, Hongliang Tian
parent 31998d1cd4
commit 195c6a0739
19 changed files with 167 additions and 44 deletions

View File

@ -412,8 +412,9 @@ impl RamInode {
}
impl PageCacheBackend for RamInode {
fn read_page(&self, _idx: usize, _frame: &VmFrame) -> Result<()> {
// do nothing
fn read_page(&self, _idx: usize, frame: &VmFrame) -> Result<()> {
// Initially, any block/page in a RamFs inode contains all zeros
frame.zero();
Ok(())
}
@ -446,9 +447,9 @@ impl Inode for RamInode {
return_errno_with_message!(Errno::EISDIR, "read is not supported");
};
let (offset, read_len) = {
let file_len = self_inode.metadata.size;
let start = file_len.min(offset);
let end = file_len.min(offset + buf.len());
let file_size = self_inode.metadata.size;
let start = file_size.min(offset);
let end = file_size.min(offset + buf.len());
(start, end - start)
};
page_cache
@ -470,17 +471,17 @@ impl Inode for RamInode {
let Some(page_cache) = self_inode.inner.as_file() else {
return_errno_with_message!(Errno::EISDIR, "write is not supported");
};
let file_len = self_inode.metadata.size;
let new_len = offset + buf.len();
let should_expand_len = new_len > file_len;
if should_expand_len {
page_cache.pages().resize(new_len)?;
let file_size = self_inode.metadata.size;
let new_size = offset + buf.len();
let should_expand_size = new_size > file_size;
if should_expand_size {
page_cache.pages().resize(new_size)?;
}
page_cache.pages().write_bytes(offset, buf)?;
if should_expand_len {
if should_expand_size {
// Turn the read guard into a write guard without releasing the lock.
let mut self_inode = self_inode.upgrade();
self_inode.resize(new_len);
self_inode.resize(new_size);
}
Ok(buf.len())
}
@ -489,12 +490,26 @@ impl Inode for RamInode {
self.write_at(offset, buf)
}
fn len(&self) -> usize {
fn size(&self) -> usize {
self.0.read().metadata.size
}
fn resize(&self, new_size: usize) -> Result<()> {
self.0.write().resize(new_size);
let self_inode = self.0.upread();
if self_inode.inner.as_file().is_none() {
return_errno!(Errno::EISDIR);
}
let file_size = self_inode.metadata.size;
if file_size == new_size {
return Ok(());
}
let mut self_inode = self_inode.upgrade();
self_inode.resize(new_size);
let page_cache = self_inode.inner.as_file().unwrap();
page_cache.pages().resize(new_size)?;
Ok(())
}