+int VFS_Unmount(const char *Mountpoint)
+{
+ tVFS_Mount *mount, *prev = NULL;
+ RWLock_AcquireWrite( &glVFS_MountList );
+ for( mount = gVFS_Mounts; mount; prev = mount, mount = mount->Next )
+ {
+ if( strcmp(Mountpoint, mount->MountPoint) == 0 ) {
+ if( mount->OpenHandleCount ) {
+ LOG("Mountpoint busy");
+ RWLock_Release(&glVFS_MountList);
+ return EBUSY;
+ }
+ if(prev)
+ prev->Next = mount->Next;
+ else
+ gVFS_Mounts = mount->Next;
+ break;
+ }
+ }
+ RWLock_Release( &glVFS_MountList );
+ if( !mount ) {
+ LOG("Mountpoint not found");
+ return ENOENT;
+ }
+
+ Log_Warning("VFS", "TODO: Impliment unmount");
+
+ // Decrease the open handle count for the mountpoint filesystem.
+ tVFS_Mount *mpmnt;
+ tVFS_Node *mpnode = VFS_ParsePath(mount->MountPoint, NULL, &mpmnt);
+ if(mpnode)
+ {
+ mpmnt->OpenHandleCount -= 2; // -1 for _ParsePath here, -1 for in _Mount
+ }
+
+ mount->Filesystem->Unmount( mount->RootNode );
+ free(mount);
+
+ return EOK;
+}
+
+int VFS_UnmountAll(void)
+{
+ int nUnmounted = 0;
+ tVFS_Mount *mount, *prev = NULL, *next;
+
+ RWLock_AcquireWrite( &glVFS_MountList );
+ // If we've unmounted the final filesystem, all good
+ if( gVFS_Mounts == NULL) {
+ RWLock_Release( &glVFS_MountList );
+ return -1;
+ }
+
+ for( mount = gVFS_Mounts; mount; prev = mount, mount = next )
+ {
+ next = mount->Next;
+ // Can't unmount stuff with open handles
+ if( mount->OpenHandleCount > 0 ) {
+ LOG("%p (%s) has open handles (%i of them)",
+ mount, mount->MountPoint, mount->OpenHandleCount);
+ continue;
+ }
+
+ if(prev)
+ prev->Next = mount->Next;
+ else
+ gVFS_Mounts = mount->Next;
+
+ if( mount->Filesystem->Unmount ) {
+ mount->Filesystem->Unmount( mount->RootNode );
+ }
+ else {
+ Log_Error("VFS", "%s (%s) does not have an unmount method, not calling it",
+ mount->MountPoint, mount->Filesystem->Name);
+ }
+ free(mount);
+ mount = prev;
+ nUnmounted ++;
+ }
+ RWLock_Release( &glVFS_MountList );
+
+ return nUnmounted;
+}
+