Changeset 66bea243 in mainline


Ignore:
Timestamp:
2011-03-09T20:48:54Z (13 years ago)
Author:
Martin Sucha <sucha14@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
f8c60f5
Parents:
868ef40
Message:

Some unrelated changes to pipefs

Location:
uspace/srv/fs/pipefs
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/fs/pipefs/pipefs.c

    r868ef40 r66bea243  
    5757vfs_info_t pipefs_vfs_info = {
    5858        .name = NAME,
     59        .concurrent_read_write = true,
     60        .write_retains_size = true,
    5961};
    6062
  • uspace/srv/fs/pipefs/pipefs.h

    r868ef40 r66bea243  
    3939#include <bool.h>
    4040#include <adt/hash_table.h>
     41#include <fibril_synch.h>
    4142
    4243#define PIPEFS_NODE(node)       ((node) ? (pipefs_node_t *)(node)->data : NULL)
     
    6667        unsigned lnkcnt;        /**< Link count. */
    6768        /* 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;
    6872        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 */
    7175        /* 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. */
    7377} 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;
    8078
    8179extern fs_reg_t pipefs_reg;
  • uspace/srv/fs/pipefs/pipefs_ops.c

    r868ef40 r66bea243  
    9696static aoff64_t pipefs_size_get(fs_node_t *fn)
    9797{
    98         return PIPEFS_NODE(fn)->size;
     98        return 0;
    9999}
    100100
     
    189189        }
    190190
    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         }
    201191        free(nodep->bp);
    202192        free(nodep);
     
    218208        nodep->lnkcnt = 0;
    219209        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);
    222215        link_initialize(&nodep->nh_link);
    223216        list_initialize(&nodep->cs_head);
     
    479472        assert(rc == EOK);
    480473        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);
    482475        free(opts);
    483476}
     
    542535        size_t bytes;
    543536        if (nodep->type == PIPEFS_FILE) {
     537                fibril_mutex_lock(&nodep->data_lock);
     538               
    544539                /*
    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
    547541                 */
    548                 if (pos < nodep->start) {
     542                if (pos != nodep->start) {
    549543                        async_answer_0(callid, ENOTSUP);
    550544                        async_answer_0(rid, ENOTSUP);
     545                        fibril_mutex_unlock(&nodep->data_lock);
    551546                        return;
    552547                }
    553548               
    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);
    573552                }
    574553               
    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);
    600568                }
    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);
    611571        } else {
    612572                pipefs_dentry_t *dentryp;
     
    678638                return;
    679639        }
     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);
    680648
    681649        /*
    682650         * Check whether we are writing to the end
    683651         */
    684         if (pos != nodep->size) {
     652        if (pos != nodep->start+nodep->data_size) {
     653                fibril_mutex_unlock(&nodep->data_lock);
    685654                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);
    689667       
    690668        /*
    691669         * 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
    694671         */
    695672        void *newdata = malloc(size);
    696673        if (!newdata) {
     674                fibril_mutex_unlock(&nodep->data_lock);
    697675                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);
    729701}
    730702
Note: See TracChangeset for help on using the changeset viewer.