Support limiting comparison by maximum file size.
[kzak@redhat.com: - resolve conflicts]
Signed-off-by: Daniele Pizzolli <dan+dev@toel.it>
Signed-off-by: Karel Zak <kzak@redhat.com>
*-s*, *--minimum-size* _size_::
The minimum size to consider. By default this is 1, so empty files will not be linked. The _size_ argument may be followed by the multiplicative suffixes KiB (=1024), MiB (=1024*1024), and so on for GiB, TiB, PiB, EiB, ZiB and YiB (the "iB" is optional, e.g., "K" has the same meaning as "KiB").
+*-S*, *--maximum-size* _size_::
+The maximum size to consider. By default this is 0 and 0 has the special meaning of unlimited. The _size_ argument may be followed by the multiplicative suffixes KiB (=1024), MiB (=1024*1024), and so on for GiB, TiB, PiB, EiB, ZiB and YiB (the "iB" is optional, e.g., "K" has the same meaning as "KiB").
+
*-b*, *--io-size* _size_::
The size of the read() or sendfile() buffer used when comparing file contents.
The _size_ argument may be followed by the multiplicative suffixes KiB, MiB,
* @keep_oldest: Choose the file with oldest timestamp as master (default = FALSE)
* @dry_run: Specifies whether hardlink should not link files (default = FALSE)
* @min_size: Minimum size of files to consider. (default = 1 byte)
+ * @max_size: Maximum size of files to consider, 0 means umlimited. (default = 0 byte)
*/
static struct options {
struct hdl_regex *include;
unsigned int keep_oldest:1;
unsigned int dry_run:1;
uintmax_t min_size;
+ uintmax_t max_size;
size_t io_size;
size_t cache_size;
} opts = {
jlog(JLOG_VERBOSE2, " %5zu: [%ld/%ld/%ld] %s",
stats.files, sb->st_dev, sb->st_ino, sb->st_nlink, fpath);
+ if ((opts.max_size > 0) && ((uintmax_t) sb->st_size > opts.max_size)) {
+ jlog(JLOG_VERBOSE1,
+ _("Skipped %s (greater than configured size)"), fpath);
+ return 0;
+ }
+
pathlen = strlen(fpath) + 1;
fil = xcalloc(1, sizeof(*fil));
fputs(_(" -x, --exclude <regex> regular expression to exclude files\n"), out);
fputs(_(" -i, --include <regex> regular expression to include files/dirs\n"), out);
fputs(_(" -s, --minimum-size <size> minimum size for files.\n"), out);
+ fputs(_(" -S, --maximum-size <size> maximum size for files.\n"), out);
fputs(_(" -b, --io-size <size> I/O buffer size for file reading (speedup, using more RAM)\n"), out);
fputs(_(" -r, --cache-size <size> memory limit for cached file content data\n"), out);
fputs(_(" -c, --content compare only file contents, same as -pot\n"), out);
*/
static int parse_options(int argc, char *argv[])
{
- static const char optstr[] = "VhvnfpotXcmMOx:y:i:r:s:b:q";
+ static const char optstr[] = "VhvnfpotXcmMOx:y:i:r:S:s:b:q";
static const struct option long_options[] = {
{"version", no_argument, NULL, 'V'},
{"help", no_argument, NULL, 'h'},
{"include", required_argument, NULL, 'i'},
{"method", required_argument, NULL, 'y' },
{"minimum-size", required_argument, NULL, 's'},
+ {"maximum-size", required_argument, NULL, 'S'},
{"io-size", required_argument, NULL, 'b'},
{"content", no_argument, NULL, 'c'},
{"quiet", no_argument, NULL, 'q'},
register_regex(&opts.include, optarg);
break;
case 's':
- opts.min_size = strtosize_or_err(optarg, _("failed to parse size"));
+ opts.min_size = strtosize_or_err(optarg, _("failed to parse minimum size"));
+ break;
+ case 'S':
+ opts.max_size = strtosize_or_err(optarg, _("failed to parse maximum size"));
break;
case 'r':
opts.cache_size = strtosize_or_err(optarg, _("failed to cache size"));
--- /dev/null
+Skipped [Redacted]/hardlink/testdir1/file-a-2 (greater than configured size)
+Skipped [Redacted]/hardlink/testdir1/file-c-2 (greater than configured size)
+Skipped [Redacted]/hardlink/testdir1/dir-1/sdir-1/file-a-2 (greater than configured size)
+Skipped [Redacted]/hardlink/testdir1/dir-1/sdir-1/file-c-2 (greater than configured size)
+Skipped [Redacted]/hardlink/testdir1/dir-1/sdir-1/file-b-1 (greater than configured size)
+Skipped [Redacted]/hardlink/testdir1/dir-1/sdir-1/file-c-1 (greater than configured size)
+Skipped [Redacted]/hardlink/testdir1/dir-1/sdir-1/file-b-2 (greater than configured size)
+Skipped [Redacted]/hardlink/testdir1/dir-1/sdir-1/file-c-3 (greater than configured size)
+Skipped [Redacted]/hardlink/testdir1/dir-1/sdir-1/file-b-3 (greater than configured size)
+Skipped [Redacted]/hardlink/testdir1/dir-1/sdir-1/file-a-3 (greater than configured size)
+Skipped [Redacted]/hardlink/testdir1/dir-1/sdir-1/file-a-1 (greater than configured size)
+Skipped [Redacted]/hardlink/testdir1/dir-1/sdir-2/file-a-1-abcdefghijklmnopqrstxyz-"§$%&()=?*+ (greater than configured size)
+Skipped [Redacted]/hardlink/testdir1/file-b-4 (greater than configured size)
+Skipped [Redacted]/hardlink/testdir1/file-b-1 (greater than configured size)
+Skipped [Redacted]/hardlink/testdir1/file-a-5 (greater than configured size)
+Skipped [Redacted]/hardlink/testdir1/file-a-4 (greater than configured size)
+Skipped [Redacted]/hardlink/testdir1/dir-2/sdir-2/file-a-5 (greater than configured size)
+Skipped [Redacted]/hardlink/testdir1/dir-2/sdir-2/file-b-5 (greater than configured size)
+Skipped [Redacted]/hardlink/testdir1/dir-2/sdir-3/file-b-4 (greater than configured size)
+Skipped [Redacted]/hardlink/testdir1/file-c-1 (greater than configured size)
+Skipped [Redacted]/hardlink/testdir1/file-b-5 (greater than configured size)
+Skipped [Redacted]/hardlink/testdir1/file-b-2 (greater than configured size)
+Skipped [Redacted]/hardlink/testdir1/file-c-3 (greater than configured size)
+Skipped [Redacted]/hardlink/testdir1/file-b-3 (greater than configured size)
+Skipped [Redacted]/hardlink/testdir1/file-a-3 (greater than configured size)
+Skipped [Redacted]/hardlink/testdir1/file-a-1 (greater than configured size)
+Mode: real
+Files: 26
+Linked: 0 files
+Compared: 0 xattrs
+Compared: 0 files
+Saved: 0 B
+Duration: [Redacted]
+dir-1/sdir-1/file-a-1 10 8192 1540236423 644
+dir-1/sdir-1/file-a-2 10 8192 1540236423 644
+dir-1/sdir-1/file-a-3 10 8192 1540236423 644
+dir-1/sdir-1/file-b-1 10 8192 1540236430 644
+dir-1/sdir-1/file-b-2 10 8192 1540236430 644
+dir-1/sdir-1/file-b-3 10 8192 1540236430 644
+dir-1/sdir-1/file-c-1 6 8192 1540236548 644
+dir-1/sdir-1/file-c-2 6 8192 1540236548 644
+dir-1/sdir-1/file-c-3 6 8192 1540236548 644
+dir-1/sdir-2/file-a-1-abcdefghijklmnopqrstxyz-"§$%&()=?*+ 10 8192 1540236423 644
+dir-2/sdir-2/file-a-5 10 8192 1540236423 644
+dir-2/sdir-2/file-b-5 10 8192 1540236430 644
+dir-2/sdir-3/file-b-4 10 8192 1540236430 644
+file-a-1 10 8192 1540236423 644
+file-a-2 10 8192 1540236423 644
+file-a-3 10 8192 1540236423 644
+file-a-4 10 8192 1540236423 644
+file-a-5 10 8192 1540236423 644
+file-b-1 10 8192 1540236430 644
+file-b-2 10 8192 1540236430 644
+file-b-3 10 8192 1540236430 644
+file-b-4 10 8192 1540236430 644
+file-b-5 10 8192 1540236430 644
+file-c-1 6 8192 1540236548 644
+file-c-2 6 8192 1540236548 644
+file-c-3 6 8192 1540236548 644
--- /dev/null
+Mode: real
+Files: 26
+Linked: 0 files
+Compared: 0 xattrs
+Compared: 0 files
+Saved: 0 B
+Duration: [Redacted]
+dir-1/sdir-1/file-a-1 10 8192 1540236423 644
+dir-1/sdir-1/file-a-2 10 8192 1540236423 644
+dir-1/sdir-1/file-a-3 10 8192 1540236423 644
+dir-1/sdir-1/file-b-1 10 8192 1540236430 644
+dir-1/sdir-1/file-b-2 10 8192 1540236430 644
+dir-1/sdir-1/file-b-3 10 8192 1540236430 644
+dir-1/sdir-1/file-c-1 6 8192 1540236548 644
+dir-1/sdir-1/file-c-2 6 8192 1540236548 644
+dir-1/sdir-1/file-c-3 6 8192 1540236548 644
+dir-1/sdir-2/file-a-1-abcdefghijklmnopqrstxyz-"§$%&()=?*+ 10 8192 1540236423 644
+dir-2/sdir-2/file-a-5 10 8192 1540236423 644
+dir-2/sdir-2/file-b-5 10 8192 1540236430 644
+dir-2/sdir-3/file-b-4 10 8192 1540236430 644
+file-a-1 10 8192 1540236423 644
+file-a-2 10 8192 1540236423 644
+file-a-3 10 8192 1540236423 644
+file-a-4 10 8192 1540236423 644
+file-a-5 10 8192 1540236423 644
+file-b-1 10 8192 1540236430 644
+file-b-2 10 8192 1540236430 644
+file-b-3 10 8192 1540236430 644
+file-b-4 10 8192 1540236430 644
+file-b-5 10 8192 1540236430 644
+file-c-1 6 8192 1540236548 644
+file-c-2 6 8192 1540236548 644
+file-c-3 6 8192 1540236548 644
show_srcdir | sed 's/\(1540236\).*/\1xxx\tperm/' >> $TS_OUTPUT 2>> $TS_ERRLOG
ts_finalize_subtest
+ts_init_subtest "maximum-size-8191"
+# Redact path and duration for reproduciblity
+$TS_CMD_HARDLINK -vv --maximum-size 8191 "$SRCDIR" | \
+ sed 's:^Skipped .*/tests/output/\(.*\):Skipped [Redacted]/\1:' | \
+ sed 's/^Duration: .*/Duration: [Redacted]/' >> $TS_OUTPUT 2>> $TS_ERRLOG
+show_srcdir >> $TS_OUTPUT 2>> $TS_ERRLOG
+ts_finalize_subtest
+
+ts_init_subtest "maximum-size-8192"
+# Redact path and duration for reproduciblity
+$TS_CMD_HARDLINK -vv --maximum-size 8192 "$SRCDIR" | \
+ sed 's:^Skipped .*/tests/output/\(.*\):Skipped [Redacted]/\1:' | \
+ sed 's/^Duration:.*/Duration: [Redacted]/' >> $TS_OUTPUT 2>> $TS_ERRLOG
+show_srcdir >> $TS_OUTPUT 2>> $TS_ERRLOG
+ts_finalize_subtest
+
+
rm -rf "$SRCDIR"
ts_finalize