Changes in uspace/lib/block/libblock.c [9d58539:4802dd7] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/block/libblock.c
r9d58539 r4802dd7 40 40 #include "../../srv/vfs/vfs.h" 41 41 #include <ipc/loc.h> 42 #include <ipc/bd.h>43 42 #include <ipc/services.h> 44 43 #include <errno.h> … … 47 46 #include <as.h> 48 47 #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 fibril_mutex_t comm_area_lock; 83 void *comm_area; 84 size_t comm_size; 82 bd_t *bd; 85 83 void *bb_buf; 86 84 aoff64_t bb_addr; … … 89 87 } devcon_t; 90 88 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 *); 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); 95 91 static aoff64_t ba_ltop(devcon_t *, aoff64_t); 96 92 … … 112 108 113 109 static int devcon_add(service_id_t service_id, async_sess_t *sess, 114 size_t bsize, void *comm_area, size_t comm_size)110 size_t bsize, bd_t *bd) 115 111 { 116 112 devcon_t *devcon; 117 118 if (comm_size < bsize)119 return EINVAL;120 113 121 114 devcon = malloc(sizeof(devcon_t)); … … 126 119 devcon->service_id = service_id; 127 120 devcon->sess = sess; 128 fibril_mutex_initialize(&devcon->comm_area_lock); 129 devcon->comm_area = comm_area; 130 devcon->comm_size = comm_size; 121 devcon->bd = bd; 131 122 devcon->bb_buf = NULL; 132 123 devcon->bb_addr = 0; … … 158 149 size_t comm_size) 159 150 { 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 151 bd_t *bd; 152 165 153 async_sess_t *sess = loc_service_connect(mgmt, service_id, 166 154 IPC_FLAG_BLOCKING); 167 155 if (!sess) { 168 munmap(comm_area, comm_size);169 156 return ENOENT; 170 157 } 171 158 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 159 int rc = bd_open(sess, &bd); 177 160 if (rc != EOK) { 178 munmap(comm_area, comm_size);179 161 async_hangup(sess); 180 162 return rc; … … 182 164 183 165 size_t bsize; 184 rc = get_block_size(sess, &bsize); 185 166 rc = bd_get_block_size(bd, &bsize); 186 167 if (rc != EOK) { 187 munmap(comm_area, comm_size);168 bd_close(bd); 188 169 async_hangup(sess); 189 170 return rc; 190 171 } 191 172 192 rc = devcon_add(service_id, sess, bsize, comm_area, comm_size);173 rc = devcon_add(service_id, sess, bsize, bd); 193 174 if (rc != EOK) { 194 munmap(comm_area, comm_size);175 bd_close(bd); 195 176 async_hangup(sess); 196 177 return rc; … … 213 194 free(devcon->bb_buf); 214 195 215 munmap(devcon->comm_area, devcon->comm_size);196 bd_close(devcon->bd); 216 197 async_hangup(devcon->sess); 217 198 … … 233 214 return ENOMEM; 234 215 235 fibril_mutex_lock(&devcon->comm_area_lock); 236 rc = read_blocks(devcon, 0, 1); 216 rc = read_blocks(devcon, 0, 1, bb_buf, devcon->pblock_size); 237 217 if (rc != EOK) { 238 fibril_mutex_unlock(&devcon->comm_area_lock);239 218 free(bb_buf); 240 219 return rc; 241 220 } 242 memcpy(bb_buf, devcon->comm_area, devcon->pblock_size);243 fibril_mutex_unlock(&devcon->comm_area_lock);244 221 245 222 devcon->bb_buf = bb_buf; … … 338 315 list_remove(&b->free_link); 339 316 if (b->dirty) { 340 memcpy(devcon->comm_area, b->data, b->size);341 rc = write_blocks(devcon, b->pba, cache->blocks_cluster);317 rc = write_blocks(devcon, b->pba, cache->blocks_cluster, 318 b->data, b->size); 342 319 if (rc != EOK) 343 320 return rc; … … 481 458 list_append(&b->free_link, &cache->free_list); 482 459 fibril_mutex_unlock(&cache->lock); 483 fibril_mutex_lock(&devcon->comm_area_lock);484 memcpy(devcon->comm_area, b->data, b->size);485 460 rc = write_blocks(devcon, b->pba, 486 cache->blocks_cluster); 487 fibril_mutex_unlock(&devcon->comm_area_lock); 461 cache->blocks_cluster, b->data, b->size); 488 462 if (rc != EOK) { 489 463 /* … … 555 529 * the new contents from the device. 556 530 */ 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); 531 rc = read_blocks(devcon, b->pba, cache->blocks_cluster, 532 b->data, cache->lblock_size); 561 533 if (rc != EOK) 562 534 b->toxic = true; … … 616 588 if (block->dirty && (block->refcnt == 1) && 617 589 (blocks_cached > CACHE_HI_WATERMARK || mode != CACHE_MODE_WB)) { 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); 590 rc = write_blocks(devcon, block->pba, cache->blocks_cluster, 591 block->data, block->size); 622 592 block->dirty = false; 623 593 } … … 688 658 * 689 659 * @param service_id Service ID of the block device. 660 * @param buf Buffer for holding one block 690 661 * @param bufpos Pointer to the first unread valid offset within the 691 662 * communication buffer. … … 699 670 * @return EOK on success or a negative return code on failure. 700 671 */ 701 int block_seqread(service_id_t service_id, size_t *bufpos, size_t *buflen,702 aoff64_t *pos, void *dst, size_t size)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) 703 674 { 704 675 size_t offset = 0; … … 711 682 block_size = devcon->pblock_size; 712 683 713 fibril_mutex_lock(&devcon->comm_area_lock);714 684 while (left > 0) { 715 685 size_t rd; … … 725 695 * destination buffer. 726 696 */ 727 memcpy(dst + offset, devcon->comm_area+ *bufpos, rd);697 memcpy(dst + offset, buf + *bufpos, rd); 728 698 offset += rd; 729 699 *bufpos += rd; … … 736 706 int rc; 737 707 738 rc = read_blocks(devcon, *pos / block_size, 1); 708 rc = read_blocks(devcon, *pos / block_size, 1, buf, 709 devcon->pblock_size); 739 710 if (rc != EOK) { 740 fibril_mutex_unlock(&devcon->comm_area_lock);741 711 return rc; 742 712 } … … 746 716 } 747 717 } 748 fibril_mutex_unlock(&devcon->comm_area_lock);749 718 750 719 return EOK; … … 763 732 { 764 733 devcon_t *devcon; 765 int rc;766 734 767 735 devcon = devcon_search(service_id); 768 736 assert(devcon); 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; 737 738 return read_blocks(devcon, ba, cnt, buf, devcon->pblock_size * cnt); 779 739 } 780 740 … … 792 752 { 793 753 devcon_t *devcon; 794 int rc;795 754 796 755 devcon = devcon_search(service_id); 797 756 assert(devcon); 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; 757 758 return write_blocks(devcon, ba, cnt, (void *)data, devcon->pblock_size * cnt); 807 759 } 808 760 … … 820 772 devcon = devcon_search(service_id); 821 773 assert(devcon); 822 823 return get_block_size(devcon->sess, bsize);774 775 return bd_get_block_size(devcon->bd, bsize); 824 776 } 825 777 … … 836 788 assert(devcon); 837 789 838 return get_num_blocks(devcon->sess, nblocks);790 return bd_get_num_blocks(devcon->bd, nblocks); 839 791 } 840 792 … … 887 839 memcpy(data, buffer + offset, bytes); 888 840 free(buffer); 889 841 890 842 return EOK; 891 843 } … … 903 855 { 904 856 devcon_t *devcon = devcon_search(service_id); 905 assert(devcon);906 907 857 toc_block_t *toc = NULL; 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); 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 } 926 871 927 872 return toc; … … 937 882 * @return EOK on success or negative error code on failure. 938 883 */ 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 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); 948 890 if (rc != EOK) { 949 891 printf("Error %d reading %zu blocks starting at block %" PRIuOFF64 … … 967 909 * @return EOK on success or negative error code on failure. 968 910 */ 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 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); 978 917 if (rc != EOK) { 979 918 printf("Error %d writing %zu blocks starting at block %" PRIuOFF64 … … 987 926 } 988 927 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 1020 928 /** Convert logical block address to physical block address. */ 1021 929 static aoff64_t ba_ltop(devcon_t *devcon, aoff64_t lba)
Note:
See TracChangeset
for help on using the changeset viewer.