From: Daan De Meyer Date: Tue, 28 Oct 2025 21:54:14 +0000 (+0100) Subject: mount-util: Iterate mountinfo backwards when unmounting X-Git-Tag: v259-rc1~231 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=2988bba60f5636c5bdd37a336bb977424e84c9ea;p=thirdparty%2Fsystemd.git mount-util: Iterate mountinfo backwards when unmounting Submounts will always be located further in the mountinfo file, so when we're unmounting, iterating backwards is likely to be more efficient than iterating forwards. It'll also reduce the amount of EBUSY debug logging we'll get since we'll stop trying to unmount parent mounts with submounts which will always fail with EBUSY. --- diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c index 4165cf4680f..3c26e648965 100644 --- a/src/fstab-generator/fstab-generator.c +++ b/src/fstab-generator/fstab-generator.c @@ -1039,7 +1039,7 @@ static int parse_fstab(bool prefix_sysroot) { log_debug("Parsing %s...", fstab); - r = libmount_parse_full(fstab, /* source = */ NULL, &table, &iter); + r = libmount_parse_full(fstab, /* source = */ NULL, MNT_ITER_FORWARD, &table, &iter); if (r == -ENOENT) return 0; if (r < 0) @@ -1442,7 +1442,7 @@ static int add_mounts_from_creds(bool prefix_sysroot) { _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL; _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL; - r = libmount_parse_full(cred, f, &table, &iter); + r = libmount_parse_full(cred, f, MNT_ITER_FORWARD, &table, &iter); if (r < 0) return log_error_errno(r, "Failed to parse credential '%s' (as fstab): %m", cred); diff --git a/src/shared/libmount-util.c b/src/shared/libmount-util.c index 126ed948af5..c6c6074c259 100644 --- a/src/shared/libmount-util.c +++ b/src/shared/libmount-util.c @@ -86,6 +86,7 @@ int dlopen_libmount(void) { int libmount_parse_full( const char *path, FILE *source, + int direction, struct libmnt_table **ret_table, struct libmnt_iter **ret_iter) { @@ -95,13 +96,14 @@ int libmount_parse_full( /* Older libmount seems to require this. */ assert(!source || path); + assert(IN_SET(direction, MNT_ITER_FORWARD, MNT_ITER_BACKWARD)); r = dlopen_libmount(); if (r < 0) return r; table = sym_mnt_new_table(); - iter = sym_mnt_new_iter(MNT_ITER_FORWARD); + iter = sym_mnt_new_iter(direction); if (!table || !iter) return -ENOMEM; @@ -126,7 +128,7 @@ int libmount_parse_fstab( struct libmnt_table **ret_table, struct libmnt_iter **ret_iter) { - return libmount_parse_full(fstab_path(), NULL, ret_table, ret_iter); + return libmount_parse_full(fstab_path(), NULL, MNT_ITER_FORWARD, ret_table, ret_iter); } int libmount_is_leaf( diff --git a/src/shared/libmount-util.h b/src/shared/libmount-util.h index f7fc39cd9bd..15921a2f42f 100644 --- a/src/shared/libmount-util.h +++ b/src/shared/libmount-util.h @@ -47,6 +47,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(struct libmnt_iter*, sym_mnt_free_iter, int libmount_parse_full( const char *path, FILE *source, + int direction, struct libmnt_table **ret_table, struct libmnt_iter **ret_iter); @@ -55,14 +56,14 @@ static inline int libmount_parse_mountinfo( struct libmnt_table **ret_table, struct libmnt_iter **ret_iter) { - return libmount_parse_full("/proc/self/mountinfo", source, ret_table, ret_iter); + return libmount_parse_full("/proc/self/mountinfo", source, MNT_ITER_FORWARD, ret_table, ret_iter); } static inline int libmount_parse_with_utab( struct libmnt_table **ret_table, struct libmnt_iter **ret_iter) { - return libmount_parse_full(NULL, NULL, ret_table, ret_iter); + return libmount_parse_full(NULL, NULL, MNT_ITER_FORWARD, ret_table, ret_iter); } int libmount_parse_fstab(struct libmnt_table **ret_table, struct libmnt_iter **ret_iter); diff --git a/src/shared/mount-util.c b/src/shared/mount-util.c index c6d1373caf1..dcdc42b00ae 100644 --- a/src/shared/mount-util.c +++ b/src/shared/mount-util.c @@ -52,7 +52,7 @@ int umount_recursive_full(const char *prefix, int flags, char **keep) { _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL; bool again = false; - r = libmount_parse_mountinfo(f, &table, &iter); + r = libmount_parse_full("/proc/self/mountinfo", f, MNT_ITER_BACKWARD, &table, &iter); if (r < 0) return log_debug_errno(r, "Failed to parse /proc/self/mountinfo: %m");