nfs4: Fix several issues introduced in previous commits

This commit is contained in:
Pawel Dziepak
2012-07-25 03:57:55 +02:00
parent 7cac2f6e50
commit df6a5eaefa
6 changed files with 114 additions and 57 deletions
+67 -47
View File
@@ -229,25 +229,9 @@ Inode::LookUp(const char* name, ino_t* id)
*id = _FileIdToInoT(fileId);
FileInfo fi;
fi.fFileId = fileId;
fi.fHandle = fh;
fi.fParent = fInfo.fHandle;
fi.fName = strdup(name);
if (fi.fName == NULL)
return B_NO_MEMORY;
char* path = reinterpret_cast<char*>(malloc(strlen(name) + 2 +
strlen(fInfo.fPath)));
if (path == NULL)
return B_NO_MEMORY;
strcpy(path, fInfo.fPath);
strcat(path, "/");
strcat(path, name);
fi.fPath = path;
fFileSystem->InoIdMap()->AddEntry(fi, *id);
result = _ChildAdded(name, fileId, fh);
if (result != B_OK)
return result;
fFileSystem->Revalidator().Lock();
if (fCache->Lock() != B_OK) {
@@ -281,10 +265,6 @@ Inode::Link(Inode* dir, const char* name)
req.PutFH(dir->fInfo.fHandle);
req.Link(name);
req.LookUp(name);
Attribute attr[] = { FATTR4_FILEID };
req.GetAttr(attr, sizeof(attr) / sizeof(Attribute));
status_t result = request.Send();
if (result != B_OK)
return result;
@@ -314,31 +294,35 @@ Inode::Link(Inode* dir, const char* name)
if (result != B_OK)
return result;
result = reply.LookUp();
if (result != B_OK)
return result;
AttrValue* values;
uint32 count;
result = reply.GetAttr(&values, &count);
if (result != B_OK)
return result;
uint32 fileID;
if (count == 0)
fileID = fFileSystem->AllocFileId();
else
fileID = values[1].fData.fValue64;
fFileSystem->Root()->MakeInfoInvalid();
if (fCache->Lock() == B_OK) {
if (atomic && fCache->ChangeInfo() == before) {
fCache->AddEntry(name, fileID, true);
fCache->SetChangeInfo(after);
} else if (fCache->ChangeInfo() != before)
fCache->Trash();
fCache->Unlock();
FileInfo fi = fInfo;
fi.fParent = dir->fInfo.fHandle;
free(const_cast<char*>(fi.fName));
fi.fName = strdup(name);
if (fi.fName == NULL)
return B_NO_MEMORY;
char* path = reinterpret_cast<char*>(malloc(strlen(name) + 2 +
strlen(fInfo.fPath)));
if (path == NULL)
return B_NO_MEMORY;
strcpy(path, dir->fInfo.fPath);
strcat(path, "/");
strcat(path, name);
free(const_cast<char*>(fi.fPath));
fi.fPath = path;
fFileSystem->InoIdMap()->AddEntry(fi, fInfo.fFileId);
if (dir->fCache->Lock() == B_OK) {
if (atomic && dir->fCache->ChangeInfo() == before) {
dir->fCache->AddEntry(name, fInfo.fFileId, true);
dir->fCache->SetChangeInfo(after);
} else if (dir->fCache->ChangeInfo() != before)
dir->fCache->Trash();
dir->fCache->Unlock();
}
return B_OK;
@@ -549,6 +533,7 @@ Inode::CreateLink(const char* name, const char* path, int mode)
req.Create(NF4LNK, name, cattr, i, path);
req.GetFH();
Attribute attr[] = { FATTR4_FILEID };
req.GetAttr(attr, sizeof(attr) / sizeof(Attribute));
@@ -573,6 +558,9 @@ Inode::CreateLink(const char* name, const char* path, int mode)
if (result != B_OK)
return result;
FileHandle handle;
reply.GetFH(&handle);
AttrValue* values;
uint32 count;
result = reply.GetAttr(&values, &count);
@@ -583,10 +571,14 @@ Inode::CreateLink(const char* name, const char* path, int mode)
if (count == 0)
fileID = fFileSystem->AllocFileId();
else
fileID = values[1].fData.fValue64;
fileID = values[0].fData.fValue64;
fFileSystem->Root()->MakeInfoInvalid();
result = _ChildAdded(name, fileID, handle);
if (result != B_OK)
return B_OK;
if (fCache->Lock() == B_OK) {
if (atomic && fCache->ChangeInfo() == before) {
fCache->AddEntry(name, fileID, true);
@@ -1310,3 +1302,31 @@ Inode::_HandleErrors(uint32 nfs4Error, RPC::Server* serv,
}
}
status_t
Inode::_ChildAdded(const char* name, uint64 fileID,
const FileHandle& fileHandle)
{
fFileSystem->Root()->MakeInfoInvalid();
FileInfo fi;
fi.fFileId = fileID;
fi.fHandle = fileHandle;
fi.fParent = fInfo.fHandle;
fi.fName = strdup(name);
if (fi.fName == NULL)
return B_NO_MEMORY;
char* path = reinterpret_cast<char*>(malloc(strlen(name) + 2 +
strlen(fInfo.fPath)));
if (path == NULL)
return B_NO_MEMORY;
strcpy(path, fInfo.fPath);
strcat(path, "/");
strcat(path, name);
fi.fPath = path;
return fFileSystem->InoIdMap()->AddEntry(fi, _FileIdToInoT(fileID));
}
@@ -92,6 +92,9 @@ protected:
_snapshot, OpenDirCookie* cookie,
uint64* _change);
status_t _ChildAdded(const char* name, uint64 fileID,
const FileHandle& fileHandle);
static inline status_t _CheckLockType(short ltype, uint32 mode);
static inline ino_t _FileIdToInoT(uint64 fileid);
@@ -52,6 +52,7 @@ Inode::CreateDir(const char* name, int mode)
req.Create(NF4DIR, name, cattr, i);
req.GetFH();
Attribute attr[] = { FATTR4_FILEID };
req.GetAttr(attr, sizeof(attr) / sizeof(Attribute));
@@ -76,6 +77,11 @@ Inode::CreateDir(const char* name, int mode)
if (result != B_OK)
return result;
FileHandle handle;
result = reply.GetFH(&handle);
if (result != B_OK)
return result;
AttrValue* values;
uint32 count;
result = reply.GetAttr(&values, &count);
@@ -86,9 +92,11 @@ Inode::CreateDir(const char* name, int mode)
if (count == 0)
fileID = fFileSystem->AllocFileId();
else
fileID = values[1].fData.fValue64;
fileID = values[0].fData.fValue64;
fFileSystem->Root()->MakeInfoInvalid();
result = _ChildAdded(name, fileID, handle);
if (result != B_OK)
return B_OK;
if (fCache->Lock() == B_OK) {
if (atomic && fCache->ChangeInfo() == before) {
@@ -132,7 +132,14 @@ Inode::Create(const char* name, int mode, int perms, OpenFileCookie* cookie,
continue;
reply.PutFH();
reply.Open(cookie->fStateId, &cookie->fStateSeq, &confirm);
bool atomic;
uint64 before, after;
result = reply.Open(cookie->fStateId, &cookie->fStateSeq, &confirm,
&before, &after, &atomic);
if (result != B_OK)
return result;
reply.GetFH(&fh);
uint64 fileId;
@@ -143,7 +150,7 @@ Inode::Create(const char* name, int mode, int perms, OpenFileCookie* cookie,
if (result != B_OK)
return result;
fileId = values[1].fData.fValue64;
fileId = values[0].fData.fValue64;
delete[] values;
} else
@@ -166,6 +173,15 @@ Inode::Create(const char* name, int mode, int perms, OpenFileCookie* cookie,
fFileSystem->InoIdMap()->AddEntry(fi, *id);
if (fCache->Lock() == B_OK) {
if (atomic && fCache->ChangeInfo() == before) {
fCache->AddEntry(name, fileId, true);
fCache->SetChangeInfo(after);
} else if (fCache->ChangeInfo() != before)
fCache->Trash();
fCache->Unlock();
}
cookie->fFileSystem = fFileSystem;
cookie->fInfo = fi;
@@ -135,8 +135,9 @@ ReplyInterpreter::Create(uint64* before, uint64* after, bool& atomic)
atomic = fReply->Stream().GetBoolean();
*before = fReply->Stream().GetUHyper();
*after = fReply->Stream().GetUHyper();
uint32 count = fReply->Stream().GetUInt();
for (uint32 i; i < count; i++)
for (uint32 i = 0; i < count; i++)
fReply->Stream().GetUInt();
return fReply->Stream().IsEOF() ? B_BAD_VALUE : B_OK;
@@ -252,7 +253,8 @@ ReplyInterpreter::LockU(LockInfo* linfo)
status_t
ReplyInterpreter::Open(uint32* id, uint32* seq, bool* confirm)
ReplyInterpreter::Open(uint32* id, uint32* seq, bool* confirm, uint64* _before,
uint64* _after, bool* _atomic)
{
status_t res = _OperationError(OpOpen);
if (res != B_OK)
@@ -264,9 +266,15 @@ ReplyInterpreter::Open(uint32* id, uint32* seq, bool* confirm)
id[2] = fReply->Stream().GetUInt();
// change info
fReply->Stream().GetBoolean();
fReply->Stream().GetUHyper();
fReply->Stream().GetUHyper();
bool atomic = fReply->Stream().GetBoolean();
if (_atomic != NULL)
*_atomic = atomic;
uint64 before = fReply->Stream().GetUHyper();
if (_before != NULL)
*_before = before;
uint64 after = fReply->Stream().GetUHyper();
if (_after != NULL)
*_after = after;
uint32 flags = fReply->Stream().GetUInt();
*confirm = (flags & OPEN4_RESULT_CONFIRM) == OPEN4_RESULT_CONFIRM;
@@ -79,7 +79,9 @@ public:
inline status_t LookUp();
inline status_t LookUpUp();
inline status_t Nverify();
status_t Open(uint32* id, uint32* seq, bool* confirm);
status_t Open(uint32* id, uint32* seq, bool* confirm,
uint64* before = NULL, uint64* after = NULL,
bool* atomic = NULL);
status_t OpenConfirm(uint32* stateSeq);
inline status_t PutFH();
inline status_t PutRootFH();