Skip to content

Commit f1385e7

Browse files
committed
mount implementation
1 parent 157c291 commit f1385e7

File tree

6 files changed

+99
-2
lines changed

6 files changed

+99
-2
lines changed

etc/syscalls_linux_aarch64.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
| 0x25 (37) | linkat | (int olddfd, const char *oldname, int newdfd, const char *newname, int flags) | __arm64_sys_linkat | true |
4242
| 0x26 (38) | renameat | (int olddfd, const char *oldname, int newdfd, const char *newname) | __arm64_sys_renameat | true |
4343
| 0x27 (39) | umount | (char *name, int flags) | __arm64_sys_umount | false |
44-
| 0x28 (40) | mount | (char *dev_name, char *dir_name, char *type, unsigned long flags, void *data) | __arm64_sys_mount | false |
44+
| 0x28 (40) | mount | (char *dev_name, char *dir_name, char *type, unsigned long flags, void *data) | __arm64_sys_mount | partial |
4545
| 0x29 (41) | pivot_root | (const char *new_root, const char *put_old) | __arm64_sys_pivot_root | false |
4646
| 0x2b (43) | statfs | (const char *pathname, struct statfs *buf) | __arm64_sys_statfs | dummy |
4747
| 0x2c (44) | fstatfs | (unsigned int fd, struct statfs *buf) | __arm64_sys_fstatfs | dummy |

src/arch/arm64/exceptions/syscall.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ use crate::{
3232
ioctl::sys_ioctl,
3333
iov::{sys_preadv, sys_preadv2, sys_pwritev, sys_pwritev2, sys_readv, sys_writev},
3434
listxattr::{sys_flistxattr, sys_listxattr, sys_llistxattr},
35+
mount::sys_mount,
3536
removexattr::{sys_fremovexattr, sys_lremovexattr, sys_removexattr},
3637
rw::{sys_pread64, sys_pwrite64, sys_read, sys_write},
3738
seek::sys_lseek,
@@ -224,6 +225,16 @@ pub async fn handle_syscall() {
224225
)
225226
.await
226227
}
228+
0x28 => {
229+
sys_mount(
230+
TUA::from_value(arg1 as _),
231+
TUA::from_value(arg2 as _),
232+
TUA::from_value(arg3 as _),
233+
arg4 as _,
234+
TUA::from_value(arg5 as _),
235+
)
236+
.await
237+
}
227238
0x2b | 0x2c => Err(KernelError::NotSupported),
228239
0x2d => sys_truncate(TUA::from_value(arg1 as _), arg2 as _).await,
229240
0x2e => sys_ftruncate(arg1.into(), arg2 as _).await,

src/drivers/fs/proc/task/fd.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::drivers::fs::proc::{get_inode_id, procfs};
22
use crate::process::fd_table::Fd;
33
use crate::process::{TaskDescriptor, find_task_by_descriptor};
44
use crate::sched::current::current_task_shared;
5+
use alloc::borrow::ToOwned;
56
use alloc::boxed::Box;
67
use alloc::format;
78
use alloc::string::ToString;
@@ -11,6 +12,7 @@ use async_trait::async_trait;
1112
use libkernel::error::Result;
1213
use libkernel::error::{FsError, KernelError};
1314
use libkernel::fs::attr::FileAttr;
15+
use libkernel::fs::pathbuf::PathBuf;
1416
use libkernel::fs::{
1517
DirStream, Dirent, FileType, Filesystem, Inode, InodeId, SimpleDirStream, SimpleFile,
1618
};
@@ -115,7 +117,11 @@ impl ProcFdFile {
115117
Self {
116118
id: inode_id,
117119
attr: FileAttr {
118-
file_type: FileType::File,
120+
file_type: if fd_info {
121+
FileType::File
122+
} else {
123+
FileType::Symlink
124+
},
119125
// Define appropriate file attributes for fdinfo file.
120126
..FileAttr::default()
121127
},
@@ -151,4 +157,23 @@ impl SimpleFile for ProcFdFile {
151157
Err(KernelError::NotSupported)
152158
}
153159
}
160+
161+
async fn readlink(&self) -> Result<PathBuf> {
162+
if !self.fd_info {
163+
if let Some(task) = find_task_by_descriptor(&self.desc) {
164+
let Some(file) = task.fd_table.lock_save_irq().get(Fd(self.fd)) else {
165+
return Err(FsError::NotFound.into());
166+
};
167+
if let Some(path) = file.path() {
168+
Ok(path.to_owned())
169+
} else {
170+
todo!();
171+
}
172+
} else {
173+
Err(FsError::NotFound.into())
174+
}
175+
} else {
176+
Err(KernelError::NotSupported)
177+
}
178+
}
154179
}

src/fs/mod.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,13 @@ impl VfsState {
7979
self.mounts.insert(mount_point_id, mount);
8080
}
8181

82+
/// Removes a mount point by its inode ID.
83+
fn remove_mount(&mut self, mount_point_id: &InodeId) -> Option<()> {
84+
let mount = self.mounts.remove(mount_point_id)?;
85+
self.filesystems.remove(&mount.fs.id())?;
86+
Some(())
87+
}
88+
8289
/// Checks if an inode is a mount point and returns the root inode of the
8390
/// mounted filesystem if it is.
8491
fn get_mount_root(&self, inode_id: &InodeId) -> Option<Arc<dyn Inode>> {
@@ -177,6 +184,19 @@ impl VFS {
177184
Ok(())
178185
}
179186

187+
#[expect(unused)]
188+
pub async fn unmount(&self, mount_point: Arc<dyn Inode>) -> Result<()> {
189+
let mount_point_id = mount_point.id();
190+
191+
// Lock the state and remove the mount.
192+
self.state
193+
.lock_save_irq()
194+
.remove_mount(&mount_point_id)
195+
.ok_or(FsError::NotFound)?;
196+
197+
Ok(())
198+
}
199+
180200
/// Resolves a path string to an Inode, starting from a given root for
181201
/// relative paths.
182202
pub async fn resolve_path(

src/fs/syscalls/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ pub mod getxattr;
77
pub mod ioctl;
88
pub mod iov;
99
pub mod listxattr;
10+
pub mod mount;
1011
pub mod open;
1112
pub mod removexattr;
1213
pub mod rw;

src/fs/syscalls/mount.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
use crate::fs::VFS;
2+
use crate::memory::uaccess::cstr::UserCStr;
3+
use crate::sched::current::current_task_shared;
4+
use core::ffi::c_char;
5+
use libkernel::error::Result;
6+
use libkernel::fs::path::Path;
7+
use libkernel::memory::address::{TUA, UA};
8+
9+
pub async fn sys_mount(
10+
dev_name: TUA<c_char>,
11+
dir_name: TUA<c_char>,
12+
type_: TUA<c_char>,
13+
_flags: i64,
14+
_data: UA,
15+
) -> Result<usize> {
16+
let mut buf = [0u8; 1024];
17+
let dev_name = UserCStr::from_ptr(dev_name)
18+
.copy_from_user(&mut buf)
19+
.await?;
20+
let mut buf = [0u8; 1024];
21+
let dir_name = UserCStr::from_ptr(dir_name)
22+
.copy_from_user(&mut buf)
23+
.await?;
24+
let mount_point = VFS
25+
.resolve_path(
26+
Path::new(dir_name),
27+
VFS.root_inode(),
28+
&current_task_shared(),
29+
)
30+
.await?;
31+
let mut buf = [0u8; 1024];
32+
let _type = UserCStr::from_ptr(type_).copy_from_user(&mut buf).await?;
33+
let dev_name = match dev_name {
34+
"proc" => "procfs",
35+
"devtmpfs" => "devfs",
36+
s => s,
37+
};
38+
VFS.mount(mount_point, dev_name, None).await?;
39+
Ok(0)
40+
}

0 commit comments

Comments
 (0)