Changeset 656 for trunk/kernel/fs/vfs.c


Ignore:
Timestamp:
Dec 6, 2019, 12:07:51 PM (4 years ago)
Author:
alain
Message:

Fix several bugs in the FATFS and in the VFS,
related to the creation of big files requiring
more than 4 Kbytes (one cluster) on device.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/fs/vfs.c

    r651 r656  
    235235
    236236#if DEBUG_VFS_INODE_CREATE
    237 char           name[CONFIG_VFS_MAX_NAME_LENGTH];
    238237uint32_t       cycle      = (uint32_t)hal_get_cycles();
    239238thread_t *     this       = CURRENT_THREAD;
    240 vfs_inode_get_name( *inode_xp , name );
    241239if( DEBUG_VFS_INODE_CREATE < cycle )
    242 printk("\n[%s] thread[%x,%x] created <%s> / inode [%x,%x] / cycle %d\n",
    243 __FUNCTION__, this->process->pid, this->trdid, name, local_cxy, inode, cycle );
     240printk("\n[%s] thread[%x,%x] created inode (%x,%x) / cycle %d\n",
     241__FUNCTION__, this->process->pid, this->trdid, local_cxy, inode, cycle );
    244242#endif
    245243 
     
    513511uint32_t   cycle = (uint32_t)hal_get_cycles();
    514512if( DEBUG_VFS_DENTRY_CREATE < cycle )
    515 printk("\n[%s] thread[%x,%x] created <%s> / dentry [%x,%x] / cycle %d\n",
     513printk("\n[%s] thread[%x,%x] created dentry <%s> : (%x,%x) / cycle %d\n",
    516514__FUNCTION__, this->process->pid, this->trdid, name, local_cxy, dentry, cycle );
    517515#endif
     
    777775}  // end vfs_open()
    778776
    779 //////////////////////////////////////
    780 int vfs_user_move( bool_t   to_buffer,
    781                    xptr_t   file_xp,
    782                    void   * buffer,
    783                    uint32_t size )
    784 {
    785     cxy_t              file_cxy;     // remote file descriptor cluster
    786     vfs_file_t       * file_ptr;     // remote file descriptor local pointer
    787     vfs_inode_type_t   inode_type;
    788     uint32_t           file_offset;  // current offset in file
    789     mapper_t         * mapper;
     777///////////////////////////////////////////
     778uint32_t vfs_user_move( bool_t   to_buffer,
     779                        xptr_t   file_xp,
     780                        void   * buffer,
     781                        uint32_t count )
     782{
     783    cxy_t              file_cxy;       // remote file descriptor cluster
     784    vfs_file_t       * file_ptr;       // remote file descriptor local pointer
     785    mapper_t         * mapper;         // local pointer on file mapper
     786    vfs_inode_t      * inode;          // local pointer on file inode
     787    vfs_inode_type_t   type;           // inode type
     788    uint32_t           offset;         // current offset in file
     789    uint32_t           size;           // current file size
     790    uint32_t           nbytes;         // number of bytes actually transfered
    790791    error_t            error;
    791792
     
    797798    file_ptr  = GET_PTR( file_xp );
    798799
    799     // get inode type from remote file descriptor
    800     inode_type = hal_remote_l32( XPTR( file_cxy , &file_ptr->type   ) );
     800    // get various infos from remote file descriptor
     801    type   = hal_remote_l32( XPTR( file_cxy , &file_ptr->type   ) );
     802    offset = hal_remote_l32( XPTR( file_cxy , &file_ptr->offset ) );
     803    mapper = hal_remote_lpt( XPTR( file_cxy , &file_ptr->mapper ) );
     804    inode  = hal_remote_lpt( XPTR( file_cxy , &file_ptr->inode  ) );
     805    size   = hal_remote_l32( XPTR( file_cxy , &inode->size      ) );
    801806   
    802807// check inode type
    803 assert( (inode_type == INODE_TYPE_FILE), "bad inode type" );
    804 
    805     // get mapper pointer and file offset from file descriptor
    806     file_offset = hal_remote_l32( XPTR( file_cxy , &file_ptr->offset ) );
    807     mapper      = hal_remote_lpt( XPTR( file_cxy , &file_ptr->mapper ) );
     808assert( (type == INODE_TYPE_FILE), "bad inode type" );
    808809
    809810#if DEBUG_VFS_USER_MOVE
     
    811812uint32_t      cycle      = (uint32_t)hal_get_cycles();
    812813thread_t    * this       = CURRENT_THREAD;
    813 vfs_inode_t * inode      = hal_remote_lpt( XPTR( file_cxy , &file_ptr->inode ) );
    814814vfs_inode_get_name( XPTR( file_cxy , inode ) , name );
    815815if( cycle > DEBUG_VFS_USER_MOVE )
     
    817817    if( to_buffer )
    818818    printk("\n[%s] thread[%x,%x] enter / %d bytes / map(%s) -> buf(%x) / offset %d / cycle %d\n",
    819     __FUNCTION__ , this->process->pid, this->trdid, size, name, buffer, file_offset, cycle );
     819    __FUNCTION__ , this->process->pid, this->trdid, count, name, buffer, offset, cycle );
    820820    else           
    821821    printk("\n[%s] thread[%x,%x] enter / %d bytes / buf(%x) -> map(%s) / offset %d / cycle %d\n",
    822     __FUNCTION__ , this->process->pid, this->trdid, size, buffer, name, file_offset, cycle );
     822    __FUNCTION__ , this->process->pid, this->trdid, count, buffer, name, offset, cycle );
    823823}
    824824#endif
    825825
    826     // move data between mapper and buffer
    827     error = mapper_move_user( XPTR( file_cxy , mapper ),
    828                               to_buffer,
    829                               file_offset,
    830                               buffer,
    831                               size );
     826    if( to_buffer ) // => compute the number of bytes to move and make the move
     827    {
     828        // compute number of bytes to move
     829        if     ( size <= offset )         nbytes = 0;
     830        else if( size < offset + count )  nbytes = size - offset;
     831        else                              nbytes = count;
     832
     833        // move data from mapper to buffer when required
     834        if( nbytes > 0 )
     835        {     
     836            error = mapper_move_user( XPTR( file_cxy , mapper ),
     837                                      to_buffer,
     838                                      offset,
     839                                      buffer,
     840                                      nbytes );
     841        }
     842        else
     843        {
     844            error = 0;
     845        }
     846    }
     847    else // to mapper => make the move and update the file size if required
     848    {
     849        nbytes = count;
     850
     851        // move data from buffer to mapper
     852        error = mapper_move_user( XPTR( file_cxy , mapper ),
     853                                  to_buffer,
     854                                  offset,
     855                                  buffer,
     856                                  count );
     857
     858        // update file size in inode if required
     859        if( offset + count > size )
     860        {
     861            vfs_inode_update_size( XPTR( file_cxy , inode ) , offset + count );
     862        }
     863    }
     864       
    832865    if( error )
    833866    {
     
    837870
    838871    // update file offset in file descriptor
    839     hal_remote_atomic_add( XPTR( file_cxy , &file_ptr->offset ) , size );
     872    hal_remote_atomic_add( XPTR( file_cxy , &file_ptr->offset ) , nbytes );
    840873
    841874#if DEBUG_VFS_USER_MOVE
     
    844877{
    845878    if( to_buffer )
    846     printk("\n[%s] thread[%x,%x] exit / cycle %d\n",
    847     __FUNCTION__ , this->process->pid, cycle );
     879    printk("\n[%s] thread[%x,%x] exit / %d bytes moved from mapper to buffer\n",
     880    __FUNCTION__ , this->process->pid, nbytes );
    848881    else           
    849     printk("\n[%s] thread[%x,%x] exit / cycle %d\n",
    850     __FUNCTION__ , this->process->pid, cycle );
     882    printk("\n[%s] thread[%x,%x] exit / %d bytes moved from buffer to mapper / size %d\n",
     883    __FUNCTION__ , this->process->pid, nbytes, hal_remote_l32(XPTR(file_cxy,&inode->size)) );
    851884}
    852885#endif
    853886
    854     return size;
     887    return nbytes;
    855888
    856889}  // end vfs_user_move()
     
    24832516#endif
    24842517
     2518#if ( DEBUG_VFS_LOOKUP & 1 )
     2519if( DEBUG_VFS_LOOKUP < cycle )
     2520vfs_display( root_xp );
     2521#endif
     2522
    24852523    // compute lookup flags
    24862524    create = (lookup_mode & VFS_LOOKUP_CREATE) == VFS_LOOKUP_CREATE;
     
    25272565#endif
    25282566
    2529         // search the child dentry matching name in parent inode
     2567        // search the child dentry matching name in parent inode XHTAB
    25302568        found = vfs_get_child( parent_xp,
    25312569                               name,
     
    25932631#if (DEBUG_VFS_LOOKUP & 1)
    25942632if( DEBUG_VFS_LOOKUP < cycle )
    2595 printk("\n[%s] thread[%x,%x] created missing inode for <%s> in cluster %x\n",
     2633printk("\n[%s] thread[%x,%x] created missing inode <%s> in cluster %x\n",
    25962634__FUNCTION__, process->pid, this->trdid, name, child_cxy );
    25972635#endif
     
    27712809{
    27722810    error_t     error;
    2773     uint32_t    cluster;
     2811    uint32_t    cluster_id;
    27742812    uint32_t    child_type;
    27752813    uint32_t    child_size;
     
    27982836    vfs_inode_t  * child_ptr  = GET_PTR( child_xp );
    27992837
    2800     // 1. allocate one free cluster in file system to child inode,
     2838    // 1. allocate one free cluster_id in file system to child inode,
    28012839    // and update the File Allocation Table in both the FAT mapper and IOC device.
    28022840    // It depends on the child inode FS type.
     
    28042842
    28052843    error = vfs_fs_cluster_alloc( ctx->type,
    2806                                   &cluster );
     2844                                  &cluster_id );
    28072845    if ( error )
    28082846    {
    2809         printk("\n[ERROR] in %s : cannot find a free VFS cluster\n",
     2847        printk("\n[ERROR] in %s : cannot find a free VFS cluster_id\n",
    28102848        __FUNCTION__ );
    28112849        return -1;
     
    28142852#if( DEBUG_VFS_NEW_DENTRY_INIT & 1)
    28152853if( DEBUG_VFS_NEW_DENTRY_INIT < cycle )
    2816 printk("\n[%s] thread[%x,%x] allocated FS cluster %x to <%s>\n",
    2817 __FUNCTION__ , this->process->pid, this->trdid, cluster, child_name );
     2854printk("\n[%s] thread[%x,%x] allocated FS cluster_id %x to <%s>\n",
     2855__FUNCTION__ , this->process->pid, this->trdid, cluster_id, child_name );
    28182856#endif
    28192857
    28202858    // 2. update the child inode descriptor size and extend
    28212859    child_type = hal_remote_l32( XPTR( child_cxy , &child_ptr->type ) );
    2822     child_size = (child_type == INODE_TYPE_DIR) ? 4096 : 0;
     2860    child_size = 0;
    28232861   
    28242862    hal_remote_s32( XPTR( child_cxy , &child_ptr->size )   , child_size );
    2825     hal_remote_spt( XPTR( child_cxy , &child_ptr->extend ) , (void*)(intptr_t)cluster );
     2863    hal_remote_spt( XPTR( child_cxy , &child_ptr->extend ) , (void*)(intptr_t)cluster_id );
    28262864
    28272865    // 3. update the parent inode mapper, and
     
    32853323#if(DEBUG_VFS_ADD_CHILD & 1)
    32863324if( DEBUG_VFS_ADD_CHILD < cycle )
    3287 printk("\n[%s] thread[%x,%x] / dentry <%s> created (%x,%x)\n",
     3325printk("\n[%s] thread[%x,%x] created dentry <%s> : (%x,%x)\n",
    32883326__FUNCTION__, this->process->pid, this->trdid, name, parent_cxy, new_dentry_ptr );
    32893327#endif
     
    33323370#if(DEBUG_VFS_ADD_CHILD & 1)
    33333371if( DEBUG_VFS_ADD_CHILD < cycle )
    3334 printk("\n[%s] thread[%x,%x] / inode <%s> created (%x,%x)\n",
     3372printk("\n[%s] thread[%x,%x] created inode <%s> : (%x,%x)\n",
    33353373__FUNCTION__ , this->process->pid, this->trdid, name , child_cxy, new_inode_ptr );
    33363374#endif
     
    33453383#if(DEBUG_VFS_ADD_CHILD & 1)
    33463384if( DEBUG_VFS_ADD_CHILD < cycle )
    3347 printk("\n[%s] thread[%x,%x] link dentry(%x,%x) to child inode(%x,%x)\n",
     3385printk("\n[%s] thread[%x,%x] linked dentry(%x,%x) to child inode(%x,%x)\n",
    33483386__FUNCTION__, this->process->pid, this->trdid,
    33493387parent_cxy, new_dentry_ptr, child_cxy, new_inode_ptr );
     
    33573395#if(DEBUG_VFS_ADD_CHILD & 1)
    33583396if( DEBUG_VFS_ADD_CHILD < cycle )
    3359 printk("\n[%s] thread[%x,%x] link dentry(%x,%x) to parent inode(%x,%x)\n",
     3397printk("\n[%s] thread[%x,%x] linked dentry(%x,%x) to parent inode(%x,%x)\n",
    33603398__FUNCTION__, this->process->pid, this->trdid,
    33613399parent_cxy, new_dentry_ptr, parent_cxy, parent_inode_ptr );
     
    38143852    return error;
    38153853
    3816 } // end vfs_fs_alloc_cluster()
     3854} // end vfs_fs_cluster_alloc()
    38173855
    38183856////////////////////////////////////////////////
Note: See TracChangeset for help on using the changeset viewer.