Merge pull request #25315 from poettering/dissect-mtree
dissect: add new --mtree switch to generate BSD comaptible mtree manifests of DDIs
This commit is contained in:
+35
-1
@@ -126,6 +126,7 @@ int recurse_dir(
|
||||
void *userdata) {
|
||||
|
||||
_cleanup_free_ DirectoryEntries *de = NULL;
|
||||
STRUCT_STATX_DEFINE(root_sx);
|
||||
int r;
|
||||
|
||||
assert(dir_fd >= 0);
|
||||
@@ -139,6 +140,26 @@ int recurse_dir(
|
||||
if (n_depth_max == UINT_MAX) /* special marker for "default" */
|
||||
n_depth_max = DEFAULT_RECURSION_MAX;
|
||||
|
||||
if (FLAGS_SET(flags, RECURSE_DIR_TOPLEVEL)) {
|
||||
if (statx_mask != 0) {
|
||||
r = statx_fallback(dir_fd, "", AT_EMPTY_PATH, statx_mask, &root_sx);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = func(RECURSE_DIR_ENTER,
|
||||
path,
|
||||
-1, /* we have no parent fd */
|
||||
dir_fd,
|
||||
NULL, /* we have no dirent */
|
||||
statx_mask != 0 ? &root_sx : NULL,
|
||||
userdata);
|
||||
if (IN_SET(r, RECURSE_DIR_LEAVE_DIRECTORY, RECURSE_DIR_SKIP_ENTRY))
|
||||
return 0;
|
||||
if (r != RECURSE_DIR_CONTINUE)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = readdir_all(dir_fd, flags, &de);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@@ -397,7 +418,7 @@ int recurse_dir(
|
||||
p,
|
||||
statx_mask,
|
||||
n_depth_max - 1,
|
||||
flags,
|
||||
flags &~ RECURSE_DIR_TOPLEVEL, /* we already called the callback for this entry */
|
||||
func,
|
||||
userdata);
|
||||
if (r != 0)
|
||||
@@ -427,6 +448,19 @@ int recurse_dir(
|
||||
return r;
|
||||
}
|
||||
|
||||
if (FLAGS_SET(flags, RECURSE_DIR_TOPLEVEL)) {
|
||||
|
||||
r = func(RECURSE_DIR_LEAVE,
|
||||
path,
|
||||
-1,
|
||||
dir_fd,
|
||||
NULL,
|
||||
statx_mask != 0 ? &root_sx : NULL,
|
||||
userdata);
|
||||
if (!IN_SET(r, RECURSE_DIR_LEAVE_DIRECTORY, RECURSE_DIR_SKIP_ENTRY, RECURSE_DIR_CONTINUE))
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,7 @@ typedef enum RecurseDirFlags {
|
||||
RECURSE_DIR_ENSURE_TYPE = 1 << 2, /* guarantees that 'd_type' field of 'de' is not DT_UNKNOWN */
|
||||
RECURSE_DIR_SAME_MOUNT = 1 << 3, /* skips over subdirectories that are submounts */
|
||||
RECURSE_DIR_INODE_FD = 1 << 4, /* passes an opened inode fd (O_DIRECTORY fd in case of dirs, O_PATH otherwise) */
|
||||
RECURSE_DIR_TOPLEVEL = 1 << 5, /* call RECURSE_DIR_ENTER/RECURSE_DIR_LEAVE once for top-level dir, too, with dir_fd=-1 and NULL dirent */
|
||||
} RecurseDirFlags;
|
||||
|
||||
typedef struct DirectoryEntries {
|
||||
|
||||
Reference in New Issue
Block a user