Changeset 2c448fb in mainline for uspace/srv


Ignore:
Timestamp:
2008-02-27T22:49:48Z (17 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
7fe1f75
Parents:
56976a17
Message:

Move the core lookup logic from TMPFS to libfs.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/fs/tmpfs/tmpfs_ops.c

    r56976a17 r2c448fb  
    4646#include <string.h>
    4747#include <stdio.h>
    48 #include <dirent.h>
    4948#include <assert.h>
    5049#include <sys/types.h>
    5150#include <libadt/hash_table.h>
    5251#include <as.h>
     52#include <libfs.h>
    5353
    5454#define min(a, b)               ((a) < (b) ? (a) : (b))
    5555#define max(a, b)               ((a) > (b) ? (a) : (b))
    5656
    57 #define PLB_GET_CHAR(i)         (tmpfs_reg.plb_ro[(i) % PLB_SIZE])
    58 
    5957#define DENTRIES_BUCKETS        256
    6058
    61 #define TMPFS_GET_INDEX(x)      (((tmpfs_dentry_t *)(x))->index)
    62 #define TMPFS_GET_LNKCNT(x)     1
     59/*
     60 * For now, we don't distinguish between different dev_handles/instances. All
     61 * requests resolve to the only instance, rooted in the following variable.
     62 */
     63static tmpfs_dentry_t *root;
     64
     65/*
     66 * Implementation of the libfs interface.
     67 */
    6368
    6469/* Forward declarations of static functions. */
    65 static void *create_node(int);
    66 static bool link_node(void *, void *, const char *);
    67 static int unlink_node(void *);
    68 static void destroy_node(void *);
     70static bool tmpfs_match(void *, const char *);
     71static void *tmpfs_create_node(int);
     72static bool tmpfs_link_node(void *, void *, const char *);
     73static int tmpfs_unlink_node(void *);
     74static void tmpfs_destroy_node(void *);
     75
     76/* Implementation of helper functions. */
     77static unsigned long tmpfs_index_get(void *nodep)
     78{
     79        return ((tmpfs_dentry_t *) nodep)->index;
     80}
     81
     82static unsigned long tmpfs_size_get(void *nodep)
     83{
     84        return ((tmpfs_dentry_t *) nodep)->size;
     85}
     86
     87static unsigned tmpfs_lnkcnt_get(void *nodep)
     88{
     89        return 1;
     90}
     91
     92static void *tmpfs_child_get(void *nodep)
     93{
     94        return ((tmpfs_dentry_t *) nodep)->child;
     95}
     96
     97static void *tmpfs_sibling_get(void *nodep)
     98{
     99        return ((tmpfs_dentry_t *) nodep)->sibling;
     100}
     101
     102static void *tmpfs_root_get(void)
     103{
     104        return root;
     105}
     106
     107static char tmpfs_plb_get_char(unsigned pos)
     108{
     109        return tmpfs_reg.plb_ro[pos % PLB_SIZE];
     110}
     111
     112static bool tmpfs_is_directory(void *nodep)
     113{
     114        return ((tmpfs_dentry_t *) nodep)->type == TMPFS_DIRECTORY;
     115}
     116
     117static bool tmpfs_is_file(void *nodep)
     118{
     119        return ((tmpfs_dentry_t *) nodep)->type == TMPFS_FILE;
     120}
     121
     122/** libfs operations */
     123libfs_ops_t tmpfs_libfs_ops = {
     124        .match = tmpfs_match,
     125        .create = tmpfs_create_node,
     126        .destroy = tmpfs_destroy_node,
     127        .link = tmpfs_link_node,
     128        .unlink = tmpfs_unlink_node,
     129        .index_get = tmpfs_index_get,
     130        .size_get = tmpfs_size_get,
     131        .lnkcnt_get = tmpfs_lnkcnt_get,
     132        .child_get = tmpfs_child_get,
     133        .sibling_get = tmpfs_sibling_get,
     134        .root_get = tmpfs_root_get,
     135        .plb_get_char = tmpfs_plb_get_char,
     136        .is_directory = tmpfs_is_directory,
     137        .is_file = tmpfs_is_file
     138};
    69139
    70140/** Hash table of all directory entries. */
    71141hash_table_t dentries;
    72142
     143/* Implementation of hash table interface. */
    73144static hash_index_t dentries_hash(unsigned long *key)
    74145{
     
    110181}
    111182
    112 /*
    113  * For now, we don't distinguish between different dev_handles/instances. All
    114  * requests resolve to the only instance, rooted in the following variable.
    115  */
    116 static tmpfs_dentry_t *root;
    117 
    118183static bool tmpfs_init(void)
    119184{
    120185        if (!hash_table_create(&dentries, DENTRIES_BUCKETS, 1, &dentries_ops))
    121186                return false;
    122         root = (tmpfs_dentry_t *) create_node(L_DIRECTORY);
     187        root = (tmpfs_dentry_t *) tmpfs_create_node(L_DIRECTORY);
    123188        return root != NULL;
    124189}
     
    131196 * @return              True on match, false otherwise.
    132197 */
    133 static bool match_component(void *nodep, const char *component)
     198bool tmpfs_match(void *nodep, const char *component)
    134199{
    135200        tmpfs_dentry_t *dentry = (tmpfs_dentry_t *) nodep;
     
    138203}
    139204
    140 void *create_node(int lflag)
     205void *tmpfs_create_node(int lflag)
    141206{
    142207        assert((lflag & L_FILE) ^ (lflag & L_DIRECTORY));
     
    158223}
    159224
    160 bool link_node(void *prnt, void *chld, const char *nm)
     225bool tmpfs_link_node(void *prnt, void *chld, const char *nm)
    161226{
    162227        tmpfs_dentry_t *parentp = (tmpfs_dentry_t *) prnt;
     
    186251}
    187252
    188 int unlink_node(void *nodeptr)
     253int tmpfs_unlink_node(void *nodeptr)
    189254{
    190255        tmpfs_dentry_t *dentry = (tmpfs_dentry_t *)nodeptr;
     
    214279}
    215280
    216 void destroy_node(void *nodep)
     281void tmpfs_destroy_node(void *nodep)
    217282{
    218283        tmpfs_dentry_t *dentry = (tmpfs_dentry_t *) nodep;
     
    231296void tmpfs_lookup(ipc_callid_t rid, ipc_call_t *request)
    232297{
    233         unsigned next = IPC_GET_ARG1(*request);
    234         unsigned last = IPC_GET_ARG2(*request);
    235         int dev_handle = IPC_GET_ARG3(*request);
    236         int lflag = IPC_GET_ARG4(*request);
    237 
    238         if (last < next)
    239                 last += PLB_SIZE;
    240 
    241         /*
    242          * Initialize TMPFS.
    243          */
     298        /* Initialize TMPFS. */
    244299        if (!root && !tmpfs_init()) {
    245300                ipc_answer_0(rid, ENOMEM);
    246301                return;
    247302        }
    248 
    249         tmpfs_dentry_t *dtmp = root->child;
    250         tmpfs_dentry_t *dcur = root;
    251 
    252         if (PLB_GET_CHAR(next) == '/')
    253                 next++;         /* eat slash */
    254        
    255         char component[NAME_MAX + 1];
    256         int len = 0;
    257         while (dtmp && next <= last) {
    258 
    259                 /* collect the component */
    260                 if (PLB_GET_CHAR(next) != '/') {
    261                         if (len + 1 == NAME_MAX) {
    262                                 /* comopnent length overflow */
    263                                 ipc_answer_0(rid, ENAMETOOLONG);
    264                                 return;
    265                         }
    266                         component[len++] = PLB_GET_CHAR(next);
    267                         next++; /* process next character */
    268                         if (next <= last)
    269                                 continue;
    270                 }
    271 
    272                 assert(len);
    273                 component[len] = '\0';
    274                 next++;         /* eat slash */
    275                 len = 0;
    276 
    277                 /* match the component */
    278                 while (dtmp && !match_component(dtmp, component))
    279                         dtmp = dtmp->sibling;
    280 
    281                 /* handle miss: match amongst siblings */
    282                 if (!dtmp) {
    283                         if ((next > last) && (lflag & L_CREATE)) {
    284                                 /* no components left and L_CREATE specified */
    285                                 if (dcur->type != TMPFS_DIRECTORY) {
    286                                         ipc_answer_0(rid, ENOTDIR);
    287                                         return;
    288                                 }
    289                                 void *nodep = create_node(lflag);
    290                                 if (nodep) {
    291                                         if (!link_node(dcur, nodep,
    292                                             component)) {
    293                                                 destroy_node(nodep);
    294                                                 ipc_answer_0(rid, ENOSPC);
    295                                         } else {
    296                                                 ipc_answer_5(rid, EOK,
    297                                                     tmpfs_reg.fs_handle,
    298                                                     dev_handle,
    299                                                     TMPFS_GET_INDEX(nodep), 0,
    300                                                     TMPFS_GET_LNKCNT(nodep));
    301                                         }
    302                                 } else {
    303                                         ipc_answer_0(rid, ENOSPC);
    304                                 }
    305                                 return;
    306                         }
    307                         ipc_answer_0(rid, ENOENT);
    308                         return;
    309                 }
    310 
    311                 /* descend one level */
    312                 dcur = dtmp;
    313                 dtmp = dtmp->child;
    314         }
    315 
    316         /* handle miss: excessive components */
    317         if (!dtmp && next <= last) {
    318                 if (lflag & L_CREATE) {
    319                         if (dcur->type != TMPFS_DIRECTORY) {
    320                                 ipc_answer_0(rid, ENOTDIR);
    321                                 return;
    322                         }
    323 
    324                         /* collect next component */
    325                         while (next <= last) {
    326                                 if (PLB_GET_CHAR(next) == '/') {
    327                                         /* more than one component */
    328                                         ipc_answer_0(rid, ENOENT);
    329                                         return;
    330                                 }
    331                                 if (len + 1 == NAME_MAX) {
    332                                         /* component length overflow */
    333                                         ipc_answer_0(rid, ENAMETOOLONG);
    334                                         return;
    335                                 }
    336                                 component[len++] = PLB_GET_CHAR(next);
    337                                 next++; /* process next character */
    338                         }
    339                         assert(len);
    340                         component[len] = '\0';
    341                         len = 0;
    342                                
    343                         void *nodep = create_node(lflag);
    344                         if (nodep) {
    345                                 if (!link_node(dcur, nodep, component)) {
    346                                         destroy_node(nodep);
    347                                         ipc_answer_0(rid, ENOSPC);
    348                                 } else {
    349                                         ipc_answer_5(rid, EOK,
    350                                             tmpfs_reg.fs_handle,
    351                                             dev_handle, TMPFS_GET_INDEX(nodep),
    352                                             0, TMPFS_GET_LNKCNT(nodep));
    353                                 }
    354                         } else {
    355                                 ipc_answer_0(rid, ENOSPC);
    356                         }
    357                         return;
    358                 }
    359                 ipc_answer_0(rid, ENOENT);
    360                 return;
    361         }
    362 
    363         /* handle hit */
    364         if (lflag & L_DESTROY) {
    365                 unsigned old_lnkcnt = TMPFS_GET_LNKCNT(dcur);
    366                 int res = unlink_node(dcur);
    367                 ipc_answer_5(rid, (ipcarg_t)res, tmpfs_reg.fs_handle,
    368                     dev_handle, dcur->index, dcur->size, old_lnkcnt);
    369                 return;
    370         }
    371         if ((lflag & (L_CREATE | L_EXCLUSIVE)) == (L_CREATE | L_EXCLUSIVE)) {
    372                 ipc_answer_0(rid, EEXIST);
    373                 return;
    374         }
    375         if ((lflag & L_FILE) && (dcur->type != TMPFS_FILE)) {
    376                 ipc_answer_0(rid, EISDIR);
    377                 return;
    378         }
    379         if ((lflag & L_DIRECTORY) && (dcur->type != TMPFS_DIRECTORY)) {
    380                 ipc_answer_0(rid, ENOTDIR);
    381                 return;
    382         }
    383 
    384         ipc_answer_5(rid, EOK, tmpfs_reg.fs_handle, dev_handle, dcur->index,
    385             dcur->size, TMPFS_GET_LNKCNT(dcur));
     303        libfs_lookup(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request);
    386304}
    387305
     
    562480        tmpfs_dentry_t *dentry = hash_table_get_instance(hlp, tmpfs_dentry_t,
    563481            dh_link);
    564         destroy_node(dentry);
     482        tmpfs_destroy_node(dentry);
    565483        ipc_answer_0(rid, EOK);
    566484}
Note: See TracChangeset for help on using the changeset viewer.