feat: add -x/--one-file-system to stay within the source filesystem

Capture the transfer root's device (st_dev) at scanner creation and skip
descending into any subdirectory on a different device (a mount point).
Implemented sender/client-side only: sequential BFS and parallel (-m) root
scan apply the same scanner_same_filesystem decision; no wire/protocol change
and default behavior is unchanged. Unit tests cover the pure decision, same
device scanning in both modes, and CLI parsing; integration tests prove -x
leaves a single-filesystem tree byte-identical and, when root can mount a
tmpfs, skips a genuine cross-device subtree.
This commit is contained in:
2026-09-06 12:18:43 +02:00
parent 06e83f2402
commit 2bcc20aa08
11 changed files with 274 additions and 20 deletions
+10 -1
View File
@@ -6,8 +6,9 @@
#include "queue.h"
#include <dirent.h>
#include <stdbool.h>
#include <threads.h>
#include <stdatomic.h>
#include <sys/types.h>
#include <threads.h>
typedef struct {
bool use_metadata;
@@ -25,6 +26,7 @@ typedef struct {
bool safe_links;
bool copy_unsafe_links;
bool checksum;
bool one_file_system;
} ScannerOptions;
typedef struct {
@@ -46,6 +48,8 @@ typedef struct {
bool safe_links;
bool copy_unsafe_links;
bool checksum;
bool one_file_system;
dev_t root_dev;
bool failed;
} DirectoryScanner;
@@ -79,6 +83,11 @@ Chunk* directory_scanner_next(DirectoryScanner* scanner);
bool directory_scanner_failed(const DirectoryScanner* scanner);
void directory_scanner_destroy(DirectoryScanner* scanner);
/* --one-file-system (-x) decision: a directory entry may be descended into
* only when the option is disabled or the entry lives on the same device as
* the transfer root. Exposed so tests can exercise the rule directly. */
bool scanner_same_filesystem(bool one_file_system, dev_t root_device, dev_t entry_device);
ParallelScanner* parallel_scanner_create_with_options(const char* root_directory,
const ScannerOptions* options,
ProtocolSession* allocation_session);