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:
* Paweł Dziepak, pdziepak@quarnos.org
*/
#ifndef FILEHANDLE_H
#define FILEHANDLE_H
#ifndef FILEINFO_H
#define FILEINFO_H
#include <stdlib.h>
@@ -27,6 +27,8 @@ struct Filehandle {
};
class Filesystem;
// Complete information needed to identify a file in any situation.
// Unfortunately just a filehandle is not enough even when they are persistent
// since OPEN requires both parent filehandle and file name (just like LOOKUP).
@@ -42,6 +44,8 @@ struct FileInfo {
inline ~FileInfo();
inline FileInfo(const FileInfo& fi);
inline FileInfo& operator=(const FileInfo& fi);
status_t UpdateFileHandles(Filesystem* fs);
};
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
if (reply.NFS4Error() == NFS4ERR_FHEXPIRED) {
_LookUpFilehandle();
dir->_LookUpFilehandle();
fInfo.UpdateFileHandles(fFilesystem);
dir->fInfo.UpdateFileHandles(dir->fFilesystem);
continue;
}
@@ -315,8 +315,8 @@ Inode::Rename(Inode* from, Inode* to, const char* fromName, const char* toName)
// filehandle has expired
if (reply.NFS4Error() == NFS4ERR_FHEXPIRED) {
from->_LookUpFilehandle();
to->_LookUpFilehandle();
from->fInfo.UpdateFileHandles(from->fFilesystem);
to->fInfo.UpdateFileHandles(to->fFilesystem);
continue;
}
@@ -956,7 +956,7 @@ Inode::_HandleErrors(uint32 nfs4Error, RPC::Server* serv,
// filehandle has expired
case NFS4ERR_FHEXPIRED:
if (_LookUpFilehandle() == B_OK)
if (fInfo.UpdateFileHandles(fFilesystem) == B_OK)
return true;
else
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,
RPC::Server* serv,
OpenFileCookie* cookie = NULL);
status_t _LookUpFilehandle();
status_t _ConfirmOpen(const Filehandle& fh,
OpenFileCookie* cookie);
@@ -14,7 +14,7 @@
#include <util/AutoLock.h>
#include <util/AVLTreeMap.h>
#include "Filehandle.h"
#include "FileInfo.h"
class InodeIdMap {
@@ -6,6 +6,7 @@ UsePrivateHeaders shared ;
KernelAddon nfs4 :
Cookie.cpp
Connection.cpp
FileInfo.cpp
Filesystem.cpp
Inode.cpp
InodeDir.cpp
@@ -14,7 +14,6 @@
#include <SupportDefs.h>
#include "Filehandle.h"
enum Procedure {
ProcNull = 0,
@@ -11,6 +11,7 @@
#include <SupportDefs.h>
#include "FileInfo.h"
#include "NFS4Defs.h"
#include "RPCReply.h"
@@ -11,6 +11,7 @@
#include <SupportDefs.h>
#include "FileInfo.h"
#include "NFS4Defs.h"
#include "ReplyInterpreter.h"
#include "RPCCall.h"