Changeset efcebe1 in mainline for uspace/lib/fs/libfs.c
- Timestamp:
- 2011-07-24T23:15:42Z (13 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 358dc13, 3fb0fec
- Parents:
- 6a44ee4
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/fs/libfs.c
r6a44ee4 refcebe1 45 45 #include <mem.h> 46 46 #include <sys/stat.h> 47 #include <stdlib.h> 47 48 48 49 #define on_error(rc, action) \ … … 61 62 } while (0) 62 63 64 static fs_reg_t reg; 65 66 static vfs_out_ops_t *vfs_out_ops = NULL; 67 static libfs_ops_t *libfs_ops = NULL; 68 69 static void libfs_mount(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *); 70 static void libfs_unmount(libfs_ops_t *, ipc_callid_t, ipc_call_t *); 71 static void libfs_lookup(libfs_ops_t *, fs_handle_t, ipc_callid_t, 72 ipc_call_t *); 73 static void libfs_stat(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *); 74 static void libfs_open_node(libfs_ops_t *, fs_handle_t, ipc_callid_t, 75 ipc_call_t *); 76 77 static void vfs_out_mounted(ipc_callid_t rid, ipc_call_t *req) 78 { 79 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req); 80 char *opts; 81 int rc; 82 83 /* Accept the mount options. */ 84 rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL); 85 if (rc != EOK) { 86 async_answer_0(rid, rc); 87 return; 88 } 89 90 fs_index_t index; 91 aoff64_t size; 92 unsigned lnkcnt; 93 rc = vfs_out_ops->mounted(devmap_handle, opts, &index, &size, &lnkcnt); 94 95 if (rc == EOK) // FIXME: size is 64-bit 96 async_answer_3(rid, EOK, index, size, lnkcnt); 97 else 98 async_answer_0(rid, rc); 99 100 free(opts); 101 } 102 103 static void vfs_out_mount(ipc_callid_t rid, ipc_call_t *req) 104 { 105 libfs_mount(libfs_ops, reg.fs_handle, rid, req); 106 } 107 108 static void vfs_out_unmounted(ipc_callid_t rid, ipc_call_t *req) 109 { 110 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req); 111 int rc; 112 113 rc = vfs_out_ops->unmounted(devmap_handle); 114 115 async_answer_0(rid, rc); 116 } 117 118 static void vfs_out_unmount(ipc_callid_t rid, ipc_call_t *req) 119 { 120 121 libfs_unmount(libfs_ops, rid, req); 122 } 123 124 static void vfs_out_lookup(ipc_callid_t rid, ipc_call_t *req) 125 { 126 libfs_lookup(libfs_ops, reg.fs_handle, rid, req); 127 } 128 129 static void vfs_out_read(ipc_callid_t rid, ipc_call_t *req) 130 { 131 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req); 132 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req); 133 aoff64_t pos = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*req), 134 IPC_GET_ARG4(*req)); 135 size_t rbytes; 136 int rc; 137 138 rc = vfs_out_ops->read(devmap_handle, index, pos, &rbytes); 139 140 if (rc == EOK) 141 async_answer_1(rid, EOK, rbytes); 142 else 143 async_answer_0(rid, rc); 144 } 145 146 static void vfs_out_write(ipc_callid_t rid, ipc_call_t *req) 147 { 148 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req); 149 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req); 150 aoff64_t pos = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*req), 151 IPC_GET_ARG4(*req)); 152 size_t wbytes; 153 aoff64_t nsize; 154 int rc; 155 156 rc = vfs_out_ops->write(devmap_handle, index, pos, &wbytes, &nsize); 157 158 if (rc == EOK) // FIXME: nsize is 64-bit 159 async_answer_2(rid, EOK, wbytes, nsize); 160 else 161 async_answer_0(rid, rc); 162 } 163 164 static void vfs_out_truncate(ipc_callid_t rid, ipc_call_t *req) 165 { 166 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req); 167 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req); 168 aoff64_t size = (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*req), 169 IPC_GET_ARG4(*req)); 170 int rc; 171 172 rc = vfs_out_ops->truncate(devmap_handle, index, size); 173 174 async_answer_0(rid, rc); 175 } 176 177 static void vfs_out_close(ipc_callid_t rid, ipc_call_t *req) 178 { 179 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req); 180 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req); 181 int rc; 182 183 rc = vfs_out_ops->close(devmap_handle, index); 184 185 async_answer_0(rid, rc); 186 } 187 188 static void vfs_out_destroy(ipc_callid_t rid, ipc_call_t *req) 189 { 190 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req); 191 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req); 192 int rc; 193 194 rc = vfs_out_ops->destroy(devmap_handle, index); 195 196 async_answer_0(rid, rc); 197 } 198 199 static void vfs_out_open_node(ipc_callid_t rid, ipc_call_t *req) 200 { 201 libfs_open_node(libfs_ops, reg.fs_handle, rid, req); 202 } 203 204 static void vfs_out_stat(ipc_callid_t rid, ipc_call_t *req) 205 { 206 libfs_stat(libfs_ops, reg.fs_handle, rid, req); 207 } 208 209 static void vfs_out_sync(ipc_callid_t rid, ipc_call_t *req) 210 { 211 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req); 212 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*req); 213 int rc; 214 215 rc = vfs_out_ops->sync(devmap_handle, index); 216 217 async_answer_0(rid, rc); 218 } 219 220 static void vfs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 221 { 222 if (iid) { 223 /* 224 * This only happens for connections opened by 225 * IPC_M_CONNECT_ME_TO calls as opposed to callback connections 226 * created by IPC_M_CONNECT_TO_ME. 227 */ 228 async_answer_0(iid, EOK); 229 } 230 231 while (true) { 232 ipc_call_t call; 233 ipc_callid_t callid = async_get_call(&call); 234 235 if (!IPC_GET_IMETHOD(call)) 236 return; 237 238 switch (IPC_GET_IMETHOD(call)) { 239 case VFS_OUT_MOUNTED: 240 vfs_out_mounted(callid, &call); 241 break; 242 case VFS_OUT_MOUNT: 243 vfs_out_mount(callid, &call); 244 break; 245 case VFS_OUT_UNMOUNTED: 246 vfs_out_unmounted(callid, &call); 247 break; 248 case VFS_OUT_UNMOUNT: 249 vfs_out_unmount(callid, &call); 250 break; 251 case VFS_OUT_LOOKUP: 252 vfs_out_lookup(callid, &call); 253 break; 254 case VFS_OUT_READ: 255 vfs_out_read(callid, &call); 256 break; 257 case VFS_OUT_WRITE: 258 vfs_out_write(callid, &call); 259 break; 260 case VFS_OUT_TRUNCATE: 261 vfs_out_truncate(callid, &call); 262 break; 263 case VFS_OUT_CLOSE: 264 vfs_out_close(callid, &call); 265 break; 266 case VFS_OUT_DESTROY: 267 vfs_out_destroy(callid, &call); 268 break; 269 case VFS_OUT_OPEN_NODE: 270 vfs_out_open_node(callid, &call); 271 break; 272 case VFS_OUT_STAT: 273 vfs_out_stat(callid, &call); 274 break; 275 case VFS_OUT_SYNC: 276 vfs_out_sync(callid, &call); 277 break; 278 default: 279 async_answer_0(callid, ENOTSUP); 280 break; 281 } 282 } 283 } 284 63 285 /** Register file system server. 64 286 * … … 68 290 * 69 291 * @param sess Session for communication with VFS. 70 * @param reg File system registration structure. It will be71 * initialized by this function.72 292 * @param info VFS info structure supplied by the file system 73 293 * implementation. 74 * @param conn Connection fibril for handling all calls originating in75 * VFS.294 * @param vops Address of the vfs_out_ops_t structure. 295 * @param lops Address of the libfs_ops_t structure. 76 296 * 77 297 * @return EOK on success or a non-zero error code on errror. 78 298 * 79 299 */ 80 int fs_register(async_sess_t *sess, fs_reg_t *reg, vfs_info_t *info,81 async_client_conn_t conn)300 int fs_register(async_sess_t *sess, vfs_info_t *info, vfs_out_ops_t *vops, 301 libfs_ops_t *lops) 82 302 { 83 303 /* … … 104 324 105 325 /* 326 * Set VFS_OUT and libfs operations. 327 */ 328 vfs_out_ops = vops; 329 libfs_ops = lops; 330 331 /* 106 332 * Ask VFS for callback connection. 107 333 */ 108 async_connect_to_me(exch, 0, 0, 0, conn, NULL);334 async_connect_to_me(exch, 0, 0, 0, vfs_connection, NULL); 109 335 110 336 /* 111 337 * Allocate piece of address space for PLB. 112 338 */ 113 reg ->plb_ro = as_get_mappable_page(PLB_SIZE);114 if (!reg ->plb_ro) {339 reg.plb_ro = as_get_mappable_page(PLB_SIZE); 340 if (!reg.plb_ro) { 115 341 async_exchange_end(exch); 116 342 async_wait_for(req, NULL); … … 121 347 * Request sharing the Path Lookup Buffer with VFS. 122 348 */ 123 rc = async_share_in_start_0_0(exch, reg ->plb_ro, PLB_SIZE);349 rc = async_share_in_start_0_0(exch, reg.plb_ro, PLB_SIZE); 124 350 125 351 async_exchange_end(exch); … … 134 360 */ 135 361 async_wait_for(req, NULL); 136 reg ->fs_handle = (int) IPC_GET_ARG1(answer);362 reg.fs_handle = (int) IPC_GET_ARG1(answer); 137 363 138 364 /* … … 140 366 * the same connection fibril as well. 141 367 */ 142 async_set_client_connection( conn);368 async_set_client_connection(vfs_connection); 143 369 144 370 return IPC_GET_RETVAL(answer); … … 151 377 152 378 void libfs_mount(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_callid_t rid, 153 ipc_call_t *req uest)154 { 155 devmap_handle_t mp_devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req uest);156 fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*req uest);157 fs_handle_t mr_fs_handle = (fs_handle_t) IPC_GET_ARG3(*req uest);158 devmap_handle_t mr_devmap_handle = (devmap_handle_t) IPC_GET_ARG4(*req uest);379 ipc_call_t *req) 380 { 381 devmap_handle_t mp_devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req); 382 fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*req); 383 fs_handle_t mr_fs_handle = (fs_handle_t) IPC_GET_ARG3(*req); 384 devmap_handle_t mr_devmap_handle = (devmap_handle_t) IPC_GET_ARG4(*req); 159 385 160 386 async_sess_t *mountee_sess = async_clone_receive(EXCHANGE_PARALLEL); … … 212 438 } 213 439 214 void libfs_unmount(libfs_ops_t *ops, ipc_callid_t rid, ipc_call_t *req uest)215 { 216 devmap_handle_t mp_devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req uest);217 fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*req uest);440 void libfs_unmount(libfs_ops_t *ops, ipc_callid_t rid, ipc_call_t *req) 441 { 442 devmap_handle_t mp_devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*req); 443 fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*req); 218 444 fs_node_t *fn; 219 445 int res; … … 259 485 } 260 486 487 static char plb_get_char(unsigned pos) 488 { 489 return reg.plb_ro[pos % PLB_SIZE]; 490 } 491 261 492 /** Lookup VFS triplet by name in the file system name space. 262 493 * … … 273 504 */ 274 505 void libfs_lookup(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_callid_t rid, 275 ipc_call_t *req uest)276 { 277 unsigned int first = IPC_GET_ARG1(*req uest);278 unsigned int last = IPC_GET_ARG2(*req uest);506 ipc_call_t *req) 507 { 508 unsigned int first = IPC_GET_ARG1(*req); 509 unsigned int last = IPC_GET_ARG2(*req); 279 510 unsigned int next = first; 280 devmap_handle_t devmap_handle = IPC_GET_ARG3(*req uest);281 int lflag = IPC_GET_ARG4(*req uest);282 fs_index_t index = IPC_GET_ARG5(*req uest);511 devmap_handle_t devmap_handle = IPC_GET_ARG3(*req); 512 int lflag = IPC_GET_ARG4(*req); 513 fs_index_t index = IPC_GET_ARG5(*req); 283 514 char component[NAME_MAX + 1]; 284 515 int len; … … 298 529 async_exch_t *exch = async_exchange_begin(cur->mp_data.sess); 299 530 async_forward_slow(rid, exch, VFS_OUT_LOOKUP, next, last, 300 cur->mp_data.devmap_handle, lflag, index, IPC_FF_ROUTE_FROM_ME); 531 cur->mp_data.devmap_handle, lflag, index, 532 IPC_FF_ROUTE_FROM_ME); 301 533 async_exchange_end(exch); 302 534 … … 306 538 307 539 /* Eat slash */ 308 if ( ops->plb_get_char(next) == '/')540 if (plb_get_char(next) == '/') 309 541 next++; 310 542 … … 319 551 /* Collect the component */ 320 552 len = 0; 321 while ((next <= last) && ( ops->plb_get_char(next) != '/')) {553 while ((next <= last) && (plb_get_char(next) != '/')) { 322 554 if (len + 1 == NAME_MAX) { 323 555 /* Component length overflow */ … … 325 557 goto out; 326 558 } 327 component[len++] = ops->plb_get_char(next);559 component[len++] = plb_get_char(next); 328 560 /* Process next character */ 329 561 next++; … … 357 589 358 590 async_exch_t *exch = async_exchange_begin(tmp->mp_data.sess); 359 async_forward_slow(rid, exch, VFS_OUT_LOOKUP, next, last,360 tmp->mp_data.devmap_handle, lflag, index,591 async_forward_slow(rid, exch, VFS_OUT_LOOKUP, next, 592 last, tmp->mp_data.devmap_handle, lflag, index, 361 593 IPC_FF_ROUTE_FROM_ME); 362 594 async_exchange_end(exch); … … 451 683 len = 0; 452 684 while (next <= last) { 453 if ( ops->plb_get_char(next) == '/') {685 if (plb_get_char(next) == '/') { 454 686 /* More than one component */ 455 687 async_answer_0(rid, ENOENT); … … 463 695 } 464 696 465 component[len++] = ops->plb_get_char(next);697 component[len++] = plb_get_char(next); 466 698 /* Process next character */ 467 699 next++; … … 637 869 rc = ops->node_open(fn); 638 870 aoff64_t size = ops->size_get(fn); 639 async_answer_4(rid, rc, LOWER32(size), UPPER32(size), ops->lnkcnt_get(fn), 871 async_answer_4(rid, rc, LOWER32(size), UPPER32(size), 872 ops->lnkcnt_get(fn), 640 873 (ops->is_file(fn) ? L_FILE : 0) | (ops->is_directory(fn) ? L_DIRECTORY : 0)); 641 874
Note:
See TracChangeset
for help on using the changeset viewer.