nfs4: Add link() hook
This commit is contained in:
@@ -210,6 +210,56 @@ Inode::LookUp(const char* name, ino_t* id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Inode::Link(Inode* dir, const char* name)
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
RPC::Server* serv = fFilesystem->Server();
|
||||||
|
Request request(serv);
|
||||||
|
RequestBuilder& req = request.Builder();
|
||||||
|
|
||||||
|
req.PutFH(fHandle);
|
||||||
|
req.SaveFH();
|
||||||
|
req.PutFH(dir->fHandle);
|
||||||
|
req.Link(name);
|
||||||
|
|
||||||
|
status_t result = request.Send();
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
ReplyInterpreter& reply = request.Reply();
|
||||||
|
|
||||||
|
// filehandle has expired
|
||||||
|
if (reply.NFS4Error() == NFS4ERR_FHEXPIRED) {
|
||||||
|
_LookUpFilehandle();
|
||||||
|
dir->_LookUpFilehandle();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// filesystem has been moved
|
||||||
|
if (reply.NFS4Error() == NFS4ERR_MOVED) {
|
||||||
|
fFilesystem->Migrate(fHandle, serv);
|
||||||
|
dir->fFilesystem->Migrate(dir->fHandle, serv);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = reply.PutFH();
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
result = reply.SaveFH();
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
result = reply.PutFH();
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
return reply.Link();
|
||||||
|
} while (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// May cause problem similar to Rename (described below). When node's is has
|
// May cause problem similar to Rename (described below). When node's is has
|
||||||
// more than one hard link and we delete the name it stores for filehandle
|
// more than one hard link and we delete the name it stores for filehandle
|
||||||
// restoration node will inocorectly become unavailable.
|
// restoration node will inocorectly become unavailable.
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ public:
|
|||||||
|
|
||||||
status_t LookUp(const char* name, ino_t* id);
|
status_t LookUp(const char* name, ino_t* id);
|
||||||
status_t ReadLink(void* buffer, size_t* length);
|
status_t ReadLink(void* buffer, size_t* length);
|
||||||
|
status_t Link(Inode* dir, const char* name);
|
||||||
status_t Remove(const char* name, FileType type);
|
status_t Remove(const char* name, FileType type);
|
||||||
static status_t Rename(Inode* from, Inode* to,
|
static status_t Rename(Inode* from, Inode* to,
|
||||||
const char* fromName, const char* toName);
|
const char* fromName, const char* toName);
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ enum Opcode {
|
|||||||
OpClose = 4,
|
OpClose = 4,
|
||||||
OpGetAttr = 9,
|
OpGetAttr = 9,
|
||||||
OpGetFH = 10,
|
OpGetFH = 10,
|
||||||
|
OpLink = 11,
|
||||||
OpLookUp = 15,
|
OpLookUp = 15,
|
||||||
OpLookUpUp = 16,
|
OpLookUpUp = 16,
|
||||||
OpOpen = 18,
|
OpOpen = 18,
|
||||||
|
|||||||
@@ -173,6 +173,21 @@ ReplyInterpreter::GetFH(Filehandle* fh)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
ReplyInterpreter::Link()
|
||||||
|
{
|
||||||
|
status_t res = _OperationError(OpLink);
|
||||||
|
if (res != B_OK)
|
||||||
|
return res;
|
||||||
|
|
||||||
|
fReply->Stream().GetBoolean();
|
||||||
|
fReply->Stream().GetUHyper();
|
||||||
|
fReply->Stream().GetUHyper();
|
||||||
|
|
||||||
|
return fReply->Stream().IsEOF() ? B_BAD_VALUE : B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
ReplyInterpreter::Open(uint32* id, uint32* seq, bool* confirm)
|
ReplyInterpreter::Open(uint32* id, uint32* seq, bool* confirm)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ public:
|
|||||||
status_t Close();
|
status_t Close();
|
||||||
status_t GetAttr(AttrValue** attrs, uint32* count);
|
status_t GetAttr(AttrValue** attrs, uint32* count);
|
||||||
status_t GetFH(Filehandle* fh);
|
status_t GetFH(Filehandle* fh);
|
||||||
|
status_t Link();
|
||||||
inline status_t LookUp();
|
inline status_t LookUp();
|
||||||
inline status_t LookUpUp();
|
inline status_t LookUpUp();
|
||||||
status_t Open(uint32* id, uint32* seq, bool* confirm);
|
status_t Open(uint32* id, uint32* seq, bool* confirm);
|
||||||
|
|||||||
@@ -118,6 +118,24 @@ RequestBuilder::GetFH()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
RequestBuilder::Link(const char* name)
|
||||||
|
{
|
||||||
|
if (fProcedure != ProcCompound)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
if (fRequest == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
if (name == NULL)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
|
fRequest->Stream().AddUInt(OpLink);
|
||||||
|
fRequest->Stream().AddString(name);
|
||||||
|
fOpCount++;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
RequestBuilder::LookUp(const char* name)
|
RequestBuilder::LookUp(const char* name)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ public:
|
|||||||
uint32 stateSeq);
|
uint32 stateSeq);
|
||||||
status_t GetAttr(Attribute* attrs, uint32 count);
|
status_t GetAttr(Attribute* attrs, uint32 count);
|
||||||
status_t GetFH();
|
status_t GetFH();
|
||||||
|
status_t Link(const char* name);
|
||||||
status_t LookUp(const char* name);
|
status_t LookUp(const char* name);
|
||||||
status_t LookUpUp();
|
status_t LookUpUp();
|
||||||
status_t Open(OpenClaim claim, uint32 seq,
|
status_t Open(OpenClaim claim, uint32 seq,
|
||||||
|
|||||||
@@ -212,6 +212,15 @@ nfs4_read_symlink(fs_volume* volume, fs_vnode* link, char* buffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
nfs4_link(fs_volume* volume, fs_vnode* dir, const char* name, fs_vnode* vnode)
|
||||||
|
{
|
||||||
|
Inode* inode = reinterpret_cast<Inode*>(vnode->private_node);
|
||||||
|
Inode* dirInode = reinterpret_cast<Inode*>(dir->private_node);
|
||||||
|
return inode->Link(dirInode, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
nfs4_unlink(fs_volume* volume, fs_vnode* dir, const char* name)
|
nfs4_unlink(fs_volume* volume, fs_vnode* dir, const char* name)
|
||||||
{
|
{
|
||||||
@@ -449,7 +458,7 @@ fs_vnode_ops gNFSv4VnodeOps = {
|
|||||||
nfs4_read_symlink,
|
nfs4_read_symlink,
|
||||||
NULL, // create_symlink()
|
NULL, // create_symlink()
|
||||||
|
|
||||||
NULL, // link()
|
nfs4_link,
|
||||||
nfs4_unlink,
|
nfs4_unlink,
|
||||||
nfs4_rename,
|
nfs4_rename,
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user