nfs4: Add attribute directory related hooks
This commit is contained in:
@@ -92,6 +92,8 @@ struct OpenDirCookie : public Cookie {
|
|||||||
NameCacheEntry* fCurrent;
|
NameCacheEntry* fCurrent;
|
||||||
bool fEOF;
|
bool fEOF;
|
||||||
|
|
||||||
|
bool fAttrDir;
|
||||||
|
|
||||||
~OpenDirCookie();
|
~OpenDirCookie();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
#include "DirectoryCache.h"
|
#include "DirectoryCache.h"
|
||||||
|
|
||||||
#include <fs_cache.h>
|
#include <fs_cache.h>
|
||||||
|
#include <NodeMonitor.h>
|
||||||
|
|
||||||
#include "Inode.h"
|
#include "Inode.h"
|
||||||
|
|
||||||
@@ -46,10 +47,11 @@ DirectoryCacheSnapshot::~DirectoryCacheSnapshot()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DirectoryCache::DirectoryCache(Inode* inode)
|
DirectoryCache::DirectoryCache(Inode* inode, bool attr)
|
||||||
:
|
:
|
||||||
fDirectoryCache(NULL),
|
fDirectoryCache(NULL),
|
||||||
fInode(inode),
|
fInode(inode),
|
||||||
|
fAttrDir(attr),
|
||||||
fTrashed(true)
|
fTrashed(true)
|
||||||
{
|
{
|
||||||
mutex_init(&fLock, NULL);
|
mutex_init(&fLock, NULL);
|
||||||
@@ -114,8 +116,12 @@ DirectoryCache::AddEntry(const char* name, ino_t node, bool created)
|
|||||||
fDirectoryCache->fEntries.Add(entry);
|
fDirectoryCache->fEntries.Add(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
return entry_cache_add(fInode->GetFileSystem()->DevId(), fInode->ID(), name,
|
if (!fAttrDir) {
|
||||||
node);
|
return entry_cache_add(fInode->GetFileSystem()->DevId(), fInode->ID(),
|
||||||
|
name, node);
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -153,7 +159,10 @@ DirectoryCache::RemoveEntry(const char* name)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
entry_cache_remove(fInode->GetFileSystem()->DevId(), fInode->ID(), name);
|
if (!fAttrDir) {
|
||||||
|
entry_cache_remove(fInode->GetFileSystem()->DevId(), fInode->ID(),
|
||||||
|
name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -231,8 +240,13 @@ DirectoryCache::NotifyChanges(DirectoryCacheSnapshot* oldSnapshot,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
notify_entry_created(fInode->GetFileSystem()->DevId(),
|
if (fAttrDir) {
|
||||||
fInode->ID(), newCurrent->fName, newCurrent->fNode);
|
notify_attribute_changed(fInode->GetFileSystem()->DevId(),
|
||||||
|
fInode->ID(), newCurrent->fName, B_ATTR_CREATED);
|
||||||
|
} else {
|
||||||
|
notify_entry_created(fInode->GetFileSystem()->DevId(),
|
||||||
|
fInode->ID(), newCurrent->fName, newCurrent->fNode);
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
oldSnapshot->fEntries.Remove(prev, oldCurrent);
|
oldSnapshot->fEntries.Remove(prev, oldCurrent);
|
||||||
|
|
||||||
@@ -243,8 +257,13 @@ DirectoryCache::NotifyChanges(DirectoryCacheSnapshot* oldSnapshot,
|
|||||||
oldCurrent = oldIt.Next();
|
oldCurrent = oldIt.Next();
|
||||||
|
|
||||||
while (oldCurrent != NULL) {
|
while (oldCurrent != NULL) {
|
||||||
notify_entry_removed(fInode->GetFileSystem()->DevId(), fInode->ID(),
|
if (fAttrDir) {
|
||||||
oldCurrent->fName, oldCurrent->fNode);
|
notify_attribute_changed(fInode->GetFileSystem()->DevId(),
|
||||||
|
fInode->ID(), newCurrent->fName, B_ATTR_REMOVED);
|
||||||
|
} else {
|
||||||
|
notify_entry_removed(fInode->GetFileSystem()->DevId(), fInode->ID(),
|
||||||
|
oldCurrent->fName, oldCurrent->fNode);
|
||||||
|
}
|
||||||
oldCurrent = oldIt.Next();
|
oldCurrent = oldIt.Next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ struct DirectoryCacheSnapshot : public KernelReferenceable {
|
|||||||
|
|
||||||
class DirectoryCache : public DoublyLinkedListLinkImpl<DirectoryCache> {
|
class DirectoryCache : public DoublyLinkedListLinkImpl<DirectoryCache> {
|
||||||
public:
|
public:
|
||||||
DirectoryCache(Inode* inode);
|
DirectoryCache(Inode* inode, bool attr = false);
|
||||||
~DirectoryCache();
|
~DirectoryCache();
|
||||||
|
|
||||||
inline status_t Lock();
|
inline status_t Lock();
|
||||||
@@ -76,6 +76,7 @@ private:
|
|||||||
|
|
||||||
Inode* fInode;
|
Inode* fInode;
|
||||||
|
|
||||||
|
bool fAttrDir;
|
||||||
bool fTrashed;
|
bool fTrashed;
|
||||||
mutex fLock;
|
mutex fLock;
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,8 @@ struct FileInfo {
|
|||||||
const char* fName;
|
const char* fName;
|
||||||
const char* fPath;
|
const char* fPath;
|
||||||
|
|
||||||
|
FileHandle fAttrDir;
|
||||||
|
|
||||||
inline FileInfo();
|
inline FileInfo();
|
||||||
inline ~FileInfo();
|
inline ~FileInfo();
|
||||||
inline FileInfo(const FileInfo& fi);
|
inline FileInfo(const FileInfo& fi);
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ Inode::Inode()
|
|||||||
:
|
:
|
||||||
fMetaCache(this),
|
fMetaCache(this),
|
||||||
fCache(NULL),
|
fCache(NULL),
|
||||||
|
fAttrCache(NULL),
|
||||||
fDelegation(NULL),
|
fDelegation(NULL),
|
||||||
fFileCache(NULL),
|
fFileCache(NULL),
|
||||||
fMaxFileSize(0),
|
fMaxFileSize(0),
|
||||||
@@ -93,6 +94,7 @@ Inode::CreateInode(FileSystem* fs, const FileInfo &fi, Inode** _inode)
|
|||||||
|
|
||||||
if (inode->fType == NF4DIR)
|
if (inode->fType == NF4DIR)
|
||||||
inode->fCache = new DirectoryCache(inode);
|
inode->fCache = new DirectoryCache(inode);
|
||||||
|
inode->fAttrCache = new DirectoryCache(inode, true);
|
||||||
|
|
||||||
// FATTR4_CHANGE is mandatory
|
// FATTR4_CHANGE is mandatory
|
||||||
inode->fChange = values[1].fData.fValue64;
|
inode->fChange = values[1].fData.fValue64;
|
||||||
@@ -131,6 +133,8 @@ Inode::~Inode()
|
|||||||
file_cache_delete(fFileCache);
|
file_cache_delete(fFileCache);
|
||||||
|
|
||||||
delete fCache;
|
delete fCache;
|
||||||
|
delete fAttrCache;
|
||||||
|
|
||||||
mutex_destroy(&fStateLock);
|
mutex_destroy(&fStateLock);
|
||||||
mutex_destroy(&fFileCacheLock);
|
mutex_destroy(&fFileCacheLock);
|
||||||
rw_lock_destroy(&fDelegationLock);
|
rw_lock_destroy(&fDelegationLock);
|
||||||
|
|||||||
@@ -82,6 +82,8 @@ public:
|
|||||||
status_t ReadDir(void* buffer, uint32 size,
|
status_t ReadDir(void* buffer, uint32 size,
|
||||||
uint32* count, OpenDirCookie* cookie);
|
uint32* count, OpenDirCookie* cookie);
|
||||||
|
|
||||||
|
status_t OpenAttrDir(OpenDirCookie* cookie);
|
||||||
|
|
||||||
status_t TestLock(OpenFileCookie* cookie,
|
status_t TestLock(OpenFileCookie* cookie,
|
||||||
struct flock* lock);
|
struct flock* lock);
|
||||||
status_t AcquireLock(OpenFileCookie* cookie,
|
status_t AcquireLock(OpenFileCookie* cookie,
|
||||||
@@ -124,6 +126,7 @@ private:
|
|||||||
|
|
||||||
MetadataCache fMetaCache;
|
MetadataCache fMetaCache;
|
||||||
DirectoryCache* fCache;
|
DirectoryCache* fCache;
|
||||||
|
DirectoryCache* fAttrCache;
|
||||||
|
|
||||||
rw_lock fDelegationLock;
|
rw_lock fDelegationLock;
|
||||||
Delegation* fDelegation;
|
Delegation* fDelegation;
|
||||||
|
|||||||
@@ -39,11 +39,36 @@ Inode::OpenDir(OpenDirCookie* cookie)
|
|||||||
cookie->fSnapshot = NULL;
|
cookie->fSnapshot = NULL;
|
||||||
cookie->fCurrent = NULL;
|
cookie->fCurrent = NULL;
|
||||||
cookie->fEOF = false;
|
cookie->fEOF = false;
|
||||||
|
cookie->fAttrDir = false;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
Inode::OpenAttrDir(OpenDirCookie* cookie)
|
||||||
|
{
|
||||||
|
cookie->fFileSystem = fFileSystem;
|
||||||
|
cookie->fSpecial = 0;
|
||||||
|
cookie->fSnapshot = NULL;
|
||||||
|
cookie->fCurrent = NULL;
|
||||||
|
cookie->fEOF = false;
|
||||||
|
cookie->fAttrDir = true;
|
||||||
|
|
||||||
|
if (fInfo.fAttrDir.fSize == 0) {
|
||||||
|
FileHandle handle;
|
||||||
|
|
||||||
|
status_t result = NFS4Inode::OpenAttrDir(&handle);
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
fInfo.fAttrDir = handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
Inode::FillDirEntry(struct dirent* de, ino_t id, const char* name, uint32 pos,
|
Inode::FillDirEntry(struct dirent* de, ino_t id, const char* name, uint32 pos,
|
||||||
uint32 size)
|
uint32 size)
|
||||||
@@ -152,10 +177,13 @@ Inode::GetDirSnapshot(DirectoryCacheSnapshot** _snapshot,
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
ino_t id;
|
ino_t id;
|
||||||
if (dirents[i].fAttrCount == 2)
|
if (!cookie->fAttrDir) {
|
||||||
id = FileIdToInoT(dirents[i].fAttrs[1].fData.fValue64);
|
if (dirents[i].fAttrCount == 2)
|
||||||
else
|
id = FileIdToInoT(dirents[i].fAttrs[1].fData.fValue64);
|
||||||
id = FileIdToInoT(fFileSystem->AllocFileId());
|
else
|
||||||
|
id = FileIdToInoT(fFileSystem->AllocFileId());
|
||||||
|
} else
|
||||||
|
id = 0;
|
||||||
|
|
||||||
NameCacheEntry* entry = new NameCacheEntry(dirents[i].fName, id);
|
NameCacheEntry* entry = new NameCacheEntry(dirents[i].fName, id);
|
||||||
if (entry == NULL || entry->fName == NULL) {
|
if (entry == NULL || entry->fName == NULL) {
|
||||||
@@ -188,29 +216,30 @@ Inode::ReadDir(void* _buffer, uint32 size, uint32* _count,
|
|||||||
}
|
}
|
||||||
|
|
||||||
status_t result;
|
status_t result;
|
||||||
|
DirectoryCache* cache = cookie->fAttrDir ? fAttrCache : fCache;
|
||||||
if (cookie->fSnapshot == NULL) {
|
if (cookie->fSnapshot == NULL) {
|
||||||
fFileSystem->Revalidator().Lock();
|
fFileSystem->Revalidator().Lock();
|
||||||
if (fCache->Lock() != B_OK) {
|
if (cache->Lock() != B_OK) {
|
||||||
fCache->ResetAndLock();
|
cache->ResetAndLock();
|
||||||
} else {
|
} else {
|
||||||
fFileSystem->Revalidator().RemoveDirectory(fCache);
|
fFileSystem->Revalidator().RemoveDirectory(cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
cookie->fSnapshot = fCache->GetSnapshot();
|
cookie->fSnapshot = cache->GetSnapshot();
|
||||||
if (cookie->fSnapshot == NULL) {
|
if (cookie->fSnapshot == NULL) {
|
||||||
uint64 change;
|
uint64 change;
|
||||||
result = GetDirSnapshot(&cookie->fSnapshot, cookie, &change);
|
result = GetDirSnapshot(&cookie->fSnapshot, cookie, &change);
|
||||||
if (result != B_OK) {
|
if (result != B_OK) {
|
||||||
fCache->Unlock();
|
cache->Unlock();
|
||||||
fFileSystem->Revalidator().Unlock();
|
fFileSystem->Revalidator().Unlock();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
fCache->ValidateChangeInfo(change);
|
cache->ValidateChangeInfo(change);
|
||||||
fCache->SetSnapshot(cookie->fSnapshot);
|
cache->SetSnapshot(cookie->fSnapshot);
|
||||||
}
|
}
|
||||||
cookie->fSnapshot->AcquireReference();
|
cookie->fSnapshot->AcquireReference();
|
||||||
fFileSystem->Revalidator().AddDirectory(fCache);
|
fFileSystem->Revalidator().AddDirectory(cache);
|
||||||
fCache->Unlock();
|
cache->Unlock();
|
||||||
fFileSystem->Revalidator().Unlock();
|
fFileSystem->Revalidator().Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,7 +248,7 @@ Inode::ReadDir(void* _buffer, uint32 size, uint32* _count,
|
|||||||
uint32 i = 0;
|
uint32 i = 0;
|
||||||
bool overflow = false;
|
bool overflow = false;
|
||||||
|
|
||||||
if (cookie->fSpecial == 0 && i < *_count) {
|
if (cookie->fSpecial == 0 && i < *_count && !cookie->fAttrDir) {
|
||||||
struct dirent* de = reinterpret_cast<dirent*>(buffer + pos);
|
struct dirent* de = reinterpret_cast<dirent*>(buffer + pos);
|
||||||
|
|
||||||
status_t result;
|
status_t result;
|
||||||
@@ -235,7 +264,7 @@ Inode::ReadDir(void* _buffer, uint32 size, uint32* _count,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cookie->fSpecial == 1 && i < *_count) {
|
if (cookie->fSpecial == 1 && i < *_count && !cookie->fAttrDir) {
|
||||||
struct dirent* de = reinterpret_cast<dirent*>(buffer + pos);
|
struct dirent* de = reinterpret_cast<dirent*>(buffer + pos);
|
||||||
|
|
||||||
status_t result;
|
status_t result;
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ enum Opcode {
|
|||||||
OpLookUpUp = 16,
|
OpLookUpUp = 16,
|
||||||
OpNverify = 17,
|
OpNverify = 17,
|
||||||
OpOpen = 18,
|
OpOpen = 18,
|
||||||
|
OpOpenAttrDir = 19,
|
||||||
OpOpenConfirm = 20,
|
OpOpenConfirm = 20,
|
||||||
OpPutFH = 22,
|
OpPutFH = 22,
|
||||||
OpPutRootFH = 24,
|
OpPutRootFH = 24,
|
||||||
|
|||||||
@@ -817,7 +817,10 @@ NFS4Inode::ReadDirOnce(DirEntry** dirents, uint32* count, OpenDirCookie* cookie,
|
|||||||
Request request(serv);
|
Request request(serv);
|
||||||
RequestBuilder& req = request.Builder();
|
RequestBuilder& req = request.Builder();
|
||||||
|
|
||||||
req.PutFH(fInfo.fHandle);
|
if (cookie->fAttrDir)
|
||||||
|
req.PutFH(fInfo.fAttrDir);
|
||||||
|
else
|
||||||
|
req.PutFH(fInfo.fHandle);
|
||||||
|
|
||||||
Attribute dirAttr[] = { FATTR4_CHANGE };
|
Attribute dirAttr[] = { FATTR4_CHANGE };
|
||||||
if (*change == 0)
|
if (*change == 0)
|
||||||
@@ -875,6 +878,37 @@ NFS4Inode::ReadDirOnce(DirEntry** dirents, uint32* count, OpenDirCookie* cookie,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
NFS4Inode::OpenAttrDir(FileHandle* handle)
|
||||||
|
{
|
||||||
|
do {
|
||||||
|
RPC::Server* serv = fFileSystem->Server();
|
||||||
|
Request request(serv);
|
||||||
|
RequestBuilder& req = request.Builder();
|
||||||
|
|
||||||
|
req.PutFH(fInfo.fHandle);
|
||||||
|
req.OpenAttrDir(true);
|
||||||
|
req.GetFH();
|
||||||
|
|
||||||
|
status_t result = request.Send();
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
ReplyInterpreter& reply = request.Reply();
|
||||||
|
|
||||||
|
if (HandleErrors(reply.NFS4Error(), serv))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
reply.PutFH();
|
||||||
|
result = reply.OpenAttrDir();
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
|
return reply.GetFH(handle);
|
||||||
|
} while (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
NFS4Inode::TestLock(OpenFileCookie* cookie, LockType* type, uint64* position,
|
NFS4Inode::TestLock(OpenFileCookie* cookie, LockType* type, uint64* position,
|
||||||
uint64* length, bool& conflict)
|
uint64* length, bool& conflict)
|
||||||
|
|||||||
@@ -68,6 +68,8 @@ protected:
|
|||||||
OpenDirCookie* cookie, bool* eof, uint64* change,
|
OpenDirCookie* cookie, bool* eof, uint64* change,
|
||||||
uint64* dirCookie, uint64* dirCookieVerf);
|
uint64* dirCookie, uint64* dirCookieVerf);
|
||||||
|
|
||||||
|
status_t OpenAttrDir(FileHandle* handle);
|
||||||
|
|
||||||
status_t TestLock(OpenFileCookie* cookie, LockType* type,
|
status_t TestLock(OpenFileCookie* cookie, LockType* type,
|
||||||
uint64* position, uint64* length, bool& conflict);
|
uint64* position, uint64* length, bool& conflict);
|
||||||
status_t AcquireLock(OpenFileCookie* cookie, LockInfo* lockInfo,
|
status_t AcquireLock(OpenFileCookie* cookie, LockInfo* lockInfo,
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ public:
|
|||||||
status_t Open(uint32* id, uint32* seq, bool* confirm,
|
status_t Open(uint32* id, uint32* seq, bool* confirm,
|
||||||
OpenDelegationData* delegData,
|
OpenDelegationData* delegData,
|
||||||
ChangeInfo* changeInfo = NULL);
|
ChangeInfo* changeInfo = NULL);
|
||||||
|
inline status_t OpenAttrDir();
|
||||||
status_t OpenConfirm(uint32* stateSeq);
|
status_t OpenConfirm(uint32* stateSeq);
|
||||||
inline status_t PutFH();
|
inline status_t PutFH();
|
||||||
inline status_t PutRootFH();
|
inline status_t PutRootFH();
|
||||||
@@ -172,6 +173,13 @@ ReplyInterpreter::LookUpUp()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline status_t
|
||||||
|
ReplyInterpreter::OpenAttrDir()
|
||||||
|
{
|
||||||
|
return _OperationError(OpOpenAttrDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
inline status_t
|
inline status_t
|
||||||
ReplyInterpreter::Nverify()
|
ReplyInterpreter::Nverify()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -445,6 +445,23 @@ RequestBuilder::OpenConfirm(uint32 seq, const uint32* id, uint32 stateSeq)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
RequestBuilder::OpenAttrDir(bool create)
|
||||||
|
{
|
||||||
|
if (fProcedure != ProcCompound)
|
||||||
|
return B_BAD_VALUE;
|
||||||
|
if (fRequest == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
fRequest->Stream().AddUInt(OpOpenAttrDir);
|
||||||
|
fRequest->Stream().AddBoolean(create);
|
||||||
|
|
||||||
|
fOpCount++;
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
RequestBuilder::PutFH(const FileHandle& fh)
|
RequestBuilder::PutFH(const FileHandle& fh)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ public:
|
|||||||
uint32 count = 0, bool excl = false,
|
uint32 count = 0, bool excl = false,
|
||||||
OpenDelegation delegType
|
OpenDelegation delegType
|
||||||
= OPEN_DELEGATE_NONE);
|
= OPEN_DELEGATE_NONE);
|
||||||
|
status_t OpenAttrDir(bool create);
|
||||||
status_t OpenConfirm(uint32 seq, const uint32* id,
|
status_t OpenConfirm(uint32 seq, const uint32* id,
|
||||||
uint32 stateSeq);
|
uint32 stateSeq);
|
||||||
status_t PutFH(const FileHandle& fh);
|
status_t PutFH(const FileHandle& fh);
|
||||||
|
|||||||
@@ -610,6 +610,52 @@ nfs4_rewind_dir(fs_volume* volume, fs_vnode* vnode, void* _cookie)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
nfs4_open_attr_dir(fs_volume* volume, fs_vnode* vnode, void** _cookie)
|
||||||
|
{
|
||||||
|
OpenDirCookie* cookie = new(std::nothrow) OpenDirCookie;
|
||||||
|
if (cookie == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
*_cookie = cookie;
|
||||||
|
|
||||||
|
Inode* inode = reinterpret_cast<Inode*>(vnode->private_node);
|
||||||
|
status_t result = inode->OpenAttrDir(cookie);
|
||||||
|
if (result != B_OK)
|
||||||
|
delete cookie;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
nfs4_close_attr_dir(fs_volume* volume, fs_vnode* vnode, void* cookie)
|
||||||
|
{
|
||||||
|
return nfs4_close_attr_dir(volume, vnode, cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
nfs4_free_attr_dir_cookie(fs_volume* volume, fs_vnode* vnode, void* cookie)
|
||||||
|
{
|
||||||
|
return nfs4_free_dir_cookie(volume, vnode, cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
nfs4_read_attr_dir(fs_volume* volume, fs_vnode* vnode, void* cookie,
|
||||||
|
struct dirent* buffer, size_t bufferSize, uint32* _num)
|
||||||
|
{
|
||||||
|
return nfs4_read_dir(volume, vnode, cookie, buffer, bufferSize, _num);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static status_t
|
||||||
|
nfs4_rewind_attr_dir(fs_volume* volume, fs_vnode* vnode, void* cookie)
|
||||||
|
{
|
||||||
|
return nfs4_rewind_attr_dir(volume, vnode, cookie);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
nfs4_test_lock(fs_volume* volume, fs_vnode* vnode, void* _cookie,
|
nfs4_test_lock(fs_volume* volume, fs_vnode* vnode, void* _cookie,
|
||||||
struct flock* lock)
|
struct flock* lock)
|
||||||
@@ -774,11 +820,11 @@ fs_vnode_ops gNFSv4VnodeOps = {
|
|||||||
nfs4_rewind_dir,
|
nfs4_rewind_dir,
|
||||||
|
|
||||||
/* attribute directory operations */
|
/* attribute directory operations */
|
||||||
NULL, // open_attr_dir
|
nfs4_open_attr_dir,
|
||||||
NULL, // close_attr_dir
|
nfs4_close_attr_dir,
|
||||||
NULL, // free_attr_dir_cookie
|
nfs4_free_attr_dir_cookie,
|
||||||
NULL, // read_attr_dir
|
nfs4_read_attr_dir,
|
||||||
NULL, // rewind_attr_dir
|
nfs4_rewind_attr_dir,
|
||||||
|
|
||||||
/* attribute operations */
|
/* attribute operations */
|
||||||
NULL, // create_attr
|
NULL, // create_attr
|
||||||
|
|||||||
Reference in New Issue
Block a user