aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Buland <eichlan@xagasoft.com>2011-02-20 07:19:44 +0000
committerMike Buland <eichlan@xagasoft.com>2011-02-20 07:19:44 +0000
commit9af80a223128dd465aabdd311fdf529e97b40e13 (patch)
tree062288ceb5816a50aa95bf77715395b76b5a12ae
parent3bb19feba42174a08842e035d21edd424ce9ced1 (diff)
downloadlibbu++-9af80a223128dd465aabdd311fdf529e97b40e13.tar.gz
libbu++-9af80a223128dd465aabdd311fdf529e97b40e13.tar.bz2
libbu++-9af80a223128dd465aabdd311fdf529e97b40e13.tar.xz
libbu++-9af80a223128dd465aabdd311fdf529e97b40e13.zip
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...
-rw-r--r--src/myriadfs.cpp69
-rw-r--r--src/myriadfs.h6
-rw-r--r--src/tools/myriadfs.cpp115
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 )
191 create( sPath, (iPerms&permMask)|typeDir, 0 ); 191 create( sPath, (iPerms&permMask)|typeDir, 0 );
192} 192}
193 193
194void Bu::MyriadFs::mkSymLink( const Bu::String &sPath, 194void Bu::MyriadFs::mkSymLink( const Bu::String &sTarget,
195 const Bu::String &sTarget ) 195 const Bu::String &sPath )
196{ 196{
197 int32_t iParent = -1; 197 int32_t iParent = -1;
198 int32_t iNode; 198 int32_t iNode;
@@ -222,6 +222,42 @@ void Bu::MyriadFs::mkSymLink( const Bu::String &sPath,
222 } 222 }
223} 223}
224 224
225void Bu::MyriadFs::mkHardLink( const Bu::String &sTarget,
226 const Bu::String &sPath )
227{
228 int32_t iParent = -1;
229 int32_t iNode;
230
231 iNode = lookupInode( sTarget, iParent );
232
233 try
234 {
235 lookupInode( sPath, iParent );
236 throw Bu::MyriadFsException("Path already exists.");
237 }
238 catch( Bu::MyriadFsException &e )
239 {
240 if( iParent < 0 )
241 throw;
242
243 // This means that an intermediate path component couldn't be found
244 if( e.getErrorCode() == 1 )
245 throw;
246
247 // The file wasn't found, but the path leading up to it was.
248 // first, figure out the final path element...
249 Bu::String sName = filePart( sPath );
250 sio << "End filename: " << sName << sio.nl;
251 sio << "Parent inode: " << iParent << sio.nl;
252 addToDir( iParent, iNode, sName );
253 MyriadStream is = mStore.openStream( 2 );
254 RawStat rs;
255 readInode( iNode, rs, is );
256 rs.iLinks++;
257 writeInode( rs, is );
258 }
259}
260
225Bu::String Bu::MyriadFs::readSymLink( const Bu::String &sPath ) 261Bu::String Bu::MyriadFs::readSymLink( const Bu::String &sPath )
226{ 262{
227 int32_t iParent = -1; 263 int32_t iParent = -1;
@@ -305,6 +341,21 @@ void Bu::MyriadFs::unlink( const Bu::String &sPath )
305 ms.setSize( ms.tell() ); 341 ms.setSize( ms.tell() );
306} 342}
307 343
344void Bu::MyriadFs::setFileSize( const Bu::String &sPath, int32_t iSize )
345{
346 int32_t iParent = -1;
347 int32_t iNode;
348 iNode = lookupInode( sPath, iParent );
349 MyriadStream ms = openByInode( iNode );
350 ms.setSize( iSize );
351}
352
353void Bu::MyriadFs::rename( const Bu::String &sFrom, const Bu::String &sTo )
354{
355 mkHardLink( sFrom, sTo );
356 unlink( sFrom );
357}
358
308dev_t Bu::MyriadFs::devToSys( uint32_t uDev ) 359dev_t Bu::MyriadFs::devToSys( uint32_t uDev )
309{ 360{
310 return (((uDev&0xFFFF0000)>>8)&0xFF00) | ((uDev&0xFF)); 361 return (((uDev&0xFFFF0000)>>8)&0xFF00) | ((uDev&0xFF));
@@ -454,25 +505,31 @@ Bu::MyriadStream Bu::MyriadFs::openByInode( int32_t iNode )
454 } 505 }
455} 506}
456 507
457int32_t Bu::MyriadFs::create( int32_t iParent, const Bu::String &sName, 508void Bu::MyriadFs::addToDir( int32_t iDir, int32_t iNode,
458 uint16_t uPerms, uint32_t uSpecial ) 509 const Bu::String &sName )
459{ 510{
460 if( sName.getSize() > 255 ) 511 if( sName.getSize() > 255 )
461 { 512 {
462 throw Bu::MyriadFsException("Filename too long, max is 255 bytes."); 513 throw Bu::MyriadFsException("Filename too long, max is 255 bytes.");
463 } 514 }
464 Bu::MyriadStream ms = openByInode( iParent ); 515 Bu::MyriadStream ms = openByInode( iDir );
465 int32_t iNumChildren = 0; 516 int32_t iNumChildren = 0;
466 ms.read( &iNumChildren, 4 ); 517 ms.read( &iNumChildren, 4 );
467 iNumChildren++; 518 iNumChildren++;
468 ms.setPos( 0 ); 519 ms.setPos( 0 );
469 ms.write( &iNumChildren, 4 ); 520 ms.write( &iNumChildren, 4 );
470 ms.setPosEnd( 0 ); 521 ms.setPosEnd( 0 );
471 int32_t iNode = allocInode( uPerms, uSpecial );
472 ms.write( &iNode, 4 ); 522 ms.write( &iNode, 4 );
473 uint8_t uLen = sName.getSize(); 523 uint8_t uLen = sName.getSize();
474 ms.write( &uLen, 1 ); 524 ms.write( &uLen, 1 );
475 ms.write( sName.getStr(), uLen ); 525 ms.write( sName.getStr(), uLen );
526}
527
528int32_t Bu::MyriadFs::create( int32_t iParent, const Bu::String &sName,
529 uint16_t uPerms, uint32_t uSpecial )
530{
531 int32_t iNode = allocInode( uPerms, uSpecial );
532 addToDir( iParent, iNode, sName );
476 return iNode; 533 return iNode;
477} 534}
478 535
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
141 void create( const Bu::String &sPath, uint16_t iPerms, 141 void create( const Bu::String &sPath, uint16_t iPerms,
142 uint32_t uSpecial ); 142 uint32_t uSpecial );
143 void mkDir( const Bu::String &sPath, uint16_t iPerms ); 143 void mkDir( const Bu::String &sPath, uint16_t iPerms );
144 void mkSymLink( const Bu::String &sPath, const Bu::String &sTarget ); 144 void mkSymLink( const Bu::String &sTarget, const Bu::String &sPath );
145 void mkHardLink( const Bu::String &sTarget, const Bu::String &sPath );
145 Bu::String readSymLink( const Bu::String &sPath ); 146 Bu::String readSymLink( const Bu::String &sPath );
146 Dir readDir( const Bu::String &sPath ); 147 Dir readDir( const Bu::String &sPath );
147 void setTimes( const Bu::String &sPath, int64_t iATime, 148 void setTimes( const Bu::String &sPath, int64_t iATime,
148 int64_t iMTime ); 149 int64_t iMTime );
149 void unlink( const Bu::String &sPath ); 150 void unlink( const Bu::String &sPath );
151 void setFileSize( const Bu::String &sPath, int32_t iSize );
152 void rename( const Bu::String &sFrom, const Bu::String &sTo );
150 153
151 static dev_t devToSys( uint32_t uDev ); 154 static dev_t devToSys( uint32_t uDev );
152 static uint32_t sysToDev( dev_t uDev ); 155 static uint32_t sysToDev( dev_t uDev );
@@ -177,6 +180,7 @@ namespace Bu
177 void writeInode( const RawStat &rs, MyriadStream &rOs ); 180 void writeInode( const RawStat &rs, MyriadStream &rOs );
178 Dir readDir( int32_t iNode ); 181 Dir readDir( int32_t iNode );
179 MyriadStream openByInode( int32_t iNode ); 182 MyriadStream openByInode( int32_t iNode );
183 void addToDir( int32_t iDir, int32_t iNode, const Bu::String &sName );
180 int32_t create( int32_t iParent, const Bu::String &sName, 184 int32_t create( int32_t iParent, const Bu::String &sName,
181 uint16_t uPerms, uint32_t uSpecial ); 185 uint16_t uPerms, uint32_t uSpecial );
182 int32_t allocInode( uint16_t uPerms, uint32_t uSpecial ); 186 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<int64_t, Bu::MyriadStream> FileHash;
24FileHash hOpenFiles; 24FileHash hOpenFiles;
25int64_t iNextFileId = 0; 25int64_t iNextFileId = 0;
26 26
27#define TRACE
28
27extern "C" { 29extern "C" {
28 static int myriadfs_getattr( const char *sPath, struct stat *stbuf ) 30 static int myriadfs_getattr( const char *sPath, struct stat *stbuf )
29 { 31 {
32#ifdef TRACE
33 printf("myriadfs_getattr(\"%s\", ... );\n", sPath );
34#endif
30 try 35 try
31 { 36 {
32 Bu::MyriadFs::Stat st; 37 Bu::MyriadFs::Stat st;
@@ -53,6 +58,9 @@ extern "C" {
53 static int myriadfs_readdir( const char *sPath, void *buf, 58 static int myriadfs_readdir( const char *sPath, void *buf,
54 fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi ) 59 fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi )
55 { 60 {
61#ifdef TRACE
62 printf("myriadfs_readdir(\"%s\", ... );\n", sPath );
63#endif
56 Bu::MyriadFs::Dir lDir = pFs->readDir( sPath ); 64 Bu::MyriadFs::Dir lDir = pFs->readDir( sPath );
57 filler( buf, ".", NULL, 0 ); 65 filler( buf, ".", NULL, 0 );
58 filler( buf, "..", NULL, 0 ); 66 filler( buf, "..", NULL, 0 );
@@ -66,19 +74,25 @@ extern "C" {
66 74
67 static int myriadfs_mkdir( const char *sPath, mode_t uMode ) 75 static int myriadfs_mkdir( const char *sPath, mode_t uMode )
68 { 76 {
77#ifdef TRACE
78 printf("myriadfs_mkdir(\"%s\", 0%o );\n", sPath, uMode );
79#endif
69 pFs->mkDir( sPath, uMode ); 80 pFs->mkDir( sPath, uMode );
70 return 0; 81 return 0;
71 } 82 }
72 83
73 static int myriadfs_open( const char *sPath, struct fuse_file_info *fi ) 84 static int myriadfs_open( const char *sPath, struct fuse_file_info *fi )
74 { 85 {
86#ifdef TRACE
87 printf("myriadfs_open(\"%s\", ... );\n", sPath );
88#endif
75 try 89 try
76 { 90 {
77 Bu::MyriadStream ms = pFs->open( sPath, 0 ); 91 Bu::MyriadStream ms = pFs->open( sPath, 0 );
78 fi->fh = iNextFileId; 92 fi->fh = iNextFileId;
79 hOpenFiles.insert( iNextFileId++, ms ); 93 hOpenFiles.insert( iNextFileId++, ms );
80 printf("File '%s' opened, %d files open now.\n", 94// printf("File '%s' opened, %d files open now.\n",
81 sPath, hOpenFiles.getSize() ); 95// sPath, hOpenFiles.getSize() );
82 return 0; 96 return 0;
83 } 97 }
84 catch(...) 98 catch(...)
@@ -90,6 +104,10 @@ extern "C" {
90 static int myriadfs_read( const char *sPath, char *buf, size_t iSize, 104 static int myriadfs_read( const char *sPath, char *buf, size_t iSize,
91 off_t iOffset, struct fuse_file_info *fi ) 105 off_t iOffset, struct fuse_file_info *fi )
92 { 106 {
107#ifdef TRACE
108 printf("myriadfs_read(\"%s\", ..., %d, %d, ... );\n", sPath, iSize,
109 iOffset );
110#endif
93 Bu::MyriadStream &ms = hOpenFiles.get( fi->fh ); 111 Bu::MyriadStream &ms = hOpenFiles.get( fi->fh );
94 ms.setPos( iOffset ); 112 ms.setPos( iOffset );
95 return ms.read( buf, iSize ); 113 return ms.read( buf, iSize );
@@ -98,6 +116,10 @@ extern "C" {
98 static int myriadfs_write( const char *sPath, const char *buf, size_t iSize, 116 static int myriadfs_write( const char *sPath, const char *buf, size_t iSize,
99 off_t iOffset, struct fuse_file_info *fi ) 117 off_t iOffset, struct fuse_file_info *fi )
100 { 118 {
119#ifdef TRACE
120 printf("myriadfs_write(\"%s\", ..., %d, %d, ... );\n", sPath, iSize,
121 iOffset );
122#endif
101 Bu::MyriadStream &ms = hOpenFiles.get( fi->fh ); 123 Bu::MyriadStream &ms = hOpenFiles.get( fi->fh );
102 ms.setPos( iOffset ); 124 ms.setPos( iOffset );
103 return ms.write( buf, iSize ); 125 return ms.write( buf, iSize );
@@ -106,13 +128,16 @@ extern "C" {
106 static int myriadfs_create( const char *sPath, mode_t uPerms, 128 static int myriadfs_create( const char *sPath, mode_t uPerms,
107 struct fuse_file_info *fi ) 129 struct fuse_file_info *fi )
108 { 130 {
131#ifdef TRACE
132 printf("myriadfs_create(\"%s\", 0%o, ... );\n", sPath, uPerms );
133#endif
109 try 134 try
110 { 135 {
111 Bu::MyriadStream ms = pFs->open( sPath, 0, uPerms ); 136 Bu::MyriadStream ms = pFs->open( sPath, 0, uPerms );
112 fi->fh = iNextFileId; 137 fi->fh = iNextFileId;
113 hOpenFiles.insert( iNextFileId++, ms ); 138 hOpenFiles.insert( iNextFileId++, ms );
114 printf("File '%s' created, %d files open now.\n", 139// printf("File '%s' created, %d files open now.\n",
115 sPath, hOpenFiles.getSize() ); 140// sPath, hOpenFiles.getSize() );
116 return 0; 141 return 0;
117 } 142 }
118 catch(...) 143 catch(...)
@@ -123,6 +148,9 @@ extern "C" {
123 148
124 static int myriadfs_mknod( const char *sPath, mode_t uPerms, dev_t Dev ) 149 static int myriadfs_mknod( const char *sPath, mode_t uPerms, dev_t Dev )
125 { 150 {
151#ifdef TRACE
152 printf("myriadfs_mknod(\"%s\", 0%o, %x );\n", sPath, uPerms, Dev );
153#endif
126 try 154 try
127 { 155 {
128 pFs->create( sPath, uPerms, Bu::MyriadFs::sysToDev( Dev ) ); 156 pFs->create( sPath, uPerms, Bu::MyriadFs::sysToDev( Dev ) );
@@ -136,9 +164,12 @@ extern "C" {
136 164
137 static int myriadfs_release( const char *sPath, struct fuse_file_info *fi ) 165 static int myriadfs_release( const char *sPath, struct fuse_file_info *fi )
138 { 166 {
167#ifdef TRACE
168 printf("myriadfs_release(\"%s\", ... );\n", sPath );
169#endif
139 hOpenFiles.erase( fi->fh ); 170 hOpenFiles.erase( fi->fh );
140 printf("File '%s' released, %d files open now.\n", 171// printf("File '%s' released, %d files open now.\n",
141 sPath, hOpenFiles.getSize() ); 172// sPath, hOpenFiles.getSize() );
142 173
143 return 0; 174 return 0;
144 } 175 }
@@ -146,6 +177,9 @@ extern "C" {
146 static int myriadfs_utimens( const char *sPath, 177 static int myriadfs_utimens( const char *sPath,
147 const struct timespec tv[2] ) 178 const struct timespec tv[2] )
148 { 179 {
180#ifdef TRACE
181 printf("myriadfs_utimens(\"%s\", ... );\n", sPath );
182#endif
149 try 183 try
150 { 184 {
151 pFs->setTimes( sPath, tv[0].tv_sec, tv[1].tv_sec ); 185 pFs->setTimes( sPath, tv[0].tv_sec, tv[1].tv_sec );
@@ -159,6 +193,9 @@ extern "C" {
159 193
160 static int myriadfs_unlink( const char *sPath ) 194 static int myriadfs_unlink( const char *sPath )
161 { 195 {
196#ifdef TRACE
197 printf("myriadfs_unlink(\"%s\");\n", sPath );
198#endif
162 try 199 try
163 { 200 {
164 pFs->unlink( sPath ); 201 pFs->unlink( sPath );
@@ -173,10 +210,12 @@ extern "C" {
173 210
174 static int myriadfs_symlink( const char *sTarget, const char *sPath ) 211 static int myriadfs_symlink( const char *sTarget, const char *sPath )
175 { 212 {
213#ifdef TRACE
214 printf("myriadfs_symlink(\"%s\", \"%s\");\n", sTarget, sPath );
215#endif
176 try 216 try
177 { 217 {
178 printf("Path = '%s', Target = '%s'\n", sPath, sTarget ); 218 pFs->mkSymLink( sTarget, sPath );
179 pFs->mkSymLink( sPath, sTarget );
180 } 219 }
181 catch( Bu::MyriadFsException &e ) 220 catch( Bu::MyriadFsException &e )
182 { 221 {
@@ -188,6 +227,9 @@ extern "C" {
188 227
189 static int myriadfs_readlink( const char *sPath, char *sOut, size_t s ) 228 static int myriadfs_readlink( const char *sPath, char *sOut, size_t s )
190 { 229 {
230#ifdef TRACE
231 printf("myriadfs_readlink(\"%s\", ... );\n", sPath );
232#endif
191 try 233 try
192 { 234 {
193 Bu::String sTrg = pFs->readSymLink( sPath ); 235 Bu::String sTrg = pFs->readSymLink( sPath );
@@ -203,6 +245,60 @@ extern "C" {
203 return 0; 245 return 0;
204 } 246 }
205 247
248 static int myriadfs_truncate( const char *sPath, off_t iSize )
249 {
250#ifdef TRACE
251 printf("myriadfs_truncate(\"%s\", %d );\n", sPath, iSize );
252#endif
253
254 try
255 {
256 pFs->setFileSize( sPath, iSize );
257 }
258 catch( Bu::MyriadFsException &e )
259 {
260 printf("MyriadFsException: %s\n", e.what() );
261 return -ENOENT;
262 }
263 return 0;
264 }
265
266 static int myriadfs_link( const char *sTarget, const char *sPath )
267 {
268#ifdef TRACE
269 printf("myriadfs_link(\"%s\", \"%s\");\n", sTarget, sPath );
270#endif
271
272 try
273 {
274 pFs->mkHardLink( sTarget, sPath );
275 }
276 catch( Bu::MyriadFsException &e )
277 {
278 printf("MyriadFsException: %s\n", e.what() );
279 return -EACCES;
280 }
281 return 0;
282 }
283
284 static int myriadfs_rename( const char *sFrom, const char *sTo )
285 {
286#ifdef TRACE
287 printf("myriadfs_rename(\"%s\", \"%s\");\n", sFrom, sTo );
288#endif
289
290 try
291 {
292 pFs->rename( sFrom, sTo );
293 }
294 catch( Bu::MyriadFsException &e )
295 {
296 printf("MyriadFsException: %s\n", e.what() );
297 return -EACCES;
298 }
299 return 0;
300 }
301
206 static struct fuse_operations myriadfs_oper; 302 static struct fuse_operations myriadfs_oper;
207 303
208 int main( int argc, char *argv[] ) 304 int main( int argc, char *argv[] )
@@ -224,6 +320,9 @@ extern "C" {
224 myriadfs_oper.rmdir = myriadfs_unlink; 320 myriadfs_oper.rmdir = myriadfs_unlink;
225 myriadfs_oper.symlink = myriadfs_symlink; 321 myriadfs_oper.symlink = myriadfs_symlink;
226 myriadfs_oper.readlink = myriadfs_readlink; 322 myriadfs_oper.readlink = myriadfs_readlink;
323 myriadfs_oper.truncate = myriadfs_truncate;
324 myriadfs_oper.link = myriadfs_link;
325 myriadfs_oper.rename = myriadfs_rename;
227 printf("Starting fuse_main.\n"); 326 printf("Starting fuse_main.\n");
228 int iRet = fuse_main( argc, argv, &myriadfs_oper, NULL ); 327 int iRet = fuse_main( argc, argv, &myriadfs_oper, NULL );
229 printf("Done with fuse_main.\n"); 328 printf("Done with fuse_main.\n");