nfs4: Fix few Inode::fOpenState related race conditions

This commit is contained in:
Pawel Dziepak
2013-01-17 00:42:13 +01:00
parent 65edbee7c8
commit ce851e2bac
5 changed files with 18 additions and 9 deletions
@@ -39,6 +39,7 @@ FileSystem::FileSystem(const MountConfiguration& configuration)
mutex_init(&fOpenOwnerLock, NULL); mutex_init(&fOpenOwnerLock, NULL);
mutex_init(&fOpenLock, NULL); mutex_init(&fOpenLock, NULL);
mutex_init(&fDelegationLock, NULL); mutex_init(&fDelegationLock, NULL);
mutex_init(&fCreateFileLock, NULL);
} }
@@ -51,6 +52,7 @@ FileSystem::~FileSystem()
mutex_destroy(&fDelegationLock); mutex_destroy(&fDelegationLock);
mutex_destroy(&fOpenLock); mutex_destroy(&fOpenLock);
mutex_destroy(&fOpenOwnerLock); mutex_destroy(&fOpenOwnerLock);
mutex_destroy(&fCreateFileLock);
free(const_cast<char*>(fPath)); free(const_cast<char*>(fPath));
delete fRoot; delete fRoot;
@@ -74,9 +74,12 @@ public:
inline const MountConfiguration& GetConfiguration(); inline const MountConfiguration& GetConfiguration();
inline mutex& CreateFileLock();
private: private:
FileSystem(const MountConfiguration& config); FileSystem(const MountConfiguration& config);
mutex fCreateFileLock;
mutex fDelegationLock; mutex fDelegationLock;
DoublyLinkedList<Delegation> fDelegationList; DoublyLinkedList<Delegation> fDelegationList;
AVLTreeMap<FileHandle, Delegation*> fHandleToDelegation; AVLTreeMap<FileHandle, Delegation*> fHandleToDelegation;
@@ -233,5 +236,12 @@ FileSystem::GetConfiguration()
} }
inline mutex&
FileSystem::CreateFileLock()
{
return fCreateFileLock;
}
#endif // FILESYSTEM_H #endif // FILESYSTEM_H
@@ -221,7 +221,6 @@ inline void
Inode::SetOpenState(OpenState* state) Inode::SetOpenState(OpenState* state)
{ {
ASSERT(state != NULL); ASSERT(state != NULL);
MutexLocker _(fStateLock);
fOpenState = state; fOpenState = state;
} }
@@ -76,20 +76,15 @@ Inode::Create(const char* name, int mode, int perms, OpenFileCookie* cookie,
cookie->fMode = mode; cookie->fMode = mode;
cookie->fLocks = NULL; cookie->fLocks = NULL;
MutexLocker _(fStateLock);
OpenState* state = new OpenState; OpenState* state = new OpenState;
status_t result = CreateState(name, mode, perms, state, data); status_t result = CreateState(name, mode, perms, state, data);
if (result != B_OK) if (result != B_OK)
return result; return result;
cookie->fOpenState = state; cookie->fOpenState = state;
fOpenState = state; cookie->fFileSystem = fFileSystem;
*id = FileIdToInoT(state->fInfo.fFileId); *id = FileIdToInoT(state->fInfo.fFileId);
cookie->fOpenState = fOpenState;
cookie->fFileSystem = fFileSystem;
fFileSystem->AddOpenFile(state); fFileSystem->AddOpenFile(state);
fFileSystem->Root()->MakeInfoInvalid(); fFileSystem->Root()->MakeInfoInvalid();
@@ -125,9 +120,11 @@ Inode::Open(int mode, OpenFileCookie* cookie)
fFileSystem->AddOpenFile(state); fFileSystem->AddOpenFile(state);
fOpenState = state; fOpenState = state;
cookie->fOpenState = state;
locker.Unlock(); locker.Unlock();
} else { } else {
fOpenState->AcquireReference(); fOpenState->AcquireReference();
cookie->fOpenState = fOpenState;
locker.Unlock(); locker.Unlock();
int newMode = mode & O_RWMASK; int newMode = mode & O_RWMASK;
@@ -167,8 +164,6 @@ Inode::Open(int mode, OpenFileCookie* cookie)
file_cache_set_size(fFileCache, 0); file_cache_set_size(fFileCache, 0);
} }
cookie->fOpenState = fOpenState;
cookie->fFileSystem = fFileSystem; cookie->fFileSystem = fFileSystem;
cookie->fMode = mode; cookie->fMode = mode;
cookie->fLocks = NULL; cookie->fLocks = NULL;
@@ -743,6 +743,9 @@ nfs4_create(fs_volume* volume, fs_vnode* dir, const char* name, int openMode,
if (inode == NULL) if (inode == NULL)
return B_ENTRY_NOT_FOUND; return B_ENTRY_NOT_FOUND;
FileSystem* fs = reinterpret_cast<FileSystem*>(volume->private_volume);
MutexLocker createLocker(fs->CreateFileLock());
OpenDelegationData data; OpenDelegationData data;
status_t result = inode->Create(name, openMode, perms, cookie, &data, status_t result = inode->Create(name, openMode, perms, cookie, &data,
_newVnodeID); _newVnodeID);