nfs4: Complete outstanding AIO requests before releasing open state
This commit is contained in:
@@ -30,11 +30,14 @@ Inode::Inode()
|
||||
fFileCache(NULL),
|
||||
fMaxFileSize(0),
|
||||
fOpenState(NULL),
|
||||
fWriteDirty(false)
|
||||
fWriteDirty(false),
|
||||
fAIOWait(create_sem(1, NULL)),
|
||||
fAIOCount(0)
|
||||
{
|
||||
rw_lock_init(&fDelegationLock, NULL);
|
||||
mutex_init(&fStateLock, NULL);
|
||||
mutex_init(&fFileCacheLock, NULL);
|
||||
mutex_init(&fAIOLock, NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -139,9 +142,13 @@ Inode::~Inode()
|
||||
delete fCache;
|
||||
delete fAttrCache;
|
||||
|
||||
delete_sem(fAIOWait);
|
||||
mutex_destroy(&fAIOLock);
|
||||
mutex_destroy(&fStateLock);
|
||||
mutex_destroy(&fFileCacheLock);
|
||||
rw_lock_destroy(&fDelegationLock);
|
||||
|
||||
ASSERT(fAIOCount == 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -944,6 +951,28 @@ Inode::SyncAndCommit(bool force)
|
||||
return B_OK;
|
||||
|
||||
file_cache_sync(fFileCache);
|
||||
WaitAIOComplete();
|
||||
return Commit();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Inode::BeginAIOOp()
|
||||
{
|
||||
MutexLocker _(fAIOLock);
|
||||
fAIOCount++;
|
||||
if (fAIOCount == 1)
|
||||
acquire_sem(fAIOWait);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Inode::EndAIOOp()
|
||||
{
|
||||
MutexLocker _(fAIOLock);
|
||||
ASSERT(fAIOCount > 0);
|
||||
fAIOCount--;
|
||||
if (fAIOCount == 0)
|
||||
release_sem(fAIOWait);
|
||||
}
|
||||
|
||||
|
||||
@@ -112,6 +112,10 @@ public:
|
||||
status_t LoadAttrDirHandle();
|
||||
|
||||
static inline ino_t FileIdToInoT(uint64 fileid);
|
||||
|
||||
void BeginAIOOp();
|
||||
void EndAIOOp();
|
||||
inline void WaitAIOComplete();
|
||||
protected:
|
||||
Inode();
|
||||
|
||||
@@ -157,9 +161,21 @@ private:
|
||||
mutex fStateLock;
|
||||
|
||||
bool fWriteDirty;
|
||||
|
||||
sem_id fAIOWait;
|
||||
uint32 fAIOCount;
|
||||
mutex fAIOLock;
|
||||
};
|
||||
|
||||
|
||||
inline void
|
||||
Inode::WaitAIOComplete()
|
||||
{
|
||||
acquire_sem(fAIOWait);
|
||||
release_sem(fAIOWait);
|
||||
}
|
||||
|
||||
|
||||
inline ino_t
|
||||
Inode::FileIdToInoT(uint64 fileid)
|
||||
{
|
||||
|
||||
@@ -62,6 +62,9 @@ WorkQueue::EnqueueJob(JobType type, void* args)
|
||||
|
||||
entry->fType = type;
|
||||
entry->fArguments = args;
|
||||
if (type == IORequest)
|
||||
reinterpret_cast<IORequestArgs*>(args)->fInode->BeginAIOOp();
|
||||
|
||||
MutexLocker locker(fQueueLock);
|
||||
fQueue.InsertAfter(fQueue.Tail(), entry);
|
||||
locker.Unlock();
|
||||
@@ -152,6 +155,7 @@ WorkQueue::JobIO(IORequestArgs* args)
|
||||
char* buffer = reinterpret_cast<char*>(malloc(length));
|
||||
if (buffer == NULL) {
|
||||
notify_io_request(args->fRequest, B_NO_MEMORY);
|
||||
args->fInode->EndAIOOp();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -188,5 +192,6 @@ WorkQueue::JobIO(IORequestArgs* args)
|
||||
free(buffer);
|
||||
|
||||
notify_io_request(args->fRequest, result);
|
||||
args->fInode->EndAIOOp();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user