Changes in / [a2271a3:eff10e03] in mainline
- Location:
- uspace
- Files:
-
- 18 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bdsh/compl.c
ra2271a3 reff10e03 280 280 281 281 cs->dir = opendir(*cs->path); 282 283 /* Skip directories that we fail to open. */284 if (cs->dir == NULL)285 cs->path++;286 282 } 287 283 -
uspace/drv/bus/usb/usbmast/scsi_ms.c
ra2271a3 reff10e03 61 61 } 62 62 63 static void usbmast_dump_sense(scsi_sense_data_t *sense_buf) 64 { 63 static void usbmast_dump_sense(usbmast_fun_t *mfun) 64 { 65 scsi_sense_data_t sense_buf; 65 66 unsigned sense_key; 66 67 sense_key = sense_buf->flags_key & 0x0f; 68 printf("Got sense data. Sense key: 0x%x (%s), ASC 0x%02x, " 69 "ASCQ 0x%02x.\n", sense_key, 70 scsi_get_sense_key_str(sense_key), 71 sense_buf->additional_code, 72 sense_buf->additional_cqual); 73 } 74 75 /** Run SCSI command. 76 * 77 * Run command and repeat in case of unit attention. 78 * XXX This is too simplified. 79 */ 80 static int usbmast_run_cmd(usbmast_fun_t *mfun, scsi_cmd_t *cmd) 81 { 82 uint8_t sense_key; 83 scsi_sense_data_t sense_buf; 84 int rc; 85 86 do { 87 rc = usb_massstor_cmd(mfun, 0xDEADBEEF, cmd); 88 if (rc != EOK) { 89 usb_log_error("Inquiry transport failed, device %s: %s.\n", 90 mfun->mdev->ddf_dev->name, str_error(rc)); 91 return rc; 92 } 93 94 if (cmd->status == CMDS_GOOD) 95 return EOK; 96 97 usb_log_error("SCSI command failed, device %s.\n", 98 mfun->mdev->ddf_dev->name); 99 100 rc = usbmast_request_sense(mfun, &sense_buf, sizeof(sense_buf)); 101 if (rc != EOK) { 102 usb_log_error("Failed to read sense data.\n"); 103 return EIO; 104 } 105 106 /* Dump sense data to log */ 107 usbmast_dump_sense(&sense_buf); 108 109 /* Get sense key */ 67 int rc; 68 69 rc = usbmast_request_sense(mfun, &sense_buf, sizeof(sense_buf)); 70 if (rc == EOK) { 110 71 sense_key = sense_buf.flags_key & 0x0f; 111 112 if (sense_key == SCSI_SK_UNIT_ATTENTION) { 113 printf("Got unit attention. Re-trying command.\n"); 114 } 115 116 } while (sense_key == SCSI_SK_UNIT_ATTENTION); 117 118 /* Command status is not good, nevertheless transport succeeded. */ 119 return EOK; 72 printf("Got sense data. Sense key: 0x%x (%s), ASC 0x%02x, " 73 "ASCQ 0x%02x.\n", sense_key, 74 scsi_get_sense_key_str(sense_key), 75 sense_buf.additional_code, 76 sense_buf.additional_cqual); 77 } else { 78 printf("Failed to read sense data.\n"); 79 } 120 80 } 121 81 … … 154 114 usb_log_error("Inquiry command failed, device %s.\n", 155 115 mfun->mdev->ddf_dev->name); 116 usbmast_dump_sense(mfun); 156 117 return EIO; 157 118 } … … 253 214 cmd.data_in_size = sizeof(data); 254 215 255 rc = usb mast_run_cmd(mfun, &cmd);216 rc = usb_massstor_cmd(mfun, 0xDEADBEEF, &cmd); 256 217 257 218 if (rc != EOK) { … … 264 225 usb_log_error("Read Capacity (10) command failed, device %s.\n", 265 226 mfun->mdev->ddf_dev->name); 227 usbmast_dump_sense(mfun); 266 228 return EIO; 267 229 } … … 290 252 { 291 253 scsi_cmd_t cmd; 292 scsi_cdb_read_1 0_t cdb;254 scsi_cdb_read_12_t cdb; 293 255 int rc; 294 256 … … 296 258 return ELIMIT; 297 259 298 if ( nblocks > UINT16_MAX)260 if ((uint64_t)nblocks * mfun->block_size > UINT32_MAX) 299 261 return ELIMIT; 300 262 301 263 memset(&cdb, 0, sizeof(cdb)); 302 cdb.op_code = SCSI_CMD_READ_1 0;264 cdb.op_code = SCSI_CMD_READ_12; 303 265 cdb.lba = host2uint32_t_be(ba); 304 cdb.xfer_len = host2uint 16_t_be(nblocks);266 cdb.xfer_len = host2uint32_t_be(nblocks); 305 267 306 268 memset(&cmd, 0, sizeof(cmd)); … … 310 272 cmd.data_in_size = nblocks * mfun->block_size; 311 273 312 rc = usb mast_run_cmd(mfun, &cmd);274 rc = usb_massstor_cmd(mfun, 0xDEADBEEF, &cmd); 313 275 314 276 if (rc != EOK) { 315 usb_log_error("Read (1 0) transport failed, device %s: %s.\n",277 usb_log_error("Read (12) transport failed, device %s: %s.\n", 316 278 mfun->mdev->ddf_dev->name, str_error(rc)); 317 279 return rc; … … 319 281 320 282 if (cmd.status != CMDS_GOOD) { 321 usb_log_error("Read (1 0) command failed, device %s.\n",283 usb_log_error("Read (12) command failed, device %s.\n", 322 284 mfun->mdev->ddf_dev->name); 285 usbmast_dump_sense(mfun); 323 286 return EIO; 324 287 } … … 346 309 { 347 310 scsi_cmd_t cmd; 348 scsi_cdb_write_1 0_t cdb;311 scsi_cdb_write_12_t cdb; 349 312 int rc; 350 313 … … 352 315 return ELIMIT; 353 316 354 if ( nblocks > UINT16_MAX)317 if ((uint64_t)nblocks * mfun->block_size > UINT32_MAX) 355 318 return ELIMIT; 356 319 357 320 memset(&cdb, 0, sizeof(cdb)); 358 cdb.op_code = SCSI_CMD_WRITE_1 0;321 cdb.op_code = SCSI_CMD_WRITE_12; 359 322 cdb.lba = host2uint32_t_be(ba); 360 cdb.xfer_len = host2uint 16_t_be(nblocks);323 cdb.xfer_len = host2uint32_t_be(nblocks); 361 324 362 325 memset(&cmd, 0, sizeof(cmd)); … … 366 329 cmd.data_out_size = nblocks * mfun->block_size; 367 330 368 rc = usb mast_run_cmd(mfun, &cmd);331 rc = usb_massstor_cmd(mfun, 0xDEADBEEF, &cmd); 369 332 370 333 if (rc != EOK) { 371 usb_log_error("Write (1 0) transport failed, device %s: %s.\n",334 usb_log_error("Write (12) transport failed, device %s: %s.\n", 372 335 mfun->mdev->ddf_dev->name, str_error(rc)); 373 336 return rc; … … 375 338 376 339 if (cmd.status != CMDS_GOOD) { 377 usb_log_error("Write (1 0) command failed, device %s.\n",340 usb_log_error("Write (12) command failed, device %s.\n", 378 341 mfun->mdev->ddf_dev->name); 342 usbmast_dump_sense(mfun); 379 343 return EIO; 380 344 } -
uspace/lib/fs/libfs.c
ra2271a3 reff10e03 45 45 #include <mem.h> 46 46 #include <sys/stat.h> 47 #include <stdlib.h>48 47 49 48 #define on_error(rc, action) \ … … 62 61 } while (0) 63 62 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-bit96 async_answer_3(rid, EOK, index, size, lnkcnt);97 else98 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 else143 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-bit159 async_answer_2(rid, EOK, wbytes, nsize);160 else161 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 by225 * IPC_M_CONNECT_ME_TO calls as opposed to callback connections226 * 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 285 63 /** Register file system server. 286 64 * … … 290 68 * 291 69 * @param sess Session for communication with VFS. 70 * @param reg File system registration structure. It will be 71 * initialized by this function. 292 72 * @param info VFS info structure supplied by the file system 293 73 * implementation. 294 * @param vops Address of the vfs_out_ops_t structure.295 * @param lops Address of the libfs_ops_t structure.74 * @param conn Connection fibril for handling all calls originating in 75 * VFS. 296 76 * 297 77 * @return EOK on success or a non-zero error code on errror. 298 78 * 299 79 */ 300 int fs_register(async_sess_t *sess, vfs_info_t *info, vfs_out_ops_t *vops,301 libfs_ops_t *lops)80 int fs_register(async_sess_t *sess, fs_reg_t *reg, vfs_info_t *info, 81 async_client_conn_t conn) 302 82 { 303 83 /* … … 324 104 325 105 /* 326 * Set VFS_OUT and libfs operations.327 */328 vfs_out_ops = vops;329 libfs_ops = lops;330 331 /*332 106 * Ask VFS for callback connection. 333 107 */ 334 async_connect_to_me(exch, 0, 0, 0, vfs_connection, NULL);108 async_connect_to_me(exch, 0, 0, 0, conn, NULL); 335 109 336 110 /* 337 111 * Allocate piece of address space for PLB. 338 112 */ 339 reg .plb_ro = as_get_mappable_page(PLB_SIZE);340 if (!reg .plb_ro) {113 reg->plb_ro = as_get_mappable_page(PLB_SIZE); 114 if (!reg->plb_ro) { 341 115 async_exchange_end(exch); 342 116 async_wait_for(req, NULL); … … 347 121 * Request sharing the Path Lookup Buffer with VFS. 348 122 */ 349 rc = async_share_in_start_0_0(exch, reg .plb_ro, PLB_SIZE);123 rc = async_share_in_start_0_0(exch, reg->plb_ro, PLB_SIZE); 350 124 351 125 async_exchange_end(exch); … … 360 134 */ 361 135 async_wait_for(req, NULL); 362 reg .fs_handle = (int) IPC_GET_ARG1(answer);136 reg->fs_handle = (int) IPC_GET_ARG1(answer); 363 137 364 138 /* … … 366 140 * the same connection fibril as well. 367 141 */ 368 async_set_client_connection( vfs_connection);142 async_set_client_connection(conn); 369 143 370 144 return IPC_GET_RETVAL(answer); … … 377 151 378 152 void libfs_mount(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_callid_t rid, 379 ipc_call_t *req )153 ipc_call_t *request) 380 154 { 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 );155 devmap_handle_t mp_devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 156 fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*request); 157 fs_handle_t mr_fs_handle = (fs_handle_t) IPC_GET_ARG3(*request); 158 devmap_handle_t mr_devmap_handle = (devmap_handle_t) IPC_GET_ARG4(*request); 385 159 386 160 async_sess_t *mountee_sess = async_clone_receive(EXCHANGE_PARALLEL); … … 438 212 } 439 213 440 void libfs_unmount(libfs_ops_t *ops, ipc_callid_t rid, ipc_call_t *req )214 void libfs_unmount(libfs_ops_t *ops, ipc_callid_t rid, ipc_call_t *request) 441 215 { 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 );216 devmap_handle_t mp_devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 217 fs_index_t mp_fs_index = (fs_index_t) IPC_GET_ARG2(*request); 444 218 fs_node_t *fn; 445 219 int res; … … 485 259 } 486 260 487 static char plb_get_char(unsigned pos)488 {489 return reg.plb_ro[pos % PLB_SIZE];490 }491 492 261 /** Lookup VFS triplet by name in the file system name space. 493 262 * … … 504 273 */ 505 274 void libfs_lookup(libfs_ops_t *ops, fs_handle_t fs_handle, ipc_callid_t rid, 506 ipc_call_t *req )275 ipc_call_t *request) 507 276 { 508 unsigned int first = IPC_GET_ARG1(*req );509 unsigned int last = IPC_GET_ARG2(*req );277 unsigned int first = IPC_GET_ARG1(*request); 278 unsigned int last = IPC_GET_ARG2(*request); 510 279 unsigned int next = first; 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 );280 devmap_handle_t devmap_handle = IPC_GET_ARG3(*request); 281 int lflag = IPC_GET_ARG4(*request); 282 fs_index_t index = IPC_GET_ARG5(*request); 514 283 char component[NAME_MAX + 1]; 515 284 int len; … … 529 298 async_exch_t *exch = async_exchange_begin(cur->mp_data.sess); 530 299 async_forward_slow(rid, exch, VFS_OUT_LOOKUP, next, last, 531 cur->mp_data.devmap_handle, lflag, index, 532 IPC_FF_ROUTE_FROM_ME); 300 cur->mp_data.devmap_handle, lflag, index, IPC_FF_ROUTE_FROM_ME); 533 301 async_exchange_end(exch); 534 302 … … 538 306 539 307 /* Eat slash */ 540 if ( plb_get_char(next) == '/')308 if (ops->plb_get_char(next) == '/') 541 309 next++; 542 310 … … 551 319 /* Collect the component */ 552 320 len = 0; 553 while ((next <= last) && ( plb_get_char(next) != '/')) {321 while ((next <= last) && (ops->plb_get_char(next) != '/')) { 554 322 if (len + 1 == NAME_MAX) { 555 323 /* Component length overflow */ … … 557 325 goto out; 558 326 } 559 component[len++] = plb_get_char(next);327 component[len++] = ops->plb_get_char(next); 560 328 /* Process next character */ 561 329 next++; … … 589 357 590 358 async_exch_t *exch = async_exchange_begin(tmp->mp_data.sess); 591 async_forward_slow(rid, exch, VFS_OUT_LOOKUP, next, 592 last,tmp->mp_data.devmap_handle, lflag, index,359 async_forward_slow(rid, exch, VFS_OUT_LOOKUP, next, last, 360 tmp->mp_data.devmap_handle, lflag, index, 593 361 IPC_FF_ROUTE_FROM_ME); 594 362 async_exchange_end(exch); … … 683 451 len = 0; 684 452 while (next <= last) { 685 if ( plb_get_char(next) == '/') {453 if (ops->plb_get_char(next) == '/') { 686 454 /* More than one component */ 687 455 async_answer_0(rid, ENOENT); … … 695 463 } 696 464 697 component[len++] = plb_get_char(next);465 component[len++] = ops->plb_get_char(next); 698 466 /* Process next character */ 699 467 next++; … … 869 637 rc = ops->node_open(fn); 870 638 aoff64_t size = ops->size_get(fn); 871 async_answer_4(rid, rc, LOWER32(size), UPPER32(size), 872 ops->lnkcnt_get(fn), 639 async_answer_4(rid, rc, LOWER32(size), UPPER32(size), ops->lnkcnt_get(fn), 873 640 (ops->is_file(fn) ? L_FILE : 0) | (ops->is_directory(fn) ? L_DIRECTORY : 0)); 874 641 -
uspace/lib/fs/libfs.h
ra2271a3 reff10e03 43 43 44 44 typedef struct { 45 int (* mounted)(devmap_handle_t, const char *, fs_index_t *, aoff64_t *,46 unsigned *);47 int (* unmounted)(devmap_handle_t);48 int (* read)(devmap_handle_t, fs_index_t, aoff64_t, size_t *);49 int (* write)(devmap_handle_t, fs_index_t, aoff64_t, size_t *,50 aoff64_t *);51 int (* truncate)(devmap_handle_t, fs_index_t, aoff64_t);52 int (* close)(devmap_handle_t, fs_index_t);53 int (* destroy)(devmap_handle_t, fs_index_t);54 int (* sync)(devmap_handle_t, fs_index_t);55 } vfs_out_ops_t;56 57 typedef struct {58 45 bool mp_active; 59 46 async_sess_t *sess; … … 84 71 int (* has_children)(bool *, fs_node_t *); 85 72 /* 86 * The second set of methods are usually mere getters that do not 87 * returnan integer error code.73 * The second set of methods are usually mere getters that do not return 74 * an integer error code. 88 75 */ 89 76 fs_index_t (* index_get)(fs_node_t *); 90 77 aoff64_t (* size_get)(fs_node_t *); 91 78 unsigned int (* lnkcnt_get)(fs_node_t *); 79 char (* plb_get_char)(unsigned pos); 92 80 bool (* is_directory)(fs_node_t *); 93 81 bool (* is_file)(fs_node_t *); … … 100 88 } fs_reg_t; 101 89 102 extern int fs_register(async_sess_t *, vfs_info_t *, vfs_out_ops_t *,103 libfs_ops_t *);90 extern int fs_register(async_sess_t *, fs_reg_t *, vfs_info_t *, 91 async_client_conn_t); 104 92 105 93 extern void fs_node_initialize(fs_node_t *); 94 95 extern void libfs_mount(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *); 96 extern void libfs_unmount(libfs_ops_t *, ipc_callid_t, ipc_call_t *); 97 extern void libfs_lookup(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *); 98 extern void libfs_stat(libfs_ops_t *, fs_handle_t, ipc_callid_t, ipc_call_t *); 99 extern void libfs_open_node(libfs_ops_t *, fs_handle_t, ipc_callid_t, 100 ipc_call_t *); 106 101 107 102 #endif -
uspace/lib/scsi/include/scsi/sbc.h
ra2271a3 reff10e03 56 56 }; 57 57 58 /** SCSI Read (10) command */59 typedef struct {60 /** Operation code (SCSI_CMD_READ_10) */61 uint8_t op_code;62 /** RdProtect, DPO, FUA, Reserved, FUA_NV, Obsolete */63 uint8_t flags;64 /** Logical block address */65 uint32_t lba;66 /** Reserved, Group Number */67 uint8_t group_no;68 /** Transfer length */69 uint16_t xfer_len;70 /** Control */71 uint8_t control;72 } __attribute__((packed)) scsi_cdb_read_10_t;73 74 58 /** SCSI Read (12) command */ 75 59 typedef struct { 76 60 /** Operation code (SCSI_CMD_READ_12) */ 77 61 uint8_t op_code; 78 /** RdProtect, DPO, FUA, Reserved, FUA_NV, Obsolete*/62 /** RdProtect, DPO, FUA, Reserved, FUA_NV, Reserved */ 79 63 uint8_t flags; 80 64 /** Logical block address */ … … 131 115 } scsi_read_capacity_10_data_t; 132 116 133 /** SCSI Write (10) command */134 typedef struct {135 /** Operation code (SCSI_CMD_WRITE_10) */136 uint8_t op_code;137 /** WrProtect, DPO, FUA, Reserved, FUA_NV, Obsolete */138 uint8_t flags;139 /** Logical block address */140 uint32_t lba;141 /** Reserved, Group Number */142 uint8_t group_no;143 /** Transfer length */144 uint16_t xfer_len;145 /** Control */146 uint8_t control;147 } __attribute__((packed)) scsi_cdb_write_10_t;148 149 117 /** SCSI Write (12) command */ 150 118 typedef struct { 151 119 /** Operation code (SCSI_CMD_WRITE_12) */ 152 120 uint8_t op_code; 153 /** WrProtect, DPO, FUA, Reserved, FUA_NV, Obsolete*/121 /** WrProtect, DPO, FUA, Reserved, FUA_NV, Reserved */ 154 122 uint8_t flags; 155 123 /** Logical block address */ -
uspace/srv/fs/devfs/devfs.c
ra2271a3 reff10e03 57 57 }; 58 58 59 fs_reg_t devfs_reg; 60 61 static void devfs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 62 { 63 if (iid) 64 async_answer_0(iid, EOK); 65 66 while (true) { 67 ipc_call_t call; 68 ipc_callid_t callid = async_get_call(&call); 69 70 if (!IPC_GET_IMETHOD(call)) 71 return; 72 73 switch (IPC_GET_IMETHOD(call)) { 74 case VFS_OUT_MOUNTED: 75 devfs_mounted(callid, &call); 76 break; 77 case VFS_OUT_MOUNT: 78 devfs_mount(callid, &call); 79 break; 80 case VFS_OUT_UNMOUNTED: 81 devfs_unmounted(callid, &call); 82 break; 83 case VFS_OUT_UNMOUNT: 84 devfs_unmount(callid, &call); 85 break; 86 case VFS_OUT_LOOKUP: 87 devfs_lookup(callid, &call); 88 break; 89 case VFS_OUT_OPEN_NODE: 90 devfs_open_node(callid, &call); 91 break; 92 case VFS_OUT_STAT: 93 devfs_stat(callid, &call); 94 break; 95 case VFS_OUT_READ: 96 devfs_read(callid, &call); 97 break; 98 case VFS_OUT_WRITE: 99 devfs_write(callid, &call); 100 break; 101 case VFS_OUT_TRUNCATE: 102 devfs_truncate(callid, &call); 103 break; 104 case VFS_OUT_CLOSE: 105 devfs_close(callid, &call); 106 break; 107 case VFS_OUT_SYNC: 108 devfs_sync(callid, &call); 109 break; 110 case VFS_OUT_DESTROY: 111 devfs_destroy(callid, &call); 112 break; 113 default: 114 async_answer_0(callid, ENOTSUP); 115 break; 116 } 117 } 118 } 119 59 120 int main(int argc, char *argv[]) 60 121 { … … 73 134 } 74 135 75 int rc = fs_register(vfs_sess, &devfs_ vfs_info, &devfs_ops,76 &devfs_libfs_ops);136 int rc = fs_register(vfs_sess, &devfs_reg, &devfs_vfs_info, 137 devfs_connection); 77 138 if (rc != EOK) { 78 139 printf("%s: Failed to register file system (%d)\n", NAME, rc); … … 91 152 * @} 92 153 */ 93 -
uspace/srv/fs/devfs/devfs.h
ra2271a3 reff10e03 36 36 #include <libfs.h> 37 37 38 extern vfs_out_ops_t devfs_ops; 39 extern libfs_ops_t devfs_libfs_ops; 38 extern fs_reg_t devfs_reg; 40 39 41 40 #endif -
uspace/srv/fs/devfs/devfs_ops.c
ra2271a3 reff10e03 403 403 } 404 404 405 static char devfs_plb_get_char(unsigned pos) 406 { 407 return devfs_reg.plb_ro[pos % PLB_SIZE]; 408 } 409 405 410 static bool devfs_is_directory(fs_node_t *fn) 406 411 { … … 442 447 .size_get = devfs_size_get, 443 448 .lnkcnt_get = devfs_lnkcnt_get, 449 .plb_get_char = devfs_plb_get_char, 444 450 .is_directory = devfs_is_directory, 445 451 .is_file = devfs_is_file, … … 456 462 } 457 463 458 static int devfs_mounted(devmap_handle_t devmap_handle, const char *opts, 459 fs_index_t *index, aoff64_t *size, unsigned *lnkcnt) 460 { 461 *index = 0; 462 *size = 0; 463 *lnkcnt = 0; 464 return EOK; 465 } 466 467 static int devfs_unmounted(devmap_handle_t devmap_handle) 468 { 469 return ENOTSUP; 470 } 471 472 static int 473 devfs_read(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos, 474 size_t *rbytes) 475 { 464 void devfs_mounted(ipc_callid_t rid, ipc_call_t *request) 465 { 466 char *opts; 467 468 /* Accept the mount options */ 469 sysarg_t retval = async_data_write_accept((void **) &opts, true, 0, 0, 470 0, NULL); 471 if (retval != EOK) { 472 async_answer_0(rid, retval); 473 return; 474 } 475 476 free(opts); 477 async_answer_3(rid, EOK, 0, 0, 0); 478 } 479 480 void devfs_mount(ipc_callid_t rid, ipc_call_t *request) 481 { 482 libfs_mount(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request); 483 } 484 485 void devfs_unmounted(ipc_callid_t rid, ipc_call_t *request) 486 { 487 async_answer_0(rid, ENOTSUP); 488 } 489 490 void devfs_unmount(ipc_callid_t rid, ipc_call_t *request) 491 { 492 libfs_unmount(&devfs_libfs_ops, rid, request); 493 } 494 495 void devfs_lookup(ipc_callid_t rid, ipc_call_t *request) 496 { 497 libfs_lookup(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request); 498 } 499 500 void devfs_open_node(ipc_callid_t rid, ipc_call_t *request) 501 { 502 libfs_open_node(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request); 503 } 504 505 void devfs_stat(ipc_callid_t rid, ipc_call_t *request) 506 { 507 libfs_stat(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request); 508 } 509 510 void devfs_read(ipc_callid_t rid, ipc_call_t *request) 511 { 512 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 513 aoff64_t pos = 514 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 515 476 516 if (index == 0) { 477 517 ipc_callid_t callid; … … 479 519 if (!async_data_read_receive(&callid, &size)) { 480 520 async_answer_0(callid, EINVAL); 481 return EINVAL; 521 async_answer_0(rid, EINVAL); 522 return; 482 523 } 483 524 … … 499 540 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 500 541 free(desc); 501 *rbytes = 1;502 return EOK;542 async_answer_1(rid, EOK, 1); 543 return; 503 544 } 504 545 … … 514 555 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 515 556 free(desc); 516 *rbytes = 1;517 return EOK;557 async_answer_1(rid, EOK, 1); 558 return; 518 559 } 519 560 … … 522 563 523 564 async_answer_0(callid, ENOENT); 524 return ENOENT; 565 async_answer_1(rid, ENOENT, 0); 566 return; 525 567 } 526 568 … … 533 575 if (!async_data_read_receive(&callid, &size)) { 534 576 async_answer_0(callid, EINVAL); 535 return EINVAL; 577 async_answer_0(rid, EINVAL); 578 return; 536 579 } 537 580 … … 542 585 async_data_read_finalize(callid, desc[pos].name, str_size(desc[pos].name) + 1); 543 586 free(desc); 544 *rbytes = 1;545 return EOK;587 async_answer_1(rid, EOK, 1); 588 return; 546 589 } 547 590 548 591 free(desc); 549 592 async_answer_0(callid, ENOENT); 550 return ENOENT; 593 async_answer_1(rid, ENOENT, 0); 594 return; 551 595 } 552 596 … … 562 606 if (lnk == NULL) { 563 607 fibril_mutex_unlock(&devices_mutex); 564 return ENOENT; 608 async_answer_0(rid, ENOENT); 609 return; 565 610 } 566 611 … … 572 617 fibril_mutex_unlock(&devices_mutex); 573 618 async_answer_0(callid, EINVAL); 574 return EINVAL; 619 async_answer_0(rid, EINVAL); 620 return; 575 621 } 576 622 … … 579 625 580 626 ipc_call_t answer; 581 aid_t msg = async_send_4(exch, VFS_OUT_READ, devmap_handle, 582 index, LOWER32(pos), UPPER32(pos), &answer); 627 aid_t msg = async_send_3(exch, IPC_GET_IMETHOD(*request), 628 IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), 629 IPC_GET_ARG3(*request), &answer); 583 630 584 631 /* Forward the IPC_M_DATA_READ request to the driver */ … … 592 639 sysarg_t rc; 593 640 async_wait_for(msg, &rc); 594 595 *rbytes = IPC_GET_ARG1(answer); 596 return rc; 597 } 598 599 return ENOENT; 600 } 601 602 static int 603 devfs_write(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos, 604 size_t *wbytes, aoff64_t *nsize) 605 { 606 if (index == 0) 607 return ENOTSUP; 641 size_t bytes = IPC_GET_ARG1(answer); 642 643 /* Driver reply is the final result of the whole operation */ 644 async_answer_1(rid, rc, bytes); 645 return; 646 } 647 648 async_answer_0(rid, ENOENT); 649 } 650 651 void devfs_write(ipc_callid_t rid, ipc_call_t *request) 652 { 653 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 654 if (index == 0) { 655 async_answer_0(rid, ENOTSUP); 656 return; 657 } 608 658 609 659 devmap_handle_type_t type = devmap_handle_probe(index); … … 611 661 if (type == DEV_HANDLE_NAMESPACE) { 612 662 /* Namespace directory */ 613 return ENOTSUP; 663 async_answer_0(rid, ENOTSUP); 664 return; 614 665 } 615 666 … … 624 675 if (lnk == NULL) { 625 676 fibril_mutex_unlock(&devices_mutex); 626 return ENOENT; 677 async_answer_0(rid, ENOENT); 678 return; 627 679 } 628 680 … … 634 686 fibril_mutex_unlock(&devices_mutex); 635 687 async_answer_0(callid, EINVAL); 636 return EINVAL; 688 async_answer_0(rid, EINVAL); 689 return; 637 690 } 638 691 … … 641 694 642 695 ipc_call_t answer; 643 aid_t msg = async_send_4(exch, VFS_OUT_WRITE, devmap_handle, 644 index, LOWER32(pos), UPPER32(pos), &answer); 696 aid_t msg = async_send_3(exch, IPC_GET_IMETHOD(*request), 697 IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), 698 IPC_GET_ARG3(*request), &answer); 645 699 646 700 /* Forward the IPC_M_DATA_WRITE request to the driver */ … … 654 708 sysarg_t rc; 655 709 async_wait_for(msg, &rc); 656 657 *wbytes = IPC_GET_ARG1(answer); 658 *nsize = 0; 659 return rc; 660 } 661 662 return ENOENT; 663 } 664 665 static int 666 devfs_truncate(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t size) 667 { 668 return ENOTSUP; 669 } 670 671 static int devfs_close(devmap_handle_t devmap_handle, fs_index_t index) 672 { 673 if (index == 0) 674 return EOK; 710 size_t bytes = IPC_GET_ARG1(answer); 711 712 /* Driver reply is the final result of the whole operation */ 713 async_answer_1(rid, rc, bytes); 714 return; 715 } 716 717 async_answer_0(rid, ENOENT); 718 } 719 720 void devfs_truncate(ipc_callid_t rid, ipc_call_t *request) 721 { 722 async_answer_0(rid, ENOTSUP); 723 } 724 725 void devfs_close(ipc_callid_t rid, ipc_call_t *request) 726 { 727 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 728 729 if (index == 0) { 730 async_answer_0(rid, EOK); 731 return; 732 } 675 733 676 734 devmap_handle_type_t type = devmap_handle_probe(index); … … 678 736 if (type == DEV_HANDLE_NAMESPACE) { 679 737 /* Namespace directory */ 680 return EOK; 738 async_answer_0(rid, EOK); 739 return; 681 740 } 682 741 … … 690 749 if (lnk == NULL) { 691 750 fibril_mutex_unlock(&devices_mutex); 692 return ENOENT; 751 async_answer_0(rid, ENOENT); 752 return; 693 753 } 694 754 … … 704 764 fibril_mutex_unlock(&devices_mutex); 705 765 706 return EOK; 707 } 708 709 return ENOENT; 710 } 711 712 static int devfs_sync(devmap_handle_t devmap_handle, fs_index_t index) 713 { 714 if (index == 0) 715 return EOK; 766 async_answer_0(rid, EOK); 767 return; 768 } 769 770 async_answer_0(rid, ENOENT); 771 } 772 773 void devfs_sync(ipc_callid_t rid, ipc_call_t *request) 774 { 775 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 776 777 if (index == 0) { 778 async_answer_0(rid, EOK); 779 return; 780 } 716 781 717 782 devmap_handle_type_t type = devmap_handle_probe(index); … … 719 784 if (type == DEV_HANDLE_NAMESPACE) { 720 785 /* Namespace directory */ 721 return EOK; 786 async_answer_0(rid, EOK); 787 return; 722 788 } 723 789 … … 731 797 if (lnk == NULL) { 732 798 fibril_mutex_unlock(&devices_mutex); 733 return ENOENT; 799 async_answer_0(rid, ENOENT); 800 return; 734 801 } 735 802 … … 741 808 742 809 ipc_call_t answer; 743 aid_t msg = async_send_2(exch, VFS_OUT_SYNC, devmap_handle,744 index, &answer);810 aid_t msg = async_send_2(exch, IPC_GET_IMETHOD(*request), 811 IPC_GET_ARG1(*request), IPC_GET_ARG2(*request), &answer); 745 812 746 813 async_exchange_end(exch); … … 752 819 async_wait_for(msg, &rc); 753 820 754 return rc; 755 } 756 757 return ENOENT; 758 } 759 760 static int devfs_destroy(devmap_handle_t devmap_handle, fs_index_t index) 761 { 762 return ENOTSUP; 763 } 764 765 vfs_out_ops_t devfs_ops = { 766 .mounted = devfs_mounted, 767 .unmounted = devfs_unmounted, 768 .read = devfs_read, 769 .write = devfs_write, 770 .truncate = devfs_truncate, 771 .close = devfs_close, 772 .destroy = devfs_destroy, 773 .sync = devfs_sync, 774 }; 821 /* Driver reply is the final result of the whole operation */ 822 async_answer_0(rid, rc); 823 return; 824 } 825 826 async_answer_0(rid, ENOENT); 827 } 828 829 void devfs_destroy(ipc_callid_t rid, ipc_call_t *request) 830 { 831 async_answer_0(rid, ENOTSUP); 832 } 775 833 776 834 /** -
uspace/srv/fs/devfs/devfs_ops.h
ra2271a3 reff10e03 34 34 #define DEVFS_DEVFS_OPS_H_ 35 35 36 #include <ipc/common.h> 36 37 #include <bool.h> 37 38 38 39 extern bool devfs_init(void); 40 41 extern void devfs_mounted(ipc_callid_t, ipc_call_t *); 42 extern void devfs_mount(ipc_callid_t, ipc_call_t *); 43 extern void devfs_unmounted(ipc_callid_t, ipc_call_t *); 44 extern void devfs_unmount(ipc_callid_t, ipc_call_t *); 45 extern void devfs_lookup(ipc_callid_t, ipc_call_t *); 46 extern void devfs_open_node(ipc_callid_t, ipc_call_t *); 47 extern void devfs_stat(ipc_callid_t, ipc_call_t *); 48 extern void devfs_sync(ipc_callid_t, ipc_call_t *); 49 extern void devfs_read(ipc_callid_t, ipc_call_t *); 50 extern void devfs_write(ipc_callid_t, ipc_call_t *); 51 extern void devfs_truncate(ipc_callid_t, ipc_call_t *); 52 extern void devfs_close(ipc_callid_t, ipc_call_t *); 53 extern void devfs_destroy(ipc_callid_t, ipc_call_t *); 39 54 40 55 #endif -
uspace/srv/fs/ext2fs/ext2fs.c
ra2271a3 reff10e03 1 1 /* 2 2 * Copyright (c) 2006 Martin Decky 3 * Copyright (c) 2008 Jakub Jermar 3 4 * Copyright (c) 2011 Martin Sucha 4 5 * All rights reserved. … … 54 55 }; 55 56 57 fs_reg_t ext2fs_reg; 58 59 /** 60 * This connection fibril processes VFS requests from VFS. 61 * 62 * In order to support simultaneous VFS requests, our design is as follows. 63 * The connection fibril accepts VFS requests from VFS. If there is only one 64 * instance of the fibril, VFS will need to serialize all VFS requests it sends 65 * to EXT2FS. To overcome this bottleneck, VFS can send EXT2FS the IPC_M_CONNECT_ME_TO 66 * call. In that case, a new connection fibril will be created, which in turn 67 * will accept the call. Thus, a new phone will be opened for VFS. 68 * 69 * There are few issues with this arrangement. First, VFS can run out of 70 * available phones. In that case, VFS can close some other phones or use one 71 * phone for more serialized requests. Similarily, EXT2FS can refuse to duplicate 72 * the connection. VFS should then just make use of already existing phones and 73 * route its requests through them. To avoid paying the fibril creation price 74 * upon each request, EXT2FS might want to keep the connections open after the 75 * request has been completed. 76 */ 77 static void ext2fs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 78 { 79 if (iid) { 80 /* 81 * This only happens for connections opened by 82 * IPC_M_CONNECT_ME_TO calls as opposed to callback connections 83 * created by IPC_M_CONNECT_TO_ME. 84 */ 85 async_answer_0(iid, EOK); 86 } 87 88 dprintf(NAME ": connection opened\n"); 89 while (true) { 90 ipc_call_t call; 91 ipc_callid_t callid = async_get_call(&call); 92 93 if (!IPC_GET_IMETHOD(call)) 94 return; 95 96 switch (IPC_GET_IMETHOD(call)) { 97 case VFS_OUT_MOUNTED: 98 ext2fs_mounted(callid, &call); 99 break; 100 case VFS_OUT_MOUNT: 101 ext2fs_mount(callid, &call); 102 break; 103 case VFS_OUT_UNMOUNTED: 104 ext2fs_unmounted(callid, &call); 105 break; 106 case VFS_OUT_UNMOUNT: 107 ext2fs_unmount(callid, &call); 108 break; 109 case VFS_OUT_LOOKUP: 110 ext2fs_lookup(callid, &call); 111 break; 112 case VFS_OUT_READ: 113 ext2fs_read(callid, &call); 114 break; 115 case VFS_OUT_WRITE: 116 ext2fs_write(callid, &call); 117 break; 118 case VFS_OUT_TRUNCATE: 119 ext2fs_truncate(callid, &call); 120 break; 121 case VFS_OUT_STAT: 122 ext2fs_stat(callid, &call); 123 break; 124 case VFS_OUT_CLOSE: 125 ext2fs_close(callid, &call); 126 break; 127 case VFS_OUT_DESTROY: 128 ext2fs_destroy(callid, &call); 129 break; 130 case VFS_OUT_OPEN_NODE: 131 ext2fs_open_node(callid, &call); 132 break; 133 case VFS_OUT_SYNC: 134 ext2fs_sync(callid, &call); 135 break; 136 default: 137 async_answer_0(callid, ENOTSUP); 138 break; 139 } 140 } 141 } 142 56 143 int main(int argc, char **argv) 57 144 { … … 71 158 } 72 159 73 rc = fs_register(vfs_sess, &ext2fs_vfs_info, &ext2fs_ops, 74 &ext2fs_libfs_ops); 160 rc = fs_register(vfs_sess, &ext2fs_reg, &ext2fs_vfs_info, ext2fs_connection); 75 161 if (rc != EOK) { 76 162 fprintf(stdout, NAME ": Failed to register fs (%d)\n", rc); -
uspace/srv/fs/ext2fs/ext2fs.h
ra2271a3 reff10e03 1 1 /* 2 * Copyright (c) 2008 Jakub Jermar 2 3 * Copyright (c) 2011 Martin Sucha 3 4 * All rights reserved. … … 35 36 36 37 #include <libext2.h> 38 #include <fibril_synch.h> 37 39 #include <libfs.h> 40 #include <atomic.h> 38 41 #include <sys/types.h> 42 #include <bool.h> 43 #include "../../vfs/vfs.h" 44 45 #ifndef dprintf 46 #define dprintf(...) printf(__VA_ARGS__) 47 #endif 39 48 40 49 #define min(a, b) ((a) < (b) ? (a) : (b)) 41 50 42 extern vfs_out_ops_t ext2fs_ops; 43 extern libfs_ops_t ext2fs_libfs_ops; 51 extern fs_reg_t ext2fs_reg; 44 52 45 53 extern int ext2fs_global_init(void); 46 54 extern int ext2fs_global_fini(void); 55 extern void ext2fs_mounted(ipc_callid_t, ipc_call_t *); 56 extern void ext2fs_mount(ipc_callid_t, ipc_call_t *); 57 extern void ext2fs_unmounted(ipc_callid_t, ipc_call_t *); 58 extern void ext2fs_unmount(ipc_callid_t, ipc_call_t *); 59 extern void ext2fs_lookup(ipc_callid_t, ipc_call_t *); 60 extern void ext2fs_read(ipc_callid_t, ipc_call_t *); 61 extern void ext2fs_write(ipc_callid_t, ipc_call_t *); 62 extern void ext2fs_truncate(ipc_callid_t, ipc_call_t *); 63 extern void ext2fs_stat(ipc_callid_t, ipc_call_t *); 64 extern void ext2fs_close(ipc_callid_t, ipc_call_t *); 65 extern void ext2fs_destroy(ipc_callid_t, ipc_call_t *); 66 extern void ext2fs_open_node(ipc_callid_t, ipc_call_t *); 67 extern void ext2fs_stat(ipc_callid_t, ipc_call_t *); 68 extern void ext2fs_sync(ipc_callid_t, ipc_call_t *); 47 69 48 70 #endif -
uspace/srv/fs/ext2fs/ext2fs_ops.c
ra2271a3 reff10e03 1 1 /* 2 * Copyright (c) 2008 Jakub Jermar 2 3 * Copyright (c) 2011 Martin Sucha 3 4 * All rights reserved. … … 86 87 */ 87 88 static int ext2fs_instance_get(devmap_handle_t, ext2fs_instance_t **); 88 static int ext2fs_read_directory(ipc_callid_t, aoff64_t, size_t,89 ext2fs_instance_t *, ext2_inode_ref_t *, size_t *);90 static int ext2fs_read_file(ipc_callid_t, aoff64_t, size_t, ext2fs_instance_t *,91 ext2_inode_ref_t *, size_t *);89 static void ext2fs_read_directory(ipc_callid_t, ipc_callid_t, aoff64_t, 90 size_t, ext2fs_instance_t *, ext2_inode_ref_t *); 91 static void ext2fs_read_file(ipc_callid_t, ipc_callid_t, aoff64_t, 92 size_t, ext2fs_instance_t *, ext2_inode_ref_t *); 92 93 static bool ext2fs_is_dots(const uint8_t *, size_t); 93 94 static int ext2fs_node_get_core(fs_node_t **, ext2fs_instance_t *, fs_index_t); … … 110 111 static aoff64_t ext2fs_size_get(fs_node_t *); 111 112 static unsigned ext2fs_lnkcnt_get(fs_node_t *); 113 static char ext2fs_plb_get_char(unsigned); 112 114 static bool ext2fs_is_directory(fs_node_t *); 113 115 static bool ext2fs_is_file(fs_node_t *node); … … 536 538 EXT2FS_DBG("%u", count); 537 539 return count; 540 } 541 542 char ext2fs_plb_get_char(unsigned pos) 543 { 544 return ext2fs_reg.plb_ro[pos % PLB_SIZE]; 538 545 } 539 546 … … 579 586 .size_get = ext2fs_size_get, 580 587 .lnkcnt_get = ext2fs_lnkcnt_get, 588 .plb_get_char = ext2fs_plb_get_char, 581 589 .is_directory = ext2fs_is_directory, 582 590 .is_file = ext2fs_is_file, … … 588 596 */ 589 597 590 static int ext2fs_mounted(devmap_handle_t devmap_handle, const char *opts, 591 fs_index_t *index, aoff64_t *size, unsigned *lnkcnt) 598 void ext2fs_mounted(ipc_callid_t rid, ipc_call_t *request) 592 599 { 593 600 EXT2FS_DBG(""); 594 601 int rc; 602 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 595 603 ext2_filesystem_t *fs; 596 604 ext2fs_instance_t *inst; 597 605 bool read_only; 598 606 607 /* Accept the mount options */ 608 char *opts; 609 rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL); 610 611 if (rc != EOK) { 612 async_answer_0(rid, rc); 613 return; 614 } 615 616 free(opts); 617 599 618 /* Allocate libext2 filesystem structure */ 600 619 fs = (ext2_filesystem_t *) malloc(sizeof(ext2_filesystem_t)); 601 if (fs == NULL) 602 return ENOMEM; 620 if (fs == NULL) { 621 async_answer_0(rid, ENOMEM); 622 return; 623 } 603 624 604 625 /* Allocate instance structure */ … … 606 627 if (inst == NULL) { 607 628 free(fs); 608 return ENOMEM; 629 async_answer_0(rid, ENOMEM); 630 return; 609 631 } 610 632 … … 614 636 free(fs); 615 637 free(inst); 616 return rc; 638 async_answer_0(rid, rc); 639 return; 617 640 } 618 641 … … 623 646 free(fs); 624 647 free(inst); 625 return rc; 648 async_answer_0(rid, rc); 649 return; 626 650 } 627 651 … … 632 656 free(fs); 633 657 free(inst); 634 return rc; 658 async_answer_0(rid, rc); 659 return; 635 660 } 636 661 … … 648 673 free(fs); 649 674 free(inst); 650 return rc; 675 async_answer_0(rid, rc); 676 return; 651 677 } 652 678 ext2fs_node_t *enode = EXT2FS_NODE(root_node); … … 657 683 fibril_mutex_unlock(&instance_list_mutex); 658 684 659 *index = EXT2_INODE_ROOT_INDEX; 660 *size = 0; 661 *lnkcnt = ext2_inode_get_usage_count(enode->inode_ref->inode); 685 async_answer_3(rid, EOK, 686 EXT2_INODE_ROOT_INDEX, 687 0, 688 ext2_inode_get_usage_count(enode->inode_ref->inode)); 662 689 663 690 ext2fs_node_put(root_node); 664 665 return EOK; 666 } 667 668 static int ext2fs_unmounted(devmap_handle_t devmap_handle) 669 { 670 EXT2FS_DBG(""); 691 } 692 693 void ext2fs_mount(ipc_callid_t rid, ipc_call_t *request) 694 { 695 EXT2FS_DBG(""); 696 libfs_mount(&ext2fs_libfs_ops, ext2fs_reg.fs_handle, rid, request); 697 } 698 699 void ext2fs_unmounted(ipc_callid_t rid, ipc_call_t *request) 700 { 701 EXT2FS_DBG(""); 702 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 671 703 ext2fs_instance_t *inst; 672 704 int rc; … … 674 706 rc = ext2fs_instance_get(devmap_handle, &inst); 675 707 676 if (rc != EOK) 677 return rc; 708 if (rc != EOK) { 709 async_answer_0(rid, rc); 710 return; 711 } 678 712 679 713 fibril_mutex_lock(&open_nodes_lock); … … 682 716 if (inst->open_nodes_count != 0) { 683 717 fibril_mutex_unlock(&open_nodes_lock); 684 return EBUSY; 718 async_answer_0(rid, EBUSY); 719 return; 685 720 } 686 721 … … 694 729 ext2_filesystem_fini(inst->filesystem); 695 730 696 return EOK; 697 } 698 699 static int 700 ext2fs_read(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos, 701 size_t *rbytes) 702 { 703 EXT2FS_DBG(""); 731 async_answer_0(rid, EOK); 732 } 733 734 void ext2fs_unmount(ipc_callid_t rid, ipc_call_t *request) 735 { 736 EXT2FS_DBG(""); 737 libfs_unmount(&ext2fs_libfs_ops, rid, request); 738 } 739 740 void ext2fs_lookup(ipc_callid_t rid, ipc_call_t *request) 741 { 742 EXT2FS_DBG(""); 743 libfs_lookup(&ext2fs_libfs_ops, ext2fs_reg.fs_handle, rid, request); 744 } 745 746 void ext2fs_read(ipc_callid_t rid, ipc_call_t *request) 747 { 748 EXT2FS_DBG(""); 749 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 750 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 751 aoff64_t pos = 752 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 704 753 705 754 ext2fs_instance_t *inst; … … 714 763 if (!async_data_read_receive(&callid, &size)) { 715 764 async_answer_0(callid, EINVAL); 716 return EINVAL; 765 async_answer_0(rid, EINVAL); 766 return; 717 767 } 718 768 … … 720 770 if (rc != EOK) { 721 771 async_answer_0(callid, rc); 722 return rc; 772 async_answer_0(rid, rc); 773 return; 723 774 } 724 775 … … 726 777 if (rc != EOK) { 727 778 async_answer_0(callid, rc); 728 return rc; 779 async_answer_0(rid, rc); 780 return; 729 781 } 730 782 731 783 if (ext2_inode_is_type(inst->filesystem->superblock, inode_ref->inode, 732 EXT2_INODE_MODE_FILE)) {733 rc = ext2fs_read_file(callid, pos, size, inst, inode_ref,734 rbytes);735 } else if (ext2_inode_is_type(inst->filesystem->superblock,736 inode_ref->inode,EXT2_INODE_MODE_DIRECTORY)) {737 rc = ext2fs_read_directory(callid, pos, size, inst, inode_ref,738 rbytes);739 }else {784 EXT2_INODE_MODE_FILE)) { 785 ext2fs_read_file(rid, callid, pos, size, inst, inode_ref); 786 } 787 else if (ext2_inode_is_type(inst->filesystem->superblock, inode_ref->inode, 788 EXT2_INODE_MODE_DIRECTORY)) { 789 ext2fs_read_directory(rid, callid, pos, size, inst, inode_ref); 790 } 791 else { 740 792 /* Other inode types not supported */ 741 793 async_answer_0(callid, ENOTSUP); 742 rc = ENOTSUP;794 async_answer_0(rid, ENOTSUP); 743 795 } 744 796 745 797 ext2_filesystem_put_inode_ref(inode_ref); 746 798 747 return rc;748 799 } 749 800 … … 763 814 } 764 815 765 int ext2fs_read_directory(ipc_callid_t callid, aoff64_t pos, size_t size,766 ext2fs_instance_t *inst, ext2_inode_ref_t *inode_ref, size_t *rbytes)816 void ext2fs_read_directory(ipc_callid_t rid, ipc_callid_t callid, aoff64_t pos, 817 size_t size, ext2fs_instance_t *inst, ext2_inode_ref_t *inode_ref) 767 818 { 768 819 ext2_directory_iterator_t it; … … 776 827 if (rc != EOK) { 777 828 async_answer_0(callid, rc); 778 return rc; 829 async_answer_0(rid, rc); 830 return; 779 831 } 780 832 … … 789 841 790 842 name_size = ext2_directory_entry_ll_get_name_length( 791 843 inst->filesystem->superblock, it.current); 792 844 793 845 /* skip . and .. */ … … 797 849 798 850 /* The on-disk entry does not contain \0 at the end 799 800 801 851 * end of entry name, so we copy it to new buffer 852 * and add the \0 at the end 853 */ 802 854 buf = malloc(name_size+1); 803 855 if (buf == NULL) { 804 856 ext2_directory_iterator_fini(&it); 805 857 async_answer_0(callid, ENOMEM); 806 return ENOMEM; 858 async_answer_0(rid, ENOMEM); 859 return; 807 860 } 808 861 memcpy(buf, &it.current->name, name_size); 809 *(buf +name_size) = 0;862 *(buf+name_size) = 0; 810 863 found = true; 811 (void) async_data_read_finalize(callid, buf, name_size +1);864 (void) async_data_read_finalize(callid, buf, name_size+1); 812 865 free(buf); 813 866 break; … … 818 871 ext2_directory_iterator_fini(&it); 819 872 async_answer_0(callid, rc); 820 return rc; 873 async_answer_0(rid, rc); 874 return; 821 875 } 822 876 } … … 824 878 if (found) { 825 879 rc = ext2_directory_iterator_next(&it); 826 if (rc != EOK) 827 return rc; 880 if (rc != EOK) { 881 async_answer_0(rid, rc); 882 return; 883 } 828 884 next = it.current_offset; 829 885 } 830 886 831 887 rc = ext2_directory_iterator_fini(&it); 832 if (rc != EOK) 833 return rc; 888 if (rc != EOK) { 889 async_answer_0(rid, rc); 890 return; 891 } 834 892 835 893 if (found) { 836 *rbytes = next - pos;837 return EOK;838 }else {894 async_answer_1(rid, EOK, next-pos); 895 } 896 else { 839 897 async_answer_0(callid, ENOENT); 840 return ENOENT;841 } 842 } 843 844 int ext2fs_read_file(ipc_callid_t callid, aoff64_t pos, size_t size,845 ext2fs_instance_t *inst, ext2_inode_ref_t *inode_ref, size_t *rbytes)898 async_answer_0(rid, ENOENT); 899 } 900 } 901 902 void ext2fs_read_file(ipc_callid_t rid, ipc_callid_t callid, aoff64_t pos, 903 size_t size, ext2fs_instance_t *inst, ext2_inode_ref_t *inode_ref) 846 904 { 847 905 int rc; … … 861 919 /* Read 0 bytes successfully */ 862 920 async_data_read_finalize(callid, NULL, 0); 863 *rbytes = 0;864 return EOK;921 async_answer_1(rid, EOK, 0); 922 return; 865 923 } 866 924 … … 881 939 if (rc != EOK) { 882 940 async_answer_0(callid, rc); 883 return rc; 941 async_answer_0(rid, rc); 942 return; 884 943 } 885 944 … … 893 952 if (buffer == NULL) { 894 953 async_answer_0(callid, ENOMEM); 895 return ENOMEM; 954 async_answer_0(rid, ENOMEM); 955 return; 896 956 } 897 957 … … 899 959 900 960 async_data_read_finalize(callid, buffer, bytes); 901 *rbytes = bytes;961 async_answer_1(rid, EOK, bytes); 902 962 903 963 free(buffer); 904 964 905 return EOK;965 return; 906 966 } 907 967 … … 910 970 if (rc != EOK) { 911 971 async_answer_0(callid, rc); 912 return rc; 972 async_answer_0(rid, rc); 973 return; 913 974 } 914 975 … … 917 978 918 979 rc = block_put(block); 919 if (rc != EOK) 920 return rc; 921 922 *rbytes = bytes; 923 return EOK; 924 } 925 926 static int 927 ext2fs_write(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos, 928 size_t *wbytes, aoff64_t *nsize) 929 { 930 EXT2FS_DBG(""); 931 return ENOTSUP; 932 } 933 934 static int 935 ext2fs_truncate(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t size) 936 { 937 EXT2FS_DBG(""); 938 return ENOTSUP; 939 } 940 941 static int ext2fs_close(devmap_handle_t devmap_handle, fs_index_t index) 942 { 943 EXT2FS_DBG(""); 944 return EOK; 945 } 946 947 static int ext2fs_destroy(devmap_handle_t devmap_handle, fs_index_t index) 948 { 949 EXT2FS_DBG(""); 950 return ENOTSUP; 951 } 952 953 static int ext2fs_sync(devmap_handle_t devmap_handle, fs_index_t index) 954 { 955 EXT2FS_DBG(""); 956 return ENOTSUP; 957 } 958 959 vfs_out_ops_t ext2fs_ops = { 960 .mounted = ext2fs_mounted, 961 .unmounted = ext2fs_unmounted, 962 .read = ext2fs_read, 963 .write = ext2fs_write, 964 .truncate = ext2fs_truncate, 965 .close = ext2fs_close, 966 .destroy = ext2fs_destroy, 967 .sync = ext2fs_sync, 968 }; 980 if (rc != EOK) { 981 async_answer_0(rid, rc); 982 return; 983 } 984 985 async_answer_1(rid, EOK, bytes); 986 } 987 988 void ext2fs_write(ipc_callid_t rid, ipc_call_t *request) 989 { 990 EXT2FS_DBG(""); 991 // devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 992 // fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 993 // aoff64_t pos = 994 // (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 995 996 // TODO 997 async_answer_0(rid, ENOTSUP); 998 } 999 1000 void ext2fs_truncate(ipc_callid_t rid, ipc_call_t *request) 1001 { 1002 EXT2FS_DBG(""); 1003 // devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 1004 // fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 1005 // aoff64_t size = 1006 // (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 1007 1008 // TODO 1009 async_answer_0(rid, ENOTSUP); 1010 } 1011 1012 void ext2fs_close(ipc_callid_t rid, ipc_call_t *request) 1013 { 1014 EXT2FS_DBG(""); 1015 async_answer_0(rid, EOK); 1016 } 1017 1018 void ext2fs_destroy(ipc_callid_t rid, ipc_call_t *request) 1019 { 1020 EXT2FS_DBG(""); 1021 // devmap_handle_t devmap_handle = (devmap_handle_t)IPC_GET_ARG1(*request); 1022 // fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request); 1023 1024 // TODO 1025 async_answer_0(rid, ENOTSUP); 1026 } 1027 1028 void ext2fs_open_node(ipc_callid_t rid, ipc_call_t *request) 1029 { 1030 EXT2FS_DBG(""); 1031 libfs_open_node(&ext2fs_libfs_ops, ext2fs_reg.fs_handle, rid, request); 1032 } 1033 1034 void ext2fs_stat(ipc_callid_t rid, ipc_call_t *request) 1035 { 1036 EXT2FS_DBG(""); 1037 libfs_stat(&ext2fs_libfs_ops, ext2fs_reg.fs_handle, rid, request); 1038 } 1039 1040 void ext2fs_sync(ipc_callid_t rid, ipc_call_t *request) 1041 { 1042 EXT2FS_DBG(""); 1043 // devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 1044 // fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 1045 1046 // TODO 1047 async_answer_0(rid, ENOTSUP); 1048 } 969 1049 970 1050 /** 971 1051 * @} 972 1052 */ 973 -
uspace/srv/fs/fat/fat.c
ra2271a3 reff10e03 56 56 }; 57 57 58 fs_reg_t fat_reg; 59 60 /** 61 * This connection fibril processes VFS requests from VFS. 62 * 63 * In order to support simultaneous VFS requests, our design is as follows. 64 * The connection fibril accepts VFS requests from VFS. If there is only one 65 * instance of the fibril, VFS will need to serialize all VFS requests it sends 66 * to FAT. To overcome this bottleneck, VFS can send FAT the IPC_M_CONNECT_ME_TO 67 * call. In that case, a new connection fibril will be created, which in turn 68 * will accept the call. Thus, a new phone will be opened for VFS. 69 * 70 * There are few issues with this arrangement. First, VFS can run out of 71 * available phones. In that case, VFS can close some other phones or use one 72 * phone for more serialized requests. Similarily, FAT can refuse to duplicate 73 * the connection. VFS should then just make use of already existing phones and 74 * route its requests through them. To avoid paying the fibril creation price 75 * upon each request, FAT might want to keep the connections open after the 76 * request has been completed. 77 */ 78 static void fat_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 79 { 80 if (iid) { 81 /* 82 * This only happens for connections opened by 83 * IPC_M_CONNECT_ME_TO calls as opposed to callback connections 84 * created by IPC_M_CONNECT_TO_ME. 85 */ 86 async_answer_0(iid, EOK); 87 } 88 89 dprintf(NAME ": connection opened\n"); 90 91 while (true) { 92 ipc_call_t call; 93 ipc_callid_t callid = async_get_call(&call); 94 95 if (!IPC_GET_IMETHOD(call)) 96 return; 97 98 switch (IPC_GET_IMETHOD(call)) { 99 case VFS_OUT_MOUNTED: 100 fat_mounted(callid, &call); 101 break; 102 case VFS_OUT_MOUNT: 103 fat_mount(callid, &call); 104 break; 105 case VFS_OUT_UNMOUNTED: 106 fat_unmounted(callid, &call); 107 break; 108 case VFS_OUT_UNMOUNT: 109 fat_unmount(callid, &call); 110 break; 111 case VFS_OUT_LOOKUP: 112 fat_lookup(callid, &call); 113 break; 114 case VFS_OUT_READ: 115 fat_read(callid, &call); 116 break; 117 case VFS_OUT_WRITE: 118 fat_write(callid, &call); 119 break; 120 case VFS_OUT_TRUNCATE: 121 fat_truncate(callid, &call); 122 break; 123 case VFS_OUT_STAT: 124 fat_stat(callid, &call); 125 break; 126 case VFS_OUT_CLOSE: 127 fat_close(callid, &call); 128 break; 129 case VFS_OUT_DESTROY: 130 fat_destroy(callid, &call); 131 break; 132 case VFS_OUT_OPEN_NODE: 133 fat_open_node(callid, &call); 134 break; 135 case VFS_OUT_SYNC: 136 fat_sync(callid, &call); 137 break; 138 default: 139 async_answer_0(callid, ENOTSUP); 140 break; 141 } 142 } 143 } 144 58 145 int main(int argc, char **argv) 59 146 { … … 71 158 } 72 159 73 rc = fs_register(vfs_sess, &fat_ vfs_info, &fat_ops, &fat_libfs_ops);160 rc = fs_register(vfs_sess, &fat_reg, &fat_vfs_info, fat_connection); 74 161 if (rc != EOK) { 75 162 fat_idx_fini(); -
uspace/srv/fs/fat/fat.h
ra2271a3 reff10e03 224 224 } fat_node_t; 225 225 226 extern vfs_out_ops_t fat_ops; 227 extern libfs_ops_t fat_libfs_ops; 226 extern fs_reg_t fat_reg; 227 228 extern void fat_mounted(ipc_callid_t, ipc_call_t *); 229 extern void fat_mount(ipc_callid_t, ipc_call_t *); 230 extern void fat_unmounted(ipc_callid_t, ipc_call_t *); 231 extern void fat_unmount(ipc_callid_t, ipc_call_t *); 232 extern void fat_lookup(ipc_callid_t, ipc_call_t *); 233 extern void fat_read(ipc_callid_t, ipc_call_t *); 234 extern void fat_write(ipc_callid_t, ipc_call_t *); 235 extern void fat_truncate(ipc_callid_t, ipc_call_t *); 236 extern void fat_stat(ipc_callid_t, ipc_call_t *); 237 extern void fat_close(ipc_callid_t, ipc_call_t *); 238 extern void fat_destroy(ipc_callid_t, ipc_call_t *); 239 extern void fat_open_node(ipc_callid_t, ipc_call_t *); 240 extern void fat_stat(ipc_callid_t, ipc_call_t *); 241 extern void fat_sync(ipc_callid_t, ipc_call_t *); 228 242 229 243 extern int fat_idx_get_new(fat_idx_t **, devmap_handle_t); -
uspace/srv/fs/fat/fat_ops.c
ra2271a3 reff10e03 85 85 static aoff64_t fat_size_get(fs_node_t *); 86 86 static unsigned fat_lnkcnt_get(fs_node_t *); 87 static char fat_plb_get_char(unsigned); 87 88 static bool fat_is_directory(fs_node_t *); 88 89 static bool fat_is_file(fs_node_t *node); … … 900 901 } 901 902 903 char fat_plb_get_char(unsigned pos) 904 { 905 return fat_reg.plb_ro[pos % PLB_SIZE]; 906 } 907 902 908 bool fat_is_directory(fs_node_t *fn) 903 909 { … … 930 936 .size_get = fat_size_get, 931 937 .lnkcnt_get = fat_lnkcnt_get, 938 .plb_get_char = fat_plb_get_char, 932 939 .is_directory = fat_is_directory, 933 940 .is_file = fat_is_file, … … 936 943 937 944 /* 938 * FAT VFS_OUToperations.945 * VFS operations. 939 946 */ 940 947 941 static int 942 fat_mounted(devmap_handle_t devmap_handle, const char *opts, fs_index_t *index, 943 aoff64_t *size, unsigned *linkcnt) 944 { 948 void fat_mounted(ipc_callid_t rid, ipc_call_t *request) 949 { 950 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 945 951 enum cache_mode cmode; 946 952 fat_bs_t *bs; 947 int rc; 948 953 954 /* Accept the mount options */ 955 char *opts; 956 int rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL); 957 958 if (rc != EOK) { 959 async_answer_0(rid, rc); 960 return; 961 } 962 949 963 /* Check for option enabling write through. */ 950 964 if (str_cmp(opts, "wtcache") == 0) … … 953 967 cmode = CACHE_MODE_WB; 954 968 969 free(opts); 970 955 971 /* initialize libblock */ 956 972 rc = block_init(EXCHANGE_SERIALIZE, devmap_handle, BS_SIZE); 957 if (rc != EOK) 958 return rc; 973 if (rc != EOK) { 974 async_answer_0(rid, rc); 975 return; 976 } 959 977 960 978 /* prepare the boot block */ … … 962 980 if (rc != EOK) { 963 981 block_fini(devmap_handle); 964 return rc; 982 async_answer_0(rid, rc); 983 return; 965 984 } 966 985 … … 970 989 if (BPS(bs) != BS_SIZE) { 971 990 block_fini(devmap_handle); 972 return ENOTSUP; 991 async_answer_0(rid, ENOTSUP); 992 return; 973 993 } 974 994 … … 977 997 if (rc != EOK) { 978 998 block_fini(devmap_handle); 979 return rc; 999 async_answer_0(rid, rc); 1000 return; 980 1001 } 981 1002 … … 985 1006 (void) block_cache_fini(devmap_handle); 986 1007 block_fini(devmap_handle); 987 return rc; 1008 async_answer_0(rid, rc); 1009 return; 988 1010 } 989 1011 … … 992 1014 (void) block_cache_fini(devmap_handle); 993 1015 block_fini(devmap_handle); 994 return rc; 1016 async_answer_0(rid, rc); 1017 return; 995 1018 } 996 1019 … … 1001 1024 block_fini(devmap_handle); 1002 1025 fat_idx_fini_by_devmap_handle(devmap_handle); 1003 return ENOMEM; 1026 async_answer_0(rid, ENOMEM); 1027 return; 1004 1028 } 1005 1029 fs_node_initialize(rfn); … … 1010 1034 block_fini(devmap_handle); 1011 1035 fat_idx_fini_by_devmap_handle(devmap_handle); 1012 return ENOMEM; 1036 async_answer_0(rid, ENOMEM); 1037 return; 1013 1038 } 1014 1039 fat_node_initialize(rootp); … … 1021 1046 block_fini(devmap_handle); 1022 1047 fat_idx_fini_by_devmap_handle(devmap_handle); 1023 return ENOMEM; 1048 async_answer_0(rid, ENOMEM); 1049 return; 1024 1050 } 1025 1051 assert(ridxp->index == 0); … … 1038 1064 fibril_mutex_unlock(&ridxp->lock); 1039 1065 1040 *index = ridxp->index; 1041 *size = rootp->size; 1042 *linkcnt = rootp->lnkcnt; 1043 1044 return EOK; 1045 } 1046 1047 static int fat_unmounted(devmap_handle_t devmap_handle) 1048 { 1066 async_answer_3(rid, EOK, ridxp->index, rootp->size, rootp->lnkcnt); 1067 } 1068 1069 void fat_mount(ipc_callid_t rid, ipc_call_t *request) 1070 { 1071 libfs_mount(&fat_libfs_ops, fat_reg.fs_handle, rid, request); 1072 } 1073 1074 void fat_unmounted(ipc_callid_t rid, ipc_call_t *request) 1075 { 1076 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 1049 1077 fs_node_t *fn; 1050 1078 fat_node_t *nodep; … … 1052 1080 1053 1081 rc = fat_root_get(&fn, devmap_handle); 1054 if (rc != EOK) 1055 return rc; 1082 if (rc != EOK) { 1083 async_answer_0(rid, rc); 1084 return; 1085 } 1056 1086 nodep = FAT_NODE(fn); 1057 1087 … … 1062 1092 if (nodep->refcnt != 2) { 1063 1093 (void) fat_node_put(fn); 1064 return EBUSY; 1094 async_answer_0(rid, EBUSY); 1095 return; 1065 1096 } 1066 1097 … … 1081 1112 block_fini(devmap_handle); 1082 1113 1083 return EOK; 1084 } 1085 1086 static int 1087 fat_read(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos, 1088 size_t *rbytes) 1089 { 1114 async_answer_0(rid, EOK); 1115 } 1116 1117 void fat_unmount(ipc_callid_t rid, ipc_call_t *request) 1118 { 1119 libfs_unmount(&fat_libfs_ops, rid, request); 1120 } 1121 1122 void fat_lookup(ipc_callid_t rid, ipc_call_t *request) 1123 { 1124 libfs_lookup(&fat_libfs_ops, fat_reg.fs_handle, rid, request); 1125 } 1126 1127 void fat_read(ipc_callid_t rid, ipc_call_t *request) 1128 { 1129 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 1130 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 1131 aoff64_t pos = 1132 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 1090 1133 fs_node_t *fn; 1091 1134 fat_node_t *nodep; … … 1096 1139 1097 1140 rc = fat_node_get(&fn, devmap_handle, index); 1098 if (rc != EOK) 1099 return rc; 1100 if (!fn) 1101 return ENOENT; 1141 if (rc != EOK) { 1142 async_answer_0(rid, rc); 1143 return; 1144 } 1145 if (!fn) { 1146 async_answer_0(rid, ENOENT); 1147 return; 1148 } 1102 1149 nodep = FAT_NODE(fn); 1103 1150 … … 1107 1154 fat_node_put(fn); 1108 1155 async_answer_0(callid, EINVAL); 1109 return EINVAL; 1156 async_answer_0(rid, EINVAL); 1157 return; 1110 1158 } 1111 1159 … … 1130 1178 fat_node_put(fn); 1131 1179 async_answer_0(callid, rc); 1132 return rc; 1180 async_answer_0(rid, rc); 1181 return; 1133 1182 } 1134 1183 (void) async_data_read_finalize(callid, … … 1137 1186 if (rc != EOK) { 1138 1187 fat_node_put(fn); 1139 return rc; 1188 async_answer_0(rid, rc); 1189 return; 1140 1190 } 1141 1191 } … … 1194 1244 rc = fat_node_put(fn); 1195 1245 async_answer_0(callid, rc != EOK ? rc : ENOENT); 1196 *rbytes = 0;1197 return rc != EOK ? rc : ENOENT;1246 async_answer_1(rid, rc != EOK ? rc : ENOENT, 0); 1247 return; 1198 1248 1199 1249 err: 1200 1250 (void) fat_node_put(fn); 1201 1251 async_answer_0(callid, rc); 1202 return rc; 1252 async_answer_0(rid, rc); 1253 return; 1203 1254 1204 1255 hit: … … 1208 1259 1209 1260 rc = fat_node_put(fn); 1210 *rbytes = bytes; 1211 return rc; 1212 } 1213 1214 static int 1215 fat_write(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos, 1216 size_t *wbytes, aoff64_t *nsize) 1217 { 1261 async_answer_1(rid, rc, (sysarg_t)bytes); 1262 } 1263 1264 void fat_write(ipc_callid_t rid, ipc_call_t *request) 1265 { 1266 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 1267 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 1268 aoff64_t pos = 1269 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 1218 1270 fs_node_t *fn; 1219 1271 fat_node_t *nodep; 1220 1272 fat_bs_t *bs; 1221 size_t bytes ;1273 size_t bytes, size; 1222 1274 block_t *b; 1223 1275 aoff64_t boundary; … … 1226 1278 1227 1279 rc = fat_node_get(&fn, devmap_handle, index); 1228 if (rc != EOK) 1229 return rc; 1230 if (!fn) 1231 return ENOENT; 1280 if (rc != EOK) { 1281 async_answer_0(rid, rc); 1282 return; 1283 } 1284 if (!fn) { 1285 async_answer_0(rid, ENOENT); 1286 return; 1287 } 1232 1288 nodep = FAT_NODE(fn); 1233 1289 … … 1237 1293 (void) fat_node_put(fn); 1238 1294 async_answer_0(callid, EINVAL); 1239 return EINVAL; 1295 async_answer_0(rid, EINVAL); 1296 return; 1240 1297 } 1241 1298 … … 1265 1322 (void) fat_node_put(fn); 1266 1323 async_answer_0(callid, rc); 1267 return rc; 1324 async_answer_0(rid, rc); 1325 return; 1268 1326 } 1269 1327 rc = fat_block_get(&b, bs, nodep, pos / BPS(bs), flags); … … 1271 1329 (void) fat_node_put(fn); 1272 1330 async_answer_0(callid, rc); 1273 return rc; 1331 async_answer_0(rid, rc); 1332 return; 1274 1333 } 1275 1334 (void) async_data_write_finalize(callid, … … 1279 1338 if (rc != EOK) { 1280 1339 (void) fat_node_put(fn); 1281 return rc; 1340 async_answer_0(rid, rc); 1341 return; 1282 1342 } 1283 1343 if (pos + bytes > nodep->size) { … … 1285 1345 nodep->dirty = true; /* need to sync node */ 1286 1346 } 1287 *wbytes = bytes; 1288 *nsize = nodep->size; 1347 size = nodep->size; 1289 1348 rc = fat_node_put(fn); 1290 return rc; 1349 async_answer_2(rid, rc, bytes, nodep->size); 1350 return; 1291 1351 } else { 1292 1352 /* … … 1304 1364 (void) fat_node_put(fn); 1305 1365 async_answer_0(callid, rc); 1306 return rc; 1366 async_answer_0(rid, rc); 1367 return; 1307 1368 } 1308 1369 /* zero fill any gaps */ … … 1312 1373 (void) fat_node_put(fn); 1313 1374 async_answer_0(callid, rc); 1314 return rc; 1375 async_answer_0(rid, rc); 1376 return; 1315 1377 } 1316 1378 rc = _fat_block_get(&b, bs, devmap_handle, lcl, NULL, … … 1320 1382 (void) fat_node_put(fn); 1321 1383 async_answer_0(callid, rc); 1322 return rc; 1384 async_answer_0(rid, rc); 1385 return; 1323 1386 } 1324 1387 (void) async_data_write_finalize(callid, … … 1329 1392 (void) fat_free_clusters(bs, devmap_handle, mcl); 1330 1393 (void) fat_node_put(fn); 1331 return rc; 1394 async_answer_0(rid, rc); 1395 return; 1332 1396 } 1333 1397 /* … … 1339 1403 (void) fat_free_clusters(bs, devmap_handle, mcl); 1340 1404 (void) fat_node_put(fn); 1341 return rc; 1342 } 1343 *nsize = nodep->size = pos + bytes; 1405 async_answer_0(rid, rc); 1406 return; 1407 } 1408 nodep->size = size = pos + bytes; 1409 nodep->dirty = true; /* need to sync node */ 1344 1410 rc = fat_node_put(fn); 1345 nodep->dirty = true; /* need to sync node */ 1346 *wbytes = bytes; 1347 return rc; 1348 } 1349 } 1350 1351 static int 1352 fat_truncate(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t size) 1353 { 1411 async_answer_2(rid, rc, bytes, size); 1412 return; 1413 } 1414 } 1415 1416 void fat_truncate(ipc_callid_t rid, ipc_call_t *request) 1417 { 1418 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 1419 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 1420 aoff64_t size = 1421 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 1354 1422 fs_node_t *fn; 1355 1423 fat_node_t *nodep; … … 1358 1426 1359 1427 rc = fat_node_get(&fn, devmap_handle, index); 1360 if (rc != EOK) 1361 return rc; 1362 if (!fn) 1363 return ENOENT; 1428 if (rc != EOK) { 1429 async_answer_0(rid, rc); 1430 return; 1431 } 1432 if (!fn) { 1433 async_answer_0(rid, ENOENT); 1434 return; 1435 } 1364 1436 nodep = FAT_NODE(fn); 1365 1437 … … 1405 1477 out: 1406 1478 fat_node_put(fn); 1407 return rc; 1408 } 1409 1410 static int fat_close(devmap_handle_t devmap_handle, fs_index_t index) 1411 { 1412 return EOK; 1413 } 1414 1415 static int fat_destroy(devmap_handle_t devmap_handle, fs_index_t index) 1416 { 1479 async_answer_0(rid, rc); 1480 return; 1481 } 1482 1483 void fat_close(ipc_callid_t rid, ipc_call_t *request) 1484 { 1485 async_answer_0(rid, EOK); 1486 } 1487 1488 void fat_destroy(ipc_callid_t rid, ipc_call_t *request) 1489 { 1490 devmap_handle_t devmap_handle = (devmap_handle_t)IPC_GET_ARG1(*request); 1491 fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request); 1417 1492 fs_node_t *fn; 1418 1493 fat_node_t *nodep; … … 1420 1495 1421 1496 rc = fat_node_get(&fn, devmap_handle, index); 1422 if (rc != EOK) 1423 return rc; 1424 if (!fn) 1425 return ENOENT; 1497 if (rc != EOK) { 1498 async_answer_0(rid, rc); 1499 return; 1500 } 1501 if (!fn) { 1502 async_answer_0(rid, ENOENT); 1503 return; 1504 } 1426 1505 1427 1506 nodep = FAT_NODE(fn); … … 1433 1512 1434 1513 rc = fat_destroy_node(fn); 1435 return rc; 1436 } 1437 1438 static int fat_sync(devmap_handle_t devmap_handle, fs_index_t index) 1439 { 1514 async_answer_0(rid, rc); 1515 } 1516 1517 void fat_open_node(ipc_callid_t rid, ipc_call_t *request) 1518 { 1519 libfs_open_node(&fat_libfs_ops, fat_reg.fs_handle, rid, request); 1520 } 1521 1522 void fat_stat(ipc_callid_t rid, ipc_call_t *request) 1523 { 1524 libfs_stat(&fat_libfs_ops, fat_reg.fs_handle, rid, request); 1525 } 1526 1527 void fat_sync(ipc_callid_t rid, ipc_call_t *request) 1528 { 1529 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 1530 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 1531 1440 1532 fs_node_t *fn; 1441 1533 int rc = fat_node_get(&fn, devmap_handle, index); 1442 if (rc != EOK) 1443 return rc; 1444 if (!fn) 1445 return ENOENT; 1534 if (rc != EOK) { 1535 async_answer_0(rid, rc); 1536 return; 1537 } 1538 if (!fn) { 1539 async_answer_0(rid, ENOENT); 1540 return; 1541 } 1446 1542 1447 1543 fat_node_t *nodep = FAT_NODE(fn); … … 1451 1547 1452 1548 fat_node_put(fn); 1453 return rc; 1454 } 1455 1456 vfs_out_ops_t fat_ops = { 1457 .mounted = fat_mounted, 1458 .unmounted = fat_unmounted, 1459 .read = fat_read, 1460 .write = fat_write, 1461 .truncate = fat_truncate, 1462 .close = fat_close, 1463 .destroy = fat_destroy, 1464 .sync = fat_sync, 1465 }; 1549 async_answer_0(rid, rc); 1550 } 1466 1551 1467 1552 /** -
uspace/srv/fs/tmpfs/tmpfs.c
ra2271a3 reff10e03 61 61 }; 62 62 63 fs_reg_t tmpfs_reg; 64 65 /** 66 * This connection fibril processes VFS requests from VFS. 67 * 68 * In order to support simultaneous VFS requests, our design is as follows. 69 * The connection fibril accepts VFS requests from VFS. If there is only one 70 * instance of the fibril, VFS will need to serialize all VFS requests it sends 71 * to FAT. To overcome this bottleneck, VFS can send TMPFS the 72 * IPC_M_CONNECT_ME_TO call. In that case, a new connection fibril will be 73 * created, which in turn will accept the call. Thus, a new phone will be 74 * opened for VFS. 75 * 76 * There are few issues with this arrangement. First, VFS can run out of 77 * available phones. In that case, VFS can close some other phones or use one 78 * phone for more serialized requests. Similarily, TMPFS can refuse to duplicate 79 * the connection. VFS should then just make use of already existing phones and 80 * route its requests through them. To avoid paying the fibril creation price 81 * upon each request, TMPFS might want to keep the connections open after the 82 * request has been completed. 83 */ 84 static void tmpfs_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg) 85 { 86 if (iid) { 87 /* 88 * This only happens for connections opened by 89 * IPC_M_CONNECT_ME_TO calls as opposed to callback connections 90 * created by IPC_M_CONNECT_TO_ME. 91 */ 92 async_answer_0(iid, EOK); 93 } 94 95 dprintf(NAME ": connection opened\n"); 96 97 while (true) { 98 ipc_call_t call; 99 ipc_callid_t callid = async_get_call(&call); 100 101 if (!IPC_GET_IMETHOD(call)) 102 return; 103 104 switch (IPC_GET_IMETHOD(call)) { 105 case VFS_OUT_MOUNTED: 106 tmpfs_mounted(callid, &call); 107 break; 108 case VFS_OUT_MOUNT: 109 tmpfs_mount(callid, &call); 110 break; 111 case VFS_OUT_UNMOUNTED: 112 tmpfs_unmounted(callid, &call); 113 break; 114 case VFS_OUT_UNMOUNT: 115 tmpfs_unmount(callid, &call); 116 break; 117 case VFS_OUT_LOOKUP: 118 tmpfs_lookup(callid, &call); 119 break; 120 case VFS_OUT_READ: 121 tmpfs_read(callid, &call); 122 break; 123 case VFS_OUT_WRITE: 124 tmpfs_write(callid, &call); 125 break; 126 case VFS_OUT_TRUNCATE: 127 tmpfs_truncate(callid, &call); 128 break; 129 case VFS_OUT_CLOSE: 130 tmpfs_close(callid, &call); 131 break; 132 case VFS_OUT_DESTROY: 133 tmpfs_destroy(callid, &call); 134 break; 135 case VFS_OUT_OPEN_NODE: 136 tmpfs_open_node(callid, &call); 137 break; 138 case VFS_OUT_STAT: 139 tmpfs_stat(callid, &call); 140 break; 141 case VFS_OUT_SYNC: 142 tmpfs_sync(callid, &call); 143 break; 144 default: 145 async_answer_0(callid, ENOTSUP); 146 break; 147 } 148 } 149 } 150 63 151 int main(int argc, char **argv) 64 152 { … … 77 165 } 78 166 79 int rc = fs_register(vfs_sess, &tmpfs_ vfs_info, &tmpfs_ops,80 &tmpfs_libfs_ops);167 int rc = fs_register(vfs_sess, &tmpfs_reg, &tmpfs_vfs_info, 168 tmpfs_connection); 81 169 if (rc != EOK) { 82 170 printf(NAME ": Failed to register file system (%d)\n", rc); -
uspace/srv/fs/tmpfs/tmpfs.h
ra2271a3 reff10e03 70 70 } tmpfs_node_t; 71 71 72 extern vfs_out_ops_t tmpfs_ops; 72 extern fs_reg_t tmpfs_reg; 73 73 74 extern libfs_ops_t tmpfs_libfs_ops; 74 75 75 76 extern bool tmpfs_init(void); 77 78 extern void tmpfs_mounted(ipc_callid_t, ipc_call_t *); 79 extern void tmpfs_mount(ipc_callid_t, ipc_call_t *); 80 extern void tmpfs_unmounted(ipc_callid_t, ipc_call_t *); 81 extern void tmpfs_unmount(ipc_callid_t, ipc_call_t *); 82 extern void tmpfs_lookup(ipc_callid_t, ipc_call_t *); 83 extern void tmpfs_read(ipc_callid_t, ipc_call_t *); 84 extern void tmpfs_write(ipc_callid_t, ipc_call_t *); 85 extern void tmpfs_truncate(ipc_callid_t, ipc_call_t *); 86 extern void tmpfs_stat(ipc_callid_t, ipc_call_t *); 87 extern void tmpfs_close(ipc_callid_t, ipc_call_t *); 88 extern void tmpfs_destroy(ipc_callid_t, ipc_call_t *); 89 extern void tmpfs_open_node(ipc_callid_t, ipc_call_t *); 90 extern void tmpfs_sync(ipc_callid_t, ipc_call_t *); 91 76 92 extern bool tmpfs_restore(devmap_handle_t); 77 93 -
uspace/srv/fs/tmpfs/tmpfs_ops.c
ra2271a3 reff10e03 104 104 } 105 105 106 static char tmpfs_plb_get_char(unsigned pos) 107 { 108 return tmpfs_reg.plb_ro[pos % PLB_SIZE]; 109 } 110 106 111 static bool tmpfs_is_directory(fs_node_t *fn) 107 112 { … … 134 139 .size_get = tmpfs_size_get, 135 140 .lnkcnt_get = tmpfs_lnkcnt_get, 141 .plb_get_char = tmpfs_plb_get_char, 136 142 .is_directory = tmpfs_is_directory, 137 143 .is_file = tmpfs_is_file, … … 427 433 } 428 434 429 /* 430 * Implementation of the VFS_OUT interface. 431 */ 432 433 static int 434 tmpfs_mounted(devmap_handle_t devmap_handle, const char *opts, 435 fs_index_t *index, aoff64_t *size, unsigned *lnkcnt) 436 { 435 void tmpfs_mounted(ipc_callid_t rid, ipc_call_t *request) 436 { 437 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 437 438 fs_node_t *rootfn; 438 439 int rc; 439 440 441 /* Accept the mount options. */ 442 char *opts; 443 rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL); 444 if (rc != EOK) { 445 async_answer_0(rid, rc); 446 return; 447 } 448 440 449 /* Check if this device is not already mounted. */ 441 450 rc = tmpfs_root_get(&rootfn, devmap_handle); 442 451 if ((rc == EOK) && (rootfn)) { 443 452 (void) tmpfs_node_put(rootfn); 444 return EEXIST; 453 free(opts); 454 async_answer_0(rid, EEXIST); 455 return; 445 456 } 446 457 447 458 /* Initialize TMPFS instance. */ 448 if (!tmpfs_instance_init(devmap_handle)) 449 return ENOMEM; 459 if (!tmpfs_instance_init(devmap_handle)) { 460 free(opts); 461 async_answer_0(rid, ENOMEM); 462 return; 463 } 450 464 451 465 rc = tmpfs_root_get(&rootfn, devmap_handle); … … 453 467 tmpfs_node_t *rootp = TMPFS_NODE(rootfn); 454 468 if (str_cmp(opts, "restore") == 0) { 455 if (!tmpfs_restore(devmap_handle)) 456 return ELIMIT; 457 } 458 459 *index = rootp->index; 460 *size = rootp->size; 461 *lnkcnt = rootp->lnkcnt; 462 463 return EOK; 464 } 465 466 static int tmpfs_unmounted(devmap_handle_t devmap_handle) 467 { 469 if (tmpfs_restore(devmap_handle)) 470 async_answer_3(rid, EOK, rootp->index, rootp->size, 471 rootp->lnkcnt); 472 else 473 async_answer_0(rid, ELIMIT); 474 } else { 475 async_answer_3(rid, EOK, rootp->index, rootp->size, 476 rootp->lnkcnt); 477 } 478 free(opts); 479 } 480 481 void tmpfs_mount(ipc_callid_t rid, ipc_call_t *request) 482 { 483 libfs_mount(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request); 484 } 485 486 void tmpfs_unmounted(ipc_callid_t rid, ipc_call_t *request) 487 { 488 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 489 468 490 tmpfs_instance_done(devmap_handle); 469 return EOK; 470 } 471 472 static int tmpfs_read(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos, 473 size_t *rbytes) 474 { 491 async_answer_0(rid, EOK); 492 } 493 494 void tmpfs_unmount(ipc_callid_t rid, ipc_call_t *request) 495 { 496 libfs_unmount(&tmpfs_libfs_ops, rid, request); 497 } 498 499 void tmpfs_lookup(ipc_callid_t rid, ipc_call_t *request) 500 { 501 libfs_lookup(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request); 502 } 503 504 void tmpfs_read(ipc_callid_t rid, ipc_call_t *request) 505 { 506 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 507 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 508 aoff64_t pos = 509 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 510 475 511 /* 476 512 * Lookup the respective TMPFS node. … … 482 518 }; 483 519 hlp = hash_table_find(&nodes, key); 484 if (!hlp) 485 return ENOENT; 520 if (!hlp) { 521 async_answer_0(rid, ENOENT); 522 return; 523 } 486 524 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, 487 525 nh_link); … … 494 532 if (!async_data_read_receive(&callid, &size)) { 495 533 async_answer_0(callid, EINVAL); 496 return EINVAL; 534 async_answer_0(rid, EINVAL); 535 return; 497 536 } 498 537 … … 517 556 if (lnk == NULL) { 518 557 async_answer_0(callid, ENOENT); 519 return ENOENT; 558 async_answer_1(rid, ENOENT, 0); 559 return; 520 560 } 521 561 … … 527 567 } 528 568 529 *rbytes = bytes; 530 return EOK; 531 } 532 533 static int 534 tmpfs_write(devmap_handle_t devmap_handle, fs_index_t index, aoff64_t pos, 535 size_t *wbytes, aoff64_t *nsize) 536 { 569 /* 570 * Answer the VFS_READ call. 571 */ 572 async_answer_1(rid, EOK, bytes); 573 } 574 575 void tmpfs_write(ipc_callid_t rid, ipc_call_t *request) 576 { 577 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 578 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 579 aoff64_t pos = 580 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 581 537 582 /* 538 583 * Lookup the respective TMPFS node. … … 544 589 }; 545 590 hlp = hash_table_find(&nodes, key); 546 if (!hlp) 547 return ENOENT; 591 if (!hlp) { 592 async_answer_0(rid, ENOENT); 593 return; 594 } 548 595 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, 549 596 nh_link); … … 556 603 if (!async_data_write_receive(&callid, &size)) { 557 604 async_answer_0(callid, EINVAL); 558 return EINVAL; 605 async_answer_0(rid, EINVAL); 606 return; 559 607 } 560 608 … … 564 612 if (pos + size <= nodep->size) { 565 613 /* The file size is not changing. */ 566 (void) async_data_write_finalize(callid, nodep->data + pos, 567 568 goto out;614 (void) async_data_write_finalize(callid, nodep->data + pos, size); 615 async_answer_2(rid, EOK, size, nodep->size); 616 return; 569 617 } 570 618 size_t delta = (pos + size) - nodep->size; … … 579 627 if (!newdata) { 580 628 async_answer_0(callid, ENOMEM); 581 size = 0;582 goto out;629 async_answer_2(rid, EOK, 0, nodep->size); 630 return; 583 631 } 584 632 /* Clear any newly allocated memory in order to emulate gaps. */ … … 587 635 nodep->data = newdata; 588 636 (void) async_data_write_finalize(callid, nodep->data + pos, size); 589 590 out: 591 *wbytes = size; 592 *nsize = nodep->size; 593 return EOK; 594 } 595 596 static int tmpfs_truncate(devmap_handle_t devmap_handle, fs_index_t index, 597 aoff64_t size) 598 { 637 async_answer_2(rid, EOK, size, nodep->size); 638 } 639 640 void tmpfs_truncate(ipc_callid_t rid, ipc_call_t *request) 641 { 642 devmap_handle_t devmap_handle = (devmap_handle_t) IPC_GET_ARG1(*request); 643 fs_index_t index = (fs_index_t) IPC_GET_ARG2(*request); 644 aoff64_t size = 645 (aoff64_t) MERGE_LOUP32(IPC_GET_ARG3(*request), IPC_GET_ARG4(*request)); 646 599 647 /* 600 648 * Lookup the respective TMPFS node. … … 605 653 }; 606 654 link_t *hlp = hash_table_find(&nodes, key); 607 if (!hlp) 608 return ENOENT; 609 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, nh_link); 610 611 if (size == nodep->size) 612 return EOK; 613 614 if (size > SIZE_MAX) 615 return ENOMEM; 655 if (!hlp) { 656 async_answer_0(rid, ENOENT); 657 return; 658 } 659 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, 660 nh_link); 661 662 if (size == nodep->size) { 663 async_answer_0(rid, EOK); 664 return; 665 } 666 667 if (size > SIZE_MAX) { 668 async_answer_0(rid, ENOMEM); 669 return; 670 } 616 671 617 672 void *newdata = realloc(nodep->data, size); 618 if (!newdata) 619 return ENOMEM; 673 if (!newdata) { 674 async_answer_0(rid, ENOMEM); 675 return; 676 } 620 677 621 678 if (size > nodep->size) { … … 626 683 nodep->size = size; 627 684 nodep->data = newdata; 628 return EOK; 629 } 630 631 static int tmpfs_close(devmap_handle_t devmap_handle, fs_index_t index) 632 { 633 return EOK; 634 } 635 636 static int tmpfs_destroy(devmap_handle_t devmap_handle, fs_index_t index) 637 { 685 async_answer_0(rid, EOK); 686 } 687 688 void tmpfs_close(ipc_callid_t rid, ipc_call_t *request) 689 { 690 async_answer_0(rid, EOK); 691 } 692 693 void tmpfs_destroy(ipc_callid_t rid, ipc_call_t *request) 694 { 695 devmap_handle_t devmap_handle = (devmap_handle_t)IPC_GET_ARG1(*request); 696 fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request); 697 int rc; 698 638 699 link_t *hlp; 639 700 unsigned long key[] = { … … 642 703 }; 643 704 hlp = hash_table_find(&nodes, key); 644 if (!hlp) 645 return ENOENT; 705 if (!hlp) { 706 async_answer_0(rid, ENOENT); 707 return; 708 } 646 709 tmpfs_node_t *nodep = hash_table_get_instance(hlp, tmpfs_node_t, 647 710 nh_link); 648 return tmpfs_destroy_node(FS_NODE(nodep)); 649 } 650 651 static int tmpfs_sync(devmap_handle_t devmap_handle, fs_index_t index) 711 rc = tmpfs_destroy_node(FS_NODE(nodep)); 712 async_answer_0(rid, rc); 713 } 714 715 void tmpfs_open_node(ipc_callid_t rid, ipc_call_t *request) 716 { 717 libfs_open_node(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request); 718 } 719 720 void tmpfs_stat(ipc_callid_t rid, ipc_call_t *request) 721 { 722 libfs_stat(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request); 723 } 724 725 void tmpfs_sync(ipc_callid_t rid, ipc_call_t *request) 652 726 { 653 727 /* … … 655 729 * thus the sync operation is a no-op. 656 730 */ 657 return EOK; 658 } 659 660 vfs_out_ops_t tmpfs_ops = { 661 .mounted = tmpfs_mounted, 662 .unmounted = tmpfs_unmounted, 663 .read = tmpfs_read, 664 .write = tmpfs_write, 665 .truncate = tmpfs_truncate, 666 .close = tmpfs_close, 667 .destroy = tmpfs_destroy, 668 .sync = tmpfs_sync, 669 }; 731 async_answer_0(rid, EOK); 732 } 670 733 671 734 /** 672 735 * @} 673 736 */ 674
Note:
See TracChangeset
for help on using the changeset viewer.