Fix symlink to directories

master
Jiajie Chen 6 years ago
parent 9c0aeb1e66
commit f8d7b06727

@ -759,8 +759,6 @@ impl SimpleFileSystem {
if let Some(block_id) = id {
let mut super_block = self.super_block.write();
if super_block.unused_blocks == 0 {
let super_block = self.super_block.read();
panic!("{:?}", super_block);
free_map.set(block_id, true);
return None;
}

@ -135,6 +135,10 @@ fn create_then_lookup() -> Result<()> {
Arc::ptr_eq(&root.lookup("dir1/file2")?, &file2),
"failed to find dir1/file2"
);
assert!(
Arc::ptr_eq(&root.lookup("/")?.lookup("dir1/file2")?, &file2),
"failed to find dir1/file2"
);
assert!(
Arc::ptr_eq(&dir1.lookup("..")?, &root),
"failed to find .. from dir1"
@ -161,6 +165,12 @@ fn create_then_lookup() -> Result<()> {
"failed to find dir1/file2 by weird relative"
);
assert!(root.lookup("./dir1/../file2").is_err(), "found non-existent file");
assert!(root.lookup("./dir1/../file3").is_err(), "found non-existent file");
assert!(root.lookup("/dir1/../dir1/../file3").is_err(), "found non-existent file");
assert!(root.lookup("/dir1/../../../dir1/../file3").is_err(), "found non-existent file");
assert!(root.lookup("/").unwrap().lookup("dir1/../file2").is_err(), "found non-existent file");
sfs.sync()?;
Ok(())
}
@ -237,6 +247,25 @@ fn test_symlinks() -> Result<()> {
"failed to find file1 by link2"
);
let dir1 = root
.create("dir1", FileType::Dir, 0o777)
.expect("failed to create dir1");
let file2 = dir1
.create("file2", FileType::File, 0o777)
.expect("failed to create /dir1/file2");
let link_dir = root
.create("link_dir", FileType::SymLink, 0o777)
.expect("failed to create link2");
let data = "dir1".as_bytes();
link_dir.resize(data.len())?;
link_dir.write_at(0, data)?;
assert!(
Arc::ptr_eq(&root.lookup_follow("link_dir/file2", 1)?, &file2),
"failed to find file2"
);
sfs.sync()?;
Ok(())
}

@ -65,10 +65,9 @@ impl INode {
}
// handle absolute path
if let Some('/') = rest_path.chars().next() {
return self
.fs()
.root_inode()
.lookup_follow(&path[1..], follow_times);
result = self.fs().root_inode();
rest_path = String::from(&rest_path[1..]);
continue;
}
let name;
match rest_path.find('/') {
@ -90,17 +89,17 @@ impl INode {
let mut content = [0u8; 256];
let len = inode.read_at(0, &mut content)?;
if let Ok(path) = str::from_utf8(&content[..len]) {
if let Some('/') = path.chars().next() {
// absolute link
return result
.fs()
.root_inode()
.lookup_follow(&path[1..], follow_times);
} else {
// relative link
// result remains unchanged
rest_path = String::from(path);
}
// result remains unchanged
rest_path = {
let mut new_path = String::from(path);
if let Some('/') = new_path.chars().last() {
new_path += &rest_path;
} else {
new_path += "/";
new_path += &rest_path;
}
new_path
};
} else {
return Err(FsError::NotDir);
}

Loading…
Cancel
Save