X-Git-Url: http://git.vrable.net/?a=blobdiff_plain;f=bluesky%2Finode.c;fp=bluesky%2Finode.c;h=7560010d3eaded3106c514b793d10aced0e3fa18;hb=260a45ace7787128b9b9748fcb9ffd003af00a5d;hp=9878559d9f35235a7d950108bfac325a525649e0;hpb=337e1b04c921c92697b74aed630343c86fabfcbd;p=bluesky.git diff --git a/bluesky/inode.c b/bluesky/inode.c index 9878559..7560010 100644 --- a/bluesky/inode.c +++ b/bluesky/inode.c @@ -141,6 +141,50 @@ void bluesky_inode_ref(BlueSkyInode *inode) g_atomic_int_inc(&inode->refcount); } +/* Free most of the resources used by an inode structure, but do not free the + * inode itself. Can be used if the inode data will be reloaded from + * serialized form to clear out old information first. */ +void bluesky_inode_free_resources(BlueSkyInode *inode) +{ + switch (inode->type) { + case BLUESKY_REGULAR: + if (inode->blocks != NULL) { + for (int i = 0; i < inode->blocks->len; i++) { + BlueSkyBlock *b = &g_array_index(inode->blocks, + BlueSkyBlock, i); + if (b->type == BLUESKY_BLOCK_DIRTY) { + g_error("Deleting an inode with dirty file data!"); + } + bluesky_cloudlog_unref(b->ref); + bluesky_string_unref(b->dirty); + } + g_array_unref(inode->blocks); + inode->blocks = NULL; + } + break; + + case BLUESKY_DIRECTORY: + if (inode->dirhash != NULL) + g_hash_table_destroy(inode->dirhash); + inode->dirhash = NULL; + if (inode->dirhash_folded != NULL) + g_hash_table_destroy(inode->dirhash_folded); + inode->dirhash_folded = NULL; + if (inode->dirents != NULL) + g_sequence_free(inode->dirents); + inode->dirents = NULL; + break; + + case BLUESKY_SYMLINK: + g_free(inode->symlink_contents); + inode->symlink_contents = NULL; + break; + + default: + break; + } +} + void bluesky_inode_unref(BlueSkyInode *inode) { if (g_atomic_int_dec_and_test(&inode->refcount)) { @@ -167,38 +211,9 @@ void bluesky_inode_unref(BlueSkyInode *inode) bluesky_list_unlink(&inode->fs->unlogged_list, inode->unlogged_list); g_mutex_unlock(inode->fs->lock); - /* Free file type specific data. It should be an error for there to be - * dirty data to commit when the reference count has reaches zero. */ - switch (inode->type) { - case BLUESKY_REGULAR: - for (int i = 0; i < inode->blocks->len; i++) { - BlueSkyBlock *b = &g_array_index(inode->blocks, - BlueSkyBlock, i); - if (b->type == BLUESKY_BLOCK_DIRTY) { - g_error("Deleting an inode with dirty file data!"); - } - bluesky_cloudlog_unref(b->ref); - bluesky_string_unref(b->dirty); - } - g_array_unref(inode->blocks); - break; - - case BLUESKY_DIRECTORY: - g_hash_table_destroy(inode->dirhash); - g_hash_table_destroy(inode->dirhash_folded); - g_sequence_free(inode->dirents); - break; - - case BLUESKY_SYMLINK: - g_free(inode->symlink_contents); - break; - - default: - break; - } + bluesky_inode_free_resources(inode); g_mutex_free(inode->lock); - g_free(inode); } }