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

View File

@ -39,6 +39,7 @@ FileSystem::FileSystem(const MountConfiguration& configuration)
mutex_init(&fOpenOwnerLock, NULL);
mutex_init(&fOpenLock, NULL);
mutex_init(&fDelegationLock, NULL);
mutex_init(&fCreateFileLock, NULL);
}
@ -51,6 +52,7 @@ FileSystem::~FileSystem()
mutex_destroy(&fDelegationLock);
mutex_destroy(&fOpenLock);
mutex_destroy(&fOpenOwnerLock);
mutex_destroy(&fCreateFileLock);
free(const_cast<char*>(fPath));
delete fRoot;

View File

@ -74,9 +74,12 @@ public:
inline const MountConfiguration& GetConfiguration();
inline mutex& CreateFileLock();
private:
FileSystem(const MountConfiguration& config);
mutex fCreateFileLock;
mutex fDelegationLock;
DoublyLinkedList<Delegation> fDelegationList;
AVLTreeMap<FileHandle, Delegation*> fHandleToDelegation;
@ -233,5 +236,12 @@ FileSystem::GetConfiguration()
}
inline mutex&
FileSystem::CreateFileLock()
{
return fCreateFileLock;
}
#endif // FILESYSTEM_H

View File

@ -221,7 +221,6 @@ inline void
Inode::SetOpenState(OpenState* state)
{
ASSERT(state != NULL);
MutexLocker _(fStateLock);
fOpenState = state;
}

View File

@ -76,20 +76,15 @@ Inode::Create(const char* name, int mode, int perms, OpenFileCookie* cookie,
cookie->fMode = mode;
cookie->fLocks = NULL;
MutexLocker _(fStateLock);
OpenState* state = new OpenState;
status_t result = CreateState(name, mode, perms, state, data);
if (result != B_OK)
return result;
cookie->fOpenState = state;
fOpenState = state;
cookie->fFileSystem = fFileSystem;
*id = FileIdToInoT(state->fInfo.fFileId);
cookie->fOpenState = fOpenState;
cookie->fFileSystem = fFileSystem;
fFileSystem->AddOpenFile(state);
fFileSystem->Root()->MakeInfoInvalid();
@ -125,9 +120,11 @@ Inode::Open(int mode, OpenFileCookie* cookie)
fFileSystem->AddOpenFile(state);
fOpenState = state;
cookie->fOpenState = state;
locker.Unlock();
} else {
fOpenState->AcquireReference();
cookie->fOpenState = fOpenState;
locker.Unlock();
int newMode = mode & O_RWMASK;
@ -167,8 +164,6 @@ Inode::Open(int mode, OpenFileCookie* cookie)
file_cache_set_size(fFileCache, 0);
}
cookie->fOpenState = fOpenState;
cookie->fFileSystem = fFileSystem;
cookie->fMode = mode;
cookie->fLocks = NULL;

View File

@ -743,6 +743,9 @@ nfs4_create(fs_volume* volume, fs_vnode* dir, const char* name, int openMode,
if (inode == NULL)
return B_ENTRY_NOT_FOUND;
FileSystem* fs = reinterpret_cast<FileSystem*>(volume->private_volume);
MutexLocker createLocker(fs->CreateFileLock());
OpenDelegationData data;
status_t result = inode->Create(name, openMode, perms, cookie, &data,
_newVnodeID);