nfs4: Fix node removal

This commit is contained in:
Pawel Dziepak
2012-08-17 02:51:20 +02:00
parent 8568341ae6
commit 7c6cdb8360
7 changed files with 36 additions and 11 deletions
@@ -266,7 +266,7 @@ Inode::Link(Inode* dir, const char* name)
status_t status_t
Inode::Remove(const char* name, FileType type) Inode::Remove(const char* name, FileType type, ino_t* id)
{ {
MemoryDeleter nameDeleter; MemoryDeleter nameDeleter;
if (type == NF4NAMEDATTR) { if (type == NF4NAMEDATTR) {
@@ -298,6 +298,8 @@ Inode::Remove(const char* name, FileType type)
} }
fFileSystem->Root()->MakeInfoInvalid(); fFileSystem->Root()->MakeInfoInvalid();
if (id != NULL)
*id = FileIdToInoT(fileID);
if (type == NF4NAMEDATTR) { if (type == NF4NAMEDATTR) {
notify_attribute_changed(fFileSystem->DevId(), ID(), name, notify_attribute_changed(fFileSystem->DevId(), ID(), name,
+2 -1
View File
@@ -57,7 +57,8 @@ public:
int mode); int mode);
status_t Link(Inode* dir, const char* name); 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, static status_t Rename(Inode* from, Inode* to,
const char* fromName, const char* toName, const char* fromName, const char* toName,
bool attribute = false); bool attribute = false);
@@ -303,6 +303,13 @@ enum Errors {
NFS4ERR_ISDIR = 21, NFS4ERR_ISDIR = 21,
NFS4ERR_INVAL = 22, NFS4ERR_INVAL = 22,
NFS4ERR_FBIG = 27, 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_BADHANDLE = 10001,
NFS4ERR_BAD_COOKIE = 10003, NFS4ERR_BAD_COOKIE = 10003,
NFS4ERR_NOTSUPP = 10004, NFS4ERR_NOTSUPP = 10004,
@@ -824,13 +824,12 @@ NFS4Inode::RemoveObject(const char* name, FileType type, ChangeInfo* changeInfo,
else else
req.Nverify(&attr, 1); req.Nverify(&attr, 1);
req.PutFH(fInfo.fHandle);
if (type != NF4NAMEDATTR) { if (type != NF4NAMEDATTR) {
Attribute idAttr[] = { FATTR4_FILEID }; Attribute idAttr[] = { FATTR4_FILEID };
req.GetAttr(idAttr, sizeof(idAttr) / sizeof(Attribute)); req.GetAttr(idAttr, sizeof(idAttr) / sizeof(Attribute));
} }
req.PutFH(fInfo.fHandle);
req.Remove(name); req.Remove(name);
status_t result = request.Send(); status_t result = request.Send();
@@ -859,8 +858,6 @@ NFS4Inode::RemoveObject(const char* name, FileType type, ChangeInfo* changeInfo,
if (result != B_OK) if (result != B_OK)
return result; return result;
reply.PutFH();
if (type != NF4NAMEDATTR) { if (type != NF4NAMEDATTR) {
AttrValue* values; AttrValue* values;
uint32 count; uint32 count;
@@ -875,6 +872,7 @@ NFS4Inode::RemoveObject(const char* name, FileType type, ChangeInfo* changeInfo,
delete[] values; delete[] values;
} }
reply.PutFH();
return reply.Remove(&changeInfo->fBefore, &changeInfo->fAfter, return reply.Remove(&changeInfo->fBefore, &changeInfo->fAfter,
changeInfo->fAtomic); changeInfo->fAtomic);
} while (true); } while (true);
@@ -110,10 +110,11 @@ NFS4Object::HandleErrors(uint32 nfs4Error, RPC::Server* serv,
} }
return false; 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_NOFILEHANDLE:
case NFS4ERR_BADHANDLE: case NFS4ERR_BADHANDLE:
case NFS4ERR_FHEXPIRED: case NFS4ERR_FHEXPIRED:
case NFS4ERR_STALE:
if (fInfo.UpdateFileHandles(fFileSystem) == B_OK) if (fInfo.UpdateFileHandles(fFileSystem) == B_OK)
return true; return true;
return false; return false;
@@ -829,13 +829,19 @@ ReplyInterpreter::_NFS4ErrorToHaiku(uint32 x)
case NFS4ERR_INVAL: return B_BAD_VALUE; case NFS4ERR_INVAL: return B_BAD_VALUE;
case NFS4ERR_FBIG: return B_FILE_TOO_LARGE; case NFS4ERR_FBIG: return B_FILE_TOO_LARGE;
case NFS4ERR_NOTSUPP: return B_UNSUPPORTED; 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_DELAY:
case NFS4ERR_DENIED: case NFS4ERR_DENIED:
case NFS4ERR_LOCKED: case NFS4ERR_LOCKED:
case NFS4ERR_GRACE: case NFS4ERR_GRACE:
return B_WOULD_BLOCK; 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; default: return B_ERROR;
} }
@@ -413,7 +413,13 @@ 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)
{ {
Inode* inode = reinterpret_cast<Inode*>(dir->private_node); 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) nfs4_remove_dir(fs_volume* volume, fs_vnode* parent, const char* name)
{ {
Inode* inode = reinterpret_cast<Inode*>(parent->private_node); 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) nfs4_remove_attr(fs_volume* volume, fs_vnode* vnode, const char* name)
{ {
Inode* inode = reinterpret_cast<Inode*>(vnode->private_node); Inode* inode = reinterpret_cast<Inode*>(vnode->private_node);
return inode->Remove(name, NF4NAMEDATTR); return inode->Remove(name, NF4NAMEDATTR, NULL);
} }