mirror of
https://review.haiku-os.org/haiku
synced 2025-02-07 06:16:11 +01:00
nfs4: Fix timeout handling code
This commit is contained in:
parent
d8a223873f
commit
0792abe006
@ -135,9 +135,10 @@ Filesystem::GetInode(ino_t id, Inode** _inode)
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
Inode* inode = new(std::nothrow)Inode(this, fi);
|
||||
if (inode == NULL)
|
||||
return B_NO_MEMORY;
|
||||
Inode* inode;
|
||||
result = Inode::CreateInode(this, fi, &inode);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
*_inode = inode;
|
||||
return B_OK;
|
||||
@ -151,6 +152,12 @@ Filesystem::CreateRootInode()
|
||||
fi.fFH = fRootFH;
|
||||
fi.fParent = fRootFH;
|
||||
fi.fName = strdup("/");
|
||||
return new(std::nothrow)Inode(this, fi);
|
||||
|
||||
Inode* inode;
|
||||
status_t result = Inode::CreateInode(this, fi, &inode);
|
||||
if (result == B_OK)
|
||||
return inode;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -15,51 +15,65 @@
|
||||
#include "Request.h"
|
||||
|
||||
|
||||
Inode::Inode()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// Creating Inode object from Filehandle probably is not a good idea when
|
||||
// filehandles are volatile.
|
||||
Inode::Inode(Filesystem* fs, const FileInfo &fi)
|
||||
:
|
||||
fHandle(fi.fFH),
|
||||
fFilesystem(fs),
|
||||
fParentFH(fi.fParent),
|
||||
fName(strdup(fi.fName))
|
||||
status_t
|
||||
Inode::CreateInode(Filesystem* fs, const FileInfo &fi, Inode** _inode)
|
||||
{
|
||||
Request request(fFilesystem->Server());
|
||||
Inode* inode = new(std::nothrow) Inode;
|
||||
if (inode == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
inode->fHandle = fi.fFH;
|
||||
inode->fFilesystem = fs;
|
||||
inode->fParentFH = fi.fParent;
|
||||
inode->fName = strdup(fi.fName);
|
||||
|
||||
Request request(fs->Server());
|
||||
RequestBuilder& req = request.Builder();
|
||||
|
||||
req.PutFH(fHandle);
|
||||
req.PutFH(inode->fHandle);
|
||||
|
||||
Attribute attr[] = { FATTR4_TYPE, FATTR4_FILEID };
|
||||
req.GetAttr(attr, sizeof(attr) / sizeof(Attribute));
|
||||
|
||||
status_t result = request.Send();
|
||||
if (result != B_OK)
|
||||
return;
|
||||
return result;
|
||||
|
||||
ReplyInterpreter& reply = request.Reply();
|
||||
|
||||
result = reply.PutFH();
|
||||
if (result != B_OK)
|
||||
return;
|
||||
return result;
|
||||
|
||||
AttrValue* values;
|
||||
uint32 count;
|
||||
result = reply.GetAttr(&values, &count);
|
||||
if (result != B_OK || count < 1)
|
||||
return;
|
||||
return result;
|
||||
|
||||
if (fi.fFileId == 0) {
|
||||
if (count < 2 || values[1].fAttribute != FATTR4_FILEID)
|
||||
fFileId = fs->AllocFileId();
|
||||
inode->fFileId = fs->AllocFileId();
|
||||
else
|
||||
fFileId = values[1].fData.fValue64;
|
||||
inode->fFileId = values[1].fData.fValue64;
|
||||
} else
|
||||
fFileId = fi.fFileId;
|
||||
inode->fFileId = fi.fFileId;
|
||||
|
||||
// FATTR4_TYPE is mandatory
|
||||
fType = values[0].fData.fValue32;
|
||||
inode->fType = values[0].fData.fValue32;
|
||||
|
||||
delete[] values;
|
||||
|
||||
*_inode = inode;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
|
@ -26,7 +26,8 @@ struct OpenFileCookie {
|
||||
|
||||
class Inode {
|
||||
public:
|
||||
Inode(Filesystem* fs, const FileInfo& fi);
|
||||
static status_t CreateInode(Filesystem* fs, const FileInfo& fi,
|
||||
Inode** inode);
|
||||
~Inode();
|
||||
|
||||
inline ino_t ID() const;
|
||||
@ -47,6 +48,8 @@ public:
|
||||
uint32* count, uint64* cookie);
|
||||
|
||||
private:
|
||||
Inode();
|
||||
|
||||
status_t _ReadDirOnce(DirEntry** dirents, uint32* count,
|
||||
uint64* cookie, bool* eof);
|
||||
status_t _FillDirEntry(struct dirent* de, ino_t id,
|
||||
|
@ -150,6 +150,8 @@ Server::SendCallAsync(Call* call, Reply** reply, Request** request)
|
||||
call->SetXID(xid);
|
||||
req->fXID = xid;
|
||||
req->fReply = reply;
|
||||
req->fEvent.Init(&req->fEvent, NULL);
|
||||
req->fDone = false;
|
||||
req->fNext = NULL;
|
||||
|
||||
fRequests.AddRequest(req);
|
||||
@ -227,6 +229,7 @@ Server::_Listener()
|
||||
Request* req = fRequests.FindRequest(reply->GetXID());
|
||||
if (req != NULL) {
|
||||
*req->fReply = reply;
|
||||
req->fDone = true;
|
||||
req->fEvent.NotifyAll();
|
||||
} else
|
||||
delete reply;
|
||||
|
@ -22,6 +22,7 @@ namespace RPC {
|
||||
struct Request {
|
||||
uint32 fXID;
|
||||
ConditionVariable fEvent;
|
||||
bool fDone;
|
||||
Reply** fReply;
|
||||
|
||||
Request* fNext;
|
||||
@ -86,6 +87,8 @@ private:
|
||||
inline status_t
|
||||
Server::WaitCall(Request* request, bigtime_t time)
|
||||
{
|
||||
if (request->fDone)
|
||||
return B_OK;
|
||||
return request->fEvent.Wait(B_RELATIVE_TIMEOUT, time);
|
||||
}
|
||||
|
||||
|
@ -35,10 +35,15 @@ Request::_SendUDP()
|
||||
result = fServer->WaitCall(rpc);
|
||||
if (result != B_OK) {
|
||||
int attempts = 1;
|
||||
while (result != B_OK && attempts++ < kRetryLimit)
|
||||
while (result != B_OK && attempts++ < kRetryLimit) {
|
||||
result = fServer->ResendCallAsync(fBuilder.Request(), rpc);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
if (attempts == kRetryLimit) {
|
||||
result = fServer->WaitCall(rpc);
|
||||
}
|
||||
|
||||
if (result != B_OK) {
|
||||
fServer->CancelCall(rpc);
|
||||
delete rpc;
|
||||
return result;
|
||||
|
@ -50,6 +50,12 @@ nfs4_mount(fs_volume* volume, const char* device, uint32 flags,
|
||||
}
|
||||
|
||||
Inode* inode = fs->CreateRootInode();
|
||||
if (inode == NULL) {
|
||||
delete fs;
|
||||
gRPCServerManager->Release(server);
|
||||
|
||||
return B_IO_ERROR;
|
||||
}
|
||||
|
||||
volume->private_volume = fs;
|
||||
volume->ops = &gNFSv4VolumeOps;
|
||||
|
Loading…
x
Reference in New Issue
Block a user