Changeset 371bd7d in mainline for uspace/lib/fs


Ignore:
Timestamp:
2010-03-27T09:22:17Z (16 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
36a75a2
Parents:
cd82bb1 (diff), eaf22d4 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

Location:
uspace/lib/fs
Files:
1 added
4 moved

Legend:

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

    rcd82bb1 r371bd7d  
    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 commonod to all FS implementations.
     34 * Glue code which is common to all FS implementations.
    3535 */
    3636
    37 #include "libfs.h" 
     37#include "libfs.h"
    3838#include "../../srv/vfs/vfs.h"
     39#include <macros.h>
    3940#include <errno.h>
    4041#include <async.h>
     
    6768 * code.
    6869 *
    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.
     70 * @param vfs_phone Open phone for communication with VFS.
     71 * @param reg       File system registration structure. It will be
     72 *                  initialized by this function.
     73 * @param info      VFS info structure supplied by the file system
     74 *                  implementation.
     75 * @param conn      Connection fibril for handling all calls originating in
     76 *                  VFS.
     77 *
     78 * @return EOK on success or a non-zero error code on errror.
     79 *
    7880 */
    7981int fs_register(int vfs_phone, fs_reg_t *reg, vfs_info_t *info,
     
    8789        ipc_call_t answer;
    8890        aid_t req = async_send_0(vfs_phone, VFS_IN_REGISTER, &answer);
    89 
     91       
    9092        /*
    9193         * Send our VFS info structure to VFS.
     
    9698                return rc;
    9799        }
    98 
     100       
    99101        /*
    100102         * Ask VFS for callback connection.
    101103         */
    102104        ipc_connect_to_me(vfs_phone, 0, 0, 0, &reg->vfs_phonehash);
    103 
     105       
    104106        /*
    105107         * Allocate piece of address space for PLB.
     
    110112                return ENOMEM;
    111113        }
    112 
     114       
    113115        /*
    114116         * Request sharing the Path Lookup Buffer with VFS.
     
    136138         */
    137139        async_set_client_connection(conn);
    138 
     140       
    139141        return IPC_GET_RETVAL(answer);
    140142}
     
    154156        int res;
    155157        ipcarg_t rc;
    156 
     158       
    157159        ipc_call_t call;
    158160        ipc_callid_t callid;
    159 
    160         /* accept the phone */
     161       
     162        /* Accept the phone */
    161163        callid = async_get_call(&call);
    162         int mountee_phone = (int)IPC_GET_ARG1(call);
     164        int mountee_phone = (int) IPC_GET_ARG1(call);
    163165        if ((IPC_GET_METHOD(call) != IPC_M_CONNECTION_CLONE) ||
    164             mountee_phone < 0) {
     166            (mountee_phone < 0)) {
    165167                ipc_answer_0(callid, EINVAL);
    166168                ipc_answer_0(rid, EINVAL);
    167169                return;
    168170        }
    169         ipc_answer_0(callid, EOK);      /* acknowledge the mountee_phone */
    170        
    171         res = async_data_write_receive(&callid, NULL);
    172         if (!res) {
    173                 ipc_hangup(mountee_phone);
    174                 ipc_answer_0(callid, EINVAL);
    175                 ipc_answer_0(rid, EINVAL);
    176                 return;
    177         }
    178 
     171       
     172        /* Acknowledge the mountee_phone */
     173        ipc_answer_0(callid, EOK);
     174       
    179175        fs_node_t *fn;
    180176        res = ops->node_get(&fn, mp_dev_handle, mp_fs_index);
    181         if (res != EOK || !fn) {
     177        if ((res != EOK) || (!fn)) {
    182178                ipc_hangup(mountee_phone);
    183                 ipc_answer_0(callid, combine_rc(res, ENOENT));
     179                async_data_write_void(combine_rc(res, ENOENT));
    184180                ipc_answer_0(rid, combine_rc(res, ENOENT));
    185181                return;
    186182        }
    187 
     183       
    188184        if (fn->mp_data.mp_active) {
    189185                ipc_hangup(mountee_phone);
    190186                (void) ops->node_put(fn);
    191                 ipc_answer_0(callid, EBUSY);
     187                async_data_write_void(EBUSY);
    192188                ipc_answer_0(rid, EBUSY);
    193189                return;
    194190        }
    195 
     191       
    196192        rc = async_req_0_0(mountee_phone, IPC_M_CONNECT_ME);
    197193        if (rc != EOK) {
    198194                ipc_hangup(mountee_phone);
    199195                (void) ops->node_put(fn);
    200                 ipc_answer_0(callid, rc);
     196                async_data_write_void(rc);
    201197                ipc_answer_0(rid, rc);
    202198                return;
     
    204200       
    205201        ipc_call_t answer;
    206         aid_t msg = async_send_1(mountee_phone, VFS_OUT_MOUNTED, mr_dev_handle,
    207             &answer);
    208         ipc_forward_fast(callid, mountee_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
    209         async_wait_for(msg, &rc);
     202        rc = async_data_write_forward_1_1(mountee_phone, VFS_OUT_MOUNTED,
     203            mr_dev_handle, &answer);
    210204       
    211205        if (rc == EOK) {
     
    215209                fn->mp_data.phone = mountee_phone;
    216210        }
     211       
    217212        /*
    218213         * Do not release the FS node so that it stays in memory.
     
    220215        ipc_answer_3(rid, rc, IPC_GET_ARG1(answer), IPC_GET_ARG2(answer),
    221216            IPC_GET_ARG3(answer));
     217}
     218
     219void libfs_unmount(libfs_ops_t *ops, ipc_callid_t rid, ipc_call_t *request)
     220{
     221        dev_handle_t mp_dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
     222        fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*request);
     223        fs_node_t *fn;
     224        int res;
     225
     226        res = ops->node_get(&fn, mp_dev_handle, mp_fs_index);
     227        if ((res != EOK) || (!fn)) {
     228                ipc_answer_0(rid, combine_rc(res, ENOENT));
     229                return;
     230        }
     231
     232        /*
     233         * We are clearly expecting to find the mount point active.
     234         */
     235        if (!fn->mp_data.mp_active) {
     236                (void) ops->node_put(fn);
     237                ipc_answer_0(rid, EINVAL);
     238                return;
     239        }
     240
     241        /*
     242         * Tell the mounted file system to unmount.
     243         */
     244        res = async_req_1_0(fn->mp_data.phone, VFS_OUT_UNMOUNTED,
     245            fn->mp_data.dev_handle);
     246
     247        /*
     248         * If everything went well, perform the clean-up on our side.
     249         */
     250        if (res == EOK) {
     251                ipc_hangup(fn->mp_data.phone);
     252                fn->mp_data.mp_active = false;
     253                fn->mp_data.fs_handle = 0;
     254                fn->mp_data.dev_handle = 0;
     255                fn->mp_data.phone = 0;
     256                /* Drop the reference created in libfs_mount(). */
     257                (void) ops->node_put(fn);
     258        }
     259
     260        (void) ops->node_put(fn);
     261        ipc_answer_0(rid, res);
    222262}
    223263
     
    238278    ipc_call_t *request)
    239279{
    240         unsigned first = IPC_GET_ARG1(*request);
    241         unsigned last = IPC_GET_ARG2(*request);
    242         unsigned next = first;
     280        unsigned int first = IPC_GET_ARG1(*request);
     281        unsigned int last = IPC_GET_ARG2(*request);
     282        unsigned int next = first;
    243283        dev_handle_t dev_handle = IPC_GET_ARG3(*request);
    244284        int lflag = IPC_GET_ARG4(*request);
    245         fs_index_t index = IPC_GET_ARG5(*request); /* when L_LINK specified */
     285        fs_index_t index = IPC_GET_ARG5(*request);
    246286        char component[NAME_MAX + 1];
    247287        int len;
    248288        int rc;
    249 
     289       
    250290        if (last < next)
    251291                last += PLB_SIZE;
    252 
     292       
    253293        fs_node_t *par = NULL;
    254294        fs_node_t *cur = NULL;
    255295        fs_node_t *tmp = NULL;
    256 
     296       
    257297        rc = ops->root_get(&cur, dev_handle);
    258298        on_error(rc, goto out_with_answer);
    259 
     299       
    260300        if (cur->mp_data.mp_active) {
    261301                ipc_forward_slow(rid, cur->mp_data.phone, VFS_OUT_LOOKUP,
     
    265305                return;
    266306        }
    267 
     307       
     308        /* Eat slash */
    268309        if (ops->plb_get_char(next) == '/')
    269                 next++;         /* eat slash */
     310                next++;
    270311       
    271312        while (next <= last) {
    272313                bool has_children;
    273 
     314               
    274315                rc = ops->has_children(&has_children, cur);
    275316                on_error(rc, goto out_with_answer);
    276317                if (!has_children)
    277318                        break;
    278 
    279                 /* collect the component */
     319               
     320                /* Collect the component */
    280321                len = 0;
    281                 while ((next <= last) &&  (ops->plb_get_char(next) != '/')) {
     322                while ((next <= last) && (ops->plb_get_char(next) != '/')) {
    282323                        if (len + 1 == NAME_MAX) {
    283                                 /* component length overflow */
     324                                /* Component length overflow */
    284325                                ipc_answer_0(rid, ENAMETOOLONG);
    285326                                goto out;
    286327                        }
    287328                        component[len++] = ops->plb_get_char(next);
    288                         next++; /* process next character */
     329                        /* Process next character */
     330                        next++;
    289331                }
    290 
     332               
    291333                assert(len);
    292334                component[len] = '\0';
    293                 next++;         /* eat slash */
    294 
    295                 /* match the component */
     335                /* Eat slash */
     336                next++;
     337               
     338                /* Match the component */
    296339                rc = ops->match(&tmp, cur, component);
    297340                on_error(rc, goto out_with_answer);
    298 
    299                 if (tmp && tmp->mp_data.mp_active) {
     341               
     342                /*
     343                 * If the matching component is a mount point, there are two
     344                 * legitimate semantics of the lookup operation. The first is
     345                 * the commonly used one in which the lookup crosses each mount
     346                 * point into the mounted file system. The second semantics is
     347                 * used mostly during unmount() and differs from the first one
     348                 * only in that the last mount point in the looked up path,
     349                 * which is also its last component, is not crossed.
     350                 */
     351
     352                if ((tmp) && (tmp->mp_data.mp_active) &&
     353                    (!(lflag & L_MP) || (next <= last))) {
    300354                        if (next > last)
    301355                                next = last = first;
    302356                        else
    303357                                next--;
    304                                
     358                       
    305359                        ipc_forward_slow(rid, tmp->mp_data.phone,
    306360                            VFS_OUT_LOOKUP, next, last, tmp->mp_data.dev_handle,
     
    312366                        return;
    313367                }
    314 
    315                 /* handle miss: match amongst siblings */
     368               
     369                /* Handle miss: match amongst siblings */
    316370                if (!tmp) {
    317371                        if (next <= last) {
    318                                 /* there are unprocessed components */
     372                                /* There are unprocessed components */
    319373                                ipc_answer_0(rid, ENOENT);
    320374                                goto out;
    321375                        }
    322                         /* miss in the last component */
    323                         if (lflag & (L_CREATE | L_LINK)) {
    324                                 /* request to create a new link */
     376                       
     377                        /* Miss in the last component */
     378                        if (lflag & (L_CREATE | L_LINK)) {
     379                                /* Request to create a new link */
    325380                                if (!ops->is_directory(cur)) {
    326381                                        ipc_answer_0(rid, ENOTDIR);
    327382                                        goto out;
    328383                                }
     384                               
    329385                                fs_node_t *fn;
    330386                                if (lflag & L_CREATE)
     
    335391                                            index);
    336392                                on_error(rc, goto out_with_answer);
     393                               
    337394                                if (fn) {
    338395                                        rc = ops->link(cur, fn, component);
     
    342399                                                ipc_answer_0(rid, rc);
    343400                                        } else {
    344                                                 ipc_answer_5(rid, EOK,
    345                                                     fs_handle, dev_handle,
     401                                                aoff64_t size = ops->size_get(fn);
     402                                                ipc_answer_5(rid, fs_handle,
     403                                                    dev_handle,
    346404                                                    ops->index_get(fn),
    347                                                     ops->size_get(fn),
     405                                                    LOWER32(size),
     406                                                    UPPER32(size),
    348407                                                    ops->lnkcnt_get(fn));
    349408                                                (void) ops->node_put(fn);
    350409                                        }
    351                                 } else {
     410                                } else
    352411                                        ipc_answer_0(rid, ENOSPC);
    353                                 }
     412                               
    354413                                goto out;
    355                         }
     414                        }
     415                       
    356416                        ipc_answer_0(rid, ENOENT);
    357417                        goto out;
    358418                }
    359 
     419               
    360420                if (par) {
    361421                        rc = ops->node_put(par);
    362422                        on_error(rc, goto out_with_answer);
    363423                }
    364 
    365                 /* descend one level */
     424               
     425                /* Descend one level */
    366426                par = cur;
    367427                cur = tmp;
    368428                tmp = NULL;
    369429        }
    370 
    371         /* handle miss: excessive components */
     430       
     431        /* Handle miss: excessive components */
    372432        if (next <= last) {
    373433                bool has_children;
    374 
    375434                rc = ops->has_children(&has_children, cur);
    376435                on_error(rc, goto out_with_answer);
     436               
    377437                if (has_children)
    378438                        goto skip_miss;
    379 
     439               
    380440                if (lflag & (L_CREATE | L_LINK)) {
    381441                        if (!ops->is_directory(cur)) {
     
    383443                                goto out;
    384444                        }
    385 
    386                         /* collect next component */
     445                       
     446                        /* Collect next component */
    387447                        len = 0;
    388448                        while (next <= last) {
    389449                                if (ops->plb_get_char(next) == '/') {
    390                                         /* more than one component */
     450                                        /* More than one component */
    391451                                        ipc_answer_0(rid, ENOENT);
    392452                                        goto out;
    393453                                }
     454                               
    394455                                if (len + 1 == NAME_MAX) {
    395                                         /* component length overflow */
     456                                        /* Component length overflow */
    396457                                        ipc_answer_0(rid, ENAMETOOLONG);
    397458                                        goto out;
    398459                                }
     460                               
    399461                                component[len++] = ops->plb_get_char(next);
    400                                 next++; /* process next character */
     462                                /* Process next character */
     463                                next++;
    401464                        }
     465                       
    402466                        assert(len);
    403467                        component[len] = '\0';
    404                                
     468                       
    405469                        fs_node_t *fn;
    406470                        if (lflag & L_CREATE)
     
    409473                                rc = ops->node_get(&fn, dev_handle, index);
    410474                        on_error(rc, goto out_with_answer);
     475                       
    411476                        if (fn) {
    412477                                rc = ops->link(cur, fn, component);
     
    416481                                        ipc_answer_0(rid, rc);
    417482                                } else {
    418                                         ipc_answer_5(rid, EOK,
    419                                             fs_handle, dev_handle,
     483                                        aoff64_t size = ops->size_get(fn);
     484                                        ipc_answer_5(rid, fs_handle,
     485                                            dev_handle,
    420486                                            ops->index_get(fn),
    421                                             ops->size_get(fn),
     487                                            LOWER32(size),
     488                                            UPPER32(size),
    422489                                            ops->lnkcnt_get(fn));
    423490                                        (void) ops->node_put(fn);
    424491                                }
    425                         } else {
     492                        } else
    426493                                ipc_answer_0(rid, ENOSPC);
    427                         }
     494                       
    428495                        goto out;
    429496                }
     497               
    430498                ipc_answer_0(rid, ENOENT);
    431499                goto out;
    432500        }
     501       
    433502skip_miss:
    434 
    435         /* handle hit */
     503       
     504        /* Handle hit */
    436505        if (lflag & L_UNLINK) {
    437                 unsigned old_lnkcnt = ops->lnkcnt_get(cur);
     506                unsigned int old_lnkcnt = ops->lnkcnt_get(cur);
    438507                rc = ops->unlink(par, cur, component);
    439                 ipc_answer_5(rid, (ipcarg_t)rc, fs_handle, dev_handle,
    440                     ops->index_get(cur), ops->size_get(cur), old_lnkcnt);
     508               
     509                if (rc == EOK) {
     510                        aoff64_t size = ops->size_get(cur);
     511                        ipc_answer_5(rid, fs_handle, dev_handle,
     512                            ops->index_get(cur), LOWER32(size), UPPER32(size),
     513                            old_lnkcnt);
     514                } else
     515                        ipc_answer_0(rid, rc);
     516               
    441517                goto out;
    442518        }
     519       
    443520        if (((lflag & (L_CREATE | L_EXCLUSIVE)) == (L_CREATE | L_EXCLUSIVE)) ||
    444521            (lflag & L_LINK)) {
     
    446523                goto out;
    447524        }
     525       
    448526        if ((lflag & L_FILE) && (ops->is_directory(cur))) {
    449527                ipc_answer_0(rid, EISDIR);
    450528                goto out;
    451529        }
     530       
    452531        if ((lflag & L_DIRECTORY) && (ops->is_file(cur))) {
    453532                ipc_answer_0(rid, ENOTDIR);
     
    455534        }
    456535
     536        if ((lflag & L_ROOT) && par) {
     537                ipc_answer_0(rid, EINVAL);
     538                goto out;
     539        }
     540       
    457541out_with_answer:
     542       
    458543        if (rc == EOK) {
    459                 ipc_answer_5(rid, EOK, fs_handle, dev_handle,
    460                     ops->index_get(cur), ops->size_get(cur),
    461                     ops->lnkcnt_get(cur));
    462         } else {
     544                if (lflag & L_OPEN)
     545                        rc = ops->node_open(cur);
     546               
     547                if (rc == EOK) {
     548                        aoff64_t size = ops->size_get(cur);
     549                        ipc_answer_5(rid, fs_handle, dev_handle,
     550                            ops->index_get(cur), LOWER32(size), UPPER32(size),
     551                            ops->lnkcnt_get(cur));
     552                } else
     553                        ipc_answer_0(rid, rc);
     554               
     555        } else
    463556                ipc_answer_0(rid, rc);
    464         }
    465 
     557       
    466558out:
     559       
    467560        if (par)
    468561                (void) ops->node_put(par);
     562       
    469563        if (cur)
    470564                (void) ops->node_put(cur);
     565       
    471566        if (tmp)
    472567                (void) ops->node_put(tmp);
     
    478573        dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request);
    479574        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
     575       
    480576        fs_node_t *fn;
    481         int rc;
    482 
    483         rc = ops->node_get(&fn, dev_handle, index);
     577        int rc = ops->node_get(&fn, dev_handle, index);
    484578        on_error(rc, answer_and_return(rid, rc));
    485 
     579       
    486580        ipc_callid_t callid;
    487581        size_t size;
    488         if (!async_data_read_receive(&callid, &size) ||
    489             size != sizeof(struct stat)) {
     582        if ((!async_data_read_receive(&callid, &size)) ||
     583            (size != sizeof(struct stat))) {
     584                ops->node_put(fn);
    490585                ipc_answer_0(callid, EINVAL);
    491586                ipc_answer_0(rid, EINVAL);
    492587                return;
    493588        }
    494 
     589       
    495590        struct stat stat;
    496591        memset(&stat, 0, sizeof(struct stat));
     
    499594        stat.dev_handle = dev_handle;
    500595        stat.index = index;
    501         stat.lnkcnt = ops->lnkcnt_get(fn); 
     596        stat.lnkcnt = ops->lnkcnt_get(fn);
    502597        stat.is_file = ops->is_file(fn);
     598        stat.is_directory = ops->is_directory(fn);
    503599        stat.size = ops->size_get(fn);
    504 
     600        stat.device = ops->device_get(fn);
     601       
     602        ops->node_put(fn);
     603       
    505604        async_data_read_finalize(callid, &stat, sizeof(struct stat));
    506605        ipc_answer_0(rid, EOK);
     
    509608/** Open VFS triplet.
    510609 *
    511  * @param ops       libfs operations structure with function pointers to
    512  *                  file system implementation
    513  * @param rid       Request ID of the VFS_OUT_OPEN_NODE request.
    514  * @param request   VFS_OUT_OPEN_NODE request data itself.
     610 * @param ops     libfs operations structure with function pointers to
     611 *                file system implementation
     612 * @param rid     Request ID of the VFS_OUT_OPEN_NODE request.
     613 * @param request VFS_OUT_OPEN_NODE request data itself.
    515614 *
    516615 */
     
    520619        dev_handle_t dev_handle = IPC_GET_ARG1(*request);
    521620        fs_index_t index = IPC_GET_ARG2(*request);
     621       
    522622        fs_node_t *fn;
    523         int rc;
    524        
    525         rc = ops->node_get(&fn, dev_handle, index);
     623        int rc = ops->node_get(&fn, dev_handle, index);
    526624        on_error(rc, answer_and_return(rid, rc));
    527625       
     
    531629        }
    532630       
    533         ipc_answer_3(rid, EOK, ops->size_get(fn), ops->lnkcnt_get(fn),
     631        rc = ops->node_open(fn);
     632        aoff64_t size = ops->size_get(fn);
     633        ipc_answer_4(rid, rc, LOWER32(size), UPPER32(size), ops->lnkcnt_get(fn),
    534634            (ops->is_file(fn) ? L_FILE : 0) | (ops->is_directory(fn) ? L_DIRECTORY : 0));
    535635       
  • uspace/lib/fs/libfs.h

    rcd82bb1 r371bd7d  
    6464        int (* match)(fs_node_t **, fs_node_t *, const char *);
    6565        int (* node_get)(fs_node_t **, dev_handle_t, fs_index_t);
     66        int (* node_open)(fs_node_t *);
    6667        int (* node_put)(fs_node_t *);
    6768        int (* create)(fs_node_t **, dev_handle_t, int);
     
    7576         */
    7677        fs_index_t (* index_get)(fs_node_t *);
    77         size_t (* size_get)(fs_node_t *);
    78         unsigned (* lnkcnt_get)(fs_node_t *);
     78        aoff64_t (* size_get)(fs_node_t *);
     79        unsigned int (* lnkcnt_get)(fs_node_t *);
    7980        char (* plb_get_char)(unsigned pos);
    8081        bool (* is_directory)(fs_node_t *);
    8182        bool (* is_file)(fs_node_t *);
     83        dev_handle_t (* device_get)(fs_node_t *);
    8284} libfs_ops_t;
    8385
     
    9395
    9496extern void libfs_mount(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
     97extern void libfs_unmount(libfs_ops_t *, ipc_callid_t, ipc_call_t *);
    9598extern void libfs_lookup(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
    9699extern void libfs_stat(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
Note: See TracChangeset for help on using the changeset viewer.