nfs4: Move file handle recovery code out of Inode class
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
+7
-3
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in New Issue
Block a user