//! Busy mount teardown and generation-change guest probe. use super::*; use os_vfs_unmount::{Error, Kind, Mount}; pub fn run(allocator: &mut memory::FrameAllocator) -> Result<(), &'static str> { let frames_before = allocator.remaining_pages(); let mut mount = Mount::new(2, 7).map_err(|_| "k1600-new")?; let old = mount.token(); let open = mount.acquire(Kind::Open).map_err(|_| "k1600-open")?; let lookup = mount.acquire(Kind::Lookup).map_err(|_| "k1600-lookup")?; let pin = mount.acquire(Kind::CachePin).map_err(|_| "k1600-pin")?; let before_all = mount; if mount.unmount() != Err(Error::Busy) || mount != before_all { return Err("k1600-all-busy"); } write_line("TURKOS/OS/K1600-MOUNT: OPEN-LOOKUP=BUSY"); mount.release(open).map_err(|_| "k1600-release-open")?; mount.release(lookup).map_err(|_| "k1600-release-lookup")?; let before_pin = mount; if mount.unmount() != Err(Error::Busy) || mount != before_pin { return Err("k1600-pin-busy"); } write_line("TURKOS/OS/K1600-MOUNT: CACHE-PIN=BUSY"); mount.release(pin).map_err(|_| "k1600-release-pin")?; if mount.unmount() != Ok(8) || mount.mounted() { return Err("k1600-unmount"); } write_line("TURKOS/OS/K1600-MOUNT: UNMOUNT=GEN8"); if mount.validate(old) != Err(Error::Stale) || mount.release(pin) != Err(Error::Stale) || mount.remount().map(|token| token.generation()) != Ok(8) || mount.validate(old) != Err(Error::Stale) || mount.validate(mount.token()) != Ok(()) { return Err("k1600-stale"); } write_line("TURKOS/OS/K1600-MOUNT: STALE=REJECTED"); let mut terminal = Mount::new(3, u64::MAX) .map_err(|_| "k1600-terminal")?; let before_overflow = terminal; if terminal.unmount() != Err(Error::Overflow) || terminal != before_overflow || allocator.remaining_pages() != frames_before { return Err("k1600-overflow"); } write_line("TURKOS/OS/K1600-MOUNT: OVERFLOW=UNCHANGED FRAMES=UNCHANGED"); Ok(()) }