Changeset b5e68c8 in mainline for uspace/lib/block/libblock.c
- Timestamp:
- 2011-05-12T16:49:44Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f36787d7
- Parents:
- e80329d6 (diff), 750636a (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. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/block/libblock.c
re80329d6 rb5e68c8 44 44 #include <sys/mman.h> 45 45 #include <async.h> 46 #include <ipc/ipc.h>47 46 #include <as.h> 48 47 #include <assert.h> … … 52 51 #include <macros.h> 53 52 #include <mem.h> 53 #include <malloc.h> 54 #include <stdio.h> 54 55 #include <sys/typefmt.h> 55 56 #include <stacktrace.h> … … 66 67 fibril_mutex_t lock; 67 68 size_t lblock_size; /**< Logical block size. */ 69 unsigned blocks_cluster; /**< Physical blocks per block_t */ 68 70 unsigned block_count; /**< Total number of blocks. */ 69 71 unsigned blocks_cached; /**< Number of cached blocks. */ … … 75 77 typedef struct { 76 78 link_t link; 77 dev _handle_t dev_handle;79 devmap_handle_t devmap_handle; 78 80 int dev_phone; 79 81 fibril_mutex_t comm_area_lock; … … 90 92 static int get_block_size(int dev_phone, size_t *bsize); 91 93 static int get_num_blocks(int dev_phone, aoff64_t *nblocks); 92 93 static devcon_t *devcon_search(dev_handle_t dev_handle) 94 static aoff64_t ba_ltop(devcon_t *devcon, aoff64_t lba); 95 96 static devcon_t *devcon_search(devmap_handle_t devmap_handle) 94 97 { 95 98 link_t *cur; … … 98 101 for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) { 99 102 devcon_t *devcon = list_get_instance(cur, devcon_t, link); 100 if (devcon->dev _handle == dev_handle) {103 if (devcon->devmap_handle == devmap_handle) { 101 104 fibril_mutex_unlock(&dcl_lock); 102 105 return devcon; … … 107 110 } 108 111 109 static int devcon_add(dev _handle_t dev_handle, int dev_phone, size_t bsize,112 static int devcon_add(devmap_handle_t devmap_handle, int dev_phone, size_t bsize, 110 113 void *comm_area, size_t comm_size) 111 114 { … … 121 124 122 125 link_initialize(&devcon->link); 123 devcon->dev _handle = dev_handle;126 devcon->devmap_handle = devmap_handle; 124 127 devcon->dev_phone = dev_phone; 125 128 fibril_mutex_initialize(&devcon->comm_area_lock); … … 134 137 for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) { 135 138 devcon_t *d = list_get_instance(cur, devcon_t, link); 136 if (d->dev _handle == dev_handle) {139 if (d->devmap_handle == devmap_handle) { 137 140 fibril_mutex_unlock(&dcl_lock); 138 141 free(devcon); … … 152 155 } 153 156 154 int block_init(dev _handle_t dev_handle, size_t comm_size)157 int block_init(devmap_handle_t devmap_handle, size_t comm_size) 155 158 { 156 159 int rc; … … 165 168 } 166 169 167 dev_phone = devmap_device_connect(dev _handle, IPC_FLAG_BLOCKING);170 dev_phone = devmap_device_connect(devmap_handle, IPC_FLAG_BLOCKING); 168 171 if (dev_phone < 0) { 169 172 munmap(comm_area, comm_size); … … 175 178 if (rc != EOK) { 176 179 munmap(comm_area, comm_size); 177 ipc_hangup(dev_phone);180 async_hangup(dev_phone); 178 181 return rc; 179 182 } … … 181 184 if (get_block_size(dev_phone, &bsize) != EOK) { 182 185 munmap(comm_area, comm_size); 183 ipc_hangup(dev_phone);186 async_hangup(dev_phone); 184 187 return rc; 185 188 } 186 189 187 rc = devcon_add(dev _handle, dev_phone, bsize, comm_area, comm_size);190 rc = devcon_add(devmap_handle, dev_phone, bsize, comm_area, comm_size); 188 191 if (rc != EOK) { 189 192 munmap(comm_area, comm_size); 190 ipc_hangup(dev_phone);193 async_hangup(dev_phone); 191 194 return rc; 192 195 } … … 195 198 } 196 199 197 void block_fini(dev _handle_t dev_handle)198 { 199 devcon_t *devcon = devcon_search(dev _handle);200 void block_fini(devmap_handle_t devmap_handle) 201 { 202 devcon_t *devcon = devcon_search(devmap_handle); 200 203 assert(devcon); 201 204 202 205 if (devcon->cache) 203 (void) block_cache_fini(dev _handle);206 (void) block_cache_fini(devmap_handle); 204 207 205 208 devcon_remove(devcon); … … 209 212 210 213 munmap(devcon->comm_area, devcon->comm_size); 211 ipc_hangup(devcon->dev_phone);214 async_hangup(devcon->dev_phone); 212 215 213 216 free(devcon); 214 217 } 215 218 216 int block_bb_read(dev _handle_t dev_handle, aoff64_t ba)219 int block_bb_read(devmap_handle_t devmap_handle, aoff64_t ba) 217 220 { 218 221 void *bb_buf; 219 222 int rc; 220 223 221 devcon_t *devcon = devcon_search(dev _handle);224 devcon_t *devcon = devcon_search(devmap_handle); 222 225 if (!devcon) 223 226 return ENOENT; … … 244 247 } 245 248 246 void *block_bb_get(dev _handle_t dev_handle)247 { 248 devcon_t *devcon = devcon_search(dev _handle);249 void *block_bb_get(devmap_handle_t devmap_handle) 250 { 251 devcon_t *devcon = devcon_search(devmap_handle); 249 252 assert(devcon); 250 253 return devcon->bb_buf; … … 259 262 { 260 263 block_t *b = hash_table_get_instance(item, block_t, hash_link); 261 return b-> boff== *key;264 return b->lba == *key; 262 265 } 263 266 … … 272 275 }; 273 276 274 int block_cache_init(dev _handle_t dev_handle, size_t size, unsigned blocks,277 int block_cache_init(devmap_handle_t devmap_handle, size_t size, unsigned blocks, 275 278 enum cache_mode mode) 276 279 { 277 devcon_t *devcon = devcon_search(dev _handle);280 devcon_t *devcon = devcon_search(devmap_handle); 278 281 cache_t *cache; 279 282 if (!devcon) … … 292 295 cache->mode = mode; 293 296 294 /* No block size translation a.t.m. */ 295 assert(cache->lblock_size == devcon->pblock_size); 297 /* Allow 1:1 or small-to-large block size translation */ 298 if (cache->lblock_size % devcon->pblock_size != 0) { 299 free(cache); 300 return ENOTSUP; 301 } 302 303 cache->blocks_cluster = cache->lblock_size / devcon->pblock_size; 296 304 297 305 if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 1, … … 305 313 } 306 314 307 int block_cache_fini(dev _handle_t dev_handle)308 { 309 devcon_t *devcon = devcon_search(dev _handle);315 int block_cache_fini(devmap_handle_t devmap_handle) 316 { 317 devcon_t *devcon = devcon_search(devmap_handle); 310 318 cache_t *cache; 311 319 int rc; … … 329 337 if (b->dirty) { 330 338 memcpy(devcon->comm_area, b->data, b->size); 331 rc = write_blocks(devcon, b-> boff, 1);339 rc = write_blocks(devcon, b->pba, cache->blocks_cluster); 332 340 if (rc != EOK) 333 341 return rc; 334 342 } 335 343 336 unsigned long key = b-> boff;344 unsigned long key = b->lba; 337 345 hash_table_remove(&cache->block_hash, &key, 1); 338 346 … … 374 382 * @param block Pointer to where the function will store the 375 383 * block pointer on success. 376 * @param dev _handle Device handle of the block device.377 * @param b off Block offset.384 * @param devmap_handle Device handle of the block device. 385 * @param ba Block address (logical). 378 386 * @param flags If BLOCK_FLAGS_NOREAD is specified, block_get() 379 387 * will not read the contents of the block from the … … 382 390 * @return EOK on success or a negative error code. 383 391 */ 384 int block_get(block_t **block, dev _handle_t dev_handle, aoff64_t boff, int flags)392 int block_get(block_t **block, devmap_handle_t devmap_handle, aoff64_t ba, int flags) 385 393 { 386 394 devcon_t *devcon; … … 388 396 block_t *b; 389 397 link_t *l; 390 unsigned long key = b off;398 unsigned long key = ba; 391 399 int rc; 392 400 393 devcon = devcon_search(dev _handle);401 devcon = devcon_search(devmap_handle); 394 402 395 403 assert(devcon); … … 405 413 l = hash_table_find(&cache->block_hash, &key); 406 414 if (l) { 415 found: 407 416 /* 408 417 * We found the block in the cache. … … 432 441 if (!b->data) { 433 442 free(b); 443 b = NULL; 434 444 goto recycle; 435 445 } … … 465 475 fibril_mutex_lock(&devcon->comm_area_lock); 466 476 memcpy(devcon->comm_area, b->data, b->size); 467 rc = write_blocks(devcon, b->boff, 1); 477 rc = write_blocks(devcon, b->pba, 478 cache->blocks_cluster); 468 479 fibril_mutex_unlock(&devcon->comm_area_lock); 469 480 if (rc != EOK) { … … 486 497 goto retry; 487 498 } 499 l = hash_table_find(&cache->block_hash, &key); 500 if (l) { 501 /* 502 * Someone else must have already 503 * instantiated the block while we were 504 * not holding the cache lock. 505 * Leave the recycled block on the 506 * freelist and continue as if we 507 * found the block of interest during 508 * the first try. 509 */ 510 fibril_mutex_unlock(&b->lock); 511 goto found; 512 } 488 513 489 514 } … … 495 520 */ 496 521 list_remove(&b->free_link); 497 temp_key = b-> boff;522 temp_key = b->lba; 498 523 hash_table_remove(&cache->block_hash, &temp_key, 1); 499 524 } 500 525 501 526 block_initialize(b); 502 b->dev _handle = dev_handle;527 b->devmap_handle = devmap_handle; 503 528 b->size = cache->lblock_size; 504 b->boff = boff; 529 b->lba = ba; 530 b->pba = ba_ltop(devcon, b->lba); 505 531 hash_table_insert(&cache->block_hash, &key, &b->hash_link); 506 532 … … 519 545 */ 520 546 fibril_mutex_lock(&devcon->comm_area_lock); 521 rc = read_blocks(devcon, b-> boff, 1);547 rc = read_blocks(devcon, b->pba, cache->blocks_cluster); 522 548 memcpy(b->data, devcon->comm_area, cache->lblock_size); 523 549 fibril_mutex_unlock(&devcon->comm_area_lock); … … 549 575 int block_put(block_t *block) 550 576 { 551 devcon_t *devcon = devcon_search(block->dev _handle);577 devcon_t *devcon = devcon_search(block->devmap_handle); 552 578 cache_t *cache; 553 579 unsigned blocks_cached; … … 557 583 assert(devcon); 558 584 assert(devcon->cache); 585 assert(block->refcnt >= 1); 559 586 560 587 cache = devcon->cache; … … 580 607 fibril_mutex_lock(&devcon->comm_area_lock); 581 608 memcpy(devcon->comm_area, block->data, block->size); 582 rc = write_blocks(devcon, block-> boff, 1);609 rc = write_blocks(devcon, block->pba, cache->blocks_cluster); 583 610 fibril_mutex_unlock(&devcon->comm_area_lock); 584 611 block->dirty = false; … … 614 641 * Take the block out of the cache and free it. 615 642 */ 616 unsigned long key = block-> boff;643 unsigned long key = block->lba; 617 644 hash_table_remove(&cache->block_hash, &key, 1); 645 fibril_mutex_unlock(&block->lock); 646 free(block->data); 618 647 free(block); 619 free(block->data);620 648 cache->blocks_cached--; 621 649 fibril_mutex_unlock(&cache->lock); … … 645 673 /** Read sequential data from a block device. 646 674 * 647 * @param dev _handle Device handle of the block device.675 * @param devmap_handle Device handle of the block device. 648 676 * @param bufpos Pointer to the first unread valid offset within the 649 677 * communication buffer. … … 657 685 * @return EOK on success or a negative return code on failure. 658 686 */ 659 int block_seqread(dev _handle_t dev_handle, size_t *bufpos, size_t *buflen,687 int block_seqread(devmap_handle_t devmap_handle, size_t *bufpos, size_t *buflen, 660 688 aoff64_t *pos, void *dst, size_t size) 661 689 { … … 665 693 devcon_t *devcon; 666 694 667 devcon = devcon_search(dev _handle);695 devcon = devcon_search(devmap_handle); 668 696 assert(devcon); 669 697 block_size = devcon->pblock_size; … … 711 739 /** Read blocks directly from device (bypass cache). 712 740 * 713 * @param dev _handle Device handle of the block device.714 * @param ba Address of first block .741 * @param devmap_handle Device handle of the block device. 742 * @param ba Address of first block (physical). 715 743 * @param cnt Number of blocks. 716 744 * @param src Buffer for storing the data. … … 718 746 * @return EOK on success or negative error code on failure. 719 747 */ 720 int block_read_direct(dev _handle_t dev_handle, aoff64_t ba, size_t cnt, void *buf)748 int block_read_direct(devmap_handle_t devmap_handle, aoff64_t ba, size_t cnt, void *buf) 721 749 { 722 750 devcon_t *devcon; 723 751 int rc; 724 752 725 devcon = devcon_search(dev _handle);753 devcon = devcon_search(devmap_handle); 726 754 assert(devcon); 727 755 … … 739 767 /** Write blocks directly to device (bypass cache). 740 768 * 741 * @param dev _handle Device handle of the block device.742 * @param ba Address of first block .769 * @param devmap_handle Device handle of the block device. 770 * @param ba Address of first block (physical). 743 771 * @param cnt Number of blocks. 744 772 * @param src The data to be written. … … 746 774 * @return EOK on success or negative error code on failure. 747 775 */ 748 int block_write_direct(dev _handle_t dev_handle, aoff64_t ba, size_t cnt,776 int block_write_direct(devmap_handle_t devmap_handle, aoff64_t ba, size_t cnt, 749 777 const void *data) 750 778 { … … 752 780 int rc; 753 781 754 devcon = devcon_search(dev _handle);782 devcon = devcon_search(devmap_handle); 755 783 assert(devcon); 756 784 … … 767 795 /** Get device block size. 768 796 * 769 * @param dev _handle Device handle of the block device.797 * @param devmap_handle Device handle of the block device. 770 798 * @param bsize Output block size. 771 799 * 772 800 * @return EOK on success or negative error code on failure. 773 801 */ 774 int block_get_bsize(dev _handle_t dev_handle, size_t *bsize)802 int block_get_bsize(devmap_handle_t devmap_handle, size_t *bsize) 775 803 { 776 804 devcon_t *devcon; 777 805 778 devcon = devcon_search(dev _handle);806 devcon = devcon_search(devmap_handle); 779 807 assert(devcon); 780 808 … … 784 812 /** Get number of blocks on device. 785 813 * 786 * @param dev _handle Device handle of the block device.814 * @param devmap_handle Device handle of the block device. 787 815 * @param nblocks Output number of blocks. 788 816 * 789 817 * @return EOK on success or negative error code on failure. 790 818 */ 791 int block_get_nblocks(dev _handle_t dev_handle, aoff64_t *nblocks)819 int block_get_nblocks(devmap_handle_t devmap_handle, aoff64_t *nblocks) 792 820 { 793 821 devcon_t *devcon; 794 822 795 devcon = devcon_search(dev _handle);823 devcon = devcon_search(devmap_handle); 796 824 assert(devcon); 797 825 … … 816 844 UPPER32(ba), cnt); 817 845 if (rc != EOK) { 818 printf("Error %d reading % dblocks starting at block %" PRIuOFF64819 " from device handle % d\n", rc, cnt, ba,820 devcon->dev _handle);846 printf("Error %d reading %zu blocks starting at block %" PRIuOFF64 847 " from device handle %" PRIun "\n", rc, cnt, ba, 848 devcon->devmap_handle); 821 849 #ifndef NDEBUG 822 850 stacktrace_print(); … … 843 871 UPPER32(ba), cnt); 844 872 if (rc != EOK) { 845 printf("Error %d writing % dblocks starting at block %" PRIuOFF64846 " to device handle % d\n", rc, cnt, ba, devcon->dev_handle);873 printf("Error %d writing %zu blocks starting at block %" PRIuOFF64 874 " to device handle %" PRIun "\n", rc, cnt, ba, devcon->devmap_handle); 847 875 #ifndef NDEBUG 848 876 stacktrace_print(); … … 855 883 static int get_block_size(int dev_phone, size_t *bsize) 856 884 { 857 ipcarg_t bs;885 sysarg_t bs; 858 886 int rc; 859 887 … … 868 896 static int get_num_blocks(int dev_phone, aoff64_t *nblocks) 869 897 { 870 ipcarg_t nb_l, nb_h;898 sysarg_t nb_l, nb_h; 871 899 int rc; 872 900 … … 879 907 } 880 908 909 /** Convert logical block address to physical block address. */ 910 static aoff64_t ba_ltop(devcon_t *devcon, aoff64_t lba) 911 { 912 assert(devcon->cache != NULL); 913 return lba * devcon->cache->blocks_cluster; 914 } 915 881 916 /** @} 882 917 */
Note:
See TracChangeset
for help on using the changeset viewer.