Skip to content

Commit 08611b7

Browse files
committed
Repository: Handle non-existing directories in garbage collection
For example, if there has been no streams created, we don't want to fail with some random ENOENT. Signed-off-by: Alexander Larsson <[email protected]>
1 parent cc12f1b commit 08611b7

File tree

2 files changed

+36
-9
lines changed

2 files changed

+36
-9
lines changed

crates/composefs/src/repository.rs

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use crate::{
2525
},
2626
mount::mount_composefs_at,
2727
splitstream::{DigestMap, SplitStreamReader, SplitStreamWriter},
28-
util::{proc_self_fd, replace_symlinkat, Sha256Digest},
28+
util::{filter_errno, proc_self_fd, replace_symlinkat, Sha256Digest},
2929
};
3030

3131
/// Call openat() on the named subdirectory of "dirfd", possibly creating it first.
@@ -491,15 +491,31 @@ impl<ObjectID: FsVerityHashValue> Repository<ObjectID> {
491491
fn gc_category(&self, category: &str) -> Result<HashSet<ObjectID>> {
492492
let mut objects = HashSet::new();
493493

494-
let category_fd = self.openat(category, OFlags::RDONLY | OFlags::DIRECTORY)?;
494+
let category_fd = match filter_errno(
495+
self.openat(category, OFlags::RDONLY | OFlags::DIRECTORY),
496+
Errno::NOENT,
497+
)
498+
.context("Opening {category} dir in repository")?
499+
{
500+
Some(fd) => fd,
501+
None => {
502+
return Ok(objects);
503+
}
504+
};
495505

496-
let refs = openat(
497-
&category_fd,
498-
"refs",
499-
OFlags::RDONLY | OFlags::DIRECTORY,
500-
Mode::empty(),
501-
)?;
502-
Self::walk_symlinkdir(refs, &mut objects)?;
506+
if let Some(refs) = filter_errno(
507+
openat(
508+
&category_fd,
509+
"refs",
510+
OFlags::RDONLY | OFlags::DIRECTORY,
511+
Mode::empty(),
512+
),
513+
Errno::NOENT,
514+
)
515+
.context("Opening {category}/refs dir in repository")?
516+
{
517+
Self::walk_symlinkdir(refs, &mut objects)?;
518+
}
503519

504520
for item in Dir::read_from(&category_fd)? {
505521
let entry = item?;

crates/composefs/src/util.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,17 @@ pub fn replace_symlinkat(
140140
Err(Errno::EXIST)
141141
}
142142

143+
pub fn filter_errno<T>(
144+
result: rustix::io::Result<T>,
145+
ignored: Errno,
146+
) -> rustix::io::Result<Option<T>> {
147+
match result {
148+
Ok(result) => Ok(Some(result)),
149+
Err(err) if err == ignored => Ok(None),
150+
Err(err) => Err(err),
151+
}
152+
}
153+
143154
#[cfg(test)]
144155
mod test {
145156
use similar_asserts::assert_eq;

0 commit comments

Comments
 (0)