Changeset 66bea243 in mainline
- Timestamp:
- 2011-03-09T20:48:54Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f8c60f5
- Parents:
- 868ef40
- Location:
- uspace/srv/fs/pipefs
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/fs/pipefs/pipefs.c
r868ef40 r66bea243 57 57 vfs_info_t pipefs_vfs_info = { 58 58 .name = NAME, 59 .concurrent_read_write = true, 60 .write_retains_size = true, 59 61 }; 60 62 -
uspace/srv/fs/pipefs/pipefs.h
r868ef40 r66bea243 39 39 #include <bool.h> 40 40 #include <adt/hash_table.h> 41 #include <fibril_synch.h> 41 42 42 43 #define PIPEFS_NODE(node) ((node) ? (pipefs_node_t *)(node)->data : NULL) … … 66 67 unsigned lnkcnt; /**< Link count. */ 67 68 /* Following is for nodes of type PIPEFS_FILE */ 69 fibril_mutex_t data_lock; 70 fibril_condvar_t data_available; 71 fibril_condvar_t data_consumed; 68 72 aoff64_t start; /**< File offset where first data block resides */ 69 size_t size; /**< File size if type is PIPEFS_FILE.*/70 link_t data_head; /**< Head of data blocks list for PIPEFS_FILE.*/73 uint8_t *data; /**< Pointer to data buffer */ 74 size_t data_size; /**< Number of remaining bytes in the data buffer */ 71 75 /* This is for directory */ 72 link_t cs_head; /**< Head of child's siblings list. */ 76 link_t cs_head; /**< Head of child's siblings list. */ 73 77 } pipefs_node_t; 74 75 typedef struct pipefs_data_block {76 link_t link; /**< Linkage for the list of data blocks */77 size_t size; /**< Size of this block */78 void *data; /**< Data for this block */79 } pipefs_data_block_t;80 78 81 79 extern fs_reg_t pipefs_reg; -
uspace/srv/fs/pipefs/pipefs_ops.c
r868ef40 r66bea243 96 96 static aoff64_t pipefs_size_get(fs_node_t *fn) 97 97 { 98 return PIPEFS_NODE(fn)->size;98 return 0; 99 99 } 100 100 … … 189 189 } 190 190 191 while (!list_empty(&nodep->data_head)) {192 assert(nodep->type == PIPEFS_FILE);193 194 pipefs_data_block_t *data_block = list_get_instance(nodep->data_head.next,195 pipefs_data_block_t, link);196 197 list_remove(&data_block->link);198 free(data_block->data);199 free(data_block);200 }201 191 free(nodep->bp); 202 192 free(nodep); … … 218 208 nodep->lnkcnt = 0; 219 209 nodep->start = 0; 220 nodep->size = 0; 221 list_initialize(&nodep->data_head); 210 nodep->data = NULL; 211 nodep->data_size = 0; 212 fibril_mutex_initialize(&nodep->data_lock); 213 fibril_condvar_initialize(&nodep->data_available); 214 fibril_condvar_initialize(&nodep->data_consumed); 222 215 link_initialize(&nodep->nh_link); 223 216 list_initialize(&nodep->cs_head); … … 479 472 assert(rc == EOK); 480 473 pipefs_node_t *rootp = PIPEFS_NODE(rootfn); 481 async_answer_3(rid, EOK, rootp->index, rootp->size, rootp->lnkcnt);474 async_answer_3(rid, EOK, rootp->index, 0, rootp->lnkcnt); 482 475 free(opts); 483 476 } … … 542 535 size_t bytes; 543 536 if (nodep->type == PIPEFS_FILE) { 537 fibril_mutex_lock(&nodep->data_lock); 538 544 539 /* 545 * Check if we still have the requested data. 546 * This may happen if the client seeked backwards 540 * Check if the client didn't seek somewhere else 547 541 */ 548 if (pos <nodep->start) {542 if (pos != nodep->start) { 549 543 async_answer_0(callid, ENOTSUP); 550 544 async_answer_0(rid, ENOTSUP); 545 fibril_mutex_unlock(&nodep->data_lock); 551 546 return; 552 547 } 553 548 554 /* 555 * Free all data blocks that end before pos. 556 * This is in case the client seeked forward 557 */ 558 while (!list_empty(&nodep->data_head)) { 559 pipefs_data_block_t *data_block = 560 list_get_instance(nodep->data_head.next, 561 pipefs_data_block_t, link); 562 563 aoff64_t block_end = nodep->start + data_block->size; 564 565 if (block_end > pos) { 566 break; 567 } 568 569 list_remove(&data_block->link); 570 free(data_block->data); 571 free(data_block); 572 nodep->start = block_end; 549 if (nodep->data == NULL || nodep->data_size > 0) { 550 // Wait for the data 551 fibril_condvar_wait(&nodep->data_available, &nodep->data_lock); 573 552 } 574 553 575 if (!list_empty(&nodep->data_head)) { 576 /* We have data block, so let's return its portion after pos */ 577 pipefs_data_block_t *data_block = 578 list_get_instance(nodep->data_head.next, 579 pipefs_data_block_t, link); 580 581 assert(nodep->start <= pos); 582 583 aoff64_t block_end = nodep->start + data_block->size; 584 size_t block_offset = pos - nodep->start; 585 586 assert(block_end > pos); 587 588 bytes = min(block_end - pos, size); 589 (void) async_data_read_finalize(callid, 590 data_block->data + block_offset, 591 bytes); 592 593 if (nodep->start + block_offset + bytes == block_end) { 594 /* Free the data block - it was fully read */ 595 list_remove(&data_block->link); 596 free(data_block->data); 597 free(data_block); 598 nodep->start = block_end; 599 } 554 assert(nodep->data != NULL); 555 assert(nodep->data_size > 0); 556 557 bytes = min(size, nodep->data_size); 558 559 (void) async_data_read_finalize(callid, nodep->data, bytes); 560 561 nodep->data += bytes; 562 nodep->data_size -= bytes; 563 nodep->start += bytes; 564 565 if (nodep->data_size == 0) { 566 nodep->data = NULL; 567 fibril_condvar_broadcast(&nodep->data_consumed); 600 568 } 601 else { 602 /* 603 * there is no data 604 * TODO implement waiting for the data 605 * and remove this else clause 606 */ 607 async_answer_0(callid, ENOTSUP); 608 async_answer_1(rid, ENOTSUP, 0); 609 return; 610 } 569 570 fibril_mutex_unlock(&nodep->data_lock); 611 571 } else { 612 572 pipefs_dentry_t *dentryp; … … 678 638 return; 679 639 } 640 641 if (size == 0) { 642 async_data_write_finalize(callid, NULL, 0); 643 async_answer_2(rid, EOK, 0, 0); 644 return; 645 } 646 647 fibril_mutex_lock(&nodep->data_lock); 680 648 681 649 /* 682 650 * Check whether we are writing to the end 683 651 */ 684 if (pos != nodep->size) { 652 if (pos != nodep->start+nodep->data_size) { 653 fibril_mutex_unlock(&nodep->data_lock); 685 654 async_answer_0(callid, ENOTSUP); 686 async_answer_2(rid, EOK, 0, nodep->size); 687 return; 688 } 655 async_answer_0(rid, ENOTSUP); 656 return; 657 } 658 659 /* 660 * Wait until there is no data buffer 661 */ 662 if (nodep->data != NULL) { 663 fibril_condvar_wait(&nodep->data_consumed, &nodep->data_lock); 664 } 665 666 assert(nodep->data == NULL); 689 667 690 668 /* 691 669 * Allocate a buffer for the new data. 692 * Currently we accept any size, create a data block from this 693 * and append it to the end of a file 670 * Currently we accept any size 694 671 */ 695 672 void *newdata = malloc(size); 696 673 if (!newdata) { 674 fibril_mutex_unlock(&nodep->data_lock); 697 675 async_answer_0(callid, ENOMEM); 698 async_answer_2(rid, EOK, 0, nodep->size); 699 return; 700 } 701 702 pipefs_data_block_t *newblock = malloc(sizeof(pipefs_data_block_t)); 703 704 if (!newblock) { 705 free(newdata); 706 async_answer_0(callid, ENOMEM); 707 async_answer_2(rid, EOK, 0, nodep->size); 708 return; 709 } 710 711 int rc = async_data_write_finalize(callid, newdata, size); 712 713 if (rc != EOK) { 714 free(newblock); 715 free(newdata); 716 async_answer_0(callid, rc); 717 async_answer_2(rid, EOK, 0, nodep->size); 718 return; 719 } 720 721 link_initialize(&newblock->link); 722 newblock->size = size; 723 newblock->data = newdata; 724 list_append(&newblock->link, &nodep->data_head); 725 726 nodep->size += size; 727 728 async_answer_2(rid, EOK, size, nodep->size); 676 async_answer_0(rid, ENOMEM); 677 return; 678 } 679 680 (void) async_data_write_finalize(callid, newdata, size); 681 682 nodep->data = newdata; 683 nodep->data_size = size; 684 685 fibril_mutex_unlock(&nodep->data_lock); 686 687 // Signal that the data is ready 688 fibril_condvar_signal(&nodep->data_available); 689 690 fibril_mutex_lock(&nodep->data_lock); 691 692 // Wait until all data is consumed 693 fibril_condvar_wait(&nodep->data_consumed, &nodep->data_lock); 694 695 assert(nodep->data == NULL); 696 697 fibril_mutex_unlock(&nodep->data_lock); 698 free(newdata); 699 700 async_answer_2(rid, EOK, size, 0); 729 701 } 730 702
Note:
See TracChangeset
for help on using the changeset viewer.