]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
mount-util: Iterate mountinfo backwards when unmounting
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Tue, 28 Oct 2025 21:54:14 +0000 (22:54 +0100)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Wed, 29 Oct 2025 11:01:32 +0000 (12:01 +0100)
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.

src/fstab-generator/fstab-generator.c
src/shared/libmount-util.c
src/shared/libmount-util.h
src/shared/mount-util.c

index 4165cf4680f6d0bb714ee739d737a63658d385e6..3c26e6489653a8e8b49afe33b31ef9e156dd919a 100644 (file)
@@ -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);
 
index 126ed948af551757b51ccdf0bd1ea27585a8e1e5..c6c6074c2595335f4fe2b2691dbef63c47d3ab87 100644 (file)
@@ -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(
index f7fc39cd9bd8f017500f4dba18a4daa39e1d3b5d..15921a2f42f742ad841ea4599d9e15547c1653ea 100644 (file)
@@ -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);
index c6d1373caf1ec9043afda80696e898eff9bc99dc..dcdc42b00ae855aa431b29c241405850d29ef86d 100644 (file)
@@ -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");