]> Projects (at) Tadryanom (dot) Me - AdrOS.git/commit
diskfs: fix LBA space leak on unlink/rmdir + add spinlock protection + ATA DMA irqsave
authorTulio A M Mendes <[email protected]>
Fri, 17 Apr 2026 21:08:02 +0000 (18:08 -0300)
committerTulio A M Mendes <[email protected]>
Fri, 17 Apr 2026 21:08:02 +0000 (18:08 -0300)
commitf16a76efc1de90ff4f71c970d7d4e0e42bb6ba7b
tree66b1afe96983ba715b22b2d353682acf6e00f27e
parent82b0e298922a0d51cca2cd7c231b4ed9fd222171
diskfs: fix LBA space leak on unlink/rmdir + add spinlock protection + ATA DMA irqsave

Root cause: diskfs_unlink and diskfs_rmdir zeroed freed inodes but
never reclaimed LBA space -- next_free_lba only grew, never shrank.
After many test runs, next_free_lba exceeded the 8192-sector disk,
causing ata_pio_read28 to fail with -EIO on out-of-range LBAs,
making writes to newly created files fail silently.

Fixes:
- Add diskfs_reclaim_space() that recalculates next_free_lba by
  scanning all inodes for the highest used LBA extent. Called from
  both diskfs_unlink and diskfs_rmdir after freeing an inode.
- Add g_diskfs_lock spinlock with irqsave/irqrestore variants
  protecting all superblock load/modify/store operations across all
  diskfs functions. All early returns properly unlock.
- Restructure diskfs_read_impl and diskfs_write_impl to cache inode
  metadata under lock, then release before sector I/O, avoiding long
  interrupt-disabled periods that could cause deadlocks/timeouts.
- Replace spin_lock/spin_unlock with spin_lock_irqsave/spin_unlock_
  irqrestore in all 4 ATA DMA channel functions to prevent deadlocks
  from timer interrupts during lock hold.

Test results: 103/103 PASS (3 consecutive runs, SMP=4),
16/16 battery PASS, 69/69 host PASS.
src/hal/x86/ata_dma.c
src/kernel/diskfs.c