btrfs: [] on the end of a struct field is a variable length array.
[haiku.git] / src / add-ons / kernel / file_systems / exfat / Inode.h
blob26bc92fa0d6f5fdcb96312872f380673c15a4ad0
1 /*
2 * Copyright 2011, Jérôme Duval, korli@users.berlios.de.
3 * Copyright 2008, Axel Dörfler, axeld@pinc-software.de.
4 * This file may be used under the terms of the MIT License.
5 */
6 #ifndef INODE_H
7 #define INODE_H
10 #include <fs_cache.h>
11 #include <lock.h>
12 #include <string.h>
14 #include "DirectoryIterator.h"
15 #include "exfat.h"
16 #include "SplayTree.h"
17 #include "Volume.h"
20 //#define TRACE_EXFAT
21 #ifdef TRACE_EXFAT
22 # define TRACEI(x...) dprintf("\33[34mexfat:\33[0m " x)
23 #else
24 # define TRACEI(x...) ;
25 #endif
28 struct InodesTreeDefinition;
31 class Inode : EntryVisitor {
32 public:
33 Inode(Volume* volume, cluster_t cluster,
34 uint32 offset);
35 Inode(Volume* volume, ino_t ino);
36 ~Inode();
38 status_t InitCheck();
40 ino_t ID() const { return fID; }
41 ino_t Parent() const { return fParent; }
42 cluster_t Cluster() const { return fCluster; }
43 uint32 Offset() const { return fOffset; }
44 cluster_t StartCluster() const
45 { return fFileInfoEntry.file_info.StartCluster(); }
46 bool IsContiguous() const
47 { return fFileInfoEntry.file_info.IsContiguous(); }
48 cluster_t NextCluster(cluster_t cluster) const;
50 rw_lock* Lock() { return &fLock; }
52 status_t UpdateNodeFromDisk();
54 bool IsDirectory() const
55 { return S_ISDIR(Mode()); }
56 bool IsFile() const
57 { return S_ISREG(Mode()); }
58 bool IsSymLink() const
59 { return S_ISLNK(Mode()); }
60 status_t CheckPermissions(int accessMode) const;
62 mode_t Mode() const;
63 off_t Size() const { return fFileInfoEntry.file_info.Size(); }
64 uid_t UserID() const { return 0;/*fNode.UserID();*/ }
65 gid_t GroupID() const { return 0;/*fNode.GroupID();*/ }
66 void GetChangeTime(struct timespec &timespec) const
67 { GetModificationTime(timespec); }
68 void GetModificationTime(struct timespec &timespec) const
69 { _GetTimespec(fFileEntry.file.ModificationDate(),
70 fFileEntry.file.ModificationTime(), timespec); }
71 void GetCreationTime(struct timespec &timespec) const
72 { _GetTimespec(fFileEntry.file.CreationDate(),
73 fFileEntry.file.CreationTime(), timespec); }
74 void GetAccessTime(struct timespec &timespec) const
75 { _GetTimespec(fFileEntry.file.AccessDate(),
76 fFileEntry.file.AccessTime(), timespec); }
78 Volume* GetVolume() const { return fVolume; }
80 status_t FindBlock(off_t logical, off_t& physical,
81 off_t *_length = NULL);
82 status_t ReadAt(off_t pos, uint8 *buffer, size_t *length);
83 status_t FillGapWithZeros(off_t start, off_t end);
85 void* FileCache() const { return fCache; }
86 void* Map() const { return fMap; }
88 bool VisitFile(struct exfat_entry*);
89 bool VisitFileInfo(struct exfat_entry*);
91 private:
92 friend struct InodesInoTreeDefinition;
93 friend struct InodesClusterTreeDefinition;
95 Inode(Volume* volume);
96 Inode(const Inode&);
97 Inode &operator=(const Inode&);
98 // no implementation
100 void _GetTimespec(uint16 date, uint16 time,
101 struct timespec &timespec) const;
102 void _Init();
104 rw_lock fLock;
105 ::Volume* fVolume;
106 ino_t fID;
107 ino_t fParent;
108 cluster_t fCluster;
109 uint32 fOffset;
110 uint32 fFlags;
111 void* fCache;
112 void* fMap;
113 status_t fInitStatus;
115 SplayTreeLink<Inode> fInoTreeLink;
116 Inode* fInoTreeNext;
117 SplayTreeLink<Inode> fClusterTreeLink;
118 Inode* fClusterTreeNext;
120 struct exfat_entry fFileEntry;
121 struct exfat_entry fFileInfoEntry;
125 // The Vnode class provides a convenience layer upon get_vnode(), so that
126 // you don't have to call put_vnode() anymore, which may make code more
127 // readable in some cases
129 class Vnode {
130 public:
131 Vnode(Volume* volume, ino_t id)
133 fInode(NULL)
135 SetTo(volume, id);
138 Vnode()
140 fStatus(B_NO_INIT),
141 fInode(NULL)
145 ~Vnode()
147 Unset();
150 status_t InitCheck()
152 return fStatus;
155 void Unset()
157 if (fInode != NULL) {
158 put_vnode(fInode->GetVolume()->FSVolume(), fInode->ID());
159 fInode = NULL;
160 fStatus = B_NO_INIT;
164 status_t SetTo(Volume* volume, ino_t id)
166 Unset();
168 return fStatus = get_vnode(volume->FSVolume(), id, (void**)&fInode);
171 status_t Get(Inode** _inode)
173 *_inode = fInode;
174 return fStatus;
177 void Keep()
179 TRACEI("Vnode::Keep()\n");
180 fInode = NULL;
183 private:
184 status_t fStatus;
185 Inode* fInode;
189 struct InodesInoTreeDefinition {
190 typedef ino_t KeyType;
191 typedef Inode NodeType;
193 static KeyType GetKey(const NodeType* node)
195 return node->ID();
198 static SplayTreeLink<NodeType>* GetLink(NodeType* node)
200 return &node->fInoTreeLink;
203 static int Compare(KeyType key, const NodeType* node)
205 return key == node->ID() ? 0
206 : (key < node->ID() ? -1 : 1);
209 static NodeType** GetListLink(NodeType* node)
211 return &node->fInoTreeNext;
215 typedef IteratableSplayTree<InodesInoTreeDefinition> InodesInoTree;
217 struct InodesClusterTreeDefinition {
218 typedef cluster_t KeyType;
219 typedef Inode NodeType;
221 static KeyType GetKey(const NodeType* node)
223 return node->Cluster();
226 static SplayTreeLink<NodeType>* GetLink(NodeType* node)
228 return &node->fClusterTreeLink;
231 static int Compare(KeyType key, const NodeType* node)
233 return key == node->Cluster() ? 0
234 : (key < node->Cluster() ? -1 : 1);
237 static NodeType** GetListLink(NodeType* node)
239 return &node->fClusterTreeNext;
243 typedef IteratableSplayTree<InodesClusterTreeDefinition> InodesClusterTree;
245 #endif // INODE_H