Changes in uspace/lib/libblock/libblock.c [00b1d20e:7a56b1ed] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/libblock/libblock.c
r00b1d20e r7a56b1ed 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); 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); 89 87 90 88 static devcon_t *devcon_search(dev_handle_t dev_handle) … … 104 102 } 105 103 106 static int devcon_add(dev_handle_t dev_handle, int dev_phone, size_t bsize,107 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) 108 106 { 109 107 link_t *cur; 110 108 devcon_t *devcon; 111 112 if (comm_size < bsize)113 return EINVAL;114 109 115 110 devcon = malloc(sizeof(devcon_t)); … … 120 115 devcon->dev_handle = dev_handle; 121 116 devcon->dev_phone = dev_phone; 122 fibril_mutex_initialize(&devcon->com m_area_lock);123 devcon->com m_area = comm_area;124 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; 125 120 devcon->bb_buf = NULL; 126 devcon->bb_ addr= 0;127 devcon-> pblock_size = bsize;121 devcon->bb_off = 0; 122 devcon->bb_size = 0; 128 123 devcon->cache = NULL; 129 124 … … 149 144 } 150 145 151 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) 152 147 { 153 148 int rc; 154 149 int dev_phone; 155 void *comm_area; 156 size_t bsize; 157 158 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, 159 153 MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); 160 if (!com m_area) {154 if (!com_area) { 161 155 return ENOMEM; 162 156 } … … 164 158 dev_phone = devmap_device_connect(dev_handle, IPC_FLAG_BLOCKING); 165 159 if (dev_phone < 0) { 166 munmap(com m_area, comm_size);160 munmap(com_area, com_size); 167 161 return dev_phone; 168 162 } 169 163 170 rc = ipc_share_out_start(dev_phone, com m_area,164 rc = ipc_share_out_start(dev_phone, com_area, 171 165 AS_AREA_READ | AS_AREA_WRITE); 172 166 if (rc != EOK) { 173 munmap(com m_area, comm_size);167 munmap(com_area, com_size); 174 168 ipc_hangup(dev_phone); 175 169 return rc; 176 170 } 177 178 if (get_block_size(dev_phone, &bsize) != EOK) { 179 munmap(comm_area, comm_size); 180 ipc_hangup(dev_phone); 181 return rc; 182 } 183 184 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); 185 173 if (rc != EOK) { 186 munmap(com m_area, comm_size);174 munmap(com_area, com_size); 187 175 ipc_hangup(dev_phone); 188 176 return rc; … … 207 195 } 208 196 209 munmap(devcon->com m_area, devcon->comm_size);197 munmap(devcon->com_area, devcon->com_size); 210 198 ipc_hangup(devcon->dev_phone); 211 199 … … 213 201 } 214 202 215 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) 216 204 { 217 205 void *bb_buf; … … 223 211 if (devcon->bb_buf) 224 212 return EEXIST; 225 bb_buf = malloc( devcon->pblock_size);213 bb_buf = malloc(size); 226 214 if (!bb_buf) 227 215 return ENOMEM; 228 229 fibril_mutex_lock(&devcon->com m_area_lock);230 rc = read_block s(devcon, 0, 1);216 217 fibril_mutex_lock(&devcon->com_area_lock); 218 rc = read_block(devcon, 0, size); 231 219 if (rc != EOK) { 232 fibril_mutex_unlock(&devcon->com m_area_lock);220 fibril_mutex_unlock(&devcon->com_area_lock); 233 221 free(bb_buf); 234 222 return rc; 235 223 } 236 memcpy(bb_buf, devcon->com m_area, devcon->pblock_size);237 fibril_mutex_unlock(&devcon->com m_area_lock);224 memcpy(bb_buf, devcon->com_area, size); 225 fibril_mutex_unlock(&devcon->com_area_lock); 238 226 239 227 devcon->bb_buf = bb_buf; 240 devcon->bb_addr = ba; 228 devcon->bb_off = off; 229 devcon->bb_size = size; 241 230 242 231 return EOK; … … 286 275 fibril_mutex_initialize(&cache->lock); 287 276 list_initialize(&cache->free_head); 288 cache-> lblock_size = size;277 cache->block_size = size; 289 278 cache->block_count = blocks; 290 279 cache->blocks_cached = 0; 291 280 cache->mode = mode; 292 293 /* No block size translation a.t.m. */294 assert(cache->lblock_size == devcon->pblock_size);295 281 296 282 if (!hash_table_create(&cache->block_hash, CACHE_BUCKETS, 1, … … 345 331 link_t *l; 346 332 unsigned long key = boff; 347 int rc = EOK;333 int rc; 348 334 349 335 devcon = devcon_search(dev_handle); … … 355 341 356 342 retry: 343 rc = EOK; 344 b = NULL; 345 357 346 fibril_mutex_lock(&cache->lock); 358 347 l = hash_table_find(&cache->block_hash, &key); … … 382 371 if (!b) 383 372 goto recycle; 384 b->data = malloc(cache-> lblock_size);373 b->data = malloc(cache->block_size); 385 374 if (!b->data) { 386 375 free(b); … … 394 383 unsigned long temp_key; 395 384 recycle: 396 assert(!list_empty(&cache->free_head)); 385 if (list_empty(&cache->free_head)) { 386 fibril_mutex_unlock(&cache->lock); 387 rc = ENOMEM; 388 goto out; 389 } 397 390 l = cache->free_head.next; 398 391 b = list_get_instance(l, block_t, free_link); … … 412 405 list_append(&b->free_link, &cache->free_head); 413 406 fibril_mutex_unlock(&cache->lock); 414 fibril_mutex_lock(&devcon->comm_area_lock); 415 memcpy(devcon->comm_area, b->data, b->size); 416 rc = write_blocks(devcon, b->boff, 1); 417 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); 418 412 if (rc != EOK) { 419 413 /* … … 450 444 block_initialize(b); 451 445 b->dev_handle = dev_handle; 452 b->size = cache-> lblock_size;446 b->size = cache->block_size; 453 447 b->boff = boff; 454 448 hash_table_insert(&cache->block_hash, &key, &b->hash_link); … … 467 461 * the new contents from the device. 468 462 */ 469 fibril_mutex_lock(&devcon->com m_area_lock);470 rc = read_block s(devcon, b->boff, 1);471 memcpy(b->data, devcon->com m_area, cache->lblock_size);472 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); 473 467 if (rc != EOK) 474 468 b->toxic = true; … … 477 471 478 472 fibril_mutex_unlock(&b->lock); 473 } 474 out: 475 if ((rc != EOK) && b) { 476 assert(b->toxic); 477 (void) block_put(b); 478 b = NULL; 479 479 } 480 480 *block = b; … … 521 521 if (block->dirty && (block->refcnt == 1) && 522 522 (blocks_cached > CACHE_HI_WATERMARK || mode != CACHE_MODE_WB)) { 523 fibril_mutex_lock(&devcon->com m_area_lock);524 memcpy(devcon->com m_area, block->data, block->size);525 rc = write_block s(devcon, block->boff, 1);526 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); 527 527 block->dirty = false; 528 528 } … … 601 601 */ 602 602 int block_seqread(dev_handle_t dev_handle, off_t *bufpos, size_t *buflen, 603 off_t *pos, void *dst, size_t size )603 off_t *pos, void *dst, size_t size, size_t block_size) 604 604 { 605 605 off_t offset = 0; 606 606 size_t left = size; 607 size_t block_size; 608 devcon_t *devcon; 609 610 devcon = devcon_search(dev_handle); 607 devcon_t *devcon = devcon_search(dev_handle); 611 608 assert(devcon); 612 block_size = devcon->pblock_size; 613 614 fibril_mutex_lock(&devcon->comm_area_lock); 609 610 fibril_mutex_lock(&devcon->com_area_lock); 615 611 while (left > 0) { 616 612 size_t rd; … … 626 622 * destination buffer. 627 623 */ 628 memcpy(dst + offset, devcon->com m_area + *bufpos, rd);624 memcpy(dst + offset, devcon->com_area + *bufpos, rd); 629 625 offset += rd; 630 626 *bufpos += rd; … … 637 633 int rc; 638 634 639 rc = read_block s(devcon, *pos / block_size, 1);635 rc = read_block(devcon, *pos / block_size, block_size); 640 636 if (rc != EOK) { 641 fibril_mutex_unlock(&devcon->com m_area_lock);637 fibril_mutex_unlock(&devcon->com_area_lock); 642 638 return rc; 643 639 } … … 647 643 } 648 644 } 649 fibril_mutex_unlock(&devcon->com m_area_lock);645 fibril_mutex_unlock(&devcon->com_area_lock); 650 646 651 647 return EOK; 652 648 } 653 649 654 /** Read block s directly from device (bypass cache).655 * 656 * @param dev _handle Device handle of the block device.657 * @param b a Address of first block.658 * @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. 659 655 * @param src Buffer for storing the data. 660 656 * 661 657 * @return EOK on success or negative error code on failure. 662 658 */ 663 int block_read_direct(dev_handle_t dev_handle, bn_t ba, size_t cnt, void *buf)664 { 665 devcon_t *devcon;659 static int read_block(devcon_t *devcon, bn_t boff, size_t block_size) 660 { 661 ipcarg_t retval; 666 662 int rc; 667 663 668 devcon = devcon_search(dev_handle);669 664 assert(devcon); 670 671 fibril_mutex_lock(&devcon->comm_area_lock); 672 673 rc = read_blocks(devcon, ba, cnt); 674 if (rc == EOK) 675 memcpy(buf, devcon->comm_area, devcon->pblock_size * cnt); 676 677 fibril_mutex_unlock(&devcon->comm_area_lock); 678 679 return rc; 680 } 681 682 /** Write blocks directly to device (bypass cache). 683 * 684 * @param dev_handle Device handle of the block device. 685 * @param ba Address of first block. 686 * @param cnt Number of blocks. 687 * @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. 688 679 * 689 680 * @return EOK on success or negative error code on failure. 690 681 */ 691 int block_write_direct(dev_handle_t dev_handle, bn_t ba, size_t cnt, 692 const void *data) 693 { 694 devcon_t *devcon; 682 static int write_block(devcon_t *devcon, bn_t boff, size_t block_size) 683 { 684 ipcarg_t retval; 695 685 int rc; 696 686 697 devcon = devcon_search(dev_handle);698 687 assert(devcon); 699 700 fibril_mutex_lock(&devcon->comm_area_lock); 701 702 memcpy(devcon->comm_area, data, devcon->pblock_size * cnt); 703 rc = read_blocks(devcon, ba, cnt); 704 705 fibril_mutex_unlock(&devcon->comm_area_lock); 706 707 return rc; 708 } 709 710 /** Get device block size. 711 * 712 * @param dev_handle Device handle of the block device. 713 * @param bsize Output block size. 714 * 715 * @return EOK on success or negative error code on failure. 716 */ 717 int block_get_bsize(dev_handle_t dev_handle, size_t *bsize) 718 { 719 devcon_t *devcon; 720 721 devcon = devcon_search(dev_handle); 722 assert(devcon); 723 724 return get_block_size(devcon->dev_phone, bsize); 725 } 726 727 /** Read blocks from block device. 728 * 729 * @param devcon Device connection. 730 * @param ba Address of first block. 731 * @param cnt Number of blocks. 732 * @param src Buffer for storing the data. 733 * 734 * @return EOK on success or negative error code on failure. 735 */ 736 static int read_blocks(devcon_t *devcon, bn_t ba, size_t cnt) 737 { 738 int rc; 739 740 assert(devcon); 741 rc = async_req_3_0(devcon->dev_phone, BD_READ_BLOCKS, LOWER32(ba), 742 UPPER32(ba), cnt); 743 return rc; 744 } 745 746 /** Write block to block device. 747 * 748 * @param devcon Device connection. 749 * @param ba Address of first block. 750 * @param cnt Number of blocks. 751 * @param src Buffer containing the data to write. 752 * 753 * @return EOK on success or negative error code on failure. 754 */ 755 static int write_blocks(devcon_t *devcon, bn_t ba, size_t cnt) 756 { 757 int rc; 758 759 assert(devcon); 760 rc = async_req_3_0(devcon->dev_phone, BD_WRITE_BLOCKS, LOWER32(ba), 761 UPPER32(ba), cnt); 762 return rc; 763 } 764 765 /** Get block size used by the device. */ 766 static int get_block_size(int dev_phone, size_t *bsize) 767 { 768 ipcarg_t bs; 769 int rc; 770 771 rc = async_req_0_1(dev_phone, BD_GET_BLOCK_SIZE, &bs); 772 if (rc == EOK) 773 *bsize = (size_t) bs; 774 775 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; 776 694 } 777 695
Note:
See TracChangeset
for help on using the changeset viewer.