Changes in uspace/lib/block/libblock.c [b72efe8:c4aa9cf] in mainline
- File:
-
- 1 edited
-
uspace/lib/block/libblock.c (modified) (21 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/block/libblock.c
rb72efe8 rc4aa9cf 60 60 static FIBRIL_MUTEX_INITIALIZE(dcl_lock); 61 61 /** Device connection list head. */ 62 static LIST_INITIALIZE(dcl );63 64 #define CACHE_BUCKETS_LOG2 1065 #define CACHE_BUCKETS (1 << CACHE_BUCKETS_LOG2)62 static LIST_INITIALIZE(dcl_head); 63 64 #define CACHE_BUCKETS_LOG2 10 65 #define CACHE_BUCKETS (1 << CACHE_BUCKETS_LOG2) 66 66 67 67 typedef struct { 68 68 fibril_mutex_t lock; 69 size_t lblock_size; /**< Logical block size. */70 unsigned blocks_cluster; /**< Physical blocks per block_t */71 unsigned block_count; /**< Total number of blocks. */72 unsigned blocks_cached; /**< Number of cached blocks. */69 size_t lblock_size; /**< Logical block size. */ 70 unsigned blocks_cluster; /**< Physical blocks per block_t */ 71 unsigned block_count; /**< Total number of blocks. */ 72 unsigned blocks_cached; /**< Number of cached blocks. */ 73 73 hash_table_t block_hash; 74 li st_t free_list;74 link_t free_head; 75 75 enum cache_mode mode; 76 76 } cache_t; … … 79 79 link_t link; 80 80 devmap_handle_t devmap_handle; 81 async_sess_t *sess;81 int dev_phone; 82 82 fibril_mutex_t comm_area_lock; 83 83 void *comm_area; … … 85 85 void *bb_buf; 86 86 aoff64_t bb_addr; 87 size_t pblock_size; /**< Physical block size. */87 size_t pblock_size; /**< Physical block size. */ 88 88 cache_t *cache; 89 89 } devcon_t; 90 90 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 *);95 static aoff64_t ba_ltop(devcon_t * , aoff64_t);91 static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt); 92 static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt); 93 static int get_block_size(int dev_phone, size_t *bsize); 94 static int get_num_blocks(int dev_phone, aoff64_t *nblocks); 95 static aoff64_t ba_ltop(devcon_t *devcon, aoff64_t lba); 96 96 97 97 static devcon_t *devcon_search(devmap_handle_t devmap_handle) 98 98 { 99 link_t *cur; 100 99 101 fibril_mutex_lock(&dcl_lock); 100 101 list_foreach(dcl, cur) { 102 for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) { 102 103 devcon_t *devcon = list_get_instance(cur, devcon_t, link); 103 104 if (devcon->devmap_handle == devmap_handle) { … … 106 107 } 107 108 } 108 109 109 fibril_mutex_unlock(&dcl_lock); 110 110 return NULL; 111 111 } 112 112 113 static int devcon_add(devmap_handle_t devmap_handle, async_sess_t *sess, 114 size_t bsize, void *comm_area, size_t comm_size) 115 { 113 static int devcon_add(devmap_handle_t devmap_handle, int dev_phone, size_t bsize, 114 void *comm_area, size_t comm_size) 115 { 116 link_t *cur; 116 117 devcon_t *devcon; 117 118 118 119 if (comm_size < bsize) 119 120 return EINVAL; 120 121 121 122 devcon = malloc(sizeof(devcon_t)); 122 123 if (!devcon) … … 125 126 link_initialize(&devcon->link); 126 127 devcon->devmap_handle = devmap_handle; 127 devcon-> sess = sess;128 devcon->dev_phone = dev_phone; 128 129 fibril_mutex_initialize(&devcon->comm_area_lock); 129 130 devcon->comm_area = comm_area; … … 133 134 devcon->pblock_size = bsize; 134 135 devcon->cache = NULL; 135 136 136 137 fibril_mutex_lock(&dcl_lock); 137 list_foreach(dcl, cur) {138 for (cur = dcl_head.next; cur != &dcl_head; cur = cur->next) { 138 139 devcon_t *d = list_get_instance(cur, devcon_t, link); 139 140 if (d->devmap_handle == devmap_handle) { … … 143 144 } 144 145 } 145 list_append(&devcon->link, &dcl );146 list_append(&devcon->link, &dcl_head); 146 147 fibril_mutex_unlock(&dcl_lock); 147 148 return EOK; … … 155 156 } 156 157 157 int block_init(exch_mgmt_t mgmt, devmap_handle_t devmap_handle, 158 size_t comm_size) 159 { 160 void *comm_area = mmap(NULL, comm_size, PROTO_READ | PROTO_WRITE, 158 int block_init(devmap_handle_t devmap_handle, size_t comm_size) 159 { 160 int rc; 161 int dev_phone; 162 void *comm_area; 163 size_t bsize; 164 165 comm_area = mmap(NULL, comm_size, PROTO_READ | PROTO_WRITE, 161 166 MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); 162 if (!comm_area) 167 if (!comm_area) { 163 168 return ENOMEM; 164 165 async_sess_t *sess = devmap_device_connect(mgmt, devmap_handle, 166 IPC_FLAG_BLOCKING);167 if ( !sess) {169 } 170 171 dev_phone = devmap_device_connect(devmap_handle, IPC_FLAG_BLOCKING); 172 if (dev_phone < 0) { 168 173 munmap(comm_area, comm_size); 169 return ENOENT; 170 } 171 172 async_exch_t *exch = async_exchange_begin(sess); 173 int rc = async_share_out_start(exch, comm_area, 174 return dev_phone; 175 } 176 177 rc = async_share_out_start(dev_phone, comm_area, 174 178 AS_AREA_READ | AS_AREA_WRITE); 175 async_exchange_end(exch); 176 179 if (rc != EOK) { 180 munmap(comm_area, comm_size); 181 async_hangup(dev_phone); 182 return rc; 183 } 184 185 if (get_block_size(dev_phone, &bsize) != EOK) { 186 munmap(comm_area, comm_size); 187 async_hangup(dev_phone); 188 return rc; 189 } 190 191 rc = devcon_add(devmap_handle, dev_phone, bsize, comm_area, comm_size); 177 192 if (rc != EOK) { 178 193 munmap(comm_area, comm_size); 179 async_hangup( sess);194 async_hangup(dev_phone); 180 195 return rc; 181 196 } 182 183 size_t bsize; 184 rc = get_block_size(sess, &bsize); 185 186 if (rc != EOK) { 187 munmap(comm_area, comm_size); 188 async_hangup(sess); 189 return rc; 190 } 191 192 rc = devcon_add(devmap_handle, sess, bsize, comm_area, comm_size); 193 if (rc != EOK) { 194 munmap(comm_area, comm_size); 195 async_hangup(sess); 196 return rc; 197 } 198 197 199 198 return EOK; 200 199 } … … 207 206 if (devcon->cache) 208 207 (void) block_cache_fini(devmap_handle); 209 208 210 209 devcon_remove(devcon); 211 210 212 211 if (devcon->bb_buf) 213 212 free(devcon->bb_buf); 214 213 215 214 munmap(devcon->comm_area, devcon->comm_size); 216 async_hangup(devcon-> sess);217 218 free(devcon); 215 async_hangup(devcon->dev_phone); 216 217 free(devcon); 219 218 } 220 219 … … 291 290 292 291 fibril_mutex_initialize(&cache->lock); 293 list_initialize(&cache->free_ list);292 list_initialize(&cache->free_head); 294 293 cache->lblock_size = size; 295 294 cache->block_count = blocks; … … 332 331 * bother with the cache and block locks because we are single-threaded. 333 332 */ 334 while (!list_empty(&cache->free_ list)) {335 block_t *b = list_get_instance( list_first(&cache->free_list),333 while (!list_empty(&cache->free_head)) { 334 block_t *b = list_get_instance(cache->free_head.next, 336 335 block_t, free_link); 337 336 … … 364 363 if (cache->blocks_cached < CACHE_LO_WATERMARK) 365 364 return true; 366 if (!list_empty(&cache->free_ list))365 if (!list_empty(&cache->free_head)) 367 366 return false; 368 367 return true; … … 453 452 unsigned long temp_key; 454 453 recycle: 455 if (list_empty(&cache->free_ list)) {454 if (list_empty(&cache->free_head)) { 456 455 fibril_mutex_unlock(&cache->lock); 457 456 rc = ENOMEM; 458 457 goto out; 459 458 } 460 l = list_first(&cache->free_list);459 l = cache->free_head.next; 461 460 b = list_get_instance(l, block_t, free_link); 462 461 … … 473 472 */ 474 473 list_remove(&b->free_link); 475 list_append(&b->free_link, &cache->free_ list);474 list_append(&b->free_link, &cache->free_head); 476 475 fibril_mutex_unlock(&cache->lock); 477 476 fibril_mutex_lock(&devcon->comm_area_lock); … … 665 664 goto retry; 666 665 } 667 list_append(&block->free_link, &cache->free_ list);666 list_append(&block->free_link, &cache->free_head); 668 667 } 669 668 fibril_mutex_unlock(&block->lock); … … 809 808 assert(devcon); 810 809 811 return get_block_size(devcon-> sess, bsize);810 return get_block_size(devcon->dev_phone, bsize); 812 811 } 813 812 … … 821 820 int block_get_nblocks(devmap_handle_t devmap_handle, aoff64_t *nblocks) 822 821 { 823 devcon_t *devcon = devcon_search(devmap_handle); 824 assert(devcon); 825 826 return get_num_blocks(devcon->sess, nblocks); 822 devcon_t *devcon; 823 824 devcon = devcon_search(devmap_handle); 825 assert(devcon); 826 827 return get_num_blocks(devcon->dev_phone, nblocks); 827 828 } 828 829 … … 890 891 static int read_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt) 891 892 { 892 assert(devcon);893 894 as ync_exch_t *exch = async_exchange_begin(devcon->sess);895 int rc = async_req_3_0(exch, BD_READ_BLOCKS, LOWER32(ba),893 int rc; 894 895 assert(devcon); 896 rc = async_req_3_0(devcon->dev_phone, BD_READ_BLOCKS, LOWER32(ba), 896 897 UPPER32(ba), cnt); 897 async_exchange_end(exch);898 899 898 if (rc != EOK) { 900 899 printf("Error %d reading %zu blocks starting at block %" PRIuOFF64 … … 905 904 #endif 906 905 } 907 908 906 return rc; 909 907 } … … 920 918 static int write_blocks(devcon_t *devcon, aoff64_t ba, size_t cnt) 921 919 { 922 assert(devcon);923 924 as ync_exch_t *exch = async_exchange_begin(devcon->sess);925 int rc = async_req_3_0(exch, BD_WRITE_BLOCKS, LOWER32(ba),920 int rc; 921 922 assert(devcon); 923 rc = async_req_3_0(devcon->dev_phone, BD_WRITE_BLOCKS, LOWER32(ba), 926 924 UPPER32(ba), cnt); 927 async_exchange_end(exch);928 929 925 if (rc != EOK) { 930 926 printf("Error %d writing %zu blocks starting at block %" PRIuOFF64 … … 934 930 #endif 935 931 } 936 937 932 return rc; 938 933 } 939 934 940 935 /** Get block size used by the device. */ 941 static int get_block_size( async_sess_t *sess, size_t *bsize)936 static int get_block_size(int dev_phone, size_t *bsize) 942 937 { 943 938 sysarg_t bs; 944 945 async_exch_t *exch = async_exchange_begin(sess); 946 int rc = async_req_0_1(exch, BD_GET_BLOCK_SIZE, &bs); 947 async_exchange_end(exch); 948 939 int rc; 940 941 rc = async_req_0_1(dev_phone, BD_GET_BLOCK_SIZE, &bs); 949 942 if (rc == EOK) 950 943 *bsize = (size_t) bs; 951 944 952 945 return rc; 953 946 } 954 947 955 948 /** Get total number of blocks on block device. */ 956 static int get_num_blocks(async_sess_t *sess, aoff64_t *nblocks) 957 { 958 sysarg_t nb_l; 959 sysarg_t nb_h; 960 961 async_exch_t *exch = async_exchange_begin(sess); 962 int rc = async_req_0_2(exch, BD_GET_NUM_BLOCKS, &nb_l, &nb_h); 963 async_exchange_end(exch); 964 965 if (rc == EOK) 949 static int get_num_blocks(int dev_phone, aoff64_t *nblocks) 950 { 951 sysarg_t nb_l, nb_h; 952 int rc; 953 954 rc = async_req_0_2(dev_phone, BD_GET_NUM_BLOCKS, &nb_l, &nb_h); 955 if (rc == EOK) { 966 956 *nblocks = (aoff64_t) MERGE_LOUP32(nb_l, nb_h); 967 957 } 958 968 959 return rc; 969 960 }
Note:
See TracChangeset
for help on using the changeset viewer.
