Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset efcebe1 in mainline


Ignore:
Timestamp:
2011-07-24T23:15:42Z (10 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master
Children:
358dc13, 3fb0fec
Parents:
6a44ee4
Message:

Get rid of per filesystem VFS_OUT method switch and IPC unmarshalling.

  • libfs now understands the notion of VFS_OUT operations and provides the single version of the switch
  • libfs now automatically takes care of some libfs provided operations, such as lookup and stat; filesystem need not be even aware of these
  • one filesystem time per libfs instance
  • plb_get_char() no longer a libfs operation
  • filesystem implemenations need not worry about IPC with the exception of VFS_OUT_READ/WRITE methods and filesystems that depend on doing extra IPC in these and similar methods, such as devfs
Location:
uspace
Files:
15 edited

Legend:

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

    r6a44ee4 refcebe1  
    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        devmap_handle_t devmap_handle = (devmap_handle_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(devmap_handle, opts, &index, &size, &lnkcnt);
     94
     95        if (rc == EOK)  // FIXME: size is 64-bit
     96                async_answer_3(rid, EOK, index, size, lnkcnt);
     97        else
     98                async_answer_0(rid, rc);
     99
     100        free(opts);
     101}
     102
     103static void vfs_out_mount(ipc_callid_t rid, ipc_call_t *req)
     104{
     105        libfs_mount(libfs_ops, reg.fs_handle, rid, req);
     106}
     107
     108static void vfs_out_unmounted(ipc_callid_t rid, ipc_call_t *req)
     109{
     110        devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
     111        int rc;
     112
     113        rc = vfs_out_ops->unmounted(devmap_handle);
     114
     115        async_answer_0(rid, rc);
     116}
     117
     118static void vfs_out_unmount(ipc_callid_t rid, ipc_call_t *req)
     119{
     120               
     121        libfs_unmount(libfs_ops, rid, req);
     122}
     123
     124static void vfs_out_lookup(ipc_callid_t rid, ipc_call_t *req)
     125{
     126        libfs_lookup(libfs_ops, reg.fs_handle, rid, req);
     127}
     128
     129static void vfs_out_read(ipc_callid_t rid, ipc_call_t *req)
     130{
     131        devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
     132        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
     133        aoff64_t pos = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*req),
     134            IPC_GET_ARG4(*req));
     135        size_t rbytes;
     136        int rc;
     137
     138        rc = vfs_out_ops->read(devmap_handle, index, pos, &rbytes);
     139
     140        if (rc == EOK)
     141                async_answer_1(rid, EOK, rbytes);
     142        else
     143                async_answer_0(rid, rc);
     144}
     145
     146static void vfs_out_write(ipc_callid_t rid, ipc_call_t *req)
     147{
     148        devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
     149        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
     150        aoff64_t pos = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*req),
     151            IPC_GET_ARG4(*req));
     152        size_t wbytes;
     153        aoff64_t nsize;
     154        int rc;
     155
     156        rc = vfs_out_ops->write(devmap_handle, index, pos, &wbytes, &nsize);
     157
     158        if (rc == EOK)  // FIXME: nsize is 64-bit
     159                async_answer_2(rid, EOK, wbytes, nsize);
     160        else
     161                async_answer_0(rid, rc);
     162}
     163
     164static void vfs_out_truncate(ipc_callid_t rid, ipc_call_t *req)
     165{
     166        devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
     167        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
     168        aoff64_t size = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*req),
     169            IPC_GET_ARG4(*req));
     170        int rc;
     171
     172        rc = vfs_out_ops->truncate(devmap_handle, index, size);
     173
     174        async_answer_0(rid, rc);
     175}
     176
     177static void vfs_out_close(ipc_callid_t rid, ipc_call_t *req)
     178{
     179        devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
     180        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
     181        int rc;
     182
     183        rc = vfs_out_ops->close(devmap_handle, index);
     184
     185        async_answer_0(rid, rc);
     186}
     187
     188static void vfs_out_destroy(ipc_callid_t rid, ipc_call_t *req)
     189{
     190        devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
     191        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
     192        int rc;
     193
     194        rc = vfs_out_ops->destroy(devmap_handle, index);
     195
     196        async_answer_0(rid, rc);
     197}
     198
     199static void vfs_out_open_node(ipc_callid_t rid, ipc_call_t *req)
     200{
     201        libfs_open_node(libfs_ops, reg.fs_handle, rid, req);
     202}
     203
     204static void vfs_out_stat(ipc_callid_t rid, ipc_call_t *req)
     205{
     206        libfs_stat(libfs_ops, reg.fs_handle, rid, req);
     207}
     208
     209static void vfs_out_sync(ipc_callid_t rid, ipc_call_t *req)
     210{
     211        devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
     212        fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
     213        int rc;
     214
     215        rc = vfs_out_ops->sync(devmap_handle, index);
     216
     217        async_answer_0(rid, rc);
     218}
     219
     220static void vfs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
     221{
     222        if (iid) {
     223                /*
     224                 * This only happens for connections opened by
     225                 * IPC_M_CONNECT_ME_TO calls as opposed to callback connections
     226                 * created by IPC_M_CONNECT_TO_ME.
     227                 */
     228                async_answer_0(iid, EOK);
     229        }
     230       
     231        while (true) {
     232                ipc_call_t call;
     233                ipc_callid_t callid = async_get_call(&call);
     234               
     235                if (!IPC_GET_IMETHOD(call))
     236                        return;
     237               
     238                switch (IPC_GET_IMETHOD(call)) {
     239                case VFS_OUT_MOUNTED:
     240                        vfs_out_mounted(callid, &call);
     241                        break;
     242                case VFS_OUT_MOUNT:
     243                        vfs_out_mount(callid, &call);
     244                        break;
     245                case VFS_OUT_UNMOUNTED:
     246                        vfs_out_unmounted(callid, &call);
     247                        break;
     248                case VFS_OUT_UNMOUNT:
     249                        vfs_out_unmount(callid, &call);
     250                        break;
     251                case VFS_OUT_LOOKUP:
     252                        vfs_out_lookup(callid, &call);
     253                        break;
     254                case VFS_OUT_READ:
     255                        vfs_out_read(callid, &call);
     256                        break;
     257                case VFS_OUT_WRITE:
     258                        vfs_out_write(callid, &call);
     259                        break;
     260                case VFS_OUT_TRUNCATE:
     261                        vfs_out_truncate(callid, &call);
     262                        break;
     263                case VFS_OUT_CLOSE:
     264                        vfs_out_close(callid, &call);
     265                        break;
     266                case VFS_OUT_DESTROY:
     267                        vfs_out_destroy(callid, &call);
     268                        break;
     269                case VFS_OUT_OPEN_NODE:
     270                        vfs_out_open_node(callid, &call);
     271                        break;
     272                case VFS_OUT_STAT:
     273                        vfs_out_stat(callid, &call);
     274                        break;
     275                case VFS_OUT_SYNC:
     276                        vfs_out_sync(callid, &call);
     277                        break;
     278                default:
     279                        async_answer_0(callid, ENOTSUP);
     280                        break;
     281                }
     282        }
     283}
     284
    63285/** Register file system server.
    64286 *
     
    68290 *
    69291 * @param sess Session for communication with VFS.
    70  * @param reg  File system registration structure. It will be
    71  *             initialized by this function.
    72292 * @param info VFS info structure supplied by the file system
    73293 *             implementation.
    74  * @param conn Connection fibril for handling all calls originating in
    75  *             VFS.
     294 * @param vops Address of the vfs_out_ops_t structure.
     295 * @param lops Address of the libfs_ops_t structure.
    76296 *
    77297 * @return EOK on success or a non-zero error code on errror.
    78298 *
    79299 */
    80 int fs_register(async_sess_t *sess, fs_reg_t *reg, vfs_info_t *info,
    81     async_client_conn_t conn)
     300int fs_register(async_sess_t *sess, vfs_info_t *info, vfs_out_ops_t *vops,
     301    libfs_ops_t *lops)
    82302{
    83303        /*
     
    104324       
    105325        /*
     326         * Set VFS_OUT and libfs operations.
     327         */
     328        vfs_out_ops = vops;
     329        libfs_ops = lops;
     330
     331        /*
    106332         * Ask VFS for callback connection.
    107333         */
    108         async_connect_to_me(exch, 0, 0, 0, conn, NULL);
     334        async_connect_to_me(exch, 0, 0, 0, vfs_connection, NULL);
    109335       
    110336        /*
    111337         * Allocate piece of address space for PLB.
    112338         */
    113         reg->plb_ro = as_get_mappable_page(PLB_SIZE);
    114         if (!reg->plb_ro) {
     339        reg.plb_ro = as_get_mappable_page(PLB_SIZE);
     340        if (!reg.plb_ro) {
    115341                async_exchange_end(exch);
    116342                async_wait_for(req, NULL);
     
    121347         * Request sharing the Path Lookup Buffer with VFS.
    122348         */
    123         rc = async_share_in_start_0_0(exch, reg->plb_ro, PLB_SIZE);
     349        rc = async_share_in_start_0_0(exch, reg.plb_ro, PLB_SIZE);
    124350       
    125351        async_exchange_end(exch);
     
    134360         */
    135361        async_wait_for(req, NULL);
    136         reg->fs_handle = (int) IPC_GET_ARG1(answer);
     362        reg.fs_handle = (int) IPC_GET_ARG1(answer);
    137363       
    138364        /*
     
    140366         * the same connection fibril as well.
    141367         */
    142         async_set_client_connection(conn);
     368        async_set_client_connection(vfs_connection);
    143369       
    144370        return IPC_GET_RETVAL(answer);
     
    151377
    152378void libfs_mount(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_callid_t rid,
    153     ipc_call_t *request)
    154 {
    155         devmap_handle_t mp_devmap_handle = (devmap_handle_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         devmap_handle_t mr_devmap_handle = (devmap_handle_t) IPC_GET_ARG4(*request);
     379    ipc_call_t *req)
     380{
     381        devmap_handle_t mp_devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
     382        fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*req);
     383        fs_handle_t mr_fs_handle = (fs_handle_t) IPC_GET_ARG3(*req);
     384        devmap_handle_t mr_devmap_handle = (devmap_handle_t) IPC_GET_ARG4(*req);
    159385       
    160386        async_sess_t *mountee_sess = async_clone_receive(EXCHANGE_PARALLEL);
     
    212438}
    213439
    214 void libfs_unmount(libfs_ops_t *ops, ipc_callid_t rid, ipc_call_t *request)
    215 {
    216         devmap_handle_t mp_devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    217         fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*request);
     440void libfs_unmount(libfs_ops_t *ops, ipc_callid_t rid, ipc_call_t *req)
     441{
     442        devmap_handle_t mp_devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
     443        fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*req);
    218444        fs_node_t *fn;
    219445        int res;
     
    259485}
    260486
     487static char plb_get_char(unsigned pos)
     488{
     489        return reg.plb_ro[pos % PLB_SIZE];
     490}
     491
    261492/** Lookup VFS triplet by name in the file system name space.
    262493 *
     
    273504 */
    274505void 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);
     506    ipc_call_t *req)
     507{
     508        unsigned int first = IPC_GET_ARG1(*req);
     509        unsigned int last = IPC_GET_ARG2(*req);
    279510        unsigned int next = first;
    280         devmap_handle_t devmap_handle = IPC_GET_ARG3(*request);
    281         int lflag = IPC_GET_ARG4(*request);
    282         fs_index_t index = IPC_GET_ARG5(*request);
     511        devmap_handle_t devmap_handle = IPC_GET_ARG3(*req);
     512        int lflag = IPC_GET_ARG4(*req);
     513        fs_index_t index = IPC_GET_ARG5(*req);
    283514        char component[NAME_MAX + 1];
    284515        int len;
     
    298529                async_exch_t *exch = async_exchange_begin(cur->mp_data.sess);
    299530                async_forward_slow(rid, exch, VFS_OUT_LOOKUP, next, last,
    300                     cur->mp_data.devmap_handle, lflag, index, IPC_FF_ROUTE_FROM_ME);
     531                    cur->mp_data.devmap_handle, lflag, index,
     532                    IPC_FF_ROUTE_FROM_ME);
    301533                async_exchange_end(exch);
    302534               
     
    306538       
    307539        /* Eat slash */
    308         if (ops->plb_get_char(next) == '/')
     540        if (plb_get_char(next) == '/')
    309541                next++;
    310542       
     
    319551                /* Collect the component */
    320552                len = 0;
    321                 while ((next <= last) && (ops->plb_get_char(next) != '/')) {
     553                while ((next <= last) && (plb_get_char(next) != '/')) {
    322554                        if (len + 1 == NAME_MAX) {
    323555                                /* Component length overflow */
     
    325557                                goto out;
    326558                        }
    327                         component[len++] = ops->plb_get_char(next);
     559                        component[len++] = plb_get_char(next);
    328560                        /* Process next character */
    329561                        next++;
     
    357589                       
    358590                        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.devmap_handle, lflag, index,
     591                        async_forward_slow(rid, exch, VFS_OUT_LOOKUP, next,
     592                            last, tmp->mp_data.devmap_handle, lflag, index,
    361593                            IPC_FF_ROUTE_FROM_ME);
    362594                        async_exchange_end(exch);
     
    451683                        len = 0;
    452684                        while (next <= last) {
    453                                 if (ops->plb_get_char(next) == '/') {
     685                                if (plb_get_char(next) == '/') {
    454686                                        /* More than one component */
    455687                                        async_answer_0(rid, ENOENT);
     
    463695                                }
    464696                               
    465                                 component[len++] = ops->plb_get_char(next);
     697                                component[len++] = plb_get_char(next);
    466698                                /* Process next character */
    467699                                next++;
     
    637869        rc = ops->node_open(fn);
    638870        aoff64_t size = ops->size_get(fn);
    639         async_answer_4(rid, rc, LOWER32(size), UPPER32(size), ops->lnkcnt_get(fn),
     871        async_answer_4(rid, rc, LOWER32(size), UPPER32(size),
     872            ops->lnkcnt_get(fn),
    640873            (ops->is_file(fn) ? L_FILE : 0) | (ops->is_directory(fn) ? L_DIRECTORY : 0));
    641874       
  • uspace/lib/fs/libfs.h

    r6a44ee4 refcebe1  
    4343
    4444typedef struct {
     45        int (* mounted)(devmap_handle_t, const char *, fs_index_t *, aoff64_t *,
     46            unsigned *);
     47        int (* unmounted)(devmap_handle_t);
     48        int (* read)(devmap_handle_t, fs_index_t, aoff64_t, size_t *);
     49        int (* write)(devmap_handle_t, fs_index_t, aoff64_t, size_t *,
     50            aoff64_t *);
     51        int (* truncate)(devmap_handle_t, fs_index_t, aoff64_t);
     52        int (* close)(devmap_handle_t, fs_index_t);
     53        int (* destroy)(devmap_handle_t, fs_index_t);
     54        int (* sync)(devmap_handle_t, fs_index_t);
     55} vfs_out_ops_t;
     56
     57typedef struct {
    4558        bool mp_active;
    4659        async_sess_t *sess;
     
    7184        int (* has_children)(bool *, fs_node_t *);
    7285        /*
    73          * The second set of methods are usually mere getters that do not return
    74          * an integer error code.
     86         * The second set of methods are usually mere getters that do not
     87         * return an integer error code.
    7588         */
    7689        fs_index_t (* index_get)(fs_node_t *);
    7790        aoff64_t (* size_get)(fs_node_t *);
    7891        unsigned int (* lnkcnt_get)(fs_node_t *);
    79         char (* plb_get_char)(unsigned pos);
    8092        bool (* is_directory)(fs_node_t *);
    8193        bool (* is_file)(fs_node_t *);
     
    88100} fs_reg_t;
    89101
    90 extern int fs_register(async_sess_t *, fs_reg_t *, vfs_info_t *,
    91     async_client_conn_t);
     102extern int fs_register(async_sess_t *, vfs_info_t *, vfs_out_ops_t *,
     103    libfs_ops_t *);
    92104
    93105extern void fs_node_initialize(fs_node_t *);
    94 
    95 extern void libfs_mount(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
    96 extern void libfs_unmount(libfs_ops_t *, ipc_callid_t, ipc_call_t *);
    97 extern void libfs_lookup(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
    98 extern void libfs_stat(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
    99 extern void libfs_open_node(libfs_ops_t *, fs_handle_t, ipc_callid_t,
    100     ipc_call_t *);
    101106
    102107#endif
  • uspace/srv/fs/devfs/devfs.c

    r6a44ee4 refcebe1  
    5757};
    5858
    59 fs_reg_t devfs_reg;
    60 
    61 static void devfs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    62 {
    63         if (iid)
    64                 async_answer_0(iid, EOK);
    65        
    66         while (true) {
    67                 ipc_call_t call;
    68                 ipc_callid_t callid = async_get_call(&call);
    69                
    70                 if (!IPC_GET_IMETHOD(call))
    71                         return;
    72                
    73                 switch (IPC_GET_IMETHOD(call)) {
    74                 case VFS_OUT_MOUNTED:
    75                         devfs_mounted(callid, &call);
    76                         break;
    77                 case VFS_OUT_MOUNT:
    78                         devfs_mount(callid, &call);
    79                         break;
    80                 case VFS_OUT_UNMOUNTED:
    81                         devfs_unmounted(callid, &call);
    82                         break;
    83                 case VFS_OUT_UNMOUNT:
    84                         devfs_unmount(callid, &call);
    85                         break;
    86                 case VFS_OUT_LOOKUP:
    87                         devfs_lookup(callid, &call);
    88                         break;
    89                 case VFS_OUT_OPEN_NODE:
    90                         devfs_open_node(callid, &call);
    91                         break;
    92                 case VFS_OUT_STAT:
    93                         devfs_stat(callid, &call);
    94                         break;
    95                 case VFS_OUT_READ:
    96                         devfs_read(callid, &call);
    97                         break;
    98                 case VFS_OUT_WRITE:
    99                         devfs_write(callid, &call);
    100                         break;
    101                 case VFS_OUT_TRUNCATE:
    102                         devfs_truncate(callid, &call);
    103                         break;
    104                 case VFS_OUT_CLOSE:
    105                         devfs_close(callid, &call);
    106                         break;
    107                 case VFS_OUT_SYNC:
    108                         devfs_sync(callid, &call);
    109                         break;
    110                 case VFS_OUT_DESTROY:
    111                         devfs_destroy(callid, &call);
    112                         break;
    113                 default:
    114                         async_answer_0(callid, ENOTSUP);
    115                         break;
    116                 }
    117         }
    118 }
    119 
    12059int main(int argc, char *argv[])
    12160{
     
    13473        }
    13574       
    136         int rc = fs_register(vfs_sess, &devfs_reg, &devfs_vfs_info,
    137             devfs_connection);
     75        int rc = fs_register(vfs_sess, &devfs_vfs_info, &devfs_ops,
     76            &devfs_libfs_ops);
    13877        if (rc != EOK) {
    13978                printf("%s: Failed to register file system (%d)\n", NAME, rc);
     
    15291 * @}
    15392 */
     93
  • uspace/srv/fs/devfs/devfs.h

    r6a44ee4 refcebe1  
    3636#include <libfs.h>
    3737
    38 extern fs_reg_t devfs_reg;
     38extern vfs_out_ops_t devfs_ops;
     39extern libfs_ops_t devfs_libfs_ops;
    3940
    4041#endif
  • uspace/srv/fs/devfs/devfs_ops.c

    r6a44ee4 refcebe1  
    403403}
    404404
    405 static char devfs_plb_get_char(unsigned pos)
    406 {
    407         return devfs_reg.plb_ro[pos % PLB_SIZE];
    408 }
    409 
    410405static bool devfs_is_directory(fs_node_t *fn)
    411406{
     
    447442        .size_get = devfs_size_get,
    448443        .lnkcnt_get = devfs_lnkcnt_get,
    449         .plb_get_char = devfs_plb_get_char,
    450444        .is_directory = devfs_is_directory,
    451445        .is_file = devfs_is_file,
     
    462456}
    463457
    464 void devfs_mounted(ipc_callid_t rid, ipc_call_t *request)
    465 {
    466         char *opts;
    467        
    468         /* Accept the mount options */
    469         sysarg_t retval = async_data_write_accept((void **) &opts, true, 0, 0,
    470             0, NULL);
    471         if (retval != EOK) {
    472                 async_answer_0(rid, retval);
    473                 return;
    474         }
    475        
    476         free(opts);
    477         async_answer_3(rid, EOK, 0, 0, 0);
    478 }
    479 
    480 void devfs_mount(ipc_callid_t rid, ipc_call_t *request)
    481 {
    482         libfs_mount(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request);
    483 }
    484 
    485 void devfs_unmounted(ipc_callid_t rid, ipc_call_t *request)
    486 {
    487         async_answer_0(rid, ENOTSUP);
    488 }
    489 
    490 void devfs_unmount(ipc_callid_t rid, ipc_call_t *request)
    491 {
    492         libfs_unmount(&devfs_libfs_ops, rid, request);
    493 }
    494 
    495 void devfs_lookup(ipc_callid_t rid, ipc_call_t *request)
    496 {
    497         libfs_lookup(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request);
    498 }
    499 
    500 void devfs_open_node(ipc_callid_t rid, ipc_call_t *request)
    501 {
    502         libfs_open_node(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request);
    503 }
    504 
    505 void devfs_stat(ipc_callid_t rid, ipc_call_t *request)
    506 {
    507         libfs_stat(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request);
    508 }
    509 
    510 void devfs_read(ipc_callid_t rid, ipc_call_t *request)
    511 {
    512         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    513         aoff64_t pos =
    514             (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
    515        
     458static int devfs_mounted(devmap_handle_t devmap_handle, const char *opts,
     459    fs_index_t *index, aoff64_t *size, unsigned *lnkcnt)
     460{
     461        *index = 0;
     462        *size = 0;
     463        *lnkcnt = 0;
     464        return EOK;
     465}
     466
     467static int devfs_unmounted(devmap_handle_t devmap_handle)
     468{
     469        return ENOTSUP;
     470}
     471
     472static int
     473devfs_read(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos,
     474    size_t *rbytes)
     475{
    516476        if (index == 0) {
    517477                ipc_callid_t callid;
     
    519479                if (!async_data_read_receive(&callid, &size)) {
    520480                        async_answer_0(callid, EINVAL);
    521                         async_answer_0(rid, EINVAL);
    522                         return;
     481                        return EINVAL;
    523482                }
    524483               
     
    540499                        async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
    541500                        free(desc);
    542                         async_answer_1(rid, EOK, 1);
    543                         return;
     501                        *rbytes = 1;
     502                        return EOK;
    544503                }
    545504               
     
    555514                                async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
    556515                                free(desc);
    557                                 async_answer_1(rid, EOK, 1);
    558                                 return;
     516                                *rbytes = 1;
     517                                return EOK;
    559518                        }
    560519                       
     
    563522               
    564523                async_answer_0(callid, ENOENT);
    565                 async_answer_1(rid, ENOENT, 0);
    566                 return;
     524                return ENOENT;
    567525        }
    568526       
     
    575533                if (!async_data_read_receive(&callid, &size)) {
    576534                        async_answer_0(callid, EINVAL);
    577                         async_answer_0(rid, EINVAL);
    578                         return;
     535                        return EINVAL;
    579536                }
    580537               
     
    585542                        async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1);
    586543                        free(desc);
    587                         async_answer_1(rid, EOK, 1);
    588                         return;
     544                        *rbytes = 1;
     545                        return EOK;
    589546                }
    590547               
    591548                free(desc);
    592549                async_answer_0(callid, ENOENT);
    593                 async_answer_1(rid, ENOENT, 0);
    594                 return;
     550                return ENOENT;
    595551        }
    596552       
     
    606562                if (lnk == NULL) {
    607563                        fibril_mutex_unlock(&devices_mutex);
    608                         async_answer_0(rid, ENOENT);
    609                         return;
     564                        return ENOENT;
    610565                }
    611566               
     
    617572                        fibril_mutex_unlock(&devices_mutex);
    618573                        async_answer_0(callid, EINVAL);
    619                         async_answer_0(rid, EINVAL);
    620                         return;
     574                        return EINVAL;
    621575                }
    622576               
     
    625579               
    626580                ipc_call_t answer;
    627                 aid_t msg = async_send_3(exch, IPC_GET_IMETHOD(*request),
    628                     IPC_GET_ARG1(*request), IPC_GET_ARG2(*request),
    629                     IPC_GET_ARG3(*request), &answer);
     581                aid_t msg = async_send_4(exch, VFS_OUT_READ, devmap_handle,
     582                    index, LOWER32(pos), UPPER32(pos), &answer);
    630583               
    631584                /* Forward the IPC_M_DATA_READ request to the driver */
     
    639592                sysarg_t rc;
    640593                async_wait_for(msg, &rc);
    641                 size_t bytes = IPC_GET_ARG1(answer);
    642                
    643                 /* Driver reply is the final result of the whole operation */
    644                 async_answer_1(rid, rc, bytes);
    645                 return;
    646         }
    647        
    648         async_answer_0(rid, ENOENT);
    649 }
    650 
    651 void devfs_write(ipc_callid_t rid, ipc_call_t *request)
    652 {
    653         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    654         if (index == 0) {
    655                 async_answer_0(rid, ENOTSUP);
    656                 return;
    657         }
     594               
     595                *rbytes = IPC_GET_ARG1(answer);
     596                return rc;
     597        }
     598       
     599        return ENOENT;
     600}
     601
     602static int
     603devfs_write(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos,
     604    size_t *wbytes, aoff64_t *nsize)
     605{
     606        if (index == 0)
     607                return ENOTSUP;
    658608       
    659609        devmap_handle_type_t type = devmap_handle_probe(index);
     
    661611        if (type == DEV_HANDLE_NAMESPACE) {
    662612                /* Namespace directory */
    663                 async_answer_0(rid, ENOTSUP);
    664                 return;
     613                return ENOTSUP;
    665614        }
    666615       
     
    675624                if (lnk == NULL) {
    676625                        fibril_mutex_unlock(&devices_mutex);
    677                         async_answer_0(rid, ENOENT);
    678                         return;
     626                        return ENOENT;
    679627                }
    680628               
     
    686634                        fibril_mutex_unlock(&devices_mutex);
    687635                        async_answer_0(callid, EINVAL);
    688                         async_answer_0(rid, EINVAL);
    689                         return;
     636                        return EINVAL;
    690637                }
    691638               
     
    694641               
    695642                ipc_call_t answer;
    696                 aid_t msg = async_send_3(exch, IPC_GET_IMETHOD(*request),
    697                     IPC_GET_ARG1(*request), IPC_GET_ARG2(*request),
    698                     IPC_GET_ARG3(*request), &answer);
     643                aid_t msg = async_send_4(exch, VFS_OUT_WRITE, devmap_handle,
     644                    index, LOWER32(pos), UPPER32(pos), &answer);
    699645               
    700646                /* Forward the IPC_M_DATA_WRITE request to the driver */
     
    708654                sysarg_t rc;
    709655                async_wait_for(msg, &rc);
    710                 size_t bytes = IPC_GET_ARG1(answer);
    711                
    712                 /* Driver reply is the final result of the whole operation */
    713                 async_answer_1(rid, rc, bytes);
    714                 return;
    715         }
    716        
    717         async_answer_0(rid, ENOENT);
    718 }
    719 
    720 void devfs_truncate(ipc_callid_t rid, ipc_call_t *request)
    721 {
    722         async_answer_0(rid, ENOTSUP);
    723 }
    724 
    725 void devfs_close(ipc_callid_t rid, ipc_call_t *request)
    726 {
    727         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    728        
    729         if (index == 0) {
    730                 async_answer_0(rid, EOK);
    731                 return;
    732         }
     656               
     657                *wbytes = IPC_GET_ARG1(answer);
     658                *nsize = 0;
     659                return rc;
     660        }
     661       
     662        return ENOENT;
     663}
     664
     665static int
     666devfs_truncate(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t size)
     667{
     668        return ENOTSUP;
     669}
     670
     671static int devfs_close(devmap_handle_t devmap_handle, fs_index_t index)
     672{
     673        if (index == 0)
     674                return EOK;
    733675       
    734676        devmap_handle_type_t type = devmap_handle_probe(index);
     
    736678        if (type == DEV_HANDLE_NAMESPACE) {
    737679                /* Namespace directory */
    738                 async_answer_0(rid, EOK);
    739                 return;
     680                return EOK;
    740681        }
    741682       
     
    749690                if (lnk == NULL) {
    750691                        fibril_mutex_unlock(&devices_mutex);
    751                         async_answer_0(rid, ENOENT);
    752                         return;
     692                        return ENOENT;
    753693                }
    754694               
     
    764704                fibril_mutex_unlock(&devices_mutex);
    765705               
    766                 async_answer_0(rid, EOK);
    767                 return;
    768         }
    769        
    770         async_answer_0(rid, ENOENT);
    771 }
    772 
    773 void devfs_sync(ipc_callid_t rid, ipc_call_t *request)
    774 {
    775         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    776        
    777         if (index == 0) {
    778                 async_answer_0(rid, EOK);
    779                 return;
    780         }
     706                return EOK;
     707        }
     708       
     709        return ENOENT;
     710}
     711
     712static int devfs_sync(devmap_handle_t devmap_handle, fs_index_t index)
     713{
     714        if (index == 0)
     715                return EOK;
    781716       
    782717        devmap_handle_type_t type = devmap_handle_probe(index);
     
    784719        if (type == DEV_HANDLE_NAMESPACE) {
    785720                /* Namespace directory */
    786                 async_answer_0(rid, EOK);
    787                 return;
     721                return EOK;
    788722        }
    789723       
     
    797731                if (lnk == NULL) {
    798732                        fibril_mutex_unlock(&devices_mutex);
    799                         async_answer_0(rid, ENOENT);
    800                         return;
     733                        return ENOENT;
    801734                }
    802735               
     
    808741               
    809742                ipc_call_t answer;
    810                 aid_t msg = async_send_2(exch, IPC_GET_IMETHOD(*request),
    811                     IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), &answer);
     743                aid_t msg = async_send_2(exch, VFS_OUT_SYNC, devmap_handle,
     744                    index, &answer);
    812745               
    813746                async_exchange_end(exch);
     
    819752                async_wait_for(msg, &rc);
    820753               
    821                 /* Driver reply is the final result of the whole operation */
    822                 async_answer_0(rid, rc);
    823                 return;
    824         }
    825        
    826         async_answer_0(rid, ENOENT);
    827 }
    828 
    829 void devfs_destroy(ipc_callid_t rid, ipc_call_t *request)
    830 {
    831         async_answer_0(rid, ENOTSUP);
    832 }
     754                return rc;
     755        }
     756       
     757        return  ENOENT;
     758}
     759
     760static int devfs_destroy(devmap_handle_t devmap_handle, fs_index_t index)
     761{
     762        return ENOTSUP;
     763}
     764
     765vfs_out_ops_t devfs_ops = {
     766        .mounted = devfs_mounted,
     767        .unmounted = devfs_unmounted,
     768        .read = devfs_read,
     769        .write = devfs_write,
     770        .truncate = devfs_truncate,
     771        .close = devfs_close,
     772        .destroy = devfs_destroy,
     773        .sync = devfs_sync,
     774};
    833775
    834776/**
  • uspace/srv/fs/devfs/devfs_ops.h

    r6a44ee4 refcebe1  
    3434#define DEVFS_DEVFS_OPS_H_
    3535
    36 #include <ipc/common.h>
    3736#include <bool.h>
    3837
    3938extern bool devfs_init(void);
    40 
    41 extern void devfs_mounted(ipc_callid_t, ipc_call_t *);
    42 extern void devfs_mount(ipc_callid_t, ipc_call_t *);
    43 extern void devfs_unmounted(ipc_callid_t, ipc_call_t *);
    44 extern void devfs_unmount(ipc_callid_t, ipc_call_t *);
    45 extern void devfs_lookup(ipc_callid_t, ipc_call_t *);
    46 extern void devfs_open_node(ipc_callid_t, ipc_call_t *);
    47 extern void devfs_stat(ipc_callid_t, ipc_call_t *);
    48 extern void devfs_sync(ipc_callid_t, ipc_call_t *);
    49 extern void devfs_read(ipc_callid_t, ipc_call_t *);
    50 extern void devfs_write(ipc_callid_t, ipc_call_t *);
    51 extern void devfs_truncate(ipc_callid_t, ipc_call_t *);
    52 extern void devfs_close(ipc_callid_t, ipc_call_t *);
    53 extern void devfs_destroy(ipc_callid_t, ipc_call_t *);
    5439
    5540#endif
  • uspace/srv/fs/ext2fs/ext2fs.c

    r6a44ee4 refcebe1  
    11/*
    22 * Copyright (c) 2006 Martin Decky
    3  * Copyright (c) 2008 Jakub Jermar
    43 * Copyright (c) 2011 Martin Sucha
    54 * All rights reserved.
     
    5554};
    5655
    57 fs_reg_t ext2fs_reg;
    58 
    59 /**
    60  * This connection fibril processes VFS requests from VFS.
    61  *
    62  * In order to support simultaneous VFS requests, our design is as follows.
    63  * The connection fibril accepts VFS requests from VFS. If there is only one
    64  * instance of the fibril, VFS will need to serialize all VFS requests it sends
    65  * to EXT2FS. To overcome this bottleneck, VFS can send EXT2FS the IPC_M_CONNECT_ME_TO
    66  * call. In that case, a new connection fibril will be created, which in turn
    67  * will accept the call. Thus, a new phone will be opened for VFS.
    68  *
    69  * There are few issues with this arrangement. First, VFS can run out of
    70  * available phones. In that case, VFS can close some other phones or use one
    71  * phone for more serialized requests. Similarily, EXT2FS can refuse to duplicate
    72  * the connection. VFS should then just make use of already existing phones and
    73  * route its requests through them. To avoid paying the fibril creation price
    74  * upon each request, EXT2FS might want to keep the connections open after the
    75  * request has been completed.
    76  */
    77 static void ext2fs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    78 {
    79         if (iid) {
    80                 /*
    81                  * This only happens for connections opened by
    82                  * IPC_M_CONNECT_ME_TO calls as opposed to callback connections
    83                  * created by IPC_M_CONNECT_TO_ME.
    84                  */
    85                 async_answer_0(iid, EOK);
    86         }
    87        
    88         dprintf(NAME ": connection opened\n");
    89         while (true) {
    90                 ipc_call_t call;
    91                 ipc_callid_t callid = async_get_call(&call);
    92                
    93                 if (!IPC_GET_IMETHOD(call))
    94                         return;
    95                
    96                 switch (IPC_GET_IMETHOD(call)) {
    97                 case VFS_OUT_MOUNTED:
    98                         ext2fs_mounted(callid, &call);
    99                         break;
    100                 case VFS_OUT_MOUNT:
    101                         ext2fs_mount(callid, &call);
    102                         break;
    103                 case VFS_OUT_UNMOUNTED:
    104                         ext2fs_unmounted(callid, &call);
    105                         break;
    106                 case VFS_OUT_UNMOUNT:
    107                         ext2fs_unmount(callid, &call);
    108                         break;
    109                 case VFS_OUT_LOOKUP:
    110                         ext2fs_lookup(callid, &call);
    111                         break;
    112                 case VFS_OUT_READ:
    113                         ext2fs_read(callid, &call);
    114                         break;
    115                 case VFS_OUT_WRITE:
    116                         ext2fs_write(callid, &call);
    117                         break;
    118                 case VFS_OUT_TRUNCATE:
    119                         ext2fs_truncate(callid, &call);
    120                         break;
    121                 case VFS_OUT_STAT:
    122                         ext2fs_stat(callid, &call);
    123                         break;
    124                 case VFS_OUT_CLOSE:
    125                         ext2fs_close(callid, &call);
    126                         break;
    127                 case VFS_OUT_DESTROY:
    128                         ext2fs_destroy(callid, &call);
    129                         break;
    130                 case VFS_OUT_OPEN_NODE:
    131                         ext2fs_open_node(callid, &call);
    132                         break;
    133                 case VFS_OUT_SYNC:
    134                         ext2fs_sync(callid, &call);
    135                         break;
    136                 default:
    137                         async_answer_0(callid, ENOTSUP);
    138                         break;
    139                 }
    140         }
    141 }
    142 
    14356int main(int argc, char **argv)
    14457{
     
    15871        }       
    15972               
    160         rc = fs_register(vfs_sess, &ext2fs_reg, &ext2fs_vfs_info, ext2fs_connection);
     73        rc = fs_register(vfs_sess, &ext2fs_vfs_info, &ext2fs_ops,
     74            &ext2fs_libfs_ops);
    16175        if (rc != EOK) {
    16276                fprintf(stdout, NAME ": Failed to register fs (%d)\n", rc);
  • uspace/srv/fs/ext2fs/ext2fs.h

    r6a44ee4 refcebe1  
    11/*
    2  * Copyright (c) 2008 Jakub Jermar
    32 * Copyright (c) 2011 Martin Sucha
    43 * All rights reserved.
     
    3635
    3736#include <libext2.h>
    38 #include <fibril_synch.h>
    3937#include <libfs.h>
    40 #include <atomic.h>
    4138#include <sys/types.h>
    42 #include <bool.h>
    43 #include "../../vfs/vfs.h"
    44 
    45 #ifndef dprintf
    46 #define dprintf(...)    printf(__VA_ARGS__)
    47 #endif
    4839
    4940#define min(a, b)               ((a) < (b) ? (a) : (b))
    5041
    51 extern fs_reg_t ext2fs_reg;
     42extern vfs_out_ops_t ext2fs_ops;
     43extern libfs_ops_t ext2fs_libfs_ops;
    5244
    5345extern int ext2fs_global_init(void);
    5446extern int ext2fs_global_fini(void);
    55 extern void ext2fs_mounted(ipc_callid_t, ipc_call_t *);
    56 extern void ext2fs_mount(ipc_callid_t, ipc_call_t *);
    57 extern void ext2fs_unmounted(ipc_callid_t, ipc_call_t *);
    58 extern void ext2fs_unmount(ipc_callid_t, ipc_call_t *);
    59 extern void ext2fs_lookup(ipc_callid_t, ipc_call_t *);
    60 extern void ext2fs_read(ipc_callid_t, ipc_call_t *);
    61 extern void ext2fs_write(ipc_callid_t, ipc_call_t *);
    62 extern void ext2fs_truncate(ipc_callid_t, ipc_call_t *);
    63 extern void ext2fs_stat(ipc_callid_t, ipc_call_t *);
    64 extern void ext2fs_close(ipc_callid_t, ipc_call_t *);
    65 extern void ext2fs_destroy(ipc_callid_t, ipc_call_t *);
    66 extern void ext2fs_open_node(ipc_callid_t, ipc_call_t *);
    67 extern void ext2fs_stat(ipc_callid_t, ipc_call_t *);
    68 extern void ext2fs_sync(ipc_callid_t, ipc_call_t *);
    6947
    7048#endif
  • uspace/srv/fs/ext2fs/ext2fs_ops.c

    r6a44ee4 refcebe1  
    11/*
    2  * Copyright (c) 2008 Jakub Jermar
    32 * Copyright (c) 2011 Martin Sucha
    43 * All rights reserved.
     
    8786 */
    8887static int ext2fs_instance_get(devmap_handle_t, ext2fs_instance_t **);
    89 static void ext2fs_read_directory(ipc_callid_t, ipc_callid_t, aoff64_t,
    90         size_t, ext2fs_instance_t *, ext2_inode_ref_t *);
    91 static void ext2fs_read_file(ipc_callid_t, ipc_callid_t, aoff64_t,
    92         size_t, ext2fs_instance_t *, ext2_inode_ref_t *);
     88static int ext2fs_read_directory(ipc_callid_t, aoff64_t, size_t,
     89    ext2fs_instance_t *, ext2_inode_ref_t *, size_t *);
     90static int ext2fs_read_file(ipc_callid_t, aoff64_t, size_t, ext2fs_instance_t *,
     91    ext2_inode_ref_t *, size_t *);
    9392static bool ext2fs_is_dots(const uint8_t *, size_t);
    9493static int ext2fs_node_get_core(fs_node_t **, ext2fs_instance_t *, fs_index_t);
     
    111110static aoff64_t ext2fs_size_get(fs_node_t *);
    112111static unsigned ext2fs_lnkcnt_get(fs_node_t *);
    113 static char ext2fs_plb_get_char(unsigned);
    114112static bool ext2fs_is_directory(fs_node_t *);
    115113static bool ext2fs_is_file(fs_node_t *node);
     
    538536        EXT2FS_DBG("%u", count);
    539537        return count;
    540 }
    541 
    542 char ext2fs_plb_get_char(unsigned pos)
    543 {
    544         return ext2fs_reg.plb_ro[pos % PLB_SIZE];
    545538}
    546539
     
    586579        .size_get = ext2fs_size_get,
    587580        .lnkcnt_get = ext2fs_lnkcnt_get,
    588         .plb_get_char = ext2fs_plb_get_char,
    589581        .is_directory = ext2fs_is_directory,
    590582        .is_file = ext2fs_is_file,
     
    596588 */
    597589
    598 void ext2fs_mounted(ipc_callid_t rid, ipc_call_t *request)
    599 {
    600         EXT2FS_DBG("");
    601         int rc;
    602         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     590static int ext2fs_mounted(devmap_handle_t devmap_handle, const char *opts,
     591   fs_index_t *index, aoff64_t *size, unsigned *lnkcnt)
     592{
     593        EXT2FS_DBG("");
     594        int rc;
    603595        ext2_filesystem_t *fs;
    604596        ext2fs_instance_t *inst;
    605597        bool read_only;
    606598       
    607         /* Accept the mount options */
    608         char *opts;
    609         rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL);
    610        
    611         if (rc != EOK) {
    612                 async_answer_0(rid, rc);
    613                 return;
    614         }
    615 
    616         free(opts);
    617        
    618599        /* Allocate libext2 filesystem structure */
    619600        fs = (ext2_filesystem_t *) malloc(sizeof(ext2_filesystem_t));
    620         if (fs == NULL) {
    621                 async_answer_0(rid, ENOMEM);
    622                 return;
    623         }
     601        if (fs == NULL)
     602                return ENOMEM;
    624603       
    625604        /* Allocate instance structure */
     
    627606        if (inst == NULL) {
    628607                free(fs);
    629                 async_answer_0(rid, ENOMEM);
    630                 return;
     608                return ENOMEM;
    631609        }
    632610       
     
    636614                free(fs);
    637615                free(inst);
    638                 async_answer_0(rid, rc);
    639                 return;
     616                return rc;
    640617        }
    641618       
     
    646623                free(fs);
    647624                free(inst);
    648                 async_answer_0(rid, rc);
    649                 return;
     625                return rc;
    650626        }
    651627       
     
    656632                free(fs);
    657633                free(inst);
    658                 async_answer_0(rid, rc);
    659                 return;
     634                return rc;
    660635        }
    661636       
     
    673648                free(fs);
    674649                free(inst);
    675                 async_answer_0(rid, rc);
    676                 return;
     650                return rc;
    677651        }
    678652        ext2fs_node_t *enode = EXT2FS_NODE(root_node);
     
    683657        fibril_mutex_unlock(&instance_list_mutex);
    684658       
    685         async_answer_3(rid, EOK,
    686             EXT2_INODE_ROOT_INDEX,
    687             0,
    688             ext2_inode_get_usage_count(enode->inode_ref->inode));
     659        *index = EXT2_INODE_ROOT_INDEX;
     660        *size = 0;
     661        *lnkcnt = ext2_inode_get_usage_count(enode->inode_ref->inode);
    689662       
    690663        ext2fs_node_put(root_node);
    691 }
    692 
    693 void ext2fs_mount(ipc_callid_t rid, ipc_call_t *request)
    694 {
    695         EXT2FS_DBG("");
    696         libfs_mount(&ext2fs_libfs_ops, ext2fs_reg.fs_handle, rid, request);
    697 }
    698 
    699 void ext2fs_unmounted(ipc_callid_t rid, ipc_call_t *request)
    700 {
    701         EXT2FS_DBG("");
    702         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     664
     665        return EOK;
     666}
     667
     668static int ext2fs_unmounted(devmap_handle_t devmap_handle)
     669{
     670        EXT2FS_DBG("");
    703671        ext2fs_instance_t *inst;
    704672        int rc;
     
    706674        rc = ext2fs_instance_get(devmap_handle, &inst);
    707675       
    708         if (rc != EOK) {
    709                 async_answer_0(rid, rc);
    710                 return;
    711         }
     676        if (rc != EOK)
     677                return rc;
    712678       
    713679        fibril_mutex_lock(&open_nodes_lock);
     
    716682        if (inst->open_nodes_count != 0) {
    717683                fibril_mutex_unlock(&open_nodes_lock);
    718                 async_answer_0(rid, EBUSY);
    719                 return;
     684                return EBUSY;
    720685        }
    721686       
     
    729694        ext2_filesystem_fini(inst->filesystem);
    730695       
    731         async_answer_0(rid, EOK);
    732 }
    733 
    734 void ext2fs_unmount(ipc_callid_t rid, ipc_call_t *request)
    735 {
    736         EXT2FS_DBG("");
    737         libfs_unmount(&ext2fs_libfs_ops, rid, request);
    738 }
    739 
    740 void ext2fs_lookup(ipc_callid_t rid, ipc_call_t *request)
    741 {
    742         EXT2FS_DBG("");
    743         libfs_lookup(&ext2fs_libfs_ops, ext2fs_reg.fs_handle, rid, request);
    744 }
    745 
    746 void ext2fs_read(ipc_callid_t rid, ipc_call_t *request)
    747 {
    748         EXT2FS_DBG("");
    749         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    750         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    751         aoff64_t pos =
    752             (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
     696        return EOK;
     697}
     698
     699static int
     700ext2fs_read(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos,
     701    size_t *rbytes)
     702{
     703        EXT2FS_DBG("");
    753704       
    754705        ext2fs_instance_t *inst;
     
    763714        if (!async_data_read_receive(&callid, &size)) {
    764715                async_answer_0(callid, EINVAL);
    765                 async_answer_0(rid, EINVAL);
    766                 return;
     716                return EINVAL;
    767717        }
    768718       
     
    770720        if (rc != EOK) {
    771721                async_answer_0(callid, rc);
    772                 async_answer_0(rid, rc);
    773                 return;
     722                return rc;
    774723        }
    775724       
     
    777726        if (rc != EOK) {
    778727                async_answer_0(callid, rc);
    779                 async_answer_0(rid, rc);
    780                 return;
     728                return rc;
    781729        }
    782730       
    783731        if (ext2_inode_is_type(inst->filesystem->superblock, inode_ref->inode,
    784                     EXT2_INODE_MODE_FILE)) {
    785                 ext2fs_read_file(rid, callid, pos, size, inst, inode_ref);
    786         }
    787         else if (ext2_inode_is_type(inst->filesystem->superblock, inode_ref->inode,
    788                     EXT2_INODE_MODE_DIRECTORY)) {
    789                 ext2fs_read_directory(rid, callid, pos, size, inst, inode_ref);
    790         }
    791         else {
     732            EXT2_INODE_MODE_FILE)) {
     733                rc = ext2fs_read_file(callid, pos, size, inst, inode_ref,
     734                    rbytes);
     735        } else if (ext2_inode_is_type(inst->filesystem->superblock,
     736            inode_ref->inode, EXT2_INODE_MODE_DIRECTORY)) {
     737                rc = ext2fs_read_directory(callid, pos, size, inst, inode_ref,
     738                    rbytes);
     739        } else {
    792740                /* Other inode types not supported */
    793741                async_answer_0(callid, ENOTSUP);
    794                 async_answer_0(rid, ENOTSUP);
     742                rc = ENOTSUP;
    795743        }
    796744       
    797745        ext2_filesystem_put_inode_ref(inode_ref);
    798746       
     747        return rc;
    799748}
    800749
     
    814763}
    815764
    816 void ext2fs_read_directory(ipc_callid_t rid, ipc_callid_t callid, aoff64_t pos,
    817         size_t size, ext2fs_instance_t *inst, ext2_inode_ref_t *inode_ref)
     765int ext2fs_read_directory(ipc_callid_t callid, aoff64_t pos, size_t size,
     766    ext2fs_instance_t *inst, ext2_inode_ref_t *inode_ref, size_t *rbytes)
    818767{
    819768        ext2_directory_iterator_t it;
     
    827776        if (rc != EOK) {
    828777                async_answer_0(callid, rc);
    829                 async_answer_0(rid, rc);
    830                 return;
     778                return rc;
    831779        }
    832780       
     
    841789               
    842790                name_size = ext2_directory_entry_ll_get_name_length(
    843                         inst->filesystem->superblock, it.current);
     791                    inst->filesystem->superblock, it.current);
    844792               
    845793                /* skip . and .. */
     
    849797               
    850798                /* The on-disk entry does not contain \0 at the end
    851                         * end of entry name, so we copy it to new buffer
    852                         * and add the \0 at the end
    853                         */
     799                 * end of entry name, so we copy it to new buffer
     800                 * and add the \0 at the end
     801                 */
    854802                buf = malloc(name_size+1);
    855803                if (buf == NULL) {
    856804                        ext2_directory_iterator_fini(&it);
    857805                        async_answer_0(callid, ENOMEM);
    858                         async_answer_0(rid, ENOMEM);
    859                         return;
     806                        return ENOMEM;
    860807                }
    861808                memcpy(buf, &it.current->name, name_size);
    862                 *(buf+name_size) = 0;
     809                *(buf + name_size) = 0;
    863810                found = true;
    864                 (void) async_data_read_finalize(callid, buf, name_size+1);
     811                (void) async_data_read_finalize(callid, buf, name_size + 1);
    865812                free(buf);
    866813                break;
     
    871818                        ext2_directory_iterator_fini(&it);
    872819                        async_answer_0(callid, rc);
    873                         async_answer_0(rid, rc);
    874                         return;
     820                        return rc;
    875821                }
    876822        }
     
    878824        if (found) {
    879825                rc = ext2_directory_iterator_next(&it);
    880                 if (rc != EOK) {
    881                         async_answer_0(rid, rc);
    882                         return;
    883                 }
     826                if (rc != EOK)
     827                        return rc;
    884828                next = it.current_offset;
    885829        }
    886830       
    887831        rc = ext2_directory_iterator_fini(&it);
    888         if (rc != EOK) {
    889                 async_answer_0(rid, rc);
    890                 return;
    891         }
     832        if (rc != EOK)
     833                return rc;
    892834       
    893835        if (found) {
    894                 async_answer_1(rid, EOK, next-pos);
    895         }
    896         else {
     836                *rbytes = next - pos;
     837                return EOK;
     838        } else {
    897839                async_answer_0(callid, ENOENT);
    898                 async_answer_0(rid, ENOENT);
    899         }
    900 }
    901 
    902 void ext2fs_read_file(ipc_callid_t rid, ipc_callid_t callid, aoff64_t pos,
    903         size_t size, ext2fs_instance_t *inst, ext2_inode_ref_t *inode_ref)
     840                return ENOENT;
     841        }
     842}
     843
     844int ext2fs_read_file(ipc_callid_t callid, aoff64_t pos, size_t size,
     845    ext2fs_instance_t *inst, ext2_inode_ref_t *inode_ref, size_t *rbytes)
    904846{
    905847        int rc;
     
    919861                /* Read 0 bytes successfully */
    920862                async_data_read_finalize(callid, NULL, 0);
    921                 async_answer_1(rid, EOK, 0);
    922                 return;
     863                *rbytes = 0;
     864                return EOK;
    923865        }
    924866       
     
    939881        if (rc != EOK) {
    940882                async_answer_0(callid, rc);
    941                 async_answer_0(rid, rc);
    942                 return;
     883                return rc;
    943884        }
    944885       
     
    952893                if (buffer == NULL) {
    953894                        async_answer_0(callid, ENOMEM);
    954                         async_answer_0(rid, ENOMEM);
    955                         return;
     895                        return ENOMEM;
    956896                }
    957897               
     
    959899               
    960900                async_data_read_finalize(callid, buffer, bytes);
    961                 async_answer_1(rid, EOK, bytes);
     901                *rbytes = bytes;
    962902               
    963903                free(buffer);
    964904               
    965                 return;
     905                return EOK;
    966906        }
    967907       
     
    970910        if (rc != EOK) {
    971911                async_answer_0(callid, rc);
    972                 async_answer_0(rid, rc);
    973                 return;
     912                return rc;
    974913        }
    975914       
     
    978917       
    979918        rc = block_put(block);
    980         if (rc != EOK) {
    981                 async_answer_0(rid, rc);
    982                 return;
    983         }
    984                
    985         async_answer_1(rid, EOK, bytes);
    986 }
    987 
    988 void ext2fs_write(ipc_callid_t rid, ipc_call_t *request)
    989 {
    990         EXT2FS_DBG("");
    991 //      devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    992 //      fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    993 //      aoff64_t pos =
    994 //          (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
    995        
    996         // TODO
    997         async_answer_0(rid, ENOTSUP);
    998 }
    999 
    1000 void ext2fs_truncate(ipc_callid_t rid, ipc_call_t *request)
    1001 {
    1002         EXT2FS_DBG("");
    1003 //      devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    1004 //      fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    1005 //      aoff64_t size =
    1006 //          (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
    1007        
    1008         // TODO
    1009         async_answer_0(rid, ENOTSUP);
    1010 }
    1011 
    1012 void ext2fs_close(ipc_callid_t rid, ipc_call_t *request)
    1013 {
    1014         EXT2FS_DBG("");
    1015         async_answer_0(rid, EOK);
    1016 }
    1017 
    1018 void ext2fs_destroy(ipc_callid_t rid, ipc_call_t *request)
    1019 {
    1020         EXT2FS_DBG("");
    1021 //      devmap_handle_t devmap_handle = (devmap_handle_t)IPC_GET_ARG1(*request);
    1022 //      fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
    1023        
    1024         // TODO
    1025         async_answer_0(rid, ENOTSUP);
    1026 }
    1027 
    1028 void ext2fs_open_node(ipc_callid_t rid, ipc_call_t *request)
    1029 {
    1030         EXT2FS_DBG("");
    1031         libfs_open_node(&ext2fs_libfs_ops, ext2fs_reg.fs_handle, rid, request);
    1032 }
    1033 
    1034 void ext2fs_stat(ipc_callid_t rid, ipc_call_t *request)
    1035 {
    1036         EXT2FS_DBG("");
    1037         libfs_stat(&ext2fs_libfs_ops, ext2fs_reg.fs_handle, rid, request);
    1038 }
    1039 
    1040 void ext2fs_sync(ipc_callid_t rid, ipc_call_t *request)
    1041 {
    1042         EXT2FS_DBG("");
    1043 //      devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    1044 //      fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    1045        
    1046         // TODO
    1047         async_answer_0(rid, ENOTSUP);
    1048 }
     919        if (rc != EOK)
     920                return rc;
     921       
     922        *rbytes = bytes;
     923        return EOK;
     924}
     925
     926static int
     927ext2fs_write(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos,
     928    size_t *wbytes, aoff64_t *nsize)
     929{
     930        EXT2FS_DBG("");
     931        return ENOTSUP;
     932}
     933
     934static int
     935ext2fs_truncate(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t size)
     936{
     937        EXT2FS_DBG("");
     938        return ENOTSUP;
     939}
     940
     941static int ext2fs_close(devmap_handle_t devmap_handle, fs_index_t index)
     942{
     943        EXT2FS_DBG("");
     944        return EOK;
     945}
     946
     947static int ext2fs_destroy(devmap_handle_t devmap_handle, fs_index_t index)
     948{
     949        EXT2FS_DBG("");
     950        return ENOTSUP;
     951}
     952
     953static int ext2fs_sync(devmap_handle_t devmap_handle, fs_index_t index)
     954{
     955        EXT2FS_DBG("");
     956        return ENOTSUP;
     957}
     958
     959vfs_out_ops_t ext2fs_ops = {
     960        .mounted = ext2fs_mounted,
     961        .unmounted = ext2fs_unmounted,
     962        .read = ext2fs_read,
     963        .write = ext2fs_write,
     964        .truncate = ext2fs_truncate,
     965        .close = ext2fs_close,
     966        .destroy = ext2fs_destroy,
     967        .sync = ext2fs_sync,
     968};
    1049969
    1050970/**
    1051971 * @}
    1052972 */
     973
  • uspace/srv/fs/fat/fat.c

    r6a44ee4 refcebe1  
    5656};
    5757
    58 fs_reg_t fat_reg;
    59 
    60 /**
    61  * This connection fibril processes VFS requests from VFS.
    62  *
    63  * In order to support simultaneous VFS requests, our design is as follows.
    64  * The connection fibril accepts VFS requests from VFS. If there is only one
    65  * instance of the fibril, VFS will need to serialize all VFS requests it sends
    66  * to FAT. To overcome this bottleneck, VFS can send FAT the IPC_M_CONNECT_ME_TO
    67  * call. In that case, a new connection fibril will be created, which in turn
    68  * will accept the call. Thus, a new phone will be opened for VFS.
    69  *
    70  * There are few issues with this arrangement. First, VFS can run out of
    71  * available phones. In that case, VFS can close some other phones or use one
    72  * phone for more serialized requests. Similarily, FAT can refuse to duplicate
    73  * the connection. VFS should then just make use of already existing phones and
    74  * route its requests through them. To avoid paying the fibril creation price
    75  * upon each request, FAT might want to keep the connections open after the
    76  * request has been completed.
    77  */
    78 static void fat_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    79 {
    80         if (iid) {
    81                 /*
    82                  * This only happens for connections opened by
    83                  * IPC_M_CONNECT_ME_TO calls as opposed to callback connections
    84                  * created by IPC_M_CONNECT_TO_ME.
    85                  */
    86                 async_answer_0(iid, EOK);
    87         }
    88        
    89         dprintf(NAME ": connection opened\n");
    90        
    91         while (true) {
    92                 ipc_call_t call;
    93                 ipc_callid_t callid = async_get_call(&call);
    94                
    95                 if (!IPC_GET_IMETHOD(call))
    96                         return;
    97                
    98                 switch (IPC_GET_IMETHOD(call)) {
    99                 case VFS_OUT_MOUNTED:
    100                         fat_mounted(callid, &call);
    101                         break;
    102                 case VFS_OUT_MOUNT:
    103                         fat_mount(callid, &call);
    104                         break;
    105                 case VFS_OUT_UNMOUNTED:
    106                         fat_unmounted(callid, &call);
    107                         break;
    108                 case VFS_OUT_UNMOUNT:
    109                         fat_unmount(callid, &call);
    110                         break;
    111                 case VFS_OUT_LOOKUP:
    112                         fat_lookup(callid, &call);
    113                         break;
    114                 case VFS_OUT_READ:
    115                         fat_read(callid, &call);
    116                         break;
    117                 case VFS_OUT_WRITE:
    118                         fat_write(callid, &call);
    119                         break;
    120                 case VFS_OUT_TRUNCATE:
    121                         fat_truncate(callid, &call);
    122                         break;
    123                 case VFS_OUT_STAT:
    124                         fat_stat(callid, &call);
    125                         break;
    126                 case VFS_OUT_CLOSE:
    127                         fat_close(callid, &call);
    128                         break;
    129                 case VFS_OUT_DESTROY:
    130                         fat_destroy(callid, &call);
    131                         break;
    132                 case VFS_OUT_OPEN_NODE:
    133                         fat_open_node(callid, &call);
    134                         break;
    135                 case VFS_OUT_SYNC:
    136                         fat_sync(callid, &call);
    137                         break;
    138                 default:
    139                         async_answer_0(callid, ENOTSUP);
    140                         break;
    141                 }
    142         }
    143 }
    144 
    14558int main(int argc, char **argv)
    14659{
     
    15871        }
    15972       
    160         rc = fs_register(vfs_sess, &fat_reg, &fat_vfs_info, fat_connection);
     73        rc = fs_register(vfs_sess, &fat_vfs_info, &fat_ops, &fat_libfs_ops);
    16174        if (rc != EOK) {
    16275                fat_idx_fini();
  • uspace/srv/fs/fat/fat.h

    r6a44ee4 refcebe1  
    224224} fat_node_t;
    225225
    226 extern fs_reg_t fat_reg;
    227 
    228 extern void fat_mounted(ipc_callid_t, ipc_call_t *);
    229 extern void fat_mount(ipc_callid_t, ipc_call_t *);
    230 extern void fat_unmounted(ipc_callid_t, ipc_call_t *);
    231 extern void fat_unmount(ipc_callid_t, ipc_call_t *);
    232 extern void fat_lookup(ipc_callid_t, ipc_call_t *);
    233 extern void fat_read(ipc_callid_t, ipc_call_t *);
    234 extern void fat_write(ipc_callid_t, ipc_call_t *);
    235 extern void fat_truncate(ipc_callid_t, ipc_call_t *);
    236 extern void fat_stat(ipc_callid_t, ipc_call_t *);
    237 extern void fat_close(ipc_callid_t, ipc_call_t *);
    238 extern void fat_destroy(ipc_callid_t, ipc_call_t *);
    239 extern void fat_open_node(ipc_callid_t, ipc_call_t *);
    240 extern void fat_stat(ipc_callid_t, ipc_call_t *);
    241 extern void fat_sync(ipc_callid_t, ipc_call_t *);
     226extern vfs_out_ops_t fat_ops;
     227extern libfs_ops_t fat_libfs_ops;
    242228
    243229extern int fat_idx_get_new(fat_idx_t **, devmap_handle_t);
  • uspace/srv/fs/fat/fat_ops.c

    r6a44ee4 refcebe1  
    8585static aoff64_t fat_size_get(fs_node_t *);
    8686static unsigned fat_lnkcnt_get(fs_node_t *);
    87 static char fat_plb_get_char(unsigned);
    8887static bool fat_is_directory(fs_node_t *);
    8988static bool fat_is_file(fs_node_t *node);
     
    901900}
    902901
    903 char fat_plb_get_char(unsigned pos)
    904 {
    905         return fat_reg.plb_ro[pos % PLB_SIZE];
    906 }
    907 
    908902bool fat_is_directory(fs_node_t *fn)
    909903{
     
    936930        .size_get = fat_size_get,
    937931        .lnkcnt_get = fat_lnkcnt_get,
    938         .plb_get_char = fat_plb_get_char,
    939932        .is_directory = fat_is_directory,
    940933        .is_file = fat_is_file,
     
    943936
    944937/*
    945  * VFS operations.
     938 * FAT VFS_OUT operations.
    946939 */
    947940
    948 void fat_mounted(ipc_callid_t rid, ipc_call_t *request)
    949 {
    950         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     941static int
     942fat_mounted(devmap_handle_t devmap_handle, const char *opts, fs_index_t *index,
     943    aoff64_t *size, unsigned *linkcnt)
     944{
    951945        enum cache_mode cmode;
    952946        fat_bs_t *bs;
    953        
    954         /* Accept the mount options */
    955         char *opts;
    956         int rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL);
    957        
    958         if (rc != EOK) {
    959                 async_answer_0(rid, rc);
    960                 return;
    961         }
    962 
     947        int rc;
     948       
    963949        /* Check for option enabling write through. */
    964950        if (str_cmp(opts, "wtcache") == 0)
     
    967953                cmode = CACHE_MODE_WB;
    968954
    969         free(opts);
    970 
    971955        /* initialize libblock */
    972956        rc = block_init(EXCHANGE_SERIALIZE, devmap_handle, BS_SIZE);
    973         if (rc != EOK) {
    974                 async_answer_0(rid, rc);
    975                 return;
    976         }
     957        if (rc != EOK)
     958                return rc;
    977959
    978960        /* prepare the boot block */
     
    980962        if (rc != EOK) {
    981963                block_fini(devmap_handle);
    982                 async_answer_0(rid, rc);
    983                 return;
     964                return rc;
    984965        }
    985966
     
    989970        if (BPS(bs) != BS_SIZE) {
    990971                block_fini(devmap_handle);
    991                 async_answer_0(rid, ENOTSUP);
    992                 return;
     972                return ENOTSUP;
    993973        }
    994974
     
    997977        if (rc != EOK) {
    998978                block_fini(devmap_handle);
    999                 async_answer_0(rid, rc);
    1000                 return;
     979                return rc;
    1001980        }
    1002981
     
    1006985                (void) block_cache_fini(devmap_handle);
    1007986                block_fini(devmap_handle);
    1008                 async_answer_0(rid, rc);
    1009                 return;
     987                return rc;
    1010988        }
    1011989
     
    1014992                (void) block_cache_fini(devmap_handle);
    1015993                block_fini(devmap_handle);
    1016                 async_answer_0(rid, rc);
    1017                 return;
     994                return rc;
    1018995        }
    1019996
     
    10241001                block_fini(devmap_handle);
    10251002                fat_idx_fini_by_devmap_handle(devmap_handle);
    1026                 async_answer_0(rid, ENOMEM);
    1027                 return;
     1003                return ENOMEM;
    10281004        }
    10291005        fs_node_initialize(rfn);
     
    10341010                block_fini(devmap_handle);
    10351011                fat_idx_fini_by_devmap_handle(devmap_handle);
    1036                 async_answer_0(rid, ENOMEM);
    1037                 return;
     1012                return ENOMEM;
    10381013        }
    10391014        fat_node_initialize(rootp);
     
    10461021                block_fini(devmap_handle);
    10471022                fat_idx_fini_by_devmap_handle(devmap_handle);
    1048                 async_answer_0(rid, ENOMEM);
    1049                 return;
     1023                return ENOMEM;
    10501024        }
    10511025        assert(ridxp->index == 0);
     
    10641038        fibril_mutex_unlock(&ridxp->lock);
    10651039
    1066         async_answer_3(rid, EOK, ridxp->index, rootp->size, rootp->lnkcnt);
    1067 }
    1068 
    1069 void fat_mount(ipc_callid_t rid, ipc_call_t *request)
    1070 {
    1071         libfs_mount(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
    1072 }
    1073 
    1074 void fat_unmounted(ipc_callid_t rid, ipc_call_t *request)
    1075 {
    1076         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     1040        *index = ridxp->index;
     1041        *size = rootp->size;
     1042        *linkcnt = rootp->lnkcnt;
     1043
     1044        return EOK;
     1045}
     1046
     1047static int fat_unmounted(devmap_handle_t devmap_handle)
     1048{
    10771049        fs_node_t *fn;
    10781050        fat_node_t *nodep;
     
    10801052
    10811053        rc = fat_root_get(&fn, devmap_handle);
    1082         if (rc != EOK) {
    1083                 async_answer_0(rid, rc);
    1084                 return;
    1085         }
     1054        if (rc != EOK)
     1055                return rc;
    10861056        nodep = FAT_NODE(fn);
    10871057
     
    10921062        if (nodep->refcnt != 2) {
    10931063                (void) fat_node_put(fn);
    1094                 async_answer_0(rid, EBUSY);
    1095                 return;
     1064                return EBUSY;
    10961065        }
    10971066       
     
    11121081        block_fini(devmap_handle);
    11131082
    1114         async_answer_0(rid, EOK);
    1115 }
    1116 
    1117 void fat_unmount(ipc_callid_t rid, ipc_call_t *request)
    1118 {
    1119         libfs_unmount(&fat_libfs_ops, rid, request);
    1120 }
    1121 
    1122 void fat_lookup(ipc_callid_t rid, ipc_call_t *request)
    1123 {
    1124         libfs_lookup(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
    1125 }
    1126 
    1127 void fat_read(ipc_callid_t rid, ipc_call_t *request)
    1128 {
    1129         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    1130         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    1131         aoff64_t pos =
    1132             (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
     1083        return EOK;
     1084}
     1085
     1086static int
     1087fat_read(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos,
     1088    size_t *rbytes)
     1089{
    11331090        fs_node_t *fn;
    11341091        fat_node_t *nodep;
     
    11391096
    11401097        rc = fat_node_get(&fn, devmap_handle, index);
    1141         if (rc != EOK) {
    1142                 async_answer_0(rid, rc);
    1143                 return;
    1144         }
    1145         if (!fn) {
    1146                 async_answer_0(rid, ENOENT);
    1147                 return;
    1148         }
     1098        if (rc != EOK)
     1099                return rc;
     1100        if (!fn)
     1101                return ENOENT;
    11491102        nodep = FAT_NODE(fn);
    11501103
     
    11541107                fat_node_put(fn);
    11551108                async_answer_0(callid, EINVAL);
    1156                 async_answer_0(rid, EINVAL);
    1157                 return;
     1109                return EINVAL;
    11581110        }
    11591111
     
    11781130                                fat_node_put(fn);
    11791131                                async_answer_0(callid, rc);
    1180                                 async_answer_0(rid, rc);
    1181                                 return;
     1132                                return rc;
    11821133                        }
    11831134                        (void) async_data_read_finalize(callid,
     
    11861137                        if (rc != EOK) {
    11871138                                fat_node_put(fn);
    1188                                 async_answer_0(rid, rc);
    1189                                 return;
     1139                                return rc;
    11901140                        }
    11911141                }
     
    12441194                rc = fat_node_put(fn);
    12451195                async_answer_0(callid, rc != EOK ? rc : ENOENT);
    1246                 async_answer_1(rid, rc != EOK ? rc : ENOENT, 0);
    1247                 return;
     1196                *rbytes = 0;
     1197                return rc != EOK ? rc : ENOENT;
    12481198
    12491199err:
    12501200                (void) fat_node_put(fn);
    12511201                async_answer_0(callid, rc);
    1252                 async_answer_0(rid, rc);
    1253                 return;
     1202                return rc;
    12541203
    12551204hit:
     
    12591208
    12601209        rc = fat_node_put(fn);
    1261         async_answer_1(rid, rc, (sysarg_t)bytes);
    1262 }
    1263 
    1264 void fat_write(ipc_callid_t rid, ipc_call_t *request)
    1265 {
    1266         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    1267         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    1268         aoff64_t pos =
    1269             (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
     1210        *rbytes = bytes;
     1211        return rc;
     1212}
     1213
     1214static int
     1215fat_write(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos,
     1216    size_t *wbytes, aoff64_t *nsize)
     1217{
    12701218        fs_node_t *fn;
    12711219        fat_node_t *nodep;
    12721220        fat_bs_t *bs;
    1273         size_t bytes, size;
     1221        size_t bytes;
    12741222        block_t *b;
    12751223        aoff64_t boundary;
     
    12781226       
    12791227        rc = fat_node_get(&fn, devmap_handle, index);
    1280         if (rc != EOK) {
    1281                 async_answer_0(rid, rc);
    1282                 return;
    1283         }
    1284         if (!fn) {
    1285                 async_answer_0(rid, ENOENT);
    1286                 return;
    1287         }
     1228        if (rc != EOK)
     1229                return rc;
     1230        if (!fn)
     1231                return ENOENT;
    12881232        nodep = FAT_NODE(fn);
    12891233       
     
    12931237                (void) fat_node_put(fn);
    12941238                async_answer_0(callid, EINVAL);
    1295                 async_answer_0(rid, EINVAL);
    1296                 return;
     1239                return EINVAL;
    12971240        }
    12981241
     
    13221265                        (void) fat_node_put(fn);
    13231266                        async_answer_0(callid, rc);
    1324                         async_answer_0(rid, rc);
    1325                         return;
     1267                        return rc;
    13261268                }
    13271269                rc = fat_block_get(&b, bs, nodep, pos / BPS(bs), flags);
     
    13291271                        (void) fat_node_put(fn);
    13301272                        async_answer_0(callid, rc);
    1331                         async_answer_0(rid, rc);
    1332                         return;
     1273                        return rc;
    13331274                }
    13341275                (void) async_data_write_finalize(callid,
     
    13381279                if (rc != EOK) {
    13391280                        (void) fat_node_put(fn);
    1340                         async_answer_0(rid, rc);
    1341                         return;
     1281                        return rc;
    13421282                }
    13431283                if (pos + bytes > nodep->size) {
     
    13451285                        nodep->dirty = true;    /* need to sync node */
    13461286                }
    1347                 size = nodep->size;
     1287                *wbytes = bytes;
     1288                *nsize = nodep->size;
    13481289                rc = fat_node_put(fn);
    1349                 async_answer_2(rid, rc, bytes, nodep->size);
    1350                 return;
     1290                return rc;
    13511291        } else {
    13521292                /*
     
    13641304                        (void) fat_node_put(fn);
    13651305                        async_answer_0(callid, rc);
    1366                         async_answer_0(rid, rc);
    1367                         return;
     1306                        return rc;
    13681307                }
    13691308                /* zero fill any gaps */
     
    13731312                        (void) fat_node_put(fn);
    13741313                        async_answer_0(callid, rc);
    1375                         async_answer_0(rid, rc);
    1376                         return;
     1314                        return rc;
    13771315                }
    13781316                rc = _fat_block_get(&b, bs, devmap_handle, lcl, NULL,
     
    13821320                        (void) fat_node_put(fn);
    13831321                        async_answer_0(callid, rc);
    1384                         async_answer_0(rid, rc);
    1385                         return;
     1322                        return rc;
    13861323                }
    13871324                (void) async_data_write_finalize(callid,
     
    13921329                        (void) fat_free_clusters(bs, devmap_handle, mcl);
    13931330                        (void) fat_node_put(fn);
    1394                         async_answer_0(rid, rc);
    1395                         return;
     1331                        return rc;
    13961332                }
    13971333                /*
     
    14031339                        (void) fat_free_clusters(bs, devmap_handle, mcl);
    14041340                        (void) fat_node_put(fn);
    1405                         async_answer_0(rid, rc);
    1406                         return;
    1407                 }
    1408                 nodep->size = size = pos + bytes;
     1341                        return rc;
     1342                }
     1343                *nsize = nodep->size = pos + bytes;
     1344                rc = fat_node_put(fn);
    14091345                nodep->dirty = true;            /* need to sync node */
    1410                 rc = fat_node_put(fn);
    1411                 async_answer_2(rid, rc, bytes, size);
    1412                 return;
    1413         }
    1414 }
    1415 
    1416 void fat_truncate(ipc_callid_t rid, ipc_call_t *request)
    1417 {
    1418         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    1419         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    1420         aoff64_t size =
    1421             (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
     1346                *wbytes = bytes;
     1347                return rc;
     1348        }
     1349}
     1350
     1351static int
     1352fat_truncate(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t size)
     1353{
    14221354        fs_node_t *fn;
    14231355        fat_node_t *nodep;
     
    14261358
    14271359        rc = fat_node_get(&fn, devmap_handle, index);
    1428         if (rc != EOK) {
    1429                 async_answer_0(rid, rc);
    1430                 return;
    1431         }
    1432         if (!fn) {
    1433                 async_answer_0(rid, ENOENT);
    1434                 return;
    1435         }
     1360        if (rc != EOK)
     1361                return rc;
     1362        if (!fn)
     1363                return ENOENT;
    14361364        nodep = FAT_NODE(fn);
    14371365
     
    14771405out:
    14781406        fat_node_put(fn);
    1479         async_answer_0(rid, rc);
    1480         return;
    1481 }
    1482 
    1483 void fat_close(ipc_callid_t rid, ipc_call_t *request)
    1484 {
    1485         async_answer_0(rid, EOK);
    1486 }
    1487 
    1488 void fat_destroy(ipc_callid_t rid, ipc_call_t *request)
    1489 {
    1490         devmap_handle_t devmap_handle = (devmap_handle_t)IPC_GET_ARG1(*request);
    1491         fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
     1407        return rc;
     1408}
     1409
     1410static int fat_close(devmap_handle_t devmap_handle, fs_index_t index)
     1411{
     1412        return EOK;
     1413}
     1414
     1415static int fat_destroy(devmap_handle_t devmap_handle, fs_index_t index)
     1416{
    14921417        fs_node_t *fn;
    14931418        fat_node_t *nodep;
     
    14951420
    14961421        rc = fat_node_get(&fn, devmap_handle, index);
    1497         if (rc != EOK) {
    1498                 async_answer_0(rid, rc);
    1499                 return;
    1500         }
    1501         if (!fn) {
    1502                 async_answer_0(rid, ENOENT);
    1503                 return;
    1504         }
     1422        if (rc != EOK)
     1423                return rc;
     1424        if (!fn)
     1425                return ENOENT;
    15051426
    15061427        nodep = FAT_NODE(fn);
     
    15121433
    15131434        rc = fat_destroy_node(fn);
    1514         async_answer_0(rid, rc);
    1515 }
    1516 
    1517 void fat_open_node(ipc_callid_t rid, ipc_call_t *request)
    1518 {
    1519         libfs_open_node(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
    1520 }
    1521 
    1522 void fat_stat(ipc_callid_t rid, ipc_call_t *request)
    1523 {
    1524         libfs_stat(&fat_libfs_ops, fat_reg.fs_handle, rid, request);
    1525 }
    1526 
    1527 void fat_sync(ipc_callid_t rid, ipc_call_t *request)
    1528 {
    1529         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    1530         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    1531        
     1435        return rc;
     1436}
     1437
     1438static int fat_sync(devmap_handle_t devmap_handle, fs_index_t index)
     1439{
    15321440        fs_node_t *fn;
    15331441        int rc = fat_node_get(&fn, devmap_handle, index);
    1534         if (rc != EOK) {
    1535                 async_answer_0(rid, rc);
    1536                 return;
    1537         }
    1538         if (!fn) {
    1539                 async_answer_0(rid, ENOENT);
    1540                 return;
    1541         }
     1442        if (rc != EOK)
     1443                return rc;
     1444        if (!fn)
     1445                return ENOENT;
    15421446       
    15431447        fat_node_t *nodep = FAT_NODE(fn);
     
    15471451       
    15481452        fat_node_put(fn);
    1549         async_answer_0(rid, rc);
    1550 }
     1453        return rc;
     1454}
     1455
     1456vfs_out_ops_t fat_ops = {
     1457        .mounted = fat_mounted,
     1458        .unmounted = fat_unmounted,
     1459        .read = fat_read,
     1460        .write = fat_write,
     1461        .truncate = fat_truncate,
     1462        .close = fat_close,
     1463        .destroy = fat_destroy,
     1464        .sync = fat_sync,
     1465};
    15511466
    15521467/**
  • uspace/srv/fs/tmpfs/tmpfs.c

    r6a44ee4 refcebe1  
    6161};
    6262
    63 fs_reg_t tmpfs_reg;
    64 
    65 /**
    66  * This connection fibril processes VFS requests from VFS.
    67  *
    68  * In order to support simultaneous VFS requests, our design is as follows.
    69  * The connection fibril accepts VFS requests from VFS. If there is only one
    70  * instance of the fibril, VFS will need to serialize all VFS requests it sends
    71  * to FAT. To overcome this bottleneck, VFS can send TMPFS the
    72  * IPC_M_CONNECT_ME_TO call. In that case, a new connection fibril will be
    73  * created, which in turn will accept the call. Thus, a new phone will be
    74  * opened for VFS.
    75  *
    76  * There are few issues with this arrangement. First, VFS can run out of
    77  * available phones. In that case, VFS can close some other phones or use one
    78  * phone for more serialized requests. Similarily, TMPFS can refuse to duplicate
    79  * the connection. VFS should then just make use of already existing phones and
    80  * route its requests through them. To avoid paying the fibril creation price
    81  * upon each request, TMPFS might want to keep the connections open after the
    82  * request has been completed.
    83  */
    84 static void tmpfs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    85 {
    86         if (iid) {
    87                 /*
    88                  * This only happens for connections opened by
    89                  * IPC_M_CONNECT_ME_TO calls as opposed to callback connections
    90                  * created by IPC_M_CONNECT_TO_ME.
    91                  */
    92                 async_answer_0(iid, EOK);
    93         }
    94        
    95         dprintf(NAME ": connection opened\n");
    96        
    97         while (true) {
    98                 ipc_call_t call;
    99                 ipc_callid_t callid = async_get_call(&call);
    100                
    101                 if (!IPC_GET_IMETHOD(call))
    102                         return;
    103                
    104                 switch (IPC_GET_IMETHOD(call)) {
    105                 case VFS_OUT_MOUNTED:
    106                         tmpfs_mounted(callid, &call);
    107                         break;
    108                 case VFS_OUT_MOUNT:
    109                         tmpfs_mount(callid, &call);
    110                         break;
    111                 case VFS_OUT_UNMOUNTED:
    112                         tmpfs_unmounted(callid, &call);
    113                         break;
    114                 case VFS_OUT_UNMOUNT:
    115                         tmpfs_unmount(callid, &call);
    116                         break;
    117                 case VFS_OUT_LOOKUP:
    118                         tmpfs_lookup(callid, &call);
    119                         break;
    120                 case VFS_OUT_READ:
    121                         tmpfs_read(callid, &call);
    122                         break;
    123                 case VFS_OUT_WRITE:
    124                         tmpfs_write(callid, &call);
    125                         break;
    126                 case VFS_OUT_TRUNCATE:
    127                         tmpfs_truncate(callid, &call);
    128                         break;
    129                 case VFS_OUT_CLOSE:
    130                         tmpfs_close(callid, &call);
    131                         break;
    132                 case VFS_OUT_DESTROY:
    133                         tmpfs_destroy(callid, &call);
    134                         break;
    135                 case VFS_OUT_OPEN_NODE:
    136                         tmpfs_open_node(callid, &call);
    137                         break;
    138                 case VFS_OUT_STAT:
    139                         tmpfs_stat(callid, &call);
    140                         break;
    141                 case VFS_OUT_SYNC:
    142                         tmpfs_sync(callid, &call);
    143                         break;
    144                 default:
    145                         async_answer_0(callid, ENOTSUP);
    146                         break;
    147                 }
    148         }
    149 }
    150 
    15163int main(int argc, char **argv)
    15264{
     
    16577        }
    16678       
    167         int rc = fs_register(vfs_sess, &tmpfs_reg, &tmpfs_vfs_info,
    168             tmpfs_connection);
     79        int rc = fs_register(vfs_sess, &tmpfs_vfs_info, &tmpfs_ops,
     80            &tmpfs_libfs_ops);
    16981        if (rc != EOK) {
    17082                printf(NAME ": Failed to register file system (%d)\n", rc);
  • uspace/srv/fs/tmpfs/tmpfs.h

    r6a44ee4 refcebe1  
    7070} tmpfs_node_t;
    7171
    72 extern fs_reg_t tmpfs_reg;
    73 
     72extern vfs_out_ops_t tmpfs_ops;
    7473extern libfs_ops_t tmpfs_libfs_ops;
    7574
    7675extern bool tmpfs_init(void);
    77 
    78 extern void tmpfs_mounted(ipc_callid_t, ipc_call_t *);
    79 extern void tmpfs_mount(ipc_callid_t, ipc_call_t *);
    80 extern void tmpfs_unmounted(ipc_callid_t, ipc_call_t *);
    81 extern void tmpfs_unmount(ipc_callid_t, ipc_call_t *);
    82 extern void tmpfs_lookup(ipc_callid_t, ipc_call_t *);
    83 extern void tmpfs_read(ipc_callid_t, ipc_call_t *);
    84 extern void tmpfs_write(ipc_callid_t, ipc_call_t *);
    85 extern void tmpfs_truncate(ipc_callid_t, ipc_call_t *);
    86 extern void tmpfs_stat(ipc_callid_t, ipc_call_t *);
    87 extern void tmpfs_close(ipc_callid_t, ipc_call_t *);
    88 extern void tmpfs_destroy(ipc_callid_t, ipc_call_t *);
    89 extern void tmpfs_open_node(ipc_callid_t, ipc_call_t *);
    90 extern void tmpfs_sync(ipc_callid_t, ipc_call_t *);
    91 
    9276extern bool tmpfs_restore(devmap_handle_t);
    9377
  • uspace/srv/fs/tmpfs/tmpfs_ops.c

    r6a44ee4 refcebe1  
    104104}
    105105
    106 static char tmpfs_plb_get_char(unsigned pos)
    107 {
    108         return tmpfs_reg.plb_ro[pos % PLB_SIZE];
    109 }
    110 
    111106static bool tmpfs_is_directory(fs_node_t *fn)
    112107{
     
    139134        .size_get = tmpfs_size_get,
    140135        .lnkcnt_get = tmpfs_lnkcnt_get,
    141         .plb_get_char = tmpfs_plb_get_char,
    142136        .is_directory = tmpfs_is_directory,
    143137        .is_file = tmpfs_is_file,
     
    433427}
    434428
    435 void tmpfs_mounted(ipc_callid_t rid, ipc_call_t *request)
    436 {
    437         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     429/*
     430 * Implementation of the VFS_OUT interface.
     431 */
     432
     433static int
     434tmpfs_mounted(devmap_handle_t devmap_handle, const char *opts,
     435    fs_index_t *index, aoff64_t *size, unsigned *lnkcnt)
     436{
    438437        fs_node_t *rootfn;
    439438        int rc;
    440439       
    441         /* Accept the mount options. */
    442         char *opts;
    443         rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL);
    444         if (rc != EOK) {
    445                 async_answer_0(rid, rc);
    446                 return;
    447         }
    448 
    449440        /* Check if this device is not already mounted. */
    450441        rc = tmpfs_root_get(&rootfn, devmap_handle);
    451442        if ((rc == EOK) && (rootfn)) {
    452443                (void) tmpfs_node_put(rootfn);
    453                 free(opts);
    454                 async_answer_0(rid, EEXIST);
    455                 return;
     444                return EEXIST;
    456445        }
    457446
    458447        /* Initialize TMPFS instance. */
    459         if (!tmpfs_instance_init(devmap_handle)) {
    460                 free(opts);
    461                 async_answer_0(rid, ENOMEM);
    462                 return;
    463         }
     448        if (!tmpfs_instance_init(devmap_handle))
     449                return ENOMEM;
    464450
    465451        rc = tmpfs_root_get(&rootfn, devmap_handle);
     
    467453        tmpfs_node_t *rootp = TMPFS_NODE(rootfn);
    468454        if (str_cmp(opts, "restore") == 0) {
    469                 if (tmpfs_restore(devmap_handle))
    470                         async_answer_3(rid, EOK, rootp->index, rootp->size,
    471                             rootp->lnkcnt);
    472                 else
    473                         async_answer_0(rid, ELIMIT);
    474         } else {
    475                 async_answer_3(rid, EOK, rootp->index, rootp->size,
    476                     rootp->lnkcnt);
    477         }
    478         free(opts);
    479 }
    480 
    481 void tmpfs_mount(ipc_callid_t rid, ipc_call_t *request)
    482 {
    483         libfs_mount(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request);
    484 }
    485 
    486 void tmpfs_unmounted(ipc_callid_t rid, ipc_call_t *request)
    487 {
    488         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    489 
     455                if (!tmpfs_restore(devmap_handle))
     456                        return ELIMIT;
     457        }
     458
     459        *index = rootp->index;
     460        *size = rootp->size;
     461        *lnkcnt = rootp->lnkcnt;
     462
     463        return EOK;
     464}
     465
     466static int tmpfs_unmounted(devmap_handle_t devmap_handle)
     467{
    490468        tmpfs_instance_done(devmap_handle);
    491         async_answer_0(rid, EOK);
    492 }
    493 
    494 void tmpfs_unmount(ipc_callid_t rid, ipc_call_t *request)
    495 {
    496         libfs_unmount(&tmpfs_libfs_ops, rid, request);
    497 }
    498 
    499 void tmpfs_lookup(ipc_callid_t rid, ipc_call_t *request)
    500 {
    501         libfs_lookup(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request);
    502 }
    503 
    504 void tmpfs_read(ipc_callid_t rid, ipc_call_t *request)
    505 {
    506         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    507         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    508         aoff64_t pos =
    509             (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
    510        
     469        return EOK;
     470}
     471
     472static int tmpfs_read(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos,
     473    size_t *rbytes)
     474{
    511475        /*
    512476         * Lookup the respective TMPFS node.
     
    518482        };
    519483        hlp = hash_table_find(&nodes, key);
    520         if (!hlp) {
    521                 async_answer_0(rid, ENOENT);
    522                 return;
    523         }
     484        if (!hlp)
     485                return ENOENT;
    524486        tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
    525487            nh_link);
     
    532494        if (!async_data_read_receive(&callid, &size)) {
    533495                async_answer_0(callid, EINVAL);
    534                 async_answer_0(rid, EINVAL);
    535                 return;
     496                return EINVAL;
    536497        }
    537498
     
    556517                if (lnk == NULL) {
    557518                        async_answer_0(callid, ENOENT);
    558                         async_answer_1(rid, ENOENT, 0);
    559                         return;
     519                        return ENOENT;
    560520                }
    561521
     
    567527        }
    568528
    569         /*
    570          * Answer the VFS_READ call.
    571          */
    572         async_answer_1(rid, EOK, bytes);
    573 }
    574 
    575 void tmpfs_write(ipc_callid_t rid, ipc_call_t *request)
    576 {
    577         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    578         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    579         aoff64_t pos =
    580             (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
    581        
     529        *rbytes = bytes;
     530        return EOK;
     531}
     532
     533static int
     534tmpfs_write(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos,
     535    size_t *wbytes, aoff64_t *nsize)
     536{
    582537        /*
    583538         * Lookup the respective TMPFS node.
     
    589544        };
    590545        hlp = hash_table_find(&nodes, key);
    591         if (!hlp) {
    592                 async_answer_0(rid, ENOENT);
    593                 return;
    594         }
     546        if (!hlp)
     547                return ENOENT;
    595548        tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
    596549            nh_link);
     
    603556        if (!async_data_write_receive(&callid, &size)) {
    604557                async_answer_0(callid, EINVAL);
    605                 async_answer_0(rid, EINVAL);
    606                 return;
     558                return EINVAL;
    607559        }
    608560
     
    612564        if (pos + size <= nodep->size) {
    613565                /* The file size is not changing. */
    614                 (void) async_data_write_finalize(callid, nodep->data + pos, size);
    615                 async_answer_2(rid, EOK, size, nodep->size);
    616                 return;
     566                (void) async_data_write_finalize(callid, nodep->data + pos,
     567                    size);
     568                goto out;
    617569        }
    618570        size_t delta = (pos + size) - nodep->size;
     
    627579        if (!newdata) {
    628580                async_answer_0(callid, ENOMEM);
    629                 async_answer_2(rid, EOK, 0, nodep->size);
    630                 return;
     581                size = 0;
     582                goto out;
    631583        }
    632584        /* Clear any newly allocated memory in order to emulate gaps. */
     
    635587        nodep->data = newdata;
    636588        (void) async_data_write_finalize(callid, nodep->data + pos, size);
    637         async_answer_2(rid, EOK, size, nodep->size);
    638 }
    639 
    640 void tmpfs_truncate(ipc_callid_t rid, ipc_call_t *request)
    641 {
    642         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
    643         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request);
    644         aoff64_t size =
    645             (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request));
    646        
     589
     590out:
     591        *wbytes = size;
     592        *nsize = nodep->size;
     593        return EOK;
     594}
     595
     596static int tmpfs_truncate(devmap_handle_t devmap_handle, fs_index_t index,
     597    aoff64_t size)
     598{
    647599        /*
    648600         * Lookup the respective TMPFS node.
     
    653605        };
    654606        link_t *hlp = hash_table_find(&nodes, key);
    655         if (!hlp) {
    656                 async_answer_0(rid, ENOENT);
    657                 return;
    658         }
    659         tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
    660             nh_link);
    661        
    662         if (size == nodep->size) {
    663                 async_answer_0(rid, EOK);
    664                 return;
    665         }
    666        
    667         if (size > SIZE_MAX) {
    668                 async_answer_0(rid, ENOMEM);
    669                 return;
    670         }
     607        if (!hlp)
     608                return ENOENT;
     609        tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, nh_link);
     610       
     611        if (size == nodep->size)
     612                return EOK;
     613       
     614        if (size > SIZE_MAX)
     615                return ENOMEM;
    671616       
    672617        void *newdata = realloc(nodep->data, size);
    673         if (!newdata) {
    674                 async_answer_0(rid, ENOMEM);
    675                 return;
    676         }
     618        if (!newdata)
     619                return ENOMEM;
    677620       
    678621        if (size > nodep->size) {
     
    683626        nodep->size = size;
    684627        nodep->data = newdata;
    685         async_answer_0(rid, EOK);
    686 }
    687 
    688 void tmpfs_close(ipc_callid_t rid, ipc_call_t *request)
    689 {
    690         async_answer_0(rid, EOK);
    691 }
    692 
    693 void tmpfs_destroy(ipc_callid_t rid, ipc_call_t *request)
    694 {
    695         devmap_handle_t devmap_handle = (devmap_handle_t)IPC_GET_ARG1(*request);
    696         fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request);
    697         int rc;
    698 
     628        return EOK;
     629}
     630
     631static int tmpfs_close(devmap_handle_t devmap_handle, fs_index_t index)
     632{
     633        return EOK;
     634}
     635
     636static int tmpfs_destroy(devmap_handle_t devmap_handle, fs_index_t index)
     637{
    699638        link_t *hlp;
    700639        unsigned long key[] = {
     
    703642        };
    704643        hlp = hash_table_find(&nodes, key);
    705         if (!hlp) {
    706                 async_answer_0(rid, ENOENT);
    707                 return;
    708         }
     644        if (!hlp)
     645                return ENOENT;
    709646        tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t,
    710647            nh_link);
    711         rc = tmpfs_destroy_node(FS_NODE(nodep));
    712         async_answer_0(rid, rc);
    713 }
    714 
    715 void tmpfs_open_node(ipc_callid_t rid, ipc_call_t *request)
    716 {
    717         libfs_open_node(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request);
    718 }
    719 
    720 void tmpfs_stat(ipc_callid_t rid, ipc_call_t *request)
    721 {
    722         libfs_stat(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request);
    723 }
    724 
    725 void tmpfs_sync(ipc_callid_t rid, ipc_call_t *request)
     648        return tmpfs_destroy_node(FS_NODE(nodep));
     649}
     650
     651static int tmpfs_sync(devmap_handle_t devmap_handle, fs_index_t index)
    726652{
    727653        /*
     
    729655         * thus the sync operation is a no-op.
    730656         */
    731         async_answer_0(rid, EOK);
    732 }
     657        return EOK;
     658}
     659
     660vfs_out_ops_t tmpfs_ops = {
     661        .mounted = tmpfs_mounted,
     662        .unmounted = tmpfs_unmounted,
     663        .read = tmpfs_read,
     664        .write = tmpfs_write,
     665        .truncate = tmpfs_truncate,
     666        .close = tmpfs_close,
     667        .destroy = tmpfs_destroy,
     668        .sync = tmpfs_sync,
     669};
    733670
    734671/**
    735672 * @}
    736673 */
     674
Note: See TracChangeset for help on using the changeset viewer.