Skip to content

Commit 7696b0a

Browse files
alexlarssonallisonkarlitskaya
authored andcommitted
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 574bbfd commit 7696b0a

File tree

2 files changed

+34
-9
lines changed

2 files changed

+34
-9
lines changed

crates/composefs/src/repository.rs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use crate::{
2626
},
2727
mount::{composefs_fsmount, mount_at},
2828
splitstream::{DigestMap, SplitStreamReader, SplitStreamWriter},
29-
util::{proc_self_fd, Sha256Digest},
29+
util::{filter_errno, proc_self_fd, Sha256Digest},
3030
};
3131

3232
/// Call openat() on the named subdirectory of "dirfd", possibly creating it first.
@@ -552,15 +552,28 @@ impl<ObjectID: FsVerityHashValue> Repository<ObjectID> {
552552
fn gc_category(&self, category: &str) -> Result<HashSet<ObjectID>> {
553553
let mut objects = HashSet::new();
554554

555-
let category_fd = self.openat(category, OFlags::RDONLY | OFlags::DIRECTORY)?;
555+
let Some(category_fd) = filter_errno(
556+
self.openat(category, OFlags::RDONLY | OFlags::DIRECTORY),
557+
Errno::NOENT,
558+
)
559+
.context("Opening {category} dir in repository")?
560+
else {
561+
return Ok(objects);
562+
};
556563

557-
let refs = openat(
558-
&category_fd,
559-
"refs",
560-
OFlags::RDONLY | OFlags::DIRECTORY,
561-
Mode::empty(),
562-
)?;
563-
Self::walk_symlinkdir(refs, &mut objects)?;
564+
if let Some(refs) = filter_errno(
565+
openat(
566+
&category_fd,
567+
"refs",
568+
OFlags::RDONLY | OFlags::DIRECTORY,
569+
Mode::empty(),
570+
),
571+
Errno::NOENT,
572+
)
573+
.context("Opening {category}/refs dir in repository")?
574+
{
575+
Self::walk_symlinkdir(refs, &mut objects)?;
576+
}
564577

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

crates/composefs/src/util.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::{
33
os::fd::{AsFd, AsRawFd},
44
};
55

6+
use rustix::io::{Errno, Result as ErrnoResult};
67
use tokio::io::{AsyncRead, AsyncReadExt};
78

89
/// Formats a string like "/proc/self/fd/3" for the given fd. This can be used to work with kernel
@@ -97,6 +98,17 @@ pub fn parse_sha256(string: impl AsRef<str>) -> Result<Sha256Digest> {
9798
Ok(value)
9899
}
99100

101+
pub(crate) fn filter_errno<T>(
102+
result: rustix::io::Result<T>,
103+
ignored: Errno,
104+
) -> ErrnoResult<Option<T>> {
105+
match result {
106+
Ok(result) => Ok(Some(result)),
107+
Err(err) if err == ignored => Ok(None),
108+
Err(err) => Err(err),
109+
}
110+
}
111+
100112
#[cfg(test)]
101113
mod test {
102114
use similar_asserts::assert_eq;

0 commit comments

Comments
 (0)