Simplify the frequent code of getting a file reference

This commit is contained in:
Tate, Hongliang Tian 2020-03-26 10:32:11 +00:00
parent 5933499f9b
commit 1a35188212
21 changed files with 96 additions and 122 deletions

@ -46,9 +46,11 @@ pub fn do_faccessat(
pub fn do_access(path: &str, mode: AccessibilityCheckMode) -> Result<()> {
debug!("access: path: {:?}, mode: {:?}", path, mode);
let inode = {
let current_ref = process::get_current();
let mut current = current_ref.lock().unwrap();
let inode = current.lookup_inode(path)?;
current.lookup_inode(path)?
};
//let metadata = inode.get_metadata();
// TODO: check metadata.mode with mode
Ok(())

@ -1,15 +1,17 @@
use super::*;
pub fn do_chdir(path: &str) -> Result<()> {
debug!("chdir: path: {:?}", path);
let current_ref = process::get_current();
let mut current_process = current_ref.lock().unwrap();
debug!("chdir: path: {:?}", path);
let inode = current_process.lookup_inode(path)?;
let info = inode.metadata()?;
if info.type_ != FileType::Dir {
return_errno!(ENOTDIR, "");
}
current_process.change_cwd(path);
Ok(())
}

@ -67,9 +67,7 @@ pub fn do_getdents64(fd: FileDesc, buf: &mut [u8]) -> Result<usize> {
buf.as_ptr(),
buf.len()
);
let current_ref = process::get_current();
let current_process = current_ref.lock().unwrap();
let file_ref = current_process.get_files().lock().unwrap().get(fd)?;
let file_ref = process::get_file(fd)?;
let info = file_ref.metadata()?;
if info.type_ != FileType::Dir {
return_errno!(ENOTDIR, "");

@ -24,9 +24,7 @@ impl DirFd {
// Get the absolute path of directory
pub fn get_dir_path(dirfd: FileDesc) -> Result<String> {
let dir_path = {
let current_ref = process::get_current();
let proc = current_ref.lock().unwrap();
let file_ref = proc.get_files().lock().unwrap().get(dirfd)?;
let file_ref = process::get_file(dirfd)?;
if let Ok(inode_file) = file_ref.as_inode_file() {
if inode_file.metadata()?.type_ != FileType::Dir {
return_errno!(ENOTDIR, "not a directory");

@ -2,18 +2,14 @@ use super::*;
pub fn do_fsync(fd: FileDesc) -> Result<()> {
debug!("fsync: fd: {}", fd);
let current_ref = process::get_current();
let current_process = current_ref.lock().unwrap();
let file_ref = current_process.get_files().lock().unwrap().get(fd)?;
let file_ref = process::get_file(fd)?;
file_ref.sync_all()?;
Ok(())
}
pub fn do_fdatasync(fd: FileDesc) -> Result<()> {
debug!("fdatasync: fd: {}", fd);
let current_ref = process::get_current();
let current_process = current_ref.lock().unwrap();
let file_ref = current_process.get_files().lock().unwrap().get(fd)?;
let file_ref = process::get_file(fd)?;
file_ref.sync_data()?;
Ok(())
}

@ -66,8 +66,6 @@ impl<'a> IoctlCmd<'a> {
pub fn do_ioctl(fd: FileDesc, cmd: &mut IoctlCmd) -> Result<()> {
debug!("ioctl: fd: {}, cmd: {:?}", fd, cmd);
let current_ref = process::get_current();
let current_process = current_ref.lock().unwrap();
let file_ref = current_process.get_files().lock().unwrap().get(fd)?;
let file_ref = process::get_file(fd)?;
file_ref.ioctl(cmd)
}

@ -1,13 +1,16 @@
use super::*;
pub fn do_link(oldpath: &str, newpath: &str) -> Result<()> {
let current_ref = process::get_current();
let current_process = current_ref.lock().unwrap();
debug!("link: oldpath: {:?}, newpath: {:?}", oldpath, newpath);
let (new_dir_path, new_file_name) = split_path(&newpath);
let (inode, new_dir_inode) = {
let current_ref = process::get_current();
let current_process = current_ref.lock().unwrap();
let inode = current_process.lookup_inode(&oldpath)?;
let new_dir_inode = current_process.lookup_inode(new_dir_path)?;
(inode, new_dir_inode)
};
new_dir_inode.link(new_file_name, &inode)?;
Ok(())
}

@ -1,8 +1,6 @@
use super::*;
pub fn do_lseek(fd: FileDesc, offset: SeekFrom) -> Result<off_t> {
let current_ref = process::get_current();
let current_process = current_ref.lock().unwrap();
let file_ref = current_process.get_files().lock().unwrap().get(fd)?;
let file_ref = process::get_file(fd)?;
file_ref.seek(offset)
}

@ -1,13 +1,15 @@
use super::*;
pub fn do_mkdir(path: &str, mode: usize) -> Result<()> {
let current_ref = process::get_current();
let current_process = current_ref.lock().unwrap();
// TODO: check pathname
debug!("mkdir: path: {:?}, mode: {:#o}", path, mode);
let (dir_path, file_name) = split_path(&path);
let inode = current_process.lookup_inode(dir_path)?;
let inode = {
let current_ref = process::get_current();
let current_process = current_ref.lock().unwrap();
current_process.lookup_inode(dir_path)?
};
if inode.find(file_name).is_ok() {
return_errno!(EEXIST, "");
}

@ -2,24 +2,18 @@ use super::*;
pub fn do_read(fd: FileDesc, buf: &mut [u8]) -> Result<usize> {
debug!("read: fd: {}", fd);
let current_ref = process::get_current();
let current_process = current_ref.lock().unwrap();
let file_ref = current_process.get_files().lock().unwrap().get(fd)?;
let file_ref = process::get_file(fd)?;
file_ref.read(buf)
}
pub fn do_readv(fd: FileDesc, bufs: &mut [&mut [u8]]) -> Result<usize> {
debug!("readv: fd: {}", fd);
let current_ref = process::get_current();
let current_process = current_ref.lock().unwrap();
let file_ref = current_process.get_files().lock().unwrap().get(fd)?;
let file_ref = process::get_file(fd)?;
file_ref.readv(bufs)
}
pub fn do_pread(fd: FileDesc, buf: &mut [u8], offset: usize) -> Result<usize> {
debug!("pread: fd: {}, offset: {}", fd, offset);
let current_ref = process::get_current();
let current_process = current_ref.lock().unwrap();
let file_ref = current_process.get_files().lock().unwrap().get(fd)?;
let file_ref = process::get_file(fd)?;
file_ref.read_at(offset, buf)
}

@ -1,12 +1,14 @@
use super::*;
pub fn do_rmdir(path: &str) -> Result<()> {
let current_ref = process::get_current();
let current_process = current_ref.lock().unwrap();
debug!("rmdir: path: {:?}", path);
let (dir_path, file_name) = split_path(&path);
let dir_inode = current_process.lookup_inode(dir_path)?;
let dir_inode = {
let current_ref = process::get_current();
let current_process = current_ref.lock().unwrap();
current_process.lookup_inode(dir_path)?
};
let file_inode = dir_inode.find(file_name)?;
if file_inode.metadata()?.type_ != FileType::Dir {
return_errno!(ENOTDIR, "rmdir on not directory");

@ -141,9 +141,7 @@ fn do_stat(path: &str) -> Result<Stat> {
pub fn do_fstat(fd: u32) -> Result<Stat> {
debug!("fstat: fd: {}", fd);
let current_ref = process::get_current();
let current_process = current_ref.lock().unwrap();
let file_ref = current_process.get_files().lock().unwrap().get(fd)?;
let file_ref = process::get_file(fd as FileDesc)?;
let stat = Stat::from(file_ref.metadata()?);
// TODO: handle symlink
Ok(stat)
@ -151,9 +149,11 @@ pub fn do_fstat(fd: u32) -> Result<Stat> {
pub fn do_lstat(path: &str) -> Result<Stat> {
debug!("lstat: path: {}", path);
let inode = {
let current_ref = process::get_current();
let current_process = current_ref.lock().unwrap();
let inode = current_process.lookup_inode(&path)?;
current_process.lookup_inode(&path)?
};
let stat = Stat::from(inode.metadata()?);
Ok(stat)
}

@ -12,9 +12,7 @@ pub fn do_readlink(path: &str, buf: &mut [u8]) -> Result<usize> {
.trim_start_matches("/proc/self/fd/")
.parse::<FileDesc>()
.map_err(|e| errno!(EBADF, "Invalid file descriptor"))?;
let current_ref = process::get_current();
let current = current_ref.lock().unwrap();
let file_ref = current.get_files().lock().unwrap().get(fd)?;
let file_ref = process::get_file(fd)?;
if let Ok(inode_file) = file_ref.as_inode_file() {
inode_file.get_abs_path().to_owned()
} else {

@ -2,17 +2,18 @@ use super::*;
pub fn do_truncate(path: &str, len: usize) -> Result<()> {
debug!("truncate: path: {:?}, len: {}", path, len);
let inode = {
let current_ref = process::get_current();
let current_process = current_ref.lock().unwrap();
current_process.lookup_inode(&path)?.resize(len)?;
current_process.lookup_inode(&path)?
};
inode.resize(len)?;
Ok(())
}
pub fn do_ftruncate(fd: FileDesc, len: usize) -> Result<()> {
debug!("ftruncate: fd: {}, len: {}", fd, len);
let current_ref = process::get_current();
let current_process = current_ref.lock().unwrap();
let file_ref = current_process.get_files().lock().unwrap().get(fd)?;
let file_ref = process::get_file(fd)?;
file_ref.set_len(len as u64)?;
Ok(())
}

@ -1,12 +1,14 @@
use super::*;
pub fn do_unlink(path: &str) -> Result<()> {
let current_ref = process::get_current();
let current_process = current_ref.lock().unwrap();
debug!("unlink: path: {:?}", path);
let (dir_path, file_name) = split_path(&path);
let dir_inode = current_process.lookup_inode(dir_path)?;
let dir_inode = {
let current_ref = process::get_current();
let current_process = current_ref.lock().unwrap();
current_process.lookup_inode(dir_path)?
};
let file_inode = dir_inode.find(file_name)?;
if file_inode.metadata()?.type_ == FileType::Dir {
return_errno!(EISDIR, "unlink on directory");

@ -2,24 +2,18 @@ use super::*;
pub fn do_write(fd: FileDesc, buf: &[u8]) -> Result<usize> {
debug!("write: fd: {}", fd);
let current_ref = process::get_current();
let current_process = current_ref.lock().unwrap();
let file_ref = current_process.get_files().lock().unwrap().get(fd)?;
let file_ref = process::get_file(fd)?;
file_ref.write(buf)
}
pub fn do_writev(fd: FileDesc, bufs: &[&[u8]]) -> Result<usize> {
debug!("writev: fd: {}", fd);
let current_ref = process::get_current();
let current_process = current_ref.lock().unwrap();
let file_ref = current_process.get_files().lock().unwrap().get(fd)?;
let file_ref = process::get_file(fd)?;
file_ref.writev(bufs)
}
pub fn do_pwrite(fd: FileDesc, buf: &[u8], offset: usize) -> Result<usize> {
debug!("pwrite: fd: {}, offset: {}", fd, offset);
let current_ref = process::get_current();
let current_process = current_ref.lock().unwrap();
let file_ref = current_process.get_files().lock().unwrap().get(fd)?;
let file_ref = process::get_file(fd)?;
file_ref.write_at(offset, buf)
}

@ -27,13 +27,10 @@ pub fn do_eventfd2(init_val: u32, flags: i32) -> Result<isize> {
Arc::new(Box::new(event))
};
let current_ref = process::get_current();
let mut proc = current_ref.lock().unwrap();
let fd = proc.get_files().lock().unwrap().put(
let fd = process::put_file(
file_ref,
inner_flags.contains(EventCreationFlags::EFD_CLOEXEC),
);
)?;
Ok(fd as isize)
}

@ -10,10 +10,8 @@ pub fn do_sendmsg(fd: c_int, msg_ptr: *const msghdr, flags_c: c_int) -> Result<i
"sendmsg: fd: {}, msg: {:?}, flags: 0x{:x}",
fd, msg_ptr, flags_c
);
let current_ref = process::get_current();
let mut proc = current_ref.lock().unwrap();
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
let file_ref = process::get_file(fd as FileDesc)?;
if let Ok(socket) = file_ref.as_socket() {
let msg_c = {
from_user::check_ptr(msg_ptr)?;
@ -40,10 +38,8 @@ pub fn do_recvmsg(fd: c_int, msg_mut_ptr: *mut msghdr_mut, flags_c: c_int) -> Re
"recvmsg: fd: {}, msg: {:?}, flags: 0x{:x}",
fd, msg_mut_ptr, flags_c
);
let current_ref = process::get_current();
let mut proc = current_ref.lock().unwrap();
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
let file_ref = process::get_file(fd as FileDesc)?;
if let Ok(socket) = file_ref.as_socket() {
let msg_mut_c = {
from_user::check_mut_ptr(msg_mut_ptr)?;

@ -82,8 +82,28 @@ mod task;
mod thread;
mod wait;
/// Get a file from the file table of the current process
pub fn get_file(fd: FileDesc) -> Result<FileRef> {
let current_ref = get_current();
let current = current_ref.lock().unwrap();
let file_ref = current.get_files().lock().unwrap().get(fd as FileDesc)?;
Ok(file_ref)
}
/// Put a file into the file table of the current process
pub fn put_file(new_file: FileRef, close_on_spawn: bool) -> Result<FileDesc> {
let current_ref = get_current();
let current = current_ref.lock().unwrap();
let new_fd = current
.get_files()
.lock()
.unwrap()
.put(new_file, close_on_spawn);
Ok(new_fd)
}
use super::*;
use fs::{File, FileRef, FileTable};
use fs::{File, FileDesc, FileRef, FileTable};
use misc::ResourceLimitsRef;
use time::GLOBAL_PROFILER;
use vm::ProcessVM;

@ -1044,10 +1044,7 @@ fn do_socket(domain: c_int, socket_type: c_int, protocol: c_int) -> Result<isize
}
};
let current_ref = process::get_current();
let mut proc = current_ref.lock().unwrap();
let fd = proc.get_files().lock().unwrap().put(file_ref, false);
let fd = process::put_file(file_ref, false)?;
Ok(fd as isize)
}
@ -1056,9 +1053,7 @@ fn do_connect(fd: c_int, addr: *const libc::sockaddr, addr_len: libc::socklen_t)
"connect: fd: {}, addr: {:?}, addr_len: {}",
fd, addr, addr_len
);
let current_ref = process::get_current();
let mut proc = current_ref.lock().unwrap();
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
let file_ref = process::get_file(fd as FileDesc)?;
if let Ok(socket) = file_ref.as_socket() {
let ret = try_libc!(libc::ocall::connect(socket.fd(), addr, addr_len));
Ok(ret as isize)
@ -1093,15 +1088,13 @@ fn do_accept4(
"accept4: fd: {}, addr: {:?}, addr_len: {:?}, flags: {:#x}",
fd, addr, addr_len, flags
);
let current_ref = process::get_current();
let mut proc = current_ref.lock().unwrap();
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
let file_ref = process::get_file(fd as FileDesc)?;
if let Ok(socket) = file_ref.as_socket() {
let socket = file_ref.as_socket()?;
let new_socket = socket.accept(addr, addr_len, flags)?;
let new_file_ref: Arc<Box<dyn File>> = Arc::new(Box::new(new_socket));
let new_fd = proc.get_files().lock().unwrap().put(new_file_ref, false);
let new_fd = process::put_file(new_file_ref, false)?;
Ok(new_fd as isize)
} else if let Ok(unix_socket) = file_ref.as_unix_socket() {
@ -1110,7 +1103,7 @@ fn do_accept4(
let new_socket = unix_socket.accept()?;
let new_file_ref: Arc<Box<dyn File>> = Arc::new(Box::new(new_socket));
let new_fd = proc.get_files().lock().unwrap().put(new_file_ref, false);
let new_fd = process::put_file(new_file_ref, false)?;
Ok(new_fd as isize)
} else {
@ -1120,9 +1113,7 @@ fn do_accept4(
fn do_shutdown(fd: c_int, how: c_int) -> Result<isize> {
debug!("shutdown: fd: {}, how: {}", fd, how);
let current_ref = process::get_current();
let mut proc = current_ref.lock().unwrap();
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
let file_ref = process::get_file(fd as FileDesc)?;
if let Ok(socket) = file_ref.as_socket() {
let ret = try_libc!(libc::ocall::shutdown(socket.fd(), how));
Ok(ret as isize)
@ -1133,9 +1124,7 @@ fn do_shutdown(fd: c_int, how: c_int) -> Result<isize> {
fn do_bind(fd: c_int, addr: *const libc::sockaddr, addr_len: libc::socklen_t) -> Result<isize> {
debug!("bind: fd: {}, addr: {:?}, addr_len: {}", fd, addr, addr_len);
let current_ref = process::get_current();
let mut proc = current_ref.lock().unwrap();
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
let file_ref = process::get_file(fd as FileDesc)?;
if let Ok(socket) = file_ref.as_socket() {
check_ptr(addr)?; // TODO: check addr_len
let ret = try_libc!(libc::ocall::bind(socket.fd(), addr, addr_len));
@ -1155,9 +1144,7 @@ fn do_bind(fd: c_int, addr: *const libc::sockaddr, addr_len: libc::socklen_t) ->
fn do_listen(fd: c_int, backlog: c_int) -> Result<isize> {
debug!("listen: fd: {}, backlog: {}", fd, backlog);
let current_ref = process::get_current();
let mut proc = current_ref.lock().unwrap();
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
let file_ref = process::get_file(fd as FileDesc)?;
if let Ok(socket) = file_ref.as_socket() {
let ret = try_libc!(libc::ocall::listen(socket.fd(), backlog));
Ok(ret as isize)
@ -1180,9 +1167,7 @@ fn do_setsockopt(
"setsockopt: fd: {}, level: {}, optname: {}, optval: {:?}, optlen: {:?}",
fd, level, optname, optval, optlen
);
let current_ref = process::get_current();
let mut proc = current_ref.lock().unwrap();
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
let file_ref = process::get_file(fd as FileDesc)?;
if let Ok(socket) = file_ref.as_socket() {
let ret = try_libc!(libc::ocall::setsockopt(
socket.fd(),
@ -1211,9 +1196,7 @@ fn do_getsockopt(
"getsockopt: fd: {}, level: {}, optname: {}, optval: {:?}, optlen: {:?}",
fd, level, optname, optval, optlen
);
let current_ref = process::get_current();
let mut proc = current_ref.lock().unwrap();
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
let file_ref = process::get_file(fd as FileDesc)?;
let socket = file_ref.as_socket()?;
let ret = try_libc!(libc::ocall::getsockopt(
@ -1235,9 +1218,7 @@ fn do_getpeername(
"getpeername: fd: {}, addr: {:?}, addr_len: {:?}",
fd, addr, addr_len
);
let current_ref = process::get_current();
let mut proc = current_ref.lock().unwrap();
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
let file_ref = process::get_file(fd as FileDesc)?;
if let Ok(socket) = file_ref.as_socket() {
let ret = try_libc!(libc::ocall::getpeername(socket.fd(), addr, addr_len));
Ok(ret as isize)
@ -1261,9 +1242,7 @@ fn do_getsockname(
"getsockname: fd: {}, addr: {:?}, addr_len: {:?}",
fd, addr, addr_len
);
let current_ref = process::get_current();
let mut proc = current_ref.lock().unwrap();
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
let file_ref = process::get_file(fd as FileDesc)?;
if let Ok(socket) = file_ref.as_socket() {
let ret = try_libc!(libc::ocall::getsockname(socket.fd(), addr, addr_len));
Ok(ret as isize)
@ -1287,9 +1266,7 @@ fn do_sendto(
"sendto: fd: {}, base: {:?}, len: {}, addr: {:?}, addr_len: {}",
fd, base, len, addr, addr_len
);
let current_ref = process::get_current();
let mut proc = current_ref.lock().unwrap();
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
let file_ref = process::get_file(fd as FileDesc)?;
let socket = file_ref.as_socket()?;
let ret = try_libc!(libc::ocall::sendto(
@ -1315,9 +1292,7 @@ fn do_recvfrom(
"recvfrom: fd: {}, base: {:?}, len: {}, flags: {}, addr: {:?}, addr_len: {:?}",
fd, base, len, flags, addr, addr_len
);
let current_ref = process::get_current();
let mut proc = current_ref.lock().unwrap();
let file_ref = proc.get_files().lock().unwrap().get(fd as FileDesc)?;
let file_ref = process::get_file(fd as FileDesc)?;
let socket = file_ref.as_socket()?;
let ret = try_libc!(libc::ocall::recvfrom(

@ -301,9 +301,7 @@ impl ProcessVM {
if flags.contains(MMapFlags::MAP_ANONYMOUS) {
VMInitializer::FillZeros()
} else {
let current_ref = get_current();
let current_process = current_ref.lock().unwrap();
let file_ref = current_process.get_files().lock().unwrap().get(fd)?;
let file_ref = process::get_file(fd)?;
VMInitializer::LoadFromFile {
file: file_ref,
offset: offset,