1 /* 2 * Copyright 2009-2013, 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 13 #include <lock.h> 14 #include <util/DoublyLinkedList.h> 15 #include <util/OpenHashTable.h> 16 17 #include "InlineReferenceable.h" 18 #include "String.h" 19 #include "StringKey.h" 20 21 22 class AttributeCookie; 23 class AttributeDirectoryCookie; 24 class AttributeIndexer; 25 class Directory; 26 class PackageNode; 27 28 29 // internal node flags 30 enum { 31 NODE_FLAG_KNOWN_TO_VFS = 0x01, 32 NODE_FLAG_VFS_INIT_ERROR = 0x02, 33 // used by subclasses 34 }; 35 36 37 class Node : public DoublyLinkedListLinkImpl<Node> { 38 public: 39 Node(ino_t id); 40 virtual ~Node(); 41 42 void AcquireReference(); 43 void ReleaseReference(); 44 int32 CountReferences(); 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 String& Name() const { return fName; } 54 55 Node*& NameHashTableNext() 56 { return fNameHashTableNext; } 57 Node*& IDHashTableNext() 58 { return fIDHashTableNext; } 59 60 virtual status_t Init(const String& name); 61 void SetID(ino_t id); 62 63 virtual status_t VFSInit(dev_t deviceID); 64 // base class version must be called on 65 // success 66 virtual void VFSUninit(); 67 // base class version must be called 68 inline bool IsKnownToVFS() const; 69 inline bool HasVFSInitError() const; 70 71 virtual mode_t Mode() const = 0; 72 virtual uid_t UserID() const; 73 virtual gid_t GroupID() const; 74 virtual timespec ModifiedTime() const = 0; 75 virtual off_t FileSize() const = 0; 76 77 virtual status_t Read(off_t offset, void* buffer, 78 size_t* bufferSize) = 0; 79 virtual status_t Read(io_request* request) = 0; 80 81 virtual status_t ReadSymlink(void* buffer, 82 size_t* bufferSize) = 0; 83 84 virtual status_t OpenAttributeDirectory( 85 AttributeDirectoryCookie*& _cookie); 86 virtual status_t OpenAttribute(const StringKey& name, 87 int openMode, AttributeCookie*& _cookie); 88 89 virtual status_t IndexAttribute(AttributeIndexer* indexer); 90 virtual void* IndexCookieForAttribute(const StringKey& name) 91 const; 92 93 private: 94 friend class Directory; 95 96 void _SetParent(Directory* parent); 97 98 protected: 99 rw_lock fLock; 100 ino_t fID; 101 Directory* fParent; 102 String fName; 103 Node* fNameHashTableNext; 104 Node* fIDHashTableNext; 105 uint32 fFlags; 106 InlineReferenceable fReferenceable; 107 }; 108 109 110 bool 111 Node::ReadLock() 112 { 113 return rw_lock_read_lock(&fLock) == B_OK; 114 } 115 116 117 void 118 Node::ReadUnlock() 119 { 120 rw_lock_read_unlock(&fLock); 121 } 122 123 124 bool 125 Node::WriteLock() 126 { 127 return rw_lock_write_lock(&fLock) == B_OK; 128 } 129 130 131 void 132 Node::WriteUnlock() 133 { 134 rw_lock_write_unlock(&fLock); 135 } 136 137 138 bool 139 Node::IsKnownToVFS() const 140 { 141 return (fFlags & NODE_FLAG_KNOWN_TO_VFS) != 0; 142 } 143 144 145 bool 146 Node::HasVFSInitError() const 147 { 148 return (fFlags & NODE_FLAG_VFS_INIT_ERROR) != 0; 149 } 150 151 152 // #pragma mark - 153 154 155 struct NodeNameHashDefinition { 156 typedef StringKey KeyType; 157 typedef Node ValueType; 158 159 size_t HashKey(const StringKey& key) const 160 { 161 return key.Hash(); 162 } 163 164 size_t Hash(const Node* value) const 165 { 166 return value->Name().Hash(); 167 } 168 169 bool Compare(const StringKey& key, const Node* value) const 170 { 171 return key == value->Name(); 172 } 173 174 Node*& GetLink(Node* value) const 175 { 176 return value->NameHashTableNext(); 177 } 178 }; 179 180 181 struct NodeIDHashDefinition { 182 typedef ino_t KeyType; 183 typedef Node ValueType; 184 185 size_t HashKey(ino_t key) const 186 { 187 return (uint64)(key >> 32) ^ (uint32)key; 188 } 189 190 size_t Hash(const Node* value) const 191 { 192 return HashKey(value->ID()); 193 } 194 195 bool Compare(ino_t key, const Node* value) const 196 { 197 return value->ID() == key; 198 } 199 200 Node*& GetLink(Node* value) const 201 { 202 return value->IDHashTableNext(); 203 } 204 }; 205 206 typedef DoublyLinkedList<Node> NodeList; 207 208 typedef BOpenHashTable<NodeNameHashDefinition> NodeNameHashTable; 209 typedef BOpenHashTable<NodeIDHashDefinition> NodeIDHashTable; 210 211 typedef AutoLocker<Node, AutoLockerReadLocking<Node> > NodeReadLocker; 212 typedef AutoLocker<Node, AutoLockerWriteLocking<Node> > NodeWriteLocker; 213 214 215 #endif // NODE_H 216