nfs4: Complete outstanding AIO requests before releasing open state

This commit is contained in:
Pawel Dziepak
2012-12-03 22:47:45 +01:00
parent b352cbf6ca
commit 83444c2321
3 changed files with 51 additions and 1 deletions
+30 -1
View File
@@ -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();
}