feat:添加symlink系统调用 (#984)

* 添加symlink系统调用

* 修改FATInode的dname的获取逻辑

* 修改fat对Dname的处理,分离dname和inode缓存的key

---------

Co-authored-by: sparkzky <sparkhhhhhhhhh@outlook.com>
Co-authored-by: longjin <longjin@DragonOS.org>
This commit is contained in:
sparkzky
2024-10-20 20:56:11 +08:00
committed by GitHub
parent cae6182257
commit 01c18c64b1
14 changed files with 328 additions and 39 deletions

View File

@ -8,4 +8,5 @@ authors = [ "xiaolin2004 <1553367438@qq.com>" ]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
libc="0.2"
errno = "0.3.9"
libc="0.2"

View File

@ -1,8 +1,10 @@
use core::ffi::{c_char, c_void};
use errno::errno;
use libc::{mount, MS_BIND};
use std::fs;
use std::path::Path;
use std::time;
fn main() {
let path = Path::new("mnt/tmp");
let dir = fs::create_dir_all(path);
@ -26,7 +28,8 @@ fn main() {
if result == 0 {
println!("Mount successful");
} else {
println!("Mount failed");
let err = errno();
println!("Mount failed with error code: {}", err.0);
}
let dur = clock.elapsed();
println!("mount costing time: {} ns", dur.as_nanos());

3
user/apps/test-symlink/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
/target
Cargo.lock
/install/

View File

@ -0,0 +1,13 @@
[package]
name = "test-symlink"
version = "0.1.0"
edition = "2021"
description = "测试symlink系统调用"
authors = [ "sparkzky <sparkhhhhhhhhh@outlook.com>" ]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
errno = "0.3.9"
libc="0.2"
nix = "0.23"

View File

@ -0,0 +1,56 @@
TOOLCHAIN=
RUSTFLAGS=
ifdef DADK_CURRENT_BUILD_DIR
# 如果是在dadk中编译那么安装到dadk的安装目录中
INSTALL_DIR = $(DADK_CURRENT_BUILD_DIR)
else
# 如果是在本地编译那么安装到当前目录下的install目录中
INSTALL_DIR = ./install
endif
ifeq ($(ARCH), x86_64)
export RUST_TARGET=x86_64-unknown-linux-musl
else ifeq ($(ARCH), riscv64)
export RUST_TARGET=riscv64gc-unknown-linux-gnu
else
# 默认为x86_86用于本地编译
export RUST_TARGET=x86_64-unknown-linux-musl
endif
run:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) run --target $(RUST_TARGET)
build:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) build --target $(RUST_TARGET)
clean:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) clean --target $(RUST_TARGET)
test:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) test --target $(RUST_TARGET)
doc:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) doc --target $(RUST_TARGET)
fmt:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) fmt
fmt-check:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) fmt --check
run-release:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) run --target $(RUST_TARGET) --release
build-release:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) build --target $(RUST_TARGET) --release
clean-release:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) clean --target $(RUST_TARGET) --release
test-release:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) test --target $(RUST_TARGET) --release
.PHONY: install
install:
RUSTFLAGS=$(RUSTFLAGS) cargo $(TOOLCHAIN) install --target $(RUST_TARGET) --path . --no-track --root $(INSTALL_DIR) --force

View File

@ -0,0 +1 @@
# 测试Symlink系统调用的程序

View File

@ -0,0 +1,78 @@
extern crate libc;
use core::ffi::{c_char, c_void};
use libc::{mount, umount};
use nix::errno::Errno;
use std::fs;
use std::os::unix::fs::symlink;
use std::path::Path;
fn main() {
mount_test_ramfs();
let target = "/mnt/myramfs/target_file.txt";
let symlink_path = "/mnt/myramfs/another/symlink_file.txt";
let dir = "/mnt/myramfs/another";
fs::write(target, "This is the content of the target file.")
.expect("Failed to create target file");
fs::create_dir(dir).expect("Failed to create target dir");
assert!(Path::new(target).exists(), "Target file was not created");
assert!(Path::new(dir).exists(), "Target dir was not created");
symlink(target, symlink_path).expect("Failed to create symlink");
assert!(Path::new(symlink_path).exists(), "Symlink was not created");
let symlink_content = fs::read_link(symlink_path).expect("Failed to read symlink");
assert_eq!(
symlink_content.display().to_string(),
target,
"Symlink points to the wrong target"
);
fs::remove_file(symlink_path).expect("Failed to remove symlink");
fs::remove_file(target).expect("Failed to remove target file");
fs::remove_dir(dir).expect("Failed to remove test_dir");
assert!(!Path::new(symlink_path).exists(), "Symlink was not deleted");
assert!(!Path::new(target).exists(), "Target file was not deleted");
assert!(!Path::new(dir).exists(), "Directory was not deleted");
umount_test_ramfs();
println!("All tests passed!");
}
fn mount_test_ramfs() {
let path = Path::new("mnt/myramfs");
let dir = fs::create_dir_all(path);
assert!(dir.is_ok(), "mkdir /mnt/myramfs failed");
let source = b"\0".as_ptr() as *const c_char;
let target = b"/mnt/myramfs\0".as_ptr() as *const c_char;
let fstype = b"ramfs\0".as_ptr() as *const c_char;
// let flags = MS_BIND;
let flags = 0;
let data = std::ptr::null() as *const c_void;
let result = unsafe { mount(source, target, fstype, flags, data) };
assert_eq!(
result,
0,
"Mount myramfs failed, errno: {}",
Errno::last().desc()
);
println!("Mount myramfs success!");
}
fn umount_test_ramfs() {
let path = b"/mnt/myramfs\0".as_ptr() as *const c_char;
let result = unsafe { umount(path) };
if result != 0 {
let err = Errno::last();
println!("Errno: {}", err);
println!("Infomation: {}", err.desc());
}
assert_eq!(result, 0, "Umount myramfs failed");
}