]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commitdiff
vfs: add cwd check to umount to prevent filesystem in use
authorTulio A M Mendes <[email protected]>
Tue, 26 May 2026 02:20:43 +0000 (23:20 -0300)
committerTulio A M Mendes <[email protected]>
Wed, 3 Jun 2026 04:02:35 +0000 (01:02 -0300)
Added busy check in vfs_umount_nolock to reject unmount if any process
has its current working directory (cwd) within the mount being unmounted.

Implementation details:
- Iterates over ready_queue_head under sched_lock
- Uses path_is_mountpoint_prefix to check if cwd is within mount
- Returns -EBUSY if any process has cwd in the mount
- Note: root directory check not implemented (root not stored as path in process struct)

This prevents crashes when processes attempt to access files after
their cwd filesystem has been unmounted.

Test results:
- Smoke test: 123/123 PASS
- Zero regressions

src/kernel/fs.c

index e75db37a5099edb16104c6f75872b0ac9386ad72..493d4679ef6eecd366d2cf0dc253cbfb332d0c52 100644 (file)
@@ -180,6 +180,26 @@ int vfs_umount_nolock(const char* mountpoint) {
         }
     }
 
+    /* Busy check: reject if any process has cwd or root in this mount */
+    extern struct process* ready_queue_head;
+    extern spinlock_t sched_lock;
+    
+    uintptr_t sched_fl = spin_lock_irqsave(&sched_lock);
+    struct process* p = ready_queue_head;
+    while (p) {
+        /* Check if cwd is within this mount */
+        if (p->cwd[0] && path_is_mountpoint_prefix(mp, p->cwd)) {
+            spin_unlock_irqrestore(&sched_lock, sched_fl);
+            return -EBUSY;
+        }
+        /* Check if root is within this mount (if different from cwd) */
+        /* Note: root is not stored as a path in current process struct,
+         * so we only check cwd for now. A full implementation would require
+         * storing root as a path or implementing vfs_getpath. */
+        p = p->rq_next;
+    }
+    spin_unlock_irqrestore(&sched_lock, sched_fl);
+
     /* Release the block device */
     if (g_mounts[idx].bdev) {
         blockdev_release(g_mounts[idx].bdev);