Changes in uspace/lib/block/libblock.c [7a72ce1a:79ae36dd] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/block/libblock.c
r7a72ce1a r79ae36dd 39 39 #include "libblock.h" 40 40 #include "../../srv/vfs/vfs.h" 41 #include <ipc/ loc.h>41 #include <ipc/devmap.h> 42 42 #include <ipc/bd.h> 43 43 #include <ipc/services.h> … … 60 60 static FIBRIL_MUTEX_INITIALIZE(dcl_lock); 61 61 /** Device connection list head. */ 62 static LIST_INITIALIZE(dcl );62 static LIST_INITIALIZE(dcl_head); 63 63 64 64 #define CACHE_BUCKETS_LOG2 10 … … 72 72 unsigned blocks_cached; /**< Number of cached blocks. */ 73 73 hash_table_t block_hash; 74 li st_t free_list;74 link_t free_head; 75 75 enum cache_mode mode; 76 76 } cache_t; … … 78 78 typedef struct { 79 79 link_t link; 80 service_id_t service_id;80 devmap_handle_t devmap_handle; 81 81 async_sess_t *sess; 82 82 fibril_mutex_t comm_area_lock; … … 93 93 static int get_block_size(async_sess_t *, size_t *); 94 94 static int get_num_blocks(async_sess_t *, aoff64_t *); 95 static int read_toc(async_sess_t *, uint8_t);96 95 static aoff64_t ba_ltop(devcon_t *, aoff64_t); 97 96 98 static devcon_t *devcon_search(service_id_t service_id) 99 { 97 static devcon_t *devcon_search(devmap_handle_t devmap_handle) 98 { 99 link_t *cur; 100 100 101 fibril_mutex_lock(&dcl_lock); 101 102 102 list_foreach(dcl, cur) {103 for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) { 103 104 devcon_t *devcon = list_get_instance(cur, devcon_t, link); 104 if (devcon-> service_id == service_id) {105 if (devcon->devmap_handle == devmap_handle) { 105 106 fibril_mutex_unlock(&dcl_lock); 106 107 return devcon; … … 112 113 } 113 114 114 static int devcon_add( service_id_t service_id, async_sess_t *sess,115 static int devcon_add(devmap_handle_t devmap_handle, async_sess_t *sess, 115 116 size_t bsize, void *comm_area, size_t comm_size) 116 117 { 118 link_t *cur; 117 119 devcon_t *devcon; 118 120 … … 125 127 126 128 link_initialize(&devcon->link); 127 devcon-> service_id = service_id;129 devcon->devmap_handle = devmap_handle; 128 130 devcon->sess = sess; 129 131 fibril_mutex_initialize(&devcon->comm_area_lock); … … 136 138 137 139 fibril_mutex_lock(&dcl_lock); 138 list_foreach(dcl, cur) {140 for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) { 139 141 devcon_t *d = list_get_instance(cur, devcon_t, link); 140 if (d-> service_id == service_id) {142 if (d->devmap_handle == devmap_handle) { 141 143 fibril_mutex_unlock(&dcl_lock); 142 144 free(devcon); … … 144 146 } 145 147 } 146 list_append(&devcon->link, &dcl );148 list_append(&devcon->link, &dcl_head); 147 149 fibril_mutex_unlock(&dcl_lock); 148 150 return EOK; … … 156 158 } 157 159 158 int block_init(exch_mgmt_t mgmt, service_id_t service_id,160 int block_init(exch_mgmt_t mgmt, devmap_handle_t devmap_handle, 159 161 size_t comm_size) 160 162 { … … 164 166 return ENOMEM; 165 167 166 async_sess_t *sess = loc_service_connect(mgmt, service_id,168 async_sess_t *sess = devmap_device_connect(mgmt, devmap_handle, 167 169 IPC_FLAG_BLOCKING); 168 170 if (!sess) { … … 191 193 } 192 194 193 rc = devcon_add( service_id, sess, bsize, comm_area, comm_size);195 rc = devcon_add(devmap_handle, sess, bsize, comm_area, comm_size); 194 196 if (rc != EOK) { 195 197 munmap(comm_area, comm_size); … … 201 203 } 202 204 203 void block_fini( service_id_t service_id)204 { 205 devcon_t *devcon = devcon_search( service_id);205 void block_fini(devmap_handle_t devmap_handle) 206 { 207 devcon_t *devcon = devcon_search(devmap_handle); 206 208 assert(devcon); 207 209 208 210 if (devcon->cache) 209 (void) block_cache_fini( service_id);211 (void) block_cache_fini(devmap_handle); 210 212 211 213 devcon_remove(devcon); … … 220 222 } 221 223 222 int block_bb_read( service_id_t service_id, aoff64_t ba)224 int block_bb_read(devmap_handle_t devmap_handle, aoff64_t ba) 223 225 { 224 226 void *bb_buf; 225 227 int rc; 226 228 227 devcon_t *devcon = devcon_search( service_id);229 devcon_t *devcon = devcon_search(devmap_handle); 228 230 if (!devcon) 229 231 return ENOENT; … … 250 252 } 251 253 252 void *block_bb_get( service_id_t service_id)253 { 254 devcon_t *devcon = devcon_search( service_id);254 void *block_bb_get(devmap_handle_t devmap_handle) 255 { 256 devcon_t *devcon = devcon_search(devmap_handle); 255 257 assert(devcon); 256 258 return devcon->bb_buf; … … 259 261 static hash_index_t cache_hash(unsigned long *key) 260 262 { 261 return MERGE_LOUP32(key[0], key[1])& (CACHE_BUCKETS - 1);263 return *key & (CACHE_BUCKETS - 1); 262 264 } 263 265 … … 265 267 { 266 268 block_t *b = hash_table_get_instance(item, block_t, hash_link); 267 return b->lba == MERGE_LOUP32(key[0], key[1]);269 return b->lba == *key; 268 270 } 269 271 … … 278 280 }; 279 281 280 int block_cache_init( service_id_t service_id, size_t size, unsigned blocks,282 int block_cache_init(devmap_handle_t devmap_handle, size_t size, unsigned blocks, 281 283 enum cache_mode mode) 282 284 { 283 devcon_t *devcon = devcon_search( service_id);285 devcon_t *devcon = devcon_search(devmap_handle); 284 286 cache_t *cache; 285 287 if (!devcon) … … 292 294 293 295 fibril_mutex_initialize(&cache->lock); 294 list_initialize(&cache->free_ list);296 list_initialize(&cache->free_head); 295 297 cache->lblock_size = size; 296 298 cache->block_count = blocks; … … 306 308 cache->blocks_cluster = cache->lblock_size / devcon->pblock_size; 307 309 308 if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 2,310 if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 1, 309 311 &cache_ops)) { 310 312 free(cache); … … 316 318 } 317 319 318 int block_cache_fini( service_id_t service_id)319 { 320 devcon_t *devcon = devcon_search( service_id);320 int block_cache_fini(devmap_handle_t devmap_handle) 321 { 322 devcon_t *devcon = devcon_search(devmap_handle); 321 323 cache_t *cache; 322 324 int rc; … … 333 335 * bother with the cache and block locks because we are single-threaded. 334 336 */ 335 while (!list_empty(&cache->free_ list)) {336 block_t *b = list_get_instance( list_first(&cache->free_list),337 while (!list_empty(&cache->free_head)) { 338 block_t *b = list_get_instance(cache->free_head.next, 337 339 block_t, free_link); 338 340 … … 345 347 } 346 348 347 unsigned long key[2] = { 348 LOWER32(b->lba), 349 UPPER32(b->lba) 350 }; 351 hash_table_remove(&cache->block_hash, key, 2); 349 unsigned long key = b->lba; 350 hash_table_remove(&cache->block_hash, &key, 1); 352 351 353 352 free(b->data); … … 368 367 if (cache->blocks_cached < CACHE_LO_WATERMARK) 369 368 return true; 370 if (!list_empty(&cache->free_ list))369 if (!list_empty(&cache->free_head)) 371 370 return false; 372 371 return true; … … 388 387 * @param block Pointer to where the function will store the 389 388 * block pointer on success. 390 * @param service_id Service IDof the block device.389 * @param devmap_handle Device handle of the block device. 391 390 * @param ba Block address (logical). 392 391 * @param flags If BLOCK_FLAGS_NOREAD is specified, block_get() … … 396 395 * @return EOK on success or a negative error code. 397 396 */ 398 int block_get(block_t **block, service_id_t service_id, aoff64_t ba, int flags)397 int block_get(block_t **block, devmap_handle_t devmap_handle, aoff64_t ba, int flags) 399 398 { 400 399 devcon_t *devcon; … … 402 401 block_t *b; 403 402 link_t *l; 404 unsigned long key[2] = { 405 LOWER32(ba), 406 UPPER32(ba) 407 }; 408 403 unsigned long key = ba; 409 404 int rc; 410 405 411 devcon = devcon_search( service_id);406 devcon = devcon_search(devmap_handle); 412 407 413 408 assert(devcon); … … 421 416 422 417 fibril_mutex_lock(&cache->lock); 423 l = hash_table_find(&cache->block_hash, key);418 l = hash_table_find(&cache->block_hash, &key); 424 419 if (l) { 425 420 found: … … 459 454 * Try to recycle a block from the free list. 460 455 */ 456 unsigned long temp_key; 461 457 recycle: 462 if (list_empty(&cache->free_ list)) {458 if (list_empty(&cache->free_head)) { 463 459 fibril_mutex_unlock(&cache->lock); 464 460 rc = ENOMEM; 465 461 goto out; 466 462 } 467 l = list_first(&cache->free_list);463 l = cache->free_head.next; 468 464 b = list_get_instance(l, block_t, free_link); 469 465 … … 480 476 */ 481 477 list_remove(&b->free_link); 482 list_append(&b->free_link, &cache->free_ list);478 list_append(&b->free_link, &cache->free_head); 483 479 fibril_mutex_unlock(&cache->lock); 484 480 fibril_mutex_lock(&devcon->comm_area_lock); … … 506 502 goto retry; 507 503 } 508 l = hash_table_find(&cache->block_hash, key);504 l = hash_table_find(&cache->block_hash, &key); 509 505 if (l) { 510 506 /* … … 529 525 */ 530 526 list_remove(&b->free_link); 531 unsigned long temp_key[2] = { 532 LOWER32(b->lba), 533 UPPER32(b->lba) 534 }; 535 hash_table_remove(&cache->block_hash, temp_key, 2); 527 temp_key = b->lba; 528 hash_table_remove(&cache->block_hash, &temp_key, 1); 536 529 } 537 530 538 531 block_initialize(b); 539 b-> service_id = service_id;532 b->devmap_handle = devmap_handle; 540 533 b->size = cache->lblock_size; 541 534 b->lba = ba; 542 535 b->pba = ba_ltop(devcon, b->lba); 543 hash_table_insert(&cache->block_hash, key, &b->hash_link);536 hash_table_insert(&cache->block_hash, &key, &b->hash_link); 544 537 545 538 /* … … 587 580 int block_put(block_t *block) 588 581 { 589 devcon_t *devcon = devcon_search(block-> service_id);582 devcon_t *devcon = devcon_search(block->devmap_handle); 590 583 cache_t *cache; 591 584 unsigned blocks_cached; … … 653 646 * Take the block out of the cache and free it. 654 647 */ 655 unsigned long key[2] = { 656 LOWER32(block->lba), 657 UPPER32(block->lba) 658 }; 659 hash_table_remove(&cache->block_hash, key, 2); 648 unsigned long key = block->lba; 649 hash_table_remove(&cache->block_hash, &key, 1); 660 650 fibril_mutex_unlock(&block->lock); 661 651 free(block->data); … … 678 668 goto retry; 679 669 } 680 list_append(&block->free_link, &cache->free_ list);670 list_append(&block->free_link, &cache->free_head); 681 671 } 682 672 fibril_mutex_unlock(&block->lock); … … 688 678 /** Read sequential data from a block device. 689 679 * 690 * @param service_id Service IDof the block device.680 * @param devmap_handle Device handle of the block device. 691 681 * @param bufpos Pointer to the first unread valid offset within the 692 682 * communication buffer. … … 700 690 * @return EOK on success or a negative return code on failure. 701 691 */ 702 int block_seqread( service_id_t service_id, size_t *bufpos, size_t *buflen,692 int block_seqread(devmap_handle_t devmap_handle, size_t *bufpos, size_t *buflen, 703 693 aoff64_t *pos, void *dst, size_t size) 704 694 { … … 708 698 devcon_t *devcon; 709 699 710 devcon = devcon_search( service_id);700 devcon = devcon_search(devmap_handle); 711 701 assert(devcon); 712 702 block_size = devcon->pblock_size; … … 754 744 /** Read blocks directly from device (bypass cache). 755 745 * 756 * @param service_id Service IDof the block device.746 * @param devmap_handle Device handle of the block device. 757 747 * @param ba Address of first block (physical). 758 748 * @param cnt Number of blocks. … … 761 751 * @return EOK on success or negative error code on failure. 762 752 */ 763 int block_read_direct( service_id_t service_id, aoff64_t ba, size_t cnt, void *buf)753 int block_read_direct(devmap_handle_t devmap_handle, aoff64_t ba, size_t cnt, void *buf) 764 754 { 765 755 devcon_t *devcon; 766 756 int rc; 767 757 768 devcon = devcon_search( service_id);758 devcon = devcon_search(devmap_handle); 769 759 assert(devcon); 770 760 … … 782 772 /** Write blocks directly to device (bypass cache). 783 773 * 784 * @param service_id Service IDof the block device.774 * @param devmap_handle Device handle of the block device. 785 775 * @param ba Address of first block (physical). 786 776 * @param cnt Number of blocks. … … 789 779 * @return EOK on success or negative error code on failure. 790 780 */ 791 int block_write_direct( service_id_t service_id, aoff64_t ba, size_t cnt,781 int block_write_direct(devmap_handle_t devmap_handle, aoff64_t ba, size_t cnt, 792 782 const void *data) 793 783 { … … 795 785 int rc; 796 786 797 devcon = devcon_search( service_id);787 devcon = devcon_search(devmap_handle); 798 788 assert(devcon); 799 789 … … 810 800 /** Get device block size. 811 801 * 812 * @param service_id Service IDof the block device.802 * @param devmap_handle Device handle of the block device. 813 803 * @param bsize Output block size. 814 804 * 815 805 * @return EOK on success or negative error code on failure. 816 806 */ 817 int block_get_bsize( service_id_t service_id, size_t *bsize)807 int block_get_bsize(devmap_handle_t devmap_handle, size_t *bsize) 818 808 { 819 809 devcon_t *devcon; 820 810 821 devcon = devcon_search( service_id);811 devcon = devcon_search(devmap_handle); 822 812 assert(devcon); 823 813 … … 827 817 /** Get number of blocks on device. 828 818 * 829 * @param service_id Service IDof the block device.819 * @param devmap_handle Device handle of the block device. 830 820 * @param nblocks Output number of blocks. 831 821 * 832 822 * @return EOK on success or negative error code on failure. 833 823 */ 834 int block_get_nblocks( service_id_t service_id, aoff64_t *nblocks)835 { 836 devcon_t *devcon = devcon_search( service_id);824 int block_get_nblocks(devmap_handle_t devmap_handle, aoff64_t *nblocks) 825 { 826 devcon_t *devcon = devcon_search(devmap_handle); 837 827 assert(devcon); 838 828 … … 842 832 /** Read bytes directly from the device (bypass cache) 843 833 * 844 * @param service_id Service IDof the block device.834 * @param devmap_handle Device handle of the block device. 845 835 * @param abs_offset Absolute offset in bytes where to start reading 846 836 * @param bytes Number of bytes to read … … 849 839 * @return EOK on success or negative error code on failure. 850 840 */ 851 int block_read_bytes_direct( service_id_t service_id, aoff64_t abs_offset,841 int block_read_bytes_direct(devmap_handle_t devmap_handle, aoff64_t abs_offset, 852 842 size_t bytes, void *data) 853 843 { … … 861 851 size_t offset; 862 852 863 rc = block_get_bsize( service_id, &phys_block_size);853 rc = block_get_bsize(devmap_handle, &phys_block_size); 864 854 if (rc != EOK) { 865 855 return rc; … … 879 869 } 880 870 881 rc = block_read_direct( service_id, first_block, blocks, buffer);871 rc = block_read_direct(devmap_handle, first_block, blocks, buffer); 882 872 if (rc != EOK) { 883 873 free(buffer); … … 890 880 891 881 return EOK; 892 }893 894 /** Get TOC from device.895 *896 * @param service_id Service ID of the block device.897 * @param session Starting session.898 * @param data Buffer to read TOC into.899 *900 * @return EOK on success.901 * @return Error code on failure.902 *903 */904 int block_get_toc(service_id_t service_id, uint8_t session, void *data)905 {906 devcon_t *devcon = devcon_search(service_id);907 assert(devcon);908 909 fibril_mutex_lock(&devcon->comm_area_lock);910 911 int rc = read_toc(devcon->sess, session);912 if (rc == EOK)913 memcpy(data, devcon->comm_area, devcon->pblock_size);914 915 fibril_mutex_unlock(&devcon->comm_area_lock);916 917 return rc;918 882 } 919 883 … … 939 903 printf("Error %d reading %zu blocks starting at block %" PRIuOFF64 940 904 " from device handle %" PRIun "\n", rc, cnt, ba, 941 devcon-> service_id);905 devcon->devmap_handle); 942 906 #ifndef NDEBUG 943 907 stacktrace_print(); … … 968 932 if (rc != EOK) { 969 933 printf("Error %d writing %zu blocks starting at block %" PRIuOFF64 970 " to device handle %" PRIun "\n", rc, cnt, ba, devcon-> service_id);934 " to device handle %" PRIun "\n", rc, cnt, ba, devcon->devmap_handle); 971 935 #ifndef NDEBUG 972 936 stacktrace_print(); … … 1008 972 } 1009 973 1010 /** Get TOC from block device. */1011 static int read_toc(async_sess_t *sess, uint8_t session)1012 {1013 async_exch_t *exch = async_exchange_begin(sess);1014 int rc = async_req_1_0(exch, BD_READ_TOC, session);1015 async_exchange_end(exch);1016 1017 return rc;1018 }1019 1020 974 /** Convert logical block address to physical block address. */ 1021 975 static aoff64_t ba_ltop(devcon_t *devcon, aoff64_t lba)
Note:
See TracChangeset
for help on using the changeset viewer.