-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make argfd
not return &'static RcFile
#415
Comments
좋은 해결책이 쉽게 보이지 않는 것 같습니다. 첫 번째로 시도한 방식은 --- a/kernel-rs/src/proc.rs
+++ b/kernel-rs/src/proc.rs
@@ -385,8 +385,9 @@ impl<'p> CurrentProc<'p> {
unsafe { guard.sched() };
}
- pub fn deref_data_raw(&mut self) -> *mut ProcData {
- self.data.get()
+ pub fn deref_data(&self) -> &ProcData {
+ // Safety: Only `CurrentProc` can use `ProcData` without lock.
+ unsafe { &*self.data.get() }
}
pub fn deref_mut_data(&mut self) -> &mut ProcData {
diff --git a/kernel-rs/src/sysfile.rs b/kernel-rs/src/sysfile.rs
index e46c2d5..1569a25 100644
--- a/kernel-rs/src/sysfile.rs
+++ b/kernel-rs/src/sysfile.rs
@@ -42,19 +42,15 @@ impl RcFile<'static> {
/// Fetch the nth word-sized system call argument as a file descriptor
/// and return both the descriptor and the corresponding struct file.
-unsafe fn argfd(
- n: usize,
- proc: &mut CurrentProc<'_>,
-) -> Result<(i32, &'static RcFile<'static>), ()> {
+unsafe fn argfd<'a>(n: usize, proc: &'a CurrentProc<'_>) -> Result<(i32, &'a RcFile<'static>), ()> {
let fd = argint(n, proc)?;
if fd < 0 || fd >= NOFILE as i32 {
return Err(());
}
- let f = some_or!(
- unsafe { &(*proc.deref_data_raw()).open_files[fd as usize] },
- return Err(())
- );
+ let f = proc.deref_data().open_files[fd as usize]
+ .as_ref()
+ .ok_or(())?;
Ok((fd, f))
} 이렇게 하면 두 번째로 시도한 방식은 --- a/kernel-rs/src/sysfile.rs
+++ b/kernel-rs/src/sysfile.rs
@@ -45,16 +45,13 @@ impl RcFile<'static> {
unsafe fn argfd(
n: usize,
proc: &mut CurrentProc<'_>,
-) -> Result<(i32, &'static RcFile<'static>), ()> {
+) -> Result<(i32, RcFile<'static>), ()> {
let fd = argint(n, proc)?;
if fd < 0 || fd >= NOFILE as i32 {
return Err(());
}
- let f = some_or!(
- unsafe { &(*proc.deref_data_raw()).open_files[fd as usize] },
- return Err(())
- );
+ let f = proc.deref_mut_data().open_files[fd as usize].take().ok_or(())?;
Ok((fd, f))
}
@@ -320,8 +317,9 @@ impl Kernel {
/// Return a new file descriptor referring to the same file as given fd.
/// Returns Ok(new file descriptor) on success, Err(()) on error.
pub unsafe fn sys_dup(&self, proc: &mut CurrentProc<'_>) -> Result<usize, ()> {
- let (_, f) = unsafe { argfd(0, proc)? };
+ let (fd, f) = unsafe { argfd(0, proc)? };
let newfile = f.clone();
+ proc.deref_mut_data().open_files[fd as usize] = Some(f);
let fd = newfile.fdalloc(proc).map_err(|_| ())?;
Ok(fd as usize)
}
@@ -329,19 +327,23 @@ impl Kernel {
/// Read n bytes into buf.
/// Returns Ok(number read) on success, Err(()) on error.
pub unsafe fn sys_read(&self, proc: &mut CurrentProc<'_>) -> Result<usize, ()> {
- let (_, f) = unsafe { argfd(0, proc)? };
+ let (fd, f) = unsafe { argfd(0, proc)? };
let n = argint(2, proc)?;
let p = argaddr(1, proc)?;
- unsafe { f.read(p.into(), n, proc) }
+ let res = unsafe { f.read(p.into(), n, proc) };
+ proc.deref_mut_data().open_files[fd as usize] = Some(f);
+ res
}
/// Write n bytes from buf to given file descriptor fd.
/// Returns Ok(n) on success, Err(()) on error.
pub unsafe fn sys_write(&self, proc: &mut CurrentProc<'_>) -> Result<usize, ()> {
- let (_, f) = unsafe { argfd(0, proc)? };
+ let (fd, f) = unsafe { argfd(0, proc)? };
let n = argint(2, proc)?;
let p = argaddr(1, proc)?;
- unsafe { f.write(p.into(), n, proc) }
+ let res = unsafe { f.write(p.into(), n, proc) };
+ proc.deref_mut_data().open_files[fd as usize] = Some(f);
+ res
}
/// Release open file fd.
@@ -355,10 +357,11 @@ impl Kernel {
/// Place info about an open file into struct stat.
/// Returns Ok(0) on success, Err(()) on error.
pub unsafe fn sys_fstat(&self, proc: &mut CurrentProc<'_>) -> Result<usize, ()> {
- let (_, f) = unsafe { argfd(0, proc)? };
+ let (fd, f) = unsafe { argfd(0, proc)? };
// user pointer to struct stat
let st = argaddr(1, proc)?;
unsafe { f.stat(st.into(), proc)? };
+ proc.deref_mut_data().open_files[fd as usize] = Some(f);
Ok(0)
} 오프라인 미팅에서 의논하면 좋을 것 같습니다. |
raw 함수가 굳이 있어야 하나요?
Originally posted by @jeehoonkang in #407 (comment)
#385 작업에서 생긴 변경사항입니다.
argfd()
에서deref_mut_data
를 이용하여 아래 코드를 작성하는 방법을 찾지 못해deref_data_raw
를 사용하였습니다.rv6/kernel-rs/src/sysfile.rs
Lines 51 to 54 in ad9226f
기존 코드는 아래와 같았습니다.
rv6/kernel-rs/src/sysfile.rs
Lines 50 to 54 in e28e1a2
혹시
deref_mut_data
등을 사용해서 구현할 수 있는 방법이 있을까요?Originally posted by @anemoneflower in #407 (comment)
deref_mut_data를 넣으면 왜 안되나요?
Originally posted by @jeehoonkang in #407 (comment)
reference를 사용하면 return되는
RcFile
에 static lifetime이 붙어있어서,CurrentProc
에도 static lifetime이 붙어야 한다는 에러가 뜹니다.Originally posted by @anemoneflower in #407 (comment)
argfd
가&'static RcFile
을 반환하는 것부터 문제가 있는 것 같습니다. 이 PR에서는deref_data_raw
를 그대로 두고,argfd
리팩토링과deref_data_raw
를 없애는 것은 추후에 별도로 진행하면 어떨까요?Originally posted by @Medowhill in #407 (comment)
The text was updated successfully, but these errors were encountered: