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.
14 #include "DirectoryIterator.h"
16 #include "SplayTree.h"
22 # define TRACEI(x...) dprintf("\33[34mexfat:\33[0m " x)
24 # define TRACEI(x...) ;
28 struct InodesTreeDefinition
;
31 class Inode
: EntryVisitor
{
33 Inode(Volume
* volume
, cluster_t cluster
,
35 Inode(Volume
* volume
, ino_t ino
);
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()); }
57 { return S_ISREG(Mode()); }
58 bool IsSymLink() const
59 { return S_ISLNK(Mode()); }
60 status_t
CheckPermissions(int accessMode
) 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
×pec
) const
67 { GetModificationTime(timespec
); }
68 void GetModificationTime(struct timespec
×pec
) const
69 { _GetTimespec(fFileEntry
.file
.ModificationDate(),
70 fFileEntry
.file
.ModificationTime(), timespec
); }
71 void GetCreationTime(struct timespec
×pec
) const
72 { _GetTimespec(fFileEntry
.file
.CreationDate(),
73 fFileEntry
.file
.CreationTime(), timespec
); }
74 void GetAccessTime(struct timespec
×pec
) 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
*);
92 friend struct InodesInoTreeDefinition
;
93 friend struct InodesClusterTreeDefinition
;
95 Inode(Volume
* volume
);
97 Inode
&operator=(const Inode
&);
100 void _GetTimespec(uint16 date
, uint16 time
,
101 struct timespec
×pec
) const;
113 status_t fInitStatus
;
115 SplayTreeLink
<Inode
> fInoTreeLink
;
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
131 Vnode(Volume
* volume
, ino_t id
)
157 if (fInode
!= NULL
) {
158 put_vnode(fInode
->GetVolume()->FSVolume(), fInode
->ID());
164 status_t
SetTo(Volume
* volume
, ino_t id
)
168 return fStatus
= get_vnode(volume
->FSVolume(), id
, (void**)&fInode
);
171 status_t
Get(Inode
** _inode
)
179 TRACEI("Vnode::Keep()\n");
189 struct InodesInoTreeDefinition
{
190 typedef ino_t KeyType
;
191 typedef Inode NodeType
;
193 static KeyType
GetKey(const NodeType
* node
)
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
;