Changeset 246 for trunk/kernel


Ignore:
Timestamp:
Jul 20, 2017, 12:55:23 PM (7 years ago)
Author:
alain
Message:

Fix a major bug in FATFS : miss handling in the FAT mapper.

Location:
trunk/kernel
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/devices/dev_ioc.h

    r188 r246  
    166166 * from the block device to a memory buffer.
    167167 * It does  not uses the IOC device waiting queue and server thread, and does not use
    168  * the IOC IRQ, but call directly the relevant OIC driver, implementing a busy-waiting
     168 * the IOC IRQ, but call directly the relevant IOC driver, implementing a busy-waiting
    169169 * policy for the calling thread.
    170170 * It must be called in the client cluster.
  • trunk/kernel/kern/kernel_init.c

    r204 r246  
    100100// This variable contains the input IRQ indexes for the IOPIC controller
    101101__attribute__((section(".kdata")))
    102 iopic_input_t         iopic_input                             CONFIG_CACHE_LINE_ALIGNED;
     102iopic_input_t        iopic_input                             CONFIG_CACHE_LINE_ALIGNED;
    103103
    104104// This variable contains the input IRQ indexes for the LAPIC controller
     
    862862            // 1. create FATFS context in cluster 0
    863863            fatfs_ctx_t * fatfs_ctx = fatfs_ctx_alloc();
     864
     865printk("\n@@@ %s extend = %x\n", __FUNCTION__ , fatfs_ctx );
    864866
    865867            nolock_assert( (fatfs_ctx != NULL) , __FUNCTION__ ,
     
    902904            hal_core_sleep();
    903905        }
     906
     907///////////////////////////////@@@
     908fatfs_ctx_display();
     909///////////////////////////////@@@
    904910
    905911        // register VFS root inode in process_zero
  • trunk/kernel/kern/printk.c

    r188 r246  
    129129            case ('l'):             // 64 bits hexadecimal
    130130            {
    131                 uint32_t       imax;
     131                uint32_t imax;
    132132                uint64_t val;
    133133               
     
    153153                len =  i + 1;
    154154                pbuf = &buf[(imax-1) - i];
     155                break;
     156            }
     157            case ('X'):             // 32 bits hexadecimal on 8 characters
     158            {
     159                uint32_t val = va_arg( args , uint32_t );
     160                for(i = 0; i < 8; i++)
     161                {
     162                    buf[7 - i] = HexaTab[val % 16];
     163                    val = (val>>4);
     164                }
     165                len =  8;
     166                pbuf = buf;
    155167                break;
    156168            }
  • trunk/kernel/mm/mapper.c

    r238 r246  
    4040#include <mapper.h>
    4141
    42 //////////////////////////
    43 mapper_t * mapper_create()
     42//////////////////////////////////////////////
     43mapper_t * mapper_create( vfs_fs_type_t type )
    4444{
    4545    mapper_t * mapper;
     
    7878    }
    7979
     80    // initialize mapper type
     81    mapper->type = type;
     82
    8083    // initialize mapper lock
    8184    rwlock_init(  &mapper->lock );
     
    139142    error_t       error;
    140143
    141     mapper_dmsg("\n[INFO] %s : enter for page %d / mapper = %x\n",
     144    mapper_dmsg("\n[INFO] %s : enters for page %d in mapper %x\n",
    142145                __FUNCTION__ , index , mapper );
    143146
     
    254257    }
    255258
    256     mapper_dmsg("\n[INFO] %s : exit for page %d / page desc = %x\n",
    257                 __FUNCTION__ , index , page );
     259    mapper_dmsg("\n[INFO] %s : exit for page %d in mapper %x / page_desc = %x\n",
     260                __FUNCTION__ , index , mapper , page );
    258261
    259262    return page;
  • trunk/kernel/mm/mapper.h

    r238 r246  
    4949 * - The mapper is protected by a blocking "rwlock", to support several simultaneous
    5050 *   readers, and only one writer. This lock implement a busy waiting policy.
    51  * - The vfs_mapper_move_page() and vfs_mapper_load_all() functions are used to move
    52  *   pages to or from the file system on device.
     51 * - The mapper_get_page() function that return a page descriptor pointer from a page
     52 *   index in file is in charge of handling the miss on the mapper cache.
     53 * - The vfs_mapper_move_page() function is used to handle miss on one specific page,
     54 *   or update a dirty page on device.
     55 * - The vfs_mapper_load_all() functions is used to load all pages of a given directory
     56 *   into the mapper.
    5357 * - the mapper_move() function is used to move data to or from an user buffer.
    5458 *   This user space buffer can be physically distributed in several clusters.
    55  * - The mapper_get_page() function that return a page descriptor pointer from a page
    56  *   index in file is in charge of handling the miss on the mapper cache.
    57  * - In the present implementation the cache size increases on demand, and the
    58  *   allocated memory is only released when the mapper/inode is destroyed.
     59 * - In the present implementation the cache size for a given file increases on demand,
     60 *   and the  allocated memory is only released when the mapper/inode is destroyed.
    5961 ******************************************************************************************/
    6062
     
    6769{
    6870        struct vfs_inode_s * inode;           /*! owner inode                                     */
     71    uint32_t             type;        /*! file system type                                */
    6972        grdxt_t              radix;           /*! pages cache implemented as a radix tree         */
    7073        rwlock_t             lock;        /*! several readers / only one writer               */
  • trunk/kernel/vfs/fatfs.c

    r238 r246  
    7373}
    7474
     75//////////////////////////////////////////////////////////////////////////////////////////
     76// This function display the content of the FATFS context.
     77//////////////////////////////////////////////////////////////////////////////////////////
     78void fatfs_ctx_display()
     79{
     80    uint32_t      type      = FS_TYPE_FATFS;
     81    vfs_ctx_t   * vfs_ctx   = &fs_context[FS_TYPE_FATFS];
     82    fatfs_ctx_t * fatfs_ctx = (fatfs_ctx_t *)vfs_ctx->extend;
     83
     84    printk("\n*** FAT context ***\n"
     85           "- fat_sectors      = %d\n"
     86           "- sector size      = %d\n"
     87           "- cluster size     = %d\n"
     88           "- fat_first_lba    = %d\n"
     89           "- data_first_lba   = %d\n"
     90           "- root_dir_cluster = %d\n"
     91           "- mapper_xp        = %l\n",
     92           fatfs_ctx->fat_sectors_count,
     93           fatfs_ctx->bytes_per_sector,
     94           fatfs_ctx->sectors_per_cluster * fatfs_ctx->bytes_per_sector,
     95           fatfs_ctx->fat_begin_lba,
     96           fatfs_ctx->cluster_begin_lba,
     97           fatfs_ctx->root_dir_cluster,
     98           fatfs_ctx->fat_mapper_xp );
     99}
    75100
    76101//////////////////////////////////////////////////////////////////////////////////////////
     
    280305
    281306//////////////////////////////////////////////////////////////////////////////////////////
    282 //              FATFS specific but public functions (used by RPC_FATFS_GET_CLUSTER)
     307//              FATFS specific but extern function (used by RPC_FATFS_GET_CLUSTER)
    283308//////////////////////////////////////////////////////////////////////////////////////////
    284309
     
    296321    uint32_t   current_cluster;        // content of current FAT slot
    297322
    298     // compute number of FAT slots per PPM page
     323    fatfs_dmsg("\n[INFO] %s : enters / first_cluster_id = %d / searched_page = %d\n",
     324               __FUNCTION__ , first_cluster , searched_page );
     325
     326#if CONFIG_FATFS_DEBUG
     327    uint32_t * buf = (uint32_t *)ppm_page2vaddr( mapper_get_page ( mapper , 0 ) );
     328    uint32_t line , word;
     329    printk("\n***  FAT content for first 128 entries ***\n");
     330    for( line = 0 ; line < 8 ; line++ )
     331    {
     332        printk("%d : ");
     333        for( word = 0 ; word < 16 ; word++ ) printk("%X ", buf[(line<<4) + word] );
     334        printk("\n");
     335    }
     336#endif
     337
     338    // compute number of FAT slots per page
    299339    uint32_t slots_per_page = CONFIG_PPM_PAGE_SIZE >> 2;
    300340
     
    307347    while( page_count_in_file <= searched_page )
    308348    {
     349
     350        fatfs_dmsg("\n[INFO] %s : page_index = %d / page_offset = %d / count = %d\n",
     351               __FUNCTION__ , current_page_index , current_page_offset , page_count_in_file );
     352
    309353        // get pointer on current page descriptor
    310354        current_page_desc = mapper_get_page( mapper , current_page_index );
     
    324368    }
    325369   
    326     // return success
     370    fatfs_dmsg("\n[INFO] %s : exit / cluster_id = %d\n",
     371               __FUNCTION__ , current_cluster );
     372
    327373    *cluster = current_cluster;
    328374    return 0;
     
    355401    uint8_t     * buffer;
    356402
    357     fatfs_dmsg("\n[INFO] %s : enters at cycle %d\n",
    358                __FUNCTION__ , hal_get_cycles() );
    359 
    360     // allocate memory for FATFS context
    361         req.type    = KMEM_FATFS_CTX;
    362         req.size    = sizeof(fatfs_ctx_t);
    363     req.flags   = AF_KERNEL | AF_ZERO;
    364 
    365         fatfs_ctx = (fatfs_ctx_t *)kmem_alloc( &req );
    366 
    367     nolock_assert( (fatfs_ctx != NULL) , __FUNCTION__ ,
     403    fatfs_dmsg("\n[INFO] %s : enters for fatfs_ctx = %x\n",
     404               __FUNCTION__ , fatfs_ctx );
     405
     406    assert( (fatfs_ctx != NULL) , __FUNCTION__ ,
    368407                   "cannot allocate memory for FATFS context\n" );
    369408
     
    373412        buffer      = (uint8_t *)kmem_alloc( &req );
    374413
    375     nolock_assert( (buffer != NULL) , __FUNCTION__ ,
     414    assert( (buffer != NULL) , __FUNCTION__ ,
    376415                   "cannot allocate memory for 512 bytes buffer\n" );
    377416     
     
    380419    error = dev_ioc_sync_read( buffer , 0 , 1 );
    381420
    382     nolock_assert( (error == 0) , __FUNCTION__ ,
     421    assert( (error == 0) , __FUNCTION__ ,
    383422                   "cannot access boot record\n" );
    384423
    385 #if CONFIG_FATFS_DEBUG
     424#if (CONFIG_FATFS_DEBUG > 1)
    386425    uint32_t   line;
    387426    uint32_t   byte = 0;
     
    439478
    440479    // allocate a mapper for the FAT itself
    441     mapper_t * fat_mapper = mapper_create();
     480    mapper_t * fat_mapper = mapper_create( FS_TYPE_FATFS );
    442481
    443482    assert( (fat_mapper != NULL) , __FUNCTION__ , "no memory for FAT mapper" );
     483
     484    // WARNING : the inode field MUST be NULL for the FAT mapper
     485    fat_mapper->inode = NULL;
    444486
    445487    // initialize the FATFS context
     
    454496    fatfs_ctx->fat_mapper_xp         = XPTR( local_cxy , fat_mapper );
    455497
    456     fatfs_dmsg("\n*** FAT context ***\n"
    457                "- fat_sectors     = %d\n"
    458                "- sector size     = %d\n"
    459                "- cluster size    = %d\n"
    460                "- fat_first_lba   = %d\n"
    461                "- data_first_lba  = %d\n"
    462                "- mapper          = %l\n",
    463                fatfs_ctx->fat_sectors_count,
    464                fatfs_ctx->bytes_per_sector,
    465                fatfs_ctx->bytes_per_cluster,
    466                fatfs_ctx->fat_begin_lba,
    467                fatfs_ctx->cluster_begin_lba,
    468                fatfs_ctx->fat_mapper_xp );
    469 
    470498}  // end fatfs_ctx_init()
    471499
     
    479507}
    480508
    481 ///////////////////////////////////////
    482 error_t fatfs_move_page( page_t * page,
    483                          bool_t   to_mapper )
    484 {
     509//////////////////////////////////////////////
     510error_t fatfs_mapper_move_page( page_t * page,
     511                                bool_t   to_mapper )
     512{
     513    error_t error;
     514
     515    // get pointer on source mapper and page index from page descriptor
     516    mapper_t * mapper = page->mapper;
     517    uint32_t   index  = page->index;
     518
     519    // get VFS inode pointer from mapper
     520    vfs_inode_t * inode = mapper->inode;
     521
     522    fatfs_dmsg("\n[INFO] %s : enter for inode %x / page_index = %d / mapper = %x\n",
     523               __FUNCTION__ , inode , index , mapper );
     524
    485525    // get memory buffer base address
    486526    uint8_t * buffer = (uint8_t *)ppm_page2vaddr( page );
    487527 
    488     // get pointer on source mapper and page index from page descriptor
    489     mapper_t * mapper      = page->mapper;
    490     uint32_t   page_index  = page->index;
    491 
    492     // get VFS inode pointer from mapper
    493     vfs_inode_t * vfs_inode = mapper->inode;
    494 
    495     // get first cluster index from VFS inode
    496     uint32_t  first_cluster = (uint32_t)(intptr_t)vfs_inode->extend;
    497 
    498     // get FATFS context pointer from VFS context
     528    // get number of sectors from FATFS context
    499529    fatfs_ctx_t * fatfs_ctx = (fatfs_ctx_t *)fs_context[FS_TYPE_FATFS].extend;
    500 
    501     // get number of sectors
    502530    uint32_t count = fatfs_ctx->sectors_per_cluster;
    503531
    504     // compute FATFS_cluster index for the accessed page
    505     uint32_t cluster = 0;
    506     error_t  error = fatfs_cluster_from_index( fatfs_ctx,
    507                                                first_cluster,
    508                                                page_index,
    509                                                &cluster );
    510     if( error ) return EIO;
    511 
    512     // get lba from cluster
    513     uint32_t lba = fatfs_lba_from_cluster( fatfs_ctx , cluster );
    514 
    515     // access device
    516     if( to_mapper ) error = dev_ioc_read ( buffer , lba , count );
    517     else            error = dev_ioc_write( buffer , lba , count );     
    518 
    519     if( error )
    520     {
    521         printk("\n[ERROR] in %s : cannot access IOC device\n", __FUNCTION__ );
    522         return error;
    523     }
    524 
    525     // successful access
     532    // analyse the mapper type : FAT or normal inode
     533    if( inode == NULL )  // it is the FAT mapper
     534    {
     535        // get lba from page index
     536        uint32_t lba = fatfs_ctx->fat_begin_lba + (count * index);
     537 
     538        fatfs_dmsg("\n[INFO] %s : for FAT / lba = %d\n",
     539                   __FUNCTION__ , lba );
     540
     541        // access device
     542        if( to_mapper ) error = dev_ioc_sync_read ( buffer , lba , count );
     543        else            error = dev_ioc_write( buffer , lba , count );     
     544
     545        if( error ) return EIO;
     546
     547        fatfs_dmsg("\n[INFO] %s : exit for FAT / page_index = %d / mapper = %x\n",
     548                   __FUNCTION__ , index , mapper );
     549    }
     550    else                 // it is a normal inode mapper
     551    {
     552        // get first cluster index from inode extension
     553        uint32_t  first_cluster = (uint32_t)(intptr_t)inode->extend;
     554
     555        fatfs_dmsg("\n[INFO] %s : for inode %x / first cluster_id = %d\n",
     556                   __FUNCTION__ , inode , first_cluster );
     557   
     558        // compute FATFS_cluster index for the accessed page
     559        uint32_t cluster = 0;
     560        error_t  error = fatfs_cluster_from_index( fatfs_ctx,
     561                                                   first_cluster,
     562                                                   index,
     563                                                   &cluster );
     564        if( error ) return EIO;
     565
     566        // get lba from cluster
     567        uint32_t lba = fatfs_lba_from_cluster( fatfs_ctx , cluster );
     568
     569        fatfs_dmsg("\n[INFO] %s : for inode %x / page = %d / cluster_id = %d / lba = %x\n",
     570                   __FUNCTION__ , inode , index , cluster , lba );
     571
     572        // access device
     573        if( to_mapper ) error = dev_ioc_sync_read ( buffer , lba , count );
     574        else            error = dev_ioc_write( buffer , lba , count );     
     575
     576        if( error ) return EIO;
     577
     578        fatfs_dmsg("\n[INFO] %s : exit for inode %x / page = %x / mapper = %x\n",
     579                   __FUNCTION__ , inode , page , mapper );
     580    }
     581
    526582    return 0;
    527 }
     583
     584}  // end fatfs_mapper_move_page()
    528585
    529586/////////////////////////////////////////////////////////////////
     
    537594
    538595    fatfs_dmsg("\n[INFO] %s : enter for child <%s> in parent inode %l\n",
    539                __FUNCTION__ , name , child_inode_xp );
     596               __FUNCTION__ , name , XPTR( local_cxy , parent_inode ) );
    540597
    541598    mapper_t * mapper = parent_inode->mapper;
     
    641698    if ( found == -1 )  // found end of directory => failure
    642699    {
    643         fatfs_dmsg("\n[INFO] %s : child <%s> not found in parent inode %l\n",
    644                    __FUNCTION__ , name , parent_inode_xp );
     700        fatfs_dmsg("\n[INFO] %s : exit / child <%s> not found in parent inode %l\n",
     701                   __FUNCTION__ , name , XPTR( local_cxy , parent_inode ) );
    645702
    646703        return ENOENT;
     
    648705    else               // found searched child name
    649706    {
    650         fatfs_dmsg("\n[INFO] %s : child <%s> found in parent inode %l\n",
    651                    __FUNCTION__ , name , parent_inode_xp );
    652 
    653707        // get child inode cluster and local pointer
    654708        cxy_t         child_cxy = GET_CXY( child_inode_xp );
     
    662716        hal_remote_sw( XPTR( child_cxy , &child_ptr->extend ) , cluster );
    663717
     718        fatfs_dmsg("\n[INFO] %s : exit / child <%s> found in parent inode %l\n",
     719                   __FUNCTION__ , name , XPTR( local_cxy , parent_inode ) );
     720
    664721        return 0;
    665722    }
  • trunk/kernel/vfs/fatfs.h

    r238 r246  
    243243 * It must be called by a thread running in cluster containing the mapper.
    244244 * The pointer on the mapper and the page index in file are registered
    245  * in the page descriptor.
     245 * in the page descriptor.
     246 * WARNING : The inode field in the mapper must be NULL for the FAT mapper.
     247 * This is used to implement a specific behaviour to access the FAT zone on device.
    246248 *****************************************************************************************
    247249 * @ page      : local pointer on page descriptor.
     
    249251 * @ return 0 if success / return EIO if error.
    250252 ****************************************************************************************/
    251 error_t fatfs_move_page( struct page_s * page,
    252                          bool_t          to_mapper );
     253error_t fatfs_mapper_move_page( struct page_s * page,
     254                                bool_t          to_mapper );
    253255
    254256
  • trunk/kernel/vfs/vfs.c

    r238 r246  
    161161    {
    162162        ctx = NULL;
    163         printk("\n[PANIC] in %s : undefined file system type\n", __FUNCTION__ );
     163                printk("\n[PANIC] in %s : illegal file system type = %d\n", __FUNCTION__ , fs_type );
    164164        hal_core_sleep();
    165165    }
     
    175175
    176176    // allocate memory for mapper
    177     mapper = mapper_create();
     177    mapper = mapper_create( fs_type );
    178178
    179179    if( mapper == NULL )
     
    209209    inode->parent_xp  = dentry_xp;
    210210    inode->ctx        = ctx;
    211     inode->mapper     = NULL; 
     211    inode->mapper     = mapper;
    212212    inode->extend     = extend;
    213213
     214    // initialise inode field in mapper
     215    mapper->inode     = inode;
     216 
    214217    // initialise threads waiting queue
    215218    xlist_root_init( XPTR( local_cxy , &inode->wait_root ) );
     
    253256                        xptr_t        child_xp )
    254257{
     258    vfs_dmsg("\n[INFO] %s : enter for child <%s>\n",
     259             __FUNCTION__ , name );
     260
    255261    error_t error = 0;
    256262
     
    279285        assert( false , __FUNCTION__ , "undefined file system type\n" );
    280286    }
     287
     288    vfs_dmsg("\n[INFO] %s : exit for child <%s>\n",
     289             __FUNCTION__ , name );
    281290
    282291    return error;
     
    12531262        // for the last name, the behaviour depends on the "mode" argument:
    12541263
    1255         if (found == false ) // directory node not found in inode tree
     1264        if (found == false ) // child node not found in inode tree
    12561265        {
    12571266            vfs_dmsg("\n[INFO] %s : <%s> not found, try to load it\n",
     
    15591568    assert( (page != NULL) , __FUNCTION__ , "page pointer is NULL\n" );
    15601569
    1561     mapper_t * mapper = page->mapper;
     1570    mapper_t    * mapper = page->mapper;
     1571
    15621572
    15631573    assert( (mapper != NULL) , __FUNCTION__ , "no mapper for page\n" );
    15641574
     1575    vfs_dmsg("\n[INFO] %s : enters for page = %d in mapper = %x\n",
     1576             __FUNCTION__ , page->index , mapper );
     1577
    15651578    // get FS type
    1566     vfs_fs_type_t fs_type = mapper->inode->ctx->type;
     1579    vfs_fs_type_t fs_type = mapper->type;
    15671580
    15681581    // call relevant FS function
     
    15701583    {
    15711584        rwlock_wr_lock( &mapper->lock );
    1572         error = fatfs_move_page( page , to_mapper );
     1585        error = fatfs_mapper_move_page( page , to_mapper );
    15731586        rwlock_wr_unlock( &mapper->lock );
    15741587    }
     
    15851598        assert( false , __FUNCTION__ , "undefined file system type\n" );
    15861599    }
     1600
     1601    vfs_dmsg("\n[INFO] %s : exit for page = %d in mapper = %x\n",
     1602             __FUNCTION__ , page->index , mapper );
    15871603
    15881604    return error;
Note: See TracChangeset for help on using the changeset viewer.