Changes in uspace/lib/block/block.c [4e00f87:dd8b6a8] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/block/block.c
r4e00f87 rdd8b6a8 37 37 */ 38 38 39 #include "../../srv/vfs/vfs.h"40 39 #include <ipc/loc.h> 41 40 #include <ipc/services.h> 42 41 #include <errno.h> 43 #include <sys/mman.h>44 42 #include <async.h> 45 43 #include <as.h> … … 57 55 #include "block.h" 58 56 57 #define MAX_WRITE_RETRIES 10 58 59 59 /** Lock protecting the device connection list */ 60 60 static FIBRIL_MUTEX_INITIALIZE(dcl_lock); … … 81 81 void *bb_buf; 82 82 aoff64_t bb_addr; 83 aoff64_t pblocks; /**< Number of physical blocks */ 83 84 size_t pblock_size; /**< Physical block size. */ 84 85 cache_t *cache; … … 93 94 fibril_mutex_lock(&dcl_lock); 94 95 95 list_foreach(dcl, cur) { 96 devcon_t *devcon = list_get_instance(cur, devcon_t, link); 96 list_foreach(dcl, link, devcon_t, devcon) { 97 97 if (devcon->service_id == service_id) { 98 98 fibril_mutex_unlock(&dcl_lock); … … 106 106 107 107 static int devcon_add(service_id_t service_id, async_sess_t *sess, 108 size_t bsize, bd_t *bd)108 size_t bsize, aoff64_t dev_size, bd_t *bd) 109 109 { 110 110 devcon_t *devcon; … … 121 121 devcon->bb_addr = 0; 122 122 devcon->pblock_size = bsize; 123 devcon->pblocks = dev_size; 123 124 devcon->cache = NULL; 124 125 125 126 fibril_mutex_lock(&dcl_lock); 126 list_foreach(dcl, cur) { 127 devcon_t *d = list_get_instance(cur, devcon_t, link); 127 list_foreach(dcl, link, devcon_t, d) { 128 128 if (d->service_id == service_id) { 129 129 fibril_mutex_unlock(&dcl_lock); … … 168 168 return rc; 169 169 } 170 171 rc = devcon_add(service_id, sess, bsize, bd); 170 171 aoff64_t dev_size; 172 rc = bd_get_num_blocks(bd, &dev_size); 172 173 if (rc != EOK) { 173 174 bd_close(bd); … … 176 177 } 177 178 179 rc = devcon_add(service_id, sess, bsize, dev_size, bd); 180 if (rc != EOK) { 181 bd_close(bd); 182 async_hangup(sess); 183 return rc; 184 } 185 178 186 return EOK; 179 187 } … … 186 194 if (devcon->cache) 187 195 (void) block_cache_fini(service_id); 196 197 (void)bd_sync_cache(devcon->bd, 0, 0); 188 198 189 199 devcon_remove(devcon); … … 353 363 fibril_mutex_initialize(&b->lock); 354 364 b->refcnt = 1; 365 b->write_failures = 0; 355 366 b->dirty = false; 356 367 b->toxic = false; … … 377 388 block_t *b; 378 389 link_t *link; 379 390 aoff64_t p_ba; 380 391 int rc; 381 392 … … 386 397 387 398 cache = devcon->cache; 399 400 /* Check whether the logical block (or part of it) is beyond 401 * the end of the device or not. 402 */ 403 p_ba = ba_ltop(devcon, ba); 404 p_ba += cache->blocks_cluster; 405 if (p_ba >= devcon->pblocks) { 406 /* This request cannot be satisfied */ 407 return EIO; 408 } 409 388 410 389 411 retry: … … 462 484 * another block next time. 463 485 */ 464 fibril_mutex_unlock(&b->lock); 465 goto retry; 466 } 486 if (b->write_failures < MAX_WRITE_RETRIES) { 487 b->write_failures++; 488 fibril_mutex_unlock(&b->lock); 489 goto retry; 490 } else { 491 printf("Too many errors writing block %" 492 PRIuOFF64 "from device handle %" PRIun "\n" 493 "SEVERE DATA LOSS POSSIBLE\n", 494 b->lba, devcon->service_id); 495 } 496 } else 497 b->write_failures = 0; 498 467 499 b->dirty = false; 468 500 if (!fibril_mutex_trylock(&cache->lock)) { … … 581 613 rc = write_blocks(devcon, block->pba, cache->blocks_cluster, 582 614 block->data, block->size); 615 if (rc == EOK) 616 block->write_failures = 0; 583 617 block->dirty = false; 584 618 } … … 606 640 */ 607 641 block->refcnt++; 608 fibril_mutex_unlock(&block->lock); 609 fibril_mutex_unlock(&cache->lock); 610 goto retry; 642 643 if (block->write_failures < MAX_WRITE_RETRIES) { 644 block->write_failures++; 645 fibril_mutex_unlock(&block->lock); 646 fibril_mutex_unlock(&cache->lock); 647 goto retry; 648 } else { 649 printf("Too many errors writing block %" 650 PRIuOFF64 "from device handle %" PRIun "\n" 651 "SEVERE DATA LOSS POSSIBLE\n", 652 block->lba, devcon->service_id); 653 } 611 654 } 612 655 /* … … 774 817 devcon_t *devcon = devcon_search(service_id); 775 818 assert(devcon); 776 819 777 820 return bd_get_num_blocks(devcon->bd, nblocks); 778 821 } … … 836 879 * 837 880 * @return Allocated TOC structure. 838 * @return NULL on failure. 839 * 840 */ 841 toc_block_t *block_get_toc(service_id_t service_id, uint8_t session) 881 * @return EOK on success or negative error code. 882 * 883 */ 884 int block_read_toc(service_id_t service_id, uint8_t session, void *buf, 885 size_t bufsize) 842 886 { 843 887 devcon_t *devcon = devcon_search(service_id); 844 toc_block_t *toc = NULL; 845 int rc; 846 847 assert(devcon); 848 849 toc = (toc_block_t *) malloc(sizeof(toc_block_t)); 850 if (toc == NULL) 851 return NULL; 852 853 rc = bd_read_toc(devcon->bd, session, toc, sizeof(toc_block_t)); 854 if (rc != EOK) { 855 free(toc); 856 return NULL; 857 } 858 859 return toc; 888 889 assert(devcon); 890 return bd_read_toc(devcon->bd, session, buf, bufsize); 860 891 } 861 892
Note:
See TracChangeset
for help on using the changeset viewer.