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