From 35f1480e2aeeb0fb30df7f770ebf3209c2e2d76d Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Mon, 15 Mar 2004 02:52:55 +0000 Subject: [PATCH] fix mounting a directory unmounts all other FS's mounted on the same mountpoint; only unmount if there's a mount that has the exact same mountpoint, root and driver --- stepmania/src/RageFileManager.cpp | 73 +++++++++++++++++-------------- stepmania/src/RageFileManager.h | 2 +- 2 files changed, 42 insertions(+), 33 deletions(-) diff --git a/stepmania/src/RageFileManager.cpp b/stepmania/src/RageFileManager.cpp index 51655f8113..fea6662bae 100644 --- a/stepmania/src/RageFileManager.cpp +++ b/stepmania/src/RageFileManager.cpp @@ -20,6 +20,25 @@ static RageMutex *g_Mutex; CString InitialWorkingDirectory; CString DirOfExecutable; +typedef map< const RageFileObj *, RageFileDriver * > FileReferences; +static FileReferences g_Refs; + +struct LoadedDriver +{ + /* A loaded driver may have a base path, which modifies the path we + * pass to the driver. For example, if the base is "Songs/", and we + * want to send the path "Songs/Foo/Bar" to it, then we actually + * only send "Foo/Bar". The path "Themes/Foo" is out of the scope + * of the driver, and GetPath returns false. */ + RageFileDriver *driver; + CString Type, Root, MountPoint; + + LoadedDriver() { driver = NULL; } + CString GetPath( CString path ); +}; + +static vector g_Drivers; + // Mountpoints as directories cause a problem. If "Themes/default" is a mountpoint, and // doesn't exist anywhere else, then GetDirListing("Themes/*") must return "default". The // driver containing "Themes/default" won't do this; its world view begins at "BGAnimations" @@ -33,37 +52,18 @@ public: err = (mode == RageFile::WRITE)? EINVAL:ENOENT; return NULL; } + /* Never flush FDB, except in LoadFromDrivers. */ void FlushDirCache( const CString &sPath ) { } - void Add( const CString &MountPoint ) + + void LoadFromDrivers( const vector &drivers ) { - FDB->AddFile( MountPoint, 0, 0 ); - } - void Delete( const CString &MountPoint ) - { - FDB->DelFile( MountPoint ); + FDB->FlushDirCache(); + for( unsigned i = 0; i < drivers.size(); ++i ) + FDB->AddFile( drivers[i].MountPoint, 0, 0 ); } }; static RageFileDriverMountpoints *g_Mountpoints = NULL; -typedef map< const RageFileObj *, RageFileDriver * > FileReferences; -static FileReferences g_Refs; - -struct LoadedDriver -{ - /* A loaded driver may have a base path, which modifies the path we - * pass to the driver. For example, if the base is "Songs/", and we - * want to send the path "Songs/Foo/Bar" to it, then we actually - * only send "Foo/Bar". The path "Themes/Foo" is out of the scope - * of the driver, and GetPath returns false. */ - RageFileDriver *driver; - CString MountPoint; - - LoadedDriver() { driver = NULL; } - CString GetPath( CString path ); -}; - -static vector g_Drivers; - static void ChangeToDirOfExecutable( CString argv0 ) { @@ -281,8 +281,8 @@ void RageFileManager::Mount( CString Type, CString Root, CString MountPoint ) { LockMut( *g_Mutex ); - // unmount anything that was previously mounted here. - Unmount(MountPoint); + // Unmount anything that was previously mounted here. + Unmount( Type, Root, MountPoint ); if( MountPoint.size() && MountPoint.Right(1) != "/" ) MountPoint += '/'; @@ -298,21 +298,30 @@ void RageFileManager::Mount( CString Type, CString Root, CString MountPoint ) LoadedDriver ld; ld.driver = driver; + ld.Type = Type; + ld.Root = Root; ld.MountPoint = MountPoint; g_Drivers.push_back( ld ); - g_Mountpoints->Add( MountPoint ); + g_Mountpoints->LoadFromDrivers( g_Drivers ); } -void RageFileManager::Unmount( CString MountPoint ) +void RageFileManager::Unmount( CString Type, CString Root, CString MountPoint ) { LockMut( *g_Mutex ); for( unsigned i = 0; i < g_Drivers.size(); ++i ) - if( !g_Drivers[i].MountPoint.CompareNoCase( MountPoint ) ) - g_Drivers.erase( g_Drivers.begin()+i ); + { + if( g_Drivers[i].Type.CompareNoCase( Type ) ) + continue; + if( g_Drivers[i].Root.CompareNoCase( Root ) ) + continue; + if( g_Drivers[i].MountPoint.CompareNoCase( MountPoint ) ) + continue; + g_Drivers.erase( g_Drivers.begin()+i ); + } - g_Mountpoints->Delete( MountPoint ); + g_Mountpoints->LoadFromDrivers( g_Drivers ); } bool RageFileManager::IsMounted( CString MountPoint ) diff --git a/stepmania/src/RageFileManager.h b/stepmania/src/RageFileManager.h index 7c0050654e..42b15f1c26 100644 --- a/stepmania/src/RageFileManager.h +++ b/stepmania/src/RageFileManager.h @@ -28,7 +28,7 @@ public: int GetFileHash( const CString &sPath ); void Mount( CString Type, CString RealPath, CString MountPoint ); - void Unmount( CString MountPoint ); + void Unmount( CString Type, CString Root, CString MountPoint ); bool IsMounted( CString MountPoint ); bool MountpointIsReady( CString MountPoint );