diff options
author | Mike Buland <eichlan@xagasoft.com> | 2011-02-20 04:59:31 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2011-02-20 04:59:31 +0000 |
commit | 3bb19feba42174a08842e035d21edd424ce9ced1 (patch) | |
tree | e6a9e60fe4527414e8334db874538677c873b4a2 /src/myriadfs.cpp | |
parent | c88a480b9bcabf9aad4f7b66685bbafacc022cc4 (diff) | |
download | libbu++-3bb19feba42174a08842e035d21edd424ce9ced1.tar.gz libbu++-3bb19feba42174a08842e035d21edd424ce9ced1.tar.bz2 libbu++-3bb19feba42174a08842e035d21edd424ce9ced1.tar.xz libbu++-3bb19feba42174a08842e035d21edd424ce9ced1.zip |
Cleaned up a little, and added a bunch more stuff to myriadfs. As far as I can
tell, we're missing rename, chown, and chmod.
Diffstat (limited to '')
-rw-r--r-- | src/myriadfs.cpp | 223 |
1 files changed, 185 insertions, 38 deletions
diff --git a/src/myriadfs.cpp b/src/myriadfs.cpp index b4ba733..41ba652 100644 --- a/src/myriadfs.cpp +++ b/src/myriadfs.cpp | |||
@@ -112,7 +112,8 @@ void Bu::MyriadFs::stat( const Bu::String &sPath, Bu::MyriadFs::Stat &rBuf ) | |||
112 | stat( iNode, rBuf, is ); | 112 | stat( iNode, rBuf, is ); |
113 | } | 113 | } |
114 | 114 | ||
115 | Bu::MyriadStream Bu::MyriadFs::open( const Bu::String &sPath, int iMode ) | 115 | Bu::MyriadStream Bu::MyriadFs::open( const Bu::String &sPath, int iMode, |
116 | uint16_t uPerms ) | ||
116 | { | 117 | { |
117 | int32_t iParent = -1; | 118 | int32_t iParent = -1; |
118 | int32_t iNode; | 119 | int32_t iNode; |
@@ -134,16 +135,10 @@ Bu::MyriadStream Bu::MyriadFs::open( const Bu::String &sPath, int iMode ) | |||
134 | 135 | ||
135 | // The file wasn't found, but the path leading up to it was. | 136 | // The file wasn't found, but the path leading up to it was. |
136 | // first, figure out the final path element... | 137 | // first, figure out the final path element... |
137 | Bu::String::const_iterator iStart = sPath.begin(); | 138 | Bu::String sName = filePart( sPath ); |
138 | if( *iStart == '/' ) | ||
139 | iStart++; | ||
140 | sio << "Scanning for filename:" << sio.nl; | ||
141 | for( Bu::String::const_iterator iEnd = iStart.find('/'); iEnd; | ||
142 | iStart = iEnd+1, iEnd = iStart.find('/') ) { } | ||
143 | Bu::String sName( iStart, sPath.end() ); | ||
144 | sio << "End filename: " << sName << sio.nl; | 139 | sio << "End filename: " << sName << sio.nl; |
145 | sio << "Parent inode: " << iParent << sio.nl; | 140 | sio << "Parent inode: " << iParent << sio.nl; |
146 | iNode = create( iParent, sName, 0664|typeRegFile, 0 ); | 141 | iNode = create( iParent, sName, (uPerms&permMask)|typeRegFile, 0 ); |
147 | sio << "New iNode: " << iNode << sio.nl; | 142 | sio << "New iNode: " << iNode << sio.nl; |
148 | return openByInode( iNode ); | 143 | return openByInode( iNode ); |
149 | } | 144 | } |
@@ -183,13 +178,7 @@ void Bu::MyriadFs::create( const Bu::String &sPath, uint16_t iPerms, | |||
183 | 178 | ||
184 | // The file wasn't found, but the path leading up to it was. | 179 | // The file wasn't found, but the path leading up to it was. |
185 | // first, figure out the final path element... | 180 | // first, figure out the final path element... |
186 | Bu::String::const_iterator iStart = sPath.begin(); | 181 | Bu::String sName = filePart( sPath ); |
187 | if( *iStart == '/' ) | ||
188 | iStart++; | ||
189 | sio << "Scanning for filename:" << sio.nl; | ||
190 | for( Bu::String::const_iterator iEnd = iStart.find('/'); iEnd; | ||
191 | iStart = iEnd+1, iEnd = iStart.find('/') ) { } | ||
192 | Bu::String sName( iStart, sPath.end() ); | ||
193 | sio << "End filename: " << sName << sio.nl; | 182 | sio << "End filename: " << sName << sio.nl; |
194 | sio << "Parent inode: " << iParent << sio.nl; | 183 | sio << "Parent inode: " << iParent << sio.nl; |
195 | iNode = create( iParent, sName, iPerms, uSpecial ); | 184 | iNode = create( iParent, sName, iPerms, uSpecial ); |
@@ -202,6 +191,49 @@ void Bu::MyriadFs::mkDir( const Bu::String &sPath, uint16_t iPerms ) | |||
202 | create( sPath, (iPerms&permMask)|typeDir, 0 ); | 191 | create( sPath, (iPerms&permMask)|typeDir, 0 ); |
203 | } | 192 | } |
204 | 193 | ||
194 | void Bu::MyriadFs::mkSymLink( const Bu::String &sPath, | ||
195 | const Bu::String &sTarget ) | ||
196 | { | ||
197 | int32_t iParent = -1; | ||
198 | int32_t iNode; | ||
199 | try | ||
200 | { | ||
201 | iNode = lookupInode( sPath, iParent ); | ||
202 | throw Bu::MyriadFsException("Path already exists."); | ||
203 | } | ||
204 | catch( Bu::MyriadFsException &e ) | ||
205 | { | ||
206 | if( iParent < 0 ) | ||
207 | throw; | ||
208 | |||
209 | // This means that an intermediate path component couldn't be found | ||
210 | if( e.getErrorCode() == 1 ) | ||
211 | throw; | ||
212 | |||
213 | // The file wasn't found, but the path leading up to it was. | ||
214 | // first, figure out the final path element... | ||
215 | Bu::String sName = filePart( sPath ); | ||
216 | sio << "End filename: " << sName << sio.nl; | ||
217 | sio << "Parent inode: " << iParent << sio.nl; | ||
218 | iNode = create( iParent, sName, 0777|typeSymLink, 0 ); | ||
219 | sio << "New iNode: " << iNode << sio.nl; | ||
220 | MyriadStream ms = openByInode( iNode ); | ||
221 | ms.write( sTarget ); | ||
222 | } | ||
223 | } | ||
224 | |||
225 | Bu::String Bu::MyriadFs::readSymLink( const Bu::String &sPath ) | ||
226 | { | ||
227 | int32_t iParent = -1; | ||
228 | int32_t iNode; | ||
229 | iNode = lookupInode( sPath, iParent ); | ||
230 | MyriadStream ms = openByInode( iNode ); | ||
231 | Bu::String sRet; | ||
232 | sRet.setSize( ms.getSize() ); | ||
233 | ms.read( sRet.getStr(), ms.getSize() ); | ||
234 | return sRet; | ||
235 | } | ||
236 | |||
205 | Bu::MyriadFs::Dir Bu::MyriadFs::readDir( const Bu::String &sPath ) | 237 | Bu::MyriadFs::Dir Bu::MyriadFs::readDir( const Bu::String &sPath ) |
206 | { | 238 | { |
207 | int32_t iParent = -1; | 239 | int32_t iParent = -1; |
@@ -220,6 +252,59 @@ void Bu::MyriadFs::setTimes( const Bu::String &sPath, int64_t iATime, | |||
220 | setTimes( iNode, iATime, iMTime ); | 252 | setTimes( iNode, iATime, iMTime ); |
221 | } | 253 | } |
222 | 254 | ||
255 | void Bu::MyriadFs::unlink( const Bu::String &sPath ) | ||
256 | { | ||
257 | int32_t iParent = -1; | ||
258 | int32_t iNode; | ||
259 | |||
260 | iNode = lookupInode( sPath, iParent ); | ||
261 | |||
262 | Dir lDir = readDir( iParent ); | ||
263 | |||
264 | Bu::String sName = filePart( sPath ); | ||
265 | |||
266 | for( Dir::iterator i = lDir.begin(); i; i++ ) | ||
267 | { | ||
268 | if( sName == (*i).sName ) | ||
269 | { | ||
270 | RawStat rs; | ||
271 | readInode( (*i).iNode, rs ); | ||
272 | if( (rs.uPerms&typeMask) == typeDir ) | ||
273 | { | ||
274 | MyriadStream msDir = mStore.openStream( rs.uStreamIndex ); | ||
275 | int32_t iCount; | ||
276 | msDir.read( &iCount, 4 ); | ||
277 | if( iCount > 0 ) | ||
278 | { | ||
279 | throw Bu::MyriadFsException("Directory not empty."); | ||
280 | } | ||
281 | } | ||
282 | if( --rs.iLinks == 0 ) | ||
283 | { | ||
284 | destroyNode( (*i).iNode ); | ||
285 | } | ||
286 | else | ||
287 | { | ||
288 | writeInode( rs ); | ||
289 | } | ||
290 | lDir.erase( i ); | ||
291 | break; | ||
292 | } | ||
293 | } | ||
294 | |||
295 | Bu::MyriadStream ms = openByInode( iParent ); | ||
296 | int32_t iNumChildren = lDir.getSize(); | ||
297 | ms.write( &iNumChildren, 4 ); | ||
298 | for( Dir::iterator i = lDir.begin(); i; i++ ) | ||
299 | { | ||
300 | ms.write( &(*i).iNode, 4 ); | ||
301 | uint8_t iSize = (*i).sName.getSize(); | ||
302 | ms.write( &iSize, 1 ); | ||
303 | ms.write( (*i).sName.getStr(), iSize ); | ||
304 | } | ||
305 | ms.setSize( ms.tell() ); | ||
306 | } | ||
307 | |||
223 | dev_t Bu::MyriadFs::devToSys( uint32_t uDev ) | 308 | dev_t Bu::MyriadFs::devToSys( uint32_t uDev ) |
224 | { | 309 | { |
225 | return (((uDev&0xFFFF0000)>>8)&0xFF00) | ((uDev&0xFF)); | 310 | return (((uDev&0xFFFF0000)>>8)&0xFF00) | ((uDev&0xFF)); |
@@ -295,6 +380,36 @@ int32_t Bu::MyriadFs::lookupInode( Bu::String::const_iterator iStart, | |||
295 | throw Bu::MyriadFsException( 2, "Path not found"); | 380 | throw Bu::MyriadFsException( 2, "Path not found"); |
296 | } | 381 | } |
297 | 382 | ||
383 | void Bu::MyriadFs::readInode( int32_t iNode, RawStat &rs, MyriadStream &rIs ) | ||
384 | { | ||
385 | rIs.setPos( hNodeIndex.get( iNode )*sizeof(RawStat) ); | ||
386 | if( rIs.read( &rs, sizeof(RawStat) ) < sizeof(RawStat) ) | ||
387 | throw Bu::MyriadFsException("Filesystem corruption detected."); | ||
388 | if( rs.iNode != iNode ) | ||
389 | throw Bu::MyriadFsException("Filesystem corruption detected."); | ||
390 | } | ||
391 | |||
392 | void Bu::MyriadFs::readInode( int32_t iNode, RawStat &rs ) | ||
393 | { | ||
394 | MyriadStream ms = mStore.openStream( 2 ); | ||
395 | readInode( iNode, rs, ms ); | ||
396 | } | ||
397 | |||
398 | void Bu::MyriadFs::writeInode( const RawStat &rs, | ||
399 | MyriadStream &rOs ) | ||
400 | { | ||
401 | rOs.setSize( hNodeIndex.getSize()*sizeof(RawStat) ); | ||
402 | rOs.setPos( hNodeIndex.get( rs.iNode )*sizeof(RawStat) ); | ||
403 | if( rOs.write( &rs, sizeof(RawStat) ) < sizeof(RawStat) ) | ||
404 | throw Bu::MyriadFsException("Error writing inode to header stream."); | ||
405 | } | ||
406 | |||
407 | void Bu::MyriadFs::writeInode( const RawStat &rs ) | ||
408 | { | ||
409 | MyriadStream ms = mStore.openStream( 2 ); | ||
410 | writeInode( rs, ms ); | ||
411 | } | ||
412 | |||
298 | Bu::MyriadFs::Dir Bu::MyriadFs::readDir( int32_t iNode ) | 413 | Bu::MyriadFs::Dir Bu::MyriadFs::readDir( int32_t iNode ) |
299 | { | 414 | { |
300 | Bu::MyriadStream ms = openByInode( iNode ); | 415 | Bu::MyriadStream ms = openByInode( iNode ); |
@@ -324,11 +439,8 @@ Bu::MyriadFs::Dir Bu::MyriadFs::readDir( int32_t iNode ) | |||
324 | 439 | ||
325 | Bu::MyriadStream Bu::MyriadFs::openByInode( int32_t iNode ) | 440 | Bu::MyriadStream Bu::MyriadFs::openByInode( int32_t iNode ) |
326 | { | 441 | { |
327 | int32_t iIndex = hNodeIndex.get( iNode ); | ||
328 | Bu::MyriadStream ms = mStore.openStream( 2 ); | ||
329 | ms.setPos( iIndex*sizeof(RawStat) ); | ||
330 | RawStat rs; | 442 | RawStat rs; |
331 | ms.read( &rs, sizeof(RawStat) ); | 443 | readInode( iNode, rs ); |
332 | switch( (rs.uPerms&typeMask) ) | 444 | switch( (rs.uPerms&typeMask) ) |
333 | { | 445 | { |
334 | case typeDir: | 446 | case typeDir: |
@@ -371,10 +483,6 @@ int32_t Bu::MyriadFs::allocInode( uint16_t uPerms, uint32_t uSpecial ) | |||
371 | { | 483 | { |
372 | if( !hNodeIndex.has( iNode ) ) | 484 | if( !hNodeIndex.has( iNode ) ) |
373 | { | 485 | { |
374 | Bu::MyriadStream is = mStore.openStream( 2 ); | ||
375 | is.setSize( (hNodeIndex.getSize()+1)*sizeof(RawStat) ); | ||
376 | is.setPos( hNodeIndex.getSize()*sizeof(RawStat) ); | ||
377 | |||
378 | hNodeIndex.insert( iNode, hNodeIndex.getSize() ); | 486 | hNodeIndex.insert( iNode, hNodeIndex.getSize() ); |
379 | RawStat rs; | 487 | RawStat rs; |
380 | rs.iNode = iNode; | 488 | rs.iNode = iNode; |
@@ -414,7 +522,7 @@ int32_t Bu::MyriadFs::allocInode( uint16_t uPerms, uint32_t uSpecial ) | |||
414 | rs.iATime = time(NULL); | 522 | rs.iATime = time(NULL); |
415 | rs.iMTime = time(NULL); | 523 | rs.iMTime = time(NULL); |
416 | rs.iCTime = time(NULL); | 524 | rs.iCTime = time(NULL); |
417 | is.write( &rs, sizeof(RawStat) ); | 525 | writeInode( rs ); |
418 | 526 | ||
419 | return iNode; | 527 | return iNode; |
420 | } | 528 | } |
@@ -426,11 +534,8 @@ int32_t Bu::MyriadFs::allocInode( uint16_t uPerms, uint32_t uSpecial ) | |||
426 | 534 | ||
427 | void Bu::MyriadFs::stat( int32_t iNode, Stat &rBuf, MyriadStream &rIs ) | 535 | void Bu::MyriadFs::stat( int32_t iNode, Stat &rBuf, MyriadStream &rIs ) |
428 | { | 536 | { |
429 | rIs.setPos( hNodeIndex.get( iNode )*sizeof(RawStat) ); | ||
430 | RawStat rs; | 537 | RawStat rs; |
431 | rIs.read( &rs, sizeof(RawStat) ); | 538 | readInode( iNode, rs, rIs ); |
432 | if( rs.iNode != iNode ) | ||
433 | throw Bu::MyriadFsException("Filesystem corruption detected."); | ||
434 | rBuf.iNode = iNode; | 539 | rBuf.iNode = iNode; |
435 | rBuf.iUser = rs.iUser; | 540 | rBuf.iUser = rs.iUser; |
436 | rBuf.iGroup = rs.iGroup; | 541 | rBuf.iGroup = rs.iGroup; |
@@ -459,11 +564,6 @@ void Bu::MyriadFs::stat( int32_t iNode, Stat &rBuf, MyriadStream &rIs ) | |||
459 | } | 564 | } |
460 | } | 565 | } |
461 | 566 | ||
462 | void Bu::MyriadFs::unlink( int32_t iNode ) | ||
463 | { | ||
464 | |||
465 | } | ||
466 | |||
467 | void Bu::MyriadFs::writeHeader() | 567 | void Bu::MyriadFs::writeHeader() |
468 | { | 568 | { |
469 | Bu::MyriadStream ms = mStore.openStream( 1 ); | 569 | Bu::MyriadStream ms = mStore.openStream( 1 ); |
@@ -489,11 +589,58 @@ void Bu::MyriadFs::setTimes( int32_t iNode, int64_t iATime, int64_t iMTime ) | |||
489 | RawStat rs; | 589 | RawStat rs; |
490 | Bu::MyriadStream is = mStore.openStream( 2 ); | 590 | Bu::MyriadStream is = mStore.openStream( 2 ); |
491 | 591 | ||
492 | is.setPos( hNodeIndex.get(iNode)*sizeof(RawStat) ); | 592 | readInode( iNode, rs, is ); |
493 | is.read( &rs, sizeof(RawStat) ); | ||
494 | rs.iATime = iATime; | 593 | rs.iATime = iATime; |
495 | rs.iMTime = iMTime; | 594 | rs.iMTime = iMTime; |
496 | is.setPos( hNodeIndex.get(iNode)*sizeof(RawStat) ); | 595 | writeInode( rs, is ); |
497 | is.write( &rs, sizeof(RawStat) ); | 596 | } |
597 | |||
598 | void Bu::MyriadFs::destroyNode( int32_t iNode ) | ||
599 | { | ||
600 | if( iNode == 0 ) | ||
601 | throw Bu::MyriadFsException("You cannot destroy the root."); | ||
602 | |||
603 | Bu::MyriadStream is = mStore.openStream( 2 ); | ||
604 | |||
605 | // This will be overwritten with the last node | ||
606 | int32_t iPosition = hNodeIndex.get( iNode ); | ||
607 | RawStat rsOld; | ||
608 | readInode( iNode, rsOld, is ); | ||
609 | switch( (rsOld.uPerms&typeMask) ) | ||
610 | { | ||
611 | case typeRegFile: | ||
612 | case typeDir: | ||
613 | case typeSymLink: | ||
614 | mStore.deleteStream( rsOld.uStreamIndex ); | ||
615 | break; | ||
616 | } | ||
617 | |||
618 | hNodeIndex.erase( iNode ); | ||
619 | |||
620 | // Read the last node, can't use the helpers, because we don't know the | ||
621 | // iNode yet. | ||
622 | if( iPosition != hNodeIndex.getSize() ) | ||
623 | { | ||
624 | // If this is the last node, then we don't need to do anything, but | ||
625 | // this case handles what to do if we aren't on the last node | ||
626 | RawStat rs; | ||
627 | is.setPos( (hNodeIndex.getSize())*sizeof(RawStat) ); | ||
628 | is.read( &rs, sizeof(RawStat) ); | ||
629 | |||
630 | hNodeIndex.get( rs.iNode ) = iPosition; | ||
631 | writeInode( rs, is ); | ||
632 | } | ||
633 | |||
634 | is.setSize( hNodeIndex.getSize() * sizeof(RawStat) ); | ||
635 | } | ||
636 | |||
637 | Bu::String Bu::MyriadFs::filePart( const Bu::String &sPath ) | ||
638 | { | ||
639 | Bu::String::const_iterator iStart = sPath.begin(); | ||
640 | if( *iStart == '/' ) | ||
641 | iStart++; | ||
642 | for( Bu::String::const_iterator iEnd = iStart.find('/'); iEnd; | ||
643 | iStart = iEnd+1, iEnd = iStart.find('/') ) { } | ||
644 | return Bu::String( iStart, sPath.end() ); | ||
498 | } | 645 | } |
499 | 646 | ||