Files
haiku-beta6/src/add-ons/kernel/file_systems/packagefs/Node.h
T
Ingo Weinhold 724fba1b09 Add Node::Init() flags parameter
* Add Node::Init() flags:
  - NODE_FLAG_KEEP_NAME: Take over ownership of the name.
  - NODE_FLAG_CONST_NAME: Don't copy the name -- it's a constant that
    lives at least as long as the object.
* Remove Init() implementations in derived classes that just call the
  base class version.
2011-07-17 16:54:30 +02:00

186 lines
3.8 KiB
C++

/*
* Copyright 2009-2011, Ingo Weinhold, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef NODE_H
#define NODE_H
#include <fs_interface.h>
#include <AutoLocker.h>
#include <Referenceable.h>
#include <lock.h>
#include <util/DoublyLinkedList.h>
#include <util/khash.h>
#include <util/OpenHashTable.h>
class AttributeCookie;
class AttributeDirectoryCookie;
class Directory;
class PackageNode;
// node flags
enum {
NODE_FLAG_KEEP_NAME = 0x01,
// Init(): Take over ownership of the given name (i.e. free in
// destructor).
NODE_FLAG_CONST_NAME = 0x02,
// Init(): The given name is a constant that won't go away during the
// lifetime of the object. No need to copy.
NODE_FLAG_OWNS_NAME = NODE_FLAG_CONST_NAME
};
class Node : public BReferenceable, public DoublyLinkedListLinkImpl<Node> {
public:
Node(ino_t id);
virtual ~Node();
inline bool ReadLock();
inline void ReadUnlock();
inline bool WriteLock();
inline void WriteUnlock();
ino_t ID() const { return fID; }
Directory* Parent() const { return fParent; }
const char* Name() const { return fName; }
Node*& NameHashTableNext()
{ return fNameHashTableNext; }
Node*& IDHashTableNext()
{ return fIDHashTableNext; }
virtual status_t Init(Directory* parent, const char* name,
uint32 flags);
// If specified to keep the name, it does
// so also on error.
virtual status_t VFSInit(dev_t deviceID);
virtual void VFSUninit();
void SetID(ino_t id);
void SetParent(Directory* parent);
virtual mode_t Mode() const = 0;
virtual uid_t UserID() const = 0;
virtual gid_t GroupID() const = 0;
virtual timespec ModifiedTime() const = 0;
virtual off_t FileSize() const = 0;
virtual status_t Read(off_t offset, void* buffer,
size_t* bufferSize) = 0;
virtual status_t Read(io_request* request) = 0;
virtual status_t ReadSymlink(void* buffer,
size_t* bufferSize) = 0;
virtual status_t OpenAttributeDirectory(
AttributeDirectoryCookie*& _cookie) = 0;
virtual status_t OpenAttribute(const char* name, int openMode,
AttributeCookie*& _cookie) = 0;
protected:
rw_lock fLock;
ino_t fID;
Directory* fParent;
char* fName;
Node* fNameHashTableNext;
Node* fIDHashTableNext;
uint32 fFlags;
};
bool
Node::ReadLock()
{
return rw_lock_read_lock(&fLock) == B_OK;
}
void
Node::ReadUnlock()
{
rw_lock_read_unlock(&fLock);
}
bool
Node::WriteLock()
{
return rw_lock_write_lock(&fLock) == B_OK;
}
void
Node::WriteUnlock()
{
rw_lock_write_unlock(&fLock);
}
struct NodeNameHashDefinition {
typedef const char* KeyType;
typedef Node ValueType;
size_t HashKey(const char* key) const
{
return hash_hash_string(key);
}
size_t Hash(const Node* value) const
{
return HashKey(value->Name());
}
bool Compare(const char* key, const Node* value) const
{
return strcmp(value->Name(), key) == 0;
}
Node*& GetLink(Node* value) const
{
return value->NameHashTableNext();
}
};
struct NodeIDHashDefinition {
typedef ino_t KeyType;
typedef Node ValueType;
size_t HashKey(ino_t key) const
{
return (uint64)(key >> 32) ^ (uint32)key;
}
size_t Hash(const Node* value) const
{
return HashKey(value->ID());
}
bool Compare(ino_t key, const Node* value) const
{
return value->ID() == key;
}
Node*& GetLink(Node* value) const
{
return value->IDHashTableNext();
}
};
typedef DoublyLinkedList<Node> NodeList;
typedef BOpenHashTable<NodeNameHashDefinition> NodeNameHashTable;
typedef BOpenHashTable<NodeIDHashDefinition> NodeIDHashTable;
typedef AutoLocker<Node, AutoLockerReadLocking<Node> > NodeReadLocker;
typedef AutoLocker<Node, AutoLockerWriteLocking<Node> > NodeWriteLocker;
#endif // NODE_H