summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock54
-rw-r--r--Cargo.toml22
-rw-r--r--ayafs/Cargo.toml18
-rw-r--r--ayafs/src/block_device/disk.rs47
-rw-r--r--ayafs/src/block_device/memory_disk.rs (renamed from src/block_device/memory_disk.rs)0
-rw-r--r--ayafs/src/block_device/mod.rs (renamed from src/block_device/mod.rs)2
-rw-r--r--ayafs/src/disk/allocation.rs (renamed from src/disk/allocation.rs)38
-rw-r--r--ayafs/src/disk/bitmap.rs (renamed from src/disk/bitmap.rs)0
-rw-r--r--ayafs/src/disk/block.rs (renamed from src/disk/block.rs)0
-rw-r--r--ayafs/src/disk/inode.rs (renamed from src/disk/inode.rs)2
-rw-r--r--ayafs/src/disk/mod.rs (renamed from src/disk/mod.rs)0
-rw-r--r--ayafs/src/filesystem/mod.rs (renamed from src/filesystem/mod.rs)0
-rw-r--r--ayafs/src/filesystem/trait_impl.rs (renamed from src/filesystem/trait_impl.rs)555
-rw-r--r--ayafs/src/main.rs (renamed from src/main.rs)23
-rw-r--r--ayafs/src/memory/cached_block.rs (renamed from src/memory/cached_block.rs)0
-rw-r--r--ayafs/src/memory/cached_inode.rs (renamed from src/memory/cached_inode.rs)5
-rw-r--r--ayafs/src/memory/dir_entry.rs (renamed from src/memory/dir_entry.rs)0
-rw-r--r--ayafs/src/memory/file_handle.rs (renamed from src/memory/file_handle.rs)0
-rw-r--r--ayafs/src/memory/mod.rs (renamed from src/memory/mod.rs)0
-rw-r--r--ayafs/src/tests/bitmap.rs (renamed from src/tests/bitmap.rs)0
-rw-r--r--ayafs/src/tests/block_cache.rs (renamed from src/tests/block_cache.rs)0
-rw-r--r--ayafs/src/tests/common/mod.rs (renamed from src/tests/common/mod.rs)0
-rw-r--r--ayafs/src/tests/mod.rs (renamed from src/tests/mod.rs)0
-rw-r--r--ayafs/src/utils/constants.rs (renamed from src/utils/constants.rs)0
-rw-r--r--ayafs/src/utils/mod.rs (renamed from src/utils/mod.rs)0
-rw-r--r--ayafs/src/utils/permissions.rs (renamed from src/utils/permissions.rs)0
-rw-r--r--mkfs.aya/Cargo.toml8
-rw-r--r--mkfs.aya/src/block_device.rs5
-rw-r--r--mkfs.aya/src/main.rs21
-rw-r--r--rust-toolchain1
30 files changed, 457 insertions, 344 deletions
diff --git a/Cargo.lock b/Cargo.lock
index bcb2183..35e0f9f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -84,6 +84,22 @@ dependencies = [
]
[[package]]
+name = "ayafs"
+version = "0.1.0"
+dependencies = [
+ "and_then_some",
+ "bitflags",
+ "clap",
+ "env_logger",
+ "fuser",
+ "indexmap",
+ "libc",
+ "log",
+ "lru",
+ "users",
+]
+
+[[package]]
name = "bitflags"
version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -103,9 +119,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
-version = "4.4.6"
+version = "4.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956"
+checksum = "41fffed7514f420abec6d183b1d3acfd9099c79c3a10a06ade4f8203f1411272"
dependencies = [
"clap_builder",
"clap_derive",
@@ -113,9 +129,9 @@ dependencies = [
[[package]]
name = "clap_builder"
-version = "4.4.6"
+version = "4.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45"
+checksum = "63361bae7eef3771745f02d8d892bec2fee5f6e34af316ba556e7f97a7069ff1"
dependencies = [
"anstream",
"anstyle",
@@ -125,9 +141,9 @@ dependencies = [
[[package]]
name = "clap_derive"
-version = "4.4.2"
+version = "4.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873"
+checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442"
dependencies = [
"heck",
"proc-macro2",
@@ -137,9 +153,9 @@ dependencies = [
[[package]]
name = "clap_lex"
-version = "0.5.1"
+version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961"
+checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1"
[[package]]
name = "colorchoice"
@@ -149,9 +165,9 @@ checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
[[package]]
name = "env_logger"
-version = "0.10.0"
+version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0"
+checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece"
dependencies = [
"humantime",
"is-terminal",
@@ -242,9 +258,9 @@ dependencies = [
[[package]]
name = "libc"
-version = "0.2.149"
+version = "0.2.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b"
+checksum = "89d92a4743f9a61002fae18374ed11e7973f530cb3a3255fb354818118b2203c"
[[package]]
name = "linux-raw-sys"
@@ -260,9 +276,9 @@ checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
[[package]]
name = "lru"
-version = "0.12.0"
+version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1efa59af2ddfad1854ae27d75009d538d0998b4b2fd47083e743ac1a10e46c60"
+checksum = "2994eeba8ed550fd9b47a0b38f0242bc3344e496483c6180b69139cc2fa5d1d7"
dependencies = [
"hashbrown",
]
@@ -274,18 +290,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
[[package]]
-name = "myfs"
+name = "mkayafs"
version = "0.1.0"
dependencies = [
- "and_then_some",
- "bitflags",
"clap",
- "env_logger",
- "fuser",
- "indexmap",
- "libc",
- "log",
- "lru",
"users",
]
diff --git a/Cargo.toml b/Cargo.toml
index 8cc9696..4f9021f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,18 +1,6 @@
-[package]
-name = "myfs"
-version = "0.1.0"
-edition = "2021"
+[workspace]
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]
-and_then_some = "1.0.0"
-bitflags = "2.4.0"
-clap = { version = "4.4.6", features = ["derive"] }
-env_logger = "0.10.0"
-fuser = "0.14.0"
-indexmap = "2.1.0"
-libc = "0.2.148"
-log = "0.4.20"
-lru = "0.12.0"
-users = "0.11.0"
+members = [
+ "ayafs",
+ "mkfs.aya",
+]
diff --git a/ayafs/Cargo.toml b/ayafs/Cargo.toml
new file mode 100644
index 0000000..43585e0
--- /dev/null
+++ b/ayafs/Cargo.toml
@@ -0,0 +1,18 @@
+[package]
+name = "ayafs"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
+and_then_some = "1.0.0"
+bitflags = "2.4.1"
+clap = { version = "4.4.10", features = ["derive"] }
+env_logger = "0.10.1"
+fuser = "0.14.0"
+indexmap = "2.1.0"
+libc = "0.2.150"
+log = "0.4.20"
+lru = "0.12.1"
+users = "0.11.0"
diff --git a/ayafs/src/block_device/disk.rs b/ayafs/src/block_device/disk.rs
new file mode 100644
index 0000000..3f0b018
--- /dev/null
+++ b/ayafs/src/block_device/disk.rs
@@ -0,0 +1,47 @@
+use std::cell::RefCell;
+use std::fs::File;
+use std::io::{Read, Seek, SeekFrom, Write};
+use std::path::{Path, PathBuf};
+use crate::block_device::{BLOCK_SIZE, BlockDevice};
+
+pub struct Disk {
+ disk_path: PathBuf,
+ device: RefCell<File>,
+}
+
+impl Disk {
+ pub fn new(disk_path: PathBuf) -> Self {
+ let device = File::options()
+ .read(true)
+ .write(true)
+ .open(disk_path.as_path())
+ .unwrap();
+ // let device = File::open(disk_path.as_path()).unwrap();
+ Self {
+ disk_path,
+ device: RefCell::new(device),
+ }
+ }
+}
+
+impl BlockDevice for Disk {
+ fn read(&self, block_id: usize, buffer: &mut [u8]) {
+ let mut device = self.device.borrow_mut();
+ device
+ .seek(SeekFrom::Start((block_id * BLOCK_SIZE) as u64))
+ .expect("Unable to seek!");
+ device
+ .read_exact(buffer)
+ .expect("Failed to read 4096 bytes!");
+ }
+
+ fn write(&self, block_id: usize, buffer: &[u8]) {
+ let mut device = self.device.borrow_mut();
+ device
+ .seek(SeekFrom::Start((block_id * BLOCK_SIZE) as u64))
+ .expect("Unable to seek!");
+ device
+ .write_all(buffer)
+ .expect("Unable to write 4096 bytes!");
+ }
+} \ No newline at end of file
diff --git a/src/block_device/memory_disk.rs b/ayafs/src/block_device/memory_disk.rs
index 0639d3e..0639d3e 100644
--- a/src/block_device/memory_disk.rs
+++ b/ayafs/src/block_device/memory_disk.rs
diff --git a/src/block_device/mod.rs b/ayafs/src/block_device/mod.rs
index a8fd8b7..a1e6544 100644
--- a/src/block_device/mod.rs
+++ b/ayafs/src/block_device/mod.rs
@@ -1,6 +1,8 @@
/// Abstracts for block devices.
/// Currently only a mock memory disk.
pub mod memory_disk;
+pub mod disk;
+
pub const BLOCK_SIZE: usize = 4096;
pub trait BlockDevice {
fn read(&self, block_id: usize, buffer: &mut [u8]);
diff --git a/src/disk/allocation.rs b/ayafs/src/disk/allocation.rs
index d0142c9..a187fad 100644
--- a/src/disk/allocation.rs
+++ b/ayafs/src/disk/allocation.rs
@@ -1,9 +1,9 @@
use crate::disk::block::{
Block, DataBlock, DoubleIndirectBlock, IndirectBlock, TripleIndirectBlock,
};
-use crate::disk::inode::{Inode, DIRECT_NUMBER};
+use crate::disk::inode::{Inode, DIRECT_NUMBER, ENTRY_PER_BLOCK};
use crate::memory::cached_block::{convert, CachedBlock};
-use crate::{AyaFS, INODE_PER_BLOCK};
+use crate::AyaFS;
use libc::c_int;
use log::debug;
@@ -59,7 +59,7 @@ impl AyaFS {
{
// println!("allocating {} in double indirect", block_index);
inode.n_blocks += 1;
- let index_within_block = DIRECT_NUMBER + INODE_PER_BLOCK + index_within_double;
+ let index_within_block = DIRECT_NUMBER + ENTRY_PER_BLOCK + index_within_double;
return Some((block_index, index_within_block));
}
@@ -79,8 +79,8 @@ impl AyaFS {
// println!("allocating {} in triple indirect", block_index);
inode.n_blocks += 1;
let index_within_block = DIRECT_NUMBER
- + INODE_PER_BLOCK
- + INODE_PER_BLOCK * INODE_PER_BLOCK
+ + ENTRY_PER_BLOCK
+ + ENTRY_PER_BLOCK * ENTRY_PER_BLOCK
+ index_within_triple;
return Some((block_index, index_within_block));
}
@@ -142,7 +142,7 @@ impl AyaFS {
self.update_block(double_indirect_block);
}
let index_within_double =
- index_within_double_indirect * INODE_PER_BLOCK + index_within_indirect;
+ index_within_double_indirect * ENTRY_PER_BLOCK + index_within_indirect;
return Some((block_index, index_within_double));
}
}
@@ -180,7 +180,7 @@ impl AyaFS {
self.update_block(triple_indirect_block);
}
let index_within_triple =
- index_within_triple_indirect * INODE_PER_BLOCK * INODE_PER_BLOCK
+ index_within_triple_indirect * ENTRY_PER_BLOCK * ENTRY_PER_BLOCK
+ index_within_double_indirect;
return Some((block_index, index_within_triple));
}
@@ -424,7 +424,7 @@ impl AyaFS {
}
// indirect block
- let indirect_number = 1024;
+ let indirect_number = ENTRY_PER_BLOCK;
if block_index_within_inode < indirect_number {
return if let Some(indirect_block) =
self.get_block::<IndirectBlock>(inode.single_indirect as usize)
@@ -432,10 +432,10 @@ impl AyaFS {
debug!(" get_block_index -> indirect");
let block_index = indirect_block.block.entries[block_index_within_inode] as usize;
if self.data_bitmap.query(block_index) {
- debug!(" get_block_index -> indirect -> direct -> ✓");
+ debug!(" get_block_index -> indirect -> ✓");
Some(block_index)
} else {
- debug!(" get_block_index -> indirect -> direct -> ×");
+ debug!(" get_block_index -> indirect -> ×");
None
}
} else {
@@ -447,25 +447,29 @@ impl AyaFS {
}
// double indirect block
- let double_indirect_number = 1024 * 1024;
+ let double_indirect_number = ENTRY_PER_BLOCK * ENTRY_PER_BLOCK;
if block_index_within_inode < double_indirect_number {
if let Some(double_indirect_block) =
self.get_block::<DoubleIndirectBlock>(inode.double_indirect as usize)
{
+ debug!(" get_block_index -> double_indirect");
// 取出 double indirect block
let indirect_block_index = double_indirect_block.block.indirect
- [block_index_within_inode / INODE_PER_BLOCK]
+ [block_index_within_inode / ENTRY_PER_BLOCK]
as usize;
// 要找的 entry 在 double indirect block 中的第几个 indirect block
if let Some(indirect_block) = self.get_block::<IndirectBlock>(indirect_block_index)
{
+ debug!(" get_block_index -> double_indirect -> indirect");
let block_index = indirect_block.block.entries
- [block_index_within_inode % INODE_PER_BLOCK]
+ [block_index_within_inode % ENTRY_PER_BLOCK]
as usize;
// 拿到 DirectoryBlock 的 index
return if self.data_bitmap.query(block_index) {
+ debug!(" get_block_index -> double_indirect -> indirect -> ✓");
Some(block_index)
} else {
+ debug!(" get_block_index -> double_indirect -> indirect -> ×");
None
};
}
@@ -481,7 +485,7 @@ impl AyaFS {
{
// 取出 triple indirect block
let double_indirect_block_index = triple_indirect_block.block.double_indirect
- [block_index_within_inode / (INODE_PER_BLOCK * INODE_PER_BLOCK)]
+ [block_index_within_inode / (ENTRY_PER_BLOCK * ENTRY_PER_BLOCK)]
as usize;
// 要找的 entry 在 triple indirect block 中的第几个 double indirect block
if let Some(double_indirect_block) =
@@ -489,13 +493,13 @@ impl AyaFS {
{
// 取出 double indirect block
let indirect_block_index = double_indirect_block.block.indirect
- [block_index_within_inode % (INODE_PER_BLOCK * INODE_PER_BLOCK)
- / INODE_PER_BLOCK] as usize;
+ [block_index_within_inode % (ENTRY_PER_BLOCK * ENTRY_PER_BLOCK)
+ / ENTRY_PER_BLOCK] as usize;
// 要找的 entry 在 double indirect block 中的第几个 indirect block
if let Some(indirect_block) = self.get_block::<IndirectBlock>(indirect_block_index)
{
let block_index = indirect_block.block.entries
- [block_index_within_inode % INODE_PER_BLOCK]
+ [block_index_within_inode % ENTRY_PER_BLOCK]
as usize;
// DirectoryBlock 的 index
return if self.data_bitmap.query(block_index) {
diff --git a/src/disk/bitmap.rs b/ayafs/src/disk/bitmap.rs
index b68c341..b68c341 100644
--- a/src/disk/bitmap.rs
+++ b/ayafs/src/disk/bitmap.rs
diff --git a/src/disk/block.rs b/ayafs/src/disk/block.rs
index 73819e2..73819e2 100644
--- a/src/disk/block.rs
+++ b/ayafs/src/disk/block.rs
diff --git a/src/disk/inode.rs b/ayafs/src/disk/inode.rs
index e686d01..0c801ad 100644
--- a/src/disk/inode.rs
+++ b/ayafs/src/disk/inode.rs
@@ -1,6 +1,7 @@
use crate::utils;
use bitflags::bitflags;
use fuser::FileType;
+use crate::block_device::BLOCK_SIZE;
pub const DIRECT_NUMBER: usize = 15;
@@ -308,3 +309,4 @@ impl Inode {
}
}
pub const INODE_SIZE: usize = std::mem::size_of::<Inode>();
+pub const ENTRY_PER_BLOCK: usize = BLOCK_SIZE / 4; \ No newline at end of file
diff --git a/src/disk/mod.rs b/ayafs/src/disk/mod.rs
index 878e832..878e832 100644
--- a/src/disk/mod.rs
+++ b/ayafs/src/disk/mod.rs
diff --git a/src/filesystem/mod.rs b/ayafs/src/filesystem/mod.rs
index 1eaa8e8..1eaa8e8 100644
--- a/src/filesystem/mod.rs
+++ b/ayafs/src/filesystem/mod.rs
diff --git a/src/filesystem/trait_impl.rs b/ayafs/src/filesystem/trait_impl.rs
index e030f04..1c40b92 100644
--- a/src/filesystem/trait_impl.rs
+++ b/ayafs/src/filesystem/trait_impl.rs
@@ -1,8 +1,7 @@
use crate::block_device::BLOCK_SIZE;
use crate::disk::block::DataBlock;
use crate::disk::inode::InodeMode;
-use crate::utils::permissions::get_groups;
-use crate::utils::permissions::{check_access, clear_suid_sgid};
+use crate::utils::permissions::{check_access, clear_suid_sgid, get_groups};
use crate::utils::{from_filetype, from_systime, time_now, to_fileattr, to_filetype};
use crate::{AyaFS, TTL};
use fuser::TimeOrNow::{Now, SpecificTime};
@@ -10,9 +9,9 @@ use fuser::{
FileType, Filesystem, KernelConfig, ReplyAttr, ReplyData, ReplyDirectory, ReplyEmpty,
ReplyEntry, ReplyOpen, ReplyWrite, Request, TimeOrNow,
};
-use libc::{c_int, link, write, EACCES, EBADF, EEXIST, EFAULT, EINVAL, EIO, EISDIR, ENAMETOOLONG, ENOENT, ENOSPC, ENOSYS, ENOTDIR, ENOTEMPTY, EPERM, IPOPT_OFFSET, O_ACCMODE, O_RDONLY, O_RDWR, O_WRONLY, R_OK, S_ISGID, S_ISUID, S_IXGRP, S_IXOTH, S_IXUSR, W_OK, RENAME_NOREPLACE, RENAME_EXCHANGE};
+use libc::{c_int, EACCES, EBADF, EEXIST, EINVAL, EIO, EISDIR, ENAMETOOLONG, ENOENT, ENOSPC, ENOTDIR, ENOTEMPTY, EPERM, IPOPT_OFFSET, O_ACCMODE, O_RDONLY, O_RDWR, O_WRONLY, R_OK, S_ISGID, S_ISUID, S_IXGRP, S_IXOTH, S_IXUSR, W_OK, RENAME_NOREPLACE, RENAME_EXCHANGE};
use log::debug;
-use std::ffi::{OsStr, OsString};
+use std::ffi::OsStr;
use std::os::unix::ffi::OsStrExt;
use std::path::Path;
use std::slice;
@@ -253,154 +252,6 @@ impl Filesystem for AyaFS {
}
}
- fn symlink(
- &mut self,
- req: &Request<'_>,
- parent: u64,
- link_name: &OsStr,
- target: &Path,
- reply: ReplyEntry,
- ) {
- debug!(
- "symlink(parent: {}, name: {:?}, target: {:?})",
- parent, link_name, target
- );
- let parent = parent as usize;
-
- // let root_inode_index = 1usize;
- // if let Some(root_inode) = self.get_inode(root_inode_index) {
- // let mut curr_inode_index = root_inode_index;
- // let mut curr_inode = root_inode.clone();
- // for segment in target.iter() {
- // match self.lookup_name(curr_inode_index, &curr_inode, segment) {
- // Ok((next_inode_index, _, next_inode)) => {
- // curr_inode_index = next_inode_index as usize;
- // curr_inode = next_inode;
- // }
- // Err(err_code) => {
- // reply.error(err_code);
- // return;
- // }
- // }
- // }
- // } else {
- // reply.error(EIO);
- // return;
- // }
-
- if let Some(parent_inode) = self.get_inode(parent) {
- if !check_access(
- req.uid(),
- req.gid(),
- parent_inode.uid,
- parent_inode.gid,
- parent_inode.mode,
- W_OK,
- ) {
- reply.error(EACCES);
- return;
- }
-
- if !parent_inode.is_dir() {
- reply.error(ENOTDIR);
- return;
- }
-
- if link_name.len() > 255 {
- reply.error(ENAMETOOLONG);
- return;
- }
-
- let target = target.as_os_str();
- let mut parent_inode = parent_inode.clone();
- if self.lookup_name(parent, &parent_inode, link_name).is_ok() {
- reply.error(EEXIST);
- return;
- }
-
- if let Some((child_inode_index, child_inode)) =
- self.create_symlink(0o777, req.uid(), req.gid(), 0)
- {
- let mut child_inode = child_inode.clone();
- child_inode.size = target.len() as u32;
- if target.len() < 60 {
- debug!("create_symlink: target length < 60, allocating in 'direct' section.");
- let target_path = target.as_bytes();
- let copy_dst = unsafe {
- let dst = (&mut child_inode.direct) as *mut u32 as *mut u8;
- slice::from_raw_parts_mut(dst, target_path.len())
- };
- copy_dst.copy_from_slice(target_path);
- } else {
- debug!("create_symlink: target length >= 60, using original layout.");
- let mut write_ptr = 0usize;
- while write_ptr < target.len() {
- let block_index = write_ptr / BLOCK_SIZE;
- let offset = write_ptr % BLOCK_SIZE;
-
- let write_length_within_block =
- if BLOCK_SIZE - offset < target.len() - write_ptr {
- BLOCK_SIZE - offset
- } else {
- target.len() - write_ptr
- };
-
- if let Some(block) =
- self.access_block_mut::<DataBlock>(&child_inode, block_index)
- {
- block.block.0[offset..offset + write_length_within_block]
- .copy_from_slice(
- &target.as_bytes()
- [write_ptr..write_ptr + write_length_within_block],
- );
- write_ptr += write_length_within_block;
- } else {
- if let Some((_block_index, block_index_within_inode)) =
- self.allocate_block_for(&mut child_inode)
- {
- let block = self
- .access_block_mut::<DataBlock>(
- &child_inode,
- block_index_within_inode,
- )
- .unwrap();
- block.block.0[offset..offset + write_length_within_block]
- .copy_from_slice(
- &target.as_bytes()
- [write_ptr..write_ptr + write_length_within_block],
- );
- write_ptr += write_length_within_block;
- } else {
- reply.error(ENOSPC);
- return;
- }
- }
- }
- }
-
- let file_attr = to_fileattr(child_inode_index, &child_inode);
- self.update_inode(child_inode_index, child_inode);
-
- if let Err(err_code) = self.add_direntry(
- parent,
- &mut parent_inode,
- child_inode_index,
- link_name,
- from_filetype(FileType::Symlink),
- ) {
- reply.error(err_code);
- return;
- }
- self.update_inode(parent, parent_inode);
- reply.entry(&TTL, &file_attr, 0);
- } else {
- reply.error(ENOSPC);
- }
- } else {
- reply.error(ENOENT);
- }
- }
-
// 这啥语义啊??
fn readlink(&mut self, req: &Request<'_>, ino: u64, reply: ReplyData) {
debug!("readlink(ino: {})", ino);
@@ -463,132 +314,6 @@ impl Filesystem for AyaFS {
}
}
- fn rename(
- &mut self,
- req: &Request<'_>,
- parent: u64,
- name: &OsStr,
- new_parent: u64,
- new_name: &OsStr,
- flags: u32,
- reply: ReplyEmpty,
- ) {
- debug!(
- "rename(parent: {}, name: {:?}, new_parent: {}, new_name: {:?})",
- parent, name, new_parent, new_name
- );
-
- let parent = parent as usize;
- let new_parent = new_parent as usize;
- if let Some(parent_inode) = self.get_inode(parent) {
- if !check_access(
- req.uid(),
- req.gid(),
- parent_inode.uid,
- parent_inode.gid,
- parent_inode.mode,
- R_OK,
- ) {
- reply.error(EACCES);
- return;
- }
-
- if name.len() > 255 {
- reply.error(ENAMETOOLONG);
- return;
- }
-
- let mut parent_inode = parent_inode.clone();
- match self.lookup_name(parent, &parent_inode, name) {
- Ok((inode_index, entry_index, inode)) => {
- if let Some(new_parent_inode) = self.get_inode(new_parent) {
- if !check_access(
- req.uid(),
- req.gid(),
- new_parent_inode.uid,
- new_parent_inode.gid,
- new_parent_inode.mode,
- W_OK,
- ) {
- reply.error(EACCES);
- return;
- }
- if new_name.len() > 255 {
- reply.error(ENAMETOOLONG);
- return;
- }
-
- let mut new_parent_inode = new_parent_inode.clone();
- match self.lookup_name(new_parent, &new_parent_inode, new_name) {
- Ok((new_inode_index, new_entry_index, new_inode)) => {
- // 新文件存在
- if flags & RENAME_NOREPLACE != 0 { // 指定 noreplace 之后不允许覆盖文件
- reply.error(EEXIST);
- return;
- }
- if flags & RENAME_EXCHANGE != 0 { // 交换两个文件
- if let Err(err_code) = self.exchange_direntry(
- parent,
- &mut parent_inode,
- name,
- new_parent,
- &mut new_parent_inode,
- new_name
- ) {
- reply.error(err_code);
- return;
- }
- } else { // 用新文件替换旧文件
- let dir_entry = self.get_direntry_by_name(parent, &parent_inode, name)
- .unwrap();
- if let Err(err_code) = self.remove_direntry(parent, &mut parent_inode, name, entry_index) {
- reply.error(err_code);
- return;
- }
- if let Err(err_code) = self.remove_direntry(new_parent, &mut new_parent_inode, new_name, new_entry_index) {
- reply.error(err_code);
- return;
- }
- if let Err(err_code) = self.add_direntry_2(new_parent, &mut new_parent_inode, new_name, dir_entry) {
- reply.error(err_code);
- return;
- }
- }
- reply.ok();
- },
- Err(ENOENT) => { // 新文件不存在, 删除旧的创建新的
- let dir_entry = self.get_direntry_by_name(parent, &parent_inode, name)
- .unwrap();
- if let Err(err_code) = self.remove_direntry(parent, &mut parent_inode, name, entry_index) {
- reply.error(err_code);
- return;
- }
- if let Err(err_code) = self.add_direntry_2(new_parent, &mut new_parent_inode, new_name, dir_entry) {
- reply.error(err_code);
- return;
- }
- reply.ok();
- },
- Err(err_code) => {
- // 其他 Err code
- reply.error(err_code);
- return;
- }
- }
- } else {
- reply.error(ENOENT);
- }
- },
- Err(err_code) => {
- reply.error(err_code);
- return;
- }
- }
- } else {
- reply.error(ENOENT);
- }
- }
-
fn mknod(
&mut self,
req: &Request<'_>,
@@ -891,6 +616,280 @@ impl Filesystem for AyaFS {
}
}
+ fn symlink(
+ &mut self,
+ req: &Request<'_>,
+ parent: u64,
+ link_name: &OsStr,
+ target: &Path,
+ reply: ReplyEntry,
+ ) {
+ debug!(
+ "symlink(parent: {}, name: {:?}, target: {:?})",
+ parent, link_name, target
+ );
+ let parent = parent as usize;
+
+ // let root_inode_index = 1usize;
+ // if let Some(root_inode) = self.get_inode(root_inode_index) {
+ // let mut curr_inode_index = root_inode_index;
+ // let mut curr_inode = root_inode.clone();
+ // for segment in target.iter() {
+ // match self.lookup_name(curr_inode_index, &curr_inode, segment) {
+ // Ok((next_inode_index, _, next_inode)) => {
+ // curr_inode_index = next_inode_index as usize;
+ // curr_inode = next_inode;
+ // }
+ // Err(err_code) => {
+ // reply.error(err_code);
+ // return;
+ // }
+ // }
+ // }
+ // } else {
+ // reply.error(EIO);
+ // return;
+ // }
+
+ if let Some(parent_inode) = self.get_inode(parent) {
+ if !check_access(
+ req.uid(),
+ req.gid(),
+ parent_inode.uid,
+ parent_inode.gid,
+ parent_inode.mode,
+ W_OK,
+ ) {
+ reply.error(EACCES);
+ return;
+ }
+
+ if !parent_inode.is_dir() {
+ reply.error(ENOTDIR);
+ return;
+ }
+
+ if link_name.len() > 255 {
+ reply.error(ENAMETOOLONG);
+ return;
+ }
+
+ let target = target.as_os_str();
+ let mut parent_inode = parent_inode.clone();
+ if self.lookup_name(parent, &parent_inode, link_name).is_ok() {
+ reply.error(EEXIST);
+ return;
+ }
+
+ if let Some((child_inode_index, child_inode)) =
+ self.create_symlink(0o777, req.uid(), req.gid(), 0)
+ {
+ let mut child_inode = child_inode.clone();
+ child_inode.size = target.len() as u32;
+ if target.len() < 60 {
+ debug!("create_symlink: target length < 60, allocating in 'direct' section.");
+ let target_path = target.as_bytes();
+ let copy_dst = unsafe {
+ let dst = (&mut child_inode.direct) as *mut u32 as *mut u8;
+ slice::from_raw_parts_mut(dst, target_path.len())
+ };
+ copy_dst.copy_from_slice(target_path);
+ } else {
+ debug!("create_symlink: target length >= 60, using original layout.");
+ let mut write_ptr = 0usize;
+ while write_ptr < target.len() {
+ let block_index = write_ptr / BLOCK_SIZE;
+ let offset = write_ptr % BLOCK_SIZE;
+
+ let write_length_within_block =
+ if BLOCK_SIZE - offset < target.len() - write_ptr {
+ BLOCK_SIZE - offset
+ } else {
+ target.len() - write_ptr
+ };
+
+ if let Some(block) =
+ self.access_block_mut::<DataBlock>(&child_inode, block_index)
+ {
+ block.block.0[offset..offset + write_length_within_block]
+ .copy_from_slice(
+ &target.as_bytes()
+ [write_ptr..write_ptr + write_length_within_block],
+ );
+ write_ptr += write_length_within_block;
+ } else {
+ if let Some((_block_index, block_index_within_inode)) =
+ self.allocate_block_for(&mut child_inode)
+ {
+ let block = self
+ .access_block_mut::<DataBlock>(
+ &child_inode,
+ block_index_within_inode,
+ )
+ .unwrap();
+ block.block.0[offset..offset + write_length_within_block]
+ .copy_from_slice(
+ &target.as_bytes()
+ [write_ptr..write_ptr + write_length_within_block],
+ );
+ write_ptr += write_length_within_block;
+ } else {
+ reply.error(ENOSPC);
+ return;
+ }
+ }
+ }
+ }
+
+ let file_attr = to_fileattr(child_inode_index, &child_inode);
+ self.update_inode(child_inode_index, child_inode);
+
+ if let Err(err_code) = self.add_direntry(
+ parent,
+ &mut parent_inode,
+ child_inode_index,
+ link_name,
+ from_filetype(FileType::Symlink),
+ ) {
+ reply.error(err_code);
+ return;
+ }
+ self.update_inode(parent, parent_inode);
+ reply.entry(&TTL, &file_attr, 0);
+ } else {
+ reply.error(ENOSPC);
+ }
+ } else {
+ reply.error(ENOENT);
+ }
+ }
+
+ fn rename(
+ &mut self,
+ req: &Request<'_>,
+ parent: u64,
+ name: &OsStr,
+ new_parent: u64,
+ new_name: &OsStr,
+ flags: u32,
+ reply: ReplyEmpty,
+ ) {
+ debug!(
+ "rename(parent: {}, name: {:?}, new_parent: {}, new_name: {:?})",
+ parent, name, new_parent, new_name
+ );
+
+ let parent = parent as usize;
+ let new_parent = new_parent as usize;
+ if let Some(parent_inode) = self.get_inode(parent) {
+ if !check_access(
+ req.uid(),
+ req.gid(),
+ parent_inode.uid,
+ parent_inode.gid,
+ parent_inode.mode,
+ R_OK,
+ ) {
+ reply.error(EACCES);
+ return;
+ }
+
+ if name.len() > 255 {
+ reply.error(ENAMETOOLONG);
+ return;
+ }
+
+ let mut parent_inode = parent_inode.clone();
+ match self.lookup_name(parent, &parent_inode, name) {
+ Ok((inode_index, entry_index, inode)) => {
+ if let Some(new_parent_inode) = self.get_inode(new_parent) {
+ if !check_access(
+ req.uid(),
+ req.gid(),
+ new_parent_inode.uid,
+ new_parent_inode.gid,
+ new_parent_inode.mode,
+ W_OK,
+ ) {
+ reply.error(EACCES);
+ return;
+ }
+ if new_name.len() > 255 {
+ reply.error(ENAMETOOLONG);
+ return;
+ }
+
+ let mut new_parent_inode = new_parent_inode.clone();
+ match self.lookup_name(new_parent, &new_parent_inode, new_name) {
+ Ok((new_inode_index, new_entry_index, new_inode)) => {
+ // 新文件存在
+ if flags & RENAME_NOREPLACE != 0 { // 指定 noreplace 之后不允许覆盖文件
+ reply.error(EEXIST);
+ return;
+ }
+ if flags & RENAME_EXCHANGE != 0 { // 交换两个文件
+ if let Err(err_code) = self.exchange_direntry(
+ parent,
+ &mut parent_inode,
+ name,
+ new_parent,
+ &mut new_parent_inode,
+ new_name
+ ) {
+ reply.error(err_code);
+ return;
+ }
+ } else { // 用新文件替换旧文件
+ let dir_entry = self.get_direntry_by_name(parent, &parent_inode, name)
+ .unwrap();
+ if let Err(err_code) = self.remove_direntry(parent, &mut parent_inode, name, entry_index) {
+ reply.error(err_code);
+ return;
+ }
+ if let Err(err_code) = self.remove_direntry(new_parent, &mut new_parent_inode, new_name, new_entry_index) {
+ reply.error(err_code);
+ return;
+ }
+ if let Err(err_code) = self.add_direntry_2(new_parent, &mut new_parent_inode, new_name, dir_entry) {
+ reply.error(err_code);
+ return;
+ }
+ }
+ reply.ok();
+ },
+ Err(ENOENT) => { // 新文件不存在, 删除旧的创建新的
+ let dir_entry = self.get_direntry_by_name(parent, &parent_inode, name)
+ .unwrap();
+ if let Err(err_code) = self.remove_direntry(parent, &mut parent_inode, name, entry_index) {
+ reply.error(err_code);
+ return;
+ }
+ if let Err(err_code) = self.add_direntry_2(new_parent, &mut new_parent_inode, new_name, dir_entry) {
+ reply.error(err_code);
+ return;
+ }
+ reply.ok();
+ },
+ Err(err_code) => {
+ // 其他 Err code
+ reply.error(err_code);
+ return;
+ }
+ }
+ } else {
+ reply.error(ENOENT);
+ }
+ },
+ Err(err_code) => {
+ reply.error(err_code);
+ return;
+ }
+ }
+ } else {
+ reply.error(ENOENT);
+ }
+ }
+
fn open(&mut self, req: &Request<'_>, ino: u64, flags: i32, reply: ReplyOpen) {
debug!("open(ino: {:#x?}, flags: {:#x?})", ino, flags);
let (access_mask, read, write) = match flags & O_ACCMODE {
diff --git a/src/main.rs b/ayafs/src/main.rs
index 78f338a..db4a017 100644
--- a/src/main.rs
+++ b/ayafs/src/main.rs
@@ -8,11 +8,12 @@ mod utils;
use clap::Parser;
use fuser::MountOption;
use indexmap::IndexMap;
-use log::debug;
+use log::{debug, LevelFilter};
use lru::LruCache;
use std::collections::HashMap;
use std::ffi::OsString;
use std::num::NonZeroUsize;
+use std::path::PathBuf;
use std::sync::atomic::AtomicU64;
use std::sync::Arc;
use std::time::Duration;
@@ -24,11 +25,14 @@ use disk::bitmap::Bitmap;
use disk::block::DataBlock;
use disk::inode::INODE_SIZE;
use users::{get_current_gid, get_current_uid};
+use crate::block_device::disk::Disk;
#[derive(Parser, Debug)]
#[command(author, version, about)]
struct Args {
mount_point: Option<String>,
+ #[arg(short, action = clap::ArgAction::Count)]
+ verbosity: u8,
#[arg(long)]
auto_unmount: bool,
#[arg(long)]
@@ -140,17 +144,28 @@ impl AyaFS {
}
fn main() {
- env_logger::init();
let args = Args::parse();
let mount_point = args.mount_point.unwrap();
+ let verbosity = args.verbosity;
+ let log_level = match verbosity {
+ 0 => LevelFilter::Error,
+ 1 => LevelFilter::Warn,
+ 2 => LevelFilter::Info,
+ 3 => LevelFilter::Debug,
+ _ => LevelFilter::Trace,
+ };
+ env_logger::builder()
+ .filter_level(log_level)
+ .init();
let options = vec![
// MountOption::RO,
MountOption::FSName("hello".to_string()),
MountOption::AutoUnmount,
MountOption::AllowRoot,
];
- let mem_disk = Arc::new(MemoryDisk::new(16384));
- let filesystem = AyaFS::new(mem_disk, 16384);
+ let disk = Arc::new(Disk::new(PathBuf::from("/dev/nvme0n1p4")));
+ // let disk = Arc::new(MemoryDisk::new(16384));
+ let filesystem = AyaFS::new(disk, 7864320);
fuser::mount2(filesystem, mount_point, &options).unwrap();
}
diff --git a/src/memory/cached_block.rs b/ayafs/src/memory/cached_block.rs
index c3d0338..c3d0338 100644
--- a/src/memory/cached_block.rs
+++ b/ayafs/src/memory/cached_block.rs
diff --git a/src/memory/cached_inode.rs b/ayafs/src/memory/cached_inode.rs
index 16c40c2..2f26dde 100644
--- a/src/memory/cached_inode.rs
+++ b/ayafs/src/memory/cached_inode.rs
@@ -4,11 +4,6 @@ use crate::{utils, AyaFS};
use and_then_some::BoolExt;
use fuser::FileType;
use libc::{c_int, EIO, EISDIR, ENOENT, ENOTDIR, ENOTEMPTY};
-use log::{debug, error};
-use std::ffi::OsStr;
-use std::os::unix::ffi::OsStrExt;
-use std::path::Path;
-use std::slice;
impl AyaFS {
pub(crate) fn create_file(
diff --git a/src/memory/dir_entry.rs b/ayafs/src/memory/dir_entry.rs
index c013e1e..c013e1e 100644
--- a/src/memory/dir_entry.rs
+++ b/ayafs/src/memory/dir_entry.rs
diff --git a/src/memory/file_handle.rs b/ayafs/src/memory/file_handle.rs
index c821619..c821619 100644
--- a/src/memory/file_handle.rs
+++ b/ayafs/src/memory/file_handle.rs
diff --git a/src/memory/mod.rs b/ayafs/src/memory/mod.rs
index d1f1ab8..d1f1ab8 100644
--- a/src/memory/mod.rs
+++ b/ayafs/src/memory/mod.rs
diff --git a/src/tests/bitmap.rs b/ayafs/src/tests/bitmap.rs
index 1a43f09..1a43f09 100644
--- a/src/tests/bitmap.rs
+++ b/ayafs/src/tests/bitmap.rs
diff --git a/src/tests/block_cache.rs b/ayafs/src/tests/block_cache.rs
index 52117b9..52117b9 100644
--- a/src/tests/block_cache.rs
+++ b/ayafs/src/tests/block_cache.rs
diff --git a/src/tests/common/mod.rs b/ayafs/src/tests/common/mod.rs
index 3abfcb4..3abfcb4 100644
--- a/src/tests/common/mod.rs
+++ b/ayafs/src/tests/common/mod.rs
diff --git a/src/tests/mod.rs b/ayafs/src/tests/mod.rs
index df442c1..df442c1 100644
--- a/src/tests/mod.rs
+++ b/ayafs/src/tests/mod.rs
diff --git a/src/utils/constants.rs b/ayafs/src/utils/constants.rs
index 8b13789..8b13789 100644
--- a/src/utils/constants.rs
+++ b/ayafs/src/utils/constants.rs
diff --git a/src/utils/mod.rs b/ayafs/src/utils/mod.rs
index 468ebdb..468ebdb 100644
--- a/src/utils/mod.rs
+++ b/ayafs/src/utils/mod.rs
diff --git a/src/utils/permissions.rs b/ayafs/src/utils/permissions.rs
index 6773511..6773511 100644
--- a/src/utils/permissions.rs
+++ b/ayafs/src/utils/permissions.rs
diff --git a/mkfs.aya/Cargo.toml b/mkfs.aya/Cargo.toml
new file mode 100644
index 0000000..c75e3cb
--- /dev/null
+++ b/mkfs.aya/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "mkayafs"
+version = "0.1.0"
+edition = "2021"
+
+[dependencies]
+users = "0.11.0"
+clap = { version = "4.4.10", features = ["derive"] } \ No newline at end of file
diff --git a/mkfs.aya/src/block_device.rs b/mkfs.aya/src/block_device.rs
new file mode 100644
index 0000000..295b357
--- /dev/null
+++ b/mkfs.aya/src/block_device.rs
@@ -0,0 +1,5 @@
+pub(crate) const BLOCK_SIZE: usize = 4096;
+pub(crate) trait BlockDevice {
+ fn read(&self, block_id: usize, buffer: &mut [u8]);
+ fn write(&self, block_id: usize, buffer: &[u8]);
+} \ No newline at end of file
diff --git a/mkfs.aya/src/main.rs b/mkfs.aya/src/main.rs
new file mode 100644
index 0000000..57ca3fc
--- /dev/null
+++ b/mkfs.aya/src/main.rs
@@ -0,0 +1,21 @@
+mod block_device;
+
+use std::fs::File;
+use std::path::PathBuf;
+use clap::Parser;
+use users::{get_current_gid, get_current_uid};
+
+#[derive(Parser, Debug)]
+#[command(author, version, about)]
+struct Args {
+ block_device: Option<PathBuf>,
+ start_point: Option<usize>,
+ length: Option<usize>,
+}
+
+fn main() {
+ let args = Args::parse();
+ let device_path = args.block_device.unwrap();
+ println!("{:?}", device_path.as_path());
+ let mut device = File::open(device_path.as_path()).unwrap();
+} \ No newline at end of file
diff --git a/rust-toolchain b/rust-toolchain
new file mode 100644
index 0000000..870bbe4
--- /dev/null
+++ b/rust-toolchain
@@ -0,0 +1 @@
+stable \ No newline at end of file