Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/fs/fat/fat_idx.c

    rca093b3 r991f645  
    3939#include "../../vfs/vfs.h"
    4040#include <errno.h>
    41 #include <string.h>
     41#include <str.h>
    4242#include <adt/hash_table.h>
    4343#include <adt/list.h>
    4444#include <assert.h>
    45 #include <fibril_sync.h>
     45#include <fibril_synch.h>
    4646
    4747/** Each instance of this type describes one interval of freed VFS indices. */
     
    5858typedef struct {
    5959        link_t          link;
    60         dev_handle_t    dev_handle;
     60        devmap_handle_t devmap_handle;
    6161
    6262        /** Next unassigned index. */
     
    7575static LIST_INITIALIZE(unused_head);
    7676
    77 static void unused_initialize(unused_t *u, dev_handle_t dev_handle)
     77static void unused_initialize(unused_t *u, devmap_handle_t devmap_handle)
    7878{
    7979        link_initialize(&u->link);
    80         u->dev_handle = dev_handle;
     80        u->devmap_handle = devmap_handle;
    8181        u->next = 0;
    8282        u->remaining = ((uint64_t)((fs_index_t)-1)) + 1;
     
    8484}
    8585
    86 static unused_t *unused_find(dev_handle_t dev_handle, bool lock)
     86static unused_t *unused_find(devmap_handle_t devmap_handle, bool lock)
    8787{
    8888        unused_t *u;
     
    9393        for (l = unused_head.next; l != &unused_head; l = l->next) {
    9494                u = list_get_instance(l, unused_t, link);
    95                 if (u->dev_handle == dev_handle)
     95                if (u->devmap_handle == devmap_handle)
    9696                        return u;
    9797        }
     
    106106/**
    107107 * Global hash table of all used fat_idx_t structures.
    108  * The index structures are hashed by the dev_handle, parent node's first
     108 * The index structures are hashed by the devmap_handle, parent node's first
    109109 * cluster and index within the parent directory.
    110110 */
     
    120120static hash_index_t pos_hash(unsigned long key[])
    121121{
    122         dev_handle_t dev_handle = (dev_handle_t)key[UPH_DH_KEY];
     122        devmap_handle_t devmap_handle = (devmap_handle_t)key[UPH_DH_KEY];
    123123        fat_cluster_t pfc = (fat_cluster_t)key[UPH_PFC_KEY];
    124124        unsigned pdi = (unsigned)key[UPH_PDI_KEY];
     
    140140        h |= (pdi & ((1 << (UPH_BUCKETS_LOG / 4)) - 1)) <<
    141141            (UPH_BUCKETS_LOG / 2);
    142         h |= (dev_handle & ((1 << (UPH_BUCKETS_LOG / 4)) - 1)) <<
     142        h |= (devmap_handle & ((1 << (UPH_BUCKETS_LOG / 4)) - 1)) <<
    143143            (3 * (UPH_BUCKETS_LOG / 4));
    144144
     
    148148static int pos_compare(unsigned long key[], hash_count_t keys, link_t *item)
    149149{
    150         dev_handle_t dev_handle = (dev_handle_t)key[UPH_DH_KEY];
    151         fat_cluster_t pfc = (fat_cluster_t)key[UPH_PFC_KEY];
    152         unsigned pdi = (unsigned)key[UPH_PDI_KEY];
     150        devmap_handle_t devmap_handle = (devmap_handle_t)key[UPH_DH_KEY];
     151        fat_cluster_t pfc;
     152        unsigned pdi;
    153153        fat_idx_t *fidx = list_get_instance(item, fat_idx_t, uph_link);
    154154
    155         return (dev_handle == fidx->dev_handle) && (pfc == fidx->pfc) &&
    156             (pdi == fidx->pdi);
     155        switch (keys) {
     156        case 1:
     157                return (devmap_handle == fidx->devmap_handle);
     158        case 3:
     159                pfc = (fat_cluster_t) key[UPH_PFC_KEY];
     160                pdi = (unsigned) key[UPH_PDI_KEY];
     161                return (devmap_handle == fidx->devmap_handle) && (pfc == fidx->pfc) &&
     162                    (pdi == fidx->pdi);
     163        default:
     164                assert((keys == 1) || (keys == 3));
     165        }
     166
     167        return 0;
    157168}
    158169
     
    170181/**
    171182 * Global hash table of all used fat_idx_t structures.
    172  * The index structures are hashed by the dev_handle and index.
     183 * The index structures are hashed by the devmap_handle and index.
    173184 */
    174185static hash_table_t ui_hash;
     
    182193static hash_index_t idx_hash(unsigned long key[])
    183194{
    184         dev_handle_t dev_handle = (dev_handle_t)key[UIH_DH_KEY];
     195        devmap_handle_t devmap_handle = (devmap_handle_t)key[UIH_DH_KEY];
    185196        fs_index_t index = (fs_index_t)key[UIH_INDEX_KEY];
    186197
    187198        hash_index_t h;
    188199
    189         h = dev_handle & ((1 << (UIH_BUCKETS_LOG / 2)) - 1);
     200        h = devmap_handle & ((1 << (UIH_BUCKETS_LOG / 2)) - 1);
    190201        h |= (index & ((1 << (UIH_BUCKETS_LOG / 2)) - 1)) <<
    191202            (UIH_BUCKETS_LOG / 2);
     
    196207static int idx_compare(unsigned long key[], hash_count_t keys, link_t *item)
    197208{
    198         dev_handle_t dev_handle = (dev_handle_t)key[UIH_DH_KEY];
    199         fs_index_t index = (fs_index_t)key[UIH_INDEX_KEY];
     209        devmap_handle_t devmap_handle = (devmap_handle_t)key[UIH_DH_KEY];
     210        fs_index_t index;
    200211        fat_idx_t *fidx = list_get_instance(item, fat_idx_t, uih_link);
    201212
    202         return (dev_handle == fidx->dev_handle) && (index == fidx->index);
     213        switch (keys) {
     214        case 1:
     215                return (devmap_handle == fidx->devmap_handle);
     216        case 2:
     217                index = (fs_index_t) key[UIH_INDEX_KEY];
     218                return (devmap_handle == fidx->devmap_handle) &&
     219                    (index == fidx->index);
     220        default:
     221                assert((keys == 1) || (keys == 2));
     222        }
     223
     224        return 0;
    203225}
    204226
    205227static void idx_remove_callback(link_t *item)
    206228{
    207         /* nothing to do */
     229        fat_idx_t *fidx = list_get_instance(item, fat_idx_t, uih_link);
     230
     231        free(fidx);
    208232}
    209233
     
    215239
    216240/** Allocate a VFS index which is not currently in use. */
    217 static bool fat_index_alloc(dev_handle_t dev_handle, fs_index_t *index)
     241static bool fat_index_alloc(devmap_handle_t devmap_handle, fs_index_t *index)
    218242{
    219243        unused_t *u;
    220244       
    221245        assert(index);
    222         u = unused_find(dev_handle, true);
     246        u = unused_find(devmap_handle, true);
    223247        if (!u)
    224248                return false;   
     
    277301
    278302/** Free a VFS index, which is no longer in use. */
    279 static void fat_index_free(dev_handle_t dev_handle, fs_index_t index)
     303static void fat_index_free(devmap_handle_t devmap_handle, fs_index_t index)
    280304{
    281305        unused_t *u;
    282306
    283         u = unused_find(dev_handle, true);
     307        u = unused_find(devmap_handle, true);
    284308        assert(u);
    285309
     
    339363}
    340364
    341 static fat_idx_t *fat_idx_create(dev_handle_t dev_handle)
     365static int fat_idx_create(fat_idx_t **fidxp, devmap_handle_t devmap_handle)
    342366{
    343367        fat_idx_t *fidx;
     
    345369        fidx = (fat_idx_t *) malloc(sizeof(fat_idx_t));
    346370        if (!fidx)
    347                 return NULL;
    348         if (!fat_index_alloc(dev_handle, &fidx->index)) {
     371                return ENOMEM;
     372        if (!fat_index_alloc(devmap_handle, &fidx->index)) {
    349373                free(fidx);
    350                 return NULL;
     374                return ENOSPC;
    351375        }
    352376               
     
    354378        link_initialize(&fidx->uih_link);
    355379        fibril_mutex_initialize(&fidx->lock);
    356         fidx->dev_handle = dev_handle;
     380        fidx->devmap_handle = devmap_handle;
    357381        fidx->pfc = FAT_CLST_RES0;      /* no parent yet */
    358382        fidx->pdi = 0;
    359383        fidx->nodep = NULL;
    360384
    361         return fidx;
    362 }
    363 
    364 fat_idx_t *fat_idx_get_new(dev_handle_t dev_handle)
     385        *fidxp = fidx;
     386        return EOK;
     387}
     388
     389int fat_idx_get_new(fat_idx_t **fidxp, devmap_handle_t devmap_handle)
    365390{
    366391        fat_idx_t *fidx;
     392        int rc;
    367393
    368394        fibril_mutex_lock(&used_lock);
    369         fidx = fat_idx_create(dev_handle);
    370         if (!fidx) {
     395        rc = fat_idx_create(&fidx, devmap_handle);
     396        if (rc != EOK) {
    371397                fibril_mutex_unlock(&used_lock);
    372                 return NULL;
     398                return rc;
    373399        }
    374400               
    375401        unsigned long ikey[] = {
    376                 [UIH_DH_KEY] = dev_handle,
     402                [UIH_DH_KEY] = devmap_handle,
    377403                [UIH_INDEX_KEY] = fidx->index,
    378404        };
     
    382408        fibril_mutex_unlock(&used_lock);
    383409
    384         return fidx;
     410        *fidxp = fidx;
     411        return EOK;
    385412}
    386413
    387414fat_idx_t *
    388 fat_idx_get_by_pos(dev_handle_t dev_handle, fat_cluster_t pfc, unsigned pdi)
     415fat_idx_get_by_pos(devmap_handle_t devmap_handle, fat_cluster_t pfc, unsigned pdi)
    389416{
    390417        fat_idx_t *fidx;
    391418        link_t *l;
    392419        unsigned long pkey[] = {
    393                 [UPH_DH_KEY] = dev_handle,
     420                [UPH_DH_KEY] = devmap_handle,
    394421                [UPH_PFC_KEY] = pfc,
    395422                [UPH_PDI_KEY] = pdi,
     
    401428                fidx = hash_table_get_instance(l, fat_idx_t, uph_link);
    402429        } else {
    403                 fidx = fat_idx_create(dev_handle);
    404                 if (!fidx) {
     430                int rc;
     431
     432                rc = fat_idx_create(&fidx, devmap_handle);
     433                if (rc != EOK) {
    405434                        fibril_mutex_unlock(&used_lock);
    406435                        return NULL;
     
    408437               
    409438                unsigned long ikey[] = {
    410                         [UIH_DH_KEY] = dev_handle,
     439                        [UIH_DH_KEY] = devmap_handle,
    411440                        [UIH_INDEX_KEY] = fidx->index,
    412441                };
     
    427456{
    428457        unsigned long pkey[] = {
    429                 [UPH_DH_KEY] = idx->dev_handle,
     458                [UPH_DH_KEY] = idx->devmap_handle,
    430459                [UPH_PFC_KEY] = idx->pfc,
    431460                [UPH_PDI_KEY] = idx->pdi,
     
    440469{
    441470        unsigned long pkey[] = {
    442                 [UPH_DH_KEY] = idx->dev_handle,
     471                [UPH_DH_KEY] = idx->devmap_handle,
    443472                [UPH_PFC_KEY] = idx->pfc,
    444473                [UPH_PDI_KEY] = idx->pdi,
     
    451480
    452481fat_idx_t *
    453 fat_idx_get_by_index(dev_handle_t dev_handle, fs_index_t index)
     482fat_idx_get_by_index(devmap_handle_t devmap_handle, fs_index_t index)
    454483{
    455484        fat_idx_t *fidx = NULL;
    456485        link_t *l;
    457486        unsigned long ikey[] = {
    458                 [UIH_DH_KEY] = dev_handle,
     487                [UIH_DH_KEY] = devmap_handle,
    459488                [UIH_INDEX_KEY] = index,
    460489        };
     
    478507{
    479508        unsigned long ikey[] = {
    480                 [UIH_DH_KEY] = idx->dev_handle,
     509                [UIH_DH_KEY] = idx->devmap_handle,
    481510                [UIH_INDEX_KEY] = idx->index,
    482511        };
     512        devmap_handle_t devmap_handle = idx->devmap_handle;
     513        fs_index_t index = idx->index;
    483514
    484515        assert(idx->pfc == FAT_CLST_RES0);
     
    493524        fibril_mutex_unlock(&used_lock);
    494525        /* Release the VFS index. */
    495         fat_index_free(idx->dev_handle, idx->index);
    496         /* Deallocate the structure. */
    497         free(idx);
     526        fat_index_free(devmap_handle, index);
     527        /* The index structure itself is freed in idx_remove_callback(). */
    498528}
    499529
     
    516546}
    517547
    518 int fat_idx_init_by_dev_handle(dev_handle_t dev_handle)
     548int fat_idx_init_by_devmap_handle(devmap_handle_t devmap_handle)
    519549{
    520550        unused_t *u;
     
    524554        if (!u)
    525555                return ENOMEM;
    526         unused_initialize(u, dev_handle);
     556        unused_initialize(u, devmap_handle);
    527557        fibril_mutex_lock(&unused_lock);
    528         if (!unused_find(dev_handle, false))
     558        if (!unused_find(devmap_handle, false)) {
    529559                list_append(&u->link, &unused_head);
    530         else
     560        } else {
     561                free(u);
    531562                rc = EEXIST;
     563        }
    532564        fibril_mutex_unlock(&unused_lock);
    533565        return rc;
    534566}
    535567
    536 void fat_idx_fini_by_dev_handle(dev_handle_t dev_handle)
    537 {
    538         unused_t *u;
    539 
    540         u = unused_find(dev_handle, true);
     568void fat_idx_fini_by_devmap_handle(devmap_handle_t devmap_handle)
     569{
     570        unsigned long ikey[] = {
     571                [UIH_DH_KEY] = devmap_handle
     572        };
     573        unsigned long pkey[] = {
     574                [UPH_DH_KEY] = devmap_handle
     575        };
     576
     577        /*
     578         * Remove this instance's index structure from up_hash and ui_hash.
     579         * Process up_hash first and ui_hash second because the index structure
     580         * is actually removed in idx_remove_callback().
     581         */
     582        fibril_mutex_lock(&used_lock);
     583        hash_table_remove(&up_hash, pkey, 1);
     584        hash_table_remove(&ui_hash, ikey, 1);
     585        fibril_mutex_unlock(&used_lock);
     586
     587        /*
     588         * Free the unused and freed structures for this instance.
     589         */
     590        unused_t *u = unused_find(devmap_handle, true);
    541591        assert(u);
    542592        list_remove(&u->link);
Note: See TracChangeset for help on using the changeset viewer.