X-Git-Url: https://git.rrq.au/?a=blobdiff_plain;f=fusefile.c;h=69750fad1507d9db3626b9927bac2bb642235ab2;hb=c790818e8496f101ae4a628db189abedaccad132;hp=5f7850ba106e2dd9d60278d9bfc2ceb5208f3070;hpb=0df8fcce46695d24edea6218bb460cce0818b0d0;p=rrq%2Ffusefile.git diff --git a/fusefile.c b/fusefile.c index 5f7850b..69750fa 100644 --- a/fusefile.c +++ b/fusefile.c @@ -295,8 +295,14 @@ static int RANGE(int s,int n ) { static int setup_source(struct Source *p,char *frag) { struct stat filestat; // Open the fragment file rw if possible, else ro - range = strrchr( frag, '/' ); // last '/' - p->filename = range? strndup( frag, range - frag ) : frag; + // First try the fragment in full, thereafter with range appendix + if ( stat( frag, &filestat ) == 0 ) { + p->filename = strdup( frag ); + range = 0; + } else { + range = strrchr( frag, '/' ); // last '/' + p->filename = range? strndup( frag, range - frag ) : frag; + } p->fd = open( p->filename, O_RDWR ); int rdonly = 0; if ( p->fd < 0 ) { @@ -307,7 +313,7 @@ static int setup_source(struct Source *p,char *frag) { perror( p->filename ); return 1; // Error return } - if ( stat( p->filename, &filestat ) ) { + if ( ( range == 0 ) && stat( p->filename, &filestat ) ) { perror( p->filename ); return 1; } @@ -327,21 +333,21 @@ static int setup_source(struct Source *p,char *frag) { p->to = filestat.st_size; // Process any range variation if ( range && *(++range) ) { - int a,b; + long int a,b; if ( 0 ) { - } else if ( RANGE( sscanf( range, "%d:%d%n", &a, &b, &c ), 2 )) { + } else if ( RANGE( sscanf( range, "%ld:%ld%n", &a, &b, &c ), 2 )) { p->from = ( a < 0 )? ( p->to + a ) : a; p->to = ( b < 0 )? ( p->to + b ) : b; - } else if ( RANGE( sscanf( range, "%d+%d%n", &a, &b, &c ), 2 )) { + } else if ( RANGE( sscanf( range, "%ld+%ld%n", &a, &b, &c ), 2 )) { p->from = ( a < 0 )? ( p->to + a ) : a; p->to = ( ( b < 0 )? p->to : p->from ) + b; - } else if ( RANGE( sscanf( range, "%d+%n", &a, &c ), 1 )) { + } else if ( RANGE( sscanf( range, "%ld+%n", &a, &c ), 1 )) { p->from = ( a < 0 )? ( p->to + a ) : a; - } else if ( RANGE( sscanf( range, ":%d%n", &b, &c ), 1 )) { + } else if ( RANGE( sscanf( range, ":%ld%n", &b, &c ), 1 )) { p->to = ( b < 0 )? ( p->to + b ) : b; - } else if ( RANGE( sscanf( range, "%d:%n", &a, &c ), 1 )) { + } else if ( RANGE( sscanf( range, "%ld:%n", &a, &c ), 1 )) { p->from = ( a < 0 )? ( p->to + a ) : a; - } else if ( RANGE( sscanf( range, "%d%n", &a, &c ), 1 )) { + } else if ( RANGE( sscanf( range, "%ld%n", &a, &c ), 1 )) { if ( a >= 0 ) { p->from = a; } else { @@ -711,6 +717,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 @@ -798,7 +838,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; @@ -808,25 +848,33 @@ 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 ].to ); + } pos = ENDSOURCE( sources.array[ src ] ); } - if ( sources.array[ src ].start < x ) { + 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, + pos - sources.array[ src ].start, + x - sources.array[ src ].start ); + } 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 && @@ -969,7 +1017,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 ) ) {