nfs4: Add unlink() and remove_dir() hooks

This commit is contained in:
Pawel Dziepak
2012-06-29 02:15:02 +02:00
parent 1ec6b0c1f7
commit 6fb3845b38
8 changed files with 95 additions and 2 deletions
@@ -210,6 +210,47 @@ Inode::LookUp(const char* name, ino_t* id)
} }
// 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
// restoration node will inocorectly become unavailable.
status_t
Inode::Remove(const char* name)
{
do {
RPC::Server* serv = fFilesystem->Server();
Request request(serv);
RequestBuilder& req = request.Builder();
req.PutFH(fHandle);
req.Remove(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();
continue;
}
// filesystem has been moved
if (reply.NFS4Error() == NFS4ERR_MOVED) {
fFilesystem->Migrate(fHandle, serv);
continue;
}
result = reply.PutFH();
if (result != B_OK)
return result;
return reply.Remove();
} while (true);
}
// Rename may cause some problems if filehandles are volatile and local Inode // Rename may cause some problems if filehandles are volatile and local Inode
// object exists for renamed node. It's stored filename will become invalid // object exists for renamed node. It's stored filename will become invalid
// and, consequnetly, filehandle restoration will fail. Probably, it will // and, consequnetly, filehandle restoration will fail. Probably, it will
@@ -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 Remove(const char* name);
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);
status_t Access(int mode); status_t Access(int mode);
@@ -34,6 +34,7 @@ enum Opcode {
OpRead = 25, OpRead = 25,
OpReadDir = 26, OpReadDir = 26,
OpReadLink = 27, OpReadLink = 27,
OpRemove = 28,
OpRename = 29, OpRename = 29,
OpRenew = 30, OpRenew = 30,
OpSaveFH = 32, OpSaveFH = 32,
@@ -290,6 +290,21 @@ ReplyInterpreter::ReadLink(void* buffer, uint32* size, uint32 maxSize)
} }
status_t
ReplyInterpreter::Remove()
{
status_t res = _OperationError(OpRemove);
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::Rename() ReplyInterpreter::Rename()
{ {
@@ -78,6 +78,7 @@ public:
status_t ReadDir(uint64* cookie, uint64* cookieVerf, status_t ReadDir(uint64* cookie, uint64* cookieVerf,
DirEntry** dirents, uint32* count, bool* eof); DirEntry** dirents, uint32* count, bool* eof);
status_t ReadLink(void* buffer, uint32* size, uint32 maxSize); status_t ReadLink(void* buffer, uint32* size, uint32 maxSize);
status_t Remove();
status_t Rename(); status_t Rename();
inline status_t Renew(); inline status_t Renew();
inline status_t SaveFH(); inline status_t SaveFH();
@@ -308,6 +308,23 @@ RequestBuilder::ReadLink()
} }
status_t
RequestBuilder::Remove(const char* file)
{
if (fProcedure != ProcCompound)
return B_BAD_VALUE;
if (fRequest == NULL)
return B_NO_MEMORY;
fRequest->Stream().AddUInt(OpRemove);
fRequest->Stream().AddString(file);
fOpCount++;
return B_OK;
}
status_t status_t
RequestBuilder::Rename(const char* from, const char* to) RequestBuilder::Rename(const char* from, const char* to)
{ {
@@ -44,6 +44,7 @@ public:
uint64 cookieVerf, Attribute* attrs, uint64 cookieVerf, Attribute* attrs,
uint32 attrCount); uint32 attrCount);
status_t ReadLink(); status_t ReadLink();
status_t Remove(const char* file);
status_t Rename(const char* from, const char* to); status_t Rename(const char* from, const char* to);
status_t Renew(uint64 clientId); status_t Renew(uint64 clientId);
status_t SaveFH(); status_t SaveFH();
@@ -212,6 +212,14 @@ nfs4_read_symlink(fs_volume* volume, fs_vnode* link, char* buffer,
} }
static status_t
nfs4_unlink(fs_volume* volume, fs_vnode* dir, const char* name)
{
Inode* inode = reinterpret_cast<Inode*>(dir->private_node);
return inode->Remove(name);
}
static status_t static status_t
nfs4_rename(fs_volume* volume, fs_vnode* fromDir, const char* fromName, nfs4_rename(fs_volume* volume, fs_vnode* fromDir, const char* fromName,
fs_vnode* toDir, const char* toName) fs_vnode* toDir, const char* toName)
@@ -309,6 +317,14 @@ nfs4_read(fs_volume* volume, fs_vnode* vnode, void* _cookie, off_t pos,
} }
static status_t
nfs4_remove_dir(fs_volume* volume, fs_vnode* parent, const char* name)
{
Inode* inode = reinterpret_cast<Inode*>(parent->private_node);
return inode->Remove(name);
}
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)
{ {
@@ -434,7 +450,7 @@ fs_vnode_ops gNFSv4VnodeOps = {
NULL, // create_symlink() NULL, // create_symlink()
NULL, // link() NULL, // link()
NULL, // unlink() nfs4_unlink,
nfs4_rename, nfs4_rename,
nfs4_access, nfs4_access,
@@ -452,7 +468,7 @@ fs_vnode_ops gNFSv4VnodeOps = {
/* directory operations */ /* directory operations */
NULL, // create_dir() NULL, // create_dir()
NULL, // remove_dir() nfs4_remove_dir,
nfs4_open_dir, nfs4_open_dir,
nfs4_close_dir, nfs4_close_dir,
nfs4_free_dir_cookie, nfs4_free_dir_cookie,