Changeset 86ffa27f in mainline for uspace/lib/fs/libfs.c


Ignore:
Timestamp:
2011-08-07T11:21:44Z (13 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
cc574511
Parents:
15f3c3f (diff), e8067c0 (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.

File:
1 edited

Legend:

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

    r15f3c3f r86ffa27f  
    4545#include <mem.h>
    4646#include <sys/stat.h>
     47#include <stdlib.h>
    4748
    4849#define on_error(rc, action) \
     
    6162        } while (0)
    6263
     64static fs_reg_t reg;
     65
     66static vfs_out_ops_t *vfs_out_ops = NULL;
     67static libfs_ops_t *libfs_ops = NULL;
     68
     69static void libfs_mount(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
     70static void libfs_unmount(libfs_ops_t *, ipc_callid_t, ipc_call_t *);
     71static void libfs_lookup(libfs_ops_t *, fs_handle_t, ipc_callid_t,
     72    ipc_call_t *);
     73static void libfs_stat(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
     74static void libfs_open_node(libfs_ops_t *, fs_handle_t, ipc_callid_t,
     75    ipc_call_t *);
     76
     77static void vfs_out_mounted(ipc_callid_t rid, ipc_call_t *req)
     78{
     79        service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
     80        char *opts;
     81        int rc;
     82       
     83        /* Accept the mount options. */
     84        rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL);
     85        if (rc != EOK) {
     86                async_answer_0(rid, rc);
     87                return;
     88        }
     89
     90        fs_index_t index;
     91        aoff64_t size;
     92        unsigned lnkcnt;
     93        rc = vfs_out_ops->mounted(service_id, opts, &index, &size, &lnkcnt);
     94
     95        if (rc == EOK)
     96                async_answer_4(rid, EOK, index, LOWER32(size), UPPER32(size),
     97                    lnkcnt);
     98        else
     99                async_answer_0(rid, rc);
     100
     101        free(opts);
     102}
     103
     104static void vfs_out_mount(ipc_callid_t rid, ipc_call_t *req)
     105{
     106        libfs_mount(libfs_ops, reg.fs_handle, rid, req);
     107}
     108
     109static void vfs_out_unmounted(ipc_callid_t rid, ipc_call_t *req)
     110{
     111        service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
     112        int rc;
     113
     114        rc = vfs_out_ops->unmounted(service_id);
     115
     116        async_answer_0(rid, rc);
     117}
     118
     119static void vfs_out_unmount(ipc_callid_t rid, ipc_call_t *req)
     120{
     121               
     122        libfs_unmount(libfs_ops, rid, req);
     123}
     124
     125static void vfs_out_lookup(ipc_callid_t rid, ipc_call_t *req)
     126{
     127        libfs_lookup(libfs_ops, reg.fs_handle, rid, req);
     128}
     129
     130static void vfs_out_read(ipc_callid_t rid, ipc_call_t *req)
     131{
     132        service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
     133        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
     134        aoff64_t pos = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*req),
     135            IPC_GET_ARG4(*req));
     136        size_t rbytes;
     137        int rc;
     138
     139        rc = vfs_out_ops->read(service_id, index, pos, &rbytes);
     140
     141        if (rc == EOK)
     142                async_answer_1(rid, EOK, rbytes);
     143        else
     144                async_answer_0(rid, rc);
     145}
     146
     147static void vfs_out_write(ipc_callid_t rid, ipc_call_t *req)
     148{
     149        service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
     150        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
     151        aoff64_t pos = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*req),
     152            IPC_GET_ARG4(*req));
     153        size_t wbytes;
     154        aoff64_t nsize;
     155        int rc;
     156
     157        rc = vfs_out_ops->write(service_id, index, pos, &wbytes, &nsize);
     158
     159        if (rc == EOK)
     160                async_answer_3(rid, EOK, wbytes, LOWER32(nsize), UPPER32(nsize));
     161        else
     162                async_answer_0(rid, rc);
     163}
     164
     165static void vfs_out_truncate(ipc_callid_t rid, ipc_call_t *req)
     166{
     167        service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
     168        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
     169        aoff64_t size = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*req),
     170            IPC_GET_ARG4(*req));
     171        int rc;
     172
     173        rc = vfs_out_ops->truncate(service_id, index, size);
     174
     175        async_answer_0(rid, rc);
     176}
     177
     178static void vfs_out_close(ipc_callid_t rid, ipc_call_t *req)
     179{
     180        service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
     181        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
     182        int rc;
     183
     184        rc = vfs_out_ops->close(service_id, index);
     185
     186        async_answer_0(rid, rc);
     187}
     188
     189static void vfs_out_destroy(ipc_callid_t rid, ipc_call_t *req)
     190{
     191        service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
     192        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
     193        int rc;
     194
     195        rc = vfs_out_ops->destroy(service_id, index);
     196
     197        async_answer_0(rid, rc);
     198}
     199
     200static void vfs_out_open_node(ipc_callid_t rid, ipc_call_t *req)
     201{
     202        libfs_open_node(libfs_ops, reg.fs_handle, rid, req);
     203}
     204
     205static void vfs_out_stat(ipc_callid_t rid, ipc_call_t *req)
     206{
     207        libfs_stat(libfs_ops, reg.fs_handle, rid, req);
     208}
     209
     210static void vfs_out_sync(ipc_callid_t rid, ipc_call_t *req)
     211{
     212        service_id_t service_id = (service_id_t) IPC_GET_ARG1(*req);
     213        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
     214        int rc;
     215
     216        rc = vfs_out_ops->sync(service_id, index);
     217
     218        async_answer_0(rid, rc);
     219}
     220
     221static void vfs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
     222{
     223        if (iid) {
     224                /*
     225                 * This only happens for connections opened by
     226                 * IPC_M_CONNECT_ME_TO calls as opposed to callback connections
     227                 * created by IPC_M_CONNECT_TO_ME.
     228                 */
     229                async_answer_0(iid, EOK);
     230        }
     231       
     232        while (true) {
     233                ipc_call_t call;
     234                ipc_callid_t callid = async_get_call(&call);
     235               
     236                if (!IPC_GET_IMETHOD(call))
     237                        return;
     238               
     239                switch (IPC_GET_IMETHOD(call)) {
     240                case VFS_OUT_MOUNTED:
     241                        vfs_out_mounted(callid, &call);
     242                        break;
     243                case VFS_OUT_MOUNT:
     244                        vfs_out_mount(callid, &call);
     245                        break;
     246                case VFS_OUT_UNMOUNTED:
     247                        vfs_out_unmounted(callid, &call);
     248                        break;
     249                case VFS_OUT_UNMOUNT:
     250                        vfs_out_unmount(callid, &call);
     251                        break;
     252                case VFS_OUT_LOOKUP:
     253                        vfs_out_lookup(callid, &call);
     254                        break;
     255                case VFS_OUT_READ:
     256                        vfs_out_read(callid, &call);
     257                        break;
     258                case VFS_OUT_WRITE:
     259                        vfs_out_write(callid, &call);
     260                        break;
     261                case VFS_OUT_TRUNCATE:
     262                        vfs_out_truncate(callid, &call);
     263                        break;
     264                case VFS_OUT_CLOSE:
     265                        vfs_out_close(callid, &call);
     266                        break;
     267                case VFS_OUT_DESTROY:
     268                        vfs_out_destroy(callid, &call);
     269                        break;
     270                case VFS_OUT_OPEN_NODE:
     271                        vfs_out_open_node(callid, &call);
     272                        break;
     273                case VFS_OUT_STAT:
     274                        vfs_out_stat(callid, &call);
     275                        break;
     276                case VFS_OUT_SYNC:
     277                        vfs_out_sync(callid, &call);
     278                        break;
     279                default:
     280                        async_answer_0(callid, ENOTSUP);
     281                        break;
     282                }
     283        }
     284}
     285
    63286/** Register file system server.
    64287 *
     
    68291 *
    69292 * @param sess Session for communication with VFS.
    70  * @param reg  File system registration structure. It will be
    71  *             initialized by this function.
    72293 * @param info VFS info structure supplied by the file system
    73294 *             implementation.
    74  * @param conn Connection fibril for handling all calls originating in
    75  *             VFS.
     295 * @param vops Address of the vfs_out_ops_t structure.
     296 * @param lops Address of the libfs_ops_t structure.
    76297 *
    77298 * @return EOK on success or a non-zero error code on errror.
    78299 *
    79300 */
    80 int fs_register(async_sess_t *sess, fs_reg_t *reg, vfs_info_t *info,
    81     async_client_conn_t conn)
     301int fs_register(async_sess_t *sess, vfs_info_t *info, vfs_out_ops_t *vops,
     302    libfs_ops_t *lops)
    82303{
    83304        /*
     
    104325       
    105326        /*
     327         * Set VFS_OUT and libfs operations.
     328         */
     329        vfs_out_ops = vops;
     330        libfs_ops = lops;
     331
     332        /*
    106333         * Ask VFS for callback connection.
    107334         */
    108         async_connect_to_me(exch, 0, 0, 0, conn, NULL);
     335        async_connect_to_me(exch, 0, 0, 0, vfs_connection, NULL);
    109336       
    110337        /*
    111338         * Allocate piece of address space for PLB.
    112339         */
    113         reg->plb_ro = as_get_mappable_page(PLB_SIZE);
    114         if (!reg->plb_ro) {
     340        reg.plb_ro = as_get_mappable_page(PLB_SIZE);
     341        if (!reg.plb_ro) {
    115342                async_exchange_end(exch);
    116343                async_wait_for(req, NULL);
     
    121348         * Request sharing the Path Lookup Buffer with VFS.
    122349         */
    123         rc = async_share_in_start_0_0(exch, reg->plb_ro, PLB_SIZE);
     350        rc = async_share_in_start_0_0(exch, reg.plb_ro, PLB_SIZE);
    124351       
    125352        async_exchange_end(exch);
     
    134361         */
    135362        async_wait_for(req, NULL);
    136         reg->fs_handle = (int) IPC_GET_ARG1(answer);
     363        reg.fs_handle = (int) IPC_GET_ARG1(answer);
    137364       
    138365        /*
     
    140367         * the same connection fibril as well.
    141368         */
    142         async_set_client_connection(conn);
     369        async_set_client_connection(vfs_connection);
    143370       
    144371        return IPC_GET_RETVAL(answer);
     
    151378
    152379void libfs_mount(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_callid_t rid,
    153     ipc_call_t *request)
    154 {
    155         service_id_t mp_service_id = (service_id_t) IPC_GET_ARG1(*request);
    156         fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*request);
    157         fs_handle_t mr_fs_handle = (fs_handle_t) IPC_GET_ARG3(*request);
    158         service_id_t mr_service_id = (service_id_t) IPC_GET_ARG4(*request);
     380    ipc_call_t *req)
     381{
     382        service_id_t mp_service_id = (service_id_t) IPC_GET_ARG1(*req);
     383        fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*req);
     384        fs_handle_t mr_fs_handle = (fs_handle_t) IPC_GET_ARG3(*req);
     385        service_id_t mr_service_id = (service_id_t) IPC_GET_ARG4(*req);
    159386       
    160387        async_sess_t *mountee_sess = async_clone_receive(EXCHANGE_PARALLEL);
     
    208435         * Do not release the FS node so that it stays in memory.
    209436         */
    210         async_answer_3(rid, rc, IPC_GET_ARG1(answer), IPC_GET_ARG2(answer),
    211             IPC_GET_ARG3(answer));
    212 }
    213 
    214 void libfs_unmount(libfs_ops_t *ops, ipc_callid_t rid, ipc_call_t *request)
    215 {
    216         service_id_t mp_service_id = (service_id_t) IPC_GET_ARG1(*request);
    217         fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*request);
     437        async_answer_4(rid, rc, IPC_GET_ARG1(answer), IPC_GET_ARG2(answer),
     438            IPC_GET_ARG3(answer), IPC_GET_ARG4(answer));
     439}
     440
     441void libfs_unmount(libfs_ops_t *ops, ipc_callid_t rid, ipc_call_t *req)
     442{
     443        service_id_t mp_service_id = (service_id_t) IPC_GET_ARG1(*req);
     444        fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*req);
    218445        fs_node_t *fn;
    219446        int res;
     
    259486}
    260487
     488static char plb_get_char(unsigned pos)
     489{
     490        return reg.plb_ro[pos % PLB_SIZE];
     491}
     492
    261493/** Lookup VFS triplet by name in the file system name space.
    262494 *
     
    273505 */
    274506void libfs_lookup(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_callid_t rid,
    275     ipc_call_t *request)
    276 {
    277         unsigned int first = IPC_GET_ARG1(*request);
    278         unsigned int last = IPC_GET_ARG2(*request);
     507    ipc_call_t *req)
     508{
     509        unsigned int first = IPC_GET_ARG1(*req);
     510        unsigned int last = IPC_GET_ARG2(*req);
    279511        unsigned int next = first;
    280         service_id_t service_id = IPC_GET_ARG3(*request);
    281         int lflag = IPC_GET_ARG4(*request);
    282         fs_index_t index = IPC_GET_ARG5(*request);
     512        service_id_t service_id = IPC_GET_ARG3(*req);
     513        int lflag = IPC_GET_ARG4(*req);
     514        fs_index_t index = IPC_GET_ARG5(*req);
    283515        char component[NAME_MAX + 1];
    284516        int len;
     
    298530                async_exch_t *exch = async_exchange_begin(cur->mp_data.sess);
    299531                async_forward_slow(rid, exch, VFS_OUT_LOOKUP, next, last,
    300                     cur->mp_data.service_id, lflag, index, IPC_FF_ROUTE_FROM_ME);
     532                    cur->mp_data.service_id, lflag, index,
     533                    IPC_FF_ROUTE_FROM_ME);
    301534                async_exchange_end(exch);
    302535               
     
    306539       
    307540        /* Eat slash */
    308         if (ops->plb_get_char(next) == '/')
     541        if (plb_get_char(next) == '/')
    309542                next++;
    310543       
     
    319552                /* Collect the component */
    320553                len = 0;
    321                 while ((next <= last) && (ops->plb_get_char(next) != '/')) {
     554                while ((next <= last) && (plb_get_char(next) != '/')) {
    322555                        if (len + 1 == NAME_MAX) {
    323556                                /* Component length overflow */
     
    325558                                goto out;
    326559                        }
    327                         component[len++] = ops->plb_get_char(next);
     560                        component[len++] = plb_get_char(next);
    328561                        /* Process next character */
    329562                        next++;
     
    357590                       
    358591                        async_exch_t *exch = async_exchange_begin(tmp->mp_data.sess);
    359                         async_forward_slow(rid, exch, VFS_OUT_LOOKUP, next, last,
    360                             tmp->mp_data.service_id, lflag, index,
     592                        async_forward_slow(rid, exch, VFS_OUT_LOOKUP, next,
     593                            last, tmp->mp_data.service_id, lflag, index,
    361594                            IPC_FF_ROUTE_FROM_ME);
    362595                        async_exchange_end(exch);
     
    451684                        len = 0;
    452685                        while (next <= last) {
    453                                 if (ops->plb_get_char(next) == '/') {
     686                                if (plb_get_char(next) == '/') {
    454687                                        /* More than one component */
    455688                                        async_answer_0(rid, ENOENT);
     
    463696                                }
    464697                               
    465                                 component[len++] = ops->plb_get_char(next);
     698                                component[len++] = plb_get_char(next);
    466699                                /* Process next character */
    467700                                next++;
     
    637870        rc = ops->node_open(fn);
    638871        aoff64_t size = ops->size_get(fn);
    639         async_answer_4(rid, rc, LOWER32(size), UPPER32(size), ops->lnkcnt_get(fn),
     872        async_answer_4(rid, rc, LOWER32(size), UPPER32(size),
     873            ops->lnkcnt_get(fn),
    640874            (ops->is_file(fn) ? L_FILE : 0) | (ops->is_directory(fn) ? L_DIRECTORY : 0));
    641875       
Note: See TracChangeset for help on using the changeset viewer.