aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/file_op.rs44
1 files changed, 20 insertions, 24 deletions
diff --git a/src/file_op.rs b/src/file_op.rs
index 5ae9c32..9a06aea 100644
--- a/src/file_op.rs
+++ b/src/file_op.rs
@@ -14,7 +14,7 @@ use std::path::{Component, Path, PathBuf};
use std::sync::Arc;
use actix_web::{HttpRequest, HttpResponse, http::header, web};
-use async_walkdir::{Filtering, WalkDir};
+use async_walkdir::WalkDir;
use futures::{StreamExt, TryStreamExt};
use log::{info, warn};
use serde::Deserialize;
@@ -60,11 +60,13 @@ impl FileHash {
pub async fn recursive_dir_size(dir: &Path) -> Result<u64, RuntimeError> {
#[cfg(target_family = "unix")]
let seen_inodes = Arc::new(RwLock::new(HashSet::new()));
- let mut entries = WalkDir::new(dir).filter(move |entry| {
- {
- #[cfg(target_family = "unix")]
- let seen = seen_inodes.clone();
- async move {
+
+ let mut entries = WalkDir::new(dir);
+
+ let mut total_size = 0;
+ loop {
+ match entries.next().await {
+ Some(Ok(entry)) => {
if let Ok(metadata) = entry.metadata().await {
if metadata.is_file() {
// On Unix, we want to filter inodes that we've already seen so we get a more
@@ -74,31 +76,25 @@ pub async fn recursive_dir_size(dir: &Path) -> Result<u64, RuntimeError> {
let (device_id, inode) = (metadata.dev(), metadata.ino());
// Check if this file has been seen before based on its device ID and inode number
- if seen.read().await.contains(&(device_id, inode)) {
- return Filtering::Ignore;
+ if seen_inodes.read().await.contains(&(device_id, inode)) {
+ continue;
} else {
- seen.write().await.insert((device_id, inode));
+ seen_inodes.write().await.insert((device_id, inode));
}
}
- return Filtering::Continue;
+ total_size += metadata.len();
}
}
- Filtering::Ignore
- }
- }
- });
-
- let mut total_size = 0;
- loop {
- match entries.next().await {
- Some(Ok(entry)) => {
- if let Ok(metadata) = entry.metadata().await {
- total_size += metadata.len();
- }
}
Some(Err(e)) => {
- warn!("Error trying to read file when calculating dir size: {e}");
- return Err(RuntimeError::InvalidPathError(e.to_string()));
+ if let Some(io_err) = e.into_io() {
+ match io_err.kind() {
+ ErrorKind::PermissionDenied => warn!(
+ "Error trying to read file when calculating dir size: {io_err}, ignoring"
+ ),
+ _ => return Err(RuntimeError::InvalidPathError(io_err.to_string())),
+ }
+ }
}
None => break,
}