Changeset 2c448fb in mainline for uspace/lib/libfs/libfs.c


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/lib/libfs/libfs.c

    r56976a17 r2c448fb  
    11/*
    2  * Copyright (c) 2007 Jakub Jermar
     2 * Copyright (c) 2008 Jakub Jermar
    33 * All rights reserved.
    44 *
     
    4141#include <ipc/ipc.h>
    4242#include <as.h>
     43#include <assert.h>
     44#include <dirent.h>
    4345
    4446/** Register file system server.
     
    121123}
    122124
     125void libfs_lookup(libfs_ops_t *ops, int fs_handle, ipc_callid_t rid,
     126    ipc_call_t *request)
     127{
     128        unsigned next = IPC_GET_ARG1(*request);
     129        unsigned last = IPC_GET_ARG2(*request);
     130        int dev_handle = IPC_GET_ARG3(*request);
     131        int lflag = IPC_GET_ARG4(*request);
     132
     133        if (last < next)
     134                last += PLB_SIZE;
     135
     136        void *cur = ops->root_get();
     137        void *tmp = ops->child_get(cur);
     138
     139        if (ops->plb_get_char(next) == '/')
     140                next++;         /* eat slash */
     141       
     142        char component[NAME_MAX + 1];
     143        int len = 0;
     144        while (tmp && next <= last) {
     145
     146                /* collect the component */
     147                if (ops->plb_get_char(next) != '/') {
     148                        if (len + 1 == NAME_MAX) {
     149                                /* comopnent length overflow */
     150                                ipc_answer_0(rid, ENAMETOOLONG);
     151                                return;
     152                        }
     153                        component[len++] = ops->plb_get_char(next);
     154                        next++; /* process next character */
     155                        if (next <= last)
     156                                continue;
     157                }
     158
     159                assert(len);
     160                component[len] = '\0';
     161                next++;         /* eat slash */
     162                len = 0;
     163
     164                /* match the component */
     165                while (tmp && !ops->match(tmp, component))
     166                        tmp = ops->sibling_get(tmp);
     167
     168                /* handle miss: match amongst siblings */
     169                if (!tmp) {
     170                        if ((next > last) && (lflag & L_CREATE)) {
     171                                /* no components left and L_CREATE specified */
     172                                if (!ops->is_directory(cur)) {
     173                                        ipc_answer_0(rid, ENOTDIR);
     174                                        return;
     175                                }
     176                                void *nodep = ops->create(lflag);
     177                                if (nodep) {
     178                                        if (!ops->link(cur, nodep, component)) {
     179                                                ops->destroy(nodep);
     180                                                ipc_answer_0(rid, ENOSPC);
     181                                        } else {
     182                                                ipc_answer_5(rid, EOK,
     183                                                    fs_handle, dev_handle,
     184                                                    ops->index_get(nodep), 0,
     185                                                    ops->lnkcnt_get(nodep));
     186                                        }
     187                                } else {
     188                                        ipc_answer_0(rid, ENOSPC);
     189                                }
     190                                return;
     191                        }
     192                        ipc_answer_0(rid, ENOENT);
     193                        return;
     194                }
     195
     196                /* descend one level */
     197                cur = tmp;
     198                tmp = ops->child_get(tmp);
     199        }
     200
     201        /* handle miss: excessive components */
     202        if (!tmp && next <= last) {
     203                if (lflag & L_CREATE) {
     204                        if (!ops->is_directory(cur)) {
     205                                ipc_answer_0(rid, ENOTDIR);
     206                                return;
     207                        }
     208
     209                        /* collect next component */
     210                        while (next <= last) {
     211                                if (ops->plb_get_char(next) == '/') {
     212                                        /* more than one component */
     213                                        ipc_answer_0(rid, ENOENT);
     214                                        return;
     215                                }
     216                                if (len + 1 == NAME_MAX) {
     217                                        /* component length overflow */
     218                                        ipc_answer_0(rid, ENAMETOOLONG);
     219                                        return;
     220                                }
     221                                component[len++] = ops->plb_get_char(next);
     222                                next++; /* process next character */
     223                        }
     224                        assert(len);
     225                        component[len] = '\0';
     226                        len = 0;
     227                               
     228                        void *nodep = ops->create(lflag);
     229                        if (nodep) {
     230                                if (!ops->link(cur, nodep, component)) {
     231                                        ops->destroy(nodep);
     232                                        ipc_answer_0(rid, ENOSPC);
     233                                } else {
     234                                        ipc_answer_5(rid, EOK,
     235                                            fs_handle, dev_handle,
     236                                            ops->index_get(nodep), 0,
     237                                            ops->lnkcnt_get(nodep));
     238                                }
     239                        } else {
     240                                ipc_answer_0(rid, ENOSPC);
     241                        }
     242                        return;
     243                }
     244                ipc_answer_0(rid, ENOENT);
     245                return;
     246        }
     247
     248        /* handle hit */
     249        if (lflag & L_DESTROY) {
     250                unsigned old_lnkcnt = ops->lnkcnt_get(cur);
     251                int res = ops->unlink(cur);
     252                ipc_answer_5(rid, (ipcarg_t)res, fs_handle, dev_handle,
     253                    ops->index_get(cur), ops->size_get(cur), old_lnkcnt);
     254                return;
     255        }
     256        if ((lflag & (L_CREATE | L_EXCLUSIVE)) == (L_CREATE | L_EXCLUSIVE)) {
     257                ipc_answer_0(rid, EEXIST);
     258                return;
     259        }
     260        if ((lflag & L_FILE) && (ops->is_directory(cur))) {
     261                ipc_answer_0(rid, EISDIR);
     262                return;
     263        }
     264        if ((lflag & L_DIRECTORY) && (ops->is_file(cur))) {
     265                ipc_answer_0(rid, ENOTDIR);
     266                return;
     267        }
     268
     269        ipc_answer_5(rid, EOK, fs_handle, dev_handle, ops->index_get(cur),
     270            ops->size_get(cur), ops->lnkcnt_get(cur));
     271}
     272
    123273/** @}
    124274 */
Note: See TracChangeset for help on using the changeset viewer.