Changeset 9a5ccfb3 in mainline


Ignore:
Timestamp:
2008-05-05T20:16:36Z (17 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4797132
Parents:
0c1ad7ac
Message:

Add hash table for used fat_idx_t structures and implement fat_idx_map().

Location:
uspace/srv/fs/fat
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/fs/fat/fat.h

    r0c1ad7ac r9a5ccfb3  
    176176 */
    177177typedef struct {
     178        /** Used indices hash table link. */
     179        link_t          uh_link;
     180
    178181        dev_handle_t    dev_handle;
    179182        fs_index_t      index;
    180183        /**
    181          * Parent first cluster.
     184         * Parent node's first cluster.
    182185         * Zero is used if this node is not linked, in which case nodep must
    183186         * contain a pointer to the in-core node structure.
     
    185188         */
    186189        fat_cluster_t   pfc;
    187         /** Parent directory entry index. */
     190        /** Directory entry index within the parent node. */
    188191        unsigned        pdi;
    189192        /** Pointer to in-core node instance. */
  • uspace/srv/fs/fat/fat_idx.c

    r0c1ad7ac r9a5ccfb3  
    7070
    7171static LIST_INITIALIZE(unused_head);
     72
     73/** Global hash table of all used fat_idx_t structures. */
     74static hash_table_t used_hash;
     75
     76#define USED_HASH_BUCKETS_LOG   12
     77#define USED_HASH_BUCKETS       (1 << USED_HASH_BUCKETS_LOG)
     78
     79#define USED_HASH_DH_KEY        0
     80#define USED_HASH_PFC_KEY       1
     81#define USED_HASH_PDI_KEY       2
     82
     83static hash_index_t idx_hash(unsigned long key[])
     84{
     85        dev_handle_t dev_handle = (dev_handle_t)key[USED_HASH_DH_KEY];
     86        fat_cluster_t pfc = (fat_cluster_t)key[USED_HASH_PFC_KEY];
     87        unsigned pdi = (unsigned)key[USED_HASH_PDI_KEY];
     88
     89        hash_index_t h;
     90
     91        /*
     92         * The least significant half of all bits are the least significant bits
     93         * of the parent node's first cluster.
     94         *
     95         * The least significant half of the most significant half of all bits
     96         * are the least significant bits of the node's dentry index within the
     97         * parent directory node.
     98         *
     99         * The most significant half of the most significant half of all bits
     100         * are the least significant bits of the device handle.
     101         */
     102        h = pfc & ((USED_HASH_BUCKETS_LOG / 2) - 1);
     103        h |= (pdi & ((USED_HASH_BUCKETS_LOG / 4) - 1)) <<
     104            (USED_HASH_BUCKETS_LOG / 2);
     105        h |= (dev_handle & ((USED_HASH_BUCKETS_LOG / 4) - 1)) <<
     106            (3 * (USED_HASH_BUCKETS_LOG / 4));
     107
     108        return h;
     109}
     110
     111static int idx_compare(unsigned long key[], hash_count_t keys, link_t *item)
     112{
     113        dev_handle_t dev_handle = (dev_handle_t)key[USED_HASH_DH_KEY];
     114        fat_cluster_t pfc = (fat_cluster_t)key[USED_HASH_PFC_KEY];
     115        unsigned pdi = (unsigned)key[USED_HASH_PDI_KEY];
     116        fat_idx_t *fidx = list_get_instance(item, fat_idx_t, uh_link);
     117
     118        return (dev_handle == fidx->dev_handle) && (pfc == fidx->pfc) &&
     119            (pdi == fidx->pdi);
     120}
     121
     122static void idx_remove_callback(link_t *item)
     123{
     124        /* nothing to do */
     125}
     126
     127static hash_table_operations_t used_idx_ops = {
     128        .hash = idx_hash,
     129        .compare = idx_compare,
     130        .remove_callback = idx_remove_callback,
     131};
    72132
    73133/** Allocate a VFS index which is not currently in use. */
     
    207267fat_idx_t *fat_idx_map(dev_handle_t dev_handle, fat_cluster_t pfc, unsigned pdi)
    208268{
    209         return NULL;    /* TODO */
    210 }
     269        fat_idx_t *fidx;
     270        link_t *l;
     271        unsigned long key[] = {
     272                [USED_HASH_DH_KEY] = dev_handle,
     273                [USED_HASH_PFC_KEY] = pfc,
     274                [USED_HASH_PDI_KEY] = pdi,
     275        };
     276
     277        l = hash_table_find(&used_hash, key);
     278        if (l) {
     279                fidx = hash_table_get_instance(l, fat_idx_t, uh_link);
     280        } else {
     281                fidx = (fat_idx_t *) malloc(sizeof(fat_idx_t));
     282                if (!fidx) {
     283                        return NULL;
     284                }
     285                if (!fat_idx_alloc(dev_handle, &fidx->index)) {
     286                        free(fidx);
     287                        return NULL;
     288                }
     289                link_initialize(&fidx->uh_link);
     290                fidx->dev_handle = dev_handle;
     291                fidx->pfc = pfc;
     292                fidx->pdi = pdi;
     293                fidx->nodep = NULL;
     294                hash_table_insert(&used_hash, key, &fidx->uh_link);
     295        }
     296
     297        return fidx;
     298}
     299
Note: See TracChangeset for help on using the changeset viewer.