nfs4: Inodes should know their name and parent's filehandle

This commit is contained in:
Pawel Dziepak
2012-06-29 02:14:30 +02:00
parent e8845bd5b7
commit 87c6b83293
6 changed files with 109 additions and 29 deletions
@@ -9,6 +9,7 @@
#define FILEHANDLE_H #define FILEHANDLE_H
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <SupportDefs.h> #include <SupportDefs.h>
@@ -26,6 +27,24 @@ struct Filehandle {
}; };
// Complete information needed to identify a file in any situation.
// Unfortunately just a filehandle is not enough even when they are persistent
// since OPEN requires both parent filehandle and file name (just like LOOKUP).
struct FileInfo {
Filehandle fFH;
Filehandle fParent;
const char* fName;
// ... full path may be needed if filehandles are volatile
inline FileInfo();
inline ~FileInfo();
inline FileInfo(const FileInfo& fi);
inline FileInfo& operator=(const FileInfo& fi);
};
inline inline
Filehandle::Filehandle() Filehandle::Filehandle()
: :
@@ -52,5 +71,40 @@ Filehandle::operator=(const Filehandle& fh)
} }
inline
FileInfo::FileInfo()
:
fName(NULL)
{
}
inline
FileInfo::~FileInfo()
{
free(const_cast<char*>(fName));
}
inline
FileInfo::FileInfo(const FileInfo& fi)
:
fFH(fi.fFH),
fParent(fi.fParent),
fName(strdup(fi.fName))
{
}
inline FileInfo&
FileInfo::operator=(const FileInfo& fi)
{
fFH = fi.fFH;
fParent = fi.fParent;
fName = strdup(fi.fName);
return *this;
}
#endif // FILEHANDLE_H #endif // FILEHANDLE_H
@@ -126,12 +126,15 @@ Filesystem::Mount(Filesystem** pfs, RPC::Server* serv, const char* fsPath,
status_t status_t
Filesystem::GetInode(ino_t id, Inode** _inode) Filesystem::GetInode(ino_t id, Inode** _inode)
{ {
Filehandle fh; FileInfo fi;
status_t result = fInoIdMap.GetFilehandle(&fh, id); status_t result = fInoIdMap.GetFileInfo(&fi, id);
if (result == B_ENTRY_NOT_FOUND)
dprintf("NFS4: unknown inode: %llu\n", id);
if (result != B_OK) if (result != B_OK)
return result; return result;
Inode* inode = new(std::nothrow)Inode(this, fh); Inode* inode = new(std::nothrow)Inode(this, fi);
if (inode == NULL) if (inode == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
@@ -143,6 +146,10 @@ Filesystem::GetInode(ino_t id, Inode** _inode)
Inode* Inode*
Filesystem::CreateRootInode() Filesystem::CreateRootInode()
{ {
return new(std::nothrow)Inode(this, fRootFH, true); FileInfo fi;
fi.fFH = fRootFH;
fi.fParent = fRootFH;
fi.fName = strdup("/");
return new(std::nothrow)Inode(this, fi);
} }
+16 -10
View File
@@ -18,15 +18,15 @@
// 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, bool root) Inode::Inode(Filesystem* fs, const FileInfo &fi)
: :
fHandle(fi.fFH),
fFilesystem(fs), fFilesystem(fs),
fRoot(root) fParentFH(fi.fParent),
fName(strdup(fi.fName))
{ {
memcpy(&fHandle, &fh, sizeof(fh));
RequestBuilder req(ProcCompound); RequestBuilder req(ProcCompound);
req.PutFH(fh); req.PutFH(fHandle);
Attribute attr[] = { FATTR4_TYPE, FATTR4_FILEID }; Attribute attr[] = { FATTR4_TYPE, FATTR4_FILEID };
req.GetAttr(attr, sizeof(attr) / sizeof(Attribute)); req.GetAttr(attr, sizeof(attr) / sizeof(Attribute));
@@ -59,6 +59,12 @@ Inode::Inode(Filesystem* fs, const Filehandle &fh, bool root)
} }
Inode::~Inode()
{
free(const_cast<char*>(fName));
}
// filesystems that do not provide fileid are currently unsupported // filesystems that do not provide fileid are currently unsupported
// client will have to be able to create its own mapping between file names // client will have to be able to create its own mapping between file names
// and made up IDs // and made up IDs
@@ -116,10 +122,12 @@ Inode::LookUp(const char* name, ino_t* id)
delete[] values; delete[] values;
return B_UNSUPPORTED; return B_UNSUPPORTED;
} }
*id = _FileIdToInoT(values[0].fData.fValue64);
fFilesystem->InoIdMap()->AddEntry(fh, values[0].fData.fValue64);
*id = _FileIdToInoT(values[0].fData.fValue64);
delete[] values; delete[] values;
fFilesystem->InoIdMap()->AddEntry(fh, fHandle, name, *id);
return B_OK; return B_OK;
} }
@@ -296,8 +304,6 @@ Inode::_ReadDirUp(struct dirent* de, uint32 pos, uint32 size)
fileId = fFilesystem->GetId(); fileId = fFilesystem->GetId();
} else } else
fileId = values[0].fData.fValue64; fileId = values[0].fData.fValue64;
fFilesystem->InoIdMap()->AddEntry(fh, fileId);
return _FillDirEntry(de, _FileIdToInoT(fileId), "..", pos, size); return _FillDirEntry(de, _FileIdToInoT(fileId), "..", pos, size);
} }
@@ -326,7 +332,7 @@ 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 (!fRoot) if (strcmp(fName, "/"))
_ReadDirUp(de, pos, size); _ReadDirUp(de, pos, size);
else else
_FillDirEntry(de, _FileIdToInoT(fFileId), "..", pos, size); _FillDirEntry(de, _FileIdToInoT(fFileId), "..", pos, size);
+4 -3
View File
@@ -20,8 +20,8 @@
class Inode { class Inode {
public: public:
Inode(Filesystem* fs, const Filehandle &fh, Inode(Filesystem* fs, const FileInfo& fi);
bool root = false); ~Inode();
inline ino_t ID() const; inline ino_t ID() const;
inline mode_t Type() const; inline mode_t Type() const;
@@ -49,7 +49,8 @@ private:
Filehandle fHandle; Filehandle fHandle;
Filesystem* fFilesystem; Filesystem* fFilesystem;
bool fRoot; Filehandle fParentFH;
const char* fName;
}; };
@@ -17,32 +17,37 @@
class InodeIdMap { class InodeIdMap {
public: public:
inline status_t AddEntry(const Filehandle& inode, inline status_t AddEntry(const Filehandle& fh,
ino_t id); const Filehandle& parent,
inline status_t GetFilehandle(Filehandle* fh, const char* name, ino_t id);
ino_t id); inline status_t GetFileInfo(FileInfo* fi, ino_t id);
private: private:
AVLTreeMap<ino_t, Filehandle> fMap; AVLTreeMap<ino_t, FileInfo> fMap;
}; };
inline status_t inline status_t
InodeIdMap::AddEntry(const Filehandle& inode, ino_t id) InodeIdMap::AddEntry(const Filehandle& fh, const Filehandle& parent,
const char* name, ino_t id)
{ {
return fMap.Insert(id, inode); FileInfo fi;
fi.fFH = fh;
fi.fParent = parent;
fi.fName = strdup(name);
return fMap.Insert(id, fi);
} }
inline status_t inline status_t
InodeIdMap::GetFilehandle(Filehandle* fh, ino_t id) InodeIdMap::GetFileInfo(FileInfo* fi, ino_t id)
{ {
AVLTreeMap<ino_t, Filehandle>::Iterator it = fMap.Find(id); AVLTreeMap<ino_t, FileInfo>::Iterator it = fMap.Find(id);
if (!it.HasCurrent()) if (!it.HasCurrent())
return B_BAD_VALUE; return B_ENTRY_NOT_FOUND;
*fh = it.Current(); *fi = it.Current();
return B_OK; return B_OK;
} }
@@ -129,6 +129,13 @@ nfs4_read_stat(fs_volume* volume, fs_vnode* vnode, struct stat* stat)
} }
static status_t
nfs4_open(fs_volume* volume, fs_vnode* vnode, int openMode, void** _cookie)
{
return B_ERROR;
}
static status_t static status_t
nfs4_open_dir(fs_volume* volume, fs_vnode* vnode, void** _cookie) nfs4_open_dir(fs_volume* volume, fs_vnode* vnode, void** _cookie)
{ {
@@ -269,7 +276,7 @@ fs_vnode_ops gNFSv4VnodeOps = {
/* file operations */ /* file operations */
NULL, // create() NULL, // create()
NULL, // open() nfs4_open,
NULL, // close() NULL, // close()
NULL, // free_cookie() NULL, // free_cookie()
NULL, // read() NULL, // read()