Changeset e27cf669 in mainline for uspace/srv
- Timestamp:
- 2010-02-09T20:19:23Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- fb150d78
- Parents:
- 975e7e9 (diff), eb73a50 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- uspace/srv
- Files:
-
- 12 added
- 34 edited
- 7 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/bd/ata_bd/ata_bd.c
r975e7e9 re27cf669 59 59 #include <devmap.h> 60 60 #include <sys/types.h> 61 #include <inttypes.h> 61 62 #include <errno.h> 62 63 #include <bool.h> … … 112 113 printf(NAME ": ATA disk driver\n"); 113 114 114 printf("I/O address 0x%p/0x%p\n", ctl_physical, cmd_physical);115 printf("I/O address %p/%p\n", ctl_physical, cmd_physical); 115 116 116 117 if (ata_bd_init() != EOK) … … 180 181 } 181 182 182 printf(" % llublocks", d->blocks, d->blocks / (2 * 1024));183 printf(" %" PRIu64 " blocks", d->blocks, d->blocks / (2 * 1024)); 183 184 184 185 mbytes = d->blocks / (2 * 1024); 185 186 if (mbytes > 0) 186 printf(" % lluMB.", mbytes);187 printf(" %" PRIu64 " MB.", mbytes); 187 188 188 189 printf("\n"); -
uspace/srv/bd/part/guid_part/guid_part.c
r975e7e9 re27cf669 54 54 #include <devmap.h> 55 55 #include <sys/types.h> 56 #include <sys/typefmt.h> 57 #include <inttypes.h> 56 58 #include <libblock.h> 57 59 #include <devmap.h> … … 196 198 size_mb = (part->length * block_size + 1024 * 1024 - 1) 197 199 / (1024 * 1024); 198 printf(NAME ": Registered device %s: % llu blocks %llu MB.\n",199 name, part->length, size_mb);200 printf(NAME ": Registered device %s: %" PRIu64 " blocks " 201 "%" PRIuBN " MB.\n", name, part->length, size_mb); 200 202 201 203 part->dev = dev; -
uspace/srv/bd/part/mbr_part/mbr_part.c
r975e7e9 re27cf669 64 64 #include <devmap.h> 65 65 #include <sys/types.h> 66 #include <sys/typefmt.h> 67 #include <inttypes.h> 66 68 #include <libblock.h> 67 69 #include <devmap.h> … … 247 249 size_mb = (part->length * block_size + 1024 * 1024 - 1) 248 250 / (1024 * 1024); 249 printf(NAME ": Registered device %s: % llu blocks %llu MB.\n",250 name, part->length, size_mb);251 printf(NAME ": Registered device %s: %" PRIuBN " blocks " 252 "%" PRIu64 " MB.\n", name, part->length, size_mb); 251 253 252 254 part->dev = dev; … … 274 276 if (brb == NULL) { 275 277 printf(NAME ": Failed allocating memory.\n"); 276 return ENOMEM; 278 return ENOMEM; 277 279 } 278 280 … … 289 291 sgn = uint16_t_le2host(brb->signature); 290 292 if (sgn != BR_SIGNATURE) { 291 printf(NAME ": Invalid boot record signature 0x%04X.\n", sgn); 293 printf(NAME ": Invalid boot record signature 0x%04" PRIX16 294 ".\n", sgn); 292 295 return EINVAL; 293 296 } … … 333 336 rc = block_read_direct(indev_handle, ba, 1, brb); 334 337 if (rc != EOK) { 335 printf(NAME ": Failed reading EBR block at %u.\n", ba); 338 printf(NAME ": Failed reading EBR block at %" 339 PRIu32 ".\n", ba); 336 340 return rc; 337 341 } … … 339 343 sgn = uint16_t_le2host(brb->signature); 340 344 if (sgn != BR_SIGNATURE) { 341 printf(NAME ": Invalid boot record signature 0x%04 X"342 " in EBR at %u.\n", sgn, ba);345 printf(NAME ": Invalid boot record signature 0x%04" 346 PRIX16 " in EBR at %" PRIu32 ".\n", sgn, ba); 343 347 return EINVAL; 344 348 } -
uspace/srv/clip/clip.c
r975e7e9 re27cf669 64 64 ipc_answer_0(rid, EOK); 65 65 break; 66 case CLIPBOARD_TAG_ BLOB:67 rc = async_data_ blob_receive(&data, 0, &size);66 case CLIPBOARD_TAG_DATA: 67 rc = async_data_write_accept((void **) &data, false, 0, 0, 0, &size); 68 68 if (rc != EOK) { 69 69 ipc_answer_0(rid, rc); … … 78 78 clip_data = data; 79 79 clip_size = size; 80 clip_tag = CLIPBOARD_TAG_ BLOB;80 clip_tag = CLIPBOARD_TAG_DATA; 81 81 82 82 fibril_mutex_unlock(&clip_mtx); … … 97 97 /* Check for clipboard data tag compatibility */ 98 98 switch (IPC_GET_ARG1(*request)) { 99 case CLIPBOARD_TAG_ BLOB:99 case CLIPBOARD_TAG_DATA: 100 100 if (!async_data_read_receive(&callid, &size)) { 101 101 ipc_answer_0(callid, EINVAL); … … 104 104 } 105 105 106 if (clip_tag != CLIPBOARD_TAG_ BLOB) {107 /* So far we only understand BLOB*/106 if (clip_tag != CLIPBOARD_TAG_DATA) { 107 /* So far we only understand binary data */ 108 108 ipc_answer_0(callid, EOVERFLOW); 109 109 ipc_answer_0(rid, EOVERFLOW); -
uspace/srv/devmap/devmap.c
r975e7e9 re27cf669 396 396 * Get driver name 397 397 */ 398 int rc = async_data_string_receive(&driver->name, DEVMAP_NAME_MAXLEN); 398 int rc = async_data_write_accept((void **) &driver->name, true, 0, 399 DEVMAP_NAME_MAXLEN, 0, NULL); 399 400 if (rc != EOK) { 400 401 free(driver); … … 510 511 /* Get fqdn */ 511 512 char *fqdn; 512 int rc = async_data_string_receive(&fqdn, DEVMAP_NAME_MAXLEN); 513 int rc = async_data_write_accept((void **) &fqdn, true, 0, 514 DEVMAP_NAME_MAXLEN, 0, NULL); 513 515 if (rc != EOK) { 514 516 free(device); … … 622 624 623 625 /* Get fqdn */ 624 int rc = async_data_string_receive(&fqdn, DEVMAP_NAME_MAXLEN); 626 int rc = async_data_write_accept((void **) &fqdn, true, 0, 627 DEVMAP_NAME_MAXLEN, 0, NULL); 625 628 if (rc != EOK) { 626 629 ipc_answer_0(iid, rc); … … 683 686 684 687 /* Get device name */ 685 int rc = async_data_string_receive(&name, DEVMAP_NAME_MAXLEN); 688 int rc = async_data_write_accept((void **) &name, true, 0, 689 DEVMAP_NAME_MAXLEN, 0, NULL); 686 690 if (rc != EOK) { 687 691 ipc_answer_0(iid, rc); -
uspace/srv/fs/devfs/devfs.c
r975e7e9 re27cf669 75 75 devfs_mount(callid, &call); 76 76 break; 77 case VFS_OUT_UNMOUNTED: 78 devfs_unmounted(callid, &call); 79 break; 80 case VFS_OUT_UNMOUNT: 81 devfs_unmount(callid, &call); 82 break; 77 83 case VFS_OUT_LOOKUP: 78 84 devfs_lookup(callid, &call); -
uspace/srv/fs/devfs/devfs_ops.c
r975e7e9 re27cf669 419 419 420 420 /* Accept the mount options */ 421 ipcarg_t retval = async_data_string_receive(&opts, 0); 421 ipcarg_t retval = async_data_write_accept((void **) &opts, true, 0, 0, 422 0, NULL); 422 423 if (retval != EOK) { 423 424 ipc_answer_0(rid, retval); … … 432 433 { 433 434 libfs_mount(&devfs_libfs_ops, devfs_reg.fs_handle, rid, request); 435 } 436 437 void devfs_unmounted(ipc_callid_t rid, ipc_call_t *request) 438 { 439 ipc_answer_0(rid, ENOTSUP); 440 } 441 442 void devfs_unmount(ipc_callid_t rid, ipc_call_t *request) 443 { 444 libfs_unmount(&devfs_libfs_ops, rid, request); 434 445 } 435 446 -
uspace/srv/fs/devfs/devfs_ops.h
r975e7e9 re27cf669 41 41 extern void devfs_mounted(ipc_callid_t, ipc_call_t *); 42 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 *); 43 45 extern void devfs_lookup(ipc_callid_t, ipc_call_t *); 44 46 extern void devfs_open_node(ipc_callid_t, ipc_call_t *); -
uspace/srv/fs/fat/fat.c
r975e7e9 re27cf669 100 100 fat_mount(callid, &call); 101 101 break; 102 case VFS_OUT_UNMOUNTED: 103 fat_unmounted(callid, &call); 104 break; 105 case VFS_OUT_UNMOUNT: 106 fat_unmount(callid, &call); 107 break; 102 108 case VFS_OUT_LOOKUP: 103 109 fat_lookup(callid, &call); -
uspace/srv/fs/fat/fat.h
r975e7e9 re27cf669 204 204 extern void fat_mounted(ipc_callid_t, ipc_call_t *); 205 205 extern void fat_mount(ipc_callid_t, ipc_call_t *); 206 extern void fat_unmounted(ipc_callid_t, ipc_call_t *); 207 extern void fat_unmount(ipc_callid_t, ipc_call_t *); 206 208 extern void fat_lookup(ipc_callid_t, ipc_call_t *); 207 209 extern void fat_read(ipc_callid_t, ipc_call_t *); -
uspace/srv/fs/fat/fat_fat.c
r975e7e9 re27cf669 361 361 uint16_t rscnt; 362 362 uint16_t sf; 363 uint 16_t ts;363 uint32_t ts; 364 364 unsigned rde; 365 365 unsigned rds; … … 379 379 sf = uint16_t_le2host(bs->sec_per_fat); 380 380 rde = uint16_t_le2host(bs->root_ent_max); 381 ts = uint16_t_le2host(bs->totsec16); 381 ts = (uint32_t) uint16_t_le2host(bs->totsec16); 382 if (ts == 0) 383 ts = uint32_t_le2host(bs->totsec32); 382 384 383 385 rds = (sizeof(fat_dentry_t) * rde) / bps; … … 608 610 } 609 611 612 /** Perform basic sanity checks on the file system. 613 * 614 * Verify if values of boot sector fields are sane. Also verify media 615 * descriptor. This is used to rule out cases when a device obviously 616 * does not contain a fat file system. 617 */ 618 int fat_sanity_check(fat_bs_t *bs, dev_handle_t dev_handle) 619 { 620 fat_cluster_t e0, e1; 621 unsigned fat_no; 622 int rc; 623 624 /* Check number of FATs. */ 625 if (bs->fatcnt == 0) 626 return ENOTSUP; 627 628 /* Check total number of sectors. */ 629 630 if (bs->totsec16 == 0 && bs->totsec32 == 0) 631 return ENOTSUP; 632 633 if (bs->totsec16 != 0 && bs->totsec32 != 0 && 634 bs->totsec16 != bs->totsec32) 635 return ENOTSUP; 636 637 /* Check media descriptor. Must be between 0xf0 and 0xff. */ 638 if ((bs->mdesc & 0xf0) != 0xf0) 639 return ENOTSUP; 640 641 /* Check number of sectors per FAT. */ 642 if (bs->sec_per_fat == 0) 643 return ENOTSUP; 644 645 /* 646 * Check that the root directory entries take up whole blocks. 647 * This check is rather strict, but it allows us to treat the root 648 * directory and non-root directories uniformly in some places. 649 * It can be removed provided that functions such as fat_read() are 650 * sanitized to support file systems with this property. 651 */ 652 if ((uint16_t_le2host(bs->root_ent_max) * sizeof(fat_dentry_t)) % 653 uint16_t_le2host(bs->bps) != 0) 654 return ENOTSUP; 655 656 /* Check signature of each FAT. */ 657 658 for (fat_no = 0; fat_no < bs->fatcnt; fat_no++) { 659 rc = fat_get_cluster(bs, dev_handle, fat_no, 0, &e0); 660 if (rc != EOK) 661 return EIO; 662 663 rc = fat_get_cluster(bs, dev_handle, fat_no, 1, &e1); 664 if (rc != EOK) 665 return EIO; 666 667 /* Check that first byte of FAT contains the media descriptor. */ 668 if ((e0 & 0xff) != bs->mdesc) 669 return ENOTSUP; 670 671 /* 672 * Check that remaining bits of the first two entries are 673 * set to one. 674 */ 675 if ((e0 >> 8) != 0xff || e1 != 0xffff) 676 return ENOTSUP; 677 } 678 679 return EOK; 680 } 681 610 682 /** 611 683 * @} -
uspace/srv/fs/fat/fat_fat.h
r975e7e9 re27cf669 87 87 off_t); 88 88 extern int fat_zero_cluster(struct fat_bs *, dev_handle_t, fat_cluster_t); 89 extern int fat_sanity_check(struct fat_bs *, dev_handle_t); 89 90 90 91 #endif -
uspace/srv/fs/fat/fat_idx.c
r975e7e9 re27cf669 149 149 { 150 150 dev_handle_t dev_handle = (dev_handle_t)key[UPH_DH_KEY]; 151 fat_cluster_t pfc = (fat_cluster_t)key[UPH_PFC_KEY];152 unsigned pdi = (unsigned)key[UPH_PDI_KEY];151 fat_cluster_t pfc; 152 unsigned pdi; 153 153 fat_idx_t *fidx = list_get_instance(item, fat_idx_t, uph_link); 154 154 155 return (dev_handle == fidx->dev_handle) && (pfc == fidx->pfc) && 156 (pdi == fidx->pdi); 155 switch (keys) { 156 case 1: 157 return (dev_handle == fidx->dev_handle); 158 case 3: 159 pfc = (fat_cluster_t) key[UPH_PFC_KEY]; 160 pdi = (unsigned) key[UPH_PDI_KEY]; 161 return (dev_handle == fidx->dev_handle) && (pfc == fidx->pfc) && 162 (pdi == fidx->pdi); 163 default: 164 assert((keys == 1) || (keys == 3)); 165 } 166 167 return 0; 157 168 } 158 169 … … 197 208 { 198 209 dev_handle_t dev_handle = (dev_handle_t)key[UIH_DH_KEY]; 199 fs_index_t index = (fs_index_t)key[UIH_INDEX_KEY];210 fs_index_t index; 200 211 fat_idx_t *fidx = list_get_instance(item, fat_idx_t, uih_link); 201 212 202 return (dev_handle == fidx->dev_handle) && (index == fidx->index); 213 switch (keys) { 214 case 1: 215 return (dev_handle == fidx->dev_handle); 216 case 2: 217 index = (fs_index_t) key[UIH_INDEX_KEY]; 218 return (dev_handle == fidx->dev_handle) && 219 (index == fidx->index); 220 default: 221 assert((keys == 1) || (keys == 2)); 222 } 223 224 return 0; 203 225 } 204 226 205 227 static void idx_remove_callback(link_t *item) 206 228 { 207 /* nothing to do */ 229 fat_idx_t *fidx = list_get_instance(item, fat_idx_t, uih_link); 230 231 free(fidx); 208 232 } 209 233 … … 486 510 [UIH_INDEX_KEY] = idx->index, 487 511 }; 512 dev_handle_t dev_handle = idx->dev_handle; 513 fs_index_t index = idx->index; 488 514 489 515 assert(idx->pfc == FAT_CLST_RES0); … … 498 524 fibril_mutex_unlock(&used_lock); 499 525 /* Release the VFS index. */ 500 fat_index_free(idx->dev_handle, idx->index); 501 /* Deallocate the structure. */ 502 free(idx); 526 fat_index_free(dev_handle, index); 527 /* The index structure itself is freed in idx_remove_callback(). */ 503 528 } 504 529 … … 531 556 unused_initialize(u, dev_handle); 532 557 fibril_mutex_lock(&unused_lock); 533 if (!unused_find(dev_handle, false)) 558 if (!unused_find(dev_handle, false)) { 534 559 list_append(&u->link, &unused_head); 535 else 560 } else { 561 free(u); 536 562 rc = EEXIST; 563 } 537 564 fibril_mutex_unlock(&unused_lock); 538 565 return rc; … … 541 568 void fat_idx_fini_by_dev_handle(dev_handle_t dev_handle) 542 569 { 543 unused_t *u; 544 545 u = unused_find(dev_handle, true); 570 unsigned long ikey[] = { 571 [UIH_DH_KEY] = dev_handle 572 }; 573 unsigned long pkey[] = { 574 [UPH_DH_KEY] = dev_handle 575 }; 576 577 /* 578 * Remove this instance's index structure from up_hash and ui_hash. 579 * Process up_hash first and ui_hash second because the index structure 580 * is actually removed in idx_remove_callback(). 581 */ 582 fibril_mutex_lock(&used_lock); 583 hash_table_remove(&up_hash, pkey, 1); 584 hash_table_remove(&ui_hash, ikey, 1); 585 fibril_mutex_unlock(&used_lock); 586 587 /* 588 * Free the unused and freed structures for this instance. 589 */ 590 unused_t *u = unused_find(dev_handle, true); 546 591 assert(u); 547 592 list_remove(&u->link); -
uspace/srv/fs/fat/fat_ops.c
r975e7e9 re27cf669 139 139 } 140 140 141 static int fat_node_fini_by_dev_handle(dev_handle_t dev_handle) 142 { 143 link_t *lnk; 144 fat_node_t *nodep; 145 int rc; 146 147 /* 148 * We are called from fat_unmounted() and assume that there are already 149 * no nodes belonging to this instance with non-zero refcount. Therefore 150 * it is sufficient to clean up only the FAT free node list. 151 */ 152 153 restart: 154 fibril_mutex_lock(&ffn_mutex); 155 for (lnk = ffn_head.next; lnk != &ffn_head; lnk = lnk->next) { 156 nodep = list_get_instance(lnk, fat_node_t, ffn_link); 157 if (!fibril_mutex_trylock(&nodep->lock)) { 158 fibril_mutex_unlock(&ffn_mutex); 159 goto restart; 160 } 161 if (!fibril_mutex_trylock(&nodep->idx->lock)) { 162 fibril_mutex_unlock(&nodep->lock); 163 fibril_mutex_unlock(&ffn_mutex); 164 goto restart; 165 } 166 if (nodep->idx->dev_handle != dev_handle) { 167 fibril_mutex_unlock(&nodep->idx->lock); 168 fibril_mutex_unlock(&nodep->lock); 169 continue; 170 } 171 172 list_remove(&nodep->ffn_link); 173 fibril_mutex_unlock(&ffn_mutex); 174 175 /* 176 * We can unlock the node and its index structure because we are 177 * the last player on this playground and VFS is preventing new 178 * players from entering. 179 */ 180 fibril_mutex_unlock(&nodep->idx->lock); 181 fibril_mutex_unlock(&nodep->lock); 182 183 if (nodep->dirty) { 184 rc = fat_node_sync(nodep); 185 if (rc != EOK) 186 return rc; 187 } 188 nodep->idx->nodep = NULL; 189 free(nodep->bp); 190 free(nodep); 191 192 /* Need to restart because we changed the ffn_head list. */ 193 goto restart; 194 } 195 fibril_mutex_unlock(&ffn_mutex); 196 197 return EOK; 198 } 199 141 200 static int fat_node_get_new(fat_node_t **nodepp) 142 201 { … … 290 349 291 350 *nodepp = nodep; 292 return EOK;293 }294 295 /** Perform basic sanity checks on the file system.296 *297 * Verify if values of boot sector fields are sane. Also verify media298 * descriptor. This is used to rule out cases when a device obviously299 * does not contain a fat file system.300 */301 static int fat_sanity_check(fat_bs_t *bs, dev_handle_t dev_handle)302 {303 fat_cluster_t e0, e1;304 unsigned fat_no;305 int rc;306 307 /* Check number of FATs. */308 if (bs->fatcnt == 0)309 return ENOTSUP;310 311 /* Check total number of sectors. */312 313 if (bs->totsec16 == 0 && bs->totsec32 == 0)314 return ENOTSUP;315 316 if (bs->totsec16 != 0 && bs->totsec32 != 0 &&317 bs->totsec16 != bs->totsec32)318 return ENOTSUP;319 320 /* Check media descriptor. Must be between 0xf0 and 0xff. */321 if ((bs->mdesc & 0xf0) != 0xf0)322 return ENOTSUP;323 324 /* Check number of sectors per FAT. */325 if (bs->sec_per_fat == 0)326 return ENOTSUP;327 328 /*329 * Check that the root directory entries take up whole blocks.330 * This check is rather strict, but it allows us to treat the root331 * directory and non-root directories uniformly in some places.332 * It can be removed provided that functions such as fat_read() are333 * sanitized to support file systems with this property.334 */335 if ((uint16_t_le2host(bs->root_ent_max) * sizeof(fat_dentry_t)) %336 uint16_t_le2host(bs->bps) != 0)337 return ENOTSUP;338 339 /* Check signature of each FAT. */340 341 for (fat_no = 0; fat_no < bs->fatcnt; fat_no++) {342 rc = fat_get_cluster(bs, dev_handle, fat_no, 0, &e0);343 if (rc != EOK)344 return EIO;345 346 rc = fat_get_cluster(bs, dev_handle, fat_no, 1, &e1);347 if (rc != EOK)348 return EIO;349 350 /* Check that first byte of FAT contains the media descriptor. */351 if ((e0 & 0xff) != bs->mdesc)352 return ENOTSUP;353 354 /*355 * Check that remaining bits of the first two entries are356 * set to one.357 */358 if ((e0 >> 8) != 0xff || e1 != 0xffff)359 return ENOTSUP;360 }361 362 351 return EOK; 363 352 } … … 985 974 uint16_t bps; 986 975 uint16_t rde; 987 int rc; 988 989 /* accept the mount options */ 990 ipc_callid_t callid; 991 size_t size; 992 if (!async_data_write_receive(&callid, &size)) { 993 ipc_answer_0(callid, EINVAL); 994 ipc_answer_0(rid, EINVAL); 995 return; 996 } 997 char *opts = malloc(size + 1); 998 if (!opts) { 999 ipc_answer_0(callid, ENOMEM); 1000 ipc_answer_0(rid, ENOMEM); 1001 return; 1002 } 1003 ipcarg_t retval = async_data_write_finalize(callid, opts, size); 1004 if (retval != EOK) { 1005 ipc_answer_0(rid, retval); 1006 free(opts); 1007 return; 1008 } 1009 opts[size] = '\0'; 976 977 /* Accept the mount options */ 978 char *opts; 979 int rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL); 980 981 if (rc != EOK) { 982 ipc_answer_0(rid, rc); 983 return; 984 } 1010 985 1011 986 /* Check for option enabling write through. */ … … 1015 990 cmode = CACHE_MODE_WB; 1016 991 992 free(opts); 993 1017 994 /* initialize libblock */ 1018 995 rc = block_init(dev_handle, BS_SIZE); … … 1054 1031 rc = fat_sanity_check(bs, dev_handle); 1055 1032 if (rc != EOK) { 1033 (void) block_cache_fini(dev_handle); 1056 1034 block_fini(dev_handle); 1057 1035 ipc_answer_0(rid, rc); … … 1061 1039 rc = fat_idx_init_by_dev_handle(dev_handle); 1062 1040 if (rc != EOK) { 1041 (void) block_cache_fini(dev_handle); 1063 1042 block_fini(dev_handle); 1064 1043 ipc_answer_0(rid, rc); … … 1069 1048 fs_node_t *rfn = (fs_node_t *)malloc(sizeof(fs_node_t)); 1070 1049 if (!rfn) { 1050 (void) block_cache_fini(dev_handle); 1071 1051 block_fini(dev_handle); 1072 1052 fat_idx_fini_by_dev_handle(dev_handle); … … 1078 1058 if (!rootp) { 1079 1059 free(rfn); 1060 (void) block_cache_fini(dev_handle); 1080 1061 block_fini(dev_handle); 1081 1062 fat_idx_fini_by_dev_handle(dev_handle); … … 1089 1070 free(rfn); 1090 1071 free(rootp); 1072 (void) block_cache_fini(dev_handle); 1091 1073 block_fini(dev_handle); 1092 1074 fat_idx_fini_by_dev_handle(dev_handle); … … 1115 1097 { 1116 1098 libfs_mount(&fat_libfs_ops, fat_reg.fs_handle, rid, request); 1099 } 1100 1101 void fat_unmounted(ipc_callid_t rid, ipc_call_t *request) 1102 { 1103 dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request); 1104 fs_node_t *fn; 1105 fat_node_t *nodep; 1106 int rc; 1107 1108 rc = fat_root_get(&fn, dev_handle); 1109 if (rc != EOK) { 1110 ipc_answer_0(rid, rc); 1111 return; 1112 } 1113 nodep = FAT_NODE(fn); 1114 1115 /* 1116 * We expect exactly two references on the root node. One for the 1117 * fat_root_get() above and one created in fat_mounted(). 1118 */ 1119 if (nodep->refcnt != 2) { 1120 (void) fat_node_put(fn); 1121 ipc_answer_0(rid, EBUSY); 1122 return; 1123 } 1124 1125 /* 1126 * Put the root node and force it to the FAT free node list. 1127 */ 1128 (void) fat_node_put(fn); 1129 (void) fat_node_put(fn); 1130 1131 /* 1132 * Perform cleanup of the node structures, index structures and 1133 * associated data. Write back this file system's dirty blocks and 1134 * stop using libblock for this instance. 1135 */ 1136 (void) fat_node_fini_by_dev_handle(dev_handle); 1137 fat_idx_fini_by_dev_handle(dev_handle); 1138 (void) block_cache_fini(dev_handle); 1139 block_fini(dev_handle); 1140 1141 ipc_answer_0(rid, EOK); 1142 } 1143 1144 void fat_unmount(ipc_callid_t rid, ipc_call_t *request) 1145 { 1146 libfs_unmount(&fat_libfs_ops, rid, request); 1117 1147 } 1118 1148 -
uspace/srv/fs/tmpfs/tmpfs.c
r975e7e9 re27cf669 106 106 tmpfs_mount(callid, &call); 107 107 break; 108 case VFS_OUT_UNMOUNTED: 109 tmpfs_unmounted(callid, &call); 110 break; 111 case VFS_OUT_UNMOUNT: 112 tmpfs_unmount(callid, &call); 113 break; 108 114 case VFS_OUT_LOOKUP: 109 115 tmpfs_lookup(callid, &call); -
uspace/srv/fs/tmpfs/tmpfs.h
r975e7e9 re27cf669 83 83 extern void tmpfs_mounted(ipc_callid_t, ipc_call_t *); 84 84 extern void tmpfs_mount(ipc_callid_t, ipc_call_t *); 85 extern void tmpfs_unmounted(ipc_callid_t, ipc_call_t *); 86 extern void tmpfs_unmount(ipc_callid_t, ipc_call_t *); 85 87 extern void tmpfs_lookup(ipc_callid_t, ipc_call_t *); 86 88 extern void tmpfs_read(ipc_callid_t, ipc_call_t *); -
uspace/srv/fs/tmpfs/tmpfs_ops.c
r975e7e9 re27cf669 147 147 hash_table_t nodes; 148 148 149 #define NODES_KEY_ INDEX 0150 #define NODES_KEY_ DEV1149 #define NODES_KEY_DEV 0 150 #define NODES_KEY_INDEX 1 151 151 152 152 /* Implementation of hash table interface for the nodes hash table. */ … … 160 160 tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t, 161 161 nh_link); 162 return (nodep->index == key[NODES_KEY_INDEX] && 163 nodep->dev_handle == key[NODES_KEY_DEV]); 162 163 switch (keys) { 164 case 1: 165 return (nodep->dev_handle == key[NODES_KEY_DEV]); 166 case 2: 167 return ((nodep->dev_handle == key[NODES_KEY_DEV]) && 168 (nodep->index == key[NODES_KEY_INDEX])); 169 default: 170 assert((keys == 1) || (keys == 2)); 171 } 172 173 return 0; 164 174 } 165 175 166 176 static void nodes_remove_callback(link_t *item) 167 177 { 178 tmpfs_node_t *nodep = hash_table_get_instance(item, tmpfs_node_t, 179 nh_link); 180 181 while (!list_empty(&nodep->cs_head)) { 182 tmpfs_dentry_t *dentryp = list_get_instance(nodep->cs_head.next, 183 tmpfs_dentry_t, link); 184 185 assert(nodep->type == TMPFS_DIRECTORY); 186 list_remove(&dentryp->link); 187 free(dentryp); 188 } 189 190 if (nodep->data) { 191 assert(nodep->type == TMPFS_FILE); 192 free(nodep->data); 193 } 194 free(nodep->bp); 195 free(nodep); 168 196 } 169 197 … … 215 243 } 216 244 245 static void tmpfs_instance_done(dev_handle_t dev_handle) 246 { 247 unsigned long key[] = { 248 [NODES_KEY_DEV] = dev_handle 249 }; 250 /* 251 * Here we are making use of one special feature of our hash table 252 * implementation, which allows to remove more items based on a partial 253 * key match. In the following, we are going to remove all nodes 254 * matching our device handle. The nodes_remove_callback() function will 255 * take care of resource deallocation. 256 */ 257 hash_table_remove(&nodes, key, 1); 258 } 259 217 260 int tmpfs_match(fs_node_t **rfn, fs_node_t *pfn, const char *component) 218 261 { … … 237 280 { 238 281 unsigned long key[] = { 239 [NODES_KEY_ INDEX] = index,240 [NODES_KEY_ DEV] = dev_handle282 [NODES_KEY_DEV] = dev_handle, 283 [NODES_KEY_INDEX] = index 241 284 }; 242 285 link_t *lnk = hash_table_find(&nodes, key); … … 296 339 /* Insert the new node into the nodes hash table. */ 297 340 unsigned long key[] = { 298 [NODES_KEY_ INDEX] = nodep->index,299 [NODES_KEY_ DEV] = nodep->dev_handle341 [NODES_KEY_DEV] = nodep->dev_handle, 342 [NODES_KEY_INDEX] = nodep->index 300 343 }; 301 344 hash_table_insert(&nodes, key, &nodep->nh_link); … … 312 355 313 356 unsigned long key[] = { 314 [NODES_KEY_ INDEX] = nodep->index,315 [NODES_KEY_ DEV] = nodep->dev_handle357 [NODES_KEY_DEV] = nodep->dev_handle, 358 [NODES_KEY_INDEX] = nodep->index 316 359 }; 317 360 hash_table_remove(&nodes, key, 2); 318 361 319 if (nodep->type == TMPFS_FILE)320 free(nodep->data);321 free(nodep->bp);322 free(nodep);362 /* 363 * The nodes_remove_callback() function takes care of the actual 364 * resource deallocation. 365 */ 323 366 return EOK; 324 367 } … … 398 441 { 399 442 dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request); 443 fs_node_t *rootfn; 400 444 int rc; 401 402 /* accept the mount options */ 403 ipc_callid_t callid; 404 size_t size; 405 if (!async_data_write_receive(&callid, &size)) { 406 ipc_answer_0(callid, EINVAL); 407 ipc_answer_0(rid, EINVAL); 408 return; 409 } 410 char *opts = malloc(size + 1); 411 if (!opts) { 412 ipc_answer_0(callid, ENOMEM); 413 ipc_answer_0(rid, ENOMEM); 414 return; 415 } 416 ipcarg_t retval = async_data_write_finalize(callid, opts, size); 417 if (retval != EOK) { 418 ipc_answer_0(rid, retval); 445 446 /* Accept the mount options. */ 447 char *opts; 448 rc = async_data_write_accept((void **) &opts, true, 0, 0, 0, NULL); 449 if (rc != EOK) { 450 ipc_answer_0(rid, rc); 451 return; 452 } 453 454 /* Check if this device is not already mounted. */ 455 rc = tmpfs_root_get(&rootfn, dev_handle); 456 if ((rc == EOK) && (rootfn)) { 457 (void) tmpfs_node_put(rootfn); 419 458 free(opts); 420 return;421 }422 opts[size] = '\0';459 ipc_answer_0(rid, EEXIST); 460 return; 461 } 423 462 424 463 /* Initialize TMPFS instance. */ 425 464 if (!tmpfs_instance_init(dev_handle)) { 465 free(opts); 426 466 ipc_answer_0(rid, ENOMEM); 427 467 return; 428 468 } 429 469 430 fs_node_t *rootfn;431 470 rc = tmpfs_root_get(&rootfn, dev_handle); 432 471 assert(rc == EOK); … … 442 481 rootp->lnkcnt); 443 482 } 483 free(opts); 444 484 } 445 485 … … 447 487 { 448 488 libfs_mount(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request); 489 } 490 491 void tmpfs_unmounted(ipc_callid_t rid, ipc_call_t *request) 492 { 493 dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request); 494 495 tmpfs_instance_done(dev_handle); 496 ipc_answer_0(rid, EOK); 497 } 498 499 void tmpfs_unmount(ipc_callid_t rid, ipc_call_t *request) 500 { 501 libfs_unmount(&tmpfs_libfs_ops, rid, request); 449 502 } 450 503 … … 465 518 link_t *hlp; 466 519 unsigned long key[] = { 467 [NODES_KEY_INDEX] = index,468 520 [NODES_KEY_DEV] = dev_handle, 521 [NODES_KEY_INDEX] = index 469 522 }; 470 523 hlp = hash_table_find(&nodes, key); … … 539 592 link_t *hlp; 540 593 unsigned long key[] = { 541 [NODES_KEY_ INDEX] = index,542 [NODES_KEY_ DEV] = dev_handle594 [NODES_KEY_DEV] = dev_handle, 595 [NODES_KEY_INDEX] = index 543 596 }; 544 597 hlp = hash_table_find(&nodes, key); … … 603 656 link_t *hlp; 604 657 unsigned long key[] = { 605 [NODES_KEY_ INDEX] = index,606 [NODES_KEY_ DEV] = dev_handle658 [NODES_KEY_DEV] = dev_handle, 659 [NODES_KEY_INDEX] = index 607 660 }; 608 661 hlp = hash_table_find(&nodes, key); … … 646 699 link_t *hlp; 647 700 unsigned long key[] = { 648 [NODES_KEY_ INDEX] = index,649 [NODES_KEY_ DEV] = dev_handle701 [NODES_KEY_DEV] = dev_handle, 702 [NODES_KEY_INDEX] = index 650 703 }; 651 704 hlp = hash_table_find(&nodes, key); -
uspace/srv/hid/char_mouse/Makefile
r975e7e9 re27cf669 32 32 EXTRA_CFLAGS = -Iinclude 33 33 34 OUTPUT = c _mouse34 OUTPUT = char_ms 35 35 36 36 SOURCES = \ 37 37 proto/ps2.c \ 38 c _mouse.c \38 char_mouse.c \ 39 39 chardev.c 40 40 -
uspace/srv/hid/char_mouse/char_mouse.c
r975e7e9 re27cf669 47 47 #include <devmap.h> 48 48 49 #include <c _mouse.h>49 #include <char_mouse.h> 50 50 #include <mouse_port.h> 51 51 #include <mouse_proto.h> -
uspace/srv/hid/char_mouse/chardev.c
r975e7e9 re27cf669 41 41 #include <errno.h> 42 42 43 #include <c _mouse.h>43 #include <char_mouse.h> 44 44 #include <mouse_port.h> 45 45 -
uspace/srv/hid/char_mouse/include/char_mouse.h
r975e7e9 re27cf669 34 34 */ 35 35 36 #ifndef C _MOUSE_H_37 #define C _MOUSE_H_36 #ifndef CHAR_MOUSE_H_ 37 #define CHAR_MOUSE_H_ 38 38 39 39 extern void mouse_handle_byte(int); -
uspace/srv/hid/char_mouse/proto/ps2.c
r975e7e9 re27cf669 37 37 #include <stdio.h> 38 38 #include <mouse_proto.h> 39 #include <c _mouse.h>39 #include <char_mouse.h> 40 40 41 41 #define BUFSIZE 3 -
uspace/srv/hid/console/console.c
r975e7e9 re27cf669 475 475 static void cons_write(console_t *cons, ipc_callid_t rid, ipc_call_t *request) 476 476 { 477 ipc_callid_t callid;477 void *buf; 478 478 size_t size; 479 if (!async_data_write_receive(&callid, &size)) { 480 ipc_answer_0(callid, EINVAL); 481 ipc_answer_0(rid, EINVAL); 479 int rc = async_data_write_accept(&buf, false, 0, 0, 0, &size); 480 481 if (rc != EOK) { 482 ipc_answer_0(rid, rc); 482 483 return; 483 484 } 484 485 char *buf = (char *) malloc(size);486 if (buf == NULL) {487 ipc_answer_0(callid, ENOMEM);488 ipc_answer_0(rid, ENOMEM);489 return;490 }491 492 (void) async_data_write_finalize(callid, buf, size);493 485 494 486 async_serialize_start(); -
uspace/srv/hid/kbd/Makefile.build
r975e7e9 re27cf669 125 125 ifeq ($(UARCH),ppc32) 126 126 SOURCES += \ 127 port/ dummy.c \128 ctl/ stty.c127 port/adb.c \ 128 ctl/apple.c 129 129 endif 130 130 -
uspace/srv/loader/arch/amd64/Makefile.inc
r975e7e9 re27cf669 27 27 # 28 28 29 EXTRA_CFLAGS = -D__64_BITS__30 29 ARCH_SOURCES := arch/$(UARCH)/amd64.s -
uspace/srv/loader/arch/arm32/Makefile.inc
r975e7e9 re27cf669 27 27 # 28 28 29 EXTRA_CFLAGS = -D__32_BITS__30 29 ARCH_SOURCES := arch/$(UARCH)/arm32.s -
uspace/srv/loader/arch/ia32/Makefile.inc
r975e7e9 re27cf669 27 27 # 28 28 29 EXTRA_CFLAGS = -D__32_BITS__30 29 ARCH_SOURCES := arch/$(UARCH)/ia32.s -
uspace/srv/loader/arch/ia64/Makefile.inc
r975e7e9 re27cf669 27 27 # 28 28 29 EXTRA_CFLAGS = -D__64_BITS__30 29 ARCH_SOURCES := arch/$(UARCH)/ia64.s 31 30 AFLAGS += -xexplicit -
uspace/srv/loader/arch/mips32/Makefile.inc
r975e7e9 re27cf669 27 27 # 28 28 29 EXTRA_CFLAGS = -D__32_BITS__30 29 ARCH_SOURCES := arch/$(UARCH)/mips32.s -
uspace/srv/loader/arch/ppc32/Makefile.inc
r975e7e9 re27cf669 27 27 # 28 28 29 EXTRA_CFLAGS = -D__32_BITS__30 29 ARCH_SOURCES := arch/$(UARCH)/ppc32.s -
uspace/srv/loader/arch/sparc64/Makefile.inc
r975e7e9 re27cf669 27 27 # 28 28 29 EXTRA_CFLAGS = -D__64_BITS__30 29 ARCH_SOURCES := arch/$(UARCH)/sparc64.s -
uspace/srv/loader/elf_load.c
r975e7e9 re27cf669 342 342 seg_ptr = (void *) seg_addr; 343 343 344 DPRINTF("Load segment at addr 0x%x, size 0x%x\n", seg_addr,345 entry->p_memsz); 344 DPRINTF("Load segment at addr %p, size 0x%x\n", seg_addr, 345 entry->p_memsz); 346 346 347 347 if (entry->p_align > 1) { … … 370 370 mem_sz = entry->p_memsz + (entry->p_vaddr - base); 371 371 372 DPRINTF("Map to seg_addr= 0x%x-0x%x.\n", seg_addr,372 DPRINTF("Map to seg_addr=%p-%p.\n", seg_addr, 373 373 entry->p_vaddr + bias + ALIGN_UP(entry->p_memsz, PAGE_SIZE)); 374 374 … … 384 384 } 385 385 386 DPRINTF("as_area_create( 0x%lx, 0x%x, %d) -> 0x%lx\n",386 DPRINTF("as_area_create(%p, 0x%x, %d) -> 0x%lx\n", 387 387 base + bias, mem_sz, flags, (uintptr_t)a); 388 388 … … 461 461 elf->info->dynamic = 462 462 (void *)((uint8_t *)entry->sh_addr + elf->bias); 463 DPRINTF("Dynamic section found at 0x%x.\n",463 DPRINTF("Dynamic section found at %p.\n", 464 464 (uintptr_t)elf->info->dynamic); 465 465 break; -
uspace/srv/loader/main.c
r975e7e9 re27cf669 125 125 static void ldr_set_cwd(ipc_callid_t rid, ipc_call_t *request) 126 126 { 127 ipc_callid_t callid; 128 size_t len; 129 130 if (!async_data_write_receive(&callid, &len)) { 131 ipc_answer_0(callid, EINVAL); 132 ipc_answer_0(rid, EINVAL); 133 return; 134 } 135 136 cwd = malloc(len + 1); 137 if (!cwd) { 138 ipc_answer_0(callid, ENOMEM); 139 ipc_answer_0(rid, ENOMEM); 140 return; 141 } 142 143 async_data_write_finalize(callid, cwd, len); 144 cwd[len] = '\0'; 145 146 ipc_answer_0(rid, EOK); 127 char *buf; 128 int rc = async_data_write_accept((void **) &buf, true, 0, 0, 0, NULL); 129 130 if (rc == EOK) { 131 if (cwd != NULL) 132 free(cwd); 133 134 cwd = buf; 135 } 136 137 ipc_answer_0(rid, rc); 147 138 } 148 139 … … 154 145 static void ldr_set_pathname(ipc_callid_t rid, ipc_call_t *request) 155 146 { 156 ipc_callid_t callid; 157 size_t len; 158 char *name_buf; 159 160 if (!async_data_write_receive(&callid, &len)) { 161 ipc_answer_0(callid, EINVAL); 162 ipc_answer_0(rid, EINVAL); 163 return; 164 } 165 166 name_buf = malloc(len + 1); 167 if (!name_buf) { 168 ipc_answer_0(callid, ENOMEM); 169 ipc_answer_0(rid, ENOMEM); 170 return; 171 } 172 173 async_data_write_finalize(callid, name_buf, len); 174 ipc_answer_0(rid, EOK); 175 176 if (pathname != NULL) { 177 free(pathname); 178 pathname = NULL; 179 } 180 181 name_buf[len] = '\0'; 182 pathname = name_buf; 147 char *buf; 148 int rc = async_data_write_accept((void **) &buf, true, 0, 0, 0, NULL); 149 150 if (rc == EOK) { 151 if (pathname != NULL) 152 free(pathname); 153 154 pathname = buf; 155 } 156 157 ipc_answer_0(rid, rc); 183 158 } 184 159 … … 190 165 static void ldr_set_args(ipc_callid_t rid, ipc_call_t *request) 191 166 { 192 ipc_callid_t callid; 193 size_t buf_size, arg_size; 194 char *p; 195 int n; 196 197 if (!async_data_write_receive(&callid, &buf_size)) { 198 ipc_answer_0(callid, EINVAL); 199 ipc_answer_0(rid, EINVAL); 200 return; 201 } 202 203 if (arg_buf != NULL) { 204 free(arg_buf); 205 arg_buf = NULL; 206 } 207 208 if (argv != NULL) { 209 free(argv); 210 argv = NULL; 211 } 212 213 arg_buf = malloc(buf_size + 1); 214 if (!arg_buf) { 215 ipc_answer_0(callid, ENOMEM); 216 ipc_answer_0(rid, ENOMEM); 217 return; 218 } 219 220 async_data_write_finalize(callid, arg_buf, buf_size); 221 222 arg_buf[buf_size] = '\0'; 223 224 /* 225 * Count number of arguments 226 */ 227 p = arg_buf; 228 n = 0; 229 while (p < arg_buf + buf_size) { 230 arg_size = str_size(p); 231 p = p + arg_size + 1; 232 ++n; 233 } 234 235 /* Allocate argv */ 236 argv = malloc((n + 1) * sizeof(char *)); 237 238 if (argv == NULL) { 239 free(arg_buf); 240 ipc_answer_0(rid, ENOMEM); 241 return; 242 } 243 244 /* 245 * Fill argv with argument pointers 246 */ 247 p = arg_buf; 248 n = 0; 249 while (p < arg_buf + buf_size) { 250 argv[n] = p; 251 252 arg_size = str_size(p); 253 p = p + arg_size + 1; 254 ++n; 255 } 256 257 argc = n; 258 argv[n] = NULL; 259 260 ipc_answer_0(rid, EOK); 167 char *buf; 168 size_t buf_size; 169 int rc = async_data_write_accept((void **) &buf, true, 0, 0, 0, &buf_size); 170 171 if (rc == EOK) { 172 /* 173 * Count number of arguments 174 */ 175 char *cur = buf; 176 int count = 0; 177 178 while (cur < buf + buf_size) { 179 size_t arg_size = str_size(cur); 180 cur += arg_size + 1; 181 count++; 182 } 183 184 /* 185 * Allocate new argv 186 */ 187 char **_argv = (char **) malloc((count + 1) * sizeof(char *)); 188 if (_argv == NULL) { 189 free(buf); 190 ipc_answer_0(rid, ENOMEM); 191 return; 192 } 193 194 /* 195 * Fill the new argv with argument pointers 196 */ 197 cur = buf; 198 count = 0; 199 while (cur < buf + buf_size) { 200 _argv[count] = cur; 201 202 size_t arg_size = str_size(cur); 203 cur += arg_size + 1; 204 count++; 205 } 206 _argv[count] = NULL; 207 208 /* 209 * Copy temporary data to global variables 210 */ 211 if (arg_buf != NULL) 212 free(arg_buf); 213 214 if (argv != NULL) 215 free(argv); 216 217 argc = count; 218 arg_buf = buf; 219 argv = _argv; 220 } 221 222 ipc_answer_0(rid, rc); 261 223 } 262 224 … … 268 230 static void ldr_set_files(ipc_callid_t rid, ipc_call_t *request) 269 231 { 270 ipc_callid_t callid;232 fdi_node_t *buf; 271 233 size_t buf_size; 272 if (!async_data_write_receive(&callid, &buf_size)) { 273 ipc_answer_0(callid, EINVAL); 274 ipc_answer_0(rid, EINVAL); 275 return; 276 } 277 278 if ((buf_size % sizeof(fdi_node_t)) != 0) { 279 ipc_answer_0(callid, EINVAL); 280 ipc_answer_0(rid, EINVAL); 281 return; 282 } 283 284 if (fil_buf != NULL) { 285 free(fil_buf); 286 fil_buf = NULL; 287 } 288 289 if (filv != NULL) { 290 free(filv); 291 filv = NULL; 292 } 293 294 fil_buf = malloc(buf_size); 295 if (!fil_buf) { 296 ipc_answer_0(callid, ENOMEM); 297 ipc_answer_0(rid, ENOMEM); 298 return; 299 } 300 301 async_data_write_finalize(callid, fil_buf, buf_size); 302 303 int count = buf_size / sizeof(fdi_node_t); 304 305 /* Allocate filvv */ 306 filv = malloc((count + 1) * sizeof(fdi_node_t *)); 307 308 if (filv == NULL) { 309 free(fil_buf); 310 ipc_answer_0(rid, ENOMEM); 311 return; 312 } 313 314 /* 315 * Fill filv with argument pointers 316 */ 317 int i; 318 for (i = 0; i < count; i++) 319 filv[i] = &fil_buf[i]; 320 321 filc = count; 322 filv[count] = NULL; 234 int rc = async_data_write_accept((void **) &buf, false, 0, 0, 235 sizeof(fdi_node_t), &buf_size); 236 237 if (rc == EOK) { 238 int count = buf_size / sizeof(fdi_node_t); 239 240 /* 241 * Allocate new filv 242 */ 243 fdi_node_t **_filv = (fdi_node_t *) malloc((count + 1) * sizeof(fdi_node_t *)); 244 if (_filv == NULL) { 245 free(buf); 246 ipc_answer_0(rid, ENOMEM); 247 return; 248 } 249 250 /* 251 * Fill the new filv with argument pointers 252 */ 253 int i; 254 for (i = 0; i < count; i++) 255 _filv[i] = &buf[i]; 256 257 _filv[count] = NULL; 258 259 /* 260 * Copy temporary data to global variables 261 */ 262 if (fil_buf != NULL) 263 free(fil_buf); 264 265 if (filv != NULL) 266 free(filv); 267 268 filc = count; 269 fil_buf = buf; 270 filv = _filv; 271 } 323 272 324 273 ipc_answer_0(rid, EOK); … … 392 341 /* Dynamically linked program */ 393 342 DPRINTF("Run ELF interpreter.\n"); 394 DPRINTF("Entry point: 0x%lx\n", interp_info.entry);343 DPRINTF("Entry point: %p\n", interp_info.entry); 395 344 396 345 ipc_answer_0(rid, EOK); -
uspace/srv/vfs/vfs.c
r975e7e9 re27cf669 87 87 vfs_mount(callid, &call); 88 88 break; 89 case VFS_IN_UNMOUNT: 90 vfs_unmount(callid, &call); 91 break; 89 92 case VFS_IN_OPEN: 90 93 vfs_open(callid, &call); … … 134 137 } 135 138 136 /* TODO: cleanup after the client */139 vfs_files_done(); 137 140 } 138 141 -
uspace/srv/vfs/vfs.h
r975e7e9 re27cf669 177 177 vfs_pair_t *, ...); 178 178 extern int vfs_open_node_internal(vfs_lookup_res_t *); 179 extern int vfs_close_internal(vfs_file_t *); 179 180 180 181 extern bool vfs_nodes_init(void); 181 182 extern vfs_node_t *vfs_node_get(vfs_lookup_res_t *); 182 183 extern void vfs_node_put(vfs_node_t *); 184 extern void vfs_node_forget(vfs_node_t *); 185 extern unsigned vfs_nodes_refcount_sum_get(fs_handle_t, dev_handle_t); 186 183 187 184 188 #define MAX_OPEN_FILES 128 185 189 186 190 extern bool vfs_files_init(void); 191 extern void vfs_files_done(void); 187 192 extern vfs_file_t *vfs_file_get(int); 188 193 extern int vfs_fd_assign(vfs_file_t *file, int fd); … … 198 203 extern void vfs_register(ipc_callid_t, ipc_call_t *); 199 204 extern void vfs_mount(ipc_callid_t, ipc_call_t *); 205 extern void vfs_unmount(ipc_callid_t, ipc_call_t *); 200 206 extern void vfs_open(ipc_callid_t, ipc_call_t *); 201 207 extern void vfs_open_node(ipc_callid_t, ipc_call_t *); -
uspace/srv/vfs/vfs_file.c
r975e7e9 re27cf669 72 72 } 73 73 return true; 74 } 75 76 /** Cleanup the table of open files. */ 77 void vfs_files_done(void) 78 { 79 int i; 80 81 if (!files) 82 return; 83 84 for (i = 0; i < MAX_OPEN_FILES; i++) { 85 if (files[i]) { 86 (void) vfs_close_internal(files[i]); 87 (void) vfs_fd_free(i); 88 } 89 } 90 91 free(files); 74 92 } 75 93 -
uspace/srv/vfs/vfs_node.c
r975e7e9 re27cf669 137 137 if (free_vfs_node) 138 138 free(node); 139 } 140 141 /** Forget node. 142 * 143 * This function will remove the node from the node hash table and deallocate 144 * its memory, regardless of the node's reference count. 145 * 146 * @param node Node to be forgotten. 147 */ 148 void vfs_node_forget(vfs_node_t *node) 149 { 150 fibril_mutex_lock(&nodes_mutex); 151 unsigned long key[] = { 152 [KEY_FS_HANDLE] = node->fs_handle, 153 [KEY_DEV_HANDLE] = node->dev_handle, 154 [KEY_INDEX] = node->index 155 }; 156 hash_table_remove(&nodes, key, 3); 157 fibril_mutex_unlock(&nodes_mutex); 158 free(node); 139 159 } 140 160 … … 231 251 } 232 252 253 struct refcnt_data { 254 /** Sum of all reference counts for this file system instance. */ 255 unsigned refcnt; 256 fs_handle_t fs_handle; 257 dev_handle_t dev_handle; 258 }; 259 260 static void refcnt_visitor(link_t *item, void *arg) 261 { 262 vfs_node_t *node = hash_table_get_instance(item, vfs_node_t, nh_link); 263 struct refcnt_data *rd = (void *) arg; 264 265 if ((node->fs_handle == rd->fs_handle) && 266 (node->dev_handle == rd->dev_handle)) 267 rd->refcnt += node->refcnt; 268 } 269 270 unsigned 271 vfs_nodes_refcount_sum_get(fs_handle_t fs_handle, dev_handle_t dev_handle) 272 { 273 struct refcnt_data rd = { 274 .refcnt = 0, 275 .fs_handle = fs_handle, 276 .dev_handle = dev_handle 277 }; 278 279 fibril_mutex_lock(&nodes_mutex); 280 hash_table_apply(&nodes, refcnt_visitor, &rd); 281 fibril_mutex_unlock(&nodes_mutex); 282 283 return rd.refcnt; 284 } 285 233 286 /** 234 287 * @} -
uspace/srv/vfs/vfs_ops.c
r975e7e9 re27cf669 92 92 } 93 93 94 rc = vfs_lookup_internal(mp, L_ DIRECTORY, &mp_res, NULL);94 rc = vfs_lookup_internal(mp, L_MP, &mp_res, NULL); 95 95 if (rc != EOK) { 96 96 /* The lookup failed for some reason. */ … … 266 266 267 267 /* We want the client to send us the mount point. */ 268 ipc_callid_t callid; 269 size_t size; 270 if (!async_data_write_receive(&callid, &size)) { 271 ipc_answer_0(callid, EINVAL); 272 ipc_answer_0(rid, EINVAL); 273 return; 274 } 275 276 /* Check whether size is reasonable wrt. the mount point. */ 277 if ((size < 1) || (size > MAX_PATH_LEN)) { 278 ipc_answer_0(callid, EINVAL); 279 ipc_answer_0(rid, EINVAL); 280 return; 281 } 282 283 /* Allocate buffer for the mount point data being received. */ 284 char *mp = malloc(size + 1); 285 if (!mp) { 286 ipc_answer_0(callid, ENOMEM); 287 ipc_answer_0(rid, ENOMEM); 288 return; 289 } 290 291 /* Deliver the mount point. */ 292 ipcarg_t retval = async_data_write_finalize(callid, mp, size); 293 if (retval != EOK) { 294 ipc_answer_0(rid, retval); 268 char *mp; 269 int rc = async_data_write_accept((void **) &mp, true, 0, MAX_PATH_LEN, 270 0, NULL); 271 if (rc != EOK) { 272 ipc_answer_0(rid, rc); 273 return; 274 } 275 276 /* Now we expect to receive the mount options. */ 277 char *opts; 278 rc = async_data_write_accept((void **) &opts, true, 0, MAX_MNTOPTS_LEN, 279 0, NULL); 280 if (rc != EOK) { 295 281 free(mp); 296 return; 297 } 298 mp[size] = '\0'; 299 300 /* Now we expect to receive the mount options. */ 301 if (!async_data_write_receive(&callid, &size)) { 302 ipc_answer_0(callid, EINVAL); 303 ipc_answer_0(rid, EINVAL); 304 free(mp); 305 return; 306 } 307 308 /* Check the offered options size. */ 309 if (size > MAX_MNTOPTS_LEN) { 310 ipc_answer_0(callid, EINVAL); 311 ipc_answer_0(rid, EINVAL); 312 free(mp); 313 return; 314 } 315 316 /* Allocate buffer for the mount options. */ 317 char *opts = (char *) malloc(size + 1); 318 if (!opts) { 319 ipc_answer_0(callid, ENOMEM); 320 ipc_answer_0(rid, ENOMEM); 321 free(mp); 322 return; 323 } 324 325 /* Deliver the mount options. */ 326 retval = async_data_write_finalize(callid, opts, size); 327 if (retval != EOK) { 328 ipc_answer_0(rid, retval); 282 ipc_answer_0(rid, rc); 283 return; 284 } 285 286 /* 287 * Now, we expect the client to send us data with the name of the file 288 * system. 289 */ 290 char *fs_name; 291 rc = async_data_write_accept((void **) &fs_name, true, 0, FS_NAME_MAXLEN, 292 0, NULL); 293 if (rc != EOK) { 329 294 free(mp); 330 295 free(opts); 331 return; 332 } 333 opts[size] = '\0'; 334 335 /* 336 * Now, we expect the client to send us data with the name of the file 337 * system. 338 */ 339 if (!async_data_write_receive(&callid, &size)) { 340 ipc_answer_0(callid, EINVAL); 341 ipc_answer_0(rid, EINVAL); 342 free(mp); 343 free(opts); 344 return; 345 } 346 347 /* 348 * Don't receive more than is necessary for storing a full file system 349 * name. 350 */ 351 if ((size < 1) || (size > FS_NAME_MAXLEN)) { 352 ipc_answer_0(callid, EINVAL); 353 ipc_answer_0(rid, EINVAL); 354 free(mp); 355 free(opts); 356 return; 357 } 358 359 /* 360 * Allocate buffer for file system name. 361 */ 362 char *fs_name = (char *) malloc(size + 1); 363 if (fs_name == NULL) { 364 ipc_answer_0(callid, ENOMEM); 365 ipc_answer_0(rid, ENOMEM); 366 free(mp); 367 free(opts); 368 return; 369 } 370 371 /* Deliver the file system name. */ 372 retval = async_data_write_finalize(callid, fs_name, size); 373 if (retval != EOK) { 374 ipc_answer_0(rid, retval); 375 free(mp); 376 free(opts); 377 free(fs_name); 378 return; 379 } 380 fs_name[size] = '\0'; 381 296 ipc_answer_0(rid, rc); 297 return; 298 } 299 382 300 /* 383 301 * Wait for IPC_M_PING so that we can return an error if we don't know … … 385 303 */ 386 304 ipc_call_t data; 387 callid = async_get_call(&data);305 ipc_callid_t callid = async_get_call(&data); 388 306 if (IPC_GET_METHOD(data) != IPC_M_PING) { 389 307 ipc_answer_0(callid, ENOTSUP); … … 429 347 } 430 348 349 void vfs_unmount(ipc_callid_t rid, ipc_call_t *request) 350 { 351 int rc; 352 char *mp; 353 vfs_lookup_res_t mp_res; 354 vfs_lookup_res_t mr_res; 355 vfs_node_t *mp_node; 356 vfs_node_t *mr_node; 357 int phone; 358 359 /* 360 * Receive the mount point path. 361 */ 362 rc = async_data_write_accept((void **) &mp, true, 0, MAX_PATH_LEN, 363 0, NULL); 364 if (rc != EOK) 365 ipc_answer_0(rid, rc); 366 367 /* 368 * Taking the namespace lock will do two things for us. First, it will 369 * prevent races with other lookup operations. Second, it will stop new 370 * references to already existing VFS nodes and creation of new VFS 371 * nodes. This is because new references are added as a result of some 372 * lookup operation or at least of some operation which is protected by 373 * the namespace lock. 374 */ 375 fibril_rwlock_write_lock(&namespace_rwlock); 376 377 /* 378 * Lookup the mounted root and instantiate it. 379 */ 380 rc = vfs_lookup_internal(mp, L_ROOT, &mr_res, NULL); 381 if (rc != EOK) { 382 fibril_rwlock_write_unlock(&namespace_rwlock); 383 free(mp); 384 ipc_answer_0(rid, rc); 385 return; 386 } 387 mr_node = vfs_node_get(&mr_res); 388 if (!mr_node) { 389 fibril_rwlock_write_unlock(&namespace_rwlock); 390 free(mp); 391 ipc_answer_0(rid, ENOMEM); 392 return; 393 } 394 395 /* 396 * Count the total number of references for the mounted file system. We 397 * are expecting at least two. One which we got above and one which we 398 * got when the file system was mounted. If we find more, it means that 399 * the file system cannot be gracefully unmounted at the moment because 400 * someone is working with it. 401 */ 402 if (vfs_nodes_refcount_sum_get(mr_node->fs_handle, 403 mr_node->dev_handle) != 2) { 404 fibril_rwlock_write_unlock(&namespace_rwlock); 405 vfs_node_put(mr_node); 406 free(mp); 407 ipc_answer_0(rid, EBUSY); 408 return; 409 } 410 411 if (str_cmp(mp, "/") == 0) { 412 413 /* 414 * Unmounting the root file system. 415 * 416 * In this case, there is no mount point node and we send 417 * VFS_OUT_UNMOUNTED directly to the mounted file system. 418 */ 419 420 free(mp); 421 phone = vfs_grab_phone(mr_node->fs_handle); 422 rc = async_req_1_0(phone, VFS_OUT_UNMOUNTED, 423 mr_node->dev_handle); 424 vfs_release_phone(phone); 425 if (rc != EOK) { 426 fibril_rwlock_write_unlock(&namespace_rwlock); 427 vfs_node_put(mr_node); 428 ipc_answer_0(rid, rc); 429 return; 430 } 431 rootfs.fs_handle = 0; 432 rootfs.dev_handle = 0; 433 } else { 434 435 /* 436 * Unmounting a non-root file system. 437 * 438 * We have a regular mount point node representing the parent 439 * file system, so we delegate the operation to it. 440 */ 441 442 rc = vfs_lookup_internal(mp, L_MP, &mp_res, NULL); 443 free(mp); 444 if (rc != EOK) { 445 fibril_rwlock_write_unlock(&namespace_rwlock); 446 vfs_node_put(mr_node); 447 ipc_answer_0(rid, rc); 448 return; 449 } 450 vfs_node_t *mp_node = vfs_node_get(&mp_res); 451 if (!mp_node) { 452 fibril_rwlock_write_unlock(&namespace_rwlock); 453 vfs_node_put(mr_node); 454 ipc_answer_0(rid, ENOMEM); 455 return; 456 } 457 458 phone = vfs_grab_phone(mp_node->fs_handle); 459 rc = async_req_2_0(phone, VFS_OUT_UNMOUNT, mp_node->dev_handle, 460 mp_node->index); 461 vfs_release_phone(phone); 462 if (rc != EOK) { 463 fibril_rwlock_write_unlock(&namespace_rwlock); 464 vfs_node_put(mp_node); 465 vfs_node_put(mr_node); 466 ipc_answer_0(rid, rc); 467 return; 468 } 469 470 /* Drop the reference we got above. */ 471 vfs_node_put(mp_node); 472 /* Drop the reference from when the file system was mounted. */ 473 vfs_node_put(mp_node); 474 } 475 476 477 /* 478 * All went well, the mounted file system was successfully unmounted. 479 * The only thing left is to forget the unmounted root VFS node. 480 */ 481 vfs_node_forget(mr_node); 482 483 fibril_rwlock_write_unlock(&namespace_rwlock); 484 ipc_answer_0(rid, EOK); 485 } 486 431 487 void vfs_open(ipc_callid_t rid, ipc_call_t *request) 432 488 { … … 454 510 /* 455 511 * Make sure that we are called with exactly one of L_FILE and 456 * L_DIRECTORY. Make sure that the user does not pass L_OPEN. 512 * L_DIRECTORY. Make sure that the user does not pass L_OPEN, 513 * L_ROOT or L_MP. 457 514 */ 458 515 if (((lflag & (L_FILE | L_DIRECTORY)) == 0) || 459 516 ((lflag & (L_FILE | L_DIRECTORY)) == (L_FILE | L_DIRECTORY)) || 460 ( (lflag & L_OPEN) != 0)) {517 (lflag & (L_OPEN | L_ROOT | L_MP))) { 461 518 ipc_answer_0(rid, EINVAL); 462 519 return; … … 468 525 lflag |= L_EXCLUSIVE; 469 526 470 ipc_callid_t callid; 471 if (!async_data_write_receive(&callid, &len)) { 472 ipc_answer_0(callid, EINVAL); 473 ipc_answer_0(rid, EINVAL); 474 return; 475 } 476 477 char *path = malloc(len + 1); 478 if (!path) { 479 ipc_answer_0(callid, ENOMEM); 480 ipc_answer_0(rid, ENOMEM); 481 return; 482 } 483 484 int rc; 485 if ((rc = async_data_write_finalize(callid, path, len))) { 486 ipc_answer_0(rid, rc); 487 free(path); 488 return; 489 } 490 path[len] = '\0'; 527 char *path; 528 int rc = async_data_write_accept((void **) &path, true, 0, 0, 0, NULL); 529 if (rc != EOK) { 530 ipc_answer_0(rid, rc); 531 return; 532 } 491 533 492 534 /* … … 679 721 } 680 722 681 staticint vfs_close_internal(vfs_file_t *file)723 int vfs_close_internal(vfs_file_t *file) 682 724 { 683 725 /* … … 756 798 757 799 /* 758 * Now we need to receive a call with client's759 * IPC_M_DATA_READ/IPC_M_DATA_WRITE request.760 */761 ipc_callid_t callid;762 int res;763 if (read)764 res = async_data_read_receive(&callid, NULL);765 else766 res = async_data_write_receive(&callid, NULL);767 if (!res) {768 ipc_answer_0(callid, EINVAL);769 ipc_answer_0(rid, EINVAL);770 return;771 }772 773 /*774 800 * Lock the open file structure so that no other thread can manipulate 775 801 * the same open file at a time. … … 795 821 } 796 822 797 int fs_phone = vfs_grab_phone(file->node->fs_handle); 798 799 /* Make a VFS_READ/VFS_WRITE request at the destination FS server. */ 800 aid_t msg; 801 ipc_call_t answer; 802 if (!read && file->append) 803 file->pos = file->node->size; 804 msg = async_send_3(fs_phone, read ? VFS_OUT_READ : VFS_OUT_WRITE, 805 file->node->dev_handle, file->node->index, file->pos, &answer); 806 807 /* 808 * Forward the IPC_M_DATA_READ/IPC_M_DATA_WRITE request to the 823 int fs_phone = vfs_grab_phone(file->node->fs_handle); 824 825 /* 826 * Make a VFS_READ/VFS_WRITE request at the destination FS server 827 * and forward the IPC_M_DATA_READ/IPC_M_DATA_WRITE request to the 809 828 * destination FS server. The call will be routed as if sent by 810 829 * ourselves. Note that call arguments are immutable in this case so we 811 830 * don't have to bother. 812 831 */ 813 ipc_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME);814 815 /* Wait for reply from the FS server. */816 832 ipcarg_t rc; 817 async_wait_for(msg, &rc); 833 ipc_call_t answer; 834 if (read) { 835 if (file->append) 836 file->pos = file->node->size; 837 838 rc = async_data_read_forward_3_1(fs_phone, VFS_OUT_READ, 839 file->node->dev_handle, file->node->index, file->pos, 840 &answer); 841 } else { 842 rc = async_data_write_forward_3_1(fs_phone, VFS_OUT_WRITE, 843 file->node->dev_handle, file->node->index, file->pos, 844 &answer); 845 } 818 846 819 847 vfs_release_phone(fs_phone); 820 848 821 849 size_t bytes = IPC_GET_ARG1(answer); 822 850 823 851 if (file->node->type == VFS_NODE_DIRECTORY) 824 852 fibril_rwlock_read_unlock(&namespace_rwlock); … … 982 1010 void vfs_stat(ipc_callid_t rid, ipc_call_t *request) 983 1011 { 984 size_t len; 1012 char *path; 1013 int rc = async_data_write_accept((void **) &path, true, 0, 0, 0, NULL); 1014 if (rc != EOK) { 1015 ipc_answer_0(rid, rc); 1016 return; 1017 } 1018 985 1019 ipc_callid_t callid; 986 987 if (!async_data_write_receive(&callid, &len)) {988 ipc_answer_0(callid, EINVAL);989 ipc_answer_0(rid, EINVAL);990 return;991 }992 char *path = malloc(len + 1);993 if (!path) {994 ipc_answer_0(callid, ENOMEM);995 ipc_answer_0(rid, ENOMEM);996 return;997 }998 int rc;999 if ((rc = async_data_write_finalize(callid, path, len))) {1000 ipc_answer_0(rid, rc);1001 free(path);1002 return;1003 }1004 path[len] = '\0';1005 1006 1020 if (!async_data_read_receive(&callid, NULL)) { 1007 1021 free(path); … … 1049 1063 { 1050 1064 int mode = IPC_GET_ARG1(*request); 1051 1052 size_t len; 1053 ipc_callid_t callid; 1054 1055 if (!async_data_write_receive(&callid, &len)) { 1056 ipc_answer_0(callid, EINVAL); 1057 ipc_answer_0(rid, EINVAL); 1058 return; 1059 } 1060 char *path = malloc(len + 1); 1061 if (!path) { 1062 ipc_answer_0(callid, ENOMEM); 1063 ipc_answer_0(rid, ENOMEM); 1064 return; 1065 } 1066 int rc; 1067 if ((rc = async_data_write_finalize(callid, path, len))) { 1068 ipc_answer_0(rid, rc); 1069 free(path); 1070 return; 1071 } 1072 path[len] = '\0'; 1073 1065 1066 char *path; 1067 int rc = async_data_write_accept((void **) &path, true, 0, 0, 0, NULL); 1068 if (rc != EOK) { 1069 ipc_answer_0(rid, rc); 1070 return; 1071 } 1072 1074 1073 /* Ignore mode for now. */ 1075 1074 (void) mode; … … 1086 1085 { 1087 1086 int lflag = IPC_GET_ARG1(*request); 1088 1089 size_t len; 1090 ipc_callid_t callid; 1091 1092 if (!async_data_write_receive(&callid, &len)) { 1093 ipc_answer_0(callid, EINVAL); 1094 ipc_answer_0(rid, EINVAL); 1095 return; 1096 } 1097 char *path = malloc(len + 1); 1098 if (!path) { 1099 ipc_answer_0(callid, ENOMEM); 1100 ipc_answer_0(rid, ENOMEM); 1101 return; 1102 } 1103 int rc; 1104 if ((rc = async_data_write_finalize(callid, path, len))) { 1105 ipc_answer_0(rid, rc); 1106 free(path); 1107 return; 1108 } 1109 path[len] = '\0'; 1087 1088 char *path; 1089 int rc = async_data_write_accept((void **) &path, true, 0, 0, 0, NULL); 1090 if (rc != EOK) { 1091 ipc_answer_0(rid, rc); 1092 return; 1093 } 1110 1094 1111 1095 fibril_rwlock_write_lock(&namespace_rwlock); … … 1136 1120 void vfs_rename(ipc_callid_t rid, ipc_call_t *request) 1137 1121 { 1138 size_t olen, nlen;1139 ipc_callid_t callid;1140 int rc;1141 1142 1122 /* Retrieve the old path. */ 1143 if (!async_data_write_receive(&callid, &olen)) { 1144 ipc_answer_0(callid, EINVAL); 1145 ipc_answer_0(rid, EINVAL); 1146 return; 1147 } 1148 char *old = malloc(olen + 1); 1149 if (!old) { 1150 ipc_answer_0(callid, ENOMEM); 1151 ipc_answer_0(rid, ENOMEM); 1152 return; 1153 } 1154 if ((rc = async_data_write_finalize(callid, old, olen))) { 1155 ipc_answer_0(rid, rc); 1123 char *old; 1124 int rc = async_data_write_accept((void **) &old, true, 0, 0, 0, NULL); 1125 if (rc != EOK) { 1126 ipc_answer_0(rid, rc); 1127 return; 1128 } 1129 1130 /* Retrieve the new path. */ 1131 char *new; 1132 rc = async_data_write_accept((void **) &new, true, 0, 0, 0, NULL); 1133 if (rc != EOK) { 1156 1134 free(old); 1157 return; 1158 } 1159 old[olen] = '\0'; 1160 1161 /* Retrieve the new path. */ 1162 if (!async_data_write_receive(&callid, &nlen)) { 1163 ipc_answer_0(callid, EINVAL); 1164 ipc_answer_0(rid, EINVAL); 1165 free(old); 1166 return; 1167 } 1168 char *new = malloc(nlen + 1); 1169 if (!new) { 1170 ipc_answer_0(callid, ENOMEM); 1171 ipc_answer_0(rid, ENOMEM); 1172 free(old); 1173 return; 1174 } 1175 if ((rc = async_data_write_finalize(callid, new, nlen))) { 1176 ipc_answer_0(rid, rc); 1177 free(old); 1178 free(new); 1179 return; 1180 } 1181 new[nlen] = '\0'; 1182 1135 ipc_answer_0(rid, rc); 1136 return; 1137 } 1138 1139 size_t olen; 1140 size_t nlen; 1183 1141 char *oldc = canonify(old, &olen); 1184 1142 char *newc = canonify(new, &nlen); 1185 if (!oldc || !newc) { 1143 1144 if ((!oldc) || (!newc)) { 1186 1145 ipc_answer_0(rid, EINVAL); 1187 1146 free(old); … … 1189 1148 return; 1190 1149 } 1150 1191 1151 oldc[olen] = '\0'; 1192 1152 newc[nlen] = '\0'; 1153 1193 1154 if ((!str_lcmp(newc, oldc, str_length(oldc))) && 1194 1155 ((newc[str_length(oldc)] == '/') || … … 1211 1172 vfs_lookup_res_t new_par_lr; 1212 1173 fibril_rwlock_write_lock(&namespace_rwlock); 1174 1213 1175 /* Lookup the node belonging to the old file name. */ 1214 1176 rc = vfs_lookup_internal(oldc, L_NONE, &old_lr, NULL); … … 1220 1182 return; 1221 1183 } 1184 1222 1185 vfs_node_t *old_node = vfs_node_get(&old_lr); 1223 1186 if (!old_node) { … … 1228 1191 return; 1229 1192 } 1193 1230 1194 /* Determine the path to the parent of the node with the new name. */ 1231 1195 char *parentc = str_dup(newc); … … 1237 1201 return; 1238 1202 } 1203 1239 1204 char *lastsl = str_rchr(parentc + 1, '/'); 1240 1205 if (lastsl) … … 1242 1207 else 1243 1208 parentc[1] = '\0'; 1209 1244 1210 /* Lookup parent of the new file name. */ 1245 1211 rc = vfs_lookup_internal(parentc, L_NONE, &new_par_lr, NULL); … … 1252 1218 return; 1253 1219 } 1220 1254 1221 /* Check whether linking to the same file system instance. */ 1255 1222 if ((old_node->fs_handle != new_par_lr.triplet.fs_handle) || … … 1261 1228 return; 1262 1229 } 1230 1263 1231 /* Destroy the old link for the new name. */ 1264 1232 vfs_node_t *new_node = NULL; 1265 1233 rc = vfs_lookup_internal(newc, L_UNLINK, &new_lr, NULL); 1234 1266 1235 switch (rc) { 1267 1236 case ENOENT: … … 1288 1257 return; 1289 1258 } 1259 1290 1260 /* Create the new link for the new name. */ 1291 1261 rc = vfs_lookup_internal(newc, L_LINK, NULL, NULL, old_node->index); … … 1299 1269 return; 1300 1270 } 1271 1301 1272 fibril_mutex_lock(&nodes_mutex); 1302 1273 old_node->lnkcnt++; 1303 1274 fibril_mutex_unlock(&nodes_mutex); 1275 1304 1276 /* Destroy the link for the old name. */ 1305 1277 rc = vfs_lookup_internal(oldc, L_UNLINK, NULL, NULL); … … 1314 1286 return; 1315 1287 } 1288 1316 1289 fibril_mutex_lock(&nodes_mutex); 1317 1290 old_node->lnkcnt--; … … 1319 1292 fibril_rwlock_write_unlock(&namespace_rwlock); 1320 1293 vfs_node_put(old_node); 1294 1321 1295 if (new_node) 1322 1296 vfs_node_put(new_node); 1297 1323 1298 free(old); 1324 1299 free(new); -
uspace/srv/vfs/vfs_register.c
r975e7e9 re27cf669 110 110 void vfs_register(ipc_callid_t rid, ipc_call_t *request) 111 111 { 112 ipc_callid_t callid;113 ipc_call_t call;114 int rc;115 size_t size;116 117 112 dprintf("Processing VFS_REGISTER request received from %p.\n", 118 113 request->in_phone_hash); 119 120 /* 121 * The first call has to be IPC_M_DATA_SEND in which we receive the 122 * VFS info structure from the client FS. 123 */ 124 if (!async_data_write_receive(&callid, &size)) { 125 /* 126 * The client doesn't obey the same protocol as we do. 127 */ 128 dprintf("Receiving of VFS info failed.\n"); 129 ipc_answer_0(callid, EINVAL); 130 ipc_answer_0(rid, EINVAL); 131 return; 132 } 133 134 dprintf("VFS info received, size = %d\n", size); 135 136 /* 137 * We know the size of the VFS info structure. See if the client 138 * understands this easy concept too. 139 */ 140 if (size != sizeof(vfs_info_t)) { 141 /* 142 * The client is sending us something, which cannot be 143 * the info structure. 144 */ 145 dprintf("Received VFS info has bad size.\n"); 146 ipc_answer_0(callid, EINVAL); 147 ipc_answer_0(rid, EINVAL); 148 return; 149 } 150 151 /* 152 * Allocate and initialize a buffer for the fs_info structure. 153 */ 154 fs_info_t *fs_info; 155 fs_info = (fs_info_t *) malloc(sizeof(fs_info_t)); 156 if (!fs_info) { 157 dprintf("Could not allocate memory for FS info.\n"); 158 ipc_answer_0(callid, ENOMEM); 159 ipc_answer_0(rid, ENOMEM); 160 return; 161 } 162 link_initialize(&fs_info->fs_link); 163 fibril_mutex_initialize(&fs_info->phone_lock); 164 165 rc = async_data_write_finalize(callid, &fs_info->vfs_info, size); 114 115 vfs_info_t *vfs_info; 116 int rc = async_data_write_accept((void **) &vfs_info, false, 117 sizeof(vfs_info_t), sizeof(vfs_info_t), 0, NULL); 118 166 119 if (rc != EOK) { 167 120 dprintf("Failed to deliver the VFS info into our AS, rc=%d.\n", 168 121 rc); 169 free(fs_info);170 ipc_answer_0(callid, rc);171 122 ipc_answer_0(rid, rc); 172 123 return; 173 124 } 174 125 126 /* 127 * Allocate and initialize a buffer for the fs_info structure. 128 */ 129 fs_info_t *fs_info = (fs_info_t *) malloc(sizeof(fs_info_t)); 130 if (!fs_info) { 131 dprintf("Could not allocate memory for FS info.\n"); 132 ipc_answer_0(rid, ENOMEM); 133 return; 134 } 135 136 link_initialize(&fs_info->fs_link); 137 fibril_mutex_initialize(&fs_info->phone_lock); 138 fs_info->vfs_info = *vfs_info; 139 free(vfs_info); 140 175 141 dprintf("VFS info delivered.\n"); 176 142 177 143 if (!vfs_info_sane(&fs_info->vfs_info)) { 178 144 free(fs_info); 179 ipc_answer_0(callid, EINVAL);180 145 ipc_answer_0(rid, EINVAL); 181 146 return; 182 147 } 183 148 184 149 fibril_mutex_lock(&fs_head_lock); 185 150 186 151 /* 187 152 * Check for duplicit registrations. … … 194 159 fibril_mutex_unlock(&fs_head_lock); 195 160 free(fs_info); 196 ipc_answer_0(callid, EEXISTS);197 161 ipc_answer_0(rid, EEXISTS); 198 162 return; 199 163 } 200 164 201 165 /* 202 166 * Add fs_info to the list of registered FS's. … … 210 174 * which to forward VFS requests to it. 211 175 */ 212 callid = async_get_call(&call); 176 ipc_call_t call; 177 ipc_callid_t callid = async_get_call(&call); 213 178 if (IPC_GET_METHOD(call) != IPC_M_CONNECT_TO_ME) { 214 179 dprintf("Unexpected call, method = %d\n", IPC_GET_METHOD(call)); … … 222 187 fs_info->phone = IPC_GET_ARG5(call); 223 188 ipc_answer_0(callid, EOK); 224 189 225 190 dprintf("Callback connection to FS created.\n"); 226 191 227 192 /* 228 193 * The client will want us to send him the address space area with PLB. 229 194 */ 230 195 196 size_t size; 231 197 if (!async_share_in_receive(&callid, &size)) { 232 198 dprintf("Unexpected call, method = %d\n", IPC_GET_METHOD(call)); … … 253 219 return; 254 220 } 255 221 256 222 /* 257 223 * Commit to read-only sharing the PLB with the client. … … 259 225 (void) async_share_in_finalize(callid, plb, 260 226 AS_AREA_READ | AS_AREA_CACHEABLE); 261 227 262 228 dprintf("Sharing PLB.\n"); 263 229 264 230 /* 265 231 * That was it. The FS has been registered.
Note:
See TracChangeset
for help on using the changeset viewer.