summary refs log tree commit diff
path: root/ripple
diff options
context:
space:
mode:
Diffstat (limited to 'ripple')
-rw-r--r--ripple/Cargo.lock159
-rw-r--r--ripple/fossil/Cargo.toml11
-rw-r--r--ripple/fossil/src/bin/mount.rs579
-rw-r--r--ripple/shell.nix4
4 files changed, 753 insertions, 0 deletions
diff --git a/ripple/Cargo.lock b/ripple/Cargo.lock
index b20b671..b04b546 100644
--- a/ripple/Cargo.lock
+++ b/ripple/Cargo.lock
@@ -3,6 +3,15 @@
 version = 3
 
 [[package]]
+name = "aho-corasick"
+version = "0.7.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
 name = "anyhow"
 version = "1.0.53"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -21,6 +30,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
 
 [[package]]
+name = "atty"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
+dependencies = [
+ "hermit-abi",
+ "libc",
+ "winapi",
+]
+
+[[package]]
 name = "autocfg"
 version = "1.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -163,6 +183,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
 
 [[package]]
+name = "env_logger"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3"
+dependencies = [
+ "atty",
+ "humantime",
+ "log",
+ "regex",
+ "termcolor",
+]
+
+[[package]]
 name = "fixedbitset"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -175,6 +208,10 @@ dependencies = [
  "blake3",
  "byteorder",
  "bytes",
+ "env_logger",
+ "fuser",
+ "libc",
+ "log",
  "prost",
  "prost-build",
  "sled",
@@ -191,6 +228,22 @@ dependencies = [
 ]
 
 [[package]]
+name = "fuser"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aef8400a4ea1d18a8302e2952f5137a9a21ab257825ccc7d67db4a8018b89022"
+dependencies = [
+ "libc",
+ "log",
+ "memchr",
+ "page_size",
+ "pkg-config",
+ "smallvec",
+ "users",
+ "zerocopy",
+]
+
+[[package]]
 name = "fxhash"
 version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -245,6 +298,12 @@ dependencies = [
 ]
 
 [[package]]
+name = "humantime"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
+
+[[package]]
 name = "indexmap"
 version = "1.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -303,6 +362,12 @@ dependencies = [
 ]
 
 [[package]]
+name = "memchr"
+version = "2.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
+
+[[package]]
 name = "memoffset"
 version = "0.6.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -350,6 +415,16 @@ dependencies = [
 ]
 
 [[package]]
+name = "page_size"
+version = "0.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eebde548fbbf1ea81a99b128872779c437752fb99f217c45245e1a61dcd9edcd"
+dependencies = [
+ "libc",
+ "winapi",
+]
+
+[[package]]
 name = "parking_lot"
 version = "0.11.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -385,6 +460,12 @@ dependencies = [
 ]
 
 [[package]]
+name = "pkg-config"
+version = "0.3.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
+
+[[package]]
 name = "ppv-lite86"
 version = "0.2.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -534,6 +615,23 @@ dependencies = [
 ]
 
 [[package]]
+name = "regex"
+version = "1.5.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
+
+[[package]]
 name = "remove_dir_all"
 version = "0.5.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -592,6 +690,18 @@ dependencies = [
 ]
 
 [[package]]
+name = "synstructure"
+version = "0.12.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "unicode-xid",
+]
+
+[[package]]
 name = "tempfile"
 version = "3.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -606,6 +716,15 @@ dependencies = [
 ]
 
 [[package]]
+name = "termcolor"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
 name = "typenum"
 version = "1.13.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -624,6 +743,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
 
 [[package]]
+name = "users"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "24cc0f6d6f267b73e5a2cadf007ba8f9bc39c6a6f9666f8cf25ea809a153b032"
+dependencies = [
+ "libc",
+ "log",
+]
+
+[[package]]
 name = "version_check"
 version = "0.9.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -663,7 +792,37 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
 
 [[package]]
+name = "winapi-util"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
 name = "winapi-x86_64-pc-windows-gnu"
 version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
+name = "zerocopy"
+version = "0.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "332f188cc1bcf1fe1064b8c58d150f497e697f49774aa846f2dc949d9a25f236"
+dependencies = [
+ "byteorder",
+ "zerocopy-derive",
+]
+
+[[package]]
+name = "zerocopy-derive"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a0fbc82b82efe24da867ee52e015e58178684bd9dd64c34e66bdf21da2582a9f"
+dependencies = [
+ "proc-macro2",
+ "syn",
+ "synstructure",
+]
diff --git a/ripple/fossil/Cargo.toml b/ripple/fossil/Cargo.toml
index af86d4e..86972c8 100644
--- a/ripple/fossil/Cargo.toml
+++ b/ripple/fossil/Cargo.toml
@@ -12,6 +12,17 @@ bytes = "1.0.1"
 blake3 = { version = "0.3.8", features = ["rayon"] }
 sled = "0.34.6"
 byteorder = "1.4.3"
+fuser = { version = "0.11.0", optional = true }
+log = { version = "0.4.14", optional = true }
+libc = { version = "0.2.112", optional = true }
+env_logger = { version = "0.9.0", optional = true }
 
 [build-dependencies]
 prost-build = "0.8.0"
+
+[features]
+wip-mount = ["fuser", "log", "libc", "env_logger"]
+
+[[bin]]
+name = "mount"
+required-features = ["wip-mount"]
diff --git a/ripple/fossil/src/bin/mount.rs b/ripple/fossil/src/bin/mount.rs
new file mode 100644
index 0000000..55dd6bf
--- /dev/null
+++ b/ripple/fossil/src/bin/mount.rs
@@ -0,0 +1,579 @@
+// SPDX-FileCopyrightText: edef <edef@unfathomable.blue>
+// SPDX-License-Identifier: OSL-3.0
+
+use {
+	libc::{c_int, ENOSYS, EPERM},
+	log::{debug, warn},
+};
+
+fn main() {
+	env_logger::init();
+
+	let store = fossil::Store::open("fossil.db").unwrap();
+	fuser::mount2(Filesystem::open(store), "mnt", &[]).unwrap();
+}
+
+struct Filesystem {
+	store: fossil::Store,
+}
+
+impl Filesystem {
+	fn open(store: fossil::Store) -> Filesystem {
+		Filesystem { store }
+	}
+}
+
+impl fuser::Filesystem for Filesystem {
+	fn init(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		_config: &mut fuser::KernelConfig,
+	) -> Result<(), c_int> {
+		Ok(())
+	}
+
+	fn destroy(&mut self) {}
+
+	fn lookup(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		parent: u64,
+		name: &std::ffi::OsStr,
+		reply: fuser::ReplyEntry,
+	) {
+		warn!(
+			"[Not Implemented] lookup(parent: {:#x?}, name {:?})",
+			parent, name
+		);
+		reply.error(ENOSYS);
+	}
+
+	fn forget(&mut self, _req: &fuser::Request<'_>, _ino: u64, _nlookup: u64) {}
+
+	fn getattr(&mut self, _req: &fuser::Request<'_>, ino: u64, reply: fuser::ReplyAttr) {
+		warn!("[Not Implemented] getattr(ino: {:#x?})", ino);
+		reply.error(ENOSYS);
+	}
+
+	fn setattr(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		ino: u64,
+		mode: Option<u32>,
+		uid: Option<u32>,
+		gid: Option<u32>,
+		size: Option<u64>,
+		_atime: Option<fuser::TimeOrNow>,
+		_mtime: Option<fuser::TimeOrNow>,
+		_ctime: Option<std::time::SystemTime>,
+		fh: Option<u64>,
+		_crtime: Option<std::time::SystemTime>,
+		_chgtime: Option<std::time::SystemTime>,
+		_bkuptime: Option<std::time::SystemTime>,
+		flags: Option<u32>,
+		reply: fuser::ReplyAttr,
+	) {
+		debug!(
+			"[Not Implemented] setattr(ino: {:#x?}, mode: {:?}, uid: {:?}, \
+            gid: {:?}, size: {:?}, fh: {:?}, flags: {:?})",
+			ino, mode, uid, gid, size, fh, flags
+		);
+		reply.error(ENOSYS);
+	}
+
+	fn readlink(&mut self, _req: &fuser::Request<'_>, ino: u64, reply: fuser::ReplyData) {
+		debug!("[Not Implemented] readlink(ino: {:#x?})", ino);
+		reply.error(ENOSYS);
+	}
+
+	fn mknod(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		parent: u64,
+		name: &std::ffi::OsStr,
+		mode: u32,
+		umask: u32,
+		rdev: u32,
+		reply: fuser::ReplyEntry,
+	) {
+		debug!(
+			"[Not Implemented] mknod(parent: {:#x?}, name: {:?}, mode: {}, \
+            umask: {:#x?}, rdev: {})",
+			parent, name, mode, umask, rdev
+		);
+		reply.error(ENOSYS);
+	}
+
+	fn mkdir(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		parent: u64,
+		name: &std::ffi::OsStr,
+		mode: u32,
+		umask: u32,
+		reply: fuser::ReplyEntry,
+	) {
+		debug!(
+			"[Not Implemented] mkdir(parent: {:#x?}, name: {:?}, mode: {}, umask: {:#x?})",
+			parent, name, mode, umask
+		);
+		reply.error(ENOSYS);
+	}
+
+	fn unlink(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		parent: u64,
+		name: &std::ffi::OsStr,
+		reply: fuser::ReplyEmpty,
+	) {
+		debug!(
+			"[Not Implemented] unlink(parent: {:#x?}, name: {:?})",
+			parent, name,
+		);
+		reply.error(ENOSYS);
+	}
+
+	fn rmdir(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		parent: u64,
+		name: &std::ffi::OsStr,
+		reply: fuser::ReplyEmpty,
+	) {
+		debug!(
+			"[Not Implemented] rmdir(parent: {:#x?}, name: {:?})",
+			parent, name,
+		);
+		reply.error(ENOSYS);
+	}
+
+	fn symlink(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		parent: u64,
+		name: &std::ffi::OsStr,
+		link: &std::path::Path,
+		reply: fuser::ReplyEntry,
+	) {
+		debug!(
+			"[Not Implemented] symlink(parent: {:#x?}, name: {:?}, link: {:?})",
+			parent, name, link,
+		);
+		reply.error(EPERM);
+	}
+
+	fn rename(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		parent: u64,
+		name: &std::ffi::OsStr,
+		newparent: u64,
+		newname: &std::ffi::OsStr,
+		flags: u32,
+		reply: fuser::ReplyEmpty,
+	) {
+		debug!(
+			"[Not Implemented] rename(parent: {:#x?}, name: {:?}, newparent: {:#x?}, \
+            newname: {:?}, flags: {})",
+			parent, name, newparent, newname, flags,
+		);
+		reply.error(ENOSYS);
+	}
+
+	fn link(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		ino: u64,
+		newparent: u64,
+		newname: &std::ffi::OsStr,
+		reply: fuser::ReplyEntry,
+	) {
+		debug!(
+			"[Not Implemented] link(ino: {:#x?}, newparent: {:#x?}, newname: {:?})",
+			ino, newparent, newname
+		);
+		reply.error(EPERM);
+	}
+
+	fn open(&mut self, _req: &fuser::Request<'_>, _ino: u64, _flags: i32, reply: fuser::ReplyOpen) {
+		reply.opened(0, 0);
+	}
+
+	fn read(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		ino: u64,
+		fh: u64,
+		offset: i64,
+		size: u32,
+		flags: i32,
+		lock_owner: Option<u64>,
+		reply: fuser::ReplyData,
+	) {
+		warn!(
+			"[Not Implemented] read(ino: {:#x?}, fh: {}, offset: {}, size: {}, \
+            flags: {:#x?}, lock_owner: {:?})",
+			ino, fh, offset, size, flags, lock_owner
+		);
+		reply.error(ENOSYS);
+	}
+
+	fn write(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		ino: u64,
+		fh: u64,
+		offset: i64,
+		data: &[u8],
+		write_flags: u32,
+		flags: i32,
+		lock_owner: Option<u64>,
+		reply: fuser::ReplyWrite,
+	) {
+		debug!(
+			"[Not Implemented] write(ino: {:#x?}, fh: {}, offset: {}, data.len(): {}, \
+            write_flags: {:#x?}, flags: {:#x?}, lock_owner: {:?})",
+			ino,
+			fh,
+			offset,
+			data.len(),
+			write_flags,
+			flags,
+			lock_owner
+		);
+		reply.error(ENOSYS);
+	}
+
+	fn flush(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		ino: u64,
+		fh: u64,
+		lock_owner: u64,
+		reply: fuser::ReplyEmpty,
+	) {
+		debug!(
+			"[Not Implemented] flush(ino: {:#x?}, fh: {}, lock_owner: {:?})",
+			ino, fh, lock_owner
+		);
+		reply.error(ENOSYS);
+	}
+
+	fn release(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		_ino: u64,
+		_fh: u64,
+		_flags: i32,
+		_lock_owner: Option<u64>,
+		_flush: bool,
+		reply: fuser::ReplyEmpty,
+	) {
+		reply.ok();
+	}
+
+	fn fsync(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		ino: u64,
+		fh: u64,
+		datasync: bool,
+		reply: fuser::ReplyEmpty,
+	) {
+		debug!(
+			"[Not Implemented] fsync(ino: {:#x?}, fh: {}, datasync: {})",
+			ino, fh, datasync
+		);
+		reply.error(ENOSYS);
+	}
+
+	fn opendir(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		_ino: u64,
+		_flags: i32,
+		reply: fuser::ReplyOpen,
+	) {
+		reply.opened(0, 0);
+	}
+
+	fn readdir(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		ino: u64,
+		fh: u64,
+		offset: i64,
+		reply: fuser::ReplyDirectory,
+	) {
+		warn!(
+			"[Not Implemented] readdir(ino: {:#x?}, fh: {}, offset: {})",
+			ino, fh, offset
+		);
+		reply.error(ENOSYS);
+	}
+
+	fn readdirplus(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		ino: u64,
+		fh: u64,
+		offset: i64,
+		reply: fuser::ReplyDirectoryPlus,
+	) {
+		debug!(
+			"[Not Implemented] readdirplus(ino: {:#x?}, fh: {}, offset: {})",
+			ino, fh, offset
+		);
+		reply.error(ENOSYS);
+	}
+
+	fn releasedir(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		_ino: u64,
+		_fh: u64,
+		_flags: i32,
+		reply: fuser::ReplyEmpty,
+	) {
+		reply.ok();
+	}
+
+	fn fsyncdir(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		ino: u64,
+		fh: u64,
+		datasync: bool,
+		reply: fuser::ReplyEmpty,
+	) {
+		debug!(
+			"[Not Implemented] fsyncdir(ino: {:#x?}, fh: {}, datasync: {})",
+			ino, fh, datasync
+		);
+		reply.error(ENOSYS);
+	}
+
+	fn statfs(&mut self, _req: &fuser::Request<'_>, _ino: u64, reply: fuser::ReplyStatfs) {
+		reply.statfs(0, 0, 0, 0, 0, 512, 255, 0);
+	}
+
+	fn setxattr(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		ino: u64,
+		name: &std::ffi::OsStr,
+		_value: &[u8],
+		flags: i32,
+		position: u32,
+		reply: fuser::ReplyEmpty,
+	) {
+		debug!(
+			"[Not Implemented] setxattr(ino: {:#x?}, name: {:?}, flags: {:#x?}, position: {})",
+			ino, name, flags, position
+		);
+		reply.error(ENOSYS);
+	}
+
+	fn getxattr(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		ino: u64,
+		name: &std::ffi::OsStr,
+		size: u32,
+		reply: fuser::ReplyXattr,
+	) {
+		debug!(
+			"[Not Implemented] getxattr(ino: {:#x?}, name: {:?}, size: {})",
+			ino, name, size
+		);
+		reply.error(ENOSYS);
+	}
+
+	fn listxattr(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		ino: u64,
+		size: u32,
+		reply: fuser::ReplyXattr,
+	) {
+		debug!(
+			"[Not Implemented] listxattr(ino: {:#x?}, size: {})",
+			ino, size
+		);
+		reply.error(ENOSYS);
+	}
+
+	fn removexattr(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		ino: u64,
+		name: &std::ffi::OsStr,
+		reply: fuser::ReplyEmpty,
+	) {
+		debug!(
+			"[Not Implemented] removexattr(ino: {:#x?}, name: {:?})",
+			ino, name
+		);
+		reply.error(ENOSYS);
+	}
+
+	fn access(&mut self, _req: &fuser::Request<'_>, ino: u64, mask: i32, reply: fuser::ReplyEmpty) {
+		debug!("[Not Implemented] access(ino: {:#x?}, mask: {})", ino, mask);
+		reply.error(ENOSYS);
+	}
+
+	fn create(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		parent: u64,
+		name: &std::ffi::OsStr,
+		mode: u32,
+		umask: u32,
+		flags: i32,
+		reply: fuser::ReplyCreate,
+	) {
+		debug!(
+			"[Not Implemented] create(parent: {:#x?}, name: {:?}, mode: {}, umask: {:#x?}, \
+            flags: {:#x?})",
+			parent, name, mode, umask, flags
+		);
+		reply.error(ENOSYS);
+	}
+
+	fn getlk(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		ino: u64,
+		fh: u64,
+		lock_owner: u64,
+		start: u64,
+		end: u64,
+		typ: i32,
+		pid: u32,
+		reply: fuser::ReplyLock,
+	) {
+		debug!(
+			"[Not Implemented] getlk(ino: {:#x?}, fh: {}, lock_owner: {}, start: {}, \
+            end: {}, typ: {}, pid: {})",
+			ino, fh, lock_owner, start, end, typ, pid
+		);
+		reply.error(ENOSYS);
+	}
+
+	fn setlk(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		ino: u64,
+		fh: u64,
+		lock_owner: u64,
+		start: u64,
+		end: u64,
+		typ: i32,
+		pid: u32,
+		sleep: bool,
+		reply: fuser::ReplyEmpty,
+	) {
+		debug!(
+			"[Not Implemented] setlk(ino: {:#x?}, fh: {}, lock_owner: {}, start: {}, \
+            end: {}, typ: {}, pid: {}, sleep: {})",
+			ino, fh, lock_owner, start, end, typ, pid, sleep
+		);
+		reply.error(ENOSYS);
+	}
+
+	fn bmap(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		ino: u64,
+		blocksize: u32,
+		idx: u64,
+		reply: fuser::ReplyBmap,
+	) {
+		debug!(
+			"[Not Implemented] bmap(ino: {:#x?}, blocksize: {}, idx: {})",
+			ino, blocksize, idx,
+		);
+		reply.error(ENOSYS);
+	}
+
+	fn ioctl(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		ino: u64,
+		fh: u64,
+		flags: u32,
+		cmd: u32,
+		in_data: &[u8],
+		out_size: u32,
+		reply: fuser::ReplyIoctl,
+	) {
+		debug!(
+			"[Not Implemented] ioctl(ino: {:#x?}, fh: {}, flags: {}, cmd: {}, \
+            in_data.len(): {}, out_size: {})",
+			ino,
+			fh,
+			flags,
+			cmd,
+			in_data.len(),
+			out_size,
+		);
+		reply.error(ENOSYS);
+	}
+
+	fn fallocate(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		ino: u64,
+		fh: u64,
+		offset: i64,
+		length: i64,
+		mode: i32,
+		reply: fuser::ReplyEmpty,
+	) {
+		debug!(
+			"[Not Implemented] fallocate(ino: {:#x?}, fh: {}, offset: {}, \
+            length: {}, mode: {})",
+			ino, fh, offset, length, mode
+		);
+		reply.error(ENOSYS);
+	}
+
+	fn lseek(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		ino: u64,
+		fh: u64,
+		offset: i64,
+		whence: i32,
+		reply: fuser::ReplyLseek,
+	) {
+		debug!(
+			"[Not Implemented] lseek(ino: {:#x?}, fh: {}, offset: {}, whence: {})",
+			ino, fh, offset, whence
+		);
+		reply.error(ENOSYS);
+	}
+
+	fn copy_file_range(
+		&mut self,
+		_req: &fuser::Request<'_>,
+		ino_in: u64,
+		fh_in: u64,
+		offset_in: i64,
+		ino_out: u64,
+		fh_out: u64,
+		offset_out: i64,
+		len: u64,
+		flags: u32,
+		reply: fuser::ReplyWrite,
+	) {
+		debug!(
+			"[Not Implemented] copy_file_range(ino_in: {:#x?}, fh_in: {}, \
+            offset_in: {}, ino_out: {:#x?}, fh_out: {}, offset_out: {}, \
+            len: {}, flags: {})",
+			ino_in, fh_in, offset_in, ino_out, fh_out, offset_out, len, flags
+		);
+		reply.error(ENOSYS);
+	}
+}
diff --git a/ripple/shell.nix b/ripple/shell.nix
index 6c67ab5..96ed84f 100644
--- a/ripple/shell.nix
+++ b/ripple/shell.nix
@@ -18,6 +18,10 @@ mkShell {
 
     # needed by prost-build
     protobuf
+
+    # needed by fuser
+    pkgconfig
+    fuse
   ];
 
   # needed by prost-build