]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
overlayfs: improve wrapper lifetime management with root refcount
authorTulio A M Mendes <[email protected]>
Thu, 11 Jun 2026 02:14:05 +0000 (23:14 -0300)
committerTulio A M Mendes <[email protected]>
Thu, 11 Jun 2026 02:14:05 +0000 (23:14 -0300)
Implement M6: overlayfs wrapper lifetime improvements.

Added is_root flag to overlay_node to distinguish root from wrapper nodes.
Modified overlay_root_close() to properly manage root node refcount and
free overlayfs structure when root is finally closed.
Initialized root node refcount to 1 and set is_root flag in overlayfs_create_root().

This ensures proper cleanup of overlayfs structures when the filesystem
is unmounted, preventing memory leaks of the overlayfs structure and root node.

Test: make test-battery PASS (157/157), make analyzer PASS

src/kernel/overlayfs.c

index de459466aab89cf188f40649ae1b6e99b277750d..8c371fab0c16d2871d79659a6e49b06d7da04864 100644 (file)
@@ -29,7 +29,8 @@ struct overlay_node {
     fs_node_t* upper;
 
     char path[256];
-    int refcount;  /* For wrapper nodes allocated by overlay_wrap_child */
+    int refcount;  /* For wrapper nodes and root node */
+    int is_root;   /* M6: Flag to identify root node for cleanup */
 };
 
 static struct fs_node* overlay_finddir_impl(struct fs_node* node, const char* name);
@@ -110,7 +111,18 @@ static const struct file_operations overlay_file_ops = {
 };
 
 static void overlay_root_close(fs_node_t* node) {
-    (void)node;
+    if (!node) return;
+    struct overlay_node* on = (struct overlay_node*)node;
+    /* M6: Root node also uses refcount for proper lifetime management */
+    on->refcount--;
+    if (on->refcount <= 0 && on->is_root) {
+        /* M6: Free overlayfs structure when root is finally closed */
+        if (on->ofs) {
+            kfree(on->ofs);
+            on->ofs = NULL;
+        }
+        kfree(on);
+    }
 }
 
 static const struct file_operations overlay_root_ops = {
@@ -354,5 +366,9 @@ fs_node_t* overlayfs_create_root(fs_node_t* lower_root, fs_node_t* upper_root) {
 
     root->path[0] = 0;
 
+    /* M6: Initialize refcount and mark as root for proper lifetime management */
+    root->refcount = 1;
+    root->is_root = 1;
+
     return &root->vfs;
 }