Changeset b8b23c8 in mainline


Ignore:
Timestamp:
2008-01-26T22:27:34Z (17 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1fe186f
Parents:
9415601
Message:

More elegant, flexible and complete version of tmpfs_lookup.

Location:
uspace
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/libc/include/errno.h

    r9415601 rb8b23c8  
    3838#include <kernel/errno.h>
    3939
     40#define ENAMETOOLONG    (-256)
     41#define EISDIR          (-257)
     42#define ENOTDIR         (-258)
     43#define ENOSPC          (-259)
     44#define EEXIST          (-260)
     45
    4046#endif
    4147
  • uspace/srv/fs/tmpfs/tmpfs_ops.c

    r9415601 rb8b23c8  
    4646#include <string.h>
    4747#include <stdio.h>
     48#include <dirent.h>
    4849#include <assert.h>
    4950#include <sys/types.h>
     
    199200 *
    200201 * @param dentry        Directory entry to compare the path component with.
    201  * @param start         Index into PLB where the path component starts.
    202  * @param last          Index of the last character of the path in PLB.
     202 * @param component     Array of characters holding component name.
    203203 *
    204  * @return              Zero on failure or delta such that (index + delta) %
    205  *                      PLB_SIZE points to the first unprocessed character in
    206  *                      PLB which comprises the path.
     204 * @return              True on match, false otherwise.
    207205 */
    208 static unsigned match_path_component(tmpfs_dentry_t *dentry, unsigned start,
    209     unsigned last)
    210 {
    211         int i, j;
    212         size_t namelen;
    213 
    214         namelen = strlen(dentry->name);
    215 
    216         if (last < start)
    217                 last += PLB_SIZE;
    218 
    219         for (i = 0, j = start; i < namelen && j <= last; i++, j++) {
    220                 if (dentry->name[i] != PLB_GET_CHAR(j))
    221                         return 0;
    222         }
    223        
    224         if (i != namelen)
    225                 return 0;
    226         if (j < last && PLB_GET_CHAR(j) != '/')
    227                 return 0;
    228         if (j == last)
    229                 return 0;
    230        
    231         return (j - start);
     206static bool match_component(tmpfs_dentry_t *dentry, const char *component)
     207{
     208        return !strcmp(dentry->name, component);
     209}
     210
     211static unsigned long create_node(tmpfs_dentry_t *dentry,
     212    const char *component, int lflag)
     213{
     214        return 0;
     215}
     216
     217static int destroy_component(tmpfs_dentry_t *dentry)
     218{
     219        return EPERM;
    232220}
    233221
     
    242230                last += PLB_SIZE;
    243231
     232        /*
     233         * Initialize TMPFS.
     234         */
    244235        if (!root && !tmpfs_init()) {
    245236                ipc_answer_0(rid, ENOMEM);
     
    250241        tmpfs_dentry_t *dcur = root;
    251242
    252         bool hit = true;
    253        
    254243        if (PLB_GET_CHAR(next) == '/')
    255244                next++;         /* eat slash */
    256245       
     246        char component[NAME_MAX + 1];
     247        int len = 0;
    257248        while (next <= last) {
    258                 unsigned delta;
    259                 hit = false;
    260                 do {
    261                         delta = match_path_component(dtmp, next, last);
    262                         if (!delta) {
    263                                 dtmp = dtmp->sibling;
    264                         } else {
    265                                 hit = true;
    266                                 next += delta;
    267                                 next++;         /* eat slash */
    268                                 dcur = dtmp;
    269                                 dtmp = dtmp->child;
    270                         }       
    271                 } while (delta == 0 && dtmp);
    272                 if (!hit) {
    273                         ipc_answer_3(rid, ENOENT, tmpfs_reg.fs_handle,
    274                             dev_handle, dcur->index);
     249
     250                /* collect the component */
     251                if (PLB_GET_CHAR(next) != '/') {
     252                        if (len + 1 == NAME_MAX) {
     253                                /* comopnent length overflow */
     254                                ipc_answer_0(rid, ENAMETOOLONG);
     255                                return;
     256                        }
     257                        component[len++] = PLB_GET_CHAR(next);
     258                        next++; /* process next character */
     259                        if (next <= last)
     260                                continue;
     261                }
     262
     263                assert(len);
     264                component[len] = '\0';
     265                next++;         /* eat slash */
     266                len = 0;
     267
     268                /* match the component */
     269                while (dtmp && !match_component(dtmp, component))
     270                        dtmp = dtmp->sibling;
     271
     272                /* handle miss: match amongst siblings */
     273                if (!dtmp) {
     274                        if ((next > last) && (lflag & L_CREATE)) {
     275                                /* no components left and L_CREATE specified */
     276                                if (dcur->type != TMPFS_DIRECTORY) {
     277                                        ipc_answer_0(rid, ENOTDIR);
     278                                        return;
     279                                }
     280                                unsigned long index = create_node(dcur,
     281                                    component, lflag);
     282                                if (index) {
     283                                        ipc_answer_4(rid, EOK,
     284                                            tmpfs_reg.fs_handle, dev_handle,
     285                                            index, 0);
     286                                } else {
     287                                        ipc_answer_0(rid, ENOSPC);
     288                                }
     289                                return;
     290                        }
     291                        ipc_answer_0(rid, ENOENT);
    275292                        return;
    276293                }
     294
     295                /* descent one level */
     296                dcur = dtmp;
     297                dtmp = dtmp->child;
     298
     299                /* handle miss: excessive components */
     300                if (!dtmp && next <= last) {
     301                        if (lflag & L_CREATE) {
     302                                if (dcur->type != TMPFS_DIRECTORY) {
     303                                        ipc_answer_0(rid, ENOTDIR);
     304                                        return;
     305                                }
     306
     307                                /* collect next component */
     308                                while (next <= last) {
     309                                        if (PLB_GET_CHAR(next) == '/') {
     310                                                /* more than one component */
     311                                                ipc_answer_0(rid, ENOENT);
     312                                                return;
     313                                        }
     314                                        if (len + 1 == NAME_MAX) {
     315                                                /* component length overflow */
     316                                                ipc_answer_0(rid, ENAMETOOLONG);
     317                                                return;
     318                                        }
     319                                        component[len++] = PLB_GET_CHAR(next);
     320                                        next++; /* process next character */
     321                                }
     322                                assert(len);
     323                                component[len] = '\0';
     324                                len = 0;
     325                               
     326                                unsigned long index;
     327                                index = create_node(dcur, component, lflag);
     328                                if (index) {
     329                                        ipc_answer_4(rid, EOK,
     330                                            tmpfs_reg.fs_handle, dev_handle,
     331                                            index, 0);
     332                                } else {
     333                                        ipc_answer_0(rid, ENOSPC);
     334                                }
     335                                return;
     336                        }
     337                        ipc_answer_0(rid, ENOENT);
     338                        return;
     339                }
     340       
     341        }
     342
     343        /* handle hit */
     344        if (lflag & L_DESTROY) {
     345                int res = destroy_component(dcur);
     346                ipc_answer_0(rid, res);
     347                return;
     348        }
     349        if ((lflag & (L_CREATE | L_EXCLUSIVE)) == (L_CREATE | L_EXCLUSIVE)) {
     350                ipc_answer_0(rid, EEXIST);
     351                return;
     352        }
     353        if ((lflag & L_FILE) && (dcur->type != TMPFS_FILE)) {
     354                ipc_answer_0(rid, EISDIR);
     355                return;
     356        }
     357        if ((lflag & L_DIRECTORY) && (dcur->type != TMPFS_DIRECTORY)) {
     358                ipc_answer_0(rid, ENOTDIR);
     359                return;
    277360        }
    278361
Note: See TracChangeset for help on using the changeset viewer.