X-Git-Url: http://git.vrable.net/?a=blobdiff_plain;ds=sidebyside;f=dir.c;fp=dir.c;h=0000000000000000000000000000000000000000;hb=70fdd2326239a9a5e02b3c3699d2588d5fee48fa;hp=204439efde629ebac028864498aa1b5d61662ff9;hpb=e176f19a88257f6d8cca5c21dce012796806ffd8;p=bluesky.git diff --git a/dir.c b/dir.c deleted file mode 100644 index 204439e..0000000 --- a/dir.c +++ /dev/null @@ -1,143 +0,0 @@ -/* Blue Sky: File Systems in the Cloud - * - * Copyright (C) 2009 The Regents of the University of California - * Written by Michael Vrable - * - * TODO: Licensing - */ - -#include -#include - -#include "bluesky.h" - -/* Core filesystem: handling of directories. */ - -void bluesky_dirent_destroy(gpointer data) -{ - BlueSkyDirent *dirent = (BlueSkyDirent *)data; - g_free(dirent->name); - g_free(dirent); -} - -gint bluesky_dirent_compare(gconstpointer a, gconstpointer b, - gpointer unused) -{ - uint32_t hash1 = ((const BlueSkyDirent *)a)->cookie; - uint32_t hash2 = ((const BlueSkyDirent *)b)->cookie; - - if (hash1 < hash2) - return -1; - else if (hash1 > hash2) - return 1; - else - return 0; -} - -/* Perform a lookup for a file name within a directory. Returns the inode - * number if found, or 0 if not (0 is never a valid inode number). Should be - * called with the inode lock already held. */ -uint64_t bluesky_directory_lookup(BlueSkyInode *inode, gchar *name) -{ - g_return_val_if_fail(inode->type == BLUESKY_DIRECTORY, 0); - g_return_val_if_fail(inode->dirhash != NULL, 0); - - BlueSkyDirent *d = g_hash_table_lookup(inode->dirhash, name); - if (d == NULL) - return 0; - else - return d->inum; -} - -/* Insert a new entry into a directory. Should be called with the inode lock - * already held. */ -gboolean bluesky_directory_insert(BlueSkyInode *dir, gchar *name, uint64_t inum) -{ - g_return_val_if_fail(dir->type == BLUESKY_DIRECTORY, FALSE); - - /* Check that no entry with the given name already exists. */ - if (g_hash_table_lookup(dir->dirhash, name) != NULL) - return FALSE; - - BlueSkyDirent *d = g_new(BlueSkyDirent, 1); - d->name = g_strdup(name); - d->inum = inum; - - GSequence *dirents = dir->dirents; - - /* Pick an unused cookie value for the directory at random. Restrict - * ourselves to positive 32-bit values (even if treated as signed), and - * keep the first four slots free. */ - while (1) { - do { - d->cookie = g_random_int() & 0x7fffffff; - } while (d->cookie < 4); - - /* If the directory is empty, we can't possibly have a collision, so - * just go with the first key chosen. */ - if (g_sequence_get_length(dirents) == 0) - break; - - /* Otherwise, try looking up the generated cookie. If we do not find a - * match, we can use this cookie value, otherwise we need to generate a - * new one and try again. Because of the check above for an empty - * directory, we know that the lookup will return something so no need - * to worry about NULL. */ - GSequenceIter *i = g_sequence_search(dir->dirents, d, - bluesky_dirent_compare, NULL); - i = g_sequence_iter_prev(i); - if (((BlueSkyDirent *)g_sequence_get(i))->cookie != d->cookie) - break; - } - - /* Add the directory entry to both indices. */ - g_sequence_insert_sorted(dirents, d, bluesky_dirent_compare, NULL); - g_hash_table_insert(dir->dirhash, d->name, d); - - bluesky_inode_update_ctime(dir, 1); - - return TRUE; -} - -/* Remove an from a directory. Should be called with the inode lock already - * held. */ -gboolean bluesky_directory_remove(BlueSkyInode *dir, gchar *name) -{ - g_return_val_if_fail(dir->type == BLUESKY_DIRECTORY, FALSE); - - BlueSkyDirent *d = g_hash_table_lookup(dir->dirhash, name); - if (d == NULL) { - return FALSE; - } - - g_hash_table_remove(dir->dirhash, name); - - GSequenceIter *i = g_sequence_search(dir->dirents, d, - bluesky_dirent_compare, NULL); - i = g_sequence_iter_prev(i); - - /* Assertion check, this ought to succeed */ - g_return_val_if_fail(g_sequence_get(i) == d, FALSE); - - g_sequence_remove(i); - - bluesky_dirent_destroy(d); - - bluesky_inode_update_ctime(dir, 1); - - return TRUE; -} - -/* Dump the contents of a directory to stdout. Debugging only. */ -void bluesky_directory_dump(BlueSkyInode *dir) -{ - g_print("Directory dump:\n"); - - GSequenceIter *i = g_sequence_get_begin_iter(dir->dirents); - - while (!g_sequence_iter_is_end(i)) { - BlueSkyDirent *d = g_sequence_get(i); - g_print(" 0x%08x [inum=%lld] %s\n", d->cookie, d->inum, d->name); - i = g_sequence_iter_next(i); - } -}