Subversion Repositories HelenOS

Rev

Rev 2758 | Rev 2763 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2758 Rev 2760
Line 54... Line 54...
54
#define min(a, b)       ((a) < (b) ? (a) : (b))
54
#define min(a, b)       ((a) < (b) ? (a) : (b))
55
#define max(a, b)       ((a) > (b) ? (a) : (b))
55
#define max(a, b)       ((a) > (b) ? (a) : (b))
56
 
56
 
57
#define DENTRIES_BUCKETS    256
57
#define DENTRIES_BUCKETS    256
58
 
58
 
-
 
59
#define NAMES_BUCKETS       4
-
 
60
 
59
/*
61
/*
60
 * For now, we don't distinguish between different dev_handles/instances. All
62
 * For now, we don't distinguish between different dev_handles/instances. All
61
 * requests resolve to the only instance, rooted in the following variable.
63
 * requests resolve to the only instance, rooted in the following variable.
62
 */
64
 */
63
static tmpfs_dentry_t *root;
65
static tmpfs_dentry_t *root;
Line 65... Line 67...
65
/*
67
/*
66
 * Implementation of the libfs interface.
68
 * Implementation of the libfs interface.
67
 */
69
 */
68
 
70
 
69
/* Forward declarations of static functions. */
71
/* Forward declarations of static functions. */
70
static bool tmpfs_match(void *, const char *);
72
static bool tmpfs_match(void *, void *, const char *);
71
static void *tmpfs_create_node(int);
73
static void *tmpfs_create_node(int);
72
static bool tmpfs_link_node(void *, void *, const char *);
74
static bool tmpfs_link_node(void *, void *, const char *);
73
static int tmpfs_unlink_node(void *, void *);
75
static int tmpfs_unlink_node(void *, void *);
74
static void tmpfs_destroy_node(void *);
76
static void tmpfs_destroy_node(void *);
75
 
77
 
Line 138... Line 140...
138
};
140
};
139
 
141
 
140
/** Hash table of all directory entries. */
142
/** Hash table of all directory entries. */
141
hash_table_t dentries;
143
hash_table_t dentries;
142
 
144
 
143
/* Implementation of hash table interface. */
145
/* Implementation of hash table interface for the dentries hash table. */
144
static hash_index_t dentries_hash(unsigned long *key)
146
static hash_index_t dentries_hash(unsigned long *key)
145
{
147
{
146
    return *key % DENTRIES_BUCKETS;
148
    return *key % DENTRIES_BUCKETS;
147
}
149
}
148
 
150
 
Line 165... Line 167...
165
    .remove_callback = dentries_remove_callback
167
    .remove_callback = dentries_remove_callback
166
};
168
};
167
 
169
 
168
unsigned tmpfs_next_index = 1;
170
unsigned tmpfs_next_index = 1;
169
 
171
 
-
 
172
typedef struct {
-
 
173
    char *name;
-
 
174
    tmpfs_dentry_t *parent;
-
 
175
    link_t link;
-
 
176
} tmpfs_name_t;
-
 
177
 
-
 
178
/* Implementation of hash table interface for the names hash table. */
-
 
179
static hash_index_t names_hash(unsigned long *key)
-
 
180
{
-
 
181
    tmpfs_dentry_t *dentry = (tmpfs_dentry_t *) *key;
-
 
182
    return dentry->index % NAMES_BUCKETS;
-
 
183
}
-
 
184
 
-
 
185
static int names_compare(unsigned long *key, hash_count_t keys, link_t *item)
-
 
186
{
-
 
187
    tmpfs_dentry_t *dentry = (tmpfs_dentry_t *) *key;
-
 
188
    tmpfs_name_t *namep = hash_table_get_instance(item, tmpfs_name_t,
-
 
189
        link);
-
 
190
    return dentry == namep->parent;
-
 
191
}
-
 
192
 
-
 
193
static void names_remove_callback(link_t *item)
-
 
194
{
-
 
195
    tmpfs_name_t *namep = hash_table_get_instance(item, tmpfs_name_t,
-
 
196
        link);
-
 
197
    free(namep->name);
-
 
198
    free(namep);
-
 
199
}
-
 
200
 
-
 
201
/** TMPFS node names hash table operations. */
-
 
202
static hash_table_operations_t names_ops = {
-
 
203
    .hash = names_hash,
-
 
204
    .compare = names_compare,
-
 
205
    .remove_callback = names_remove_callback
-
 
206
};
-
 
207
 
-
 
208
static void tmpfs_name_initialize(tmpfs_name_t *namep)
-
 
209
{
-
 
210
    namep->name = NULL;
-
 
211
    namep->parent = NULL;
-
 
212
    link_initialize(&namep->link);
-
 
213
}
-
 
214
 
170
static void tmpfs_dentry_initialize(tmpfs_dentry_t *dentry)
215
static bool tmpfs_dentry_initialize(tmpfs_dentry_t *dentry)
171
{
216
{
172
    dentry->index = 0;
217
    dentry->index = 0;
173
    dentry->sibling = NULL;
218
    dentry->sibling = NULL;
174
    dentry->child = NULL;
219
    dentry->child = NULL;
175
    dentry->name = NULL;
-
 
176
    dentry->type = TMPFS_NONE;
220
    dentry->type = TMPFS_NONE;
177
    dentry->lnkcnt = 0;
221
    dentry->lnkcnt = 0;
178
    dentry->size = 0;
222
    dentry->size = 0;
179
    dentry->data = NULL;
223
    dentry->data = NULL;
180
    link_initialize(&dentry->dh_link);
224
    link_initialize(&dentry->dh_link);
-
 
225
    return (bool)hash_table_create(&dentry->names, NAMES_BUCKETS, 1,
-
 
226
        &names_ops);
181
}
227
}
182
 
228
 
183
static bool tmpfs_init(void)
229
static bool tmpfs_init(void)
184
{
230
{
185
    if (!hash_table_create(&dentries, DENTRIES_BUCKETS, 1, &dentries_ops))
231
    if (!hash_table_create(&dentries, DENTRIES_BUCKETS, 1, &dentries_ops))
186
        return false;
232
        return false;
187
    root = (tmpfs_dentry_t *) tmpfs_create_node(L_DIRECTORY);
233
    root = (tmpfs_dentry_t *) tmpfs_create_node(L_DIRECTORY);
-
 
234
    if (!root) {
-
 
235
        hash_table_destroy(&dentries);
-
 
236
        return false;
-
 
237
    }
188
    root->lnkcnt = 1;
238
    root->lnkcnt = 1;
189
    return root != NULL;
239
    return true;
190
}
240
}
191
 
241
 
192
/** Compare one component of path to a directory entry.
242
/** Compare one component of path to a directory entry.
193
 *
243
 *
-
 
244
 * @param prnt      Node from which we descended.
194
 * @param nodep     Node to compare the path component with.
245
 * @param chld      Node to compare the path component with.
195
 * @param component Array of characters holding component name.
246
 * @param component Array of characters holding component name.
196
 *
247
 *
197
 * @return      True on match, false otherwise.
248
 * @return      True on match, false otherwise.
198
 */
249
 */
199
bool tmpfs_match(void *nodep, const char *component)
250
bool tmpfs_match(void *prnt, void *chld, const char *component)
200
{
251
{
201
    tmpfs_dentry_t *dentry = (tmpfs_dentry_t *) nodep;
252
    tmpfs_dentry_t *parentp = (tmpfs_dentry_t *) prnt;
-
 
253
    tmpfs_dentry_t *childp = (tmpfs_dentry_t *) chld;
202
 
254
 
-
 
255
    unsigned long key = (unsigned long) parentp;
-
 
256
    link_t *hlp = hash_table_find(&childp->names, &key);
-
 
257
    assert(hlp);
-
 
258
    tmpfs_name_t *namep = hash_table_get_instance(hlp, tmpfs_name_t, link);
-
 
259
 
203
    return !strcmp(dentry->name, component);
260
    return !strcmp(namep->name, component);
204
}
261
}
205
 
262
 
206
void *tmpfs_create_node(int lflag)
263
void *tmpfs_create_node(int lflag)
207
{
264
{
208
    assert((lflag & L_FILE) ^ (lflag & L_DIRECTORY));
265
    assert((lflag & L_FILE) ^ (lflag & L_DIRECTORY));
209
 
266
 
210
    tmpfs_dentry_t *node = malloc(sizeof(tmpfs_dentry_t));
267
    tmpfs_dentry_t *node = malloc(sizeof(tmpfs_dentry_t));
211
    if (!node)
268
    if (!node)
212
        return NULL;
269
        return NULL;
213
 
270
 
214
    tmpfs_dentry_initialize(node);
271
    if (!tmpfs_dentry_initialize(node)) {
-
 
272
        free(node);
-
 
273
        return NULL;
-
 
274
    }
215
    node->index = tmpfs_next_index++;
275
    node->index = tmpfs_next_index++;
216
    if (lflag & L_DIRECTORY)
276
    if (lflag & L_DIRECTORY)
217
        node->type = TMPFS_DIRECTORY;
277
        node->type = TMPFS_DIRECTORY;
218
    else
278
    else
219
        node->type = TMPFS_FILE;
279
        node->type = TMPFS_FILE;
Line 228... Line 288...
228
    tmpfs_dentry_t *parentp = (tmpfs_dentry_t *) prnt;
288
    tmpfs_dentry_t *parentp = (tmpfs_dentry_t *) prnt;
229
    tmpfs_dentry_t *childp = (tmpfs_dentry_t *) chld;
289
    tmpfs_dentry_t *childp = (tmpfs_dentry_t *) chld;
230
 
290
 
231
    assert(parentp->type == TMPFS_DIRECTORY);
291
    assert(parentp->type == TMPFS_DIRECTORY);
232
 
292
 
-
 
293
    tmpfs_name_t *namep = malloc(sizeof(tmpfs_name_t));
-
 
294
    if (!namep)
-
 
295
        return false;
-
 
296
    tmpfs_name_initialize(namep);
233
    size_t len = strlen(nm);
297
    size_t len = strlen(nm);
234
    char *name = malloc(len + 1);
298
    namep->name = malloc(len + 1);
-
 
299
    if (!namep->name) {
235
    if (!name)
300
        free(namep);
236
        return false;
301
        return false;
-
 
302
    }
-
 
303
    strcpy(namep->name, nm);
-
 
304
    namep->parent = parentp;
237
   
305
   
238
    childp->lnkcnt++;
306
    childp->lnkcnt++;
239
   
307
 
240
    strcpy(name, nm);
308
    unsigned long key = (unsigned long) parentp;
241
    childp->name = name;
309
    hash_table_insert(&childp->names, &key, &namep->link);
242
 
310
 
243
    /* Insert the new node into the namespace. */
311
    /* Insert the new node into the namespace. */
244
    if (parentp->child) {
312
    if (parentp->child) {
245
        tmpfs_dentry_t *tmp = parentp->child;
313
        tmpfs_dentry_t *tmp = parentp->child;
246
        while (tmp->sibling)
314
        while (tmp->sibling)
Line 273... Line 341...
273
            tmp = tmp->sibling;
341
            tmp = tmp->sibling;
274
        tmp->sibling = childp->sibling;
342
        tmp->sibling = childp->sibling;
275
    }
343
    }
276
    childp->sibling = NULL;
344
    childp->sibling = NULL;
277
 
345
 
278
    free(childp->name);
346
    unsigned long key = (unsigned long) parentp;
279
    childp->name = NULL;
347
    hash_table_remove(&childp->names, &key, 1);
280
 
348
 
281
    childp->lnkcnt--;
349
    childp->lnkcnt--;
282
 
350
 
283
    return EOK;
351
    return EOK;
284
}
352
}
Line 292... Line 360...
292
    assert(!dentry->sibling);
360
    assert(!dentry->sibling);
293
 
361
 
294
    unsigned long index = dentry->index;
362
    unsigned long index = dentry->index;
295
    hash_table_remove(&dentries, &index, 1);
363
    hash_table_remove(&dentries, &index, 1);
296
 
364
 
-
 
365
    hash_table_destroy(&dentry->names);
-
 
366
 
297
    if (dentry->type == TMPFS_FILE)
367
    if (dentry->type == TMPFS_FILE)
298
        free(dentry->data);
368
        free(dentry->data);
299
    free(dentry);
369
    free(dentry);
300
}
370
}
301
 
371
 
Line 362... Line 432...
362
            ipc_answer_0(callid, ENOENT);
432
            ipc_answer_0(callid, ENOENT);
363
            ipc_answer_1(rid, ENOENT, 0);
433
            ipc_answer_1(rid, ENOENT, 0);
364
            return;
434
            return;
365
        }
435
        }
366
 
436
 
-
 
437
        unsigned long key = (unsigned long) dentry;
-
 
438
        link_t *hlp = hash_table_find(&cur->names, &key);
-
 
439
        assert(hlp);
-
 
440
        tmpfs_name_t *namep = hash_table_get_instance(hlp, tmpfs_name_t,
-
 
441
            link);
-
 
442
 
367
        (void) ipc_data_read_finalize(callid, cur->name,
443
        (void) ipc_data_read_finalize(callid, namep->name,
368
            strlen(cur->name) + 1);
444
            strlen(namep->name) + 1);
369
        bytes = 1;
445
        bytes = 1;
370
    }
446
    }
371
 
447
 
372
    /*
448
    /*
373
     * Answer the VFS_READ call.
449
     * Answer the VFS_READ call.