diff options
Diffstat (limited to '')
-rw-r--r-- | src/unstable/myriadfs.h | 205 |
1 files changed, 205 insertions, 0 deletions
diff --git a/src/unstable/myriadfs.h b/src/unstable/myriadfs.h new file mode 100644 index 0000000..ff14292 --- /dev/null +++ b/src/unstable/myriadfs.h | |||
@@ -0,0 +1,205 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2007-2023 Xagasoft, All rights reserved. | ||
3 | * | ||
4 | * This file is part of the libbu++ library and is released under the | ||
5 | * terms of the license contained in the file LICENSE. | ||
6 | */ | ||
7 | |||
8 | #ifndef MYRIAD_FS_H | ||
9 | #define MYRIAD_FS_H | ||
10 | |||
11 | #include <sys/types.h> | ||
12 | |||
13 | #include "bu/myriad.h" | ||
14 | #include "bu/readwritemutex.h" | ||
15 | |||
16 | namespace Bu | ||
17 | { | ||
18 | class Stream; | ||
19 | |||
20 | subExceptionDecl( MyriadFsException ); | ||
21 | |||
22 | /** | ||
23 | * A POSIX compliant, node based filesystem built on top of Myriad. | ||
24 | * | ||
25 | * A header is placed into stream 1. | ||
26 | * Header format: | ||
27 | * int32_t iMagicHeader (A7188B39) | ||
28 | * int8_t iVersion (1) | ||
29 | * int32_t iNumNodes | ||
30 | * NodeLookup[iNumNodes] nNode | ||
31 | * | ||
32 | * Node lookup: | ||
33 | * int32_t iInode | ||
34 | * int32_t iPosition | ||
35 | * | ||
36 | * The node headers or inode structures have a base size of 44 bytes. | ||
37 | * The name is stored in the directory format. | ||
38 | * Basic node header format: | ||
39 | * int32_t iNode | ||
40 | * int32_t iUser | ||
41 | * int32_t iGroup | ||
42 | * uint16_t uPerms | ||
43 | * int16_t iLinks | ||
44 | * uint32_t uStreamIndex | ||
45 | * int64_t iATime | ||
46 | * int64_t iMTime | ||
47 | * int64_t iCTime | ||
48 | * | ||
49 | * Some types get special formats for their assosiated data stream, or | ||
50 | * other special considerations, here's a list: | ||
51 | * | ||
52 | * - typeFifo: No stream, uStreamIndex unused (probably) | ||
53 | * - typeChrDev: No stream, uStreamIndex is device hi/lo | ||
54 | * - typeDir: The stream contains a directory contents listing, described | ||
55 | * below | ||
56 | * - typeBlkDev: No stream, uStreamIndex is device hi/lo | ||
57 | * - typeRegFile: The stream is the file data | ||
58 | * - typeSymLink: The stream is the destination of the symlink | ||
59 | * - typeSocket: No steram, uStreamIndex unused (probably) | ||
60 | * | ||
61 | * Directory streams have this simple listing format. They contain a list | ||
62 | * of all child elements, with no particular order at the moment. The . and | ||
63 | * .. entries are not listed, they are implicit: | ||
64 | * int32_t iNumNodes | ||
65 | * NodeTable[iNumNodes] nChildren | ||
66 | * | ||
67 | * NodeTable: | ||
68 | * int32_t iInode | ||
69 | * uint8_t uNameSize | ||
70 | * char[uNameSize] sName | ||
71 | */ | ||
72 | class MyriadFs | ||
73 | { | ||
74 | public: | ||
75 | MyriadFs( Bu::Stream &rStore, int iBlockSize=512 ); | ||
76 | virtual ~MyriadFs(); | ||
77 | |||
78 | enum | ||
79 | { | ||
80 | permOthX = 0000001, | ||
81 | permOthW = 0000002, | ||
82 | permOthR = 0000004, | ||
83 | permGrpX = 0000010, | ||
84 | permGrpW = 0000020, | ||
85 | permGrpR = 0000040, | ||
86 | permUsrX = 0000100, | ||
87 | permUsrW = 0000200, | ||
88 | permUsrR = 0000400, | ||
89 | permSticky = 0001000, | ||
90 | permSetGid = 0002000, | ||
91 | permSetUid = 0004000, | ||
92 | permMask = 0007777, | ||
93 | typeFifo = 0010000, | ||
94 | typeChrDev = 0020000, | ||
95 | typeDir = 0040000, | ||
96 | typeBlkDev = 0060000, | ||
97 | typeRegFile = 0100000, | ||
98 | typeSymLink = 0120000, | ||
99 | typeSocket = 0140000, | ||
100 | typeMask = 0170000 | ||
101 | }; | ||
102 | |||
103 | enum | ||
104 | { | ||
105 | Read = 0x01, ///< Open file for reading | ||
106 | Write = 0x02, ///< Open file for writing | ||
107 | Create = 0x04, ///< Create file if it doesn't exist | ||
108 | Truncate = 0x08, ///< Truncate file if it does exist | ||
109 | Append = 0x10, ///< Always append on every write | ||
110 | NonBlock = 0x20, ///< Open file in non-blocking mode | ||
111 | Exclusive = 0x44, ///< Create file, if it exists then fail | ||
112 | |||
113 | // Helpful mixes | ||
114 | ReadWrite = 0x03, ///< Open for reading and writing | ||
115 | WriteNew = 0x0E ///< Create a file (or truncate) for writing. | ||
116 | /// Same as Write|Create|Truncate | ||
117 | }; | ||
118 | |||
119 | class Stat | ||
120 | { | ||
121 | public: | ||
122 | int32_t iNode; | ||
123 | int32_t iUser; | ||
124 | int32_t iGroup; | ||
125 | uint16_t uPerms; | ||
126 | int16_t iLinks; | ||
127 | int64_t iATime; | ||
128 | int64_t iMTime; | ||
129 | int64_t iCTime; | ||
130 | int32_t iSize; | ||
131 | uint32_t uDev; | ||
132 | Bu::String sName; | ||
133 | }; | ||
134 | typedef Bu::List<Stat> Dir; | ||
135 | |||
136 | void stat( const Bu::String &sPath, Stat &rBuf ); | ||
137 | MyriadStream open( const Bu::String &sPath, int iMode, | ||
138 | uint16_t uPerms=0664 ); | ||
139 | void create( const Bu::String &sPath, uint16_t iPerms ); | ||
140 | void create( const Bu::String &sPath, uint16_t iPerms, | ||
141 | uint16_t iDevHi, uint16_t iDevLo ); | ||
142 | void create( const Bu::String &sPath, uint16_t iPerms, | ||
143 | uint32_t uSpecial ); | ||
144 | void mkDir( const Bu::String &sPath, uint16_t iPerms ); | ||
145 | void mkSymLink( const Bu::String &sTarget, const Bu::String &sPath ); | ||
146 | void mkHardLink( const Bu::String &sTarget, const Bu::String &sPath ); | ||
147 | Bu::String readSymLink( const Bu::String &sPath ); | ||
148 | Dir readDir( const Bu::String &sPath ); | ||
149 | void setTimes( const Bu::String &sPath, int64_t iATime, | ||
150 | int64_t iMTime ); | ||
151 | void unlink( const Bu::String &sPath ); | ||
152 | void setFileSize( const Bu::String &sPath, int32_t iSize ); | ||
153 | void rename( const Bu::String &sFrom, const Bu::String &sTo ); | ||
154 | |||
155 | static dev_t devToSys( uint32_t uDev ); | ||
156 | static uint32_t sysToDev( dev_t uDev ); | ||
157 | |||
158 | private: | ||
159 | class RawStat | ||
160 | { | ||
161 | public: | ||
162 | int32_t iNode; | ||
163 | int32_t iUser; | ||
164 | int32_t iGroup; | ||
165 | uint16_t uPerms; | ||
166 | int16_t iLinks; | ||
167 | uint32_t uStreamIndex; | ||
168 | int64_t iATime; | ||
169 | int64_t iMTime; | ||
170 | int64_t iCTime; | ||
171 | }; | ||
172 | typedef Bu::Hash<int32_t, int32_t> NodeIndex; | ||
173 | |||
174 | private: | ||
175 | int32_t lookupInode( const Bu::String &sPath, int32_t &iParent ); | ||
176 | int32_t lookupInode( Bu::String::const_iterator iStart, | ||
177 | int32_t iNode, int32_t &iParent ); | ||
178 | void readInode( int32_t iNode, RawStat &rs, MyriadStream &rIs ); | ||
179 | void readInode( int32_t iNode, RawStat &rs ); | ||
180 | void writeInode( const RawStat &rs ); | ||
181 | void writeInode( const RawStat &rs, MyriadStream &rOs ); | ||
182 | Dir readDir( int32_t iNode ); | ||
183 | MyriadStream openByInode( int32_t iNode ); | ||
184 | void addToDir( int32_t iDir, int32_t iNode, const Bu::String &sName ); | ||
185 | int32_t create( int32_t iParent, const Bu::String &sName, | ||
186 | uint16_t uPerms, uint32_t uSpecial ); | ||
187 | int32_t allocInode( uint16_t uPerms, uint32_t uSpecial ); | ||
188 | void stat( int32_t iNode, Stat &rBuf, MyriadStream &rIs ); | ||
189 | void writeHeader(); | ||
190 | void setTimes( int32_t iNode, int64_t iATime, int64_t iMTime ); | ||
191 | void destroyNode( int32_t iNode ); | ||
192 | |||
193 | Bu::String filePart( const Bu::String &sPath ); | ||
194 | |||
195 | private: | ||
196 | Bu::Stream &rStore; | ||
197 | Bu::Myriad mStore; | ||
198 | Bu::ReadWriteMutex mNodeIndex; | ||
199 | NodeIndex hNodeIndex; | ||
200 | int32_t iUser; | ||
201 | int32_t iGroup; | ||
202 | }; | ||
203 | }; | ||
204 | |||
205 | #endif | ||