Subversion Repositories HelenOS

Rev

Rev 2521 | Rev 2526 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2521 Rev 2523
Line 37... Line 37...
37
 
37
 
38
#include <ipc/ipc.h>
38
#include <ipc/ipc.h>
39
#include <ipc/services.h>
39
#include <ipc/services.h>
40
#include <async.h>
40
#include <async.h>
41
#include <errno.h>
41
#include <errno.h>
-
 
42
#include <stdlib.h>
-
 
43
#include <bool.h>
42
#include "vfs.h"
44
#include "vfs.h"
43
 
45
 
-
 
46
/** Verify the VFS info structure.
-
 
47
 *
-
 
48
 * @param info      Info structure to be verified.
-
 
49
 *
-
 
50
 * @return      Non-zero if the info structure is sane, zero otherwise.
-
 
51
 */
-
 
52
static int vfs_info_sane(vfs_info_t *info)
-
 
53
{
-
 
54
    return 1;   /* XXX */
-
 
55
}
-
 
56
 
-
 
57
/** VFS_REGISTER protocol function.
-
 
58
 *
-
 
59
 * @param rid       Hash of the call with the request.
-
 
60
 * @param request   Call structure with the request.
-
 
61
 */
44
static void vfs_register(ipc_callid_t iid, ipc_call_t *icall)
62
static void vfs_register(ipc_callid_t rid, ipc_call_t *request)
45
{
63
{
46
    ipc_callid_t callid;
64
    ipc_callid_t callid;
47
    ipc_call_t call;
65
    ipc_call_t call;
-
 
66
    int rc;
-
 
67
    size_t size;
48
 
68
 
49
    callid = async_get_call(&call);
-
 
50
    if (IPC_GET_METHOD(call) == IPC_M_DATA_SEND) {
-
 
51
        size_t size = IPC_GET_ARG3(call);
-
 
52
        if (size != sizeof(vfs_info_t)) {
-
 
53
            /*
69
    /*
54
             * The client is sending us something, which cannot be
70
     * The first call has to be IPC_M_DATA_SEND in which we receive the
55
             * the info structure.
71
     * VFS info structure from the client FS.
56
             */
72
     */
57
            ipc_answer_fast(iid, EINVAL, 0, 0);
-
 
58
            ipc_answer_fast(callid, EINVAL, 0, 0);
73
    if (!ipc_data_send_accept(&callid, &call, NULL, &size)) {
59
            return;
-
 
60
        }
-
 
61
        /*
-
 
62
         * XXX: continue here
-
 
63
         * Allocate an info structue, answer the call, check sanity
-
 
64
         * of the copied-in info structure, ...
-
 
65
         */
-
 
66
    } else {
-
 
67
        /*
74
        /*
68
         * The client doesn't obey the same protocol as we do.
75
         * The client doesn't obey the same protocol as we do.
69
         */
76
         */
70
        ipc_answer_fast(iid, EINVAL, 0, 0);
-
 
71
        ipc_answer_fast(callid, EINVAL, 0, 0);
77
        ipc_answer_fast(callid, EINVAL, 0, 0);
-
 
78
        ipc_answer_fast(rid, EINVAL, 0, 0);
72
        return;
79
        return;
73
    }
80
    }
-
 
81
   
-
 
82
    /*
-
 
83
     * We know the size of the info structure. See if the client understands
-
 
84
     * this easy concept too.
-
 
85
     */
-
 
86
    if (size != sizeof(vfs_info_t)) {
-
 
87
        /*
-
 
88
         * The client is sending us something, which cannot be
-
 
89
         * the info structure.
-
 
90
         */
-
 
91
        ipc_answer_fast(callid, EINVAL, 0, 0);
-
 
92
        ipc_answer_fast(rid, EINVAL, 0, 0);
-
 
93
        return;
-
 
94
    }
-
 
95
    vfs_info_t *info;
-
 
96
 
-
 
97
    /*
-
 
98
     * Allocate a buffer for the info structure.
-
 
99
     */
-
 
100
    info = (vfs_info_t *) malloc(sizeof(vfs_info_t));
-
 
101
    if (!info) {
-
 
102
        ipc_answer_fast(callid, ENOMEM, 0, 0);
-
 
103
        ipc_answer_fast(rid, ENOMEM, 0, 0);
-
 
104
        return;
-
 
105
    }
-
 
106
       
-
 
107
    rc = ipc_data_send_answer(callid, &call, info, size);
-
 
108
    if (!rc) {
-
 
109
        free(info);
-
 
110
        ipc_answer_fast(callid, rc, 0, 0);
-
 
111
        ipc_answer_fast(rid, rc, 0, 0);
-
 
112
        return;
-
 
113
    }
-
 
114
       
-
 
115
    if (!vfs_info_sane(info)) {
-
 
116
        free(info);
-
 
117
        ipc_answer_fast(callid, EINVAL, 0, 0);
-
 
118
        ipc_answer_fast(rid, EINVAL, 0, 0);
-
 
119
        return;
-
 
120
    }
-
 
121
       
74
}
122
}
75
 
123
 
76
static void vfs_connection(ipc_callid_t iid, ipc_call_t *icall)
124
static void vfs_connection(ipc_callid_t iid, ipc_call_t *icall)
77
{
125
{
78
    ipcarg_t iarg1, iarg2;
126
    bool keep_on_going = 1;
79
 
127
 
80
    /*
128
    /*
81
     * The connection was opened via the IPC_CONNECT_ME_TO call.
129
     * The connection was opened via the IPC_CONNECT_ME_TO call.
82
     * This call needs to be answered.
130
     * This call needs to be answered.
83
     *
-
 
84
     * The protocol is that the requested action is specified in ARG1
-
 
85
     * of the opening call. If the request has a single integer argument,
-
 
86
     * it is passed in ARG2.
-
 
87
     */
131
     */
88
    iarg1 = IPC_GET_ARG1(*icall);
-
 
89
    iarg2 = IPC_GET_ARG2(*icall);
132
    ipc_answer_fast(iid, EOK, 0, 0);
90
 
133
 
91
    /*
134
    /*
-
 
135
     * Here we enter the main connection fibril loop.
-
 
136
     * The logic behind this loop and the protocol is that we'd like to keep
92
     * Now, the connection can either be from an individual FS,
137
     * each connection open for a while before we close it. The benefit of
93
     * which is trying to register itself and pass us its capabilities.
138
     * this is that the client doesn't have to establish a new connection
-
 
139
     * upon each request.  On the other hand, the client must be ready to
94
     * Or, the connection is a regular connection from a client that wants
140
     * re-establish a connection if we hang it up due to reaching of maximum
95
     * us to do something for it (e.g. open a file, mount a fs etc.).
141
     * number of requests per connection or due to the client timing out.
96
     */
142
     */
-
 
143
     
-
 
144
    while (keep_on_going) {
-
 
145
        ipc_callid_t callid;
-
 
146
        ipc_call_t call;
-
 
147
 
-
 
148
        callid = async_get_call(&call);
-
 
149
       
97
    switch (iarg1) {
150
        switch (IPC_GET_METHOD(call)) {
-
 
151
        case IPC_M_PHONE_HUNGUP:
-
 
152
            keep_on_going = false;
-
 
153
            break;
98
    case VFS_REGISTER:
154
        case VFS_REGISTER:
99
        vfs_register(iid, icall);
155
            vfs_register(callid, &call);
-
 
156
            keep_on_going = false;
100
        break;
157
            break;
101
    case VFS_MOUNT:
158
        case VFS_MOUNT:
102
    case VFS_UNMOUNT:
159
        case VFS_UNMOUNT:
103
    case VFS_OPEN:
160
        case VFS_OPEN:
-
 
161
        case VFS_CREATE:
-
 
162
        case VFS_CLOSE:
-
 
163
        case VFS_READ:
-
 
164
        case VFS_WRITE:
-
 
165
        case VFS_SEEK:
104
    default:
166
        default:
105
        ipc_answer_fast(iid, ENOTSUP, 0, 0);
167
            ipc_answer_fast(callid, ENOTSUP, 0, 0);
106
        break;
168
            break;
-
 
169
        }
107
    }
170
    }
-
 
171
 
-
 
172
    /* TODO: cleanup after the client */
-
 
173
   
108
}
174
}
109
 
175
 
110
int main(int argc, char **argv)
176
int main(int argc, char **argv)
111
{
177
{
112
    ipcarg_t phonead;
178
    ipcarg_t phonead;