|
|
|
@ -1,25 +1,28 @@
|
|
|
|
|
extern crate std;
|
|
|
|
|
|
|
|
|
|
use std::fs::{self, OpenOptions};
|
|
|
|
|
use std::boxed::Box;
|
|
|
|
|
use std::sync::Arc;
|
|
|
|
|
use std::sync::Mutex;
|
|
|
|
|
use std::mem::uninitialized;
|
|
|
|
|
use crate::sfs::*;
|
|
|
|
|
use crate::vfs::*;
|
|
|
|
|
use crate::*;
|
|
|
|
|
use rcore_fs::vfs::{FileSystem, Result, FileType, Metadata, Timespec};
|
|
|
|
|
|
|
|
|
|
fn _open_sample_file() -> Arc<SimpleFileSystem> {
|
|
|
|
|
fs::copy("sfs.img", "test.img").expect("failed to open sfs.img");
|
|
|
|
|
let file = OpenOptions::new()
|
|
|
|
|
.read(true).write(true).open("test.img")
|
|
|
|
|
.expect("failed to open test.img");
|
|
|
|
|
SimpleFileSystem::open(Box::new(file))
|
|
|
|
|
SimpleFileSystem::open(Arc::new(Mutex::new(file)))
|
|
|
|
|
.expect("failed to open SFS")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn _create_new_sfs() -> Arc<SimpleFileSystem> {
|
|
|
|
|
let file = tempfile::tempfile()
|
|
|
|
|
.expect("failed to create file");
|
|
|
|
|
SimpleFileSystem::create(Box::new(file), 32 * 4096)
|
|
|
|
|
SimpleFileSystem::create(Arc::new(Mutex::new(file)), 32 * 4096)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
#[ignore]
|
|
|
|
|
fn open_sample_file() {
|
|
|
|
@ -36,9 +39,9 @@ fn create_new_sfs() {
|
|
|
|
|
fn create_file() -> Result<()> {
|
|
|
|
|
let sfs = _create_new_sfs();
|
|
|
|
|
let root = sfs.root_inode();
|
|
|
|
|
let file1 = root.create("file1", FileType::File)?;
|
|
|
|
|
let file1 = root.create("file1", FileType::File, 0o777)?;
|
|
|
|
|
|
|
|
|
|
assert_eq!(file1.info()?, Metadata {
|
|
|
|
|
assert_eq!(file1.metadata()?, Metadata {
|
|
|
|
|
inode: 5,
|
|
|
|
|
size: 0,
|
|
|
|
|
type_: FileType::File,
|
|
|
|
@ -49,7 +52,9 @@ fn create_file() -> Result<()> {
|
|
|
|
|
nlinks: 1,
|
|
|
|
|
uid: 0,
|
|
|
|
|
ctime: Timespec { sec: 0, nsec: 0 },
|
|
|
|
|
gid: 0
|
|
|
|
|
gid: 0,
|
|
|
|
|
blk_size: 4096,
|
|
|
|
|
dev: 0,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
sfs.sync()?;
|
|
|
|
@ -60,13 +65,13 @@ fn create_file() -> Result<()> {
|
|
|
|
|
fn resize() -> Result<()> {
|
|
|
|
|
let sfs = _create_new_sfs();
|
|
|
|
|
let root = sfs.root_inode();
|
|
|
|
|
let file1 = root.create("file1", FileType::File)?;
|
|
|
|
|
assert_eq!(file1.info()?.size, 0, "empty file size != 0");
|
|
|
|
|
let file1 = root.create("file1", FileType::File, 0o777)?;
|
|
|
|
|
assert_eq!(file1.metadata()?.size, 0, "empty file size != 0");
|
|
|
|
|
|
|
|
|
|
const SIZE1: usize = 0x1234;
|
|
|
|
|
const SIZE2: usize = 0x1250;
|
|
|
|
|
file1.resize(SIZE1)?;
|
|
|
|
|
assert_eq!(file1.info()?.size, SIZE1, "wrong size after resize");
|
|
|
|
|
assert_eq!(file1.metadata()?.size, SIZE1, "wrong size after resize");
|
|
|
|
|
let mut data1: [u8; SIZE2] = unsafe { uninitialized() };
|
|
|
|
|
let len = file1.read_at(0, data1.as_mut())?;
|
|
|
|
|
assert_eq!(len, SIZE1, "wrong size returned by read_at()");
|
|
|
|
@ -90,7 +95,7 @@ fn resize_on_dir_should_panic() -> Result<()> {
|
|
|
|
|
fn resize_too_large_should_panic() -> Result<()> {
|
|
|
|
|
let sfs = _create_new_sfs();
|
|
|
|
|
let root = sfs.root_inode();
|
|
|
|
|
let file1 = root.create("file1", FileType::File)?;
|
|
|
|
|
let file1 = root.create("file1", FileType::File, 0o777)?;
|
|
|
|
|
assert!(file1.resize(1 << 28).is_err());
|
|
|
|
|
sfs.sync()?;
|
|
|
|
|
|
|
|
|
@ -105,14 +110,14 @@ fn create_then_lookup() -> Result<()> {
|
|
|
|
|
assert!(Arc::ptr_eq(&root.lookup(".")?, &root), "failed to find .");
|
|
|
|
|
assert!(Arc::ptr_eq(&root.lookup("..")?, &root), "failed to find ..");
|
|
|
|
|
|
|
|
|
|
let file1 = root.create("file1", FileType::File)
|
|
|
|
|
let file1 = root.create("file1", FileType::File, 0o777)
|
|
|
|
|
.expect("failed to create file1");
|
|
|
|
|
assert!(Arc::ptr_eq(&root.lookup("file1")?, &file1), "failed to find file1");
|
|
|
|
|
assert!(root.lookup("file2").is_err(), "found non-existent file");
|
|
|
|
|
|
|
|
|
|
let dir1 = root.create("dir1", FileType::Dir)
|
|
|
|
|
let dir1 = root.create("dir1", FileType::Dir, 0o777)
|
|
|
|
|
.expect("failed to create dir1");
|
|
|
|
|
let file2 = dir1.create("file2", FileType::File)
|
|
|
|
|
let file2 = dir1.create("file2", FileType::File, 0o777)
|
|
|
|
|
.expect("failed to create /dir1/file2");
|
|
|
|
|
assert!(Arc::ptr_eq(&root.lookup("dir1/file2")?, &file2), "failed to find dir1/file1");
|
|
|
|
|
assert!(Arc::ptr_eq(&dir1.lookup("..")?, &root), "failed to find .. from dir1");
|
|
|
|
@ -138,7 +143,7 @@ fn kernel_image_file_create() -> Result<()> {
|
|
|
|
|
let sfs = _open_sample_file();
|
|
|
|
|
let root = sfs.root_inode();
|
|
|
|
|
let files_count_before = root.list()?.len();
|
|
|
|
|
root.create("hello2", FileType::File)?;
|
|
|
|
|
root.create("hello2", FileType::File, 0o777)?;
|
|
|
|
|
let files_count_after = root.list()?.len();
|
|
|
|
|
assert_eq!(files_count_before + 1, files_count_after);
|
|
|
|
|
assert!(root.lookup("hello2").is_ok());
|
|
|
|
@ -168,7 +173,7 @@ fn kernel_image_file_rename() -> Result<()> {
|
|
|
|
|
let sfs = _open_sample_file();
|
|
|
|
|
let root = sfs.root_inode();
|
|
|
|
|
let files_count_before = root.list()?.len();
|
|
|
|
|
root.rename("hello", "hello2")?;
|
|
|
|
|
root.move_("hello", &root, "hello2")?;
|
|
|
|
|
let files_count_after = root.list()?.len();
|
|
|
|
|
assert_eq!(files_count_before, files_count_after);
|
|
|
|
|
assert!(root.lookup("hello").is_err());
|
|
|
|
@ -185,7 +190,7 @@ fn kernel_image_file_move() -> Result<()> {
|
|
|
|
|
let root = sfs.root_inode();
|
|
|
|
|
let files_count_before = root.list()?.len();
|
|
|
|
|
root.unlink("divzero")?;
|
|
|
|
|
let rust_dir = root.create("rust", FileType::Dir)?;
|
|
|
|
|
let rust_dir = root.create("rust", FileType::Dir, 0o777)?;
|
|
|
|
|
root.move_("hello", &rust_dir, "hello_world")?;
|
|
|
|
|
let files_count_after = root.list()?.len();
|
|
|
|
|
assert_eq!(files_count_before, files_count_after + 1);
|
|
|
|
@ -202,11 +207,11 @@ fn kernel_image_file_move() -> Result<()> {
|
|
|
|
|
fn hard_link() -> Result<()> {
|
|
|
|
|
let sfs = _create_new_sfs();
|
|
|
|
|
let root = sfs.root_inode();
|
|
|
|
|
let file1 = root.create("file1", FileType::File)?;
|
|
|
|
|
let file1 = root.create("file1", FileType::File, 0o777)?;
|
|
|
|
|
root.link("file2", &file1)?;
|
|
|
|
|
let file2 = root.lookup("file2")?;
|
|
|
|
|
file1.resize(100)?;
|
|
|
|
|
assert_eq!(file2.info()?.size, 100);
|
|
|
|
|
assert_eq!(file2.metadata()?.size, 100);
|
|
|
|
|
|
|
|
|
|
sfs.sync()?;
|
|
|
|
|
Ok(())
|
|
|
|
@ -217,58 +222,58 @@ fn nlinks() -> Result<()> {
|
|
|
|
|
let sfs = _create_new_sfs();
|
|
|
|
|
let root = sfs.root_inode();
|
|
|
|
|
// -root
|
|
|
|
|
assert_eq!(root.info()?.nlinks, 2);
|
|
|
|
|
assert_eq!(root.metadata()?.nlinks, 2);
|
|
|
|
|
|
|
|
|
|
let file1 = root.create("file1", FileType::File)?;
|
|
|
|
|
let file1 = root.create("file1", FileType::File, 0o777)?;
|
|
|
|
|
// -root
|
|
|
|
|
// `-file1 <f1>
|
|
|
|
|
assert_eq!(file1.info()?.nlinks, 1);
|
|
|
|
|
assert_eq!(root.info()?.nlinks, 2);
|
|
|
|
|
assert_eq!(file1.metadata()?.nlinks, 1);
|
|
|
|
|
assert_eq!(root.metadata()?.nlinks, 2);
|
|
|
|
|
|
|
|
|
|
let dir1 = root.create("dir1", FileType::Dir)?;
|
|
|
|
|
let dir1 = root.create("dir1", FileType::Dir, 0o777)?;
|
|
|
|
|
// -root
|
|
|
|
|
// +-dir1
|
|
|
|
|
// `-file1 <f1>
|
|
|
|
|
assert_eq!(dir1.info()?.nlinks, 2);
|
|
|
|
|
assert_eq!(root.info()?.nlinks, 3);
|
|
|
|
|
assert_eq!(dir1.metadata()?.nlinks, 2);
|
|
|
|
|
assert_eq!(root.metadata()?.nlinks, 3);
|
|
|
|
|
|
|
|
|
|
root.rename("dir1", "dir_1")?;
|
|
|
|
|
root.move_("dir1", &root, "dir_1")?;
|
|
|
|
|
// -root
|
|
|
|
|
// +-dir_1
|
|
|
|
|
// `-file1 <f1>
|
|
|
|
|
assert_eq!(dir1.info()?.nlinks, 2);
|
|
|
|
|
assert_eq!(root.info()?.nlinks, 3);
|
|
|
|
|
assert_eq!(dir1.metadata()?.nlinks, 2);
|
|
|
|
|
assert_eq!(root.metadata()?.nlinks, 3);
|
|
|
|
|
|
|
|
|
|
dir1.link("file1_", &file1)?;
|
|
|
|
|
// -root
|
|
|
|
|
// +-dir_1
|
|
|
|
|
// | `-file1_ <f1>
|
|
|
|
|
// `-file1 <f1>
|
|
|
|
|
assert_eq!(dir1.info()?.nlinks, 2);
|
|
|
|
|
assert_eq!(root.info()?.nlinks, 3);
|
|
|
|
|
assert_eq!(file1.info()?.nlinks, 2);
|
|
|
|
|
assert_eq!(dir1.metadata()?.nlinks, 2);
|
|
|
|
|
assert_eq!(root.metadata()?.nlinks, 3);
|
|
|
|
|
assert_eq!(file1.metadata()?.nlinks, 2);
|
|
|
|
|
|
|
|
|
|
let dir2 = root.create("dir2", FileType::Dir)?;
|
|
|
|
|
let dir2 = root.create("dir2", FileType::Dir, 0o777)?;
|
|
|
|
|
// -root
|
|
|
|
|
// +-dir_1
|
|
|
|
|
// | `-file1_ <f1>
|
|
|
|
|
// +-dir2
|
|
|
|
|
// `-file1 <f1>
|
|
|
|
|
assert_eq!(dir1.info()?.nlinks, 2);
|
|
|
|
|
assert_eq!(dir2.info()?.nlinks, 2);
|
|
|
|
|
assert_eq!(root.info()?.nlinks, 4);
|
|
|
|
|
assert_eq!(file1.info()?.nlinks, 2);
|
|
|
|
|
assert_eq!(dir1.metadata()?.nlinks, 2);
|
|
|
|
|
assert_eq!(dir2.metadata()?.nlinks, 2);
|
|
|
|
|
assert_eq!(root.metadata()?.nlinks, 4);
|
|
|
|
|
assert_eq!(file1.metadata()?.nlinks, 2);
|
|
|
|
|
|
|
|
|
|
root.rename("file1", "file_1")?;
|
|
|
|
|
root.move_("file1", &root, "file_1")?;
|
|
|
|
|
// -root
|
|
|
|
|
// +-dir_1
|
|
|
|
|
// | `-file1_ <f1>
|
|
|
|
|
// +-dir2
|
|
|
|
|
// `-file_1 <f1>
|
|
|
|
|
assert_eq!(dir1.info()?.nlinks, 2);
|
|
|
|
|
assert_eq!(dir2.info()?.nlinks, 2);
|
|
|
|
|
assert_eq!(root.info()?.nlinks, 4);
|
|
|
|
|
assert_eq!(file1.info()?.nlinks, 2);
|
|
|
|
|
assert_eq!(dir1.metadata()?.nlinks, 2);
|
|
|
|
|
assert_eq!(dir2.metadata()?.nlinks, 2);
|
|
|
|
|
assert_eq!(root.metadata()?.nlinks, 4);
|
|
|
|
|
assert_eq!(file1.metadata()?.nlinks, 2);
|
|
|
|
|
|
|
|
|
|
root.move_("file_1", &dir2, "file__1")?;
|
|
|
|
|
// -root
|
|
|
|
@ -276,10 +281,10 @@ fn nlinks() -> Result<()> {
|
|
|
|
|
// | `-file1_ <f1>
|
|
|
|
|
// `-dir2
|
|
|
|
|
// `-file__1 <f1>
|
|
|
|
|
assert_eq!(dir1.info()?.nlinks, 2);
|
|
|
|
|
assert_eq!(dir2.info()?.nlinks, 2);
|
|
|
|
|
assert_eq!(root.info()?.nlinks, 4);
|
|
|
|
|
assert_eq!(file1.info()?.nlinks, 2);
|
|
|
|
|
assert_eq!(dir1.metadata()?.nlinks, 2);
|
|
|
|
|
assert_eq!(dir2.metadata()?.nlinks, 2);
|
|
|
|
|
assert_eq!(root.metadata()?.nlinks, 4);
|
|
|
|
|
assert_eq!(file1.metadata()?.nlinks, 2);
|
|
|
|
|
|
|
|
|
|
root.move_("dir_1", &dir2, "dir__1")?;
|
|
|
|
|
// -root
|
|
|
|
@ -287,44 +292,44 @@ fn nlinks() -> Result<()> {
|
|
|
|
|
// +-dir__1
|
|
|
|
|
// | `-file1_ <f1>
|
|
|
|
|
// `-file__1 <f1>
|
|
|
|
|
assert_eq!(dir1.info()?.nlinks, 2);
|
|
|
|
|
assert_eq!(dir2.info()?.nlinks, 3);
|
|
|
|
|
assert_eq!(root.info()?.nlinks, 3);
|
|
|
|
|
assert_eq!(file1.info()?.nlinks, 2);
|
|
|
|
|
assert_eq!(dir1.metadata()?.nlinks, 2);
|
|
|
|
|
assert_eq!(dir2.metadata()?.nlinks, 3);
|
|
|
|
|
assert_eq!(root.metadata()?.nlinks, 3);
|
|
|
|
|
assert_eq!(file1.metadata()?.nlinks, 2);
|
|
|
|
|
|
|
|
|
|
dir2.unlink("file__1")?;
|
|
|
|
|
// -root
|
|
|
|
|
// `-dir2
|
|
|
|
|
// `-dir__1
|
|
|
|
|
// `-file1_ <f1>
|
|
|
|
|
assert_eq!(file1.info()?.nlinks, 1);
|
|
|
|
|
assert_eq!(dir1.info()?.nlinks, 2);
|
|
|
|
|
assert_eq!(dir2.info()?.nlinks, 3);
|
|
|
|
|
assert_eq!(root.info()?.nlinks, 3);
|
|
|
|
|
assert_eq!(file1.metadata()?.nlinks, 1);
|
|
|
|
|
assert_eq!(dir1.metadata()?.nlinks, 2);
|
|
|
|
|
assert_eq!(dir2.metadata()?.nlinks, 3);
|
|
|
|
|
assert_eq!(root.metadata()?.nlinks, 3);
|
|
|
|
|
|
|
|
|
|
dir1.unlink("file1_")?;
|
|
|
|
|
// -root
|
|
|
|
|
// `-dir2
|
|
|
|
|
// `-dir__1
|
|
|
|
|
assert_eq!(file1.info()?.nlinks, 0);
|
|
|
|
|
assert_eq!(dir1.info()?.nlinks, 2);
|
|
|
|
|
assert_eq!(dir2.info()?.nlinks, 3);
|
|
|
|
|
assert_eq!(root.info()?.nlinks, 3);
|
|
|
|
|
assert_eq!(file1.metadata()?.nlinks, 0);
|
|
|
|
|
assert_eq!(dir1.metadata()?.nlinks, 2);
|
|
|
|
|
assert_eq!(dir2.metadata()?.nlinks, 3);
|
|
|
|
|
assert_eq!(root.metadata()?.nlinks, 3);
|
|
|
|
|
|
|
|
|
|
dir2.unlink("dir__1")?;
|
|
|
|
|
// -root
|
|
|
|
|
// `-dir2
|
|
|
|
|
assert_eq!(file1.info()?.nlinks, 0);
|
|
|
|
|
assert_eq!(dir1.info()?.nlinks, 0);
|
|
|
|
|
assert_eq!(root.info()?.nlinks, 3);
|
|
|
|
|
assert_eq!(dir2.info()?.nlinks, 2);
|
|
|
|
|
assert_eq!(file1.metadata()?.nlinks, 0);
|
|
|
|
|
assert_eq!(dir1.metadata()?.nlinks, 0);
|
|
|
|
|
assert_eq!(root.metadata()?.nlinks, 3);
|
|
|
|
|
assert_eq!(dir2.metadata()?.nlinks, 2);
|
|
|
|
|
|
|
|
|
|
root.unlink("dir2")?;
|
|
|
|
|
// -root
|
|
|
|
|
assert_eq!(file1.info()?.nlinks, 0);
|
|
|
|
|
assert_eq!(dir1.info()?.nlinks, 0);
|
|
|
|
|
assert_eq!(root.info()?.nlinks, 2);
|
|
|
|
|
assert_eq!(dir2.info()?.nlinks, 0);
|
|
|
|
|
assert_eq!(file1.metadata()?.nlinks, 0);
|
|
|
|
|
assert_eq!(dir1.metadata()?.nlinks, 0);
|
|
|
|
|
assert_eq!(root.metadata()?.nlinks, 2);
|
|
|
|
|
assert_eq!(dir2.metadata()?.nlinks, 0);
|
|
|
|
|
|
|
|
|
|
sfs.sync()?;
|
|
|
|
|
Ok(())
|