diff --git a/src/api2/types.rs b/src/api2/types.rs index d06a5cc9..806ba4ba 100644 --- a/src/api2/types.rs +++ b/src/api2/types.rs @@ -313,6 +313,10 @@ pub struct GarbageCollectionStatus { pub removed_bytes: u64, /// Number of removed chunks. pub removed_chunks: usize, + /// Sum of pending bytes (pending removal - kept for safety). + pub pending_bytes: u64, + /// Number of pending chunks (pending removal - kept for safety). + pub pending_chunks: usize, } impl Default for GarbageCollectionStatus { @@ -325,6 +329,8 @@ impl Default for GarbageCollectionStatus { disk_chunks: 0, removed_bytes: 0, removed_chunks: 0, + pending_bytes: 0, + pending_chunks: 0, } } } diff --git a/src/backup/chunk_store.rs b/src/backup/chunk_store.rs index fa9c2710..906b0f7d 100644 --- a/src/backup/chunk_store.rs +++ b/src/backup/chunk_store.rs @@ -289,7 +289,7 @@ impl ChunkStore { pub fn sweep_unused_chunks( &self, - oldest_writer: Option, + oldest_writer: i64, status: &mut GarbageCollectionStatus, worker: Arc, ) -> Result<(), Error> { @@ -299,10 +299,8 @@ impl ChunkStore { let mut min_atime = now - 3600*24; // at least 24h (see mount option relatime) - if let Some(stamp) = oldest_writer { - if stamp < min_atime { - min_atime = stamp; - } + if oldest_writer < min_atime { + min_atime = oldest_writer; } min_atime -= 300; // add 5 mins gap for safety @@ -338,10 +336,9 @@ impl ChunkStore { let lock = self.mutex.lock(); if let Ok(stat) = fstatat(dirfd, filename, nix::fcntl::AtFlags::AT_SYMLINK_NOFOLLOW) { - let age = now - stat.st_atime; - //println!("FOUND {} {:?}", age/(3600*24), filename); if stat.st_atime < min_atime { - println!("UNLINK {} {:?}", age/(3600*24), filename); + //let age = now - stat.st_atime; + //println!("UNLINK {} {:?}", age/(3600*24), filename); let res = unsafe { libc::unlinkat(dirfd, filename.as_ptr(), 0) }; if res != 0 { let err = nix::Error::last(); @@ -354,9 +351,14 @@ impl ChunkStore { } status.removed_chunks += 1; status.removed_bytes += stat.st_size as u64; - } else { - status.disk_chunks += 1; - status.disk_bytes += stat.st_size as u64; + } else { + if stat.st_atime < oldest_writer { + status.pending_chunks += 1; + status.pending_bytes += stat.st_size as u64; + } else { + status.disk_chunks += 1; + status.disk_bytes += stat.st_size as u64; + } } } drop(lock); diff --git a/src/backup/datastore.rs b/src/backup/datastore.rs index d4ee7dd4..3ee48fee 100644 --- a/src/backup/datastore.rs +++ b/src/backup/datastore.rs @@ -338,7 +338,9 @@ impl DataStore { let _exclusive_lock = self.chunk_store.try_exclusive_lock()?; - let oldest_writer = self.chunk_store.oldest_writer(); + let now = unsafe { libc::time(std::ptr::null_mut()) }; + + let oldest_writer = self.chunk_store.oldest_writer().unwrap_or(now); let mut gc_status = GarbageCollectionStatus::default(); gc_status.upid = Some(worker.to_string()); @@ -352,6 +354,10 @@ impl DataStore { worker.log(&format!("Removed bytes: {}", gc_status.removed_bytes)); worker.log(&format!("Removed chunks: {}", gc_status.removed_chunks)); + if gc_status.pending_bytes > 0 { + worker.log(&format!("Pending removals: {} bytes ({} chunks)", gc_status.pending_bytes, gc_status.pending_chunks)); + } + worker.log(&format!("Original data bytes: {}", gc_status.index_data_bytes)); if gc_status.index_data_bytes > 0 {