X-Git-Url: https://git.rrq.au/?a=blobdiff_plain;f=fusefile.c;h=a1bf2bd926792844ecee3c989dd131da641d69e2;hb=refs%2Fheads%2Fdebian;hp=e05b90ebdf4c8a3de0c45d56a562dc71f4031fc4;hpb=79ad3ccaefe9383207f11e32cb324b88f0086137;p=rrq%2Ffusefile.git diff --git a/fusefile.c b/fusefile.c index e05b90e..a1bf2bd 100644 --- a/fusefile.c +++ b/fusefile.c @@ -290,8 +290,9 @@ static void dup_source_item(int index) { fprintf( stderr, "** OOM when expanding frament table\n" ); usage(); } - memcpy( &sources.array[ index+1 ], &sources.array[ index ], - sizeof( struct Source ) ); + // copy elements from [index] to [count-1] one element down + size_t size = ( sources.count - index - 1 ) * sizeof( struct Source ); + memmove( &sources.array[ index+1 ], &sources.array[ index ], size ); } #if DEBUG @@ -328,7 +329,7 @@ static int setup_source(struct Source *p,char *frag) { perror( p->filename ); return 1; // Error return } - if ( ( range == 0 ) && stat( p->filename, &filestat ) ) { + if ( ( range != 0 ) && stat( p->filename, &filestat ) ) { perror( p->filename ); return 1; } @@ -462,28 +463,14 @@ static int find_source(off_t offset) { if ( offset >= sources.size ) { return -1; } -#if DEBUG - fprintf( stderr, "find_source( %ld )\n", offset ); -#endif while ( lo + 1 < hi ) { int m = ( lo + hi ) / 2; if ( offset < sources.array[ m ].start ) { -#if DEBUG - fprintf( stderr, " offset < [%d].start: %ld\n", - m, sources.array[ m ].start ); -#endif hi = m; } else { -#if DEBUG - fprintf( stderr, " offset >= [%d].start: %ld\n", - m, sources.array[ m ].start ); -#endif lo = m; } } -#if DEBUG - fprintf( stderr, "found %d\n", lo ); -#endif return lo; } @@ -522,30 +509,25 @@ static int overlay_merge(char *buf,off_t beg,off_t end) { static int fusefile_read(const char *path, char *buf, size_t size, off_t off, struct fuse_file_info *fi) { -#if DEBUG - fprintf( stderr, "fusefile_read( %s )\n", path ); -#endif if( strcmp( path, "/" ) != 0 ) { return -ENOENT; } -#if DEBUG - fprintf( stderr, "read %ld %ld\n", off, size ); -#endif size_t rr = 0; // total reading - while ( size > 0 ) { #if DEBUG - fprintf( stderr, " find_source %ld %ld\n", off, size ); + fprintf( stderr, "fusefile_read %ld + %ld\n", off, size ); #endif + while ( size > 0 ) { int i = find_source( off ); if ( i < 0 ) { return ( off == sources.size )? rr : -ENOENT; } +#if DEBUG + fprintf( stderr, " item: %d ", i ); + print_source(& sources.array[i] ); +#endif if ( sources.array[i].fd < 0 ) { return -ENOENT; } -#if DEBUG - print_source( &sources.array[i] ); -#endif times.atime = time( 0 ); size_t b = off - sources.array[i].start + sources.array[i].from; size_t n = sources.array[i].to - b; @@ -556,20 +538,13 @@ static int fusefile_read(const char *path, char *buf, size_t size, fsync( sources.array[i].fd ); sources.array[i].dirty = 0; } -#if DEBUG - fprintf( stderr, " seek fd=%d to %ld\n", sources.array[i].fd, b ); -#endif if ( lseek( sources.array[i].fd, b, SEEK_SET ) < 0 ) { perror( sources.array[i].filename ); return -ENOENT; } -#if DEBUG - fprintf( stderr, " now read %ld from fd=%d\n", - n, sources.array[i].fd ); -#endif ssize_t r = read( sources.array[i].fd, buf + rr, n ); #if DEBUG - fprintf( stderr, " got %ld bytes\n", r ); + fprintf( stderr, " got: %ld bytes of %ld at %ld\n", r, n, rr ); #endif if ( r < 0 ) { perror( sources.array[i].filename ); @@ -657,29 +632,54 @@ static off_t overlay_inject_from_region(off_t beg,off_t end) { } struct Region frags[3] = { { sources.array[ index ].start, beg }, - { beg, ENDSOURCE( sources.array[ index ] ) }, - { ENDSOURCE( sources.array[ index ] ), end } }; + { beg, end }, + { end, ENDSOURCE( sources.array[ index ] ) } }; +#if DEBUG + int i; + for ( i = 0; i < 3; i++ ) { + fprintf( stderr, "frags[%d] = (%ld, %ld)\n", + i, frags[i].beg, frags[i].end ); + } +#endif ssize_t size = frags[0].end - frags[0].beg; if ( size ) { - // "Duplicate" the indexed source data, copying the filename + // Handle any portion before injection point. dup_source_item( index ); - sources.array[ index ].to = sources.array[ index ].from + size; + off_t point = sources.array[ index ].from + size; + sources.array[ index ].to = point; +#if DEBUG + fprintf( stderr, "item %d ", index ); + print_source( &sources.array[ index ] ); +#endif + // Adjust item after injection point index++; sources.array[ index ].start = beg; - sources.array[ index ].from = sources.array[ index-1 ].to; + sources.array[ index ].from = point; +#if DEBUG + fprintf( stderr, "item %d adjust ", index ); + print_source( &sources.array[ index ] ); +#endif } size = frags[2].end - frags[2].beg; if ( size ) { + // Handle any remaining portion following injection fragment dup_source_item( index ); sources.array[ index+1 ].start = frags[2].beg; - sources.array[ index+1 ].from = sources.array[ index+1 ].to -size; + sources.array[ index+1 ].from += frags[1].end - frags[1].beg; +#if DEBUG + fprintf( stderr, "item %d ", index+1 ); + print_source( &sources.array[ index+1 ] ); +#endif } - // Replace the [index] fragment + // Set up the injection fragment sources.array[ index ].filename = overlay.source.filename; - sources.array[ index ].start = beg; sources.array[ index ].from = beg; sources.array[ index ].to = end; - sources.array[ index ].fd = overlay.source.fd; //? + sources.array[ index ].fd = overlay.source.fd; +#if DEBUG + fprintf( stderr, "item %d ", index ); + print_source( &sources.array[ index ] ); +#endif return end; } @@ -699,9 +699,14 @@ static void overlay_inject() { } size_t count = 0; size_t size = sizeof( overlay.count ); - if ( read( overlay.source.fd, &count, size ) != size ) { - fprintf( stderr, "** error injecting %s\n", overlay.source.filename ); - usage(); + size_t n; + if ( ( n = read( overlay.source.fd, &count, size ) ) != size ) { + if ( n != 0 ) { + fprintf( stderr, "** error injecting %s\n", + overlay.source.filename ); + usage(); + } + fprintf( stderr, "** ignoring empty %s\n", overlay.source.filename ); } if ( count == 0 ) { close( overlay.source.fd ); @@ -717,12 +722,16 @@ static void overlay_inject() { for ( i = 0; i < count; i++ ) { off_t beg = overlay.table[i].beg; while ( beg < overlay.table[i].end ) { +#if DEBUG + fprintf( stderr, "inject [%ld,%ld] ", beg, overlay.table[i].end ); + print_source( &overlay.source ); +#endif + beg = overlay_inject_from_region( beg, overlay.table[i].end ); } } free( overlay.table ); overlay.table = 0; - close( overlay.source.fd ); } /** @@ -731,7 +740,7 @@ static void overlay_inject() { static void overlay_post_setup() { char *end; while ( ( end = strchr( overlay.source.filename, ':' ) ) ) { - *end = 0; // + *end = 0; // overlay_inject(); overlay.source.filename = end + 1; } @@ -796,7 +805,6 @@ static int fusefile_write_buf(const char *path, struct fuse_bufvec *buf, if ( strcmp( path, "/" ) != 0 ) { return -ENOENT; } - size_t size = 0; int i; for ( i = 0; i < buf->count; i++ ) { @@ -837,6 +845,40 @@ static int fusefile_write(const char *path, const char *buf, size_t size, return size; } +#define PUSHBUF 104857600 +/** + * Write data from overlay to source. + */ +static void push_oly(off_t beg, off_t end) { + static char * buffer = 0; + // Pretend that there isn't an overlay + char *filename = overlay.source.filename; + if ( buffer == 0 ) { + buffer = malloc( PUSHBUF ); + if ( buffer == 0 ) { + fprintf( stderr, "** OOM!!\n" ); + exit( 1 ); + } + } + overlay.source.filename = 0; + while ( beg < end ) { + off_t size = end - beg; + if ( size > PUSHBUF ) { + size = PUSHBUF; + } + if ( lseek( overlay.source.fd, beg, SEEK_SET ) < 0 ) { + fprintf( stderr, "** Cannot seek overlay at %ld\n", beg ); + break; + } + size = read( overlay.source.fd, buffer, size ); + if ( write_block( beg, buffer, size ) < 0 ) { + fprintf( stderr, "** Cannot push %ld bytes at %ld\n", size, beg ); + } + beg += size; + } + overlay.source.filename = filename; +} + static void fusefile_destroy(void *data) { char *mnt = (char*) data; // As passed to fuse_main #if DEBUG @@ -922,7 +964,7 @@ void *fusefile_init(struct fuse_conn_info *fci) { /** * Dump the current fragmentation to stdout. */ -static int dump_fragments() { +static int dump_fragments(int push) { int oly = 0; int src = 0; size_t pos = 0; @@ -932,25 +974,37 @@ static int dump_fragments() { for ( ; src < sources.count && ENDSOURCE( sources.array[ src ] ) <= x; src++ ) { // Dump sources.array[src] in full - fprintf( stdout, "%s/%ld:%ld\n", - sources.array[ src ].filename, - pos - sources.array[ src ].start, - sources.array[ src ].to ); + if ( !push ) { + fprintf( stdout, "%s/%ld:%ld\n", + sources.array[ src ].filename, + pos - sources.array[ src ].start + + sources.array[ src ].from, + sources.array[ src ].to ); + } pos = ENDSOURCE( sources.array[ src ] ); } if ( ( src < sources.count ) && ( sources.array[ src ].start < x ) ) { // Dump sources.array[src] up to x; - fprintf( stdout, "%s/%ld:%ld\n", - sources.array[ src ].filename, - pos - sources.array[ src ].start, - x - sources.array[ src ].start ); + if ( !push ) { + fprintf( stdout, "%s/%ld:%ld\n", + sources.array[ src ].filename, + sources.array[ src ].from + + pos - sources.array[ src ].start, + x - sources.array[ src ].start + + sources.array[ src ].from + ); + } pos = ENDSOURCE( sources.array[ src ] ); } if ( oly < overlay.count ) { - fprintf( stdout, "%s/%ld:%ld\n", - overlay.source.filename, - overlay.table[ oly ].beg, - overlay.table[ oly ].end ); + if ( !push ) { + fprintf( stdout, "%s/%ld:%ld\n", + overlay.source.filename, + overlay.table[ oly ].beg, + overlay.table[ oly ].end ); + } else { + push_oly( overlay.table[ oly ].beg, overlay.table[ oly ].end ); + } pos = overlay.table[ oly++ ].end; } for ( ; src < sources.count && @@ -999,6 +1053,7 @@ static int setup_argv(int argc,char ***argv) { // note: (*argv)[ argc ] is the mount point argument char *OURS[] = { "-odefault_permissions", + //"-s", // Forced single-threading (*argv)[ argc ] }; #define OURSN ( sizeof( OURS ) / sizeof( char* ) ) @@ -1044,10 +1099,10 @@ int main(int argc, char *argv[]) } fuseargc = i; mnt = argv[ i++ ]; // First non-option argument is the mount pount - if ( strcmp( argv[i], "-overlay:" ) == 0 ) { + #define OVERLAYTAG "-overlay:" + if ( strncmp( argv[i], OVERLAYTAG, strlen( OVERLAYTAG ) ) == 0 ) { // consume "-overlay:filename[,filename]*" - // Verify file access; to overlay must be writable. - overlay_setup( argv[i++] + strlen( "-overlay:" ) ); + overlay_setup( argv[i++] + strlen( OVERLAYTAG ) ); if ( i >= argc ) { usage(); } @@ -1092,7 +1147,10 @@ int main(int argc, char *argv[]) } fuseargc = setup_argv( fuseargc, &argv ); if ( strcmp( "-dump", argv[ 1 ] ) == 0 ) { - return dump_fragments(); + return dump_fragments( 0 ); + } + if ( strcmp( "-push", argv[ 1 ] ) == 0 ) { + return dump_fragments( 1 ); } struct fuse_args args = FUSE_ARGS_INIT( fuseargc, argv ); if ( fuse_parse_cmdline( &args, &mnt, &mt, &fg ) ) {