From e7b80cca1c93efda1576e19846ebf089ff6cfa95 Mon Sep 17 00:00:00 2001 From: edef Date: Tue, 3 May 2022 21:09:59 +0000 Subject: ripple/fossil: handle missing blobs more gracefully Change-Id: I8a928b57ecc81bea31d757e73b9ece9474628db4 --- ripple/fossil/src/bin/extract.rs | 6 +++--- ripple/fossil/src/bin/mount.rs | 15 +++++++++------ ripple/fossil/src/lib.rs | 20 ++++++++------------ 3 files changed, 20 insertions(+), 21 deletions(-) (limited to 'ripple/fossil') diff --git a/ripple/fossil/src/bin/extract.rs b/ripple/fossil/src/bin/extract.rs index 64e27d4..0a7d0c7 100644 --- a/ripple/fossil/src/bin/extract.rs +++ b/ripple/fossil/src/bin/extract.rs @@ -26,7 +26,7 @@ fn main() { let store = fossil::Store::open(args.store).unwrap(); let root = { - let bytes = store.read_blob(args.root); + let bytes = store.read_blob(args.root).expect("blob not found"); let pb = store::Directory::decode(&*bytes).unwrap(); Directory::from_pb(pb) @@ -41,7 +41,7 @@ fn extract(store: &fossil::Store, path: &Path, dir: &Directory) { let path = path.join(name); match node.clone() { fossil::Node::Directory(fossil::DirectoryRef { ident, size: _ }) => { - let blob = store.read_blob(ident); + let blob = store.read_blob(ident).expect("blob not found"); let pb = store::Directory::decode(&*blob).unwrap(); fs::create_dir(&path).unwrap(); extract(store, &path, &Directory::from_pb(pb)); @@ -58,7 +58,7 @@ fn extract(store: &fossil::Store, path: &Path, dir: &Directory) { .mode(mode) .open(path) .unwrap(); - let blob = store.read_blob(ident); + let blob = store.read_blob(ident).expect("blob not found"); f.write_all(&blob).unwrap(); } fossil::Node::Link { target } => { diff --git a/ripple/fossil/src/bin/mount.rs b/ripple/fossil/src/bin/mount.rs index 846e543..9e0e8aa 100644 --- a/ripple/fossil/src/bin/mount.rs +++ b/ripple/fossil/src/bin/mount.rs @@ -132,7 +132,7 @@ impl Filesystem { (inode, &self.roots[&inode]) } hash_map::Entry::Vacant(e) => { - let root = memtree::load_root(&self.store, ident); + let root = memtree::load_root(&self.store, ident)?; let inode = self.inode_tail; self.inode_tail += inode + 1 + root.size() as u64; @@ -241,7 +241,10 @@ impl fuser::Filesystem for Filesystem { fn open(&mut self, _req: &fuser::Request<'_>, ino: u64, _flags: i32, reply: fuser::ReplyOpen) { match self.find(ino) { Some(memtree::Node::File(f)) => { - let contents = self.store.open_blob(f.ident); + let contents = self + .store + .open_blob(f.ident) + .expect("file points at missing blob"); let fh = Box::new(Handle::File { contents: RefCell::new(contents), }); @@ -823,9 +826,9 @@ mod memtree { } } - pub fn load_root(store: &fossil::Store, ident: Digest) -> Directory { + pub fn load_root(store: &fossil::Store, ident: Digest) -> Option { let pb = { - let bytes = store.read_blob(ident); + let bytes = store.read_blob(ident)?; store::Directory::decode(&*bytes).unwrap() }; let mut children = BTreeMap::new(); @@ -836,7 +839,7 @@ mod memtree { size: _, } in pb.directories { - let child = load_root(store, fossil::digest_from_bytes(&r#ref)); + let child = load_root(store, fossil::digest_from_bytes(&r#ref))?; children.insert(name, NodeBuf::Directory(child)); } @@ -859,7 +862,7 @@ mod memtree { children.insert(name, NodeBuf::Link { target }); } - Directory::from_children(children) + Some(Directory::from_children(children)) } impl Directory { diff --git a/ripple/fossil/src/lib.rs b/ripple/fossil/src/lib.rs index 004cf45..007a771 100644 --- a/ripple/fossil/src/lib.rs +++ b/ripple/fossil/src/lib.rs @@ -207,18 +207,14 @@ impl Store { Some(store::Chunk::decode(&*buf).unwrap()) } - pub fn read_blob(&self, ident: Digest) -> Vec { + pub fn read_blob(&self, ident: Digest) -> Option> { let mut buffer = Vec::new(); - self.open_blob(ident).read_to_end(&mut buffer).unwrap(); - buffer + self.open_blob(ident)?.read_to_end(&mut buffer).unwrap(); + Some(buffer) } - pub fn open_blob(&self, ident: Digest) -> Blob { - let buf = self - .blobs - .get(&*ident.as_bytes()) - .unwrap() - .expect("blob not found"); + pub fn open_blob(&self, ident: Digest) -> Option { + let buf = self.blobs.get(&*ident.as_bytes()).unwrap()?; let store::Blob { mut chunks, @@ -241,7 +237,7 @@ impl Store { }) .collect(); - Blob(bao::decode::Decoder::new_outboard( + Some(Blob(bao::decode::Decoder::new_outboard( RawBlob { store: self, chunks, @@ -250,7 +246,7 @@ impl Store { }, io::Cursor::new(bao_inline), &ident, - )) + ))) } } @@ -537,5 +533,5 @@ fn read_write() { // TODO(edef): use a temporary file let store = Store::open("fossil.db").unwrap(); let ident = store.write_blob(&data); - assert_eq!(data, store.read_blob(ident)); + assert_eq!(Some(data), store.read_blob(ident)); } -- cgit 1.4.1