nfs4: Do not store pointer to parent in inodes
This commit is contained in:
@@ -131,7 +131,7 @@ Filesystem::GetInode(ino_t id, Inode** _inode)
|
|||||||
if (result != B_OK)
|
if (result != B_OK)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
Inode* inode = new(std::nothrow)Inode(this, fh, NULL);
|
Inode* inode = new(std::nothrow)Inode(this, fh);
|
||||||
if (inode == NULL)
|
if (inode == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
@@ -143,6 +143,6 @@ Filesystem::GetInode(ino_t id, Inode** _inode)
|
|||||||
Inode*
|
Inode*
|
||||||
Filesystem::CreateRootInode()
|
Filesystem::CreateRootInode()
|
||||||
{
|
{
|
||||||
return new(std::nothrow)Inode(this, fRootFH, NULL);
|
return new(std::nothrow)Inode(this, fRootFH, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,10 +18,10 @@
|
|||||||
|
|
||||||
// Creating Inode object from Filehandle probably is not a good idea when
|
// Creating Inode object from Filehandle probably is not a good idea when
|
||||||
// filehandles are volatile.
|
// filehandles are volatile.
|
||||||
Inode::Inode(Filesystem* fs, const Filehandle &fh, Inode* parent)
|
Inode::Inode(Filesystem* fs, const Filehandle &fh, bool root)
|
||||||
:
|
:
|
||||||
fFilesystem(fs),
|
fFilesystem(fs),
|
||||||
fParent(parent)
|
fRoot(root)
|
||||||
{
|
{
|
||||||
memcpy(&fHandle, &fh, sizeof(fh));
|
memcpy(&fHandle, &fh, sizeof(fh));
|
||||||
|
|
||||||
@@ -65,6 +65,7 @@ Inode::Inode(Filesystem* fs, const Filehandle &fh, Inode* parent)
|
|||||||
status_t
|
status_t
|
||||||
Inode::LookUp(const char* name, ino_t* id)
|
Inode::LookUp(const char* name, ino_t* id)
|
||||||
{
|
{
|
||||||
|
dprintf("nfs4: lookup: %s\n", name);
|
||||||
if (fType != NF4DIR)
|
if (fType != NF4DIR)
|
||||||
return B_NOT_A_DIRECTORY;
|
return B_NOT_A_DIRECTORY;
|
||||||
|
|
||||||
@@ -116,10 +117,10 @@ Inode::LookUp(const char* name, ino_t* id)
|
|||||||
delete[] values;
|
delete[] values;
|
||||||
return B_UNSUPPORTED;
|
return B_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
*id = values[0].fData.fValue64;
|
*id = _FileIdToInoT(values[0].fData.fValue64);
|
||||||
delete[] values;
|
fFilesystem->InoIdMap()->AddEntry(fh, values[0].fData.fValue64);
|
||||||
|
|
||||||
fFilesystem->InoIdMap()->AddEntry(fh, *id);
|
delete[] values;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -256,6 +257,53 @@ Inode::_FillDirEntry(struct dirent* de, ino_t id, const char* name, uint32 pos,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Inode::_ReadDirUp(struct dirent* de, uint32 pos, uint32 size)
|
||||||
|
{
|
||||||
|
RequestBuilder req(ProcCompound);
|
||||||
|
req.PutFH(fHandle);
|
||||||
|
req.LookUpUp();
|
||||||
|
req.GetFH();
|
||||||
|
Attribute attr[] = { FATTR4_FILEID };
|
||||||
|
req.GetAttr(attr, sizeof(attr) / sizeof(Attribute));
|
||||||
|
|
||||||
|
RPC::Reply *rpl;
|
||||||
|
fFilesystem->Server()->SendCall(req.Request(), &rpl);
|
||||||
|
ReplyInterpreter reply(rpl);
|
||||||
|
|
||||||
|
status_t result;
|
||||||
|
result = reply.PutFH();
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
result = reply.LookUpUp();
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
Filehandle fh;
|
||||||
|
result = reply.GetFH(&fh);
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
AttrValue* values;
|
||||||
|
uint32 count;
|
||||||
|
result = reply.GetAttr(&values, &count);
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
uint64 fileId;
|
||||||
|
if (count < 1 || values[0].fAttribute != FATTR4_FILEID) {
|
||||||
|
// Server does not provide fileid. We need to make something up.
|
||||||
|
fileId = fFilesystem->GetId();
|
||||||
|
} else
|
||||||
|
fileId = values[0].fData.fValue64;
|
||||||
|
|
||||||
|
fFilesystem->InoIdMap()->AddEntry(fh, fileId);
|
||||||
|
|
||||||
|
return _FillDirEntry(de, _FileIdToInoT(fileId), "..", pos, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Inode::ReadDir(void* _buffer, uint32 size, uint32* _count, uint64* cookie)
|
Inode::ReadDir(void* _buffer, uint32 size, uint32* _count, uint64* cookie)
|
||||||
{
|
{
|
||||||
@@ -279,10 +327,10 @@ Inode::ReadDir(void* _buffer, uint32 size, uint32* _count, uint64* cookie)
|
|||||||
if (cookie[0] == 0 && cookie[1] == 1 && count < *_count) {
|
if (cookie[0] == 0 && cookie[1] == 1 && count < *_count) {
|
||||||
struct dirent* de = reinterpret_cast<dirent*>(buffer + pos);
|
struct dirent* de = reinterpret_cast<dirent*>(buffer + pos);
|
||||||
|
|
||||||
if (fParent != NULL)
|
if (!fRoot)
|
||||||
_FillDirEntry(de, fParent->fFileId, "..", pos, size);
|
_ReadDirUp(de, pos, size);
|
||||||
else
|
else
|
||||||
_FillDirEntry(de, fFileId, "..", pos, size);
|
_FillDirEntry(de, _FileIdToInoT(fFileId), "..", pos, size);
|
||||||
|
|
||||||
pos += de->d_reclen;
|
pos += de->d_reclen;
|
||||||
count++;
|
count++;
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
class Inode {
|
class Inode {
|
||||||
public:
|
public:
|
||||||
Inode(Filesystem* fs, const Filehandle &fh,
|
Inode(Filesystem* fs, const Filehandle &fh,
|
||||||
Inode* parent);
|
bool root = false);
|
||||||
|
|
||||||
inline ino_t ID() const;
|
inline ino_t ID() const;
|
||||||
inline mode_t Type() const;
|
inline mode_t Type() const;
|
||||||
@@ -38,6 +38,8 @@ private:
|
|||||||
uint64* cookie, bool* eof);
|
uint64* cookie, bool* eof);
|
||||||
status_t _FillDirEntry(struct dirent* de, ino_t id,
|
status_t _FillDirEntry(struct dirent* de, ino_t id,
|
||||||
const char* name, uint32 pos, uint32 size);
|
const char* name, uint32 pos, uint32 size);
|
||||||
|
status_t _ReadDirUp(struct dirent* de, uint32 pos,
|
||||||
|
uint32 size);
|
||||||
|
|
||||||
static inline ino_t _FileIdToInoT(uint64 fileid);
|
static inline ino_t _FileIdToInoT(uint64 fileid);
|
||||||
|
|
||||||
@@ -46,7 +48,8 @@ private:
|
|||||||
|
|
||||||
Filehandle fHandle;
|
Filehandle fHandle;
|
||||||
Filesystem* fFilesystem;
|
Filesystem* fFilesystem;
|
||||||
Inode* fParent; // this will cause trouble
|
|
||||||
|
bool fRoot;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user