nfs4: close*() should wake all blocked operations
This commit is contained in:
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2012 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Paweł Dziepak, [email protected]
|
||||
*/
|
||||
|
||||
|
||||
#include "Cookie.h"
|
||||
|
||||
#include "Inode.h"
|
||||
#include "Request.h"
|
||||
|
||||
|
||||
vint64 OpenFileCookie::fLastOwnerId = 0;
|
||||
|
||||
|
||||
Cookie::Cookie()
|
||||
:
|
||||
fRequests(NULL)
|
||||
{
|
||||
mutex_init(&fRequestLock, NULL);
|
||||
}
|
||||
|
||||
|
||||
Cookie::~Cookie()
|
||||
{
|
||||
mutex_destroy(&fRequestLock);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Cookie::RegisterRequest(RPC::Request* req)
|
||||
{
|
||||
mutex_lock(&fRequestLock);
|
||||
RequestEntry* ent = new RequestEntry;
|
||||
if (ent == NULL) {
|
||||
mutex_unlock(&fRequestLock);
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
ent->fRequest = req;
|
||||
ent->fNext = fRequests;
|
||||
fRequests = ent;
|
||||
mutex_unlock(&fRequestLock);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Cookie::UnregisterRequest(RPC::Request* req)
|
||||
{
|
||||
mutex_lock(&fRequestLock);
|
||||
RequestEntry* ent = fRequests;
|
||||
RequestEntry* prev = NULL;
|
||||
while (ent != NULL) {
|
||||
if (ent->fRequest == req) {
|
||||
if (prev == NULL)
|
||||
fRequests = ent->fNext;
|
||||
else
|
||||
prev->fNext = ent->fNext;
|
||||
delete ent;
|
||||
}
|
||||
|
||||
prev = ent;
|
||||
ent = ent->fNext;
|
||||
}
|
||||
mutex_unlock(&fRequestLock);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Cookie::CancelAll()
|
||||
{
|
||||
mutex_lock(&fRequestLock);
|
||||
RequestEntry* ent = fRequests;
|
||||
while (ent != NULL) {
|
||||
fInode->FileSystem()->Server()->WakeCall(ent->fRequest);
|
||||
ent = ent->fNext;
|
||||
}
|
||||
mutex_unlock(&fRequestLock);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2012 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Paweł Dziepak, [email protected]
|
||||
*/
|
||||
#ifndef COOKIE_H
|
||||
#define COOKIE_H
|
||||
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#include "Filesystem.h"
|
||||
|
||||
class Inode;
|
||||
|
||||
struct Cookie {
|
||||
struct RequestEntry {
|
||||
RPC::Request* fRequest;
|
||||
RequestEntry* fNext;
|
||||
};
|
||||
|
||||
Inode* fInode;
|
||||
RequestEntry* fRequests;
|
||||
mutex fRequestLock;
|
||||
|
||||
Cookie();
|
||||
virtual ~Cookie();
|
||||
|
||||
status_t RegisterRequest(RPC::Request* req);
|
||||
status_t UnregisterRequest(RPC::Request* req);
|
||||
status_t CancelAll();
|
||||
};
|
||||
|
||||
struct OpenFileCookie : public Cookie {
|
||||
uint64 fClientId;
|
||||
|
||||
uint32 fMode;
|
||||
|
||||
Filehandle fHandle;
|
||||
uint32 fStateId[3];
|
||||
uint32 fStateSeq;
|
||||
|
||||
uint32 fSequence;
|
||||
|
||||
uint64 fOwnerId;
|
||||
static vint64 fLastOwnerId;
|
||||
|
||||
OpenFileCookie* fNext;
|
||||
OpenFileCookie* fPrev;
|
||||
};
|
||||
|
||||
struct OpenDirCookie : public Cookie {
|
||||
uint64 fCookie;
|
||||
uint64 fCookieVerf;
|
||||
};
|
||||
|
||||
|
||||
#endif // COOKIE_H
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
#include "Request.h"
|
||||
|
||||
|
||||
vint64 OpenFileCookie::fLastOwnerId = 0;
|
||||
|
||||
|
||||
Inode::Inode()
|
||||
{
|
||||
}
|
||||
@@ -447,6 +444,7 @@ Inode::Open(int mode, OpenFileCookie* cookie)
|
||||
bool confirm;
|
||||
status_t result;
|
||||
|
||||
cookie->fInode = this;
|
||||
cookie->fHandle = fHandle;
|
||||
cookie->fMode = mode;
|
||||
cookie->fSequence = 0;
|
||||
@@ -610,7 +608,7 @@ Inode::Read(OpenFileCookie* cookie, off_t pos, void* buffer, size_t* _length)
|
||||
req.Read(cookie->fStateId, cookie->fStateSeq, pos + size,
|
||||
*_length - size);
|
||||
|
||||
status_t result = request.Send();
|
||||
status_t result = request.Send(cookie);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
@@ -664,7 +662,7 @@ Inode::Read(OpenFileCookie* cookie, off_t pos, void* buffer, size_t* _length)
|
||||
|
||||
|
||||
status_t
|
||||
Inode::OpenDir(uint64* cookie)
|
||||
Inode::OpenDir(OpenDirCookie* cookie)
|
||||
{
|
||||
if (fType != NF4DIR)
|
||||
return B_NOT_A_DIRECTORY;
|
||||
@@ -707,8 +705,9 @@ Inode::OpenDir(uint64* cookie)
|
||||
if (allowed & ACCESS4_READ != ACCESS4_READ)
|
||||
return B_PERMISSION_DENIED;
|
||||
|
||||
cookie[0] = 0;
|
||||
cookie[1] = 2;
|
||||
cookie->fInode = this;
|
||||
cookie->fCookie = 0;
|
||||
cookie->fCookieVerf = 2;
|
||||
|
||||
return B_OK;
|
||||
} while (true);
|
||||
@@ -716,7 +715,7 @@ Inode::OpenDir(uint64* cookie)
|
||||
|
||||
|
||||
status_t
|
||||
Inode::_ReadDirOnce(DirEntry** dirents, uint32* count, uint64* cookie,
|
||||
Inode::_ReadDirOnce(DirEntry** dirents, uint32* count, OpenDirCookie* cookie,
|
||||
bool* eof)
|
||||
{
|
||||
do {
|
||||
@@ -727,9 +726,10 @@ Inode::_ReadDirOnce(DirEntry** dirents, uint32* count, uint64* cookie,
|
||||
req.PutFH(fHandle);
|
||||
|
||||
Attribute attr[] = { FATTR4_FSID, FATTR4_FILEID };
|
||||
req.ReadDir(*count, cookie, attr, sizeof(attr) / sizeof(Attribute));
|
||||
req.ReadDir(*count, cookie->fCookie, cookie->fCookieVerf, attr,
|
||||
sizeof(attr) / sizeof(Attribute));
|
||||
|
||||
status_t result = request.Send();
|
||||
status_t result = request.Send(cookie);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
@@ -751,7 +751,8 @@ Inode::_ReadDirOnce(DirEntry** dirents, uint32* count, uint64* cookie,
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
return reply.ReadDir(cookie, dirents, count, eof);
|
||||
return reply.ReadDir(&cookie->fCookie, &cookie->fCookieVerf, dirents,
|
||||
count, eof);
|
||||
} while (true);
|
||||
}
|
||||
|
||||
@@ -846,7 +847,8 @@ Inode::_ReadDirUp(struct dirent* de, uint32 pos, uint32 size)
|
||||
// When directories are cached client should store inode numbers it assigned
|
||||
// to directroy entries and use them consequently.
|
||||
status_t
|
||||
Inode::ReadDir(void* _buffer, uint32 size, uint32* _count, uint64* cookie)
|
||||
Inode::ReadDir(void* _buffer, uint32 size, uint32* _count,
|
||||
OpenDirCookie* cookie)
|
||||
{
|
||||
uint32 count = 0;
|
||||
uint32 pos = 0;
|
||||
@@ -855,17 +857,17 @@ Inode::ReadDir(void* _buffer, uint32 size, uint32* _count, uint64* cookie)
|
||||
|
||||
char* buffer = reinterpret_cast<char*>(_buffer);
|
||||
|
||||
if (cookie[0] == 0 && cookie[1] == 2 && count < *_count) {
|
||||
if (cookie->fCookie == 0 && cookie->fCookieVerf == 2 && count < *_count) {
|
||||
struct dirent* de = reinterpret_cast<dirent*>(buffer + pos);
|
||||
|
||||
_FillDirEntry(de, fFileId, ".", pos, size);
|
||||
|
||||
pos += de->d_reclen;
|
||||
count++;
|
||||
cookie[1]--;
|
||||
cookie->fCookieVerf--;
|
||||
}
|
||||
|
||||
if (cookie[0] == 0 && cookie[1] == 1 && count < *_count) {
|
||||
if (cookie->fCookie == 0 && cookie->fCookieVerf == 1 && count < *_count) {
|
||||
struct dirent* de = reinterpret_cast<dirent*>(buffer + pos);
|
||||
|
||||
if (strcmp(fName, "/"))
|
||||
@@ -875,7 +877,7 @@ Inode::ReadDir(void* _buffer, uint32 size, uint32* _count, uint64* cookie)
|
||||
|
||||
pos += de->d_reclen;
|
||||
count++;
|
||||
cookie[1]--;
|
||||
cookie->fCookieVerf--;
|
||||
}
|
||||
|
||||
bool overflow = false;
|
||||
|
||||
@@ -13,29 +13,12 @@
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#include "Cookie.h"
|
||||
#include "Filesystem.h"
|
||||
#include "NFS4Defs.h"
|
||||
#include "ReplyInterpreter.h"
|
||||
|
||||
|
||||
struct OpenFileCookie {
|
||||
uint64 fClientId;
|
||||
|
||||
uint32 fMode;
|
||||
|
||||
Filehandle fHandle;
|
||||
uint32 fStateId[3];
|
||||
uint32 fStateSeq;
|
||||
|
||||
uint32 fSequence;
|
||||
|
||||
uint64 fOwnerId;
|
||||
static vint64 fLastOwnerId;
|
||||
|
||||
OpenFileCookie* fNext;
|
||||
OpenFileCookie* fPrev;
|
||||
};
|
||||
|
||||
class Inode {
|
||||
public:
|
||||
static status_t CreateInode(Filesystem* fs, const FileInfo& fi,
|
||||
@@ -45,6 +28,7 @@ public:
|
||||
inline ino_t ID() const;
|
||||
inline mode_t Type() const;
|
||||
inline const char* Name() const;
|
||||
inline Filesystem* FileSystem() const;
|
||||
|
||||
status_t LookUp(const char* name, ino_t* id);
|
||||
status_t ReadLink(void* buffer, size_t* length);
|
||||
@@ -56,9 +40,9 @@ public:
|
||||
status_t Read(OpenFileCookie* cookie, off_t pos,
|
||||
void* buffer, size_t* length);
|
||||
|
||||
status_t OpenDir(uint64* cookie);
|
||||
status_t OpenDir(OpenDirCookie* cookie);
|
||||
status_t ReadDir(void* buffer, uint32 size,
|
||||
uint32* count, uint64* cookie);
|
||||
uint32* count, OpenDirCookie* cookie);
|
||||
|
||||
private:
|
||||
Inode();
|
||||
@@ -66,7 +50,7 @@ private:
|
||||
status_t _LookUpFilehandle();
|
||||
|
||||
status_t _ReadDirOnce(DirEntry** dirents, uint32* count,
|
||||
uint64* cookie, bool* eof);
|
||||
OpenDirCookie* cookie, bool* eof);
|
||||
status_t _FillDirEntry(struct dirent* de, ino_t id,
|
||||
const char* name, uint32 pos, uint32 size);
|
||||
status_t _ReadDirUp(struct dirent* de, uint32 pos,
|
||||
@@ -119,5 +103,12 @@ Inode::Name() const
|
||||
}
|
||||
|
||||
|
||||
inline Filesystem*
|
||||
Inode::FileSystem() const
|
||||
{
|
||||
return fFilesystem;
|
||||
}
|
||||
|
||||
|
||||
#endif // INODE_H
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ SubDir HAIKU_TOP src add-ons kernel file_systems nfs4 ;
|
||||
UsePrivateHeaders kernel ;
|
||||
|
||||
KernelAddon nfs4 :
|
||||
Cookie.cpp
|
||||
Connection.cpp
|
||||
Filesystem.cpp
|
||||
Inode.cpp
|
||||
|
||||
@@ -155,6 +155,7 @@ Server::SendCallAsync(Call* call, Reply** reply, Request** request)
|
||||
req->fReply = reply;
|
||||
req->fEvent.Init(&req->fEvent, NULL);
|
||||
req->fDone = false;
|
||||
req->fError = B_OK;
|
||||
req->fNext = NULL;
|
||||
|
||||
fRequests.AddRequest(req);
|
||||
@@ -185,6 +186,22 @@ Server::ResendCallAsync(Call* call, Request* req)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Server::WakeCall(Request* request)
|
||||
{
|
||||
Request* req = fRequests.FindRequest(request->fXID);
|
||||
if (req == NULL)
|
||||
return B_OK;
|
||||
|
||||
request->fError = B_FILE_ERROR;
|
||||
*request->fReply = NULL;
|
||||
request->fDone = true;
|
||||
request->fEvent.NotifyAll();
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Server::Repair()
|
||||
{
|
||||
|
||||
@@ -22,8 +22,10 @@ namespace RPC {
|
||||
struct Request {
|
||||
uint32 fXID;
|
||||
ConditionVariable fEvent;
|
||||
|
||||
bool fDone;
|
||||
Reply** fReply;
|
||||
status_t fError;
|
||||
|
||||
Request* fNext;
|
||||
};
|
||||
@@ -62,6 +64,7 @@ public:
|
||||
inline status_t WaitCall(Request* request,
|
||||
bigtime_t time = kWaitTime);
|
||||
inline status_t CancelCall(Request* request);
|
||||
status_t WakeCall(Request* request);
|
||||
|
||||
status_t Repair();
|
||||
|
||||
|
||||
@@ -237,14 +237,14 @@ ReplyInterpreter::Read(void* buffer, uint32* size, bool* eof)
|
||||
|
||||
|
||||
status_t
|
||||
ReplyInterpreter::ReadDir(uint64* cookie, DirEntry** dirents, uint32* _count,
|
||||
bool* eof)
|
||||
ReplyInterpreter::ReadDir(uint64* cookie, uint64* cookieVerf,
|
||||
DirEntry** dirents, uint32* _count, bool* eof)
|
||||
{
|
||||
status_t res = _OperationError(OpReadDir);
|
||||
if (res != B_OK)
|
||||
return res;
|
||||
|
||||
cookie[1] = fReply->Stream().GetUHyper();
|
||||
*cookieVerf = fReply->Stream().GetUHyper();
|
||||
|
||||
bool isNext;
|
||||
uint32 count = 0;
|
||||
@@ -254,7 +254,7 @@ ReplyInterpreter::ReadDir(uint64* cookie, DirEntry** dirents, uint32* _count,
|
||||
|
||||
isNext = fReply->Stream().GetBoolean();
|
||||
while (isNext && count < *_count) {
|
||||
cookie[0] = fReply->Stream().GetUHyper();
|
||||
*cookie = fReply->Stream().GetUHyper();
|
||||
|
||||
entries[count].fName = fReply->Stream().GetString();
|
||||
_DecodeAttrs(fReply->Stream(), &entries[count].fAttrs,
|
||||
|
||||
@@ -75,8 +75,8 @@ public:
|
||||
inline status_t PutFH();
|
||||
inline status_t PutRootFH();
|
||||
status_t Read(void* buffer, uint32* size, bool* eof);
|
||||
status_t ReadDir(uint64* cookie, DirEntry** dirents,
|
||||
uint32* count, bool* eof);
|
||||
status_t ReadDir(uint64* cookie, uint64* cookieVerf,
|
||||
DirEntry** dirents, uint32* count, bool* eof);
|
||||
status_t ReadLink(void* buffer, uint32* size, uint32 maxSize);
|
||||
inline status_t Renew();
|
||||
status_t SetClientID(uint64* clientid, uint64* verifier);
|
||||
|
||||
@@ -7,15 +7,16 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "Inode.h"
|
||||
#include "Request.h"
|
||||
|
||||
|
||||
status_t
|
||||
Request::Send()
|
||||
Request::Send(Cookie* cookie)
|
||||
{
|
||||
switch (fServer->ID().fProtocol) {
|
||||
case ProtocolUDP: return _SendUDP();
|
||||
case ProtocolTCP: return _SendTCP();
|
||||
case ProtocolUDP: return _SendUDP(cookie);
|
||||
case ProtocolTCP: return _SendTCP(cookie);
|
||||
}
|
||||
|
||||
return B_BAD_VALUE;
|
||||
@@ -23,41 +24,61 @@ Request::Send()
|
||||
|
||||
|
||||
status_t
|
||||
Request::_SendUDP()
|
||||
Request::_SendUDP(Cookie* cookie)
|
||||
{
|
||||
RPC::Reply *rpl;
|
||||
RPC::Reply *rpl = NULL;
|
||||
RPC::Request *rpc;
|
||||
|
||||
status_t result = fServer->SendCallAsync(fBuilder.Request(), &rpl, &rpc);
|
||||
if (result != B_OK)
|
||||
return result;
|
||||
|
||||
if (cookie != NULL)
|
||||
cookie->RegisterRequest(rpc);
|
||||
|
||||
result = fServer->WaitCall(rpc);
|
||||
if (result != B_OK) {
|
||||
int attempts = 1;
|
||||
while (result != B_OK && attempts++ < kRetryLimit) {
|
||||
result = fServer->ResendCallAsync(fBuilder.Request(), rpc);
|
||||
if (result != B_OK)
|
||||
if (result != B_OK) {
|
||||
if (cookie != NULL)
|
||||
cookie->UnregisterRequest(rpc);
|
||||
return result;
|
||||
}
|
||||
|
||||
result = fServer->WaitCall(rpc);
|
||||
}
|
||||
|
||||
if (result != B_OK) {
|
||||
if (cookie != NULL)
|
||||
cookie->UnregisterRequest(rpc);
|
||||
fServer->CancelCall(rpc);
|
||||
delete rpc;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
return fReply.SetTo(rpl);
|
||||
if (cookie != NULL)
|
||||
cookie->UnregisterRequest(rpc);
|
||||
|
||||
if (rpc->fError != B_OK) {
|
||||
delete rpl;
|
||||
result = rpc->fError;
|
||||
delete rpc;
|
||||
return result;
|
||||
} else {
|
||||
fReply.SetTo(rpl);
|
||||
delete rpc;
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
Request::_SendTCP()
|
||||
Request::_SendTCP(Cookie* cookie)
|
||||
{
|
||||
RPC::Reply *rpl;
|
||||
RPC::Reply *rpl = NULL;
|
||||
RPC::Request *rpc;
|
||||
|
||||
status_t result;
|
||||
@@ -71,8 +92,14 @@ Request::_SendTCP()
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cookie != NULL)
|
||||
cookie->RegisterRequest(rpc);
|
||||
|
||||
result = fServer->WaitCall(rpc);
|
||||
if (result != B_OK) {
|
||||
if (cookie != NULL)
|
||||
cookie->UnregisterRequest(rpc);
|
||||
|
||||
fServer->CancelCall(rpc);
|
||||
delete rpc;
|
||||
|
||||
@@ -80,7 +107,19 @@ Request::_SendTCP()
|
||||
}
|
||||
} while (result != B_OK && attempts++ < kRetryLimit);
|
||||
|
||||
return fReply.SetTo(rpl);
|
||||
if (cookie != NULL)
|
||||
cookie->UnregisterRequest(rpc);
|
||||
|
||||
if (rpc->fError != B_OK) {
|
||||
delete rpl;
|
||||
result = rpc->fError;
|
||||
delete rpc;
|
||||
return result;
|
||||
} else {
|
||||
fReply.SetTo(rpl);
|
||||
delete rpc;
|
||||
return B_OK;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
#include "RPCServer.h"
|
||||
|
||||
|
||||
class Cookie;
|
||||
|
||||
class Request {
|
||||
public:
|
||||
inline Request(RPC::Server* serv);
|
||||
@@ -21,12 +23,12 @@ public:
|
||||
inline RequestBuilder& Builder();
|
||||
inline ReplyInterpreter& Reply();
|
||||
|
||||
status_t Send();
|
||||
status_t Send(Cookie* cookie = NULL);
|
||||
void Reset();
|
||||
|
||||
private:
|
||||
status_t _SendUDP();
|
||||
status_t _SendTCP();
|
||||
status_t _SendUDP(Cookie* cookie);
|
||||
status_t _SendTCP(Cookie* cookie);
|
||||
|
||||
RPC::Server* fServer;
|
||||
|
||||
|
||||
@@ -267,8 +267,8 @@ RequestBuilder::Read(const uint32* id, uint32 stateSeq, uint64 pos, uint32 len)
|
||||
|
||||
|
||||
status_t
|
||||
RequestBuilder::ReadDir(uint32 count, uint64* cookie, Attribute* attrs,
|
||||
uint32 attrCount)
|
||||
RequestBuilder::ReadDir(uint32 count, uint64 cookie, uint64 cookieVerf,
|
||||
Attribute* attrs, uint32 attrCount)
|
||||
{
|
||||
(void)count;
|
||||
|
||||
@@ -278,8 +278,8 @@ RequestBuilder::ReadDir(uint32 count, uint64* cookie, Attribute* attrs,
|
||||
return B_NO_MEMORY;
|
||||
|
||||
fRequest->Stream().AddUInt(OpReadDir);
|
||||
fRequest->Stream().AddUHyper(cookie[0]);
|
||||
fRequest->Stream().AddUHyper(cookie[1]);
|
||||
fRequest->Stream().AddUHyper(cookie);
|
||||
fRequest->Stream().AddUHyper(cookieVerf);
|
||||
|
||||
// consider predicting this values basing on count or buffer size
|
||||
fRequest->Stream().AddUInt(0x2000);
|
||||
|
||||
@@ -40,8 +40,9 @@ public:
|
||||
status_t PutRootFH();
|
||||
status_t Read(const uint32* id, uint32 stateSeq,
|
||||
uint64 pos, uint32 len);
|
||||
status_t ReadDir(uint32 count, uint64* cookie,
|
||||
Attribute* attrs, uint32 attrCount);
|
||||
status_t ReadDir(uint32 count, uint64 cookie,
|
||||
uint64 cookieVerf, Attribute* attrs,
|
||||
uint32 attrCount);
|
||||
status_t ReadLink();
|
||||
status_t Renew(uint64 clientId);
|
||||
status_t SetClientID(const RPC::Server* serv);
|
||||
|
||||
@@ -253,9 +253,15 @@ nfs4_open(fs_volume* volume, fs_vnode* vnode, int openMode, void** _cookie)
|
||||
|
||||
|
||||
static status_t
|
||||
nfs4_close(fs_volume* volume, fs_vnode* vnode, void* cookie)
|
||||
nfs4_close(fs_volume* volume, fs_vnode* vnode, void* _cookie)
|
||||
{
|
||||
return B_OK;
|
||||
Inode* inode = reinterpret_cast<Inode*>(vnode->private_node);
|
||||
|
||||
if (inode->Type() == S_IFDIR || inode->Type() == S_IFLNK)
|
||||
return B_OK;
|
||||
|
||||
Cookie* cookie = reinterpret_cast<Cookie*>(_cookie);
|
||||
return cookie->CancelAll();
|
||||
}
|
||||
|
||||
|
||||
@@ -296,7 +302,7 @@ nfs4_read(fs_volume* volume, fs_vnode* vnode, void* _cookie, off_t pos,
|
||||
static status_t
|
||||
nfs4_open_dir(fs_volume* volume, fs_vnode* vnode, void** _cookie)
|
||||
{
|
||||
uint64* cookie = new(std::nothrow) uint64[2];
|
||||
OpenDirCookie* cookie = new(std::nothrow) OpenDirCookie;
|
||||
if (cookie == NULL)
|
||||
return B_NO_MEMORY;
|
||||
*_cookie = cookie;
|
||||
@@ -311,16 +317,17 @@ nfs4_open_dir(fs_volume* volume, fs_vnode* vnode, void** _cookie)
|
||||
|
||||
|
||||
static status_t
|
||||
nfs4_close_dir(fs_volume* volume, fs_vnode* vnode, void* cookie)
|
||||
nfs4_close_dir(fs_volume* volume, fs_vnode* vnode, void* _cookie)
|
||||
{
|
||||
return B_OK;
|
||||
Cookie* cookie = reinterpret_cast<Cookie*>(_cookie);
|
||||
return cookie->CancelAll();
|
||||
}
|
||||
|
||||
|
||||
static status_t
|
||||
nfs4_free_dir_cookie(fs_volume* volume, fs_vnode* vnode, void* cookie)
|
||||
{
|
||||
delete[] reinterpret_cast<uint64*>(cookie);
|
||||
delete reinterpret_cast<OpenDirCookie*>(cookie);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -329,7 +336,7 @@ static status_t
|
||||
nfs4_read_dir(fs_volume* volume, fs_vnode* vnode, void* _cookie,
|
||||
struct dirent* buffer, size_t bufferSize, uint32* _num)
|
||||
{
|
||||
uint64* cookie = reinterpret_cast<uint64*>(_cookie);
|
||||
OpenDirCookie* cookie = reinterpret_cast<OpenDirCookie*>(_cookie);
|
||||
Inode* inode = reinterpret_cast<Inode*>(vnode->private_node);
|
||||
return inode->ReadDir(buffer, bufferSize, _num, cookie);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user