From 78348bed8433e7b7429ff4a0233b43ba614ac28d Mon Sep 17 00:00:00 2001 From: Ralph Ronnquist Date: Thu, 26 May 2022 19:50:52 +1000 Subject: [PATCH] various corrections --- fusefile.c | 147 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 126 insertions(+), 21 deletions(-) diff --git a/fusefile.c b/fusefile.c index 41c6ed6..55ba86a 100644 --- a/fusefile.c +++ b/fusefile.c @@ -49,6 +49,12 @@ static struct { ssize_t size; } sources; +static struct { + time_t atime; + time_t mtime; + time_t ctime; +} times; + #define SOURCEARRAYP(i) ((void*)&sources.array[ i ]) /** @@ -157,10 +163,9 @@ static int fusefile_getattr(const char *path,struct stat *stbuf) { } stbuf->st_nlink = 1; stbuf->st_size = sources.size; - time_t now = time( 0 ); - stbuf->st_atime = now; - stbuf->st_mtime = now; - stbuf->st_ctime = now; + stbuf->st_atime = times.atime; + stbuf->st_mtime = times.mtime; + stbuf->st_ctime = times.ctime; stbuf->st_uid = getuid(); stbuf->st_gid = getgid(); return 0; @@ -175,6 +180,7 @@ static int fusefile_open(const char *path,struct fuse_file_info *fi) { return -ENOENT; } // set O-CLOEXEC for this opening? + times.atime = time( 0 ); return 0; } @@ -184,14 +190,12 @@ static int find_source(off_t offset) { if ( offset > sources.size ) { return -1; } - while ( lo < hi ) { + while ( lo + 1 < hi ) { int m = ( lo + hi ) / 2; - if ( sources.array[m].start > offset ) { + if ( offset < sources.array[ m ].start ) { hi = m; - } else if ( m+1 < hi && sources.array[m+1].start < offset ) { - lo = m+1; } else { - return m; + lo = m; } } return lo; @@ -202,6 +206,7 @@ static int find_source(off_t offset) { */ static int insert_source(struct Source *source,size_t off) { int index = find_source( off ); + int i; // Ensure at least 5 "free" Sources in // and allocate space for 20 new otherwise. if ( sources.count + 5 > sources.limit ) { @@ -214,17 +219,28 @@ static int insert_source(struct Source *source,size_t off) { sources.array = new; sources.limit = size; } +#if DEBUG + fprintf( stderr, "index=%d\n", index ); +#endif if ( index < sources.count ) { ssize_t b = ( sources.count - index ) * sizeof(struct Source); +#if DEBUG + fprintf( stderr, "b=%ld\n", b ); +#endif if ( sources.array[ index ].start < off ) { // Split the record at // and adjust index - b *= 2; memcpy( SOURCEARRAYP( index+2 ), SOURCEARRAYP( index ), b ); sources.count += 2; b = off - sources.array[ index ].start; sources.array[ index + 2 ].from += b; // adjust tail fragment sources.array[ index++ ].to = b; // adjust head fragment +#if DEBUG + print_source( &sources.array[ index-1 ] ); + print_source( &sources.array[ index ] ); + print_source( &sources.array[ index+1 ] ); + fprintf( stderr, "---\n"); +#endif } else { // Insert the new source at memcpy( SOURCEARRAYP( index+1 ), SOURCEARRAYP( index ), b ); @@ -238,11 +254,17 @@ static int insert_source(struct Source *source,size_t off) { sources.array[ index ].fd = source->fd; sources.array[ index ].from = source->from; sources.array[ index ].to = source->to; - for ( ; index < sources.count; index++ ) { - sources.array[ index ].start = off; - off += sources.array[ index ].to - sources.array[ index ].from; + for ( i = index; i < sources.count; i++ ) { + sources.array[ i ].start = off; + off += sources.array[ i ].to - sources.array[ i ].from; +#if DEBUG + print_source( &sources.array[ i ] ); +#endif } sources.size = off; +#if DEBUG + fprintf( stderr, "count=%d size=%ld\n", sources.count, sources.size ); +#endif return index; } @@ -301,6 +323,7 @@ static int fusefile_read(const char *path, char *buf, size_t size, off += r; size -= r; } + times.atime = time( 0 ); return rr; } @@ -314,10 +337,72 @@ static int write_block(int fd,const char *buf,size_t size) { if ( n <= 0 ) { return n; } + buf += n; + size -= n; } return orig; } +static int fusefile_write_buf(const char *path, struct fuse_bufvec *buf, + off_t off, struct fuse_file_info *fi) { +#if DEBUG + fprintf( stderr, "fusefile_write_buf( %s )\n", path ); +#endif + if ( strcmp( path, "/" ) != 0 ) { + return -ENOENT; + } + + // Ensure a pad was nominated + if ( pad.filename == 0 ) { + return 1; + } + + // Determine total size + size_t size = 0; + int i; +#if DEBUG + fprintf( stderr, "count = %ld\n", buf->count ); +#endif + for ( i = 0; i < buf->count; i++ ) { + struct fuse_buf *p = &buf->buf[ i ]; + size += p->size; + } + static char meta[ 100 ]; + sprintf( meta, "%ld\n%ld\n", off, size ); +#if DEBUG + fprintf( stderr, "meta( %ld %ld )\n", off, size ); +#endif + if ( write_block( pad.fd, meta, strlen( meta ) ) <= 0 ) { + perror( pad.filename ); + return -EIO; + } + struct Source source = { + .filename = pad.filename, + .fd = pad.fd, + .from = lseek( pad.fd, 0, SEEK_END ), + .to = 0, + .start = 0 + }; + for ( i = 0; i < buf->count; i++ ) { + struct fuse_buf *p = &buf->buf[i]; + if ( p->flags & FUSE_BUF_IS_FD ) { +#if DEBUG + fprintf( stderr, "Content held in a file ... HELP!!\n" ); +#endif + return -EIO; + } else { + ssize_t n = write_block( pad.fd, (char*) p->mem, p->size ); + if ( n != p->size ) { + return -EIO; + } + } + } + source.to = source.from + size; + insert_source( &source, off ); + times.mtime = time( 0 ); + return size; +} + /** * Insert a fragment at . The data is appended to the pad file, * and a descriptor is inserted; the fragment containing is @@ -328,14 +413,12 @@ static int fusefile_write(const char *path, const char *buf, size_t size, off_t off, struct fuse_file_info *fi) { #if DEBUG - fprintf( stderr, "fusefile_write( %s )\n", path ); + fprintf( stderr, "fusefile_write( %s %ld )\n", path, size ); #endif if ( strcmp( path, "/" ) != 0 ) { return -ENOENT; } -#if DEBUG - fprintf( stderr, "write %ld %ld\n", off, size ); -#endif + // Ensure a pad was nominated if ( pad.filename == 0 ) { return 1; @@ -359,6 +442,7 @@ static int fusefile_write(const char *path, const char *buf, size_t size, } source.to = source.from + size; insert_source( &source, off ); + times.mtime = time( 0 ); return size; } @@ -402,21 +486,33 @@ static int fusefile_fsync(const char *path, int x, struct fuse_file_info *fi) { return 0; } +/** + * + */ +static int fusefile_truncate(const char *path, off_t len) { +#if DEBUG + fprintf( stderr, "fusefile_truncate( %s, %ld )\n", path, len ); +#endif + if ( strcmp( path, "/" ) != 0 ) { + return -ENOENT; + } + return -EIO; +} + static struct fuse_operations fusefile_oper = { .getattr = fusefile_getattr, .open = fusefile_open, .read = fusefile_read, .write = fusefile_write, + .write_buf = fusefile_write_buf, .destroy = fusefile_destroy, .flush = fusefile_flush, .release = fusefile_release, .fsync = fusefile_fsync, - //void *(*init) (struct fuse_conn_info *conn); - //int (*write_buf) (const char *, struct fuse_bufvec *buf, off_t off, - // struct fuse_file_info *); + .truncate = fusefile_truncate, //.truncate = fusefile_truncate, - //.flush = fusefile_flush, //.release = fusefile_release, + //void *(*init) (struct fuse_conn_info *conn); }; static void usage() { @@ -487,12 +583,21 @@ int main(int argc, char *argv[]) perror( mnt ); return 1; } + time_t now = time( 0 ); + times.atime = now; + times.mtime = now; + times.ctime = now; temporary = 1; close( fd ); } else if ( ! S_ISREG( stbuf.st_mode ) ) { fprintf( stderr, "mountpoint is not a regular file\n" ); return 1; + } else { + times.atime = stbuf.st_atime; + times.mtime = stbuf.st_mtime; + times.ctime = stbuf.st_ctime; } + fuseargc = setup_argv( fuseargc, &argv ); struct fuse_args args = FUSE_ARGS_INIT( fuseargc, argv ); if ( fuse_parse_cmdline( &args, &mnt, &mt, &fg ) ) { -- 2.39.2