From e2b9484ea77119e7a9b720d0f65eedbde23bc5c6 Mon Sep 17 00:00:00 2001 From: Ralph Ronnquist Date: Sat, 12 Aug 2023 08:42:36 +1000 Subject: [PATCH] Added -push action, to push overlay data into source fragments. --- fusefile.8 | 14 ++++++++--- fusefile.c | 73 +++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 70 insertions(+), 17 deletions(-) diff --git a/fusefile.8 b/fusefile.8 index 6af36f4..194f4aa 100644 --- a/fusefile.8 +++ b/fusefile.8 @@ -8,6 +8,8 @@ fusefile, fusedisk \- FUSE file mount for combining file fragments .br .B fusefile \fB-dump\fR \fR[\fIfuse-opts\fR] \fBmountpoint\fR \fR[\fIoverlay\fR] \fIfilename/from-to\fR ... .br +.B fusefile \fB-push\fR \fR[\fIfuse-opts\fR] \fBmountpoint\fR \fR[\fIoverlay\fR] \fIfilename/from-to\fR ... +.br .B fusedisk \fR[\fIfuse-opts\fR] \fBmountpoint\fR \fR[\fIoverlay\fR] \fIfilename/from-to\fR ... .SH DESCRIPTION @@ -33,12 +35,18 @@ from the fragments. The option \fB-dump\fR as first argument together with a fusefile setup will print the setup to standard output rather than establishing -a fusefile mount. This is of most use with a prior overlay setup, -where then the printout includes the portions of updates that have -been captured in the overlay. The printout is the series of fusefile +a fusefile mount. This is of most use with a prior overlay setup where +then the printout includes the portions of updates that have been +captured in the overlay. The printout is the series of fusefile fragment argments to give in order to intersperse the captured overlay portions according to the overlay table. +The option \fB-push\fR as first argument together with a fusefile +setup will push the overlay into the sources (except for +write-protected fragments). This is only of use with a prior overlay +setup where then the updates that have been captured in the overlay +get pushed into the fragments. + \fBfusedisk\fR is a helper script to set up a \fBfusefile\fR as a block device (via \fIfuseblk\fR) by using the device mapper (\fBdmsetup\fR) to manage an empty block device mapping where content diff --git a/fusefile.c b/fusefile.c index 9e5cb45..69750fa 100644 --- a/fusefile.c +++ b/fusefile.c @@ -717,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 @@ -804,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; @@ -814,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 ( ( 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 && @@ -975,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 ) ) { -- 2.39.2