[pve-devel] [PATCH proxmox-offline-mirror v2 4/5] pool: gc: remove empty directories under link_dir
Stoiko Ivanov
s.ivanov at proxmox.com
Tue Jul 9 12:47:04 CEST 2024
garbage collection currently is quite aggressive in removing all files
under the link_dir, which are not a hard-link to a checksum file.
removing directories that remain empty below the link_dir should thus
not too dangerous.
without this patch, removing a snapshot on a mirror, running gc there,
and syncing everything to a medium, leaves the medium with an
hierarchy of empty directories below the removed snapshot (the files
get cleaned up the directories remain).
using WalkDir::content_first() seems better than to check for
emptiness after each file-removal [0]
[0] https://docs.rs/walkdir/latest/walkdir/struct.WalkDir.html#method.contents_first
Signed-off-by: Stoiko Ivanov <s.ivanov at proxmox.com>
---
src/pool.rs | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/src/pool.rs b/src/pool.rs
index b4f2a6a..56dcbb4 100644
--- a/src/pool.rs
+++ b/src/pool.rs
@@ -451,6 +451,7 @@ impl PoolLockGuard<'_> {
/// Run a garbage collection, removing
/// - any checksum files that have no links outside of `pool_dir`
/// - any files in `link_dir` that have no corresponding checksum files
+ /// - any empty directories below `link_dir` remaining after the file removal
pub(crate) fn gc(&self) -> Result<(usize, u64), Error> {
let (inode_map, _link_count) = self.get_inode_csum_map()?;
@@ -459,7 +460,8 @@ impl PoolLockGuard<'_> {
let handle_entry = |entry: Result<walkdir::DirEntry, walkdir::Error>,
count: &mut usize,
- size: &mut u64|
+ size: &mut u64,
+ remove_empty_dir: bool|
-> Result<(), Error> {
let path = entry?.into_path();
if path == self.lock_path() {
@@ -467,6 +469,10 @@ impl PoolLockGuard<'_> {
}
let meta = path.metadata()?;
+ if remove_empty_dir && meta.is_dir() && path.read_dir()?.next().is_none() {
+ std::fs::remove_dir(path)?;
+ return Ok(());
+ }
if !meta.is_file() {
return Ok(());
};
@@ -507,11 +513,12 @@ impl PoolLockGuard<'_> {
};
WalkDir::new(&self.pool.link_dir)
+ .contents_first(true)
.into_iter()
- .try_for_each(|entry| handle_entry(entry, &mut count, &mut size))?;
+ .try_for_each(|entry| handle_entry(entry, &mut count, &mut size, true))?;
WalkDir::new(&self.pool.pool_dir)
.into_iter()
- .try_for_each(|entry| handle_entry(entry, &mut count, &mut size))?;
+ .try_for_each(|entry| handle_entry(entry, &mut count, &mut size, false))?;
Ok((count, size))
}
--
2.39.2
More information about the pve-devel
mailing list