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