database entry: lock // pthread lock accesses // how many active accesses we have compressed // boolean addition to fi->fh entry: database - pointer to above, alloc'ed by search_and_add compress_data - stores data of compression/decompression (bzopen var's) compress_type - NONE/FILEWRITE/FILEREAD // when NONE it means compress_data isn't set yet, and we dont know if the file is running FILEWRITE or FILEREAD // This handles "quick" compressing/decompressing, direct without going through the background stuff. // find.c should never end up modifying a file with accesses > 0 quick_compress.c: search_and_add(char *path) { search database, if not found alloc new and list_add lock(database->lock); } // this returns TRUE if all ok, and FALSE if we should use pwrite quick_compress(fi->fh,data,offset) { if offset != fi->fh->database->offset || fi->fh->type == FILEREAD { decompress(file); return FALSE; } if (!fi->fh->compressor_data) { compressor_bzopen(cache in compressor_data); fi->fh->type = FILEWRITE; } compressor_bzwrite(fd_bz2, buf, rd); return TRUE; } quick_decompress(fi->fh,data,offset) { if offset != fi->fh->database->offset || fi->fh->type == FILEWRITE { decompress(file); return FALSE; } if (!fi->fh->compressor_data) { decompressor_bzopen(cache in compressor_data); fi->fh->type = FILEREAD; } decompressor_bzread(fd_bz2, buf, rd); return TRUE; } quick_close(fi->fh,data,offset) { if (fi->fh->compressor_data) { BZ2_bzclose(fd_bz2); fi->fh->compressor_data = NULL; } } fuse_open: { fi->fh->database = search_and_add(path); fi->fh->database->accesses++; fi->fh->database->compressed = boolean, true if file is compressed, false otherwise. unlock(fi->fh->database->lock); } # if two files use this function, it'll lock the database, realize offset is wrong, decompress the file, do pwrite and unlock, that way the next write will start using pwrite aswell. fuse_write: lock(fi->fh->database->lock); if !fi->fh->database->compressed || !quick_write() pwrite unlock(fi->fh->database->lock); # This should have seperate compression info (like offset/zlibstream) in fi->fh, as we can easily do multiple reads from one file, but it still has to check ->compressed. fuse_read: lock(fi->fh->database->lock); if !fi->fh->database->compressed || !quick_read() pread unlock(fi->fh->database->lock); fuse_close: lock(database); // this is to prevent race condition when deleting from the database lock(fi->fh->database->lock); if fi->fh->compressed quick_close(); fi->fh->database->accesses--; if fi->fh->database->accesses == 0 { if !fi->fh->database->compressed then // If file isn't compressed chances are we've been doing something fancy, and we should background compress it later. background_compress list_del(fi->fh->database); free fi->fh->database } unlock(fi->fh->database->lock); unlock(database;