nfs4: Do not let local changes invalidate cache
This commit is contained in:
@@ -304,7 +304,23 @@ Inode::Link(Inode* dir, const char* name)
|
||||
reply.SaveFH();
|
||||
reply.PutFH();
|
||||
|
||||
return reply.Link();
|
||||
uint64 before, after;
|
||||
bool atomic;
|
||||
result = reply.Link(&before, &after, atomic);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
if (fCache->Lock() == B_OK) {
|
||||
if (atomic && fCache->ChangeInfo() == before) {
|
||||
// TODO: update cache
|
||||
//fCache->AddEntry(name, );
|
||||
fCache->SetChangeInfo(after);
|
||||
} else if (fCache->ChangeInfo() != before)
|
||||
fCache->Trash();
|
||||
fCache->Unlock();
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
} while (true);
|
||||
}
|
||||
|
||||
@@ -361,9 +377,19 @@ Inode::Remove(const char* name, FileType type)
|
||||
return result;
|
||||
|
||||
reply.PutFH();
|
||||
result = reply.Remove();
|
||||
|
||||
// remove entry
|
||||
uint64 before, after;
|
||||
bool atomic;
|
||||
result = reply.Remove(&before, &after, atomic);
|
||||
|
||||
if (fCache->Lock() == B_OK) {
|
||||
if (atomic && fCache->ChangeInfo() == before) {
|
||||
fCache->RemoveEntry(name);
|
||||
fCache->SetChangeInfo(after);
|
||||
} else if (fCache->ChangeInfo() != before)
|
||||
fCache->Trash();
|
||||
fCache->Unlock();
|
||||
}
|
||||
|
||||
fFileSystem->Root()->MakeInfoInvalid();
|
||||
|
||||
@@ -415,9 +441,29 @@ Inode::Rename(Inode* from, Inode* to, const char* fromName, const char* toName)
|
||||
reply.SaveFH();
|
||||
reply.PutFH();
|
||||
|
||||
result = reply.Rename();
|
||||
uint64 fromBefore, fromAfter, toBefore, toAfter;
|
||||
bool fromAtomic, toAtomic;
|
||||
result = reply.Rename(&fromBefore, &fromAfter, fromAtomic, &toBefore,
|
||||
&toAfter, toAtomic);
|
||||
|
||||
// remove entry
|
||||
if (from->fCache->Lock() == B_OK) {
|
||||
if (fromAtomic && from->fCache->ChangeInfo() == fromBefore) {
|
||||
from->fCache->RemoveEntry(fromName);
|
||||
from->fCache->SetChangeInfo(fromAfter);
|
||||
} else if (from->fCache->ChangeInfo() != fromBefore)
|
||||
from->fCache->Trash();
|
||||
from->fCache->Unlock();
|
||||
}
|
||||
|
||||
if (to->fCache->Lock() == B_OK) {
|
||||
if (toAtomic && to->fCache->ChangeInfo() == toBefore) {
|
||||
// TODO: update cache
|
||||
//fCache->AddEntry(toName, );
|
||||
to->fCache->SetChangeInfo(toAfter);
|
||||
} else if (to->fCache->ChangeInfo() != toBefore)
|
||||
to->fCache->Trash();
|
||||
to->fCache->Unlock();
|
||||
};
|
||||
|
||||
return result;
|
||||
} while (true);
|
||||
@@ -474,10 +520,22 @@ Inode::CreateLink(const char* name, const char* path, int mode)
|
||||
|
||||
reply.PutFH();
|
||||
|
||||
result = reply.Create();
|
||||
uint64 before, after;
|
||||
bool atomic;
|
||||
result = reply.Create(&before, &after, atomic);
|
||||
|
||||
fFileSystem->Root()->MakeInfoInvalid();
|
||||
|
||||
if (fCache->Lock() == B_OK) {
|
||||
if (atomic && fCache->ChangeInfo() == before) {
|
||||
// TODO: update cache
|
||||
//fCache->AddEntry(name, );
|
||||
fCache->SetChangeInfo(after);
|
||||
} else if (fCache->ChangeInfo() != before)
|
||||
fCache->Trash();
|
||||
fCache->Unlock();
|
||||
}
|
||||
|
||||
return result;
|
||||
} while (true);
|
||||
}
|
||||
|
||||
@@ -67,7 +67,23 @@ Inode::CreateDir(const char* name, int mode)
|
||||
|
||||
reply.PutFH();
|
||||
|
||||
return reply.Create();
|
||||
uint64 before, after;
|
||||
bool atomic;
|
||||
result = reply.Create(&before, &after, atomic);
|
||||
|
||||
fFileSystem->Root()->MakeInfoInvalid();
|
||||
|
||||
if (fCache->Lock() == B_OK) {
|
||||
if (atomic && fCache->ChangeInfo() == before) {
|
||||
// TODO: update cache
|
||||
//fCache->AddEntry(name, );
|
||||
fCache->SetChangeInfo(after);
|
||||
} else if (fCache->ChangeInfo() != before)
|
||||
fCache->Trash();
|
||||
fCache->Unlock();
|
||||
}
|
||||
|
||||
return result;
|
||||
} while (true);
|
||||
}
|
||||
|
||||
|
||||
@@ -126,15 +126,15 @@ ReplyInterpreter::Close()
|
||||
|
||||
|
||||
status_t
|
||||
ReplyInterpreter::Create()
|
||||
ReplyInterpreter::Create(uint64* before, uint64* after, bool& atomic)
|
||||
{
|
||||
status_t res = _OperationError(OpCreate);
|
||||
if (res != B_OK)
|
||||
return res;
|
||||
|
||||
fReply->Stream().GetBoolean();
|
||||
fReply->Stream().GetUHyper();
|
||||
fReply->Stream().GetUHyper();
|
||||
atomic = fReply->Stream().GetBoolean();
|
||||
*before = fReply->Stream().GetUHyper();
|
||||
*after = fReply->Stream().GetUHyper();
|
||||
uint32 count = fReply->Stream().GetUInt();
|
||||
for (uint32 i; i < count; i++)
|
||||
fReply->Stream().GetUInt();
|
||||
@@ -187,15 +187,15 @@ ReplyInterpreter::GetFH(FileHandle* fh)
|
||||
|
||||
|
||||
status_t
|
||||
ReplyInterpreter::Link()
|
||||
ReplyInterpreter::Link(uint64* before, uint64* after, bool& atomic)
|
||||
{
|
||||
status_t res = _OperationError(OpLink);
|
||||
if (res != B_OK)
|
||||
return res;
|
||||
|
||||
fReply->Stream().GetBoolean();
|
||||
fReply->Stream().GetUHyper();
|
||||
fReply->Stream().GetUHyper();
|
||||
atomic = fReply->Stream().GetBoolean();
|
||||
*before = fReply->Stream().GetUHyper();
|
||||
*after = fReply->Stream().GetUHyper();
|
||||
|
||||
return fReply->Stream().IsEOF() ? B_BAD_VALUE : B_OK;
|
||||
}
|
||||
@@ -369,35 +369,35 @@ ReplyInterpreter::ReadLink(void* buffer, uint32* size, uint32 maxSize)
|
||||
|
||||
|
||||
status_t
|
||||
ReplyInterpreter::Remove()
|
||||
ReplyInterpreter::Remove(uint64* before, uint64* after, bool& atomic)
|
||||
{
|
||||
status_t res = _OperationError(OpRemove);
|
||||
if (res != B_OK)
|
||||
return res;
|
||||
|
||||
fReply->Stream().GetBoolean();
|
||||
fReply->Stream().GetUHyper();
|
||||
fReply->Stream().GetUHyper();
|
||||
atomic = fReply->Stream().GetBoolean();
|
||||
*before = fReply->Stream().GetUHyper();
|
||||
*after = fReply->Stream().GetUHyper();
|
||||
|
||||
return fReply->Stream().IsEOF() ? B_BAD_VALUE : B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ReplyInterpreter::Rename()
|
||||
ReplyInterpreter::Rename(uint64* fromBefore, uint64* fromAfter,
|
||||
bool& fromAtomic, uint64* toBefore, uint64* toAfter, bool& toAtomic)
|
||||
{
|
||||
status_t res = _OperationError(OpRename);
|
||||
if (res != B_OK)
|
||||
return res;
|
||||
|
||||
fReply->Stream().GetBoolean();
|
||||
fReply->Stream().GetUHyper();
|
||||
fReply->Stream().GetUHyper();
|
||||
|
||||
fReply->Stream().GetBoolean();
|
||||
fReply->Stream().GetUHyper();
|
||||
fReply->Stream().GetUHyper();
|
||||
fromAtomic = fReply->Stream().GetBoolean();
|
||||
*fromBefore = fReply->Stream().GetUHyper();
|
||||
*fromAfter = fReply->Stream().GetUHyper();
|
||||
|
||||
toAtomic = fReply->Stream().GetBoolean();
|
||||
*toBefore = fReply->Stream().GetUHyper();
|
||||
*toAfter = fReply->Stream().GetUHyper();
|
||||
return fReply->Stream().IsEOF() ? B_BAD_VALUE : B_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -69,10 +69,10 @@ public:
|
||||
|
||||
status_t Access(uint32* supported, uint32* allowed);
|
||||
status_t Close();
|
||||
status_t Create();
|
||||
status_t Create(uint64* before, uint64* after, bool& atomic);
|
||||
status_t GetAttr(AttrValue** attrs, uint32* count);
|
||||
status_t GetFH(FileHandle* fh);
|
||||
status_t Link();
|
||||
status_t Link(uint64* before, uint64* after, bool& atomic);
|
||||
status_t Lock(LockInfo* linfo);
|
||||
status_t LockT(uint64* pos, uint64* len, LockType* type);
|
||||
status_t LockU(LockInfo* linfo);
|
||||
@@ -87,8 +87,10 @@ public:
|
||||
status_t ReadDir(uint64* cookie, uint64* cookieVerf,
|
||||
DirEntry** dirents, uint32* count, bool* eof);
|
||||
status_t ReadLink(void* buffer, uint32* size, uint32 maxSize);
|
||||
status_t Remove();
|
||||
status_t Rename();
|
||||
status_t Remove(uint64* before, uint64* after, bool& atomic);
|
||||
status_t Rename(uint64* fromBefore, uint64* fromAfter,
|
||||
bool& fromAtomic, uint64* toBefore, uint64* toAfter,
|
||||
bool& toAtomic);
|
||||
inline status_t Renew();
|
||||
inline status_t SaveFH();
|
||||
status_t SetAttr();
|
||||
|
||||
Reference in New Issue
Block a user