Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/libfs/libfs.c

    r1313ee9 r0143f72  
    11/*
    2  * Copyright (c) 2009 Jakub Jermar
     2 * Copyright (c) 2009 Jakub Jermar 
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup libfs
     29/** @addtogroup libfs 
    3030 * @{
    31  */
     31 */ 
    3232/**
    3333 * @file
    34  * Glue code which is common to all FS implementations.
    35  */
    36 
    37 #include "libfs.h"
     34 * Glue code which is commonod to all FS implementations.
     35 */
     36
     37#include "libfs.h" 
    3838#include "../../srv/vfs/vfs.h"
    3939#include <errno.h>
     
    4646#include <sys/stat.h>
    4747
    48 #define on_error(rc, action) \
    49         do { \
    50                 if ((rc) != EOK) \
    51                         action; \
    52         } while (0)
    53 
    54 #define combine_rc(rc1, rc2) \
    55         ((rc1) == EOK ? (rc2) : (rc1))
    56 
    57 #define answer_and_return(rid, rc) \
    58         do { \
    59                 ipc_answer_0((rid), (rc)); \
    60                 return; \
    61         } while (0)
    62 
    6348/** Register file system server.
    6449 *
     
    6752 * code.
    6853 *
    69  * @param vfs_phone Open phone for communication with VFS.
    70  * @param reg       File system registration structure. It will be
    71  *                  initialized by this function.
    72  * @param info      VFS info structure supplied by the file system
    73  *                  implementation.
    74  * @param conn      Connection fibril for handling all calls originating in
    75  *                  VFS.
    76  *
    77  * @return EOK on success or a non-zero error code on errror.
    78  *
     54 * @param vfs_phone     Open phone for communication with VFS.
     55 * @param reg           File system registration structure. It will be
     56 *                      initialized by this function.
     57 * @param info          VFS info structure supplied by the file system
     58 *                      implementation.
     59 * @param conn          Connection fibril for handling all calls originating in
     60 *                      VFS.
     61 *
     62 * @return              EOK on success or a non-zero error code on errror.
    7963 */
    8064int fs_register(int vfs_phone, fs_reg_t *reg, vfs_info_t *info,
     
    8872        ipc_call_t answer;
    8973        aid_t req = async_send_0(vfs_phone, VFS_IN_REGISTER, &answer);
    90        
     74
    9175        /*
    9276         * Send our VFS info structure to VFS.
    9377         */
    94         int rc = async_data_write_start(vfs_phone, info, sizeof(*info));
     78        int rc = ipc_data_write_start(vfs_phone, info, sizeof(*info));
    9579        if (rc != EOK) {
    9680                async_wait_for(req, NULL);
    9781                return rc;
    9882        }
    99        
     83
    10084        /*
    10185         * Ask VFS for callback connection.
    10286         */
    10387        ipc_connect_to_me(vfs_phone, 0, 0, 0, &reg->vfs_phonehash);
    104        
     88
    10589        /*
    10690         * Allocate piece of address space for PLB.
     
    11195                return ENOMEM;
    11296        }
    113        
     97
    11498        /*
    11599         * Request sharing the Path Lookup Buffer with VFS.
    116100         */
    117         rc = async_share_in_start_0_0(vfs_phone, reg->plb_ro, PLB_SIZE);
     101        rc = ipc_share_in_start_0_0(vfs_phone, reg->plb_ro, PLB_SIZE);
    118102        if (rc) {
    119103                async_wait_for(req, NULL);
     
    137121         */
    138122        async_set_client_connection(conn);
    139        
     123
    140124        return IPC_GET_RETVAL(answer);
    141125}
     
    155139        int res;
    156140        ipcarg_t rc;
    157        
     141
    158142        ipc_call_t call;
    159143        ipc_callid_t callid;
    160        
    161         /* Accept the phone */
     144
     145        /* accept the phone */
    162146        callid = async_get_call(&call);
    163147        int mountee_phone = (int)IPC_GET_ARG1(call);
    164148        if ((IPC_GET_METHOD(call) != IPC_M_CONNECTION_CLONE) ||
    165             (mountee_phone < 0)) {
     149            mountee_phone < 0) {
    166150                ipc_answer_0(callid, EINVAL);
    167151                ipc_answer_0(rid, EINVAL);
    168152                return;
    169153        }
    170        
    171         /* Acknowledge the mountee_phone */
    172         ipc_answer_0(callid, EOK);
    173        
    174         res = async_data_write_receive(&callid, NULL);
     154        ipc_answer_0(callid, EOK);      /* acknowledge the mountee_phone */
     155       
     156        res = ipc_data_write_receive(&callid, NULL);
    175157        if (!res) {
    176158                ipc_hangup(mountee_phone);
     
    179161                return;
    180162        }
    181        
    182         fs_node_t *fn;
    183         res = ops->node_get(&fn, mp_dev_handle, mp_fs_index);
    184         if ((res != EOK) || (!fn)) {
     163
     164        fs_node_t *fn = ops->node_get(mp_dev_handle, mp_fs_index);
     165        if (!fn) {
    185166                ipc_hangup(mountee_phone);
    186                 ipc_answer_0(callid, combine_rc(res, ENOENT));
    187                 ipc_answer_0(rid, combine_rc(res, ENOENT));
    188                 return;
    189         }
    190        
     167                ipc_answer_0(callid, ENOENT);
     168                ipc_answer_0(rid, ENOENT);
     169                return;
     170        }
     171
    191172        if (fn->mp_data.mp_active) {
    192173                ipc_hangup(mountee_phone);
    193                 (void) ops->node_put(fn);
     174                ops->node_put(fn);
    194175                ipc_answer_0(callid, EBUSY);
    195176                ipc_answer_0(rid, EBUSY);
    196177                return;
    197178        }
    198        
     179
    199180        rc = async_req_0_0(mountee_phone, IPC_M_CONNECT_ME);
    200         if (rc != EOK) {
     181        if (rc != 0) {
    201182                ipc_hangup(mountee_phone);
    202                 (void) ops->node_put(fn);
     183                ops->node_put(fn);
    203184                ipc_answer_0(callid, rc);
    204185                ipc_answer_0(rid, rc);
     
    218199                fn->mp_data.phone = mountee_phone;
    219200        }
    220        
    221201        /*
    222202         * Do not release the FS node so that it stays in memory.
     
    242222    ipc_call_t *request)
    243223{
    244         unsigned int first = IPC_GET_ARG1(*request);
    245         unsigned int last = IPC_GET_ARG2(*request);
    246         unsigned int next = first;
     224        unsigned first = IPC_GET_ARG1(*request);
     225        unsigned last = IPC_GET_ARG2(*request);
     226        unsigned next = first;
    247227        dev_handle_t dev_handle = IPC_GET_ARG3(*request);
    248228        int lflag = IPC_GET_ARG4(*request);
    249         fs_index_t index = IPC_GET_ARG5(*request);
     229        fs_index_t index = IPC_GET_ARG5(*request); /* when L_LINK specified */
    250230        char component[NAME_MAX + 1];
    251231        int len;
    252         int rc;
    253        
     232
    254233        if (last < next)
    255234                last += PLB_SIZE;
    256        
     235
    257236        fs_node_t *par = NULL;
    258         fs_node_t *cur = NULL;
     237        fs_node_t *cur = ops->root_get(dev_handle);
    259238        fs_node_t *tmp = NULL;
    260        
    261         rc = ops->root_get(&cur, dev_handle);
    262         on_error(rc, goto out_with_answer);
    263        
     239
    264240        if (cur->mp_data.mp_active) {
    265241                ipc_forward_slow(rid, cur->mp_data.phone, VFS_OUT_LOOKUP,
    266242                    next, last, cur->mp_data.dev_handle, lflag, index,
    267243                    IPC_FF_ROUTE_FROM_ME);
    268                 (void) ops->node_put(cur);
    269                 return;
    270         }
    271        
    272         /* Eat slash */
     244                ops->node_put(cur);
     245                return;
     246        }
     247
    273248        if (ops->plb_get_char(next) == '/')
    274                 next++;
    275        
    276         while (next <= last) {
    277                 bool has_children;
    278                
    279                 rc = ops->has_children(&has_children, cur);
    280                 on_error(rc, goto out_with_answer);
    281                 if (!has_children)
    282                         break;
    283                
    284                 /* Collect the component */
     249                next++;         /* eat slash */
     250       
     251        while (next <= last && ops->has_children(cur)) {
     252                /* collect the component */
    285253                len = 0;
    286                 while ((next <= last) && (ops->plb_get_char(next) != '/')) {
     254                while ((next <= last) &&  (ops->plb_get_char(next) != '/')) {
    287255                        if (len + 1 == NAME_MAX) {
    288                                 /* Component length overflow */
     256                                /* component length overflow */
    289257                                ipc_answer_0(rid, ENAMETOOLONG);
    290258                                goto out;
    291259                        }
    292260                        component[len++] = ops->plb_get_char(next);
    293                         /* Process next character */
    294                         next++;
     261                        next++; /* process next character */
    295262                }
    296                
     263
    297264                assert(len);
    298265                component[len] = '\0';
    299                 /* Eat slash */
    300                 next++;
    301                
    302                 /* Match the component */
    303                 rc = ops->match(&tmp, cur, component);
    304                 on_error(rc, goto out_with_answer);
    305                
    306                 if ((tmp) && (tmp->mp_data.mp_active)) {
     266                next++;         /* eat slash */
     267
     268                /* match the component */
     269                tmp = ops->match(cur, component);
     270                if (tmp && tmp->mp_data.mp_active) {
    307271                        if (next > last)
    308272                                next = last = first;
    309273                        else
    310274                                next--;
    311                        
     275                               
    312276                        ipc_forward_slow(rid, tmp->mp_data.phone,
    313277                            VFS_OUT_LOOKUP, next, last, tmp->mp_data.dev_handle,
    314278                            lflag, index, IPC_FF_ROUTE_FROM_ME);
    315                         (void) ops->node_put(cur);
    316                         (void) ops->node_put(tmp);
     279                        ops->node_put(cur);
     280                        ops->node_put(tmp);
    317281                        if (par)
    318                                 (void) ops->node_put(par);
     282                                ops->node_put(par);
    319283                        return;
    320284                }
    321                
    322                 /* Handle miss: match amongst siblings */
     285
     286                /* handle miss: match amongst siblings */
    323287                if (!tmp) {
    324288                        if (next <= last) {
    325                                 /* There are unprocessed components */
     289                                /* there are unprocessed components */
    326290                                ipc_answer_0(rid, ENOENT);
    327291                                goto out;
    328292                        }
    329                        
    330                         /* Miss in the last component */
    331                         if (lflag & (L_CREATE | L_LINK)) {
    332                                 /* Request to create a new link */
     293                        /* miss in the last component */
     294                        if (lflag & (L_CREATE | L_LINK)) {
     295                                /* request to create a new link */
    333296                                if (!ops->is_directory(cur)) {
    334297                                        ipc_answer_0(rid, ENOTDIR);
    335298                                        goto out;
    336299                                }
    337                                
    338300                                fs_node_t *fn;
    339301                                if (lflag & L_CREATE)
    340                                         rc = ops->create(&fn, dev_handle,
    341                                             lflag);
     302                                        fn = ops->create(dev_handle, lflag);
    342303                                else
    343                                         rc = ops->node_get(&fn, dev_handle,
     304                                        fn = ops->node_get(dev_handle,
    344305                                            index);
    345                                 on_error(rc, goto out_with_answer);
    346                                
    347306                                if (fn) {
     307                                        int rc;
     308
    348309                                        rc = ops->link(cur, fn, component);
    349310                                        if (rc != EOK) {
    350                                                 if (lflag & L_CREATE)
    351                                                         (void) ops->destroy(fn);
     311                                                if (lflag & L_CREATE) {
     312                                                        (void)ops->destroy(fn);
     313                                                }
    352314                                                ipc_answer_0(rid, rc);
    353315                                        } else {
     
    357319                                                    ops->size_get(fn),
    358320                                                    ops->lnkcnt_get(fn));
    359                                                 (void) ops->node_put(fn);
     321                                                ops->node_put(fn);
    360322                                        }
    361                                 } else
     323                                } else {
    362324                                        ipc_answer_0(rid, ENOSPC);
    363                                
     325                                }
    364326                                goto out;
    365                         }
    366                        
     327                        }
    367328                        ipc_answer_0(rid, ENOENT);
    368329                        goto out;
    369330                }
    370                
    371                 if (par) {
    372                         rc = ops->node_put(par);
    373                         on_error(rc, goto out_with_answer);
    374                 }
    375                
    376                 /* Descend one level */
     331
     332                if (par)
     333                        ops->node_put(par);
     334
     335                /* descend one level */
    377336                par = cur;
    378337                cur = tmp;
    379338                tmp = NULL;
    380339        }
    381        
    382         /* Handle miss: excessive components */
    383         if (next <= last) {
    384                 bool has_children;
    385                 rc = ops->has_children(&has_children, cur);
    386                 on_error(rc, goto out_with_answer);
    387                
    388                 if (has_children)
    389                         goto skip_miss;
    390                
     340
     341        /* handle miss: excessive components */
     342        if (next <= last && !ops->has_children(cur)) {
    391343                if (lflag & (L_CREATE | L_LINK)) {
    392344                        if (!ops->is_directory(cur)) {
     
    394346                                goto out;
    395347                        }
    396                        
    397                         /* Collect next component */
     348
     349                        /* collect next component */
    398350                        len = 0;
    399351                        while (next <= last) {
    400352                                if (ops->plb_get_char(next) == '/') {
    401                                         /* More than one component */
     353                                        /* more than one component */
    402354                                        ipc_answer_0(rid, ENOENT);
    403355                                        goto out;
    404356                                }
    405                                
    406357                                if (len + 1 == NAME_MAX) {
    407                                         /* Component length overflow */
     358                                        /* component length overflow */
    408359                                        ipc_answer_0(rid, ENAMETOOLONG);
    409360                                        goto out;
    410361                                }
    411                                
    412362                                component[len++] = ops->plb_get_char(next);
    413                                 /* Process next character */
    414                                 next++;
     363                                next++; /* process next character */
    415364                        }
    416                        
    417365                        assert(len);
    418366                        component[len] = '\0';
    419                        
     367                               
    420368                        fs_node_t *fn;
    421369                        if (lflag & L_CREATE)
    422                                 rc = ops->create(&fn, dev_handle, lflag);
     370                                fn = ops->create(dev_handle, lflag);
    423371                        else
    424                                 rc = ops->node_get(&fn, dev_handle, index);
    425                         on_error(rc, goto out_with_answer);
    426                        
     372                                fn = ops->node_get(dev_handle, index);
    427373                        if (fn) {
     374                                int rc;
     375
    428376                                rc = ops->link(cur, fn, component);
    429377                                if (rc != EOK) {
    430378                                        if (lflag & L_CREATE)
    431                                                 (void) ops->destroy(fn);
     379                                                (void)ops->destroy(fn);
    432380                                        ipc_answer_0(rid, rc);
    433381                                } else {
     
    437385                                            ops->size_get(fn),
    438386                                            ops->lnkcnt_get(fn));
    439                                         (void) ops->node_put(fn);
     387                                        ops->node_put(fn);
    440388                                }
    441                         } else
     389                        } else {
    442390                                ipc_answer_0(rid, ENOSPC);
    443                        
     391                        }
    444392                        goto out;
    445393                }
    446                
    447394                ipc_answer_0(rid, ENOENT);
    448395                goto out;
    449396        }
    450        
    451 skip_miss:
    452        
    453         /* Handle hit */
     397
     398        /* handle hit */
    454399        if (lflag & L_UNLINK) {
    455                 unsigned int old_lnkcnt = ops->lnkcnt_get(cur);
    456                 rc = ops->unlink(par, cur, component);
    457                 ipc_answer_5(rid, (ipcarg_t) rc, fs_handle, dev_handle,
     400                unsigned old_lnkcnt = ops->lnkcnt_get(cur);
     401                int res = ops->unlink(par, cur, component);
     402                ipc_answer_5(rid, (ipcarg_t)res, fs_handle, dev_handle,
    458403                    ops->index_get(cur), ops->size_get(cur), old_lnkcnt);
    459404                goto out;
    460405        }
    461        
    462406        if (((lflag & (L_CREATE | L_EXCLUSIVE)) == (L_CREATE | L_EXCLUSIVE)) ||
    463407            (lflag & L_LINK)) {
     
    465409                goto out;
    466410        }
    467        
    468411        if ((lflag & L_FILE) && (ops->is_directory(cur))) {
    469412                ipc_answer_0(rid, EISDIR);
    470413                goto out;
    471414        }
    472        
    473415        if ((lflag & L_DIRECTORY) && (ops->is_file(cur))) {
    474416                ipc_answer_0(rid, ENOTDIR);
    475417                goto out;
    476418        }
    477        
    478 out_with_answer:
    479        
    480         if (rc == EOK) {
    481                 if (lflag & L_OPEN)
    482                         rc = ops->node_open(cur);
    483                
    484                 ipc_answer_5(rid, rc, fs_handle, dev_handle,
    485                     ops->index_get(cur), ops->size_get(cur),
    486                     ops->lnkcnt_get(cur));
    487         } else
    488                 ipc_answer_0(rid, rc);
    489        
     419
     420        ipc_answer_5(rid, EOK, fs_handle, dev_handle, ops->index_get(cur),
     421            ops->size_get(cur), ops->lnkcnt_get(cur));
     422
    490423out:
    491        
    492424        if (par)
    493                 (void) ops->node_put(par);
    494        
     425                ops->node_put(par);
    495426        if (cur)
    496                 (void) ops->node_put(cur);
    497        
     427                ops->node_put(cur);
    498428        if (tmp)
    499                 (void) ops->node_put(tmp);
     429                ops->node_put(tmp);
    500430}
    501431
     
    505435        dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
    506436        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    507        
    508         fs_node_t *fn;
    509         int rc = ops->node_get(&fn, dev_handle, index);
    510         on_error(rc, answer_and_return(rid, rc));
    511        
     437        fs_node_t *fn = ops->node_get(dev_handle, index);
     438
    512439        ipc_callid_t callid;
    513440        size_t size;
    514         if ((!async_data_read_receive(&callid, &size)) ||
    515             (size != sizeof(struct stat))) {
    516                 ops->node_put(fn);
     441        if (!ipc_data_read_receive(&callid, &size) ||
     442            size != sizeof(struct stat)) {
    517443                ipc_answer_0(callid, EINVAL);
    518444                ipc_answer_0(rid, EINVAL);
    519445                return;
    520446        }
    521        
     447
    522448        struct stat stat;
    523449        memset(&stat, 0, sizeof(struct stat));
     
    526452        stat.dev_handle = dev_handle;
    527453        stat.index = index;
    528         stat.lnkcnt = ops->lnkcnt_get(fn);
     454        stat.lnkcnt = ops->lnkcnt_get(fn); 
    529455        stat.is_file = ops->is_file(fn);
    530         stat.is_directory = ops->is_directory(fn);
    531456        stat.size = ops->size_get(fn);
    532         stat.device = ops->device_get(fn);
    533        
    534         ops->node_put(fn);
    535        
    536         async_data_read_finalize(callid, &stat, sizeof(struct stat));
     457
     458        ipc_data_read_finalize(callid, &stat, sizeof(struct stat));
    537459        ipc_answer_0(rid, EOK);
    538460}
     
    540462/** Open VFS triplet.
    541463 *
    542  * @param ops     libfs operations structure with function pointers to
    543  *                file system implementation
    544  * @param rid     Request ID of the VFS_OUT_OPEN_NODE request.
    545  * @param request VFS_OUT_OPEN_NODE request data itself.
     464 * @param ops       libfs operations structure with function pointers to
     465 *                  file system implementation
     466 * @param rid       Request ID of the VFS_OUT_OPEN_NODE request.
     467 * @param request   VFS_OUT_OPEN_NODE request data itself.
    546468 *
    547469 */
     
    551473        dev_handle_t dev_handle = IPC_GET_ARG1(*request);
    552474        fs_index_t index = IPC_GET_ARG2(*request);
    553         fs_node_t *fn;
    554         int rc;
    555        
    556         rc = ops->node_get(&fn, dev_handle, index);
    557         on_error(rc, answer_and_return(rid, rc));
    558        
    559         if (fn == NULL) {
     475       
     476        fs_node_t *node = ops->node_get(dev_handle, index);
     477       
     478        if (node == NULL) {
    560479                ipc_answer_0(rid, ENOENT);
    561480                return;
    562481        }
    563482       
    564         rc = ops->node_open(fn);
    565         ipc_answer_3(rid, rc, ops->size_get(fn), ops->lnkcnt_get(fn),
    566             (ops->is_file(fn) ? L_FILE : 0) | (ops->is_directory(fn) ? L_DIRECTORY : 0));
    567        
    568         (void) ops->node_put(fn);
     483        ipc_answer_5(rid, EOK, fs_handle, dev_handle, index,
     484            ops->size_get(node), ops->lnkcnt_get(node));
     485       
     486        ops->node_put(node);
    569487}
    570488
Note: See TracChangeset for help on using the changeset viewer.