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

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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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    }
Note: See TracChangeset for help on using the changeset viewer.