1 /* 2 * Copyright 2007, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * All rights reserved. Distributed under the terms of the MIT license. 4 */ 5 #ifndef NODE_H 6 #define NODE_H 7 8 #include <fs_interface.h> 9 #include <NodeMonitor.h> 10 11 #include "Attribute.h" 12 #include "Entry.h" 13 #include "String.h" 14 15 class AllocationInfo; 16 class AttributeIterator; 17 class Directory; 18 class Volume; 19 20 // node type 21 enum { 22 NODE_TYPE_DIRECTORY, 23 NODE_TYPE_FILE, 24 NODE_TYPE_SYMLINK, 25 }; 26 27 // access modes 28 enum { 29 ACCESS_R = S_IROTH, 30 ACCESS_W = S_IWOTH, 31 ACCESS_X = S_IXOTH, 32 }; 33 34 class Node : public DoublyLinkedListLinkImpl<Node> { 35 public: 36 Node(Volume *volume, uint8 type); 37 virtual ~Node(); 38 39 virtual status_t InitCheck() const; 40 41 Node*& HashLink() { return fHashLink; } 42 43 inline void SetVolume(Volume *volume) { fVolume = volume; } 44 inline Volume *GetVolume() const { return fVolume; } 45 46 inline ino_t GetID() const { return fID; } 47 48 status_t AddReference(); 49 void RemoveReference(); 50 int32 GetRefCount() { return fRefCount; } 51 52 virtual status_t Link(Entry *entry); 53 virtual status_t Unlink(Entry *entry); 54 55 inline bool IsDirectory() const { return S_ISDIR(fMode); } 56 inline bool IsFile() const { return S_ISREG(fMode); } 57 inline bool IsSymLink() const { return S_ISLNK(fMode); } 58 59 virtual status_t SetSize(off_t newSize) = 0; 60 virtual off_t GetSize() const = 0; 61 62 // stat data 63 64 inline void SetMode(mode_t mode) 65 { fMode = (fMode & ~S_IUMSK) | (mode & S_IUMSK); } 66 inline mode_t GetMode() const { return fMode; } 67 68 inline void SetUID(uid_t uid) { fUID = uid; MarkModified(B_STAT_UID); } 69 inline uid_t GetUID() const { return fUID; } 70 71 inline void SetGID(uid_t gid) { fGID = gid; MarkModified(B_STAT_GID); } 72 inline uid_t GetGID() const { return fGID; } 73 74 inline void SetATime(time_t aTime) { fATime = aTime; } 75 inline time_t GetATime() const { return fATime; } 76 77 void SetMTime(time_t mTime); 78 inline time_t GetMTime() const { return fMTime; } 79 80 inline void SetCTime(time_t cTime) { fCTime = cTime; } 81 inline time_t GetCTime() const { return fCTime; } 82 83 inline void SetCrTime(time_t crTime) { fCrTime = crTime; } 84 inline time_t GetCrTime() const { return fCrTime; } 85 86 inline void MarkModified(uint32 flags) { fModified |= flags; } 87 inline uint32 MarkUnmodified(); 88 inline bool IsModified() const { return fModified; } 89 90 status_t CheckPermissions(int mode) const; 91 92 bool IsKnownToVFS() const { return fIsKnownToVFS; } 93 94 // attributes 95 status_t CreateAttribute(const char *name, Attribute **attribute); 96 status_t DeleteAttribute(Attribute *attribute); 97 status_t AddAttribute(Attribute *attribute); 98 status_t RemoveAttribute(Attribute *attribute); 99 100 status_t FindAttribute(const char *name, Attribute **attribute) const; 101 102 status_t GetPreviousAttribute(Attribute **attribute) const; 103 status_t GetNextAttribute(Attribute **attribute) const; 104 105 Entry *GetFirstReferrer() const; 106 Entry *GetLastReferrer() const; 107 Entry *GetPreviousReferrer(Entry *entry) const; 108 Entry *GetNextReferrer(Entry *entry) const; 109 110 // debugging 111 virtual void GetAllocationInfo(AllocationInfo &info); 112 113 private: 114 Node *fHashLink; 115 Volume *fVolume; 116 ino_t fID; 117 int32 fRefCount; 118 mode_t fMode; 119 uid_t fUID; 120 uid_t fGID; 121 time_t fATime; 122 time_t fMTime; 123 time_t fCTime; 124 time_t fCrTime; 125 uint32 fModified; 126 bool fIsKnownToVFS; 127 128 // attribute management 129 DoublyLinkedList<Attribute> fAttributes; 130 131 protected: 132 // entries referring to this node 133 DoublyLinkedList<Entry, GetNodeReferrerLink> fReferrers; 134 }; 135 136 // MarkUnmodified 137 inline 138 uint32 139 Node::MarkUnmodified() 140 { 141 uint32 modified = fModified; 142 if (modified) { 143 fCTime = time(NULL); 144 SetMTime(fCTime); 145 fModified = 0; 146 } 147 return modified; 148 } 149 150 // open_mode_to_access 151 inline static 152 int 153 open_mode_to_access(int openMode) 154 { 155 switch (openMode & O_RWMASK) { 156 case O_RDONLY: 157 return ACCESS_R; 158 case O_WRONLY: 159 return ACCESS_W; 160 case O_RDWR: 161 return ACCESS_R | ACCESS_W; 162 } 163 return 0; 164 } 165 166 167 // NodeMTimeUpdater 168 class NodeMTimeUpdater { 169 public: 170 NodeMTimeUpdater(Node *node) : fNode(node) {} 171 ~NodeMTimeUpdater() 172 { 173 if (fNode && fNode->IsModified()) 174 fNode->MarkUnmodified(); 175 } 176 177 private: 178 Node *fNode; 179 }; 180 181 #endif // NODE_H 182