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;