Merge pull request #25500 from DaanDeMeyer/mcopy-skip-symlinks

mkfs-util: Skip symlinks when calling mcopy
This commit is contained in:
Daan De Meyer
2022-11-24 16:28:01 +01:00
committed by GitHub
4 changed files with 41 additions and 13 deletions
+4 -4
View File
@@ -8,11 +8,11 @@
#include "stat-util.h"
#include "string-util.h"
static int dirent_ensure_type(DIR *d, struct dirent *de) {
int dirent_ensure_type(int dir_fd, struct dirent *de) {
STRUCT_STATX_DEFINE(sx);
int r;
assert(d);
assert(dir_fd >= 0);
assert(de);
if (de->d_type != DT_UNKNOWN)
@@ -24,7 +24,7 @@ static int dirent_ensure_type(DIR *d, struct dirent *de) {
}
/* Let's ask only for the type, nothing else. */
r = statx_fallback(dirfd(d), de->d_name, AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, STATX_TYPE, &sx);
r = statx_fallback(dir_fd, de->d_name, AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, STATX_TYPE, &sx);
if (r < 0)
return r;
@@ -80,7 +80,7 @@ struct dirent *readdir_ensure_type(DIR *d) {
if (!de)
return NULL;
r = dirent_ensure_type(d, de);
r = dirent_ensure_type(dirfd(d), de);
if (r >= 0)
return de;
if (r != -ENOENT) {
+1
View File
@@ -10,6 +10,7 @@
bool dirent_is_file(const struct dirent *de) _pure_;
bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) _pure_;
int dirent_ensure_type(int dir_fd, struct dirent *de);
struct dirent *readdir_ensure_type(DIR *d);
struct dirent *readdir_no_dot(DIR *dirp);
+18 -1
View File
@@ -33,6 +33,7 @@ int readdir_all(int dir_fd,
struct dirent *entry;
DirectoryEntries *nde;
size_t add, sz, j;
int r;
assert(dir_fd >= 0);
@@ -84,6 +85,15 @@ int readdir_all(int dir_fd,
if (ignore_dirent(entry, flags))
continue;
if (FLAGS_SET(flags, RECURSE_DIR_ENSURE_TYPE)) {
r = dirent_ensure_type(dir_fd, entry);
if (r == -ENOENT)
/* dentry gone by now? no problem, let's just suppress it */
continue;
if (r < 0)
return r;
}
de->n_entries++;
}
@@ -104,8 +114,14 @@ int readdir_all(int dir_fd,
if (ignore_dirent(entry, flags))
continue;
/* If d_type == DT_UNKNOWN that means we failed to ensure the type in the earlier loop and
* didn't include the dentry in de->n_entries and as such should skip it here as well. */
if (FLAGS_SET(flags, RECURSE_DIR_ENSURE_TYPE) && entry->d_type == DT_UNKNOWN)
continue;
de->entries[j++] = entry;
}
assert(j == de->n_entries);
if (FLAGS_SET(flags, RECURSE_DIR_SORT))
typesafe_qsort(de->entries, de->n_entries, sort_func);
@@ -160,7 +176,8 @@ int recurse_dir(
return r;
}
r = readdir_all(dir_fd, flags, &de);
/* Mask out RECURSE_DIR_ENSURE_TYPE so we can do it ourselves and avoid an extra statx() call. */
r = readdir_all(dir_fd, flags & ~RECURSE_DIR_ENSURE_TYPE, &de);
if (r < 0)
return r;