Changes in uspace/lib/libblock/libblock.c [08232ee:7a56b1ed] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libblock/libblock.c
r08232ee r7a56b1ed 47 47 #include <as.h> 48 48 #include <assert.h> 49 #include <fibril_sync h.h>49 #include <fibril_sync.h> 50 50 #include <adt/list.h> 51 51 #include <adt/hash_table.h> 52 #include <macros.h>53 52 #include <mem.h> 54 53 … … 63 62 typedef struct { 64 63 fibril_mutex_t lock; 65 size_t lblock_size; /**< Logical block size. */64 size_t block_size; /**< Block size. */ 66 65 unsigned block_count; /**< Total number of blocks. */ 67 66 unsigned blocks_cached; /**< Number of cached blocks. */ … … 75 74 dev_handle_t dev_handle; 76 75 int dev_phone; 77 fibril_mutex_t com m_area_lock;78 void *com m_area;79 size_t com m_size;76 fibril_mutex_t com_area_lock; 77 void *com_area; 78 size_t com_size; 80 79 void *bb_buf; 81 bn_t bb_addr;82 size_t pblock_size; /**< Physical block size. */80 off_t bb_off; 81 size_t bb_size; 83 82 cache_t *cache; 84 83 } devcon_t; 85 84 86 static int read_blocks(devcon_t *devcon, bn_t ba, size_t cnt); 87 static int write_blocks(devcon_t *devcon, bn_t ba, size_t cnt); 88 static int get_block_size(int dev_phone, size_t *bsize); 89 static int get_num_blocks(int dev_phone, bn_t *nblocks); 85 static int read_block(devcon_t *devcon, bn_t boff, size_t block_size); 86 static int write_block(devcon_t *devcon, bn_t boff, size_t block_size); 90 87 91 88 static devcon_t *devcon_search(dev_handle_t dev_handle) … … 105 102 } 106 103 107 static int devcon_add(dev_handle_t dev_handle, int dev_phone, size_t bsize,108 void *comm_area, size_t comm_size)104 static int devcon_add(dev_handle_t dev_handle, int dev_phone, void *com_area, 105 size_t com_size) 109 106 { 110 107 link_t *cur; 111 108 devcon_t *devcon; 112 113 if (comm_size < bsize)114 return EINVAL;115 109 116 110 devcon = malloc(sizeof(devcon_t)); … … 121 115 devcon->dev_handle = dev_handle; 122 116 devcon->dev_phone = dev_phone; 123 fibril_mutex_initialize(&devcon->com m_area_lock);124 devcon->com m_area = comm_area;125 devcon->com m_size = comm_size;117 fibril_mutex_initialize(&devcon->com_area_lock); 118 devcon->com_area = com_area; 119 devcon->com_size = com_size; 126 120 devcon->bb_buf = NULL; 127 devcon->bb_ addr= 0;128 devcon-> pblock_size = bsize;121 devcon->bb_off = 0; 122 devcon->bb_size = 0; 129 123 devcon->cache = NULL; 130 124 … … 150 144 } 151 145 152 int block_init(dev_handle_t dev_handle, size_t com m_size)146 int block_init(dev_handle_t dev_handle, size_t com_size) 153 147 { 154 148 int rc; 155 149 int dev_phone; 156 void *comm_area; 157 size_t bsize; 158 159 comm_area = mmap(NULL, comm_size, PROTO_READ | PROTO_WRITE, 150 void *com_area; 151 152 com_area = mmap(NULL, com_size, PROTO_READ | PROTO_WRITE, 160 153 MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); 161 if (!com m_area) {154 if (!com_area) { 162 155 return ENOMEM; 163 156 } … … 165 158 dev_phone = devmap_device_connect(dev_handle, IPC_FLAG_BLOCKING); 166 159 if (dev_phone < 0) { 167 munmap(com m_area, comm_size);160 munmap(com_area, com_size); 168 161 return dev_phone; 169 162 } 170 163 171 rc = async_share_out_start(dev_phone, comm_area,164 rc = ipc_share_out_start(dev_phone, com_area, 172 165 AS_AREA_READ | AS_AREA_WRITE); 173 166 if (rc != EOK) { 174 munmap(com m_area, comm_size);167 munmap(com_area, com_size); 175 168 ipc_hangup(dev_phone); 176 169 return rc; 177 170 } 178 179 if (get_block_size(dev_phone, &bsize) != EOK) { 180 munmap(comm_area, comm_size); 181 ipc_hangup(dev_phone); 182 return rc; 183 } 184 185 rc = devcon_add(dev_handle, dev_phone, bsize, comm_area, comm_size); 171 172 rc = devcon_add(dev_handle, dev_phone, com_area, com_size); 186 173 if (rc != EOK) { 187 munmap(com m_area, comm_size);174 munmap(com_area, com_size); 188 175 ipc_hangup(dev_phone); 189 176 return rc; … … 208 195 } 209 196 210 munmap(devcon->com m_area, devcon->comm_size);197 munmap(devcon->com_area, devcon->com_size); 211 198 ipc_hangup(devcon->dev_phone); 212 199 … … 214 201 } 215 202 216 int block_bb_read(dev_handle_t dev_handle, bn_t ba)203 int block_bb_read(dev_handle_t dev_handle, off_t off, size_t size) 217 204 { 218 205 void *bb_buf; … … 224 211 if (devcon->bb_buf) 225 212 return EEXIST; 226 bb_buf = malloc( devcon->pblock_size);213 bb_buf = malloc(size); 227 214 if (!bb_buf) 228 215 return ENOMEM; 229 230 fibril_mutex_lock(&devcon->com m_area_lock);231 rc = read_block s(devcon, 0, 1);216 217 fibril_mutex_lock(&devcon->com_area_lock); 218 rc = read_block(devcon, 0, size); 232 219 if (rc != EOK) { 233 fibril_mutex_unlock(&devcon->com m_area_lock);220 fibril_mutex_unlock(&devcon->com_area_lock); 234 221 free(bb_buf); 235 222 return rc; 236 223 } 237 memcpy(bb_buf, devcon->com m_area, devcon->pblock_size);238 fibril_mutex_unlock(&devcon->com m_area_lock);224 memcpy(bb_buf, devcon->com_area, size); 225 fibril_mutex_unlock(&devcon->com_area_lock); 239 226 240 227 devcon->bb_buf = bb_buf; 241 devcon->bb_addr = ba; 228 devcon->bb_off = off; 229 devcon->bb_size = size; 242 230 243 231 return EOK; … … 287 275 fibril_mutex_initialize(&cache->lock); 288 276 list_initialize(&cache->free_head); 289 cache-> lblock_size = size;277 cache->block_size = size; 290 278 cache->block_count = blocks; 291 279 cache->blocks_cached = 0; 292 280 cache->mode = mode; 293 294 /* No block size translation a.t.m. */295 assert(cache->lblock_size == devcon->pblock_size);296 281 297 282 if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 1, … … 386 371 if (!b) 387 372 goto recycle; 388 b->data = malloc(cache-> lblock_size);373 b->data = malloc(cache->block_size); 389 374 if (!b->data) { 390 375 free(b); … … 420 405 list_append(&b->free_link, &cache->free_head); 421 406 fibril_mutex_unlock(&cache->lock); 422 fibril_mutex_lock(&devcon->comm_area_lock); 423 memcpy(devcon->comm_area, b->data, b->size); 424 rc = write_blocks(devcon, b->boff, 1); 425 fibril_mutex_unlock(&devcon->comm_area_lock); 407 fibril_mutex_lock(&devcon->com_area_lock); 408 memcpy(devcon->com_area, b->data, b->size); 409 rc = write_block(devcon, b->boff, 410 cache->block_size); 411 fibril_mutex_unlock(&devcon->com_area_lock); 426 412 if (rc != EOK) { 427 413 /* … … 458 444 block_initialize(b); 459 445 b->dev_handle = dev_handle; 460 b->size = cache-> lblock_size;446 b->size = cache->block_size; 461 447 b->boff = boff; 462 448 hash_table_insert(&cache->block_hash, &key, &b->hash_link); … … 475 461 * the new contents from the device. 476 462 */ 477 fibril_mutex_lock(&devcon->com m_area_lock);478 rc = read_block s(devcon, b->boff, 1);479 memcpy(b->data, devcon->com m_area, cache->lblock_size);480 fibril_mutex_unlock(&devcon->com m_area_lock);463 fibril_mutex_lock(&devcon->com_area_lock); 464 rc = read_block(devcon, b->boff, cache->block_size); 465 memcpy(b->data, devcon->com_area, cache->block_size); 466 fibril_mutex_unlock(&devcon->com_area_lock); 481 467 if (rc != EOK) 482 468 b->toxic = true; … … 535 521 if (block->dirty && (block->refcnt == 1) && 536 522 (blocks_cached > CACHE_HI_WATERMARK || mode != CACHE_MODE_WB)) { 537 fibril_mutex_lock(&devcon->com m_area_lock);538 memcpy(devcon->com m_area, block->data, block->size);539 rc = write_block s(devcon, block->boff, 1);540 fibril_mutex_unlock(&devcon->com m_area_lock);523 fibril_mutex_lock(&devcon->com_area_lock); 524 memcpy(devcon->com_area, block->data, block->size); 525 rc = write_block(devcon, block->boff, block->size); 526 fibril_mutex_unlock(&devcon->com_area_lock); 541 527 block->dirty = false; 542 528 } … … 615 601 */ 616 602 int block_seqread(dev_handle_t dev_handle, off_t *bufpos, size_t *buflen, 617 off_t *pos, void *dst, size_t size )603 off_t *pos, void *dst, size_t size, size_t block_size) 618 604 { 619 605 off_t offset = 0; 620 606 size_t left = size; 621 size_t block_size; 622 devcon_t *devcon; 623 624 devcon = devcon_search(dev_handle); 607 devcon_t *devcon = devcon_search(dev_handle); 625 608 assert(devcon); 626 block_size = devcon->pblock_size; 627 628 fibril_mutex_lock(&devcon->comm_area_lock); 609 610 fibril_mutex_lock(&devcon->com_area_lock); 629 611 while (left > 0) { 630 612 size_t rd; … … 640 622 * destination buffer. 641 623 */ 642 memcpy(dst + offset, devcon->com m_area + *bufpos, rd);624 memcpy(dst + offset, devcon->com_area + *bufpos, rd); 643 625 offset += rd; 644 626 *bufpos += rd; … … 651 633 int rc; 652 634 653 rc = read_block s(devcon, *pos / block_size, 1);635 rc = read_block(devcon, *pos / block_size, block_size); 654 636 if (rc != EOK) { 655 fibril_mutex_unlock(&devcon->com m_area_lock);637 fibril_mutex_unlock(&devcon->com_area_lock); 656 638 return rc; 657 639 } … … 661 643 } 662 644 } 663 fibril_mutex_unlock(&devcon->com m_area_lock);645 fibril_mutex_unlock(&devcon->com_area_lock); 664 646 665 647 return EOK; 666 648 } 667 649 668 /** Read block s directly from device (bypass cache).669 * 670 * @param dev _handle Device handle of the block device.671 * @param b a Address of first block.672 * @param cnt Number of blocks.650 /** Read block from block device. 651 * 652 * @param devcon Device connection. 653 * @param boff Block index. 654 * @param block_size Block size. 673 655 * @param src Buffer for storing the data. 674 656 * 675 657 * @return EOK on success or negative error code on failure. 676 658 */ 677 int block_read_direct(dev_handle_t dev_handle, bn_t ba, size_t cnt, void *buf)678 { 679 devcon_t *devcon;659 static int read_block(devcon_t *devcon, bn_t boff, size_t block_size) 660 { 661 ipcarg_t retval; 680 662 int rc; 681 663 682 devcon = devcon_search(dev_handle);683 664 assert(devcon); 684 685 fibril_mutex_lock(&devcon->comm_area_lock); 686 687 rc = read_blocks(devcon, ba, cnt); 688 if (rc == EOK) 689 memcpy(buf, devcon->comm_area, devcon->pblock_size * cnt); 690 691 fibril_mutex_unlock(&devcon->comm_area_lock); 692 693 return rc; 694 } 695 696 /** Write blocks directly to device (bypass cache). 697 * 698 * @param dev_handle Device handle of the block device. 699 * @param ba Address of first block. 700 * @param cnt Number of blocks. 701 * @param src The data to be written. 665 rc = async_req_2_1(devcon->dev_phone, BD_READ_BLOCK, boff, block_size, 666 &retval); 667 if ((rc != EOK) || (retval != EOK)) 668 return (rc != EOK ? rc : (int) retval); 669 670 return EOK; 671 } 672 673 /** Write block to block device. 674 * 675 * @param devcon Device connection. 676 * @param boff Block index. 677 * @param block_size Block size. 678 * @param src Buffer containing the data to write. 702 679 * 703 680 * @return EOK on success or negative error code on failure. 704 681 */ 705 int block_write_direct(dev_handle_t dev_handle, bn_t ba, size_t cnt, 706 const void *data) 707 { 708 devcon_t *devcon; 682 static int write_block(devcon_t *devcon, bn_t boff, size_t block_size) 683 { 684 ipcarg_t retval; 709 685 int rc; 710 686 711 devcon = devcon_search(dev_handle);712 687 assert(devcon); 713 714 fibril_mutex_lock(&devcon->comm_area_lock); 715 716 memcpy(devcon->comm_area, data, devcon->pblock_size * cnt); 717 rc = write_blocks(devcon, ba, cnt); 718 719 fibril_mutex_unlock(&devcon->comm_area_lock); 720 721 return rc; 722 } 723 724 /** Get device block size. 725 * 726 * @param dev_handle Device handle of the block device. 727 * @param bsize Output block size. 728 * 729 * @return EOK on success or negative error code on failure. 730 */ 731 int block_get_bsize(dev_handle_t dev_handle, size_t *bsize) 732 { 733 devcon_t *devcon; 734 735 devcon = devcon_search(dev_handle); 736 assert(devcon); 737 738 return get_block_size(devcon->dev_phone, bsize); 739 } 740 741 /** Get number of blocks on device. 742 * 743 * @param dev_handle Device handle of the block device. 744 * @param nblocks Output number of blocks. 745 * 746 * @return EOK on success or negative error code on failure. 747 */ 748 int block_get_nblocks(dev_handle_t dev_handle, bn_t *nblocks) 749 { 750 devcon_t *devcon; 751 752 devcon = devcon_search(dev_handle); 753 assert(devcon); 754 755 return get_num_blocks(devcon->dev_phone, nblocks); 756 } 757 758 /** Read blocks from block device. 759 * 760 * @param devcon Device connection. 761 * @param ba Address of first block. 762 * @param cnt Number of blocks. 763 * @param src Buffer for storing the data. 764 * 765 * @return EOK on success or negative error code on failure. 766 */ 767 static int read_blocks(devcon_t *devcon, bn_t ba, size_t cnt) 768 { 769 int rc; 770 771 assert(devcon); 772 rc = async_req_3_0(devcon->dev_phone, BD_READ_BLOCKS, LOWER32(ba), 773 UPPER32(ba), cnt); 774 return rc; 775 } 776 777 /** Write block to block device. 778 * 779 * @param devcon Device connection. 780 * @param ba Address of first block. 781 * @param cnt Number of blocks. 782 * @param src Buffer containing the data to write. 783 * 784 * @return EOK on success or negative error code on failure. 785 */ 786 static int write_blocks(devcon_t *devcon, bn_t ba, size_t cnt) 787 { 788 int rc; 789 790 assert(devcon); 791 rc = async_req_3_0(devcon->dev_phone, BD_WRITE_BLOCKS, LOWER32(ba), 792 UPPER32(ba), cnt); 793 return rc; 794 } 795 796 /** Get block size used by the device. */ 797 static int get_block_size(int dev_phone, size_t *bsize) 798 { 799 ipcarg_t bs; 800 int rc; 801 802 rc = async_req_0_1(dev_phone, BD_GET_BLOCK_SIZE, &bs); 803 if (rc == EOK) 804 *bsize = (size_t) bs; 805 806 return rc; 807 } 808 809 /** Get total number of blocks on block device. */ 810 static int get_num_blocks(int dev_phone, bn_t *nblocks) 811 { 812 ipcarg_t nb_l, nb_h; 813 int rc; 814 815 rc = async_req_0_2(dev_phone, BD_GET_NUM_BLOCKS, &nb_l, &nb_h); 816 if (rc == EOK) { 817 *nblocks = (bn_t) MERGE_LOUP32(nb_l, nb_h); 818 } 819 820 return rc; 688 rc = async_req_2_1(devcon->dev_phone, BD_WRITE_BLOCK, boff, block_size, 689 &retval); 690 if ((rc != EOK) || (retval != EOK)) 691 return (rc != EOK ? rc : (int) retval); 692 693 return EOK; 821 694 } 822 695
Note:
See TracChangeset
for help on using the changeset viewer.