Changes in uspace/lib/fs/libfs.c [44451ee:ffa2c8ef] in mainline


Ignore:
File:
1 edited

Legend:

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

    r44451ee rffa2c8ef  
    4545#include <mem.h>
    4646#include <sys/stat.h>
    47 #include <stdlib.h>
    4847
    4948#define on_error(rc, action) \
     
    6261        } while (0)
    6362
    64 static fs_reg_t reg;
    65 
    66 static vfs_out_ops_t *vfs_out_ops = NULL;
    67 static libfs_ops_t *libfs_ops = NULL;
    68 
    69 static void libfs_mount(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
    70 static void libfs_unmount(libfs_ops_t *, ipc_callid_t, ipc_call_t *);
    71 static void libfs_lookup(libfs_ops_t *, fs_handle_t, ipc_callid_t,
    72     ipc_call_t *);
    73 static void libfs_stat(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *);
    74 static void libfs_open_node(libfs_ops_t *, fs_handle_t, ipc_callid_t,
    75     ipc_call_t *);
    76 
    77 static 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)
    96                 async_answer_4(rid, EOK, index, LOWER32(size), UPPER32(size),
    97                     lnkcnt);
    98         else
    99                 async_answer_0(rid, rc);
    100 
    101         free(opts);
    102 }
    103 
    104 static void vfs_out_mount(ipc_callid_t rid, ipc_call_t *req)
    105 {
    106         libfs_mount(libfs_ops, reg.fs_handle, rid, req);
    107 }
    108 
    109 static void vfs_out_unmounted(ipc_callid_t rid, ipc_call_t *req)
    110 {
    111         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
    112         int rc;
    113 
    114         rc = vfs_out_ops->unmounted(devmap_handle);
    115 
    116         async_answer_0(rid, rc);
    117 }
    118 
    119 static void vfs_out_unmount(ipc_callid_t rid, ipc_call_t *req)
    120 {
    121                
    122         libfs_unmount(libfs_ops, rid, req);
    123 }
    124 
    125 static void vfs_out_lookup(ipc_callid_t rid, ipc_call_t *req)
    126 {
    127         libfs_lookup(libfs_ops, reg.fs_handle, rid, req);
    128 }
    129 
    130 static void vfs_out_read(ipc_callid_t rid, ipc_call_t *req)
    131 {
    132         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
    133         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
    134         aoff64_t pos = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*req),
    135             IPC_GET_ARG4(*req));
    136         size_t rbytes;
    137         int rc;
    138 
    139         rc = vfs_out_ops->read(devmap_handle, index, pos, &rbytes);
    140 
    141         if (rc == EOK)
    142                 async_answer_1(rid, EOK, rbytes);
    143         else
    144                 async_answer_0(rid, rc);
    145 }
    146 
    147 static void vfs_out_write(ipc_callid_t rid, ipc_call_t *req)
    148 {
    149         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
    150         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
    151         aoff64_t pos = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*req),
    152             IPC_GET_ARG4(*req));
    153         size_t wbytes;
    154         aoff64_t nsize;
    155         int rc;
    156 
    157         rc = vfs_out_ops->write(devmap_handle, index, pos, &wbytes, &nsize);
    158 
    159         if (rc == EOK)
    160                 async_answer_3(rid, EOK, wbytes, LOWER32(nsize), UPPER32(nsize));
    161         else
    162                 async_answer_0(rid, rc);
    163 }
    164 
    165 static void vfs_out_truncate(ipc_callid_t rid, ipc_call_t *req)
    166 {
    167         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
    168         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
    169         aoff64_t size = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*req),
    170             IPC_GET_ARG4(*req));
    171         int rc;
    172 
    173         rc = vfs_out_ops->truncate(devmap_handle, index, size);
    174 
    175         async_answer_0(rid, rc);
    176 }
    177 
    178 static void vfs_out_close(ipc_callid_t rid, ipc_call_t *req)
    179 {
    180         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
    181         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
    182         int rc;
    183 
    184         rc = vfs_out_ops->close(devmap_handle, index);
    185 
    186         async_answer_0(rid, rc);
    187 }
    188 
    189 static void vfs_out_destroy(ipc_callid_t rid, ipc_call_t *req)
    190 {
    191         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
    192         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
    193         int rc;
    194 
    195         rc = vfs_out_ops->destroy(devmap_handle, index);
    196 
    197         async_answer_0(rid, rc);
    198 }
    199 
    200 static void vfs_out_open_node(ipc_callid_t rid, ipc_call_t *req)
    201 {
    202         libfs_open_node(libfs_ops, reg.fs_handle, rid, req);
    203 }
    204 
    205 static void vfs_out_stat(ipc_callid_t rid, ipc_call_t *req)
    206 {
    207         libfs_stat(libfs_ops, reg.fs_handle, rid, req);
    208 }
    209 
    210 static void vfs_out_sync(ipc_callid_t rid, ipc_call_t *req)
    211 {
    212         devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
    213         fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req);
    214         int rc;
    215 
    216         rc = vfs_out_ops->sync(devmap_handle, index);
    217 
    218         async_answer_0(rid, rc);
    219 }
    220 
    221 static void vfs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    222 {
    223         if (iid) {
    224                 /*
    225                  * This only happens for connections opened by
    226                  * IPC_M_CONNECT_ME_TO calls as opposed to callback connections
    227                  * created by IPC_M_CONNECT_TO_ME.
    228                  */
    229                 async_answer_0(iid, EOK);
    230         }
    231        
    232         while (true) {
    233                 ipc_call_t call;
    234                 ipc_callid_t callid = async_get_call(&call);
    235                
    236                 if (!IPC_GET_IMETHOD(call))
    237                         return;
    238                
    239                 switch (IPC_GET_IMETHOD(call)) {
    240                 case VFS_OUT_MOUNTED:
    241                         vfs_out_mounted(callid, &call);
    242                         break;
    243                 case VFS_OUT_MOUNT:
    244                         vfs_out_mount(callid, &call);
    245                         break;
    246                 case VFS_OUT_UNMOUNTED:
    247                         vfs_out_unmounted(callid, &call);
    248                         break;
    249                 case VFS_OUT_UNMOUNT:
    250                         vfs_out_unmount(callid, &call);
    251                         break;
    252                 case VFS_OUT_LOOKUP:
    253                         vfs_out_lookup(callid, &call);
    254                         break;
    255                 case VFS_OUT_READ:
    256                         vfs_out_read(callid, &call);
    257                         break;
    258                 case VFS_OUT_WRITE:
    259                         vfs_out_write(callid, &call);
    260                         break;
    261                 case VFS_OUT_TRUNCATE:
    262                         vfs_out_truncate(callid, &call);
    263                         break;
    264                 case VFS_OUT_CLOSE:
    265                         vfs_out_close(callid, &call);
    266                         break;
    267                 case VFS_OUT_DESTROY:
    268                         vfs_out_destroy(callid, &call);
    269                         break;
    270                 case VFS_OUT_OPEN_NODE:
    271                         vfs_out_open_node(callid, &call);
    272                         break;
    273                 case VFS_OUT_STAT:
    274                         vfs_out_stat(callid, &call);
    275                         break;
    276                 case VFS_OUT_SYNC:
    277                         vfs_out_sync(callid, &call);
    278                         break;
    279                 default:
    280                         async_answer_0(callid, ENOTSUP);
    281                         break;
    282                 }
    283         }
    284 }
    285 
    28663/** Register file system server.
    28764 *
     
    29067 * code.
    29168 *
    292  * @param sess Session for communication with VFS.
    293  * @param info VFS info structure supplied by the file system
    294  *             implementation.
    295  * @param vops Address of the vfs_out_ops_t structure.
    296  * @param lops Address of the libfs_ops_t structure.
     69 * @param vfs_phone Open phone for communication with VFS.
     70 * @param reg       File system registration structure. It will be
     71 *                  initialized by this function.
     72 * @param info      VFS info structure supplied by the file system
     73 *                  implementation.
     74 * @param conn      Connection fibril for handling all calls originating in
     75 *                  VFS.
    29776 *
    29877 * @return EOK on success or a non-zero error code on errror.
    29978 *
    30079 */
    301 int fs_register(async_sess_t *sess, vfs_info_t *info, vfs_out_ops_t *vops,
    302     libfs_ops_t *lops)
     80int fs_register(int vfs_phone, fs_reg_t *reg, vfs_info_t *info,
     81    async_client_conn_t conn)
    30382{
    30483        /*
     
    30786         * out-of-order, when it knows that the operation succeeded or failed.
    30887         */
    309        
    310         async_exch_t *exch = async_exchange_begin(sess);
    311        
    31288        ipc_call_t answer;
    313         aid_t req = async_send_0(exch, VFS_IN_REGISTER, &answer);
     89        aid_t req = async_send_0(vfs_phone, VFS_IN_REGISTER, &answer);
    31490       
    31591        /*
    31692         * Send our VFS info structure to VFS.
    31793         */
    318         int rc = async_data_write_start(exch, info, sizeof(*info));
    319        
     94        int rc = async_data_write_start(vfs_phone, info, sizeof(*info));
    32095        if (rc != EOK) {
    321                 async_exchange_end(exch);
    32296                async_wait_for(req, NULL);
    32397                return rc;
     
    32599       
    326100        /*
    327          * Set VFS_OUT and libfs operations.
    328          */
    329         vfs_out_ops = vops;
    330         libfs_ops = lops;
    331 
    332         /*
    333101         * Ask VFS for callback connection.
    334102         */
    335         async_connect_to_me(exch, 0, 0, 0, vfs_connection, NULL);
     103        async_connect_to_me(vfs_phone, 0, 0, 0, conn);
    336104       
    337105        /*
    338106         * Allocate piece of address space for PLB.
    339107         */
    340         reg.plb_ro = as_get_mappable_page(PLB_SIZE);
    341         if (!reg.plb_ro) {
    342                 async_exchange_end(exch);
     108        reg->plb_ro = as_get_mappable_page(PLB_SIZE);
     109        if (!reg->plb_ro) {
    343110                async_wait_for(req, NULL);
    344111                return ENOMEM;
     
    348115         * Request sharing the Path Lookup Buffer with VFS.
    349116         */
    350         rc = async_share_in_start_0_0(exch, reg.plb_ro, PLB_SIZE);
    351        
    352         async_exchange_end(exch);
    353        
     117        rc = async_share_in_start_0_0(vfs_phone, reg->plb_ro, PLB_SIZE);
    354118        if (rc) {
    355119                async_wait_for(req, NULL);
     
    361125         */
    362126        async_wait_for(req, NULL);
    363         reg.fs_handle = (int) IPC_GET_ARG1(answer);
     127        reg->fs_handle = (int) IPC_GET_ARG1(answer);
    364128       
    365129        /*
     
    367131         * the same connection fibril as well.
    368132         */
    369         async_set_client_connection(vfs_connection);
     133        async_set_client_connection(conn);
    370134       
    371135        return IPC_GET_RETVAL(answer);
     
    378142
    379143void libfs_mount(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_callid_t rid,
    380     ipc_call_t *req)
     144    ipc_call_t *request)
    381145{
    382         devmap_handle_t mp_devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
    383         fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*req);
    384         fs_handle_t mr_fs_handle = (fs_handle_t) IPC_GET_ARG3(*req);
    385         devmap_handle_t mr_devmap_handle = (devmap_handle_t) IPC_GET_ARG4(*req);
    386        
    387         async_sess_t *mountee_sess = async_clone_receive(EXCHANGE_PARALLEL);
    388         if (mountee_sess == NULL) {
     146        devmap_handle_t mp_devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     147        fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*request);
     148        fs_handle_t mr_fs_handle = (fs_handle_t) IPC_GET_ARG3(*request);
     149        devmap_handle_t mr_devmap_handle = (devmap_handle_t) IPC_GET_ARG4(*request);
     150        int res;
     151        sysarg_t rc;
     152       
     153        ipc_call_t call;
     154        ipc_callid_t callid;
     155       
     156        /* Accept the phone */
     157        callid = async_get_call(&call);
     158        int mountee_phone = (int) IPC_GET_ARG1(call);
     159        if ((IPC_GET_IMETHOD(call) != IPC_M_CONNECTION_CLONE) ||
     160            (mountee_phone < 0)) {
     161                async_answer_0(callid, EINVAL);
    389162                async_answer_0(rid, EINVAL);
    390163                return;
    391164        }
    392165       
     166        /* Acknowledge the mountee_phone */
     167        async_answer_0(callid, EOK);
     168       
    393169        fs_node_t *fn;
    394         int res = ops->node_get(&fn, mp_devmap_handle, mp_fs_index);
     170        res = ops->node_get(&fn, mp_devmap_handle, mp_fs_index);
    395171        if ((res != EOK) || (!fn)) {
    396                 async_hangup(mountee_sess);
     172                async_hangup(mountee_phone);
    397173                async_data_write_void(combine_rc(res, ENOENT));
    398174                async_answer_0(rid, combine_rc(res, ENOENT));
     
    401177       
    402178        if (fn->mp_data.mp_active) {
    403                 async_hangup(mountee_sess);
     179                async_hangup(mountee_phone);
    404180                (void) ops->node_put(fn);
    405181                async_data_write_void(EBUSY);
     
    408184        }
    409185       
    410         async_exch_t *exch = async_exchange_begin(mountee_sess);
    411         async_sess_t *sess = async_connect_me(EXCHANGE_PARALLEL, exch);
    412        
    413         if (!sess) {
    414                 async_exchange_end(exch);
    415                 async_hangup(mountee_sess);
     186        rc = async_req_0_0(mountee_phone, IPC_M_CONNECT_ME);
     187        if (rc != EOK) {
     188                async_hangup(mountee_phone);
    416189                (void) ops->node_put(fn);
    417                 async_data_write_void(errno);
    418                 async_answer_0(rid, errno);
     190                async_data_write_void(rc);
     191                async_answer_0(rid, rc);
    419192                return;
    420193        }
    421194       
    422195        ipc_call_t answer;
    423         int rc = async_data_write_forward_1_1(exch, VFS_OUT_MOUNTED,
     196        rc = async_data_write_forward_1_1(mountee_phone, VFS_OUT_MOUNTED,
    424197            mr_devmap_handle, &answer);
    425         async_exchange_end(exch);
    426198       
    427199        if (rc == EOK) {
     
    429201                fn->mp_data.fs_handle = mr_fs_handle;
    430202                fn->mp_data.devmap_handle = mr_devmap_handle;
    431                 fn->mp_data.sess = mountee_sess;
     203                fn->mp_data.phone = mountee_phone;
    432204        }
    433205       
     
    435207         * Do not release the FS node so that it stays in memory.
    436208         */
    437         async_answer_4(rid, rc, IPC_GET_ARG1(answer), IPC_GET_ARG2(answer),
    438             IPC_GET_ARG3(answer), IPC_GET_ARG4(answer));
     209        async_answer_3(rid, rc, IPC_GET_ARG1(answer), IPC_GET_ARG2(answer),
     210            IPC_GET_ARG3(answer));
    439211}
    440212
    441 void libfs_unmount(libfs_ops_t *ops, ipc_callid_t rid, ipc_call_t *req)
     213void libfs_unmount(libfs_ops_t *ops, ipc_callid_t rid, ipc_call_t *request)
    442214{
    443         devmap_handle_t mp_devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req);
    444         fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*req);
     215        devmap_handle_t mp_devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request);
     216        fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*request);
    445217        fs_node_t *fn;
    446218        int res;
     
    464236         * Tell the mounted file system to unmount.
    465237         */
    466         async_exch_t *exch = async_exchange_begin(fn->mp_data.sess);
    467         res = async_req_1_0(exch, VFS_OUT_UNMOUNTED, fn->mp_data.devmap_handle);
    468         async_exchange_end(exch);
     238        res = async_req_1_0(fn->mp_data.phone, VFS_OUT_UNMOUNTED,
     239            fn->mp_data.devmap_handle);
    469240
    470241        /*
     
    472243         */
    473244        if (res == EOK) {
    474                 async_hangup(fn->mp_data.sess);
     245                async_hangup(fn->mp_data.phone);
    475246                fn->mp_data.mp_active = false;
    476247                fn->mp_data.fs_handle = 0;
    477248                fn->mp_data.devmap_handle = 0;
    478                 fn->mp_data.sess = NULL;
    479                
     249                fn->mp_data.phone = 0;
    480250                /* Drop the reference created in libfs_mount(). */
    481251                (void) ops->node_put(fn);
     
    484254        (void) ops->node_put(fn);
    485255        async_answer_0(rid, res);
    486 }
    487 
    488 static char plb_get_char(unsigned pos)
    489 {
    490         return reg.plb_ro[pos % PLB_SIZE];
    491256}
    492257
     
    505270 */
    506271void libfs_lookup(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_callid_t rid,
    507     ipc_call_t *req)
     272    ipc_call_t *request)
    508273{
    509         unsigned int first = IPC_GET_ARG1(*req);
    510         unsigned int last = IPC_GET_ARG2(*req);
     274        unsigned int first = IPC_GET_ARG1(*request);
     275        unsigned int last = IPC_GET_ARG2(*request);
    511276        unsigned int next = first;
    512         devmap_handle_t devmap_handle = IPC_GET_ARG3(*req);
    513         int lflag = IPC_GET_ARG4(*req);
    514         fs_index_t index = IPC_GET_ARG5(*req);
     277        devmap_handle_t devmap_handle = IPC_GET_ARG3(*request);
     278        int lflag = IPC_GET_ARG4(*request);
     279        fs_index_t index = IPC_GET_ARG5(*request);
    515280        char component[NAME_MAX + 1];
    516281        int len;
     
    528293       
    529294        if (cur->mp_data.mp_active) {
    530                 async_exch_t *exch = async_exchange_begin(cur->mp_data.sess);
    531                 async_forward_slow(rid, exch, VFS_OUT_LOOKUP, next, last,
    532                     cur->mp_data.devmap_handle, lflag, index,
     295                async_forward_slow(rid, cur->mp_data.phone, VFS_OUT_LOOKUP,
     296                    next, last, cur->mp_data.devmap_handle, lflag, index,
    533297                    IPC_FF_ROUTE_FROM_ME);
    534                 async_exchange_end(exch);
    535                
    536298                (void) ops->node_put(cur);
    537299                return;
     
    539301       
    540302        /* Eat slash */
    541         if (plb_get_char(next) == '/')
     303        if (ops->plb_get_char(next) == '/')
    542304                next++;
    543305       
     
    552314                /* Collect the component */
    553315                len = 0;
    554                 while ((next <= last) && (plb_get_char(next) != '/')) {
     316                while ((next <= last) && (ops->plb_get_char(next) != '/')) {
    555317                        if (len + 1 == NAME_MAX) {
    556318                                /* Component length overflow */
     
    558320                                goto out;
    559321                        }
    560                         component[len++] = plb_get_char(next);
     322                        component[len++] = ops->plb_get_char(next);
    561323                        /* Process next character */
    562324                        next++;
     
    589351                                next--;
    590352                       
    591                         async_exch_t *exch = async_exchange_begin(tmp->mp_data.sess);
    592                         async_forward_slow(rid, exch, VFS_OUT_LOOKUP, next,
    593                             last, tmp->mp_data.devmap_handle, lflag, index,
    594                             IPC_FF_ROUTE_FROM_ME);
    595                         async_exchange_end(exch);
    596                        
     353                        async_forward_slow(rid, tmp->mp_data.phone,
     354                            VFS_OUT_LOOKUP, next, last, tmp->mp_data.devmap_handle,
     355                            lflag, index, IPC_FF_ROUTE_FROM_ME);
    597356                        (void) ops->node_put(cur);
    598357                        (void) ops->node_put(tmp);
     
    632391                                                if (lflag & L_CREATE)
    633392                                                        (void) ops->destroy(fn);
    634                                                 else
    635                                                         (void) ops->node_put(fn);
    636393                                                async_answer_0(rid, rc);
    637394                                        } else {
     
    684441                        len = 0;
    685442                        while (next <= last) {
    686                                 if (plb_get_char(next) == '/') {
     443                                if (ops->plb_get_char(next) == '/') {
    687444                                        /* More than one component */
    688445                                        async_answer_0(rid, ENOENT);
     
    696453                                }
    697454                               
    698                                 component[len++] = plb_get_char(next);
     455                                component[len++] = ops->plb_get_char(next);
    699456                                /* Process next character */
    700457                                next++;
     
    716473                                        if (lflag & L_CREATE)
    717474                                                (void) ops->destroy(fn);
    718                                         else
    719                                                 (void) ops->node_put(fn);
    720475                                        async_answer_0(rid, rc);
    721476                                } else {
     
    870625        rc = ops->node_open(fn);
    871626        aoff64_t size = ops->size_get(fn);
    872         async_answer_4(rid, rc, LOWER32(size), UPPER32(size),
    873             ops->lnkcnt_get(fn),
     627        async_answer_4(rid, rc, LOWER32(size), UPPER32(size), ops->lnkcnt_get(fn),
    874628            (ops->is_file(fn) ? L_FILE : 0) | (ops->is_directory(fn) ? L_DIRECTORY : 0));
    875629       
Note: See TracChangeset for help on using the changeset viewer.