Phase 3完成:FUSE完整重构以支持fuse-t
核心成果: - fuse-t库成功纳入项目(build.rs + Cargo.toml) - fuse-backend-rs API完整实现(270行代码) - FileSystem trait完整重写(lookup/getattr/read/readdir/open/release/opendir/releasedir/statfs) - ZeroCopyWriter API正确集成(write_from方法) - 服务循环正确实现(get_request + handle_message) 技术实现: - 依赖:fuse-backend-rs(fusedev + fuse-t features) - 链接:fuse-t库(pkg-config + DiskArbitration framework) - 数据库:find_node_id_by_parent方法新增 - API:DirEntry/Entry/stat64正确使用 - 服务:FuseSession/FuseChannel正确集成 编译状态: - 8警告,0错误 - 成功编译markbase-fuse库和main程序 状态:Phase 3完整实施完成
This commit is contained in:
415
Cargo.lock
generated
415
Cargo.lock
generated
@@ -178,6 +178,15 @@ version = "1.0.102"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c"
|
||||
|
||||
[[package]]
|
||||
name = "arc-swap"
|
||||
version = "1.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a3a1fd6f75306b68087b831f025c712524bcb19aad54e557b1129cfa0a2b207"
|
||||
dependencies = [
|
||||
"rustversion",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "argon2"
|
||||
version = "0.5.3"
|
||||
@@ -210,7 +219,7 @@ checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -335,7 +344,7 @@ checksum = "57d123550fa8d071b7255cb0cc04dc302baa6c8c4a79f55701552684d8399bce"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -421,7 +430,7 @@ dependencies = [
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"syn",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -585,6 +594,15 @@ dependencies = [
|
||||
"crossbeam-queue",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "caps"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd1ddba47aba30b6a889298ad0109c3b8dcb0e8fc993b459daa7067d46f865e0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cbc"
|
||||
version = "0.1.2"
|
||||
@@ -738,7 +756,7 @@ dependencies = [
|
||||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -860,6 +878,12 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc64"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2707e3afba5e19b75d582d88bc79237418f2a2a2d673d01cf9b03633b46e98f3"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.15"
|
||||
@@ -1032,7 +1056,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1073,7 +1097,7 @@ dependencies = [
|
||||
"http-body",
|
||||
"http-body-util",
|
||||
"libc",
|
||||
"log 0.4.29",
|
||||
"log",
|
||||
"lru",
|
||||
"mime_guess",
|
||||
"parking_lot",
|
||||
@@ -1087,6 +1111,19 @@ dependencies = [
|
||||
"xmltree",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dbs-snapshot"
|
||||
version = "1.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0315cb247b6726d92c74b955b7d79b4be475be58335fee120f19292740132eb1"
|
||||
dependencies = [
|
||||
"displaydoc",
|
||||
"libc",
|
||||
"thiserror 1.0.69",
|
||||
"versionize",
|
||||
"versionize_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "delegate"
|
||||
version = "0.13.5"
|
||||
@@ -1095,7 +1132,7 @@ checksum = "780eb241654bf097afb00fc5f054a09b687dad862e485fdcf8399bb056565370"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1137,7 +1174,7 @@ checksum = "d08b3a0bcc0d079199cd476b2cae8435016ec11d1c0986c6901c5ac223041534"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1212,7 +1249,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1375,6 +1412,12 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "endian-type"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d"
|
||||
|
||||
[[package]]
|
||||
name = "enum_dispatch"
|
||||
version = "0.3.13"
|
||||
@@ -1384,7 +1427,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1402,7 +1445,7 @@ version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32e90c2accc4b07a8456ea0debdc2e7587bdd890680d71173a15d4ae604f6eef"
|
||||
dependencies = [
|
||||
"log 0.4.29",
|
||||
"log",
|
||||
"regex",
|
||||
]
|
||||
|
||||
@@ -1422,7 +1465,7 @@ dependencies = [
|
||||
"anstyle",
|
||||
"env_filter",
|
||||
"jiff",
|
||||
"log 0.4.29",
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1543,7 +1586,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"chrono",
|
||||
"log 0.4.29",
|
||||
"log",
|
||||
"rusqlite",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -1645,16 +1688,32 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||
|
||||
[[package]]
|
||||
name = "fuse"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "80e57070510966bfef93662a81cb8aa2b1c7db0964354fa9921434f04b9e8660"
|
||||
name = "fuse-backend-rs"
|
||||
version = "0.14.0"
|
||||
dependencies = [
|
||||
"arc-swap",
|
||||
"async-trait",
|
||||
"bitflags 1.3.2",
|
||||
"caps",
|
||||
"core-foundation-sys",
|
||||
"dbs-snapshot",
|
||||
"io-uring",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"log 0.3.9",
|
||||
"pkg-config",
|
||||
"thread-scoped",
|
||||
"time 0.1.45",
|
||||
"log",
|
||||
"mio 0.8.11",
|
||||
"nix 0.24.3",
|
||||
"radix_trie",
|
||||
"tokio",
|
||||
"tokio-test",
|
||||
"tokio-uring",
|
||||
"versionize",
|
||||
"versionize_derive",
|
||||
"vhost",
|
||||
"virtio-bindings",
|
||||
"virtio-queue",
|
||||
"vm-memory",
|
||||
"vmm-sys-util 0.15.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1713,7 +1772,7 @@ checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2115,7 +2174,7 @@ dependencies = [
|
||||
"core-foundation-sys",
|
||||
"iana-time-zone-haiku",
|
||||
"js-sys",
|
||||
"log 0.4.29",
|
||||
"log",
|
||||
"wasm-bindgen",
|
||||
"windows-core 0.62.2",
|
||||
]
|
||||
@@ -2320,6 +2379,16 @@ dependencies = [
|
||||
"rand_core 0.10.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "io-uring"
|
||||
version = "0.5.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd1e1a01cfb924fd8c5c43b6827965db394f5a3a16c599ce03452266e1cf984c"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.2"
|
||||
@@ -2348,7 +2417,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4603d3033e49e2b0e31229fcab20a5d40089c607d975cd9c80551dc69eed9102"
|
||||
dependencies = [
|
||||
"jiff-static",
|
||||
"log 0.4.29",
|
||||
"log",
|
||||
"portable-atomic",
|
||||
"portable-atomic-util",
|
||||
"serde_core",
|
||||
@@ -2362,7 +2431,7 @@ checksum = "782d32378dddf207193ac91cefb848ad41abb58195c95168e1291227a0832b47"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2526,15 +2595,6 @@ dependencies = [
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
|
||||
dependencies = [
|
||||
"log 0.4.29",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.29"
|
||||
@@ -2603,7 +2663,7 @@ dependencies = [
|
||||
"flate2",
|
||||
"futures-util",
|
||||
"hmac 0.12.1",
|
||||
"log 0.4.29",
|
||||
"log",
|
||||
"markbase-webdav",
|
||||
"md5 0.8.0",
|
||||
"pulldown-cmark",
|
||||
@@ -2658,13 +2718,14 @@ dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
"filetree",
|
||||
"fuse",
|
||||
"fuse-backend-rs",
|
||||
"libc",
|
||||
"log 0.4.29",
|
||||
"log",
|
||||
"rusqlite",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"time 0.3.47",
|
||||
"time",
|
||||
"vm-memory",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2788,6 +2849,15 @@ version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mime"
|
||||
version = "0.3.17"
|
||||
@@ -2820,6 +2890,18 @@ dependencies = [
|
||||
"simd-adler32",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"wasi 0.11.1+wasi-snapshot-preview1",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "1.2.0"
|
||||
@@ -2889,6 +2971,27 @@ dependencies = [
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nibble_vec"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43"
|
||||
dependencies = [
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.24.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"memoffset",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.31.3"
|
||||
@@ -2918,7 +3021,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2de419e64947cd8830e66beb584acc3fb42ed411d103e3c794dda355d1b374b5"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"time 0.3.47",
|
||||
"time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2999,7 +3102,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3239,7 +3342,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"delegate",
|
||||
"futures",
|
||||
"log 0.4.29",
|
||||
"log",
|
||||
"rand 0.8.6",
|
||||
"thiserror 1.0.69",
|
||||
"tokio",
|
||||
@@ -3257,7 +3360,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"delegate",
|
||||
"futures",
|
||||
"log 0.4.29",
|
||||
"log",
|
||||
"rand 0.10.1",
|
||||
"sha2 0.11.0",
|
||||
"thiserror 2.0.18",
|
||||
@@ -3619,7 +3722,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3703,6 +3806,16 @@ version = "6.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf"
|
||||
|
||||
[[package]]
|
||||
name = "radix_trie"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd"
|
||||
dependencies = [
|
||||
"endian-type",
|
||||
"nibble_vec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.4.6"
|
||||
@@ -3996,7 +4109,7 @@ dependencies = [
|
||||
"inout 0.2.2",
|
||||
"internal-russh-num-bigint",
|
||||
"keccak",
|
||||
"log 0.4.29",
|
||||
"log",
|
||||
"md5 0.8.0",
|
||||
"ml-kem",
|
||||
"module-lattice",
|
||||
@@ -4050,8 +4163,8 @@ version = "0.61.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "443f6bbcfacb34a1aab2b12b99bf08e0c63abdc5a0db261901365df9d57fff51"
|
||||
dependencies = [
|
||||
"log 0.4.29",
|
||||
"nix",
|
||||
"log",
|
||||
"nix 0.31.3",
|
||||
"ssh-encoding 0.3.0-rc.9",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
@@ -4081,7 +4194,7 @@ dependencies = [
|
||||
"home",
|
||||
"inout 0.1.4",
|
||||
"internal-russh-forked-ssh-key",
|
||||
"log 0.4.29",
|
||||
"log",
|
||||
"md5 0.7.0",
|
||||
"num-integer",
|
||||
"p256 0.13.2",
|
||||
@@ -4122,7 +4235,7 @@ dependencies = [
|
||||
"chrono",
|
||||
"dashmap",
|
||||
"gloo-timers",
|
||||
"log 0.4.29",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_bytes",
|
||||
"thiserror 2.0.18",
|
||||
@@ -4163,7 +4276,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"crc32c",
|
||||
"env_logger",
|
||||
"log 0.4.29",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror 2.0.18",
|
||||
@@ -4236,6 +4349,12 @@ dependencies = [
|
||||
"cipher 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scoped-tls"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
@@ -4336,7 +4455,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4545,7 +4664,7 @@ dependencies = [
|
||||
"fnv",
|
||||
"fs2",
|
||||
"inline-array",
|
||||
"log 0.4.29",
|
||||
"log",
|
||||
"pagetable",
|
||||
"parking_lot",
|
||||
"rayon",
|
||||
@@ -4561,6 +4680,16 @@ version = "1.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.4.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.6.3"
|
||||
@@ -4737,6 +4866,17 @@ version = "2.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.117"
|
||||
@@ -4762,7 +4902,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4825,7 +4965,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4836,24 +4976,7 @@ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread-scoped"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bcbb6aa301e5d3b0b5ef639c9a9c7e2f1c944f177b460c04dc24c69b1fa2bd99"
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"wasi 0.10.0+wasi-snapshot-preview1",
|
||||
"winapi",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4919,11 +5042,11 @@ checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"libc",
|
||||
"mio",
|
||||
"mio 1.2.0",
|
||||
"parking_lot",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"socket2",
|
||||
"socket2 0.6.3",
|
||||
"tokio-macros",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
@@ -4936,7 +5059,7 @@ checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4951,7 +5074,7 @@ dependencies = [
|
||||
"fallible-iterator 0.2.0",
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
"log 0.4.29",
|
||||
"log",
|
||||
"parking_lot",
|
||||
"percent-encoding",
|
||||
"phf",
|
||||
@@ -4959,7 +5082,7 @@ dependencies = [
|
||||
"postgres-protocol",
|
||||
"postgres-types",
|
||||
"rand 0.10.1",
|
||||
"socket2",
|
||||
"socket2 0.6.3",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"whoami",
|
||||
@@ -4988,6 +5111,20 @@ dependencies = [
|
||||
"tokio-stream",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-uring"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d5e02bb137e030b3a547c65a3bd2f1836d66a97369fdcc69034002b10e155ef"
|
||||
dependencies = [
|
||||
"io-uring",
|
||||
"libc",
|
||||
"scoped-tls",
|
||||
"slab",
|
||||
"socket2 0.4.10",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.7.18"
|
||||
@@ -5077,7 +5214,7 @@ version = "0.1.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100"
|
||||
dependencies = [
|
||||
"log 0.4.29",
|
||||
"log",
|
||||
"pin-project-lite",
|
||||
"tracing-attributes",
|
||||
"tracing-core",
|
||||
@@ -5091,7 +5228,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5237,6 +5374,7 @@ checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76"
|
||||
dependencies = [
|
||||
"getrandom 0.4.2",
|
||||
"js-sys",
|
||||
"rand 0.10.1",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
@@ -5252,6 +5390,34 @@ version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "versionize"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62929d59c7f6730b7298fcb363760550f4db6e353fbac4076d447d0e82799d6d"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"crc64",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"syn 1.0.109",
|
||||
"versionize_derive",
|
||||
"vmm-sys-util 0.12.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "versionize_derive"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c4971c07ef708cd51003222e509aaed8eae14aeb2907706b01578843195e03a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vfs"
|
||||
version = "0.12.2"
|
||||
@@ -5262,10 +5428,67 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.0+wasi-snapshot-preview1"
|
||||
name = "vhost"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
|
||||
checksum = "c76d90ce3c6b37d610a5304c9a445cfff580cf8b4b9fd02fb256aaf68552c28a"
|
||||
dependencies = [
|
||||
"bitflags 2.11.1",
|
||||
"libc",
|
||||
"uuid",
|
||||
"vm-memory",
|
||||
"vmm-sys-util 0.15.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "virtio-bindings"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "091f1f09cfbf2a78563b562e7a949465cce1aef63b6065645188d995162f8868"
|
||||
|
||||
[[package]]
|
||||
name = "virtio-queue"
|
||||
version = "0.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e358084f32ed165fddb41d98ff1b7ff3c08b9611d8d6114a1b422e2e85688baf"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"virtio-bindings",
|
||||
"vm-memory",
|
||||
"vmm-sys-util 0.15.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vm-memory"
|
||||
version = "0.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f39348a049689cabd3377cdd9182bf526ec76a6f823b79903896452e9d7a7380"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"thiserror 2.0.18",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vmm-sys-util"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d1435039746e20da4f8d507a72ee1b916f7b4b05af7a91c093d2c6561934ede"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vmm-sys-util"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "506c62fdf617a5176827c2f9afbcf1be155b03a9b4bf9617a60dbc07e3a1642f"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
@@ -5351,7 +5574,7 @@ dependencies = [
|
||||
"bumpalo",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.117",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@@ -5531,7 +5754,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5542,7 +5765,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5553,7 +5776,7 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5564,7 +5787,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5828,7 +6051,7 @@ dependencies = [
|
||||
"heck",
|
||||
"indexmap",
|
||||
"prettyplease",
|
||||
"syn",
|
||||
"syn 2.0.117",
|
||||
"wasm-metadata",
|
||||
"wit-bindgen-core",
|
||||
"wit-component",
|
||||
@@ -5844,7 +6067,7 @@ dependencies = [
|
||||
"prettyplease",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.117",
|
||||
"wit-bindgen-core",
|
||||
"wit-bindgen-rust",
|
||||
]
|
||||
@@ -5858,7 +6081,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"bitflags 2.11.1",
|
||||
"indexmap",
|
||||
"log 0.4.29",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
@@ -5877,7 +6100,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"id-arena",
|
||||
"indexmap",
|
||||
"log 0.4.29",
|
||||
"log",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
@@ -5966,7 +6189,7 @@ checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.117",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
@@ -5987,7 +6210,7 @@ checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6007,7 +6230,7 @@ checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.117",
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
@@ -6028,7 +6251,7 @@ checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6061,7 +6284,7 @@ checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6080,7 +6303,7 @@ dependencies = [
|
||||
"hmac 0.12.1",
|
||||
"pbkdf2 0.11.0",
|
||||
"sha1 0.10.6",
|
||||
"time 0.3.47",
|
||||
"time",
|
||||
"zstd 0.11.2+zstd.1.5.2",
|
||||
]
|
||||
|
||||
|
||||
@@ -18,10 +18,11 @@ path = "src/lib.rs"
|
||||
anyhow = "1"
|
||||
clap = { version = "4", features = ["derive"] }
|
||||
filetree = { path = "../filetree" }
|
||||
fuse = "0.3.1"
|
||||
fuse-backend-rs = { path = "../fuse-backend-rs-fork", features = ["fusedev", "fuse-t"] }
|
||||
libc = "0.2"
|
||||
log = "0.4"
|
||||
rusqlite = { version = "0.32", features = ["bundled"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
time = "0.3"
|
||||
vm-memory = "0.17"
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
fn main() {
|
||||
// Manual linking for FUSE-T on macOS (no pkg-config dependency)
|
||||
println!("cargo:rustc-link-search=native=/usr/local/lib");
|
||||
|
||||
// Link to both fuse3 and fuse-t (FUSE-T provides both)
|
||||
println!("cargo:rustc-link-lib=dylib=fuse3");
|
||||
println!("cargo:rustc-link-lib=dylib=fuse-t");
|
||||
|
||||
// Set rpath for runtime loading
|
||||
println!("cargo:rustc-link-arg=-Wl,-rpath,/usr/local/lib");
|
||||
|
||||
println!("cargo:rerun-if-changed=build.rs");
|
||||
}
|
||||
if cfg!(target_os = "macos") {
|
||||
// Link fuse-t library
|
||||
println!("cargo:rustc-link-lib=fuse-t");
|
||||
|
||||
// Link macOS frameworks
|
||||
println!("cargo:rustc-link-lib=framework=DiskArbitration");
|
||||
println!("cargo:rustc-link-lib=framework=CoreFoundation");
|
||||
|
||||
// Add fuse-t include path
|
||||
println!("cargo:rustc-link-search=native=/usr/local/lib");
|
||||
|
||||
// Rerun if fuse-t changes
|
||||
println!("cargo:rerun-if-changed=/usr/local/lib/libfuse-t.dylib");
|
||||
}
|
||||
}
|
||||
@@ -106,6 +106,21 @@ impl DbManager {
|
||||
Ok(labels)
|
||||
}
|
||||
|
||||
pub fn find_node_id_by_parent(&self, parent_id: &str, name: &str) -> Result<Option<String>> {
|
||||
let conn = self.conn.lock().unwrap();
|
||||
|
||||
let sql = "SELECT node_id FROM file_nodes WHERE parent_id = ?1 AND label = ?2 AND tree_type = ?3 LIMIT 1";
|
||||
let mut stmt = conn.prepare(sql)?;
|
||||
|
||||
let result = stmt.query_row(params![parent_id, name, &self.tree_type], |row| row.get::<_, String>(0));
|
||||
|
||||
match result {
|
||||
Ok(node_id) => Ok(Some(node_id)),
|
||||
Err(rusqlite::Error::QueryReturnedNoRows) => Ok(None),
|
||||
Err(e) => Err(e.into()),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn preload_files(
|
||||
&self,
|
||||
cache: &super::cache::ThreadSafeCache,
|
||||
|
||||
@@ -1,28 +1,25 @@
|
||||
use anyhow::Result;
|
||||
use fuse::{
|
||||
FileAttr, FileType, Filesystem, ReplyAttr, ReplyData, ReplyDirectory, ReplyEntry, Request,
|
||||
};
|
||||
use libc::{EIO, ENOENT};
|
||||
use fuse_backend_rs::api::filesystem::{Context, DirEntry, Entry, FileSystem, ZeroCopyWriter};
|
||||
use fuse_backend_rs::abi::fuse_abi::{stat64, statvfs64, FsOptions, OpenOptions};
|
||||
use std::collections::HashMap;
|
||||
use std::ffi::CStr;
|
||||
use std::fs::File;
|
||||
use std::io::{Read, SeekFrom};
|
||||
use std::path::Path;
|
||||
use std::sync::Arc;
|
||||
use std::time::SystemTime;
|
||||
use std::io::{Read, Seek, SeekFrom};
|
||||
use std::os::unix::io::{AsRawFd, FromRawFd};
|
||||
use std::sync::{Arc, RwLock};
|
||||
use std::time::{Duration, SystemTime};
|
||||
|
||||
use std::ffi::CString;
|
||||
use super::cache::ThreadSafeCache;
|
||||
use super::db::DbManager;
|
||||
|
||||
const TTL: std::time::Duration = std::time::Duration::from_secs(1);
|
||||
const READ_CHUNK_SIZE: usize = 524288; // 512KB for maximum throughput
|
||||
|
||||
const CACHE_SIZE: usize = 1000;
|
||||
const TTL: Duration = Duration::from_secs(1);
|
||||
const READ_CHUNK_SIZE: usize = 524288; // 512KB
|
||||
|
||||
pub struct MarkBaseFs {
|
||||
db: Arc<DbManager>,
|
||||
cache: Arc<ThreadSafeCache>,
|
||||
inode_map: HashMap<u64, String>,
|
||||
path_cache: HashMap<String, u64>,
|
||||
next_inode: u64,
|
||||
inode_map: RwLock<HashMap<u64, String>>,
|
||||
next_inode: RwLock<u64>,
|
||||
}
|
||||
|
||||
impl MarkBaseFs {
|
||||
@@ -30,213 +27,253 @@ impl MarkBaseFs {
|
||||
let db = DbManager::open(db_path, tree_type)?;
|
||||
let cache = ThreadSafeCache::new();
|
||||
|
||||
let count = db.preload_files(&cache, CACHE_SIZE)?;
|
||||
println!("Pre-cached {} files for tree_type: {}", count, tree_type);
|
||||
|
||||
Ok(Self {
|
||||
db: Arc::new(db),
|
||||
cache: Arc::new(cache),
|
||||
inode_map: HashMap::new(),
|
||||
path_cache: HashMap::new(),
|
||||
next_inode: 2,
|
||||
inode_map: RwLock::new(HashMap::new()),
|
||||
next_inode: RwLock::new(2),
|
||||
})
|
||||
}
|
||||
|
||||
fn find_node_id_by_inode(&self, ino: u64) -> Option<String> {
|
||||
self.inode_map.get(&ino).cloned()
|
||||
self.inode_map.read().unwrap().get(&ino).cloned()
|
||||
}
|
||||
|
||||
fn get_or_create_inode(&mut self, node_id: &str) -> u64 {
|
||||
// Find existing inode
|
||||
for (ino, id) in &self.inode_map {
|
||||
fn get_or_create_inode(&self, node_id: &str) -> u64 {
|
||||
let map = self.inode_map.read().unwrap();
|
||||
for (ino, id) in &*map {
|
||||
if id == node_id {
|
||||
return *ino;
|
||||
}
|
||||
}
|
||||
drop(map);
|
||||
|
||||
// Create new inode
|
||||
let ino = self.next_inode;
|
||||
self.next_inode += 1;
|
||||
self.inode_map.insert(ino, node_id.to_string());
|
||||
let mut next = self.next_inode.write().unwrap();
|
||||
let ino = *next;
|
||||
*next += 1;
|
||||
|
||||
let mut map = self.inode_map.write().unwrap();
|
||||
map.insert(ino, node_id.to_string());
|
||||
ino
|
||||
}
|
||||
|
||||
fn find_node_id_by_path(&self, path: &str) -> Option<String> {
|
||||
// Check path cache first
|
||||
if let Some(node_id) = self.cache.lookup_path(path) {
|
||||
return Some(node_id);
|
||||
}
|
||||
|
||||
// Query from database
|
||||
match self.db.find_node_id(path) {
|
||||
Ok(Some(node_id)) => {
|
||||
self.cache.insert_path(path, &node_id);
|
||||
Some(node_id)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_file_path(&self, node_id: &str) -> Option<String> {
|
||||
// Check cache first
|
||||
if let Some((path, _)) = self.cache.lookup_file(node_id) {
|
||||
return Some(path);
|
||||
}
|
||||
|
||||
// Query from database
|
||||
match self.db.get_file_path(node_id) {
|
||||
Ok(Some(path)) => {
|
||||
self.cache.insert_file(node_id, &path, 0);
|
||||
Some(path)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn make_file_attr(ino: u64, node_type: &str, file_size: u64) -> FileAttr {
|
||||
FileAttr {
|
||||
ino,
|
||||
size: file_size,
|
||||
blocks: (file_size + 511) / 512,
|
||||
atime: SystemTime::now(),
|
||||
mtime: SystemTime::now(),
|
||||
ctime: SystemTime::now(),
|
||||
crtime: SystemTime::now(),
|
||||
kind: if node_type == "folder" {
|
||||
FileType::Directory
|
||||
} else {
|
||||
FileType::RegularFile
|
||||
},
|
||||
perm: if node_type == "folder" { 0o755 } else { 0o644 },
|
||||
nlink: if node_type == "folder" { 2 } else { 1 },
|
||||
uid: 501, // default user
|
||||
gid: 20, // default group
|
||||
rdev: 0,
|
||||
flags: 0,
|
||||
}
|
||||
fn make_stat64(node_type: &str, file_size: u64) -> stat64 {
|
||||
let mut st = unsafe { std::mem::zeroed::<stat64>() };
|
||||
st.st_ino = 0;
|
||||
st.st_mode = if node_type == "folder" { 0o755 } else { 0o644 };
|
||||
st.st_nlink = if node_type == "folder" { 2 } else { 1 };
|
||||
st.st_uid = 501;
|
||||
st.st_gid = 20;
|
||||
st.st_size = file_size as i64;
|
||||
st.st_blocks = ((file_size + 511) / 512) as i64;
|
||||
st.st_blksize = 4096;
|
||||
|
||||
let now = SystemTime::now();
|
||||
st.st_atime = now.duration_since(SystemTime::UNIX_EPOCH).unwrap().as_secs() as i64;
|
||||
st.st_mtime = st.st_atime;
|
||||
st.st_ctime = st.st_atime;
|
||||
|
||||
st
|
||||
}
|
||||
}
|
||||
|
||||
impl Filesystem for MarkBaseFs {
|
||||
fn lookup(&mut self, _req: &Request, parent: u64, name: &Path, reply: ReplyEntry) {
|
||||
let parent_path = if parent == 1 { "/" } else { "" };
|
||||
let full_path = format!("{}/{}", parent_path, name.to_string_lossy());
|
||||
impl FileSystem for MarkBaseFs {
|
||||
type Inode = u64;
|
||||
type Handle = u64;
|
||||
|
||||
let node_id = self.find_node_id_by_path(&full_path);
|
||||
fn init(&self, capable: FsOptions) -> std::io::Result<FsOptions> {
|
||||
Ok(capable)
|
||||
}
|
||||
|
||||
fn lookup(
|
||||
&self,
|
||||
ctx: &Context,
|
||||
parent: Self::Inode,
|
||||
name: &CStr,
|
||||
) -> std::io::Result<Entry> {
|
||||
let name_str = name.to_string_lossy();
|
||||
|
||||
let node_id = if parent == 1 {
|
||||
self.db.find_node_id(&format!("/{}", name_str)).ok().flatten()
|
||||
} else {
|
||||
let parent_id = self.find_node_id_by_inode(parent);
|
||||
match parent_id {
|
||||
Some(pid) => self.db.find_node_id_by_parent(&pid, &name_str).ok().flatten(),
|
||||
None => None,
|
||||
}
|
||||
};
|
||||
|
||||
match node_id {
|
||||
Some(id) => {
|
||||
let info = self.db.get_node_info(&id).ok();
|
||||
|
||||
let info = self.db.get_node_info(&id);
|
||||
match info {
|
||||
Some((node_type, file_size)) => {
|
||||
Ok(Some((node_type, file_size))) => {
|
||||
let ino = self.get_or_create_inode(&id);
|
||||
let attr = self.make_file_attr(ino, &node_type, file_size);
|
||||
let attr = MarkBaseFs::make_stat64(&node_type, file_size);
|
||||
|
||||
reply.entry(&TTL, &attr, 0);
|
||||
Ok(Entry {
|
||||
inode: ino,
|
||||
generation: 0,
|
||||
attr,
|
||||
attr_flags: 0,
|
||||
attr_timeout: TTL,
|
||||
entry_timeout: TTL,
|
||||
})
|
||||
}
|
||||
_ => reply.error(ENOENT),
|
||||
_ => Err(std::io::Error::from_raw_os_error(libc::ENOENT)),
|
||||
}
|
||||
}
|
||||
None => reply.error(ENOENT),
|
||||
None => Err(std::io::Error::from_raw_os_error(libc::ENOENT)),
|
||||
}
|
||||
}
|
||||
|
||||
fn getattr(&mut self, _req: &Request, ino: u64, reply: ReplyAttr) {
|
||||
if ino == 1 {
|
||||
let attr = self.make_file_attr(1, "folder", 0);
|
||||
reply.attr(&TTL, &attr);
|
||||
return;
|
||||
fn forget(&self, ctx: &Context, inode: Self::Inode, count: u64) {
|
||||
let mut map = self.inode_map.write().unwrap();
|
||||
map.remove(&inode);
|
||||
}
|
||||
|
||||
fn getattr(
|
||||
&self,
|
||||
ctx: &Context,
|
||||
inode: Self::Inode,
|
||||
handle: Option<Self::Handle>,
|
||||
) -> std::io::Result<(stat64, Duration)> {
|
||||
if inode == 1 {
|
||||
let attr = MarkBaseFs::make_stat64("folder", 0);
|
||||
return Ok((attr, TTL));
|
||||
}
|
||||
|
||||
let node_id = self.find_node_id_by_inode(ino);
|
||||
|
||||
let node_id = self.find_node_id_by_inode(inode);
|
||||
match node_id {
|
||||
Some(id) => {
|
||||
let info = self.db.get_node_info(&id).ok();
|
||||
|
||||
let info = self.db.get_node_info(&id);
|
||||
match info {
|
||||
Some((node_type, file_size)) => {
|
||||
let attr = self.make_file_attr(ino, &node_type, file_size);
|
||||
reply.attr(&TTL, &attr);
|
||||
Ok(Some((node_type, file_size))) => {
|
||||
let attr = MarkBaseFs::make_stat64(&node_type, file_size);
|
||||
Ok((attr, TTL))
|
||||
}
|
||||
_ => reply.error(ENOENT),
|
||||
_ => Err(std::io::Error::from_raw_os_error(libc::ENOENT)),
|
||||
}
|
||||
}
|
||||
None => reply.error(ENOENT),
|
||||
None => Err(std::io::Error::from_raw_os_error(libc::ENOENT)),
|
||||
}
|
||||
}
|
||||
|
||||
fn open(
|
||||
&self,
|
||||
ctx: &Context,
|
||||
inode: Self::Inode,
|
||||
flags: u32,
|
||||
fuse_flags: u32,
|
||||
) -> std::io::Result<(Option<Self::Handle>, OpenOptions, Option<u32>)> {
|
||||
Ok((Some(inode), OpenOptions::empty(), None))
|
||||
}
|
||||
|
||||
fn read(
|
||||
&mut self,
|
||||
_req: &Request,
|
||||
ino: u64,
|
||||
fh: u64,
|
||||
offset: i64,
|
||||
&self,
|
||||
ctx: &Context,
|
||||
inode: Self::Inode,
|
||||
handle: Self::Handle,
|
||||
w: &mut dyn ZeroCopyWriter,
|
||||
size: u32,
|
||||
reply: ReplyData,
|
||||
) {
|
||||
let node_id = self.find_node_id_by_inode(ino);
|
||||
|
||||
offset: u64,
|
||||
lock_owner: Option<u64>,
|
||||
flags: u32,
|
||||
) -> std::io::Result<usize> {
|
||||
let node_id = self.find_node_id_by_inode(inode);
|
||||
match node_id {
|
||||
Some(id) => {
|
||||
let file_path = self.get_file_path(&id);
|
||||
|
||||
let file_path = self.db.get_file_path(&id);
|
||||
match file_path {
|
||||
Some(fp) => {
|
||||
let mut file = File::open(&fp)?;
|
||||
file.seek(SeekFrom::Start(offset as u64)).ok();
|
||||
|
||||
let mut buffer = vec![0u8; size as usize];
|
||||
let bytes_read = file.read(&mut buffer).ok();
|
||||
buffer.truncate(bytes_read);
|
||||
reply.data(&buffer);
|
||||
Ok(Some(fp)) => {
|
||||
let file = File::open(&fp)?;
|
||||
let fd = file.as_raw_fd();
|
||||
let f = unsafe { File::from_raw_fd(fd) };
|
||||
let mut f = std::mem::ManuallyDrop::new(f);
|
||||
|
||||
w.write_from(&mut *f, size as usize, offset)
|
||||
}
|
||||
None => reply.error(ENOENT),
|
||||
_ => Err(std::io::Error::from_raw_os_error(libc::ENOENT)),
|
||||
}
|
||||
}
|
||||
None => reply.error(ENOENT),
|
||||
None => Err(std::io::Error::from_raw_os_error(libc::ENOENT)),
|
||||
}
|
||||
}
|
||||
|
||||
fn release(
|
||||
&self,
|
||||
ctx: &Context,
|
||||
inode: Self::Inode,
|
||||
flags: u32,
|
||||
handle: Self::Handle,
|
||||
flush: bool,
|
||||
flock_release: bool,
|
||||
lock_owner: Option<u64>,
|
||||
) -> std::io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn opendir(
|
||||
&self,
|
||||
ctx: &Context,
|
||||
inode: Self::Inode,
|
||||
flags: u32,
|
||||
) -> std::io::Result<(Option<Self::Handle>, OpenOptions)> {
|
||||
Ok((Some(inode), OpenOptions::empty()))
|
||||
}
|
||||
|
||||
fn readdir(
|
||||
&mut self,
|
||||
_req: &Request,
|
||||
ino: u64,
|
||||
fh: u64,
|
||||
offset: i64,
|
||||
mut reply: ReplyDirectory,
|
||||
) {
|
||||
&self,
|
||||
ctx: &Context,
|
||||
inode: Self::Inode,
|
||||
handle: Self::Handle,
|
||||
size: u32,
|
||||
offset: u64,
|
||||
add_entry: &mut dyn FnMut(DirEntry) -> std::io::Result<usize>,
|
||||
) -> std::io::Result<()> {
|
||||
if offset == 0 {
|
||||
reply.add(ino, 1, FileType::Directory, ".");
|
||||
reply.add(ino, 2, FileType::Directory, "..");
|
||||
add_entry(DirEntry {
|
||||
name: b".\0",
|
||||
ino: inode,
|
||||
offset: 1,
|
||||
type_: libc::S_IFDIR as u32,
|
||||
})?;
|
||||
|
||||
if ino == 1 {
|
||||
// Root - show Home folder
|
||||
reply.add(2, 3, FileType::Directory, "Home");
|
||||
} else {
|
||||
let node_id = self.find_node_id_by_inode(ino);
|
||||
|
||||
match node_id {
|
||||
Some(id) => {
|
||||
let children = self.db.list_children(&id).ok();
|
||||
let mut child_offset = 3;
|
||||
|
||||
for child_name in children {
|
||||
reply.add(
|
||||
child_offset,
|
||||
child_offset + 1,
|
||||
FileType::RegularFile,
|
||||
&child_name,
|
||||
);
|
||||
child_offset += 1;
|
||||
}
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
add_entry(DirEntry {
|
||||
name: b"..\0",
|
||||
ino: 1,
|
||||
offset: 2,
|
||||
type_: libc::S_IFDIR as u32,
|
||||
})?;
|
||||
}
|
||||
|
||||
reply.ok();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
fn releasedir(
|
||||
&self,
|
||||
ctx: &Context,
|
||||
inode: Self::Inode,
|
||||
flags: u32,
|
||||
handle: Self::Handle,
|
||||
) -> std::io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn statfs(
|
||||
&self,
|
||||
ctx: &Context,
|
||||
inode: Self::Inode,
|
||||
) -> std::io::Result<statvfs64> {
|
||||
let mut st = unsafe { std::mem::zeroed::<statvfs64>() };
|
||||
st.f_bsize = 4096;
|
||||
st.f_blocks = 1000000;
|
||||
st.f_bfree = 500000;
|
||||
st.f_bavail = 500000;
|
||||
st.f_files = 1000;
|
||||
st.f_ffree = 500;
|
||||
st.f_favail = 500;
|
||||
st.f_namemax = 255;
|
||||
Ok(st)
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,6 @@ use anyhow::Result;
|
||||
use clap::{Parser, Subcommand};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(name = "markbase-fuse", about = "MarkBase FUSE Mount Tool")]
|
||||
@@ -43,7 +42,8 @@ fn main() -> Result<()> {
|
||||
}
|
||||
|
||||
fn mount_user(user: String, tree_type: String, dir: PathBuf) -> Result<()> {
|
||||
use fuse::mount;
|
||||
use fuse_backend_rs::api::server::Server;
|
||||
use fuse_backend_rs::transport::FuseSession;
|
||||
use markbase_fuse::MarkBaseFs;
|
||||
use std::env::current_dir;
|
||||
|
||||
@@ -61,7 +61,7 @@ fn mount_user(user: String, tree_type: String, dir: PathBuf) -> Result<()> {
|
||||
std::fs::create_dir_all(&dir)?;
|
||||
}
|
||||
|
||||
println!("=== MarkBase FUSE (fuse crate + FUSE-T) ===");
|
||||
println!("=== MarkBase FUSE (fuse-backend-rs + fuse-t) ===");
|
||||
println!("User: {}", user);
|
||||
println!("Tree Type: {}", tree_type);
|
||||
println!("Database: {}", db_path.display());
|
||||
@@ -69,34 +69,42 @@ fn mount_user(user: String, tree_type: String, dir: PathBuf) -> Result<()> {
|
||||
println!("");
|
||||
|
||||
let fs = MarkBaseFs::new(&db_path.to_string_lossy(), &tree_type)?;
|
||||
let fs = Arc::new(Mutex::new(fs));
|
||||
let server = Arc::new(Server::new(fs));
|
||||
|
||||
let options = vec![
|
||||
"-o",
|
||||
"rw",
|
||||
"-o",
|
||||
"allow_other",
|
||||
"-o",
|
||||
"noatime",
|
||||
"-o",
|
||||
"local",
|
||||
"-o",
|
||||
"big_writes",
|
||||
"-o",
|
||||
"max_read=524288",
|
||||
"-o",
|
||||
"max_write=524288",
|
||||
"-o",
|
||||
"kernel_cache",
|
||||
];
|
||||
|
||||
mount(fs, &dir, &options)?;
|
||||
let mut session = FuseSession::new(&dir, "markbase", "markbase-fuse", false)?;
|
||||
session.mount()?;
|
||||
|
||||
println!("Mounted successfully!");
|
||||
println!("Press Ctrl+C to unmount...");
|
||||
|
||||
let mut channel = session.new_channel()?;
|
||||
|
||||
let ebadf = std::io::Error::from_raw_os_error(libc::EBADF);
|
||||
loop {
|
||||
if let Some((reader, writer)) = channel.get_request()? {
|
||||
if let Err(e) = server.handle_message(reader, writer.into(), None, None) {
|
||||
match e {
|
||||
fuse_backend_rs::Error::EncodeMessage(e) if e.kind() == std::io::ErrorKind::Other => {
|
||||
break;
|
||||
}
|
||||
_ => {
|
||||
eprintln!("Handling fuse message failed: {:?}", e);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
println!("fuse server exits");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
session.umount()?;
|
||||
println!("Unmounted successfully");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn unmount_user(dir: PathBuf) -> Result<()> {
|
||||
println!("Unmounting: {}", dir.display());
|
||||
|
||||
@@ -104,4 +112,4 @@ fn unmount_user(dir: PathBuf) -> Result<()> {
|
||||
|
||||
println!("Unmounted successfully");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user