]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
hardlink: implement --mount
authorKarel Zak <kzak@redhat.com>
Thu, 31 Oct 2024 10:21:20 +0000 (11:21 +0100)
committerKarel Zak <kzak@redhat.com>
Thu, 31 Oct 2024 10:21:20 +0000 (11:21 +0100)
Let's export another feature of nftw() to the hardlink command line.
In this case, we will force the file-tree-walk to stay within the same
filesystem.

Addresses: https://github.com/util-linux/util-linux/discussions/3244
Signed-off-by: Karel Zak <kzak@redhat.com>
bash-completion/hardlink
misc-utils/hardlink.1.adoc
misc-utils/hardlink.c

index 22e5b5fa8755424fc1748c8b8b515d58a360aba4..926b659ff402b017570343f160bdf416ac280823 100644 (file)
@@ -53,6 +53,7 @@ _hardlink_module()
                        --respect-name
                        --maximize
                        --minimize
+                       --mount
                        --dry-run
                        --ignore-owner
                        --keep-oldest
index 1a353f06aba25e6b3e9a7c61b5370ef9891bbb95..192bf95191384e7c3605d5befc2ebd0b8401cde0 100644 (file)
@@ -112,6 +112,9 @@ A regular expression that excludes files from being compared and linked. This op
 *--exclude-subtree* _regex_::
 A regular expression that excludes entire directories from being compared and linked. This option can also be used multiple times.
 
+*--mount*::
+Do not traverse directories on different filesystems (remain within the same filesystem).
+
 *-X*, *--respect-xattrs*::
 Only try to link files with the same extended attributes.
 
index 55e09265e1f79825989df9c881cd59da649b27a4..2d3861c98ef5f627067e9a301402814a9c9e2294 100644 (file)
@@ -195,6 +195,7 @@ static struct options {
        unsigned int keep_oldest:1;
        unsigned int prio_trees:1;
        unsigned int dry_run:1;
+       unsigned int within_mount:1;
        uintmax_t min_size;
        uintmax_t max_size;
        size_t io_size;
@@ -1217,6 +1218,7 @@ static void __attribute__((__noreturn__)) usage(void)
 #ifdef USE_SKIP_SUBTREE
        fputs(_("     --exclude-subtree <regex>  regular expression to exclude directories\n"), out);
 #endif
+       fputs(_("     --mount                stay within the same filesystem\n"), out);
 #ifdef USE_XATTR
        fputs(_(" -X, --respect-xattrs       respect extended attributes\n"), out);
 #endif
@@ -1243,7 +1245,8 @@ static int parse_options(int argc, char *argv[])
        enum {
                OPT_REFLINK = CHAR_MAX + 1,
                OPT_SKIP_RELINKS,
-               OPT_EXCLUDE_SUBTREE
+               OPT_EXCLUDE_SUBTREE,
+               OPT_MOUNT
        };
        static const char optstr[] = "VhvndfpotXcmMFOx:y:i:r:S:s:b:q";
        static const struct option long_options[] = {
@@ -1266,6 +1269,7 @@ static int parse_options(int argc, char *argv[])
 #ifdef USE_SKIP_SUBTREE
                {"exclude-subtree", required_argument, NULL, OPT_EXCLUDE_SUBTREE},
 #endif
+               {"mount", no_argument, NULL, OPT_MOUNT},
                {"method", required_argument, NULL, 'y' },
                {"minimum-size", required_argument, NULL, 's'},
                {"maximum-size", required_argument, NULL, 'S'},
@@ -1379,6 +1383,9 @@ static int parse_options(int argc, char *argv[])
                        reflinks_skip = 1;
                        break;
 #endif
+               case OPT_MOUNT:
+                       opts.within_mount = 1;
+                       break;
                case 'h':
                        usage();
                case 'V':
@@ -1485,11 +1492,14 @@ int main(int argc, char *argv[])
        stats.started = TRUE;
 
        ftw_flags = FTW_PHYS;
+
+       if (opts.within_mount)
+               ftw_flags |= FTW_MOUNT;
+
 #ifdef USE_SKIP_SUBTREE
        if (opts.exclude_subtree)
                ftw_flags |= FTW_ACTIONRETVAL;
 #endif
-
        jlog(JLOG_VERBOSE2, _("Scanning [device/inode/links]:"));
        for (; optind < argc; optind++) {
                char *path = realpath(argv[optind], NULL);