various corrections
authorRalph Ronnquist <ralph.ronnquist@gmail.com>
Thu, 26 May 2022 09:50:52 +0000 (19:50 +1000)
committerRalph Ronnquist <ralph.ronnquist@gmail.com>
Thu, 26 May 2022 09:50:52 +0000 (19:50 +1000)
fusefile.c

index 41c6ed6042f6ca9462b02f19b45f6136a8eb0ae3..55ba86aae686986003fefb3b6e083abfb44d4b75 100644 (file)
@@ -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 <source.array>
     // 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 <index> record at <off>
            // 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 <index>
            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 <off>. The data is appended to the pad file,
  * and a descriptor is inserted; the fragment containing <off> 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 ) ) {