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);
|
*id = _FileIdToInoT(fileId);
|
||||||
|
|
||||||
FileInfo fi;
|
result = _ChildAdded(name, fileId, fh);
|
||||||
fi.fFileId = fileId;
|
if (result != B_OK)
|
||||||
fi.fHandle = fh;
|
return result;
|
||||||
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);
|
|
||||||
|
|
||||||
fFileSystem->Revalidator().Lock();
|
fFileSystem->Revalidator().Lock();
|
||||||
if (fCache->Lock() != B_OK) {
|
if (fCache->Lock() != B_OK) {
|
||||||
@@ -281,10 +265,6 @@ Inode::Link(Inode* dir, const char* name)
|
|||||||
req.PutFH(dir->fInfo.fHandle);
|
req.PutFH(dir->fInfo.fHandle);
|
||||||
req.Link(name);
|
req.Link(name);
|
||||||
|
|
||||||
req.LookUp(name);
|
|
||||||
Attribute attr[] = { FATTR4_FILEID };
|
|
||||||
req.GetAttr(attr, sizeof(attr) / sizeof(Attribute));
|
|
||||||
|
|
||||||
status_t result = request.Send();
|
status_t result = request.Send();
|
||||||
if (result != B_OK)
|
if (result != B_OK)
|
||||||
return result;
|
return result;
|
||||||
@@ -314,31 +294,35 @@ Inode::Link(Inode* dir, const char* name)
|
|||||||
if (result != B_OK)
|
if (result != B_OK)
|
||||||
return result;
|
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();
|
fFileSystem->Root()->MakeInfoInvalid();
|
||||||
|
|
||||||
if (fCache->Lock() == B_OK) {
|
FileInfo fi = fInfo;
|
||||||
if (atomic && fCache->ChangeInfo() == before) {
|
fi.fParent = dir->fInfo.fHandle;
|
||||||
fCache->AddEntry(name, fileID, true);
|
free(const_cast<char*>(fi.fName));
|
||||||
fCache->SetChangeInfo(after);
|
fi.fName = strdup(name);
|
||||||
} else if (fCache->ChangeInfo() != before)
|
if (fi.fName == NULL)
|
||||||
fCache->Trash();
|
return B_NO_MEMORY;
|
||||||
fCache->Unlock();
|
|
||||||
|
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;
|
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.Create(NF4LNK, name, cattr, i, path);
|
||||||
|
|
||||||
|
req.GetFH();
|
||||||
Attribute attr[] = { FATTR4_FILEID };
|
Attribute attr[] = { FATTR4_FILEID };
|
||||||
req.GetAttr(attr, sizeof(attr) / sizeof(Attribute));
|
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)
|
if (result != B_OK)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
FileHandle handle;
|
||||||
|
reply.GetFH(&handle);
|
||||||
|
|
||||||
AttrValue* values;
|
AttrValue* values;
|
||||||
uint32 count;
|
uint32 count;
|
||||||
result = reply.GetAttr(&values, &count);
|
result = reply.GetAttr(&values, &count);
|
||||||
@@ -583,10 +571,14 @@ Inode::CreateLink(const char* name, const char* path, int mode)
|
|||||||
if (count == 0)
|
if (count == 0)
|
||||||
fileID = fFileSystem->AllocFileId();
|
fileID = fFileSystem->AllocFileId();
|
||||||
else
|
else
|
||||||
fileID = values[1].fData.fValue64;
|
fileID = values[0].fData.fValue64;
|
||||||
|
|
||||||
fFileSystem->Root()->MakeInfoInvalid();
|
fFileSystem->Root()->MakeInfoInvalid();
|
||||||
|
|
||||||
|
result = _ChildAdded(name, fileID, handle);
|
||||||
|
if (result != B_OK)
|
||||||
|
return B_OK;
|
||||||
|
|
||||||
if (fCache->Lock() == B_OK) {
|
if (fCache->Lock() == B_OK) {
|
||||||
if (atomic && fCache->ChangeInfo() == before) {
|
if (atomic && fCache->ChangeInfo() == before) {
|
||||||
fCache->AddEntry(name, fileID, true);
|
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,
|
_snapshot, OpenDirCookie* cookie,
|
||||||
uint64* _change);
|
uint64* _change);
|
||||||
|
|
||||||
|
status_t _ChildAdded(const char* name, uint64 fileID,
|
||||||
|
const FileHandle& fileHandle);
|
||||||
|
|
||||||
static inline status_t _CheckLockType(short ltype, uint32 mode);
|
static inline status_t _CheckLockType(short ltype, uint32 mode);
|
||||||
|
|
||||||
static inline ino_t _FileIdToInoT(uint64 fileid);
|
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.Create(NF4DIR, name, cattr, i);
|
||||||
|
|
||||||
|
req.GetFH();
|
||||||
Attribute attr[] = { FATTR4_FILEID };
|
Attribute attr[] = { FATTR4_FILEID };
|
||||||
req.GetAttr(attr, sizeof(attr) / sizeof(Attribute));
|
req.GetAttr(attr, sizeof(attr) / sizeof(Attribute));
|
||||||
|
|
||||||
@@ -76,6 +77,11 @@ Inode::CreateDir(const char* name, int mode)
|
|||||||
if (result != B_OK)
|
if (result != B_OK)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
FileHandle handle;
|
||||||
|
result = reply.GetFH(&handle);
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
AttrValue* values;
|
AttrValue* values;
|
||||||
uint32 count;
|
uint32 count;
|
||||||
result = reply.GetAttr(&values, &count);
|
result = reply.GetAttr(&values, &count);
|
||||||
@@ -86,9 +92,11 @@ Inode::CreateDir(const char* name, int mode)
|
|||||||
if (count == 0)
|
if (count == 0)
|
||||||
fileID = fFileSystem->AllocFileId();
|
fileID = fFileSystem->AllocFileId();
|
||||||
else
|
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 (fCache->Lock() == B_OK) {
|
||||||
if (atomic && fCache->ChangeInfo() == before) {
|
if (atomic && fCache->ChangeInfo() == before) {
|
||||||
|
|||||||
@@ -132,7 +132,14 @@ Inode::Create(const char* name, int mode, int perms, OpenFileCookie* cookie,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
reply.PutFH();
|
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);
|
reply.GetFH(&fh);
|
||||||
|
|
||||||
uint64 fileId;
|
uint64 fileId;
|
||||||
@@ -143,7 +150,7 @@ Inode::Create(const char* name, int mode, int perms, OpenFileCookie* cookie,
|
|||||||
if (result != B_OK)
|
if (result != B_OK)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
fileId = values[1].fData.fValue64;
|
fileId = values[0].fData.fValue64;
|
||||||
|
|
||||||
delete[] values;
|
delete[] values;
|
||||||
} else
|
} else
|
||||||
@@ -166,6 +173,15 @@ Inode::Create(const char* name, int mode, int perms, OpenFileCookie* cookie,
|
|||||||
|
|
||||||
fFileSystem->InoIdMap()->AddEntry(fi, *id);
|
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->fFileSystem = fFileSystem;
|
||||||
cookie->fInfo = fi;
|
cookie->fInfo = fi;
|
||||||
|
|
||||||
|
|||||||
@@ -135,8 +135,9 @@ ReplyInterpreter::Create(uint64* before, uint64* after, bool& atomic)
|
|||||||
atomic = fReply->Stream().GetBoolean();
|
atomic = fReply->Stream().GetBoolean();
|
||||||
*before = fReply->Stream().GetUHyper();
|
*before = fReply->Stream().GetUHyper();
|
||||||
*after = fReply->Stream().GetUHyper();
|
*after = fReply->Stream().GetUHyper();
|
||||||
|
|
||||||
uint32 count = fReply->Stream().GetUInt();
|
uint32 count = fReply->Stream().GetUInt();
|
||||||
for (uint32 i; i < count; i++)
|
for (uint32 i = 0; i < count; i++)
|
||||||
fReply->Stream().GetUInt();
|
fReply->Stream().GetUInt();
|
||||||
|
|
||||||
return fReply->Stream().IsEOF() ? B_BAD_VALUE : B_OK;
|
return fReply->Stream().IsEOF() ? B_BAD_VALUE : B_OK;
|
||||||
@@ -252,7 +253,8 @@ ReplyInterpreter::LockU(LockInfo* linfo)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
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);
|
status_t res = _OperationError(OpOpen);
|
||||||
if (res != B_OK)
|
if (res != B_OK)
|
||||||
@@ -264,9 +266,15 @@ ReplyInterpreter::Open(uint32* id, uint32* seq, bool* confirm)
|
|||||||
id[2] = fReply->Stream().GetUInt();
|
id[2] = fReply->Stream().GetUInt();
|
||||||
|
|
||||||
// change info
|
// change info
|
||||||
fReply->Stream().GetBoolean();
|
bool atomic = fReply->Stream().GetBoolean();
|
||||||
fReply->Stream().GetUHyper();
|
if (_atomic != NULL)
|
||||||
fReply->Stream().GetUHyper();
|
*_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();
|
uint32 flags = fReply->Stream().GetUInt();
|
||||||
*confirm = (flags & OPEN4_RESULT_CONFIRM) == OPEN4_RESULT_CONFIRM;
|
*confirm = (flags & OPEN4_RESULT_CONFIRM) == OPEN4_RESULT_CONFIRM;
|
||||||
|
|||||||
@@ -79,7 +79,9 @@ public:
|
|||||||
inline status_t LookUp();
|
inline status_t LookUp();
|
||||||
inline status_t LookUpUp();
|
inline status_t LookUpUp();
|
||||||
inline status_t Nverify();
|
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);
|
status_t OpenConfirm(uint32* stateSeq);
|
||||||
inline status_t PutFH();
|
inline status_t PutFH();
|
||||||
inline status_t PutRootFH();
|
inline status_t PutRootFH();
|
||||||
|
|||||||
Reference in New Issue
Block a user