nfs4: Fix write commit race condition
This commit is contained in:
@@ -37,6 +37,7 @@ Inode::Inode()
|
|||||||
rw_lock_init(&fDelegationLock, NULL);
|
rw_lock_init(&fDelegationLock, NULL);
|
||||||
mutex_init(&fStateLock, NULL);
|
mutex_init(&fStateLock, NULL);
|
||||||
mutex_init(&fFileCacheLock, NULL);
|
mutex_init(&fFileCacheLock, NULL);
|
||||||
|
rw_lock_init(&fWriteLock, NULL);
|
||||||
mutex_init(&fAIOLock, NULL);
|
mutex_init(&fAIOLock, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,6 +148,7 @@ Inode::~Inode()
|
|||||||
mutex_destroy(&fStateLock);
|
mutex_destroy(&fStateLock);
|
||||||
mutex_destroy(&fFileCacheLock);
|
mutex_destroy(&fFileCacheLock);
|
||||||
rw_lock_destroy(&fDelegationLock);
|
rw_lock_destroy(&fDelegationLock);
|
||||||
|
rw_lock_destroy(&fWriteLock);
|
||||||
|
|
||||||
ASSERT(fAIOCount == 0);
|
ASSERT(fAIOCount == 0);
|
||||||
}
|
}
|
||||||
@@ -938,8 +940,10 @@ Inode::ReleaseOpenState()
|
|||||||
{
|
{
|
||||||
ASSERT(fOpenState != NULL);
|
ASSERT(fOpenState != NULL);
|
||||||
|
|
||||||
if (fOpenState->ReleaseReference() == 1)
|
if (fOpenState->ReleaseReference() == 1) {
|
||||||
|
ASSERT(fAIOCount == 0);
|
||||||
fOpenState = NULL;
|
fOpenState = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -161,6 +161,7 @@ private:
|
|||||||
OpenState* fOpenState;
|
OpenState* fOpenState;
|
||||||
mutex fStateLock;
|
mutex fStateLock;
|
||||||
|
|
||||||
|
rw_lock fWriteLock;
|
||||||
bool fWriteDirty;
|
bool fWriteDirty;
|
||||||
|
|
||||||
sem_id fAIOWait;
|
sem_id fAIOWait;
|
||||||
|
|||||||
@@ -36,8 +36,6 @@ Inode::CreateState(const char* name, int mode, int perms, OpenState* state,
|
|||||||
if (result != B_OK)
|
if (result != B_OK)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
RevalidateFileCache();
|
|
||||||
|
|
||||||
FileInfo fi;
|
FileInfo fi;
|
||||||
fi.fFileId = fileID;
|
fi.fFileId = fileID;
|
||||||
fi.fHandle = handle;
|
fi.fHandle = handle;
|
||||||
@@ -186,6 +184,7 @@ status_t
|
|||||||
Inode::Close(OpenFileCookie* cookie)
|
Inode::Close(OpenFileCookie* cookie)
|
||||||
{
|
{
|
||||||
ASSERT(cookie != NULL);
|
ASSERT(cookie != NULL);
|
||||||
|
ASSERT(fOpenState == cookie->fOpenState);
|
||||||
|
|
||||||
SyncAndCommit();
|
SyncAndCommit();
|
||||||
|
|
||||||
@@ -371,8 +370,10 @@ Inode::WriteDirect(OpenStateCookie* cookie, off_t pos, const void* _buffer,
|
|||||||
state = cookie->fOpenState;
|
state = cookie->fOpenState;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!attribute)
|
if (!attribute) {
|
||||||
|
ReadLocker _(fWriteLock);
|
||||||
fWriteDirty = true;
|
fWriteDirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
while (size < *_length) {
|
while (size < *_length) {
|
||||||
uint32 len = *_length - size;
|
uint32 len = *_length - size;
|
||||||
@@ -432,6 +433,8 @@ Inode::Write(OpenFileCookie* cookie, off_t pos, const void* _buffer,
|
|||||||
status_t
|
status_t
|
||||||
Inode::Commit()
|
Inode::Commit()
|
||||||
{
|
{
|
||||||
|
WriteLocker _(fWriteLock);
|
||||||
|
|
||||||
if (!fWriteDirty)
|
if (!fWriteDirty)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
status_t result = CommitWrites();
|
status_t result = CommitWrites();
|
||||||
|
|||||||
Reference in New Issue
Block a user