Subversion Repositories HelenOS

Rev

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

Rev 4306 Rev 4357
Line 66... Line 66...
66
/*
66
/*
67
 * Implementation of the libfs interface.
67
 * Implementation of the libfs interface.
68
 */
68
 */
69
 
69
 
70
/* Forward declarations of static functions. */
70
/* Forward declarations of static functions. */
71
static void *tmpfs_match(void *, const char *);
71
static fs_node_t *tmpfs_match(fs_node_t *, const char *);
72
static void *tmpfs_node_get(dev_handle_t, fs_index_t);
72
static fs_node_t *tmpfs_node_get(dev_handle_t, fs_index_t);
73
static void tmpfs_node_put(void *);
73
static void tmpfs_node_put(fs_node_t *);
74
static void *tmpfs_create_node(dev_handle_t, int);
74
static fs_node_t *tmpfs_create_node(dev_handle_t, int);
75
static int tmpfs_link_node(void *, void *, const char *);
75
static int tmpfs_link_node(fs_node_t *, fs_node_t *, const char *);
76
static int tmpfs_unlink_node(void *, void *);
76
static int tmpfs_unlink_node(fs_node_t *, fs_node_t *);
77
static int tmpfs_destroy_node(void *);
77
static int tmpfs_destroy_node(fs_node_t *);
78
 
78
 
79
/* Implementation of helper functions. */
79
/* Implementation of helper functions. */
80
static fs_index_t tmpfs_index_get(void *nodep)
80
static fs_index_t tmpfs_index_get(fs_node_t *fn)
81
{
81
{
82
    return ((tmpfs_dentry_t *) nodep)->index;
82
    return TMPFS_NODE(fn)->index;
83
}
83
}
84
 
84
 
85
static size_t tmpfs_size_get(void *nodep)
85
static size_t tmpfs_size_get(fs_node_t *fn)
86
{
86
{
87
    return ((tmpfs_dentry_t *) nodep)->size;
87
    return TMPFS_NODE(fn)->size;
88
}
88
}
89
 
89
 
90
static unsigned tmpfs_lnkcnt_get(void *nodep)
90
static unsigned tmpfs_lnkcnt_get(fs_node_t *fn)
91
{
91
{
92
    return ((tmpfs_dentry_t *) nodep)->lnkcnt;
92
    return TMPFS_NODE(fn)->lnkcnt;
93
}
93
}
94
 
94
 
95
static bool tmpfs_has_children(void *nodep)
95
static bool tmpfs_has_children(fs_node_t *fn)
96
{
96
{
97
    return ((tmpfs_dentry_t *) nodep)->child != NULL;
97
    return TMPFS_NODE(fn)->child != NULL;
98
}
98
}
99
 
99
 
100
static void *tmpfs_root_get(dev_handle_t dev_handle)
100
static fs_node_t *tmpfs_root_get(dev_handle_t dev_handle)
101
{
101
{
102
    return tmpfs_node_get(dev_handle, TMPFS_SOME_ROOT);
102
    return tmpfs_node_get(dev_handle, TMPFS_SOME_ROOT);
103
}
103
}
104
 
104
 
105
static char tmpfs_plb_get_char(unsigned pos)
105
static char tmpfs_plb_get_char(unsigned pos)
106
{
106
{
107
    return tmpfs_reg.plb_ro[pos % PLB_SIZE];
107
    return tmpfs_reg.plb_ro[pos % PLB_SIZE];
108
}
108
}
109
 
109
 
110
static bool tmpfs_is_directory(void *nodep)
110
static bool tmpfs_is_directory(fs_node_t *fn)
111
{
111
{
112
    return ((tmpfs_dentry_t *) nodep)->type == TMPFS_DIRECTORY;
112
    return TMPFS_NODE(fn)->type == TMPFS_DIRECTORY;
113
}
113
}
114
 
114
 
115
static bool tmpfs_is_file(void *nodep)
115
static bool tmpfs_is_file(fs_node_t *fn)
116
{
116
{
117
    return ((tmpfs_dentry_t *) nodep)->type == TMPFS_FILE;
117
    return TMPFS_NODE(fn)->type == TMPFS_FILE;
118
}
118
}
119
 
119
 
120
/** libfs operations */
120
/** libfs operations */
121
libfs_ops_t tmpfs_libfs_ops = {
121
libfs_ops_t tmpfs_libfs_ops = {
122
    .match = tmpfs_match,
122
    .match = tmpfs_match,
Line 211... Line 211...
211
    link_initialize(&namep->link);
211
    link_initialize(&namep->link);
212
}
212
}
213
 
213
 
214
static bool tmpfs_dentry_initialize(tmpfs_dentry_t *dentry)
214
static bool tmpfs_dentry_initialize(tmpfs_dentry_t *dentry)
215
{
215
{
-
 
216
    dentry->bp = NULL;
216
    dentry->index = 0;
217
    dentry->index = 0;
217
    dentry->dev_handle = 0;
218
    dentry->dev_handle = 0;
218
    dentry->sibling = NULL;
219
    dentry->sibling = NULL;
219
    dentry->child = NULL;
220
    dentry->child = NULL;
220
    dentry->type = TMPFS_NONE;
221
    dentry->type = TMPFS_NONE;
Line 234... Line 235...
234
    return true;
235
    return true;
235
}
236
}
236
 
237
 
237
static bool tmpfs_instance_init(dev_handle_t dev_handle)
238
static bool tmpfs_instance_init(dev_handle_t dev_handle)
238
{
239
{
239
    tmpfs_dentry_t *root;
240
    fs_node_t *rfn;
240
   
241
   
241
    root = (tmpfs_dentry_t *) tmpfs_create_node(dev_handle, L_DIRECTORY);
242
    rfn = tmpfs_create_node(dev_handle, L_DIRECTORY);
242
    if (!root)
243
    if (!rfn)
243
        return false;
244
        return false;
244
    root->lnkcnt = 0;   /* FS root is not linked */
245
    TMPFS_NODE(rfn)->lnkcnt = 0;    /* FS root is not linked */
245
    return true;
246
    return true;
246
}
247
}
247
 
248
 
248
/** Compare one component of path to a directory entry.
249
/** Compare one component of path to a directory entry.
249
 *
250
 *
Line 262... Line 263...
262
    assert(hlp);
263
    assert(hlp);
263
    tmpfs_name_t *namep = hash_table_get_instance(hlp, tmpfs_name_t, link);
264
    tmpfs_name_t *namep = hash_table_get_instance(hlp, tmpfs_name_t, link);
264
    return !str_cmp(namep->name, component);
265
    return !str_cmp(namep->name, component);
265
}
266
}
266
 
267
 
267
void *tmpfs_match(void *prnt, const char *component)
268
fs_node_t *tmpfs_match(fs_node_t *pfn, const char *component)
268
{
269
{
269
    tmpfs_dentry_t *parentp = (tmpfs_dentry_t *) prnt;
270
    tmpfs_dentry_t *parentp = TMPFS_NODE(pfn);
270
    tmpfs_dentry_t *childp = parentp->child;
271
    tmpfs_dentry_t *childp = parentp->child;
271
 
272
 
272
    while (childp && !tmpfs_match_one(parentp, childp, component))
273
    while (childp && !tmpfs_match_one(parentp, childp, component))
273
        childp = childp->sibling;
274
        childp = childp->sibling;
274
 
275
 
275
    return (void *) childp;
276
    return FS_NODE(childp);
276
}
277
}
277
 
278
 
278
void *
-
 
279
tmpfs_node_get(dev_handle_t dev_handle, fs_index_t index)
279
fs_node_t *tmpfs_node_get(dev_handle_t dev_handle, fs_index_t index)
280
{
280
{
281
    unsigned long key[] = {
281
    unsigned long key[] = {
282
        [DENTRIES_KEY_INDEX] = index,
282
        [DENTRIES_KEY_INDEX] = index,
283
        [DENTRIES_KEY_DEV] = dev_handle
283
        [DENTRIES_KEY_DEV] = dev_handle
284
    };
284
    };
285
    link_t *lnk = hash_table_find(&dentries, key);
285
    link_t *lnk = hash_table_find(&dentries, key);
286
    if (!lnk)
286
    if (!lnk)
287
        return NULL;
287
        return NULL;
288
    return hash_table_get_instance(lnk, tmpfs_dentry_t, dh_link);
288
    return FS_NODE(hash_table_get_instance(lnk, tmpfs_dentry_t, dh_link));
289
}
289
}
290
 
290
 
291
void tmpfs_node_put(void *node)
291
void tmpfs_node_put(fs_node_t *fn)
292
{
292
{
293
    /* nothing to do */
293
    /* nothing to do */
294
}
294
}
295
 
295
 
296
void *tmpfs_create_node(dev_handle_t dev_handle, int lflag)
296
fs_node_t *tmpfs_create_node(dev_handle_t dev_handle, int lflag)
297
{
297
{
298
    assert((lflag & L_FILE) ^ (lflag & L_DIRECTORY));
298
    assert((lflag & L_FILE) ^ (lflag & L_DIRECTORY));
299
 
299
 
-
 
300
    fs_node_t *fn = malloc(sizeof(fs_node_t));
-
 
301
    if (!fn)
-
 
302
        return NULL;
-
 
303
   
300
    tmpfs_dentry_t *node = malloc(sizeof(tmpfs_dentry_t));
304
    tmpfs_dentry_t *node = malloc(sizeof(tmpfs_dentry_t));
301
    if (!node)
305
    if (!node) {
-
 
306
        free(fn);
302
        return NULL;
307
        return NULL;
303
 
308
    }
304
    if (!tmpfs_dentry_initialize(node)) {
309
    if (!tmpfs_dentry_initialize(node)) {
-
 
310
        free(fn);
305
        free(node);
311
        free(node);
306
        return NULL;
312
        return NULL;
307
    }
313
    }
-
 
314
    fn->data = node;
-
 
315
    node->bp = fn;  /* establish the back pointer */
308
    if (!tmpfs_root_get(dev_handle))
316
    if (!tmpfs_root_get(dev_handle))
309
        node->index = TMPFS_SOME_ROOT;
317
        node->index = TMPFS_SOME_ROOT;
310
    else
318
    else
311
        node->index = tmpfs_next_index++;
319
        node->index = tmpfs_next_index++;
312
    node->dev_handle = dev_handle;
320
    node->dev_handle = dev_handle;
Line 319... Line 327...
319
    unsigned long key[] = {
327
    unsigned long key[] = {
320
        [DENTRIES_KEY_INDEX] = node->index,
328
        [DENTRIES_KEY_INDEX] = node->index,
321
        [DENTRIES_KEY_DEV] = node->dev_handle
329
        [DENTRIES_KEY_DEV] = node->dev_handle
322
    };
330
    };
323
    hash_table_insert(&dentries, key, &node->dh_link);
331
    hash_table_insert(&dentries, key, &node->dh_link);
324
    return (void *) node;
332
    return fn;
325
}
333
}
326
 
334
 
327
int tmpfs_link_node(void *prnt, void *chld, const char *nm)
335
int tmpfs_link_node(fs_node_t *pfn, fs_node_t *cfn, const char *nm)
328
{
336
{
329
    tmpfs_dentry_t *parentp = (tmpfs_dentry_t *) prnt;
337
    tmpfs_dentry_t *parentp = TMPFS_NODE(pfn);
330
    tmpfs_dentry_t *childp = (tmpfs_dentry_t *) chld;
338
    tmpfs_dentry_t *childp = TMPFS_NODE(cfn);
331
 
339
 
332
    assert(parentp->type == TMPFS_DIRECTORY);
340
    assert(parentp->type == TMPFS_DIRECTORY);
333
 
341
 
334
    tmpfs_name_t *namep = malloc(sizeof(tmpfs_name_t));
342
    tmpfs_name_t *namep = malloc(sizeof(tmpfs_name_t));
335
    if (!namep)
343
    if (!namep)
Line 360... Line 368...
360
    }
368
    }
361
 
369
 
362
    return EOK;
370
    return EOK;
363
}
371
}
364
 
372
 
365
int tmpfs_unlink_node(void *prnt, void *chld)
373
int tmpfs_unlink_node(fs_node_t *pfn, fs_node_t *cfn)
366
{
374
{
367
    tmpfs_dentry_t *parentp = (tmpfs_dentry_t *)prnt;
375
    tmpfs_dentry_t *parentp = TMPFS_NODE(pfn);
368
    tmpfs_dentry_t *childp = (tmpfs_dentry_t *)chld;
376
    tmpfs_dentry_t *childp = TMPFS_NODE(cfn);
369
 
377
 
370
    if (!parentp)
378
    if (!parentp)
371
        return EBUSY;
379
        return EBUSY;
372
 
380
 
373
    if (childp->child)
381
    if (childp->child)
Line 390... Line 398...
390
    childp->lnkcnt--;
398
    childp->lnkcnt--;
391
 
399
 
392
    return EOK;
400
    return EOK;
393
}
401
}
394
 
402
 
395
int tmpfs_destroy_node(void *nodep)
403
int tmpfs_destroy_node(fs_node_t *fn)
396
{
404
{
397
    tmpfs_dentry_t *dentry = (tmpfs_dentry_t *) nodep;
405
    tmpfs_dentry_t *dentry = TMPFS_NODE(fn);
398
   
406
   
399
    assert(!dentry->lnkcnt);
407
    assert(!dentry->lnkcnt);
400
    assert(!dentry->child);
408
    assert(!dentry->child);
401
    assert(!dentry->sibling);
409
    assert(!dentry->sibling);
402
 
410
 
Line 408... Line 416...
408
 
416
 
409
    hash_table_destroy(&dentry->names);
417
    hash_table_destroy(&dentry->names);
410
 
418
 
411
    if (dentry->type == TMPFS_FILE)
419
    if (dentry->type == TMPFS_FILE)
412
        free(dentry->data);
420
        free(dentry->data);
-
 
421
    free(dentry->bp);
413
    free(dentry);
422
    free(dentry);
414
    return EOK;
423
    return EOK;
415
}
424
}
416
 
425
 
417
void tmpfs_mounted(ipc_callid_t rid, ipc_call_t *request)
426
void tmpfs_mounted(ipc_callid_t rid, ipc_call_t *request)
Line 444... Line 453...
444
    if (!tmpfs_instance_init(dev_handle)) {
453
    if (!tmpfs_instance_init(dev_handle)) {
445
        ipc_answer_0(rid, ENOMEM);
454
        ipc_answer_0(rid, ENOMEM);
446
        return;
455
        return;
447
    }
456
    }
448
 
457
 
449
    tmpfs_dentry_t *root = tmpfs_root_get(dev_handle);
458
    tmpfs_dentry_t *root = TMPFS_NODE(tmpfs_root_get(dev_handle));
450
    if (str_cmp(opts, "restore") == 0) {
459
    if (str_cmp(opts, "restore") == 0) {
451
        if (tmpfs_restore(dev_handle))
460
        if (tmpfs_restore(dev_handle))
452
            ipc_answer_3(rid, EOK, root->index, root->size,
461
            ipc_answer_3(rid, EOK, root->index, root->size,
453
                root->lnkcnt);
462
                root->lnkcnt);
454
        else
463
        else
Line 670... Line 679...
670
        ipc_answer_0(rid, ENOENT);
679
        ipc_answer_0(rid, ENOENT);
671
        return;
680
        return;
672
    }
681
    }
673
    tmpfs_dentry_t *dentry = hash_table_get_instance(hlp, tmpfs_dentry_t,
682
    tmpfs_dentry_t *dentry = hash_table_get_instance(hlp, tmpfs_dentry_t,
674
        dh_link);
683
        dh_link);
675
    rc = tmpfs_destroy_node(dentry);
684
    rc = tmpfs_destroy_node(FS_NODE(dentry));
676
    ipc_answer_0(rid, rc);
685
    ipc_answer_0(rid, rc);
677
}
686
}
678
 
687
 
679
/**
688
/**
680
 * @}
689
 * @}