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