nfs4: Fix several issues introduced in previous commits
This commit is contained in:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user