Changes in uspace/lib/block/libblock.c [4802dd7:9d58539] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/block/libblock.c
r4802dd7 r9d58539 40 40 #include "../../srv/vfs/vfs.h" 41 41 #include <ipc/loc.h> 42 #include <ipc/bd.h> 42 43 #include <ipc/services.h> 43 44 #include <errno.h> … … 46 47 #include <as.h> 47 48 #include <assert.h> 48 #include <bd.h>49 49 #include <fibril_synch.h> 50 50 #include <adt/list.h> … … 80 80 service_id_t service_id; 81 81 async_sess_t *sess; 82 bd_t *bd; 82 fibril_mutex_t comm_area_lock; 83 void *comm_area; 84 size_t comm_size; 83 85 void *bb_buf; 84 86 aoff64_t bb_addr; … … 87 89 } devcon_t; 88 90 89 static int read_blocks(devcon_t *, aoff64_t, size_t, void *, size_t); 90 static int write_blocks(devcon_t *, aoff64_t, size_t, void *, size_t); 91 static int read_blocks(devcon_t *, aoff64_t, size_t); 92 static int write_blocks(devcon_t *, aoff64_t, size_t); 93 static int get_block_size(async_sess_t *, size_t *); 94 static int get_num_blocks(async_sess_t *, aoff64_t *); 91 95 static aoff64_t ba_ltop(devcon_t *, aoff64_t); 92 96 … … 108 112 109 113 static int devcon_add(service_id_t service_id, async_sess_t *sess, 110 size_t bsize, bd_t *bd)114 size_t bsize, void *comm_area, size_t comm_size) 111 115 { 112 116 devcon_t *devcon; 117 118 if (comm_size < bsize) 119 return EINVAL; 113 120 114 121 devcon = malloc(sizeof(devcon_t)); … … 119 126 devcon->service_id = service_id; 120 127 devcon->sess = sess; 121 devcon->bd = bd; 128 fibril_mutex_initialize(&devcon->comm_area_lock); 129 devcon->comm_area = comm_area; 130 devcon->comm_size = comm_size; 122 131 devcon->bb_buf = NULL; 123 132 devcon->bb_addr = 0; … … 149 158 size_t comm_size) 150 159 { 151 bd_t *bd; 152 160 void *comm_area = mmap(NULL, comm_size, PROTO_READ | PROTO_WRITE, 161 MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); 162 if (!comm_area) 163 return ENOMEM; 164 153 165 async_sess_t *sess = loc_service_connect(mgmt, service_id, 154 166 IPC_FLAG_BLOCKING); 155 167 if (!sess) { 168 munmap(comm_area, comm_size); 156 169 return ENOENT; 157 170 } 158 171 159 int rc = bd_open(sess, &bd); 172 async_exch_t *exch = async_exchange_begin(sess); 173 int rc = async_share_out_start(exch, comm_area, 174 AS_AREA_READ | AS_AREA_WRITE); 175 async_exchange_end(exch); 176 160 177 if (rc != EOK) { 178 munmap(comm_area, comm_size); 161 179 async_hangup(sess); 162 180 return rc; … … 164 182 165 183 size_t bsize; 166 rc = bd_get_block_size(bd, &bsize); 184 rc = get_block_size(sess, &bsize); 185 167 186 if (rc != EOK) { 168 bd_close(bd);187 munmap(comm_area, comm_size); 169 188 async_hangup(sess); 170 189 return rc; 171 190 } 172 191 173 rc = devcon_add(service_id, sess, bsize, bd);192 rc = devcon_add(service_id, sess, bsize, comm_area, comm_size); 174 193 if (rc != EOK) { 175 bd_close(bd);194 munmap(comm_area, comm_size); 176 195 async_hangup(sess); 177 196 return rc; … … 194 213 free(devcon->bb_buf); 195 214 196 bd_close(devcon->bd);215 munmap(devcon->comm_area, devcon->comm_size); 197 216 async_hangup(devcon->sess); 198 217 … … 214 233 return ENOMEM; 215 234 216 rc = read_blocks(devcon, 0, 1, bb_buf, devcon->pblock_size); 235 fibril_mutex_lock(&devcon->comm_area_lock); 236 rc = read_blocks(devcon, 0, 1); 217 237 if (rc != EOK) { 238 fibril_mutex_unlock(&devcon->comm_area_lock); 218 239 free(bb_buf); 219 240 return rc; 220 241 } 242 memcpy(bb_buf, devcon->comm_area, devcon->pblock_size); 243 fibril_mutex_unlock(&devcon->comm_area_lock); 221 244 222 245 devcon->bb_buf = bb_buf; … … 315 338 list_remove(&b->free_link); 316 339 if (b->dirty) { 317 rc = write_blocks(devcon, b->pba, cache->blocks_cluster,318 b->data, b->size);340 memcpy(devcon->comm_area, b->data, b->size); 341 rc = write_blocks(devcon, b->pba, cache->blocks_cluster); 319 342 if (rc != EOK) 320 343 return rc; … … 458 481 list_append(&b->free_link, &cache->free_list); 459 482 fibril_mutex_unlock(&cache->lock); 483 fibril_mutex_lock(&devcon->comm_area_lock); 484 memcpy(devcon->comm_area, b->data, b->size); 460 485 rc = write_blocks(devcon, b->pba, 461 cache->blocks_cluster, b->data, b->size); 486 cache->blocks_cluster); 487 fibril_mutex_unlock(&devcon->comm_area_lock); 462 488 if (rc != EOK) { 463 489 /* … … 529 555 * the new contents from the device. 530 556 */ 531 rc = read_blocks(devcon, b->pba, cache->blocks_cluster, 532 b->data, cache->lblock_size); 557 fibril_mutex_lock(&devcon->comm_area_lock); 558 rc = read_blocks(devcon, b->pba, cache->blocks_cluster); 559 memcpy(b->data, devcon->comm_area, cache->lblock_size); 560 fibril_mutex_unlock(&devcon->comm_area_lock); 533 561 if (rc != EOK) 534 562 b->toxic = true; … … 588 616 if (block->dirty && (block->refcnt == 1) && 589 617 (blocks_cached > CACHE_HI_WATERMARK || mode != CACHE_MODE_WB)) { 590 rc = write_blocks(devcon, block->pba, cache->blocks_cluster, 591 block->data, block->size); 618 fibril_mutex_lock(&devcon->comm_area_lock); 619 memcpy(devcon->comm_area, block->data, block->size); 620 rc = write_blocks(devcon, block->pba, cache->blocks_cluster); 621 fibril_mutex_unlock(&devcon->comm_area_lock); 592 622 block->dirty = false; 593 623 } … … 658 688 * 659 689 * @param service_id Service ID of the block device. 660 * @param buf Buffer for holding one block661 690 * @param bufpos Pointer to the first unread valid offset within the 662 691 * communication buffer. … … 670 699 * @return EOK on success or a negative return code on failure. 671 700 */ 672 int block_seqread(service_id_t service_id, void *buf, size_t *bufpos,673 size_t *buflen,aoff64_t *pos, void *dst, size_t size)701 int block_seqread(service_id_t service_id, size_t *bufpos, size_t *buflen, 702 aoff64_t *pos, void *dst, size_t size) 674 703 { 675 704 size_t offset = 0; … … 682 711 block_size = devcon->pblock_size; 683 712 713 fibril_mutex_lock(&devcon->comm_area_lock); 684 714 while (left > 0) { 685 715 size_t rd; … … 695 725 * destination buffer. 696 726 */ 697 memcpy(dst + offset, buf+ *bufpos, rd);727 memcpy(dst + offset, devcon->comm_area + *bufpos, rd); 698 728 offset += rd; 699 729 *bufpos += rd; … … 706 736 int rc; 707 737 708 rc = read_blocks(devcon, *pos / block_size, 1, buf, 709 devcon->pblock_size); 738 rc = read_blocks(devcon, *pos / block_size, 1); 710 739 if (rc != EOK) { 740 fibril_mutex_unlock(&devcon->comm_area_lock); 711 741 return rc; 712 742 } … … 716 746 } 717 747 } 748 fibril_mutex_unlock(&devcon->comm_area_lock); 718 749 719 750 return EOK; … … 732 763 { 733 764 devcon_t *devcon; 765 int rc; 734 766 735 767 devcon = devcon_search(service_id); 736 768 assert(devcon); 737 738 return read_blocks(devcon, ba, cnt, buf, devcon->pblock_size * cnt); 769 770 fibril_mutex_lock(&devcon->comm_area_lock); 771 772 rc = read_blocks(devcon, ba, cnt); 773 if (rc == EOK) 774 memcpy(buf, devcon->comm_area, devcon->pblock_size * cnt); 775 776 fibril_mutex_unlock(&devcon->comm_area_lock); 777 778 return rc; 739 779 } 740 780 … … 752 792 { 753 793 devcon_t *devcon; 794 int rc; 754 795 755 796 devcon = devcon_search(service_id); 756 797 assert(devcon); 757 758 return write_blocks(devcon, ba, cnt, (void *)data, devcon->pblock_size * cnt); 798 799 fibril_mutex_lock(&devcon->comm_area_lock); 800 801 memcpy(devcon->comm_area, data, devcon->pblock_size * cnt); 802 rc = write_blocks(devcon, ba, cnt); 803 804 fibril_mutex_unlock(&devcon->comm_area_lock); 805 806 return rc; 759 807 } 760 808 … … 772 820 devcon = devcon_search(service_id); 773 821 assert(devcon); 774 775 return bd_get_block_size(devcon->bd, bsize);822 823 return get_block_size(devcon->sess, bsize); 776 824 } 777 825 … … 788 836 assert(devcon); 789 837 790 return bd_get_num_blocks(devcon->bd, nblocks);838 return get_num_blocks(devcon->sess, nblocks); 791 839 } 792 840 … … 839 887 memcpy(data, buffer + offset, bytes); 840 888 free(buffer); 841 889 842 890 return EOK; 843 891 } … … 855 903 { 856 904 devcon_t *devcon = devcon_search(service_id); 905 assert(devcon); 906 857 907 toc_block_t *toc = NULL; 858 int rc; 859 860 assert(devcon); 861 862 toc = (toc_block_t *) malloc(sizeof(toc_block_t)); 863 if (toc == NULL) 864 return NULL; 865 866 rc = bd_read_toc(devcon->bd, session, toc, sizeof(toc_block_t)); 867 if (rc != EOK) { 868 free(toc); 869 return NULL; 870 } 908 909 fibril_mutex_lock(&devcon->comm_area_lock); 910 911 async_exch_t *exch = async_exchange_begin(devcon->sess); 912 int rc = async_req_1_0(exch, BD_READ_TOC, session); 913 async_exchange_end(exch); 914 915 if (rc == EOK) { 916 toc = (toc_block_t *) malloc(sizeof(toc_block_t)); 917 if (toc != NULL) { 918 memset(toc, 0, sizeof(toc_block_t)); 919 memcpy(toc, devcon->comm_area, 920 min(devcon->pblock_size, sizeof(toc_block_t))); 921 } 922 } 923 924 925 fibril_mutex_unlock(&devcon->comm_area_lock); 871 926 872 927 return toc; … … 882 937 * @return EOK on success or negative error code on failure. 883 938 */ 884 static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt, void *buf, 885 size_t size) 886 { 887 assert(devcon); 888 889 int rc = bd_read_blocks(devcon->bd, ba, cnt, buf, size); 939 static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt) 940 { 941 assert(devcon); 942 943 async_exch_t *exch = async_exchange_begin(devcon->sess); 944 int rc = async_req_3_0(exch, BD_READ_BLOCKS, LOWER32(ba), 945 UPPER32(ba), cnt); 946 async_exchange_end(exch); 947 890 948 if (rc != EOK) { 891 949 printf("Error %d reading %zu blocks starting at block %" PRIuOFF64 … … 909 967 * @return EOK on success or negative error code on failure. 910 968 */ 911 static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt, void *data, 912 size_t size) 913 { 914 assert(devcon); 915 916 int rc = bd_write_blocks(devcon->bd, ba, cnt, data, size); 969 static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt) 970 { 971 assert(devcon); 972 973 async_exch_t *exch = async_exchange_begin(devcon->sess); 974 int rc = async_req_3_0(exch, BD_WRITE_BLOCKS, LOWER32(ba), 975 UPPER32(ba), cnt); 976 async_exchange_end(exch); 977 917 978 if (rc != EOK) { 918 979 printf("Error %d writing %zu blocks starting at block %" PRIuOFF64 … … 926 987 } 927 988 989 /** Get block size used by the device. */ 990 static int get_block_size(async_sess_t *sess, size_t *bsize) 991 { 992 sysarg_t bs; 993 994 async_exch_t *exch = async_exchange_begin(sess); 995 int rc = async_req_0_1(exch, BD_GET_BLOCK_SIZE, &bs); 996 async_exchange_end(exch); 997 998 if (rc == EOK) 999 *bsize = (size_t) bs; 1000 1001 return rc; 1002 } 1003 1004 /** Get total number of blocks on block device. */ 1005 static int get_num_blocks(async_sess_t *sess, aoff64_t *nblocks) 1006 { 1007 sysarg_t nb_l; 1008 sysarg_t nb_h; 1009 1010 async_exch_t *exch = async_exchange_begin(sess); 1011 int rc = async_req_0_2(exch, BD_GET_NUM_BLOCKS, &nb_l, &nb_h); 1012 async_exchange_end(exch); 1013 1014 if (rc == EOK) 1015 *nblocks = (aoff64_t) MERGE_LOUP32(nb_l, nb_h); 1016 1017 return rc; 1018 } 1019 928 1020 /** Convert logical block address to physical block address. */ 929 1021 static aoff64_t ba_ltop(devcon_t *devcon, aoff64_t lba)
Note:
See TracChangeset
for help on using the changeset viewer.