From 3a1e5f10dd8aef4bc02f76e735c4a3244147ffe8 Mon Sep 17 00:00:00 2001 From: Alexander Batischev Date: Wed, 28 Jul 2021 19:50:03 +0300 Subject: FsIter: annotate entries belonging to CACHEDIR.TAGs --- src/backup_run.rs | 29 +++++++++++++---------------- src/fsiter.rs | 25 ++++++++++++++++++------- 2 files changed, 31 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/backup_run.rs b/src/backup_run.rs index 9667382..2b23aa4 100644 --- a/src/backup_run.rs +++ b/src/backup_run.rs @@ -5,7 +5,7 @@ use crate::client::{BackupClient, ClientError}; use crate::config::ClientConfig; use crate::error::ObnamError; use crate::fsentry::FilesystemEntry; -use crate::fsiter::{FsIterError, FsIterator}; +use crate::fsiter::{AnnotatedFsEntry, FsIterError, FsIterator}; use crate::generation::{LocalGeneration, LocalGenerationError, NascentError, NascentGeneration}; use crate::policy::BackupPolicy; use log::{info, warn}; @@ -119,7 +119,7 @@ impl<'a> BackupRun<'a> { pub fn backup( &self, - entry: Result, + entry: Result, old: &LocalGeneration, ) -> Result { match entry { @@ -129,10 +129,10 @@ impl<'a> BackupRun<'a> { Err(BackupError::FsIterError(err)) } Ok(entry) => { - let path = &entry.pathbuf(); + let path = &entry.inner.pathbuf(); info!("backup: {}", path.display()); self.found_live_file(path); - let reason = self.policy.needs_backup(&old, &entry); + let reason = self.policy.needs_backup(&old, &entry.inner); match reason { Reason::IsNew | Reason::Changed @@ -145,7 +145,7 @@ impl<'a> BackupRun<'a> { reason, )), Reason::Unchanged | Reason::Skipped | Reason::FileError => { - let fileno = old.get_fileno(&entry.pathbuf())?; + let fileno = old.get_fileno(&entry.inner.pathbuf())?; let ids = if let Some(fileno) = fileno { let mut ids = vec![]; for id in old.chunkids(fileno)?.iter()? { @@ -155,12 +155,11 @@ impl<'a> BackupRun<'a> { } else { vec![] }; - // TODO: replace `false` with an actual value Ok(FsEntryBackupOutcome { - entry, + entry: entry.inner, ids, reason, - is_cachedir_tag: false, + is_cachedir_tag: entry.is_cachedir_tag, }) } } @@ -179,29 +178,27 @@ impl<'a> BackupRun<'a> { fn backup_file( client: &BackupClient, - entry: &FilesystemEntry, + entry: &AnnotatedFsEntry, path: &Path, chunk_size: usize, reason: Reason, ) -> FsEntryBackupOutcome { - let ids = client.upload_filesystem_entry(&entry, chunk_size); + let ids = client.upload_filesystem_entry(&entry.inner, chunk_size); match ids { Err(err) => { warn!("error backing up {}, skipping it: {}", path.display(), err); FsEntryBackupOutcome { - entry: entry.clone(), + entry: entry.inner.clone(), ids: vec![], reason: Reason::FileError, - // TODO: replace `false` with an actual value - is_cachedir_tag: false, + is_cachedir_tag: entry.is_cachedir_tag, } } Ok(ids) => FsEntryBackupOutcome { - entry: entry.clone(), + entry: entry.inner.clone(), ids, reason, - // TODO: replace `false` with an actual value - is_cachedir_tag: false, + is_cachedir_tag: entry.is_cachedir_tag, }, } } diff --git a/src/fsiter.rs b/src/fsiter.rs index aea9078..2325793 100644 --- a/src/fsiter.rs +++ b/src/fsiter.rs @@ -3,6 +3,13 @@ use log::{debug, warn}; use std::path::{Path, PathBuf}; use walkdir::{DirEntry, IntoIter, WalkDir}; +/// Filesystem entry along with additional info about it. +pub struct AnnotatedFsEntry { + pub inner: FilesystemEntry, + /// Is `entry` a valid CACHEDIR.TAG? + pub is_cachedir_tag: bool, +} + /// Iterator over file system entries in a directory tree. pub struct FsIterator { iter: SkipCachedirs, @@ -32,7 +39,7 @@ impl FsIterator { } impl Iterator for FsIterator { - type Item = Result; + type Item = Result; fn next(&mut self) -> Option { self.iter.next() } @@ -45,7 +52,7 @@ struct SkipCachedirs { exclude_cache_tag_directories: bool, // This is the last tag we've found. `next()` will yield it before asking `iter` for more // entries. - cachedir_tag: Option>, + cachedir_tag: Option>, } impl SkipCachedirs { @@ -94,13 +101,13 @@ impl SkipCachedirs { if content == CACHEDIR_TAG { self.iter.skip_current_dir(); - self.cachedir_tag = Some(new_entry(&tag_path)); + self.cachedir_tag = Some(new_entry(&tag_path, true)); } } } impl Iterator for SkipCachedirs { - type Item = Result; + type Item = Result; fn next(&mut self) -> Option { self.cachedir_tag.take().or_else(|| { @@ -111,14 +118,14 @@ impl Iterator for SkipCachedirs { Some(Err(err)) => Some(Err(FsIterError::WalkDir(err))), Some(Ok(entry)) => { self.try_enqueue_cachedir_tag(&entry); - Some(new_entry(entry.path())) + Some(new_entry(entry.path(), false)) } } }) } } -fn new_entry(path: &Path) -> Result { +fn new_entry(path: &Path, is_cachedir_tag: bool) -> Result { let meta = std::fs::symlink_metadata(path); debug!("metadata for {:?}: {:?}", path, meta); let meta = match meta { @@ -130,5 +137,9 @@ fn new_entry(path: &Path) -> Result { }; let entry = FilesystemEntry::from_metadata(path, &meta)?; debug!("FileSystemEntry for {:?}: {:?}", path, entry); - Ok(entry) + let annotated = AnnotatedFsEntry { + inner: entry, + is_cachedir_tag, + }; + Ok(annotated) } -- cgit v1.2.1