Ignore:
File:
1 edited

Legend:

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

    r6f2c1ff rb1956e3  
    734734}
    735735
    736 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)
    737796{
    738797        /*
     
    746805         */
    747806       
    748         int fd = IPC_GET_ARG1(*request);
    749        
    750807        /* Lookup the file structure corresponding to the file descriptor. */
    751808        vfs_file_t *file = vfs_file_get(fd);
    752         if (!file) {
    753                 async_answer_0(rid, ENOENT);
    754                 return;
    755         }
     809        if (!file)
     810                return ENOENT;
    756811       
    757812        /*
     
    786841        async_exch_t *fs_exch = vfs_exchange_grab(file->node->fs_handle);
    787842       
    788         /*
    789          * Make a VFS_READ/VFS_WRITE request at the destination FS server
    790          * and forward the IPC_M_DATA_READ/IPC_M_DATA_WRITE request to the
    791          * destination FS server. The call will be routed as if sent by
    792          * ourselves. Note that call arguments are immutable in this case so we
    793          * don't have to bother.
    794          */
    795         sysarg_t rc;
     843        if (!read && file->append)
     844                file->pos = file->node->size;
     845       
     846        /*
     847         * Handle communication with the endpoint FS.
     848         */
    796849        ipc_call_t answer;
    797         if (read) {
    798                 rc = async_data_read_forward_4_1(fs_exch, VFS_OUT_READ,
    799                     file->node->service_id, file->node->index,
    800                     LOWER32(file->pos), UPPER32(file->pos), &answer);
    801         } else {
    802                 if (file->append)
    803                         file->pos = file->node->size;
    804                
    805                 rc = async_data_write_forward_4_1(fs_exch, VFS_OUT_WRITE,
    806                     file->node->service_id, file->node->index,
    807                     LOWER32(file->pos), UPPER32(file->pos), &answer);
    808         }
     850        int rc = ipc_cb(fs_exch, file, &answer, read, ipc_cb_data);
    809851       
    810852        vfs_exchange_release(fs_exch);
     
    833875        vfs_file_put(file);     
    834876
    835         /*
    836          * FS server's reply is the final result of the whole operation we
    837          * return to the client.
    838          */
     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);
    839885        async_answer_1(rid, rc, bytes);
    840886}
    841887
     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
    842893void vfs_read(ipc_callid_t rid, ipc_call_t *request)
    843894{
    844         vfs_rdwr(rid, request, true);
     895        vfs_rdwr_client(rid, request, true);
    845896}
    846897
    847898void vfs_write(ipc_callid_t rid, ipc_call_t *request)
    848899{
    849         vfs_rdwr(rid, request, false);
     900        vfs_rdwr_client(rid, request, false);
    850901}
    851902
     
    893944               
    894945                file->pos += off;
    895                 newoff = (file->pos > OFF64_MAX) ?  OFF64_MAX : file->pos;
     946                newoff = (file->pos > OFF64_MAX) ? OFF64_MAX : file->pos;
    896947               
    897948                fibril_mutex_unlock(&file->lock);
Note: See TracChangeset for help on using the changeset viewer.