nfs4: Move file handle recovery code out of Inode class

This commit is contained in:
Pawel Dziepak
2012-07-03 19:17:04 +02:00
parent fed1e3e967
commit 9b7f2d1b24
9 changed files with 106 additions and 81 deletions
@@ -0,0 +1,90 @@
/*
* Copyright 2012 Haiku, Inc. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Authors:
* Paweł Dziepak, [email protected]
*/
#include "FileInfo.h"
#include "Filesystem.h"
#include "Request.h"
static status_t
sParsePath(RequestBuilder& req, uint32* count, const char* _path)
{
char* path = strdup(_path);
char* pathStart = path;
char* pathEnd;
while (pathStart != NULL) {
pathEnd = strpbrk(pathStart, "/");
if (pathEnd != NULL)
*pathEnd = '\0';
req.LookUp(pathStart);
if (pathEnd != NULL && pathEnd[1] != '\0')
pathStart = pathEnd + 1;
else
pathStart = NULL;
(*count)++;
}
free(path);
return B_OK;
}
status_t
FileInfo::UpdateFileHandles(Filesystem* fs)
{
Request request(fs->Server());
RequestBuilder& req = request.Builder();
req.PutRootFH();
uint32 lookupCount = 0;
sParsePath(req, &lookupCount, fs->Path());
sParsePath(req, &lookupCount, fPath);
if (fs->IsAttrSupported(FATTR4_FILEID)) {
AttrValue attr;
attr.fAttribute = FATTR4_FILEID;
attr.fFreePointer = false;
attr.fData.fValue64 = fFileId;
req.Verify(&attr, 1);
}
req.GetFH();
req.LookUpUp();
req.GetFH();
status_t result = request.Send();
if (result != B_OK)
return result;
ReplyInterpreter& reply = request.Reply();
reply.PutRootFH();
for (uint32 i = 0; i < lookupCount; i++)
reply.LookUp();
if (fs->IsAttrSupported(FATTR4_FILEID)) {
result = reply.Verify();
if (result != B_OK)
return result;
}
reply.GetFH(&fHandle);
if (reply.LookUpUp() == B_ENTRY_NOT_FOUND) {
fParent = fHandle;
return B_OK;
} else
return reply.GetFH(&fParent);
}
@@ -5,8 +5,8 @@
* Authors: * Authors:
* Paweł Dziepak, pdziepak@quarnos.org * Paweł Dziepak, pdziepak@quarnos.org
*/ */
#ifndef FILEHANDLE_H #ifndef FILEINFO_H
#define FILEHANDLE_H #define FILEINFO_H
#include <stdlib.h> #include <stdlib.h>
@@ -27,6 +27,8 @@ struct Filehandle {
}; };
class Filesystem;
// Complete information needed to identify a file in any situation. // Complete information needed to identify a file in any situation.
// Unfortunately just a filehandle is not enough even when they are persistent // Unfortunately just a filehandle is not enough even when they are persistent
// since OPEN requires both parent filehandle and file name (just like LOOKUP). // since OPEN requires both parent filehandle and file name (just like LOOKUP).
@@ -42,6 +44,8 @@ struct FileInfo {
inline ~FileInfo(); inline ~FileInfo();
inline FileInfo(const FileInfo& fi); inline FileInfo(const FileInfo& fi);
inline FileInfo& operator=(const FileInfo& fi); inline FileInfo& operator=(const FileInfo& fi);
status_t UpdateFileHandles(Filesystem* fs);
}; };
struct FilesystemId { struct FilesystemId {
@@ -140,5 +144,5 @@ FilesystemId::operator!=(const FilesystemId& fsid) const
} }
#endif // FILEHANDLE_H #endif // FILEHINFO_H
+5 -75
View File
@@ -210,8 +210,8 @@ Inode::Link(Inode* dir, const char* name)
// filehandle has expired // filehandle has expired
if (reply.NFS4Error() == NFS4ERR_FHEXPIRED) { if (reply.NFS4Error() == NFS4ERR_FHEXPIRED) {
_LookUpFilehandle(); fInfo.UpdateFileHandles(fFilesystem);
dir->_LookUpFilehandle(); dir->fInfo.UpdateFileHandles(dir->fFilesystem);
continue; continue;
} }
@@ -315,8 +315,8 @@ Inode::Rename(Inode* from, Inode* to, const char* fromName, const char* toName)
// filehandle has expired // filehandle has expired
if (reply.NFS4Error() == NFS4ERR_FHEXPIRED) { if (reply.NFS4Error() == NFS4ERR_FHEXPIRED) {
from->_LookUpFilehandle(); from->fInfo.UpdateFileHandles(from->fFilesystem);
to->_LookUpFilehandle(); to->fInfo.UpdateFileHandles(to->fFilesystem);
continue; continue;
} }
@@ -956,7 +956,7 @@ Inode::_HandleErrors(uint32 nfs4Error, RPC::Server* serv,
// filehandle has expired // filehandle has expired
case NFS4ERR_FHEXPIRED: case NFS4ERR_FHEXPIRED:
if (_LookUpFilehandle() == B_OK) if (fInfo.UpdateFileHandles(fFilesystem) == B_OK)
return true; return true;
else else
return false; return false;
@@ -980,73 +980,3 @@ Inode::_HandleErrors(uint32 nfs4Error, RPC::Server* serv,
} }
} }
static status_t
sParsePath(RequestBuilder& req, uint32* count, const char* _path)
{
char* path = strdup(_path);
char* pathStart = path;
char* pathEnd;
while (pathStart != NULL) {
pathEnd = strpbrk(pathStart, "/");
if (pathEnd != NULL)
*pathEnd = '\0';
req.LookUp(pathStart);
if (pathEnd != NULL && pathEnd[1] != '\0')
pathStart = pathEnd + 1;
else
pathStart = NULL;
(*count)++;
}
free(path);
return B_OK;
}
status_t
Inode::_LookUpFilehandle()
{
Request request(fFilesystem->Server());
RequestBuilder& req = request.Builder();
req.PutRootFH();
uint32 lookupCount = 0;
sParsePath(req, &lookupCount, fFilesystem->Path());
sParsePath(req, &lookupCount, fInfo.fPath);
req.GetFH();
if (fFilesystem->IsAttrSupported(FATTR4_FILEID)) {
AttrValue attr;
attr.fAttribute = FATTR4_FILEID;
attr.fFreePointer = false;
attr.fData.fValue64 = fInfo.fFileId;
req.Verify(&attr, 1);
}
status_t result = request.Send();
if (result != B_OK)
return result;
ReplyInterpreter& reply = request.Reply();
reply.PutRootFH();
for (uint32 i = 0; i < lookupCount; i++)
reply.LookUp();
result = reply.GetFH(&fInfo.fHandle);
if (result != B_OK)
return result;
if (fFilesystem->IsAttrSupported(FATTR4_FILEID))
return reply.Verify();
else
return B_OK;
}
@@ -74,7 +74,6 @@ protected:
bool _HandleErrors(uint32 nfs4Error, bool _HandleErrors(uint32 nfs4Error,
RPC::Server* serv, RPC::Server* serv,
OpenFileCookie* cookie = NULL); OpenFileCookie* cookie = NULL);
status_t _LookUpFilehandle();
status_t _ConfirmOpen(const Filehandle& fh, status_t _ConfirmOpen(const Filehandle& fh,
OpenFileCookie* cookie); OpenFileCookie* cookie);
@@ -14,7 +14,7 @@
#include <util/AutoLock.h> #include <util/AutoLock.h>
#include <util/AVLTreeMap.h> #include <util/AVLTreeMap.h>
#include "Filehandle.h" #include "FileInfo.h"
class InodeIdMap { class InodeIdMap {
@@ -6,6 +6,7 @@ UsePrivateHeaders shared ;
KernelAddon nfs4 : KernelAddon nfs4 :
Cookie.cpp Cookie.cpp
Connection.cpp Connection.cpp
FileInfo.cpp
Filesystem.cpp Filesystem.cpp
Inode.cpp Inode.cpp
InodeDir.cpp InodeDir.cpp
@@ -14,7 +14,6 @@
#include <SupportDefs.h> #include <SupportDefs.h>
#include "Filehandle.h"
enum Procedure { enum Procedure {
ProcNull = 0, ProcNull = 0,
@@ -11,6 +11,7 @@
#include <SupportDefs.h> #include <SupportDefs.h>
#include "FileInfo.h"
#include "NFS4Defs.h" #include "NFS4Defs.h"
#include "RPCReply.h" #include "RPCReply.h"
@@ -11,6 +11,7 @@
#include <SupportDefs.h> #include <SupportDefs.h>
#include "FileInfo.h"
#include "NFS4Defs.h" #include "NFS4Defs.h"
#include "ReplyInterpreter.h" #include "ReplyInterpreter.h"
#include "RPCCall.h" #include "RPCCall.h"