Skip to content

Commit 362631d

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 55e52b5 commit 362631d

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.
@@ -490,15 +490,31 @@ impl<ObjectID: FsVerityHashValue> Repository<ObjectID> {
490490
fn gc_category(&self, category: &str) -> Result<HashSet<ObjectID>> {
491491
let mut objects = HashSet::new();
492492

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

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

503519
for item in Dir::read_from(&category_fd)? {
504520
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)