nfs4: Do not store pointer to parent in inodes

This commit is contained in:
Pawel Dziepak
2012-06-29 02:14:27 +02:00
parent 7bfa4fe805
commit ed517d6c62
3 changed files with 63 additions and 12 deletions
@@ -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);
} }
+56 -8
View File
@@ -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++;
+5 -2
View File
@@ -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;
}; };