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