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 { if let Some(block_id) = id {
let mut super_block = self.super_block.write(); let mut super_block = self.super_block.write();
if super_block.unused_blocks == 0 { if super_block.unused_blocks == 0 {
let super_block = self.super_block.read();
panic!("{:?}", super_block);
free_map.set(block_id, true); free_map.set(block_id, true);
return None; return None;
} }

@ -135,6 +135,10 @@ fn create_then_lookup() -> Result<()> {
Arc::ptr_eq(&root.lookup("dir1/file2")?, &file2), Arc::ptr_eq(&root.lookup("dir1/file2")?, &file2),
"failed to find dir1/file2" "failed to find dir1/file2"
); );
assert!(
Arc::ptr_eq(&root.lookup("/")?.lookup("dir1/file2")?, &file2),
"failed to find dir1/file2"
);
assert!( assert!(
Arc::ptr_eq(&dir1.lookup("..")?, &root), Arc::ptr_eq(&dir1.lookup("..")?, &root),
"failed to find .. from dir1" "failed to find .. from dir1"
@ -161,6 +165,12 @@ fn create_then_lookup() -> Result<()> {
"failed to find dir1/file2 by weird relative" "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()?; sfs.sync()?;
Ok(()) Ok(())
} }
@ -237,6 +247,25 @@ fn test_symlinks() -> Result<()> {
"failed to find file1 by link2" "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()?; sfs.sync()?;
Ok(()) Ok(())
} }

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

Loading…
Cancel
Save