From fd461ced704fc8e47367efe6a03b8f9b417c20c7 Mon Sep 17 00:00:00 2001 From: Andreas Gruenbacher Date: Thu, 11 Mar 2021 19:19:38 +0100 Subject: getfattr: Add --one-file-system option Add a --one-filesystem option to getfattr. With this option, getfattr will not cross mount points, similar to "tar --one-file-system". --- include/walk_tree.h | 1 + libmisc/walk_tree.c | 10 ++++++++++ tools/getfattr.c | 6 ++++++ 3 files changed, 17 insertions(+) diff --git a/include/walk_tree.h b/include/walk_tree.h index 9f1ec34..b19ec23 100644 --- a/include/walk_tree.h +++ b/include/walk_tree.h @@ -25,6 +25,7 @@ #define WALK_TREE_LOGICAL 0x04 #define WALK_TREE_DEREFERENCE 0x08 #define WALK_TREE_DEREFERENCE_TOPLEVEL 0x10 +#define WALK_TREE_ONE_FILESYSTEM 0x20 #define WALK_TREE_TOPLEVEL 0x100 #define WALK_TREE_SYMLINK 0x200 diff --git a/libmisc/walk_tree.c b/libmisc/walk_tree.c index 47b2b25..e9a942f 100644 --- a/libmisc/walk_tree.c +++ b/libmisc/walk_tree.c @@ -49,6 +49,7 @@ struct walk_tree_args { struct entry_handle *closed; unsigned int num_dir_handles; struct stat st; + dev_t dev; }; static int walk_tree_visited(struct entry_handle *dirs, dev_t dev, ino_t ino) @@ -81,6 +82,14 @@ static int walk_tree_rec(struct walk_tree_args *args) if (lstat(args->path, &args->st) != 0) return args->func(args->path, NULL, flags | WALK_TREE_FAILED, args->arg); + + if (flags & WALK_TREE_ONE_FILESYSTEM) { + if (args->dev == 0) + args->dev = args->st.st_dev; + else if (args->st.st_dev != args->dev) + return 0; + } + if (S_ISLNK(args->st.st_mode)) { flags |= WALK_TREE_SYMLINK; if ((flags & WALK_TREE_DEREFERENCE) || @@ -244,6 +253,7 @@ int walk_tree(const char *path, int walk_flags, unsigned int num, args.func = func; args.arg = arg; args.depth = 0; + args.dev = 0; return walk_tree_rec(&args); } diff --git a/tools/getfattr.c b/tools/getfattr.c index 1c0ba21..abdd0d4 100644 --- a/tools/getfattr.c +++ b/tools/getfattr.c @@ -46,6 +46,7 @@ struct option long_options[] = { { "only-values", 0, 0, 'v' }, { "no-dereference", 0, 0, 'h' }, { "absolute-names", 0, 0, 'a' }, + { "one-file-system", 0, 0, 1 }, { "recursive", 0, 0, 'R' }, { "logical", 0, 0, 'L' }, { "physical", 0, 0, 'P' }, @@ -390,6 +391,7 @@ void help(void) " --match=pattern only get attributes with names matching pattern\n" " --only-values print the bare values only\n" " -h, --no-dereference do not dereference symbolic links\n" +" --one-file-system skip files on different filesystems\n" " --absolute-names don't strip leading '/' in pathnames\n" " -R, --recursive recurse into subdirectories\n" " -L, --logical logical walk, follow symbolic links\n" @@ -465,6 +467,10 @@ int main(int argc, char *argv[]) walk_flags |= WALK_TREE_RECURSIVE; break; + case 1: /* one filesystem */ + walk_flags |= WALK_TREE_ONE_FILESYSTEM; + break; + case 'V': printf("%s " VERSION "\n", progname); return 0; -- cgit v1.2.1