Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/vfs/vfs_ops.c

    rfeeac0d rb1956e3  
    266266}
    267267
    268 void vfs_mount(ipc_callid_t rid, ipc_call_t *request)
     268void vfs_mount_srv(ipc_callid_t rid, ipc_call_t *request)
    269269{
    270270        service_id_t service_id;
     
    405405}
    406406
    407 void vfs_unmount(ipc_callid_t rid, ipc_call_t *request)
     407void vfs_unmount_srv(ipc_callid_t rid, ipc_call_t *request)
    408408{
    409409        int rc;
     
    637637        else
    638638                fibril_rwlock_read_unlock(&namespace_rwlock);
     639
     640        if (!node) {
     641                async_answer_0(rid, ENOMEM);
     642                return;
     643        }
    639644       
    640645        /* Truncate the file if requested and if necessary. */
     
    729734}
    730735
    731 static void vfs_rdwr(ipc_callid_t rid, ipc_call_t *request, bool read)
     736typedef int (* rdwr_ipc_cb_t)(async_exch_t *, vfs_file_t *, ipc_call_t *,
     737    bool, void *);
     738
     739static int rdwr_ipc_client(async_exch_t *exch, vfs_file_t *file,
     740    ipc_call_t *answer, bool read, void *data)
     741{
     742        size_t *bytes = (size_t *) data;
     743        int rc;
     744
     745        /*
     746         * Make a VFS_READ/VFS_WRITE request at the destination FS server
     747         * and forward the IPC_M_DATA_READ/IPC_M_DATA_WRITE request to the
     748         * destination FS server. The call will be routed as if sent by
     749         * ourselves. Note that call arguments are immutable in this case so we
     750         * don't have to bother.
     751         */
     752
     753        if (read) {
     754                rc = async_data_read_forward_4_1(exch, VFS_OUT_READ,
     755                    file->node->service_id, file->node->index,
     756                    LOWER32(file->pos), UPPER32(file->pos), answer);
     757        } else {
     758                rc = async_data_write_forward_4_1(exch, VFS_OUT_WRITE,
     759                    file->node->service_id, file->node->index,
     760                    LOWER32(file->pos), UPPER32(file->pos), answer);
     761        }
     762
     763        *bytes = IPC_GET_ARG1(*answer);
     764        return rc;
     765}
     766
     767static int rdwr_ipc_internal(async_exch_t *exch, vfs_file_t *file,
     768    ipc_call_t *answer, bool read, void *data)
     769{
     770        rdwr_io_chunk_t *chunk = (rdwr_io_chunk_t *) data;
     771
     772        if (exch == NULL)
     773                return ENOENT;
     774       
     775        aid_t msg = async_send_fast(exch, read ? VFS_OUT_READ : VFS_OUT_WRITE,
     776            file->node->service_id, file->node->index, LOWER32(file->pos),
     777            UPPER32(file->pos), answer);
     778        if (msg == 0)
     779                return EINVAL;
     780
     781        int retval = async_data_read_start(exch, chunk->buffer, chunk->size);
     782        if (retval != EOK) {
     783                async_forget(msg);
     784                return retval;
     785        }
     786       
     787        sysarg_t rc;
     788        async_wait_for(msg, &rc);
     789       
     790        chunk->size = IPC_GET_ARG1(*answer);
     791
     792        return (int) rc;
     793}
     794
     795static int vfs_rdwr(int fd, bool read, rdwr_ipc_cb_t ipc_cb, void *ipc_cb_data)
    732796{
    733797        /*
     
    741805         */
    742806       
    743         int fd = IPC_GET_ARG1(*request);
    744        
    745807        /* Lookup the file structure corresponding to the file descriptor. */
    746808        vfs_file_t *file = vfs_file_get(fd);
    747         if (!file) {
    748                 async_answer_0(rid, ENOENT);
    749                 return;
    750         }
     809        if (!file)
     810                return ENOENT;
    751811       
    752812        /*
     
    781841        async_exch_t *fs_exch = vfs_exchange_grab(file->node->fs_handle);
    782842       
    783         /*
    784          * Make a VFS_READ/VFS_WRITE request at the destination FS server
    785          * and forward the IPC_M_DATA_READ/IPC_M_DATA_WRITE request to the
    786          * destination FS server. The call will be routed as if sent by
    787          * ourselves. Note that call arguments are immutable in this case so we
    788          * don't have to bother.
    789          */
    790         sysarg_t rc;
     843        if (!read && file->append)
     844                file->pos = file->node->size;
     845       
     846        /*
     847         * Handle communication with the endpoint FS.
     848         */
    791849        ipc_call_t answer;
    792         if (read) {
    793                 rc = async_data_read_forward_4_1(fs_exch, VFS_OUT_READ,
    794                     file->node->service_id, file->node->index,
    795                     LOWER32(file->pos), UPPER32(file->pos), &answer);
    796         } else {
    797                 if (file->append)
    798                         file->pos = file->node->size;
    799                
    800                 rc = async_data_write_forward_4_1(fs_exch, VFS_OUT_WRITE,
    801                     file->node->service_id, file->node->index,
    802                     LOWER32(file->pos), UPPER32(file->pos), &answer);
    803         }
     850        int rc = ipc_cb(fs_exch, file, &answer, read, ipc_cb_data);
    804851       
    805852        vfs_exchange_release(fs_exch);
     
    828875        vfs_file_put(file);     
    829876
    830         /*
    831          * FS server's reply is the final result of the whole operation we
    832          * return to the client.
    833          */
     877        return rc;
     878}
     879       
     880static void vfs_rdwr_client(ipc_callid_t rid, ipc_call_t *request, bool read)
     881{
     882        size_t bytes = 0;       
     883        int rc = vfs_rdwr(IPC_GET_ARG1(*request), read, rdwr_ipc_client,
     884            &bytes);
    834885        async_answer_1(rid, rc, bytes);
    835886}
    836887
     888int vfs_rdwr_internal(int fd, bool read, rdwr_io_chunk_t *chunk)
     889{
     890        return vfs_rdwr(fd, read, rdwr_ipc_internal, chunk);
     891}
     892
    837893void vfs_read(ipc_callid_t rid, ipc_call_t *request)
    838894{
    839         vfs_rdwr(rid, request, true);
     895        vfs_rdwr_client(rid, request, true);
    840896}
    841897
    842898void vfs_write(ipc_callid_t rid, ipc_call_t *request)
    843899{
    844         vfs_rdwr(rid, request, false);
     900        vfs_rdwr_client(rid, request, false);
    845901}
    846902
     
    888944               
    889945                file->pos += off;
    890                 newoff = (file->pos > OFF64_MAX) ?  OFF64_MAX : file->pos;
     946                newoff = (file->pos > OFF64_MAX) ? OFF64_MAX : file->pos;
    891947               
    892948                fibril_mutex_unlock(&file->lock);
     
    14121468}
    14131469
     1470void vfs_statfs(ipc_callid_t rid, ipc_call_t *request)
     1471{
     1472        char *path;
     1473        int rc = async_data_write_accept((void **) &path, true, 0, 0, 0, NULL);
     1474        if (rc != EOK) {
     1475                async_answer_0(rid, rc);
     1476                return;
     1477        }
     1478       
     1479        ipc_callid_t callid;
     1480        if (!async_data_read_receive(&callid, NULL)) {
     1481                free(path);
     1482                async_answer_0(callid, EINVAL);
     1483                async_answer_0(rid, EINVAL);
     1484                return;
     1485        }
     1486
     1487        vfs_lookup_res_t lr;
     1488        fibril_rwlock_read_lock(&namespace_rwlock);
     1489        rc = vfs_lookup_internal(path, L_NONE, &lr, NULL);
     1490        free(path);
     1491        if (rc != EOK) {
     1492                fibril_rwlock_read_unlock(&namespace_rwlock);
     1493                async_answer_0(callid, rc);
     1494                async_answer_0(rid, rc);
     1495                return;
     1496        }
     1497        vfs_node_t *node = vfs_node_get(&lr);
     1498        if (!node) {
     1499                fibril_rwlock_read_unlock(&namespace_rwlock);
     1500                async_answer_0(callid, ENOMEM);
     1501                async_answer_0(rid, ENOMEM);
     1502                return;
     1503        }
     1504
     1505        fibril_rwlock_read_unlock(&namespace_rwlock);
     1506
     1507        async_exch_t *exch = vfs_exchange_grab(node->fs_handle);
     1508       
     1509        aid_t msg;
     1510        msg = async_send_3(exch, VFS_OUT_STATFS, node->service_id,
     1511            node->index, false, NULL);
     1512        async_forward_fast(callid, exch, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);
     1513       
     1514        vfs_exchange_release(exch);
     1515       
     1516        sysarg_t rv;
     1517        async_wait_for(msg, &rv);
     1518
     1519        async_answer_0(rid, rv);
     1520
     1521        vfs_node_put(node);
     1522}
     1523
    14141524/**
    14151525 * @}
Note: See TracChangeset for help on using the changeset viewer.