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/mm/mapper.c

    r651 r656  
    2727#include <hal_special.h>
    2828#include <hal_uspace.h>
     29#include <hal_vmm.h>
    2930#include <grdxt.h>
    3031#include <string.h>
     
    141142    error_t    error;
    142143
     144    uint32_t   inode_size;   
     145    uint32_t   inode_type;
     146
    143147    thread_t * this = CURRENT_THREAD;
    144148
    145149    // get target mapper cluster and local pointer
    146     cxy_t      mapper_cxy = GET_CXY( mapper_xp );
    147     mapper_t * mapper_ptr = GET_PTR( mapper_xp );
     150    cxy_t         mapper_cxy = GET_CXY( mapper_xp );
     151    mapper_t    * mapper_ptr = GET_PTR( mapper_xp );
     152
     153    // get inode pointer
     154    vfs_inode_t * inode = hal_remote_lpt( XPTR( mapper_cxy , &mapper_ptr->inode ) );
     155
     156    // get inode size and type if relevant
     157    if( inode != NULL )
     158    {
     159        inode_size = hal_remote_l32( XPTR( mapper_cxy , &inode->size ) );
     160        inode_type = hal_remote_l32( XPTR( mapper_cxy , &inode->type ) );
     161    }
     162    else
     163    {
     164        inode_size = 0;
     165        inode_type = 0;
     166    }
    148167
    149168#if DEBUG_MAPPER_HANDLE_MISS
    150169uint32_t      cycle = (uint32_t)hal_get_cycles();
    151170char          name[CONFIG_VFS_MAX_NAME_LENGTH];
    152 vfs_inode_t * inode = mapper->inode;
    153171if( (DEBUG_MAPPER_HANDLE_MISS < cycle) && (inode != NULL) )
    154172{
    155     vfs_inode_get_name( XPTR( local_cxy , inode ) , name );
    156     printk("\n[%s] thread[%x,%x] enter for page %d in <%s> / cluster %x / cycle %d",
     173    vfs_inode_get_name( XPTR( mapper_cxy , inode ) , name );
     174    printk("\n[%s] thread[%x,%x] enter for page %d in <%s> / cxy %x / cycle %d\n",
    157175    __FUNCTION__, this->process->pid, this->trdid, page_id, name, mapper_cxy, cycle );
    158     if( DEBUG_MAPPER_HANDLE_MISS & 1 ) grdxt_display( XPTR(local_cxy,&mapper->rt), name );
    159176}
    160177if( (DEBUG_MAPPER_HANDLE_MISS < cycle) && (inode == NULL) )
    161178{
    162     printk("\n[%s] thread[%x,%x] enter for page %d in FAT / cluster %x / cycle %d",
     179    printk("\n[%s] thread[%x,%x] enter for page %d in FAT / cxy %x / cycle %d\n",
    163180    __FUNCTION__, this->process->pid, this->trdid, page_id, mapper_cxy, cycle );
    164     if( DEBUG_MAPPER_HANDLE_MISS & 1 ) grdxt_display( XPTR(local_cxy,&mapper->rt), "FAT" );
     181}
     182#endif
     183
     184#if( DEBUG_MAPPER_HANDLE_MISS & 2 )
     185if( DEBUG_MAPPER_HANDLE_MISS < cycle )
     186{
     187    if (inode != NULL) grdxt_remote_display( XPTR( mapper_cxy , &mapper_ptr->rt ) , name );
     188    else               grdxt_remote_display( XPTR( mapper_cxy , &mapper_ptr->rt ) , "FAT" );
    165189}
    166190#endif
    167191
    168192    // allocate one 4 Kbytes page from the remote mapper cluster
    169     page_t * page_ptr = ppm_remote_alloc_pages( mapper_cxy , 0 );
     193    xptr_t page_xp = ppm_remote_alloc_pages( mapper_cxy , 0 );
     194    page_t * page_ptr = GET_PTR( page_xp );
    170195                           
    171     if( page_ptr == NULL )
     196    if( page_xp == XPTR_NULL )
    172197    {
    173198        printk("\n[ERROR] in %s : thread [%x,%x] cannot allocate page in cluster %x\n",
     
    176201    }
    177202
    178     // build extended pointer on new page descriptor
    179     xptr_t page_xp = XPTR( mapper_cxy , page_ptr );
    180 
    181203    // initialize the page descriptor
    182204    page_remote_init( page_xp );
    183205
     206    // initialize specific page descriptor fields
    184207    hal_remote_s32( XPTR( mapper_cxy , &page_ptr->refcount ) , 1          );
    185208    hal_remote_s32( XPTR( mapper_cxy , &page_ptr->index )    , page_id    );
     
    200223    }
    201224
    202     // launch I/O operation to load page from IOC device to mapper
    203     error = vfs_fs_move_page( page_xp , IOC_SYNC_READ );
    204 
    205     if( error )
    206     {
    207         printk("\n[ERROR] in %s : thread[%x,%x] cannot load page from device\n",
    208         __FUNCTION__ , this->process->pid, this->trdid );
    209         mapper_remote_release_page( mapper_xp , page_ptr );
    210         return -1;
     225    // launch I/O operation to load page from IOC device when required:
     226    // - it is the FAT mapper
     227    // - it is a directory mapper
     228    // - it is a file mapper, and it exist data on IOC device for this page
     229    if( (inode == NULL) || (inode_type == INODE_TYPE_DIR) || (inode_size > (page_id << 10) ) )
     230    {
     231        error = vfs_fs_move_page( page_xp , IOC_SYNC_READ );
     232
     233        if( error )
     234        {
     235            printk("\n[ERROR] in %s : thread[%x,%x] cannot load page from device\n",
     236            __FUNCTION__ , this->process->pid, this->trdid );
     237            mapper_remote_release_page( mapper_xp , page_ptr );
     238            return -1;
     239         }
    211240    }
    212241
     
    215244
    216245#if DEBUG_MAPPER_HANDLE_MISS
    217 cycle = (uint32_t)hal_get_cycles();
     246ppn_t ppn = ppm_page2ppn( page_xp );
    218247if( (DEBUG_MAPPER_HANDLE_MISS < cycle) && (inode != NULL) )
    219248{
    220     printk("\n[%s] thread[%x,%x] exit for page %d in <%s> / ppn %x / cycle %d",
    221     __FUNCTION__, this->process->pid, this->trdid,
    222     page_id, name, ppm_page2ppn( page_xp ), cycle );
    223     if( DEBUG_MAPPER_HANDLE_MISS & 1 ) grdxt_display( XPTR(local_cxy,&mapper->rt) , name );
     249    printk("\n[%s] thread[%x,%x] exit for page %d in <%s> / page %x / ppn %x\n",
     250    __FUNCTION__, this->process->pid, this->trdid, page_id, name, page_ptr, ppn );
    224251}
    225252if( (DEBUG_MAPPER_HANDLE_MISS < cycle) && (inode == NULL) )
    226253{
    227     printk("\n[%s] thread[%x,%x] exit for page %d in FAT / ppn %x / cycle %d",
    228     __FUNCTION__, this->process->pid, this->trdid,
    229     page_id, ppm_page2ppn( page_xp ), cycle );
    230     if( DEBUG_MAPPER_HANDLE_MISS & 1 ) grdxt_display( XPTR(local_cxy,&mapper->rt ), "FAT" );
     254    printk("\n[%s] thread[%x,%x] exit for page %d in FAT / page %x / ppn %x\n",
     255    __FUNCTION__, this->process->pid, this->trdid, page_id, page_ptr, ppn );
     256}
     257#endif
     258
     259#if( DEBUG_MAPPER_HANDLE_MISS & 2 )
     260if( DEBUG_MAPPER_HANDLE_MISS < cycle )
     261{
     262    if (inode != NULL) grdxt_remote_display( XPTR( mapper_cxy , &mapper_ptr->rt ) , name );
     263    else               grdxt_remote_display( XPTR( mapper_cxy , &mapper_ptr->rt ) , "FAT" );
    231264}
    232265#endif
     
    241274{
    242275    error_t       error;
    243     mapper_t    * mapper_ptr;
    244     cxy_t         mapper_cxy;
    245     xptr_t        lock_xp;        // extended pointer on mapper lock
    246     xptr_t        page_xp;        // extended pointer on searched page descriptor
    247     xptr_t        rt_xp;          // extended pointer on radix tree in mapper
    248276
    249277    thread_t * this = CURRENT_THREAD;
    250278
    251279    // get mapper cluster and local pointer
    252     mapper_ptr = GET_PTR( mapper_xp );
    253     mapper_cxy = GET_CXY( mapper_xp );
     280    mapper_t * mapper_ptr = GET_PTR( mapper_xp );
     281    cxy_t      mapper_cxy = GET_CXY( mapper_xp );
    254282
    255283#if DEBUG_MAPPER_GET_PAGE
     
    270298#endif
    271299
     300#if( DEBUG_MAPPER_GET_PAGE & 2 )
     301if( DEBUG_MAPPER_GET_PAGE < cycle )
     302ppm_remote_display( local_cxy );
     303#endif
     304
    272305    // check thread can yield
    273306    thread_assert_can_yield( this , __FUNCTION__ );
    274307
    275308    // build extended pointer on mapper lock and mapper rt
    276     lock_xp  = XPTR( mapper_cxy , &mapper_ptr->lock );
    277     rt_xp    = XPTR( mapper_cxy , &mapper_ptr->rt );
     309    xptr_t lock_xp  = XPTR( mapper_cxy , &mapper_ptr->lock );
     310    xptr_t rt_xp    = XPTR( mapper_cxy , &mapper_ptr->rt );
    278311
    279312    // take mapper lock in READ_MODE
     
    281314
    282315    // search page in radix tree
    283     page_xp  = grdxt_remote_lookup( rt_xp , page_id );
     316    xptr_t page_xp  = grdxt_remote_lookup( rt_xp , page_id );
    284317
    285318    // test mapper miss
     
    310343
    311344#if (DEBUG_MAPPER_GET_PAGE & 1)
    312 if( DEBUG_MAPPER_GET_PAGE < cycle )
    313 printk("\n[%s] thread[%x,%x] load missing page from FS : ppn %x\n",
    314 __FUNCTION__, this->process->pid, this->trdid, ppm_page2ppn(page_xp) );
     345if( (DEBUG_MAPPER_GET_PAGE < cycle) && (inode != NULL) )
     346{
     347    printk("\n[%s] thread[%x,%x] introduced missing page in <%s> mapper / ppn %x\n",
     348    __FUNCTION__, this->process->pid, this->trdid, name, ppm_page2ppn(page_xp) );
     349}
     350if( (DEBUG_MAPPER_GET_PAGE < cycle) && (inode == NULL) )
     351{
     352    printk("\n[%s] thread[%x,%x] introduced missing page in FAT mapper / ppn %x\n",
     353    __FUNCTION__, this->process->pid, this->trdid, ppm_page2ppn(page_xp) );
     354}
    315355#endif
    316356       
     
    328368if( (DEBUG_MAPPER_GET_PAGE < cycle) && (inode != NULL) )
    329369{
    330     printk("\n[%s] thread[%x,%x] exit for page %d of <%s> mapper / ppn %x / cycle %d\n",
    331     __FUNCTION__, this->process->pid, this->trdid, page_id,
    332     name, ppm_page2ppn(page_xp), cycle );
     370    printk("\n[%s] thread[%x,%x] exit for page %d of <%s> mapper / ppn %x\n",
     371    __FUNCTION__, this->process->pid, this->trdid, page_id, name, ppm_page2ppn(page_xp) );
    333372}
    334373if( (DEBUG_MAPPER_GET_PAGE < cycle) && (inode == NULL) )
    335374{
    336     printk("\n[%s] thread[%x,%x] exit for page %d of FAT mapper  / ppn %x / cycle %d\n",
    337     __FUNCTION__, this->process->pid, this->trdid, page_id,
    338     ppm_page2ppn(page_xp), cycle );
    339 }
     375    printk("\n[%s] thread[%x,%x] exit for page %d of FAT mapper  / ppn %x\n",
     376    __FUNCTION__, this->process->pid, this->trdid, page_id, ppm_page2ppn(page_xp) );
     377}
     378#endif
     379
     380#if( DEBUG_MAPPER_GET_PAGE & 2)
     381if( DEBUG_MAPPER_GET_PAGE < cycle )
     382ppm_remote_display( local_cxy );
    340383#endif
    341384
     
    476519__FUNCTION__, this->process->pid, this->trdid, page_bytes,
    477520local_cxy, buf_ptr, name, GET_CXY(map_xp), GET_PTR(map_xp) );
    478 mapper_display_page(  mapper_xp , page_id, 128 );
     521mapper_display_page(  mapper_xp , page_xp , 128 );
    479522#endif
    480523
     
    600643{
    601644    if( to_buffer )
    602     printk("\n[%s] mapper <%s> page %d => buffer(%x,%x) / %d bytes\n",
     645    printk("\n[%s] mapper <%s> page %d => buffer (%x,%x) / %d bytes\n",
    603646    __FUNCTION__, name, page_id, dst_cxy, dst_ptr, page_bytes );
    604647    else
    605     printk("\n[%s] buffer(%x,%x) => mapper <%s> page %d / %d bytes\n",
     648    printk("\n[%s] buffer (%x,%x) => mapper <%s> page %d / %d bytes\n",
    606649    __FUNCTION__, src_cxy, src_ptr, name, page_id, page_bytes );
    607650}
     
    617660cycle  = (uint32_t)hal_get_cycles();
    618661if( DEBUG_MAPPER_MOVE_KERNEL < cycle )
    619 printk("\n[%s] thread[%x,%x] exit / cycle %d\n",
    620 __FUNCTION__, this->process->pid, this->trdid, cycle );
     662printk("\n[%s] thread[%x,%x] exit / mapper <%s> / buffer (%x,%x) / cycle %d\n",
     663__FUNCTION__, this->process->pid, this->trdid, name, buffer_cxy, buffer_ptr, cycle );
    621664#endif
    622665
     
    707750        if( page == NULL ) break;
    708751
    709 assert( (page->index == found_key ), "wrong page descriptor index" );
    710 assert( (page->order == 0),          "mapper page order must be 0" );
     752assert( (page->index == found_key ), "page_index (%d) != key (%d)", page->index, found_key );
     753assert( (page->order == 0), "page_order (%d] != 0", page->order );
    711754
    712755        // build extended pointer on page descriptor
     
    753796}  // end mapper_sync()
    754797
    755 //////////////////////////////////////////////////
    756 error_t mapper_display_page( xptr_t     mapper_xp,
    757                              uint32_t   page_id,
    758                              uint32_t   nbytes )
    759 {
    760     xptr_t        page_xp;        // extended pointer on page descriptor
    761     xptr_t        base_xp;        // extended pointer on page base
     798///////////////////////////////////////////////
     799void mapper_display_page( xptr_t     mapper_xp,
     800                          xptr_t     page_xp,
     801                          uint32_t   nbytes )
     802{
    762803    char          buffer[4096];   // local buffer
    763     uint32_t    * tabi;           // pointer on uint32_t to scan buffer
    764804    uint32_t      line;           // line index
    765805    uint32_t      word;           // word index
    766     cxy_t         mapper_cxy;     // mapper cluster identifier
    767     mapper_t    * mapper_ptr;     // mapper local pointer
    768     vfs_inode_t * inode_ptr;      // inode local pointer
    769806 
    770807    char       name[CONFIG_VFS_MAX_NAME_LENGTH];
    771808
    772     if( nbytes > 4096)
    773     {
    774         printk("\n[ERROR] in %s : nbytes (%d) cannot be larger than 4096\n",
    775         __FUNCTION__, nbytes );
    776         return -1;
    777     }
    778    
    779     // get extended pointer on page descriptor
    780     page_xp = mapper_remote_get_page( mapper_xp , page_id );
    781 
    782     if( page_xp == XPTR_NULL)
    783     {
    784         printk("\n[ERROR] in %s : cannot access page %d in mapper\n",
    785         __FUNCTION__, page_id );
    786         return -1;
    787     }
    788 
    789     // get cluster and local pointer
    790     mapper_cxy = GET_CXY( mapper_xp );
    791     mapper_ptr = GET_PTR( mapper_xp );
     809assert( (nbytes <= 4096)         , "nbytes cannot be larger than 4096");
     810assert( (mapper_xp != XPTR_NULL) , "mapper_xp argument cannot be null");
     811assert( (page_xp   != XPTR_NULL) , "page_xp argument cannot be null");
     812
     813    // get mapper cluster and local pointer
     814    cxy_t      mapper_cxy = GET_CXY( mapper_xp );
     815    mapper_t * mapper_ptr = GET_PTR( mapper_xp );
     816
     817    // get page cluster an local pointer
     818    cxy_t    page_cxy = GET_CXY( page_xp );
     819    page_t * page_ptr = GET_PTR( page_xp );
     820
     821    // get page_id and mapper from page descriptor
     822    uint32_t   page_id = hal_remote_l32( XPTR( page_cxy , &page_ptr->index ) );
     823    mapper_t * mapper  = hal_remote_lpt( XPTR( page_cxy , &page_ptr->mapper ) );
     824
     825assert( (mapper_cxy == page_cxy ) , "mapper and page must be in same cluster");
     826assert( (mapper_ptr == mapper   ) , "unconsistent mapper_xp & page_xp arguments");
    792827
    793828    // get inode
    794     inode_ptr = hal_remote_lpt( XPTR( mapper_cxy , &mapper_ptr->inode ) );
     829    vfs_inode_t * inode_ptr = hal_remote_lpt( XPTR( mapper_cxy , &mapper_ptr->inode ) );
    795830
    796831    // get inode name
    797     if( inode_ptr == NULL ) strcpy( name , "fat" );
     832    if( inode_ptr == NULL ) strcpy( name , "FAT" );
    798833    else  vfs_inode_get_name( XPTR( mapper_cxy , inode_ptr ) , name );
    799834   
    800835    // get extended pointer on page base
    801     base_xp = ppm_page2base( page_xp );
     836    xptr_t base_xp = ppm_page2base( page_xp );
    802837   
    803838    // copy remote page to local buffer
    804839    hal_remote_memcpy( XPTR( local_cxy , buffer ) , base_xp , nbytes );
    805840
     841    // display header
     842    uint32_t * tabi = (uint32_t *)buffer;
     843    printk("\n***** mapper <%s> / page_id %d / cxy %x / mapper %x / buffer %x\n",
     844    name, page_id, mapper_cxy, mapper_ptr, GET_PTR( base_xp ) );
     845
    806846    // display 8 words per line
    807     tabi = (uint32_t *)buffer;
    808     printk("\n***** mapper <%s> / %d bytes in page %d (%x,%x)\n",
    809     name, nbytes, page_id, GET_CXY(base_xp), GET_PTR(base_xp) );
    810847    for( line = 0 ; line < (nbytes >> 5) ; line++ )
    811848    {
     
    815852    }
    816853
    817     return 0;
    818 
    819 }  // end mapper_display_page
    820 
    821 
     854}  // end mapper_display_page()
     855
     856
Note: See TracChangeset for help on using the changeset viewer.