source: mainline/uspace/srv/fs/udf/udf_idx.c@ 951e451

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 951e451 was 5e801dc, checked in by GitHub <noreply@…>, 6 years ago

Indicate and enforce constness of hash table key in certain functions (#158)

The assumption here is that modifying key in the hash/equal functions in something completely unexpected, and not something you would ever want to do intentionally, so it makes sense to disallow it entirely to get that extra level of checking.

  • Property mode set to 100644
File size: 5.2 KB
RevLine 
[48e3190]1/*
2 * Copyright (c) 2012 Julia Medvedeva
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
[b1834a01]29/** @addtogroup udf
[48e3190]30 * @{
31 */
32/**
33 * @file udf_idx.c
34 * @brief Very simple UDF hashtable for nodes
35 */
36
37#include "../../vfs/vfs.h"
38#include <errno.h>
39#include <str.h>
40#include <assert.h>
41#include <fibril_synch.h>
[38d150e]42#include <stdlib.h>
[48e3190]43#include <adt/hash_table.h>
[38fc00b]44#include <adt/hash.h>
[48e3190]45#include <adt/list.h>
[3e6a98c5]46#include <stdbool.h>
[48e3190]47#include "udf_idx.h"
48#include "udf.h"
49
50static FIBRIL_MUTEX_INITIALIZE(udf_idx_lock);
51
52static hash_table_t udf_idx;
53
[38fc00b]54typedef struct {
55 service_id_t service_id;
56 fs_index_t index;
[1b20da0]57} udf_ht_key_t;
[38fc00b]58
59static size_t udf_idx_hash(const ht_link_t *item)
[48e3190]60{
[38fc00b]61 udf_node_t *node = hash_table_get_inst(item, udf_node_t, link);
62 return hash_combine(node->instance->service_id, node->index);
[48e3190]63}
64
[5e801dc]65static size_t udf_idx_key_hash(const void *k)
[48e3190]66{
[5e801dc]67 const udf_ht_key_t *key = k;
[38fc00b]68 return hash_combine(key->service_id, key->index);
[48e3190]69}
70
[5e801dc]71static bool udf_idx_key_equal(const void *k, const ht_link_t *item)
[48e3190]72{
[5e801dc]73 const udf_ht_key_t *key = k;
[38fc00b]74 udf_node_t *node = hash_table_get_inst(item, udf_node_t, link);
75
76 return (key->service_id == node->instance->service_id) &&
77 (key->index == node->index);
[48e3190]78}
79
[38fc00b]80static hash_table_ops_t udf_idx_ops = {
[48e3190]81 .hash = udf_idx_hash,
[38fc00b]82 .key_hash = udf_idx_key_hash,
83 .key_equal = udf_idx_key_equal,
84 .equal = NULL,
[1b20da0]85 .remove_callback = NULL
[48e3190]86};
87
88/** Initialization of hash table
89 *
[cde999a]90 * @return EOK on success or an error code.
[48e3190]91 *
92 */
[b7fd2a0]93errno_t udf_idx_init(void)
[48e3190]94{
[38fc00b]95 if (!hash_table_create(&udf_idx, 0, 0, &udf_idx_ops))
[48e3190]96 return ENOMEM;
[a35b458]97
[48e3190]98 return EOK;
99}
100
101/** Delete hash table
102 *
[cde999a]103 * @return EOK on success or an error code.
[48e3190]104 *
105 */
[b7fd2a0]106errno_t udf_idx_fini(void)
[48e3190]107{
108 hash_table_destroy(&udf_idx);
109 return EOK;
110}
111
112/** Get node from hash table
113 *
114 * @param udfn Returned value - UDF node
115 * @param instance UDF instance
116 * @param index Absolute position of ICB (sector)
117 *
[cde999a]118 * @return EOK on success or an error code.
[48e3190]119 *
120 */
[b7fd2a0]121errno_t udf_idx_get(udf_node_t **udfn, udf_instance_t *instance, fs_index_t index)
[48e3190]122{
123 fibril_mutex_lock(&udf_idx_lock);
[38fc00b]124
125 udf_ht_key_t key = {
126 .service_id = instance->service_id,
127 .index = index
[48e3190]128 };
[a35b458]129
[38fc00b]130 ht_link_t *already_open = hash_table_find(&udf_idx, &key);
[48e3190]131 if (already_open) {
[38fc00b]132 udf_node_t *node = hash_table_get_inst(already_open,
[48e3190]133 udf_node_t, link);
134 node->ref_cnt++;
[a35b458]135
[48e3190]136 *udfn = node;
[a35b458]137
[48e3190]138 fibril_mutex_unlock(&udf_idx_lock);
139 return EOK;
140 }
[a35b458]141
[48e3190]142 fibril_mutex_unlock(&udf_idx_lock);
143 return ENOENT;
144}
145
146/** Create new node in hash table
147 *
148 * @param udfn Returned value - new UDF node
149 * @param instance UDF instance
150 * @param index Absolute position of ICB (sector)
151 *
[cde999a]152 * @return EOK on success or an error code.
[48e3190]153 *
154 */
[b7fd2a0]155errno_t udf_idx_add(udf_node_t **udfn, udf_instance_t *instance, fs_index_t index)
[48e3190]156{
157 fibril_mutex_lock(&udf_idx_lock);
[a35b458]158
[48e3190]159 udf_node_t *udf_node = malloc(sizeof(udf_node_t));
160 if (udf_node == NULL) {
161 fibril_mutex_unlock(&udf_idx_lock);
162 return ENOMEM;
163 }
[a35b458]164
[48e3190]165 fs_node_t *fs_node = malloc(sizeof(fs_node_t));
166 if (fs_node == NULL) {
167 free(udf_node);
168 fibril_mutex_unlock(&udf_idx_lock);
169 return ENOMEM;
170 }
[a35b458]171
[48e3190]172 fs_node_initialize(fs_node);
[a35b458]173
[48e3190]174 udf_node->index = index;
175 udf_node->instance = instance;
176 udf_node->ref_cnt = 1;
177 udf_node->link_cnt = 0;
178 udf_node->fs_node = fs_node;
179 udf_node->data = NULL;
180 udf_node->allocators = NULL;
[a35b458]181
[48e3190]182 fibril_mutex_initialize(&udf_node->lock);
183 fs_node->data = udf_node;
[a35b458]184
[38fc00b]185 hash_table_insert(&udf_idx, &udf_node->link);
[48e3190]186 instance->open_nodes_count++;
[a35b458]187
[48e3190]188 *udfn = udf_node;
[a35b458]189
[48e3190]190 fibril_mutex_unlock(&udf_idx_lock);
191 return EOK;
192}
193
194/** Delete node from hash table
195 *
196 * @param node UDF node
197 *
[cde999a]198 * @return EOK on success or an error code.
[48e3190]199 *
200 */
[b7fd2a0]201errno_t udf_idx_del(udf_node_t *node)
[48e3190]202{
203 assert(node->ref_cnt == 0);
[a35b458]204
[48e3190]205 fibril_mutex_lock(&udf_idx_lock);
[a35b458]206
[38fc00b]207 hash_table_remove_item(&udf_idx, &node->link);
[a35b458]208
[48e3190]209 assert(node->instance->open_nodes_count > 0);
210 node->instance->open_nodes_count--;
[a35b458]211
[48e3190]212 free(node->fs_node);
213 free(node);
[a35b458]214
[48e3190]215 fibril_mutex_unlock(&udf_idx_lock);
216 return EOK;
217}
218
219/**
220 * @}
221 */
Note: See TracBrowser for help on using the repository browser.