nfs4: Fix node removal
This commit is contained in:
@@ -266,7 +266,7 @@ Inode::Link(Inode* dir, const char* name)
|
||||
|
||||
|
||||
status_t
|
||||
Inode::Remove(const char* name, FileType type)
|
||||
Inode::Remove(const char* name, FileType type, ino_t* id)
|
||||
{
|
||||
MemoryDeleter nameDeleter;
|
||||
if (type == NF4NAMEDATTR) {
|
||||
@@ -298,6 +298,8 @@ Inode::Remove(const char* name, FileType type)
|
||||
}
|
||||
|
||||
fFileSystem->Root()->MakeInfoInvalid();
|
||||
if (id != NULL)
|
||||
*id = FileIdToInoT(fileID);
|
||||
|
||||
if (type == NF4NAMEDATTR) {
|
||||
notify_attribute_changed(fFileSystem->DevId(), ID(), name,
|
||||
|
||||
@@ -57,7 +57,8 @@ public:
|
||||
int mode);
|
||||
|
||||
status_t Link(Inode* dir, const char* name);
|
||||
status_t Remove(const char* name, FileType type);
|
||||
status_t Remove(const char* name, FileType type,
|
||||
ino_t* id);
|
||||
static status_t Rename(Inode* from, Inode* to,
|
||||
const char* fromName, const char* toName,
|
||||
bool attribute = false);
|
||||
|
||||
@@ -303,6 +303,13 @@ enum Errors {
|
||||
NFS4ERR_ISDIR = 21,
|
||||
NFS4ERR_INVAL = 22,
|
||||
NFS4ERR_FBIG = 27,
|
||||
NFS4ERR_NOSPC = 28,
|
||||
NFS4ERR_ROFS = 30,
|
||||
NFS4ERR_MLINK = 31,
|
||||
NFS4ERR_NAMETOOLONG = 63,
|
||||
NFS4ERR_NOTEMPTY = 66,
|
||||
NFS4ERR_DQUOT = 69,
|
||||
NFS4ERR_STALE = 70,
|
||||
NFS4ERR_BADHANDLE = 10001,
|
||||
NFS4ERR_BAD_COOKIE = 10003,
|
||||
NFS4ERR_NOTSUPP = 10004,
|
||||
|
||||
@@ -824,13 +824,12 @@ NFS4Inode::RemoveObject(const char* name, FileType type, ChangeInfo* changeInfo,
|
||||
else
|
||||
req.Nverify(&attr, 1);
|
||||
|
||||
req.PutFH(fInfo.fHandle);
|
||||
|
||||
if (type != NF4NAMEDATTR) {
|
||||
Attribute idAttr[] = { FATTR4_FILEID };
|
||||
req.GetAttr(idAttr, sizeof(idAttr) / sizeof(Attribute));
|
||||
}
|
||||
|
||||
req.PutFH(fInfo.fHandle);
|
||||
req.Remove(name);
|
||||
|
||||
status_t result = request.Send();
|
||||
@@ -859,8 +858,6 @@ NFS4Inode::RemoveObject(const char* name, FileType type, ChangeInfo* changeInfo,
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
reply.PutFH();
|
||||
|
||||
if (type != NF4NAMEDATTR) {
|
||||
AttrValue* values;
|
||||
uint32 count;
|
||||
@@ -875,6 +872,7 @@ NFS4Inode::RemoveObject(const char* name, FileType type, ChangeInfo* changeInfo,
|
||||
delete[] values;
|
||||
}
|
||||
|
||||
reply.PutFH();
|
||||
return reply.Remove(&changeInfo->fBefore, &changeInfo->fAfter,
|
||||
changeInfo->fAtomic);
|
||||
} while (true);
|
||||
|
||||
@@ -110,10 +110,11 @@ NFS4Object::HandleErrors(uint32 nfs4Error, RPC::Server* serv,
|
||||
}
|
||||
return false;
|
||||
|
||||
// FileHandle has expired or is invalid
|
||||
// File Handle has expired, is invalid or the node has been deleted
|
||||
case NFS4ERR_NOFILEHANDLE:
|
||||
case NFS4ERR_BADHANDLE:
|
||||
case NFS4ERR_FHEXPIRED:
|
||||
case NFS4ERR_STALE:
|
||||
if (fInfo.UpdateFileHandles(fFileSystem) == B_OK)
|
||||
return true;
|
||||
return false;
|
||||
|
||||
@@ -829,13 +829,19 @@ ReplyInterpreter::_NFS4ErrorToHaiku(uint32 x)
|
||||
case NFS4ERR_INVAL: return B_BAD_VALUE;
|
||||
case NFS4ERR_FBIG: return B_FILE_TOO_LARGE;
|
||||
case NFS4ERR_NOTSUPP: return B_UNSUPPORTED;
|
||||
case NFS4ERR_ROFS: return B_READ_ONLY_DEVICE;
|
||||
case NFS4ERR_NAMETOOLONG: return B_NAME_TOO_LONG;
|
||||
case NFS4ERR_NOTEMPTY: return B_DIRECTORY_NOT_EMPTY;
|
||||
// ...
|
||||
case NFS4ERR_DELAY:
|
||||
case NFS4ERR_DENIED:
|
||||
case NFS4ERR_LOCKED:
|
||||
case NFS4ERR_GRACE:
|
||||
return B_WOULD_BLOCK;
|
||||
case NFS4ERR_FHEXPIRED: return B_ENTRY_NOT_FOUND;
|
||||
|
||||
case NFS4ERR_STALE:
|
||||
case NFS4ERR_FHEXPIRED:
|
||||
return B_FILE_NOT_FOUND;
|
||||
// ...
|
||||
default: return B_ERROR;
|
||||
}
|
||||
|
||||
@@ -413,7 +413,13 @@ 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, NF4REG);
|
||||
|
||||
ino_t id;
|
||||
status_t result = inode->Remove(name, NF4REG, &id);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
return remove_vnode(volume, id);
|
||||
}
|
||||
|
||||
|
||||
@@ -607,7 +613,11 @@ 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, NF4DIR);
|
||||
ino_t id;
|
||||
status_t result = inode->Remove(name, NF4DIR, &id);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
return remove_vnode(volume, id);
|
||||
}
|
||||
|
||||
|
||||
@@ -826,7 +836,7 @@ static status_t
|
||||
nfs4_remove_attr(fs_volume* volume, fs_vnode* vnode, const char* name)
|
||||
{
|
||||
Inode* inode = reinterpret_cast<Inode*>(vnode->private_node);
|
||||
return inode->Remove(name, NF4NAMEDATTR);
|
||||
return inode->Remove(name, NF4NAMEDATTR, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user