From 9af80a223128dd465aabdd311fdf529e97b40e13 Mon Sep 17 00:00:00 2001 From: Mike Buland Date: Sun, 20 Feb 2011 07:19:44 +0000 Subject: Well, unlink, mkHardLink, setFileSize, and more are freshly implemented, as is rename, but there seems to be a problem, rename uses mkHardLink, and if the target exists, hey, it adds another one...not quite ideal... --- src/myriadfs.cpp | 69 ++++++++++++++++++++++++++--- src/myriadfs.h | 6 ++- src/tools/myriadfs.cpp | 115 +++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 175 insertions(+), 15 deletions(-) diff --git a/src/myriadfs.cpp b/src/myriadfs.cpp index 41ba652..cebae1c 100644 --- a/src/myriadfs.cpp +++ b/src/myriadfs.cpp @@ -191,8 +191,8 @@ void Bu::MyriadFs::mkDir( const Bu::String &sPath, uint16_t iPerms ) create( sPath, (iPerms&permMask)|typeDir, 0 ); } -void Bu::MyriadFs::mkSymLink( const Bu::String &sPath, - const Bu::String &sTarget ) +void Bu::MyriadFs::mkSymLink( const Bu::String &sTarget, + const Bu::String &sPath ) { int32_t iParent = -1; int32_t iNode; @@ -222,6 +222,42 @@ void Bu::MyriadFs::mkSymLink( const Bu::String &sPath, } } +void Bu::MyriadFs::mkHardLink( const Bu::String &sTarget, + const Bu::String &sPath ) +{ + int32_t iParent = -1; + int32_t iNode; + + iNode = lookupInode( sTarget, iParent ); + + try + { + lookupInode( sPath, iParent ); + throw Bu::MyriadFsException("Path already exists."); + } + catch( Bu::MyriadFsException &e ) + { + if( iParent < 0 ) + throw; + + // This means that an intermediate path component couldn't be found + if( e.getErrorCode() == 1 ) + throw; + + // The file wasn't found, but the path leading up to it was. + // first, figure out the final path element... + Bu::String sName = filePart( sPath ); + sio << "End filename: " << sName << sio.nl; + sio << "Parent inode: " << iParent << sio.nl; + addToDir( iParent, iNode, sName ); + MyriadStream is = mStore.openStream( 2 ); + RawStat rs; + readInode( iNode, rs, is ); + rs.iLinks++; + writeInode( rs, is ); + } +} + Bu::String Bu::MyriadFs::readSymLink( const Bu::String &sPath ) { int32_t iParent = -1; @@ -305,6 +341,21 @@ void Bu::MyriadFs::unlink( const Bu::String &sPath ) ms.setSize( ms.tell() ); } +void Bu::MyriadFs::setFileSize( const Bu::String &sPath, int32_t iSize ) +{ + int32_t iParent = -1; + int32_t iNode; + iNode = lookupInode( sPath, iParent ); + MyriadStream ms = openByInode( iNode ); + ms.setSize( iSize ); +} + +void Bu::MyriadFs::rename( const Bu::String &sFrom, const Bu::String &sTo ) +{ + mkHardLink( sFrom, sTo ); + unlink( sFrom ); +} + dev_t Bu::MyriadFs::devToSys( uint32_t uDev ) { return (((uDev&0xFFFF0000)>>8)&0xFF00) | ((uDev&0xFF)); @@ -454,25 +505,31 @@ Bu::MyriadStream Bu::MyriadFs::openByInode( int32_t iNode ) } } -int32_t Bu::MyriadFs::create( int32_t iParent, const Bu::String &sName, - uint16_t uPerms, uint32_t uSpecial ) +void Bu::MyriadFs::addToDir( int32_t iDir, int32_t iNode, + const Bu::String &sName ) { if( sName.getSize() > 255 ) { throw Bu::MyriadFsException("Filename too long, max is 255 bytes."); } - Bu::MyriadStream ms = openByInode( iParent ); + Bu::MyriadStream ms = openByInode( iDir ); int32_t iNumChildren = 0; ms.read( &iNumChildren, 4 ); iNumChildren++; ms.setPos( 0 ); ms.write( &iNumChildren, 4 ); ms.setPosEnd( 0 ); - int32_t iNode = allocInode( uPerms, uSpecial ); ms.write( &iNode, 4 ); uint8_t uLen = sName.getSize(); ms.write( &uLen, 1 ); ms.write( sName.getStr(), uLen ); +} + +int32_t Bu::MyriadFs::create( int32_t iParent, const Bu::String &sName, + uint16_t uPerms, uint32_t uSpecial ) +{ + int32_t iNode = allocInode( uPerms, uSpecial ); + addToDir( iParent, iNode, sName ); return iNode; } diff --git a/src/myriadfs.h b/src/myriadfs.h index b54d170..cc9961a 100644 --- a/src/myriadfs.h +++ b/src/myriadfs.h @@ -141,12 +141,15 @@ namespace Bu void create( const Bu::String &sPath, uint16_t iPerms, uint32_t uSpecial ); void mkDir( const Bu::String &sPath, uint16_t iPerms ); - void mkSymLink( const Bu::String &sPath, const Bu::String &sTarget ); + void mkSymLink( const Bu::String &sTarget, const Bu::String &sPath ); + void mkHardLink( const Bu::String &sTarget, const Bu::String &sPath ); Bu::String readSymLink( const Bu::String &sPath ); Dir readDir( const Bu::String &sPath ); void setTimes( const Bu::String &sPath, int64_t iATime, int64_t iMTime ); void unlink( const Bu::String &sPath ); + void setFileSize( const Bu::String &sPath, int32_t iSize ); + void rename( const Bu::String &sFrom, const Bu::String &sTo ); static dev_t devToSys( uint32_t uDev ); static uint32_t sysToDev( dev_t uDev ); @@ -177,6 +180,7 @@ namespace Bu void writeInode( const RawStat &rs, MyriadStream &rOs ); Dir readDir( int32_t iNode ); MyriadStream openByInode( int32_t iNode ); + void addToDir( int32_t iDir, int32_t iNode, const Bu::String &sName ); int32_t create( int32_t iParent, const Bu::String &sName, uint16_t uPerms, uint32_t uSpecial ); int32_t allocInode( uint16_t uPerms, uint32_t uSpecial ); diff --git a/src/tools/myriadfs.cpp b/src/tools/myriadfs.cpp index 8db59d7..3e4599b 100644 --- a/src/tools/myriadfs.cpp +++ b/src/tools/myriadfs.cpp @@ -24,9 +24,14 @@ typedef Bu::Hash FileHash; FileHash hOpenFiles; int64_t iNextFileId = 0; +#define TRACE + extern "C" { static int myriadfs_getattr( const char *sPath, struct stat *stbuf ) { +#ifdef TRACE + printf("myriadfs_getattr(\"%s\", ... );\n", sPath ); +#endif try { Bu::MyriadFs::Stat st; @@ -53,6 +58,9 @@ extern "C" { static int myriadfs_readdir( const char *sPath, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi ) { +#ifdef TRACE + printf("myriadfs_readdir(\"%s\", ... );\n", sPath ); +#endif Bu::MyriadFs::Dir lDir = pFs->readDir( sPath ); filler( buf, ".", NULL, 0 ); filler( buf, "..", NULL, 0 ); @@ -66,19 +74,25 @@ extern "C" { static int myriadfs_mkdir( const char *sPath, mode_t uMode ) { +#ifdef TRACE + printf("myriadfs_mkdir(\"%s\", 0%o );\n", sPath, uMode ); +#endif pFs->mkDir( sPath, uMode ); return 0; } static int myriadfs_open( const char *sPath, struct fuse_file_info *fi ) { +#ifdef TRACE + printf("myriadfs_open(\"%s\", ... );\n", sPath ); +#endif try { Bu::MyriadStream ms = pFs->open( sPath, 0 ); fi->fh = iNextFileId; hOpenFiles.insert( iNextFileId++, ms ); - printf("File '%s' opened, %d files open now.\n", - sPath, hOpenFiles.getSize() ); +// printf("File '%s' opened, %d files open now.\n", +// sPath, hOpenFiles.getSize() ); return 0; } catch(...) @@ -90,6 +104,10 @@ extern "C" { static int myriadfs_read( const char *sPath, char *buf, size_t iSize, off_t iOffset, struct fuse_file_info *fi ) { +#ifdef TRACE + printf("myriadfs_read(\"%s\", ..., %d, %d, ... );\n", sPath, iSize, + iOffset ); +#endif Bu::MyriadStream &ms = hOpenFiles.get( fi->fh ); ms.setPos( iOffset ); return ms.read( buf, iSize ); @@ -98,6 +116,10 @@ extern "C" { static int myriadfs_write( const char *sPath, const char *buf, size_t iSize, off_t iOffset, struct fuse_file_info *fi ) { +#ifdef TRACE + printf("myriadfs_write(\"%s\", ..., %d, %d, ... );\n", sPath, iSize, + iOffset ); +#endif Bu::MyriadStream &ms = hOpenFiles.get( fi->fh ); ms.setPos( iOffset ); return ms.write( buf, iSize ); @@ -106,13 +128,16 @@ extern "C" { static int myriadfs_create( const char *sPath, mode_t uPerms, struct fuse_file_info *fi ) { +#ifdef TRACE + printf("myriadfs_create(\"%s\", 0%o, ... );\n", sPath, uPerms ); +#endif try { Bu::MyriadStream ms = pFs->open( sPath, 0, uPerms ); fi->fh = iNextFileId; hOpenFiles.insert( iNextFileId++, ms ); - printf("File '%s' created, %d files open now.\n", - sPath, hOpenFiles.getSize() ); +// printf("File '%s' created, %d files open now.\n", +// sPath, hOpenFiles.getSize() ); return 0; } catch(...) @@ -123,6 +148,9 @@ extern "C" { static int myriadfs_mknod( const char *sPath, mode_t uPerms, dev_t Dev ) { +#ifdef TRACE + printf("myriadfs_mknod(\"%s\", 0%o, %x );\n", sPath, uPerms, Dev ); +#endif try { pFs->create( sPath, uPerms, Bu::MyriadFs::sysToDev( Dev ) ); @@ -136,9 +164,12 @@ extern "C" { static int myriadfs_release( const char *sPath, struct fuse_file_info *fi ) { +#ifdef TRACE + printf("myriadfs_release(\"%s\", ... );\n", sPath ); +#endif hOpenFiles.erase( fi->fh ); - printf("File '%s' released, %d files open now.\n", - sPath, hOpenFiles.getSize() ); +// printf("File '%s' released, %d files open now.\n", +// sPath, hOpenFiles.getSize() ); return 0; } @@ -146,6 +177,9 @@ extern "C" { static int myriadfs_utimens( const char *sPath, const struct timespec tv[2] ) { +#ifdef TRACE + printf("myriadfs_utimens(\"%s\", ... );\n", sPath ); +#endif try { pFs->setTimes( sPath, tv[0].tv_sec, tv[1].tv_sec ); @@ -159,6 +193,9 @@ extern "C" { static int myriadfs_unlink( const char *sPath ) { +#ifdef TRACE + printf("myriadfs_unlink(\"%s\");\n", sPath ); +#endif try { pFs->unlink( sPath ); @@ -173,10 +210,12 @@ extern "C" { static int myriadfs_symlink( const char *sTarget, const char *sPath ) { +#ifdef TRACE + printf("myriadfs_symlink(\"%s\", \"%s\");\n", sTarget, sPath ); +#endif try { - printf("Path = '%s', Target = '%s'\n", sPath, sTarget ); - pFs->mkSymLink( sPath, sTarget ); + pFs->mkSymLink( sTarget, sPath ); } catch( Bu::MyriadFsException &e ) { @@ -188,6 +227,9 @@ extern "C" { static int myriadfs_readlink( const char *sPath, char *sOut, size_t s ) { +#ifdef TRACE + printf("myriadfs_readlink(\"%s\", ... );\n", sPath ); +#endif try { Bu::String sTrg = pFs->readSymLink( sPath ); @@ -203,6 +245,60 @@ extern "C" { return 0; } + static int myriadfs_truncate( const char *sPath, off_t iSize ) + { +#ifdef TRACE + printf("myriadfs_truncate(\"%s\", %d );\n", sPath, iSize ); +#endif + + try + { + pFs->setFileSize( sPath, iSize ); + } + catch( Bu::MyriadFsException &e ) + { + printf("MyriadFsException: %s\n", e.what() ); + return -ENOENT; + } + return 0; + } + + static int myriadfs_link( const char *sTarget, const char *sPath ) + { +#ifdef TRACE + printf("myriadfs_link(\"%s\", \"%s\");\n", sTarget, sPath ); +#endif + + try + { + pFs->mkHardLink( sTarget, sPath ); + } + catch( Bu::MyriadFsException &e ) + { + printf("MyriadFsException: %s\n", e.what() ); + return -EACCES; + } + return 0; + } + + static int myriadfs_rename( const char *sFrom, const char *sTo ) + { +#ifdef TRACE + printf("myriadfs_rename(\"%s\", \"%s\");\n", sFrom, sTo ); +#endif + + try + { + pFs->rename( sFrom, sTo ); + } + catch( Bu::MyriadFsException &e ) + { + printf("MyriadFsException: %s\n", e.what() ); + return -EACCES; + } + return 0; + } + static struct fuse_operations myriadfs_oper; int main( int argc, char *argv[] ) @@ -224,6 +320,9 @@ extern "C" { myriadfs_oper.rmdir = myriadfs_unlink; myriadfs_oper.symlink = myriadfs_symlink; myriadfs_oper.readlink = myriadfs_readlink; + myriadfs_oper.truncate = myriadfs_truncate; + myriadfs_oper.link = myriadfs_link; + myriadfs_oper.rename = myriadfs_rename; printf("Starting fuse_main.\n"); int iRet = fuse_main( argc, argv, &myriadfs_oper, NULL ); printf("Done with fuse_main.\n"); -- cgit v1.2.3