From 9b4d0451016c061d9d2a1046a4a11f0b52fe8cf3 Mon Sep 17 00:00:00 2001 From: Ralph Ronnquist Date: Wed, 16 Aug 2023 12:06:27 +1000 Subject: [PATCH] fixed overlay stacking bugs --- fusefile.c | 123 +++++++++++++++++++++++++++++------------------------ 1 file changed, 68 insertions(+), 55 deletions(-) diff --git a/fusefile.c b/fusefile.c index ab97ff7..c8964f4 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 @@ -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++ ) { @@ -967,9 +975,10 @@ static int dump_fragments(int push) { ENDSOURCE( sources.array[ src ] ) <= x; src++ ) { // Dump sources.array[src] in full if ( !push ) { - fprintf( stdout, "%s/%ld:%ld\n", + fprintf( stdout, "A %s/%ld:%ld\n", sources.array[ src ].filename, - pos - sources.array[ src ].start, + pos - sources.array[ src ].start + + sources.array[ src ].from, sources.array[ src ].to ); } pos = ENDSOURCE( sources.array[ src ] ); @@ -977,10 +986,13 @@ static int dump_fragments(int push) { if ( ( src < sources.count ) && ( sources.array[ src ].start < x ) ) { // Dump sources.array[src] up to x; if ( !push ) { - fprintf( stdout, "%s/%ld:%ld\n", + fprintf( stdout, "B %s/%ld:%ld\n", sources.array[ src ].filename, - pos - sources.array[ src ].start, - x - sources.array[ src ].start ); + sources.array[ src ].from, + //pos - sources.array[ src ].start, + x - sources.array[ src ].start + + sources.array[ src ].from + ); } pos = ENDSOURCE( sources.array[ src ] ); } @@ -1041,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* ) ) -- 2.39.2