From 7c6cdb836049521a65ae47018e15020b1701dc5c Mon Sep 17 00:00:00 2001 From: Pawel Dziepak Date: Fri, 17 Aug 2012 02:51:20 +0200 Subject: [PATCH] nfs4: Fix node removal --- src/add-ons/kernel/file_systems/nfs4/Inode.cpp | 4 +++- src/add-ons/kernel/file_systems/nfs4/Inode.h | 3 ++- src/add-ons/kernel/file_systems/nfs4/NFS4Defs.h | 7 +++++++ .../kernel/file_systems/nfs4/NFS4Inode.cpp | 6 ++---- .../kernel/file_systems/nfs4/NFS4Object.cpp | 3 ++- .../file_systems/nfs4/ReplyInterpreter.cpp | 8 +++++++- .../file_systems/nfs4/kernel_interface.cpp | 16 +++++++++++++--- 7 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp index 29f9cb7bb2..2ff488e8de 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Inode.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/Inode.cpp @@ -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, diff --git a/src/add-ons/kernel/file_systems/nfs4/Inode.h b/src/add-ons/kernel/file_systems/nfs4/Inode.h index 3815e9741e..6c9e1fc9de 100644 --- a/src/add-ons/kernel/file_systems/nfs4/Inode.h +++ b/src/add-ons/kernel/file_systems/nfs4/Inode.h @@ -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); diff --git a/src/add-ons/kernel/file_systems/nfs4/NFS4Defs.h b/src/add-ons/kernel/file_systems/nfs4/NFS4Defs.h index 1a617ff67f..236d37742f 100644 --- a/src/add-ons/kernel/file_systems/nfs4/NFS4Defs.h +++ b/src/add-ons/kernel/file_systems/nfs4/NFS4Defs.h @@ -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, diff --git a/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.cpp b/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.cpp index 43ae3fe060..3ae8de5beb 100644 --- a/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/NFS4Inode.cpp @@ -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); diff --git a/src/add-ons/kernel/file_systems/nfs4/NFS4Object.cpp b/src/add-ons/kernel/file_systems/nfs4/NFS4Object.cpp index e24abcecd0..918c44f473 100644 --- a/src/add-ons/kernel/file_systems/nfs4/NFS4Object.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/NFS4Object.cpp @@ -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; diff --git a/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp b/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp index bf4f4dd2ac..4ed2023277 100644 --- a/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/ReplyInterpreter.cpp @@ -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; } diff --git a/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp b/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp index a675138ce9..c2e4b6ae17 100644 --- a/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp +++ b/src/add-ons/kernel/file_systems/nfs4/kernel_interface.cpp @@ -413,7 +413,13 @@ static status_t nfs4_unlink(fs_volume* volume, fs_vnode* dir, const char* name) { Inode* inode = reinterpret_cast(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(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(vnode->private_node); - return inode->Remove(name, NF4NAMEDATTR); + return inode->Remove(name, NF4NAMEDATTR, NULL); }