1/* 2 * Copyright 2009-2011, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5#ifndef NODE_H 6#define NODE_H 7 8 9#include <fs_interface.h> 10 11#include <AutoLocker.h> 12#include <Referenceable.h> 13 14#include <lock.h> 15#include <util/DoublyLinkedList.h> 16#include <util/khash.h> 17#include <util/OpenHashTable.h> 18 19 20class AttributeCookie; 21class AttributeDirectoryCookie; 22class AttributeIndexer; 23class Directory; 24class PackageNode; 25 26 27// node flags 28enum { 29 NODE_FLAG_KEEP_NAME = 0x01, 30 // Init(): Take over ownership of the given name (i.e. free in 31 // destructor). 32 NODE_FLAG_CONST_NAME = 0x02, 33 // Init(): The given name is a constant that won't go away during the 34 // lifetime of the object. No need to copy. 35 NODE_FLAG_OWNS_NAME = NODE_FLAG_KEEP_NAME, 36 NODE_FLAG_KNOWN_TO_VFS = 0x04, 37 // internal flag 38}; 39 40 41class Node : public BReferenceable, public DoublyLinkedListLinkImpl<Node> { 42public: 43 Node(ino_t id); 44 virtual ~Node(); 45 46 inline bool ReadLock(); 47 inline void ReadUnlock(); 48 inline bool WriteLock(); 49 inline void WriteUnlock(); 50 51 ino_t ID() const { return fID; } 52 Directory* Parent() const { return fParent; } 53 const char* Name() const { return fName; } 54 55 Node*& NameHashTableNext() 56 { return fNameHashTableNext; } 57 Node*& IDHashTableNext() 58 { return fIDHashTableNext; } 59 60 virtual status_t Init(Directory* parent, const char* name, 61 uint32 flags); 62 // If specified to keep the name, it does 63 // so also on error. 64 65 virtual status_t VFSInit(dev_t deviceID); 66 // base class version must be called on 67 // success 68 virtual void VFSUninit(); 69 // base class version must be called 70 inline bool IsKnownToVFS() const; 71 72 void SetID(ino_t id); 73 void SetParent(Directory* parent); 74 75 virtual mode_t Mode() const = 0; 76 virtual uid_t UserID() const; 77 virtual gid_t GroupID() const; 78 virtual timespec ModifiedTime() const = 0; 79 virtual off_t FileSize() const = 0; 80 81 virtual status_t Read(off_t offset, void* buffer, 82 size_t* bufferSize) = 0; 83 virtual status_t Read(io_request* request) = 0; 84 85 virtual status_t ReadSymlink(void* buffer, 86 size_t* bufferSize) = 0; 87 88 virtual status_t OpenAttributeDirectory( 89 AttributeDirectoryCookie*& _cookie); 90 virtual status_t OpenAttribute(const char* name, int openMode, 91 AttributeCookie*& _cookie); 92 93 virtual status_t IndexAttribute(AttributeIndexer* indexer); 94 virtual void* IndexCookieForAttribute(const char* name) const; 95 96protected: 97 rw_lock fLock; 98 ino_t fID; 99 Directory* fParent; 100 char* fName; 101 Node* fNameHashTableNext; 102 Node* fIDHashTableNext; 103 uint32 fFlags; 104}; 105 106 107bool 108Node::ReadLock() 109{ 110 return rw_lock_read_lock(&fLock) == B_OK; 111} 112 113 114void 115Node::ReadUnlock() 116{ 117 rw_lock_read_unlock(&fLock); 118} 119 120 121bool 122Node::WriteLock() 123{ 124 return rw_lock_write_lock(&fLock) == B_OK; 125} 126 127 128void 129Node::WriteUnlock() 130{ 131 rw_lock_write_unlock(&fLock); 132} 133 134 135bool 136Node::IsKnownToVFS() const 137{ 138 return (fFlags & NODE_FLAG_KNOWN_TO_VFS) != 0; 139} 140 141 142// #pragma mark - 143 144 145struct NodeNameHashDefinition { 146 typedef const char* KeyType; 147 typedef Node ValueType; 148 149 size_t HashKey(const char* key) const 150 { 151 return hash_hash_string(key); 152 } 153 154 size_t Hash(const Node* value) const 155 { 156 return HashKey(value->Name()); 157 } 158 159 bool Compare(const char* key, const Node* value) const 160 { 161 return strcmp(value->Name(), key) == 0; 162 } 163 164 Node*& GetLink(Node* value) const 165 { 166 return value->NameHashTableNext(); 167 } 168}; 169 170 171struct NodeIDHashDefinition { 172 typedef ino_t KeyType; 173 typedef Node ValueType; 174 175 size_t HashKey(ino_t key) const 176 { 177 return (uint64)(key >> 32) ^ (uint32)key; 178 } 179 180 size_t Hash(const Node* value) const 181 { 182 return HashKey(value->ID()); 183 } 184 185 bool Compare(ino_t key, const Node* value) const 186 { 187 return value->ID() == key; 188 } 189 190 Node*& GetLink(Node* value) const 191 { 192 return value->IDHashTableNext(); 193 } 194}; 195 196typedef DoublyLinkedList<Node> NodeList; 197 198typedef BOpenHashTable<NodeNameHashDefinition> NodeNameHashTable; 199typedef BOpenHashTable<NodeIDHashDefinition> NodeIDHashTable; 200 201typedef AutoLocker<Node, AutoLockerReadLocking<Node> > NodeReadLocker; 202typedef AutoLocker<Node, AutoLockerWriteLocking<Node> > NodeWriteLocker; 203 204 205#endif // NODE_H 206