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
HashLink()41 Node*& HashLink() { return fHashLink; }
42
SetVolume(Volume * volume)43 inline void SetVolume(Volume *volume) { fVolume = volume; }
GetVolume()44 inline Volume *GetVolume() const { return fVolume; }
45
GetID()46 inline ino_t GetID() const { return fID; }
47
48 status_t AddReference();
49 void RemoveReference();
GetRefCount()50 int32 GetRefCount() { return fRefCount; }
51
52 virtual status_t Link(Entry *entry);
53 virtual status_t Unlink(Entry *entry);
54
IsDirectory()55 inline bool IsDirectory() const { return S_ISDIR(fMode); }
IsFile()56 inline bool IsFile() const { return S_ISREG(fMode); }
IsSymLink()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
SetMode(mode_t mode)64 inline void SetMode(mode_t mode)
65 { fMode = (fMode & ~S_IUMSK) | (mode & S_IUMSK); }
GetMode()66 inline mode_t GetMode() const { return fMode; }
67
SetUID(uid_t uid)68 inline void SetUID(uid_t uid) { fUID = uid; MarkModified(B_STAT_UID); }
GetUID()69 inline uid_t GetUID() const { return fUID; }
70
SetGID(uid_t gid)71 inline void SetGID(uid_t gid) { fGID = gid; MarkModified(B_STAT_GID); }
GetGID()72 inline uid_t GetGID() const { return fGID; }
73
SetATime(time_t aTime)74 inline void SetATime(time_t aTime) { fATime = aTime; }
GetATime()75 inline time_t GetATime() const { return fATime; }
76
77 void SetMTime(time_t mTime);
GetMTime()78 inline time_t GetMTime() const { return fMTime; }
79
SetCTime(time_t cTime)80 inline void SetCTime(time_t cTime) { fCTime = cTime; }
GetCTime()81 inline time_t GetCTime() const { return fCTime; }
82
SetCrTime(time_t crTime)83 inline void SetCrTime(time_t crTime) { fCrTime = crTime; }
GetCrTime()84 inline time_t GetCrTime() const { return fCrTime; }
85
MarkModified(uint32 flags)86 inline void MarkModified(uint32 flags) { fModified |= flags; }
87 inline uint32 MarkUnmodified();
IsModified()88 inline bool IsModified() const { return fModified; }
89
90 status_t CheckPermissions(int mode) const;
91
IsKnownToVFS()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
MarkUnmodified()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
open_mode_to_access(int openMode)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:
NodeMTimeUpdater(Node * node)170 NodeMTimeUpdater(Node *node) : fNode(node) {}
~NodeMTimeUpdater()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