nfs4: Fix few Inode::fOpenState related race conditions
This commit is contained in:
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user