Changeset 2c2d54a in mainline for uspace/srv/vfs


Ignore:
Timestamp:
2016-09-02T17:58:05Z (9 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4c3602c4
Parents:
4bf0926e (diff), 3233adb (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge from lp:~jakub/helenos/pager

Location:
uspace/srv/vfs
Files:
1 added
4 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/vfs/Makefile

    r4bf0926e r2c2d54a  
    3838        vfs_ops.c \
    3939        vfs_lookup.c \
    40         vfs_register.c
     40        vfs_register.c \
     41        vfs_pager.c
    4142
    4243include $(USPACE_PREFIX)/Makefile.common
  • uspace/srv/vfs/vfs.c

    r4bf0926e r2c2d54a  
    3737
    3838#include <vfs/vfs.h>
     39#include <stdlib.h>
    3940#include <ipc/services.h>
     41#include <abi/ipc/methods.h>
     42#include <libarch/config.h>
    4043#include <ns.h>
    4144#include <async.h>
     
    5154#define NAME  "vfs"
    5255
     56static void vfs_pager(ipc_callid_t iid, ipc_call_t *icall, void *arg)
     57{
     58        async_answer_0(iid, EOK);
     59
     60        while (true) {
     61                ipc_call_t call;
     62                ipc_callid_t callid = async_get_call(&call);
     63               
     64                if (!IPC_GET_IMETHOD(call))
     65                        break;
     66               
     67                switch (IPC_GET_IMETHOD(call)) {
     68                case IPC_M_PAGE_IN:
     69                        vfs_page_in(callid, &call);
     70                        break;
     71                default:
     72                        async_answer_0(callid, ENOTSUP);
     73                        break;
     74                }
     75        }
     76}
     77
    5378static void vfs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    5479{
     
    150175int main(int argc, char **argv)
    151176{
     177        int rc;
     178
    152179        printf("%s: HelenOS VFS server\n", NAME);
    153180       
     
    165192         */
    166193        plb = as_area_create(AS_AREA_ANY, PLB_SIZE,
    167             AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE);
     194            AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE, AS_AREA_UNPAGED);
    168195        if (plb == AS_MAP_FAILED) {
    169196                printf("%s: Cannot create address space area\n", NAME);
     
    179206
    180207        /*
     208         * Create a port for the pager.
     209         */
     210        port_id_t port;
     211        rc = async_create_port(INTERFACE_PAGER, vfs_pager, NULL, &port);
     212        if (rc != EOK)
     213                return rc;
     214               
     215        /*
    181216         * Set a connection handling function/fibril.
    182217         */
     
    192227         * Register at the naming service.
    193228         */
    194         int rc = service_register(SERVICE_VFS);
     229        rc = service_register(SERVICE_VFS);
    195230        if (rc != EOK) {
    196231                printf("%s: Cannot register VFS service\n", NAME);
  • uspace/srv/vfs/vfs.h

    r4bf0926e r2c2d54a  
    224224extern void vfs_statfs(ipc_callid_t, ipc_call_t *);
    225225
     226extern void vfs_page_in(ipc_callid_t, ipc_call_t *);
     227
     228typedef struct {
     229        void *buffer;
     230        size_t size;
     231} rdwr_io_chunk_t;
     232
     233extern int vfs_rdwr_internal(int, bool, rdwr_io_chunk_t *);
     234
    226235#endif
    227236
  • uspace/srv/vfs/vfs_ops.c

    r4bf0926e r2c2d54a  
    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.