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:
|
* 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
|
||||||
|
|
||||||
@@ -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"
|
||||||
|
|||||||
Reference in New Issue
Block a user