Changeset d79dcdb in mainline for uspace/srv/vfs/vfs.c
- Timestamp:
- 2007-09-15T08:54:35Z (17 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 4ec91b2f
- Parents:
- 183b4a0
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/vfs/vfs.c
r183b4a0 rd79dcdb 40 40 #include <async.h> 41 41 #include <errno.h> 42 #include <stdlib.h> 43 #include <bool.h> 42 44 #include "vfs.h" 43 45 44 static void vfs_register(ipc_callid_t iid, ipc_call_t *icall) 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 */ 62 static void vfs_register(ipc_callid_t rid, ipc_call_t *request) 45 63 { 46 64 ipc_callid_t callid; 47 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 /* 54 * The client is sending us something, which cannot be 55 * the info structure. 56 */ 57 ipc_answer_fast(iid, EINVAL, 0, 0); 58 ipc_answer_fast(callid, EINVAL, 0, 0); 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 { 69 /* 70 * The first call has to be IPC_M_DATA_SEND in which we receive the 71 * VFS info structure from the client FS. 72 */ 73 if (!ipc_data_send_accept(&callid, &call, NULL, &size)) { 67 74 /* 68 75 * The client doesn't obey the same protocol as we do. 69 76 */ 70 ipc_answer_fast(iid, EINVAL, 0, 0);71 77 ipc_answer_fast(callid, EINVAL, 0, 0); 78 ipc_answer_fast(rid, EINVAL, 0, 0); 72 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 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 129 * The connection was opened via the IPC_CONNECT_ME_TO call. 82 130 * This call needs to be answered. 83 *84 * The protocol is that the requested action is specified in ARG185 * 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 /* 92 * Now, the connection can either be from an individual FS, 93 * which is trying to register itself and pass us its capabilities. 94 * Or, the connection is a regular connection from a client that wants 95 * us to do something for it (e.g. open a file, mount a fs etc.). 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 137 * each connection open for a while before we close it. The benefit of 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 140 * re-establish a connection if we hang it up due to reaching of maximum 141 * number of requests per connection or due to the client timing out. 96 142 */ 97 switch (iarg1) { 98 case VFS_REGISTER: 99 vfs_register(iid, icall); 100 break; 101 case VFS_MOUNT: 102 case VFS_UNMOUNT: 103 case VFS_OPEN: 104 default: 105 ipc_answer_fast(iid, ENOTSUP, 0, 0); 106 break; 143 144 while (keep_on_going) { 145 ipc_callid_t callid; 146 ipc_call_t call; 147 148 callid = async_get_call(&call); 149 150 switch (IPC_GET_METHOD(call)) { 151 case IPC_M_PHONE_HUNGUP: 152 keep_on_going = false; 153 break; 154 case VFS_REGISTER: 155 vfs_register(callid, &call); 156 keep_on_going = false; 157 break; 158 case VFS_MOUNT: 159 case VFS_UNMOUNT: 160 case VFS_OPEN: 161 case VFS_CREATE: 162 case VFS_CLOSE: 163 case VFS_READ: 164 case VFS_WRITE: 165 case VFS_SEEK: 166 default: 167 ipc_answer_fast(callid, ENOTSUP, 0, 0); 168 break; 169 } 107 170 } 171 172 /* TODO: cleanup after the client */ 173 108 174 } 109 175
Note:
See TracChangeset
for help on using the changeset viewer.