Changeset 238 for trunk/kernel


Ignore:
Timestamp:
Jul 19, 2017, 3:31:39 PM (5 years ago)
Author:
alain
Message:

Fixing bugs in vfs_lookup()

Location:
trunk/kernel
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/kernel/devices/dev_dma.c

    r188 r238  
    4040extern chdev_directory_t  chdev_dir;         // allocated in kernel_init.c
    4141
    42 ////////////////////////////////////
    43 void dev_dma_init( chdev_t * chdev )
     42//////////////////////////////////
     43void dev_dma_init( chdev_t * dma )
    4444{
    45     // get implementation & channel from DMA chdev descriptor
    46     uint32_t impl    = chdev->impl;
    47     uint32_t channel = chdev->channel;
     45    // get implementation & channel from DMA dma descriptor
     46    uint32_t impl    = dma->impl;
     47    uint32_t channel = dma->channel;
    4848
    49     // set chdev name
    50     snprintf( chdev->name , 16 , "dma_%d_%x" , channel , local_cxy );
     49    // set dma name
     50    snprintf( dma->name , 16 , "dma_%d_%x" , channel , local_cxy );
    5151
    5252    // set field "cmd", "isr", and call the relevant driver init function
    5353    if( impl == IMPL_DMA_SCL )
    5454    {
    55         chdev->cmd = &soclib_dma_cmd;
    56         chdev->isr = &soclib_dma_isr;
    57         soclib_dma_init( chdev );
     55        dma->cmd = &soclib_dma_cmd;
     56        dma->isr = &soclib_dma_isr;
     57        soclib_dma_init( dma );
    5858    }
    5959    else
     
    6363
    6464    // bind IRQ to the core defined by the DMA channel
    65     dev_pic_bind_irq( channel , chdev );
     65    dev_pic_bind_irq( channel , dma );
    6666
    6767    // enable IRQ
    68     dev_pic_enable_irq( channel, chdev );
     68    dev_pic_enable_irq( channel, XPTR( local_cxy , dma ) );
    6969
    7070    // create server thread
     
    7575                                  THREAD_DEV,
    7676                                  &chdev_sequencial_server,
    77                                   chdev,
     77                                  dma,
    7878                                  cluster_select_local_core() );
    7979    if( error )
     
    8383
    8484    // initialises server field in DMA chdev descriptor
    85     chdev->server = new_thread;
     85    dma->server = new_thread;
    8686   
    8787    // start server thread
  • trunk/kernel/devices/dev_ioc.c

    r216 r238  
    6363
    6464    // enable IRQ
    65     dev_pic_enable_irq( lid ,ioc );
     65    dev_pic_enable_irq( lid , XPTR( local_cxy , ioc ) );
    6666
    6767    // create server thread
  • trunk/kernel/devices/dev_mmc.c

    r188 r238  
    3636extern chdev_directory_t  chdev_dir;         // allocated in kernel_init.c
    3737
    38 ////////////////////////////////////
    39 void dev_mmc_init( chdev_t * chdev )
     38//////////////////////////////////
     39void dev_mmc_init( chdev_t * mmc )
    4040{
    4141    // get implementation from device descriptor
    42     uint32_t  impl = chdev->impl;
    43 
    44     // set chdev name
    45     snprintf( chdev->name , 16 , "mmc_%x" , local_cxy );
     42    uint32_t  impl = mmc->impl;
     43
     44    // set mmc name
     45    snprintf( mmc->name , 16 , "mmc_%x" , local_cxy );
    4646
    4747    // set driver specific fields in device descriptor and call driver init function
    4848    if( impl == IMPL_MMC_TSR )
    4949    {
    50         chdev->cmd = &soclib_mmc_cmd;
    51         chdev->isr = &soclib_mmc_isr;
    52         soclib_mmc_init( chdev );
     50        mmc->cmd = &soclib_mmc_cmd;
     51        mmc->isr = &soclib_mmc_isr;
     52        soclib_mmc_init( mmc );
    5353    }
    5454    else
     
    5858
    5959    // bind IRQ to CP0
    60     dev_pic_bind_irq( 0 , chdev );
     60    dev_pic_bind_irq( 0 , mmc );
    6161   
    6262    // enable IRQ
    63     dev_pic_enable_irq( 0 , chdev );
     63    dev_pic_enable_irq( 0 , XPTR( local_cxy , mmc ) );
    6464
    6565}  // end dev_mmc_init()
  • trunk/kernel/devices/dev_nic.c

    r188 r238  
    133133    {
    134134        // enable NIC-RX IRQ
    135         dev_pic_enable_irq( core->lid , dev_ptr );
     135        dev_pic_enable_irq( core->lid , dev_xp );
    136136
    137137        // block on THREAD_BLOCKED_IO condition and deschedule
     
    140140
    141141        // disable NIC-RX IRQ
    142         dev_pic_disable_irq( core->lid , dev_ptr );
     142        dev_pic_disable_irq( core->lid , dev_xp );
    143143    }
    144144
     
    203203    {
    204204        // enable NIC-TX IRQ
    205         dev_pic_enable_irq( core->lid ,dev_ptr );
     205        dev_pic_enable_irq( core->lid ,dev_xp );
    206206
    207207        // block on THREAD_BLOCKED I/O condition and deschedule
     
    210210
    211211        // disable NIC-TX IRQ
    212         dev_pic_disable_irq( core->lid , dev_ptr );
     212        dev_pic_disable_irq( core->lid , dev_xp );
    213213    }
    214214
  • trunk/kernel/devices/dev_txt.c

    r188 r238  
    7777
    7878        // enable TXT IRQ
    79         dev_pic_enable_irq( lid , txt );
     79        dev_pic_enable_irq( lid , XPTR( local_cxy , txt ) );
    8080
    8181        // create server thread
  • trunk/kernel/kern/rpc.c

    r188 r238  
    6666    &rpc_vfs_file_create_server,        // 14
    6767    &rpc_vfs_file_destroy_server,       // 15
    68     &rpc_fatfs_get_cluster_server,      // 16
    69     &rpc_undefined,                     // 17
    70     &rpc_undefined,                     // 18
     68    &rpc_vfs_inode_load_server,         // 16
     69    &rpc_vfs_mapper_load_all_server,    // 17
     70    &rpc_fatfs_get_cluster_server,      // 18
    7171    &rpc_undefined,                     // 19
    7272
     
    100100                                uint32_t * ppn )       // out
    101101{
    102     // any RPC must be remote
    103     if( cxy == local_cxy )
    104     {
    105         printk("PANIC in %s : target is not remote\n", __FUNCTION__ );
    106         hal_core_sleep();
    107     }
     102    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
    108103
    109104    // initialise RPC descriptor header
     
    157152                                   pid_t     * pid )     // out
    158153{
    159     // RPC must be remote
    160     if( cxy == local_cxy )
    161     {
    162         printk("PANIC in %s : target is not remote\n", __FUNCTION__ );
    163         hal_core_sleep();
    164     }
     154    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
    165155
    166156    // initialise RPC descriptor header
     
    213203                              error_t     * error )   // out
    214204{
    215     // RPC must be remote
    216     if( cxy == local_cxy )
    217     {
    218         printk("PANIC in %s : target is not remote\n", __FUNCTION__ );
    219         hal_core_sleep();
    220     }
     205    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
    221206
    222207    // initialise RPC descriptor header
     
    270255{
    271256    // only reference cluster can send this RPC
    272     if( GET_CXY( process->ref_xp ) != local_cxy )
    273     {
    274         printk("PANIC in %s : caller is not the reference process\n", __FUNCTION__ );
    275         hal_core_sleep();
    276     }
     257    assert( (GET_CXY( process->ref_xp ) == local_cxy) , __FUNCTION__ ,
     258            "caller must be reference process cluster\n");
    277259
    278260    // get local process index in reference cluster
     
    344326                                    error_t        * error )      // out
    345327{
    346     // RPC must be remote
    347     if( cxy == local_cxy )
    348     {
    349         printk("\n[PANIC] in %s : target is not remote\n", __FUNCTION__ );
    350         hal_core_sleep();
    351     }
     328    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
    352329
    353330    // initialise RPC descriptor header
     
    427404                                      error_t * error )      // out
    428405{
    429     // RPC must be remote
    430     if( cxy == local_cxy )
    431     {
    432         printk("PANIC in %s : target is not remote\n", __FUNCTION__ );
    433         hal_core_sleep();
    434     }
     406    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
    435407
    436408    // initialise RPC descriptor header
     
    490462                             uint32_t    sig_id )    // in
    491463{
    492     // RPC must be remote
    493     if( cxy == local_cxy )
    494     {
    495         printk("PANIC in %s : target is not remote\n", __FUNCTION__ );
    496         hal_core_sleep();
    497     }
     464    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
    498465
    499466    // initialise RPC descriptor header
     
    545512                                  error_t      * error )     // out
    546513{
    547     // RPC must be remote
    548     if( cxy == local_cxy )
    549     {
    550         printk("PANIC in %s : target cluster is not remote\n", __FUNCTION__ );
    551         hal_core_sleep();
    552     }
     514    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
    553515
    554516    // initialise RPC descriptor header
     
    627589                                   struct vfs_inode_s * inode )
    628590{
    629     // RPC must be remote
    630     if( cxy == local_cxy )
    631     {
    632         printk("PANIC in %s : target cluster is not remote\n", __FUNCTION__ );
    633         hal_core_sleep();
    634     }
     591    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
    635592
    636593    // initialise RPC descriptor header
     
    674631                                   error_t              * error )       // out
    675632{
    676     // RPC must be remote
    677     if( cxy == local_cxy )
    678     {
    679         printk("PANIC in %s : target cluster is not remote\n", __FUNCTION__ );
    680         hal_core_sleep();
    681     }
     633    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
    682634
    683635    // initialise RPC descriptor header
     
    689641    rpc.args[0] = (uint64_t)type;
    690642    rpc.args[1] = (uint64_t)(intptr_t)name;
    691     rpc.args[2] = (uint64_t)strlen( name );
    692     rpc.args[3] = (uint64_t)(intptr_t)parent;
     643    rpc.args[2] = (uint64_t)(intptr_t)parent;
    693644
    694645    // register RPC request in remote RPC fifo (blocking function)
     
    696647
    697648    // get output values from RPC descriptor
    698     *dentry_xp = (xptr_t)rpc.args[4];
    699     *error     = (error_t)rpc.args[5];
     649    *dentry_xp = (xptr_t)rpc.args[3];
     650    *error     = (error_t)rpc.args[4];
    700651}
    701652
     
    707658    vfs_inode_t * parent;
    708659    xptr_t        dentry_xp;
     660    error_t       error;
     661
    709662    char          name_copy[CONFIG_VFS_MAX_NAME_LENGTH];
    710     uint32_t      length;
    711     error_t       error;
    712663
    713664    // get client cluster identifier and pointer on RPC descriptor
     
    715666    rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp );
    716667
    717     // get argument "name" & "length" from client RPC descriptor and makes a local copy
    718     name   = (char *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
    719     length = (uint32_t)        hal_remote_lwd( XPTR( client_cxy , &desc->args[2] ) );
    720     hal_remote_memcpy( XPTR( local_cxy , name_copy ),
    721                        XPTR( client_cxy , name ),
    722                                            length + 1 );               // +1 for the NUL char
    723 
    724     // get arguments "type" and "parent" from client RPC descriptor
     668    // get arguments "name", "type", and "parent" from client RPC descriptor
    725669    type   = (uint32_t)               hal_remote_lwd( XPTR( client_cxy , &desc->args[0] ) );
    726     parent = (vfs_inode_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[3] ) );
     670    name   = (char *)(intptr_t)       hal_remote_lwd( XPTR( client_cxy , &desc->args[1] ) );
     671    parent = (vfs_inode_t *)(intptr_t)hal_remote_lwd( XPTR( client_cxy , &desc->args[2] ) );
    727672                       
     673    // makes a local copy of  name
     674    hal_remote_strcpy( XPTR( local_cxy , name_copy ),
     675                       XPTR( client_cxy , name ) );
     676
    728677    // call local kernel function
    729678    error = vfs_dentry_create( type,
     
    733682 
    734683    // set output arguments
    735     hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)dentry_xp );
    736     hal_remote_swd( XPTR( client_cxy , &desc->args[5] ) , (uint64_t)error );
     684    hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)dentry_xp );
     685    hal_remote_swd( XPTR( client_cxy , &desc->args[4] ) , (uint64_t)error );
    737686}
    738687
     
    745694                                    vfs_dentry_t * dentry )
    746695{
    747     // RPC must be remote
    748     if( cxy == local_cxy )
    749     {
    750         printk("PANIC in %s : target cluster is not remote\n", __FUNCTION__ );
    751         hal_core_sleep();
    752     }
     696    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
    753697
    754698    // initialise RPC descriptor header
     
    792736                                 error_t              * error )      // out
    793737{
    794     // RPC must be remote
    795     if( cxy == local_cxy )
    796     {
    797         printk("PANIC in %s : target cluster is not remote\n", __FUNCTION__ );
    798         hal_core_sleep();
    799     }
     738    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
    800739
    801740    // initialise RPC descriptor header
     
    850789                                  vfs_file_t * file )
    851790{
    852     // RPC must be remote
    853     if( cxy == local_cxy )
    854     {
    855         printk("PANIC in %s : target cluster is not remote\n", __FUNCTION__ );
    856         hal_core_sleep();
    857     }
     791    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
    858792
    859793    // initialise RPC descriptor header
     
    886820
    887821/////////////////////////////////////////////////////////////////////////////////////////
    888 // [16]          Marshaling functions attached to RPC_FATFS_GET_CLUSTER
     822// [16]          Marshaling functions attached to RPC_VFS_INODE_LOAD 
     823/////////////////////////////////////////////////////////////////////////////////////////
     824
     825//////////////////////////////////////////////////
     826void rpc_vfs_inode_load_client( cxy_t         cxy,
     827                                vfs_inode_t * parent_inode,    // in
     828                                char        * name,            // in
     829                                xptr_t        child_inode_xp,  // in
     830                                error_t     * error )          // out
     831{
     832    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
     833
     834    // initialise RPC descriptor header
     835    rpc_desc_t  rpc;
     836    rpc.index    = RPC_VFS_INODE_LOAD;
     837    rpc.response = 1;
     838
     839    // set input arguments in RPC descriptor
     840    rpc.args[0] = (uint64_t)(intptr_t)parent_inode;
     841    rpc.args[1] = (uint64_t)(intptr_t)name;
     842    rpc.args[2] = (uint64_t)child_inode_xp;
     843
     844    // register RPC request in remote RPC fifo (blocking function)
     845    rpc_send_sync( cxy , &rpc );
     846
     847    // get output values from RPC descriptor
     848    *error   = (error_t)rpc.args[3];
     849}
     850
     851///////////////////////////////////////////
     852void rpc_vfs_inode_load_server( xptr_t xp )
     853{
     854    error_t       error;
     855    vfs_inode_t * parent;
     856    xptr_t        child_xp;
     857    char        * name;
     858
     859    char          name_copy[CONFIG_VFS_MAX_NAME_LENGTH];
     860
     861    // get client cluster identifier and pointer on RPC descriptor
     862    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
     863    rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp );
     864
     865    // get arguments "parent", "name", and "child_xp"
     866    parent     = (vfs_inode_t*)(intptr_t)hal_remote_lwd(XPTR(client_cxy , &desc->args[0]));
     867    name       = (char*)(intptr_t)       hal_remote_lwd(XPTR(client_cxy , &desc->args[1]));
     868    child_xp   = (xptr_t)                hal_remote_lwd(XPTR(client_cxy , &desc->args[2]));
     869
     870    // get name local copy
     871    hal_remote_strcpy( XPTR( local_cxy , name_copy ) ,
     872                       XPTR( client_cxy , name ) );
     873
     874    // call the kernel function
     875    error = vfs_inode_load( parent , name_copy , child_xp );
     876
     877    // set output argument
     878    hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
     879}
     880
     881/////////////////////////////////////////////////////////////////////////////////////////
     882// [17]          Marshaling functions attached to RPC_VFS_MAPPER_LOAD_ALL
     883/////////////////////////////////////////////////////////////////////////////////////////
     884
     885///////////////////////////////////////////////////////
     886void rpc_vfs_mapper_load_all_client( cxy_t         cxy,
     887                                     vfs_inode_t * inode,      // in
     888                                     error_t     * error )     // out
     889{
     890    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
     891
     892    // initialise RPC descriptor header
     893    rpc_desc_t  rpc;
     894    rpc.index    = RPC_VFS_INODE_LOAD;
     895    rpc.response = 1;
     896
     897    // set input arguments in RPC descriptor
     898    rpc.args[0] = (uint64_t)(intptr_t)inode;
     899
     900    // register RPC request in remote RPC fifo (blocking function)
     901    rpc_send_sync( cxy , &rpc );
     902
     903    // get output values from RPC descriptor
     904    *error   = (error_t)rpc.args[1];
     905}
     906
     907////////////////////////////////////////////////
     908void rpc_vfs_mapper_load_all_server( xptr_t xp )
     909{
     910    error_t       error;
     911    vfs_inode_t * inode;
     912
     913    // get client cluster identifier and pointer on RPC descriptor
     914    cxy_t        client_cxy  = (cxy_t)GET_CXY( xp );
     915    rpc_desc_t * desc        = (rpc_desc_t *)GET_PTR( xp );
     916
     917    // get arguments "parent", "name", and "child_xp"
     918    inode = (vfs_inode_t*)(intptr_t)hal_remote_lwd(XPTR(client_cxy , &desc->args[0]));
     919
     920    // call the kernel function
     921    error = vfs_mapper_load_all( inode );
     922
     923    // set output argument
     924    hal_remote_swd( XPTR( client_cxy , &desc->args[3] ) , (uint64_t)error );
     925}
     926
     927/////////////////////////////////////////////////////////////////////////////////////////
     928// [18]          Marshaling functions attached to RPC_FATFS_GET_CLUSTER
    889929/////////////////////////////////////////////////////////////////////////////////////////
    890930
     
    897937                                   error_t  * error )    // out
    898938{
    899     // RPC must be remote
    900     if( cxy == local_cxy )
    901     {
    902         printk("PANIC in %s : target is not remote\n", __FUNCTION__ );
    903         hal_core_sleep();
    904     }
     939    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
    905940
    906941    // initialise RPC descriptor header
     
    958993                                  xptr_t    * vseg_xp )    // out
    959994{
    960     // RPC must be remote
    961     if( cxy == local_cxy )
    962     {
    963         printk("PANIC in %s : target is not remote\n", __FUNCTION__ );
    964         hal_core_sleep();
    965     }
     995    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
    966996
    967997    // initialise RPC descriptor header
     
    10191049                             error_t   * error )   // out
    10201050{
    1021     // RPC must be remote
    1022     if( cxy == local_cxy )
    1023     {
    1024         printk("PANIC in %s : target is not remote\n", __FUNCTION__ );
    1025         hal_core_sleep();
    1026     }
     1051    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
    10271052
    10281053    // initialise RPC descriptor header
     
    10791104                           xptr_t *   buf_xp )     // out
    10801105{
    1081     // RPC must be remote
    1082     if( cxy == local_cxy )
    1083     {
    1084         printk("PANIC in %s : target is not remote\n", __FUNCTION__ );
    1085         hal_core_sleep();
    1086     }
     1106    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
    10871107
    10881108    // initialise RPC descriptor header
     
    11311151                          uint32_t   kmem_type )   // in
    11321152{
    1133     // RPC must be remote
    1134     if( cxy == local_cxy )
    1135     {
    1136         printk("PANIC in %s : target is not remote\n", __FUNCTION__ );
    1137         hal_core_sleep();
    1138     }
     1153    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
    11391154
    11401155    // initialise RPC descriptor header
     
    11821197                             error_t  * error )        // out
    11831198{
    1184     // RPC must be remote
    1185     if( cxy == local_cxy )
    1186     {
    1187         printk("PANIC in %s : target cluster is not remote\n", __FUNCTION__ );
    1188         hal_core_sleep();
    1189     }
     1199    assert( (cxy != local_cxy) , __FUNCTION__ , "target cluster is not remote\n");
    11901200
    11911201    // initialise RPC descriptor header
  • trunk/kernel/kern/rpc.h

    r188 r238  
    7171    RPC_VFS_FILE_CREATE        = 14,
    7272    RPC_VFS_FILE_DESTROY       = 15,
    73     RPC_FATFS_GET_CLUSTER      = 16,
     73    RPC_VFS_INODE_LOAD         = 16,
     74    RPC_VFS_MAPPER_LOAD_ALL    = 17,
     75    RPC_FATFS_GET_CLUSTER      = 18,
    7476
    7577    RPC_VMM_GET_REF_VSEG       = 20,
     
    421423void rpc_vfs_file_destroy_server( xptr_t xp );
    422424
    423 /***********************************************************************************
    424  * [16] The RPC_FATFS_GET_CLUSTER can be send by any thread running in a "client"
     425/***********************************************************************************
     426 * [16] The RPC_VFS_LOAD_INODE calls the vfs_inode_load() kernel function in a
     427 * remote cluster containing a parent inode directory to scan the associated
     428 * mapper, find a directory entry, identified by its name, and update the remote
     429 * child inode.
     430 ***********************************************************************************
     431 * @ cxy            :  server cluster identifier
     432 * @ parent_inode   : [in]  local pointer on parent inode.
     433 * @ name           : [in]  local pointer on child name (in client cluster).
     434 * @ child_inode_xp : [in]  extended pointer on child inode (in another cluster).
     435 * @ error          : [out] error status (0 if success).
     436 **********************************************************************************/
     437void rpc_vfs_inode_load_client( cxy_t                cxy,
     438                                struct vfs_inode_s * parent_inode,
     439                                char               * name,
     440                                xptr_t               child_inode_xp,
     441                                error_t            * error );
     442
     443void rpc_vfs_inode_load_server( xptr_t xp );
     444
     445/***********************************************************************************
     446 * [17] The RPC_VFS_MAPPER_LOAD_ALL calls the vfs_mapper_load_all() kernel function
     447 * in a remote cluster containing an inode, to load all pages of the associated
     448 * mapper from the file system on device.
     449 ***********************************************************************************
     450 * @ cxy     :  server cluster identifier
     451 * @ inode   : [in]  local pointer on inode in server cluster.
     452 * @ error   : [out] error status (0 if success).
     453 **********************************************************************************/
     454void rpc_vfs_mapper_load_all_client( cxy_t                cxy,
     455                                     struct vfs_inode_s * inode,
     456                                     error_t            * error );
     457
     458void rpc_vfs_mapper_load_all_server( xptr_t xp );
     459
     460/***********************************************************************************
     461 * [18] The RPC_FATFS_GET_CLUSTER can be send by any thread running in a "client"
    425462 * cluster to scan the FAT mapper, stored in a remote "server" cluster, and get
    426463 * from the mapper the local pointer on a given page.
  • trunk/kernel/libk/string.c

    r223 r238  
    152152}
    153153
     154/////////////////////////////////////
     155inline uint8_t to_lower( uint8_t  c )
     156{
     157   if (c >= 'A' && c <= 'Z') return (c | 0x20);
     158   else                      return c;
     159}
     160
     161
     162/////////////////////////////////////
     163inline uint8_t to_upper( uint8_t  c )
     164{
     165   if (c >= 'a' && c <= 'z') return (c & ~(0x20));
     166   else                      return c;
     167}
     168
     169
  • trunk/kernel/libk/string.h

    r23 r238  
    122122                 int          c );
    123123
     124/********************************************************************************************
     125 * This function returns a lower case ASCII code if input is in [A...Z] range.
     126 ********************************************************************************************
     127 * @ c     : character to be forced to lower case.
     128 * @ return lower case ASCII code.
     129 *******************************************************************************************/
     130inline uint8_t to_lower( uint8_t  c );
     131
     132/********************************************************************************************
     133 * This function returns an upper case ASCII code if input is in [a...z] range.
     134 ********************************************************************************************
     135 * @ c     : character to be forced to upper case.
     136 * @ return upper case ASCII code.
     137 *******************************************************************************************/
     138inline uint8_t to_upper( uint8_t  c );
     139
    124140#endif  /* _STRING_H_ */
  • trunk/kernel/mm/mapper.c

    r204 r238  
    164164        page = grdxt_lookup( &mapper->radix , index );
    165165
    166         if ( page == NULL )   // missing page => load it from file system
     166        if ( page == NULL )   // missing page => create it and load it from file system
    167167        {
    168168            mapper_dmsg("\n[INFO] %s : missing page => load from FS\n", __FUNCTION__ );
     
    208208            }
    209209
     210            // update the mapper and index fields in page descriptor
     211            // required by the vfs_move_page_to_mapper()
     212            page->mapper = mapper;
     213            page->index  = index;
     214
    210215            // launch I/O operation to load page from file system
    211             error = vfs_move_page_to_mapper( page );
     216            error = vfs_mapper_move_page( page , true );   // to mapper
    212217
    213218            if( error )
     
    223228            }
    224229
    225             // update the mapper and index fields in page descriptor
    226             page->mapper = mapper;
    227             page->index  = index;
    228 
    229230            // reset the page INLOAD flag to make the page available to all readers
    230231            page_clear_flag( page , PG_INLOAD );
     
    267268
    268269    // lauch IO operation to update page to file system
    269     error = vfs_move_page_from_mapper( page );
     270    error = vfs_mapper_move_page( page , false );    // from mapper
    270271
    271272    if( error )
  • trunk/kernel/mm/mapper.h

    r204 r238  
    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 two functions vfs_move_page_to_mapper() and vfs_move_page_from_mapper() define
    52  *   the generic API used to move pages to or from the relevant file system.
    53  * - the mapper_move() function is used to move data to or from a, possibly distributed
    54  *   user buffer in user space.
     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.
     53 * - the mapper_move() function is used to move data to or from an user buffer.
     54 *   This user space buffer can be physically distributed in several clusters.
    5555 * - The mapper_get_page() function that return a page descriptor pointer from a page
    5656 *   index in file is in charge of handling the miss on the mapper cache.
  • trunk/kernel/mm/page.c

    r149 r238  
    147147
    148148                // sync the page
    149                 vfs_move_page_from_mapper( page );
     149                vfs_mapper_move_page( page , false );  // from mapper
    150150
    151151                // unlock the page
  • trunk/kernel/vfs/devfs.h

    r204 r238  
    2828//////////////////////////////////////////////////////////////////////////////////////////
    2929// The DEVFS File System contains inodes and dentries associated to all chdev descriptors
    30 // availables in the architecture. It is structured as a three levels tree structure :
     30// availables in the architecture.
     31//
     32// It is structured as a three levels tree structure :
    3133// - The "dev" directory inode is stored in cluster_IO. It is the root of the DEVFS
    3234//   file system. The parent inode is the "/" VFS root.
     
    3840//   The parent dentry is stored in cluster_IO.
    3941//
    40 // The DEVFS file system uses the DEVFS context extension to register an extended pointer
    41 // on the DEVFS "dev" inode, and and another extended pointer on the "external" inode.
    42 //
    43 // The DEVFS file system uses the VFS inode extension to store the pointer
    44 // on the associated chdev descriptor.
     42// The DEVFS extensions to the generic VFS are the following:
     43// 1) The vfs_ctx_t "extend" field is a void* pointing on the devfs_ctx_t structure.
     44//    This structure contains two extended pointers on the DEVFS "dev" directory inode,
     45//    and on the "external" directory inode.
     46// 2) The vfs_inode_t "extend" field is a void*, pointing on the associated
     47//    chdev descriptor.
    4548//////////////////////////////////////////////////////////////////////////////////////////
    4649
  • trunk/kernel/vfs/fatfs.c

    r188 r238  
    22 * fatfs.c - FATFS file system API implementation.
    33 *
    4  * Author    Mohamed Lamine Karaoui (2014,2015)
    5  *           Alain Greiner (2016,2017)
     4 * Author    Alain Greiner (2016,2017)
    65 *
    76 * Copyright (c) UPMC Sorbonne Universites
     
    3029#include <ppm.h>
    3130#include <vfs.h>
     31#include <string.h>
    3232#include <rpc.h>
    3333#include <mapper.h>
     
    4646 
    4747//////////////////////////////////////////////////////////////////////////////////////////
    48 //              FATFS private functions
    49 //////////////////////////////////////////////////////////////////////////////////////////
     48//              FATFS private and static functions
     49//////////////////////////////////////////////////////////////////////////////////////////
     50
     51//////////////////////////////////////////////////////////////////////////////////////////
     52// These functions return the "offset" and "length" values of an
     53// [offset,length] constant defined in the fatfs.h file.
     54//////////////////////////////////////////////////////////////////////////////////////////
     55
     56static inline int get_length( int offset , int length ) { return length; }
     57
     58static inline int get_offset( int offset , int length ) { return offset; }
     59
    5060
    5161//////////////////////////////////////////////////////////////////////////////////////////
     
    6373}
    6474
    65 /////////////////////////////////////////////
    66 error_t fatfs_get_cluster( mapper_t * mapper,
    67                            uint32_t   first_cluster,
    68                            uint32_t   searched_page,
    69                            uint32_t * cluster )
    70 {
    71     page_t   * current_page_desc;      // pointer on current page descriptor
    72     uint32_t * current_page_buffer;    // pointer on current page (array of uint32_t)
    73     uint32_t   current_page_index;     // index of current page in mapper
    74     uint32_t   current_page_offset;    // offset of slot in current page
    75     uint32_t   page_count_in_file;     // index of page in file (index in linked list)
    76     uint32_t   current_cluster;        // content of current FAT slot
    77 
    78     // compute number of FAT slots per PPM page
    79     uint32_t slots_per_page = CONFIG_PPM_PAGE_SIZE >> 2;
    80 
    81     // initialize loop variable
    82     current_page_index  = first_cluster / slots_per_page;
    83     current_page_offset = first_cluster % slots_per_page;
    84     page_count_in_file  = 0;
    85 
    86     // scan FAT (i.e. traverse FAT linked list)
    87     while( page_count_in_file <= searched_page )
    88     {
    89         // get pointer on current page descriptor
    90         current_page_desc = mapper_get_page( mapper , current_page_index );
    91 
    92         if( current_page_desc == NULL ) return EIO;
    93 
    94         // get pointer on buffer for current page
    95         current_page_buffer = (uint32_t *)ppm_page2vaddr( current_page_desc );
    96 
    97         // get FAT slot content
    98         current_cluster = current_page_buffer[current_page_offset];
    99 
    100         // update loop variables
    101         current_page_index  = current_cluster / slots_per_page;
    102         current_page_offset = current_cluster % slots_per_page;
    103         page_count_in_file++;
    104     }
    105    
    106     // return success
    107     *cluster = current_cluster;
    108     return 0;
    109 
    110 }  // end fatfs_get_cluster()
    111 
    112 ///////////////////////////////////////////////////////////////////////////////////////
    113 // This static function return an integer record value (one, two, or four bytes)
     75
     76//////////////////////////////////////////////////////////////////////////////////////////
     77// This function return an integer record value (one, two, or four bytes)
    11478// from a memory buffer, taking into account endianness.
    115 ///////////////////////////////////////////////////////////////////////////////////////
     79//////////////////////////////////////////////////////////////////////////////////////////
    11680// @ offset        : first byte of record in buffer.
    11781// @ size          : record length in bytes (1/2/4).
     
    11983// @ little endian : the most significant byte has the highest address when true.
    12084// @ return the integer value in a 32 bits word.
    121 ///////////////////////////////////////////////////////////////////////////////////////
    122 static uint32_t get_record_from_buffer( uint32_t    offset,
    123                                         uint32_t    size,
    124                                         uint8_t   * buffer,
    125                                         uint32_t    little_endian )
     85//////////////////////////////////////////////////////////////////////////////////////////
     86static uint32_t fatfs_get_record( uint32_t    offset,
     87                                  uint32_t    size,
     88                                  uint8_t   * buffer,
     89                                  uint32_t    little_endian )
    12690{
    12791    uint32_t n;
     
    138102    return res;
    139103
    140 }  // end get_record_from_buffer()
    141 
    142 
    143 
    144 ////////////////////////////////////////////////////////////////////////////////////////
     104}  // end fatfs_get_record()
     105
     106//////////////////////////////////////////////////////////////////////////////////////////
     107// This static function retun in the <name> buffer a short name stored in
     108// a SFN FATFS directory entry.
     109/////////////////////////i////////////////////////////////////////////////////////////////
     110// @ buffer   : pointer on buffer containing the directory entry.
     111// @ name     : [out] buffer allocated by the caller.
     112//////////////////////////////////////////////////////////////////////////////////////////
     113static void fatfs_get_name_from_short( uint8_t * buffer,
     114                                       char    * name )
     115{
     116    uint32_t i;
     117    uint32_t j = 0;
     118
     119    // get name
     120    for ( i = 0; i < 8 && buffer[i] != ' '; i++ )
     121    {
     122        name[j] = to_lower( buffer[i] );
     123        j++;
     124    }
     125
     126    // get extension
     127    for ( i = 8; i < 8 + 3 && buffer[i] != ' '; i++ )
     128    {
     129        // we entered the loop so there is an extension. add the dot
     130        if ( i == 8 )
     131        {
     132            name[j] = '.';
     133            j++;
     134        }
     135
     136        name[j] = to_lower( buffer[i] );
     137        j++;
     138    }
     139
     140    name[j] = '\0';
     141}
     142
     143//////////////////////////////////////////////////////////////////////////////////////////
     144// This static function retun in the <name> buffer a partial name stored in
     145// a LFN FATFS directory entry.
     146/////////////////////////i////////////////////////////////////////////////////////////////
     147// @ buffer   : pointer on buffer containing the directory entry.
     148// @ name     : [out] buffer allocated by the caller.
     149//////////////////////////////////////////////////////////////////////////////////////////
     150static void fatfs_get_name_from_long( uint8_t * buffer,
     151                                      char    * name )
     152{
     153    uint32_t   name_offset   = 0;
     154    uint32_t   buffer_offset = get_length(LDIR_ORD);
     155    uint32_t   l_name_1      = get_length(LDIR_NAME_1);
     156    uint32_t   l_name_2      = get_length(LDIR_NAME_2);
     157    uint32_t   l_name_3      = get_length(LDIR_NAME_3);
     158    uint32_t   l_attr        = get_length(LDIR_ATTR);
     159    uint32_t   l_type        = get_length(LDIR_TYPE);
     160    uint32_t   l_chksum      = get_length(LDIR_CHKSUM);
     161    uint32_t   l_rsvd        = get_length(LDIR_RSVD);
     162
     163    uint32_t   j             = 0;
     164    uint32_t   eof           = 0;
     165
     166    while ( (buffer_offset != DIR_ENTRY_SIZE)  && (!eof) )
     167    {
     168        while (j != l_name_1 && !eof )
     169        {
     170            if ( (buffer[buffer_offset] == 0x00) ||
     171                 (buffer[buffer_offset] == 0xFF) )
     172            {
     173                eof = 1;
     174                continue;
     175            }
     176            name[name_offset] = buffer[buffer_offset];
     177            buffer_offset += 2;
     178            j += 2;
     179            name_offset++;
     180        }
     181
     182        buffer_offset += (l_attr + l_type + l_chksum);
     183        j = 0;
     184
     185        while (j != l_name_2 && !eof )
     186        {
     187            if ( (buffer[buffer_offset] == 0x00) ||
     188                 (buffer[buffer_offset] == 0xFF) )
     189            {
     190                eof = 1;
     191                continue;
     192            }
     193            name[name_offset] = buffer[buffer_offset];
     194            buffer_offset += 2;
     195            j += 2;
     196            name_offset++;
     197        }
     198
     199        buffer_offset += l_rsvd;
     200        j = 0;
     201
     202        while (j != l_name_3 && !eof )
     203        {
     204            if ( (buffer[buffer_offset] == 0x00) ||
     205                 (buffer[buffer_offset] == 0xFF) )
     206            {
     207                eof = 1;
     208                continue;
     209            }
     210            name[name_offset] = buffer[buffer_offset];
     211            buffer_offset += 2;
     212            j += 2;
     213            name_offset++;
     214        }
     215    }
     216    name[name_offset] = 0;
     217
     218} // end get_name_from_long()
     219
     220//////////////////////////////////////////////////////////////////////////////////////////
    145221// This function returns the FATFS cluster index of a page identified by its page
    146222// index in the file, using the FAT mapper. It scans the FAT mapper, starting from the
     
    152228// in the cluster containing the FAT mapper, and the RPC latency is not critical
    153229// compared to the device access latency.
    154 ////////////////////////////////////////////////////////////////////////////////////////
     230//////////////////////////////////////////////////////////////////////////////////////////
    155231// @ ctx               : pointer on local FATFS context.
    156232// @ first_cluster : first cluster allocated to a file in FATFS.
     
    158234// @ cluster_index : [out] pointer on buffer for FATFS cluster index.
    159235// @ return 0 if success / return EIO if a FAT cluster miss cannot be solved.
    160 ////////////////////////////////////////////////////////////////////////////////////////
     236//////////////////////////////////////////////////////////////////////////////////////////
    161237static error_t fatfs_cluster_from_index( fatfs_ctx_t * ctx,
    162238                                         uint32_t      first_cluster,
     
    203279}  // end fatfs_cluster_from_index()
    204280
     281//////////////////////////////////////////////////////////////////////////////////////////
     282//              FATFS specific but public functions (used by RPC_FATFS_GET_CLUSTER)
     283//////////////////////////////////////////////////////////////////////////////////////////
     284
     285/////////////////////////////////////////////
     286error_t fatfs_get_cluster( mapper_t * mapper,
     287                           uint32_t   first_cluster,
     288                           uint32_t   searched_page,
     289                           uint32_t * cluster )
     290{
     291    page_t   * current_page_desc;      // pointer on current page descriptor
     292    uint32_t * current_page_buffer;    // pointer on current page (array of uint32_t)
     293    uint32_t   current_page_index;     // index of current page in mapper
     294    uint32_t   current_page_offset;    // offset of slot in current page
     295    uint32_t   page_count_in_file;     // index of page in file (index in linked list)
     296    uint32_t   current_cluster;        // content of current FAT slot
     297
     298    // compute number of FAT slots per PPM page
     299    uint32_t slots_per_page = CONFIG_PPM_PAGE_SIZE >> 2;
     300
     301    // initialize loop variable
     302    current_page_index  = first_cluster / slots_per_page;
     303    current_page_offset = first_cluster % slots_per_page;
     304    page_count_in_file  = 0;
     305
     306    // scan FAT (i.e. traverse FAT linked list)
     307    while( page_count_in_file <= searched_page )
     308    {
     309        // get pointer on current page descriptor
     310        current_page_desc = mapper_get_page( mapper , current_page_index );
     311
     312        if( current_page_desc == NULL ) return EIO;
     313
     314        // get pointer on buffer for current page
     315        current_page_buffer = (uint32_t *)ppm_page2vaddr( current_page_desc );
     316
     317        // get FAT slot content
     318        current_cluster = current_page_buffer[current_page_offset];
     319
     320        // update loop variables
     321        current_page_index  = current_cluster / slots_per_page;
     322        current_page_offset = current_cluster % slots_per_page;
     323        page_count_in_file++;
     324    }
     325   
     326    // return success
     327    *cluster = current_cluster;
     328    return 0;
     329
     330}  // end fatfs_get_cluster()
    205331
    206332
    207333
    208334///////////////////////////////////////////////////////////////////////////////////////
    209 // Generic API : the following functions are called by the kernel
     335// Generic API : the following functions are called by the kernel (VFS)
    210336//               and must be defined by all supported file systems.
    211337///////////////////////////////////////////////////////////////////////////////////////
     
    275401
    276402    // check sector size from boot record
    277     uint32_t sector_size = get_record_from_buffer( BPB_BYTSPERSEC , buffer , 1 );
     403    uint32_t sector_size = fatfs_get_record( BPB_BYTSPERSEC , buffer , 1 );
    278404
    279405    nolock_assert( (sector_size == 512) , __FUNCTION__ ,
     
    281407
    282408    // check cluster size from boot record
    283     uint32_t nb_sectors = get_record_from_buffer( BPB_SECPERCLUS , buffer , 1 );
     409    uint32_t nb_sectors = fatfs_get_record( BPB_SECPERCLUS , buffer , 1 );
    284410
    285411    nolock_assert( (nb_sectors == 8) , __FUNCTION__ ,
     
    287413
    288414    // check number of FAT copies from boot record
    289     uint32_t nb_fats = get_record_from_buffer( BPB_NUMFATS , buffer , 1 );
     415    uint32_t nb_fats = fatfs_get_record( BPB_NUMFATS , buffer , 1 );
    290416
    291417    nolock_assert( (nb_fats == 1) , __FUNCTION__ ,
     
    293419
    294420    // get & check number of sectors in FAT from boot record
    295     uint32_t fat_sectors = get_record_from_buffer( BPB_FAT32_FATSZ32 , buffer , 1 );
     421    uint32_t fat_sectors = fatfs_get_record( BPB_FAT32_FATSZ32 , buffer , 1 );
    296422
    297423    nolock_assert( ((fat_sectors & 0xF) == 0) , __FUNCTION__ ,
     
    299425
    300426    // get and check root cluster from boot record
    301     uint32_t root_cluster = get_record_from_buffer( BPB_FAT32_ROOTCLUS , buffer , 1 );
     427    uint32_t root_cluster = fatfs_get_record( BPB_FAT32_ROOTCLUS , buffer , 1 );
    302428
    303429    nolock_assert( (root_cluster == 2) , __FUNCTION__ ,
     
    305431
    306432    // get FAT lba from boot record
    307     uint32_t fat_lba = get_record_from_buffer( BPB_RSVDSECCNT , buffer , 1 );
     433    uint32_t fat_lba = fatfs_get_record( BPB_RSVDSECCNT , buffer , 1 );
    308434
    309435    // release the 512 bytes buffer
     
    353479}
    354480
    355 ////////////////////////////////////////////////
    356 static error_t fatfs_access_page( page_t * page,
    357                                   bool_t   is_read )
     481///////////////////////////////////////
     482error_t fatfs_move_page( page_t * page,
     483                         bool_t   to_mapper )
    358484{
    359485    // get memory buffer base address
     
    388514
    389515    // access device
    390     if( is_read ) error = dev_ioc_read ( buffer , lba , count );
    391     else          error = dev_ioc_write( buffer , lba , count );     
     516    if( to_mapper ) error = dev_ioc_read ( buffer , lba , count );
     517    else            error = dev_ioc_write( buffer , lba , count );     
    392518
    393519    if( error )
     
    401527}
    402528
    403 ////////////////////////////////////////////////
    404 error_t fatfs_write_page( struct page_s * page )
    405 {
    406     bool_t is_read = false;
    407     return fatfs_access_page( page , is_read );
    408 }
    409 
    410 ///////////////////////////////////////////////
    411 error_t fatfs_read_page( struct page_s * page )
    412 {
    413     bool_t is_read = true;
    414     return fatfs_access_page( page , is_read );
    415 }
    416 
     529/////////////////////////////////////////////////////////////////
     530error_t fatfs_inode_load( vfs_inode_t * parent_inode,
     531                          char        * name,
     532                          xptr_t        child_inode_xp )
     533{
     534    // Two embedded loops:
     535    // - scan the parent mapper pages
     536    // - scan the directory entries in each 4 Kbytes page
     537
     538    fatfs_dmsg("\n[INFO] %s : enter for child <%s> in parent inode %l\n",
     539               __FUNCTION__ , name , child_inode_xp );
     540
     541    mapper_t * mapper = parent_inode->mapper;
     542
     543    assert( (mapper != NULL) , __FUNCTION__ , "parent mapper undefined\n");
     544   
     545    char       cname[CONFIG_VFS_MAX_NAME_LENGTH];  // name extracter from each directory entry
     546
     547    char       lfn1[16];         // buffer for one partial cname
     548    char       lfn2[16];         // buffer for one partial cname
     549    char       lfn3[16];         // buffer for one partial cname
     550    page_t   * page;             // pointer on current page descriptor
     551    uint8_t  * base;             // pointer on current page base
     552    uint32_t   offset  = 0;      // byte offset in page
     553    uint32_t   index   = 0;      // page index in mapper
     554    uint32_t   attr;             // directory entry ATTR field
     555    uint32_t   ord;              // directory entry ORD field
     556    uint32_t   seq;              // sequence index
     557    uint32_t   lfn     = 0;      // LFN entries number
     558    uint32_t   size    = 0;      // searched file/dir size (bytes)
     559    uint32_t   cluster = 0;      // searched file/dir cluster index
     560    uint32_t   is_dir  = 0;      // searched file/dir type
     561    uint32_t   dentry;           // directory entry index
     562    int32_t    found   = 0;      // not found (0) / name found (1) / end of dir (-1)
     563
     564    // scan the parent directory mapper
     565    while ( found == 0 )
     566    {
     567        // get one page
     568        page = mapper_get_page( mapper , index );
     569
     570        assert( (page != NULL) , __FUNCTION__ , "bad parent mapper\n");
     571
     572        // get page base
     573        base = ppm_page2vaddr( page );
     574
     575        // scan this page until end of directory, end of page, or name found
     576        while( (offset < 4096) && (found == 0) )
     577        {
     578            attr = fatfs_get_record( DIR_ATTR , base + offset , 0 );   
     579            ord  = fatfs_get_record( LDIR_ORD , base + offset , 0 );   
     580
     581            if (ord == NO_MORE_ENTRY)                 // no more entry => break
     582            {
     583                found = -1;
     584            }
     585            else if ( ord == FREE_ENTRY )             // free entry => skip
     586            {
     587                offset = offset + 32;
     588            }
     589            else if ( attr == ATTR_LONG_NAME_MASK )   // LFN entry => get partial cname
     590            {
     591                seq = ord & 0x3;
     592                lfn = (seq > lfn) ? seq : lfn;   
     593                if      ( seq == 1 ) fatfs_get_name_from_long( base + offset, lfn1 );
     594                else if ( seq == 2 ) fatfs_get_name_from_long( base + offset, lfn2 );
     595                else if ( seq == 3 ) fatfs_get_name_from_long( base + offset, lfn3 );
     596                offset = offset + 32;
     597            }
     598            else                                 // NORMAL entry
     599            {
     600                // build the extracted name
     601                if      ( lfn == 0 )
     602                {
     603                    fatfs_get_name_from_short( base + offset , cname );
     604                }
     605                else if ( lfn == 1 )
     606                {
     607                    strcpy( cname      , lfn1 );
     608                }   
     609                else if ( lfn == 2 )
     610                {
     611                    strcpy( cname      , lfn1 );
     612                    strcpy( cname + 13 , lfn2 );
     613                }
     614                else if ( lfn == 3 )
     615                {
     616                    strcpy( cname      , lfn1 );
     617                    strcpy( cname + 13 , lfn2 );
     618                    strcpy( cname + 26 , lfn3 );
     619                }
     620
     621                // get dentry arguments if extracted cname == searched name
     622                if ( strcmp( name , cname ) == 0 )
     623                {
     624                    cluster = (fatfs_get_record( DIR_FST_CLUS_HI , base + offset , 1 ) << 16) |
     625                              (fatfs_get_record( DIR_FST_CLUS_LO , base + offset , 1 )      ) ;
     626                    dentry  = ((index<<12) + offset)>>5;
     627                    is_dir  = ((attr & ATTR_DIRECTORY) == ATTR_DIRECTORY);
     628                    size    = fatfs_get_record( DIR_FILE_SIZE , base + offset , 1 );
     629                    found   = 1;
     630                }
     631                offset = offset + 32;
     632                lfn    = 0;
     633            }
     634        }  // end loop on directory entries
     635        index++;
     636        offset = 0;
     637    }  // end loop on pages
     638
     639    // analyse the result of scan
     640
     641    if ( found == -1 )  // found end of directory => failure
     642    {
     643        fatfs_dmsg("\n[INFO] %s : child <%s> not found in parent inode %l\n",
     644                   __FUNCTION__ , name , parent_inode_xp );
     645
     646        return ENOENT;
     647    }
     648    else               // found searched child name
     649    {
     650        fatfs_dmsg("\n[INFO] %s : child <%s> found in parent inode %l\n",
     651                   __FUNCTION__ , name , parent_inode_xp );
     652
     653        // get child inode cluster and local pointer
     654        cxy_t         child_cxy = GET_CXY( child_inode_xp );
     655        vfs_inode_t * child_ptr = (vfs_inode_t *)GET_PTR( child_inode_xp );
     656
     657        // update the child inode "type", "size", and "extend" fields
     658        vfs_inode_type_t type = (is_dir) ? INODE_TYPE_DIR : INODE_TYPE_FILE;
     659
     660        hal_remote_sw( XPTR( child_cxy , &child_ptr->type   ) , type );
     661        hal_remote_sw( XPTR( child_cxy , &child_ptr->size   ) , size );
     662        hal_remote_sw( XPTR( child_cxy , &child_ptr->extend ) , cluster );
     663
     664        return 0;
     665    }
     666}  // end fatfs_inode_load()
  • trunk/kernel/vfs/fatfs.h

    r188 r238  
    3333///////////////////////////////////////////////////////////////////////////////////////////
    3434// The FATFS File System implements a FAT32 read/write file system.
     35//
     36// The FATFS extensions to the generic VFS are the following:
     37// 1) The vfs_ctx_t "extend" field is a void* pointing on the fatfs_ctx_t structure.
     38//    This structure contains various general informations such as the total
     39//    number of sectors in FAT region, the number of bytes per sector, the number
     40//    of sectors per cluster, the lba of FAT region, the lba of data region, or the
     41//    cluster index for the root directory. It contains also an extended pointer
     42//    on the FAT mapper.
     43// 2) The vfs_inode_t "extend" field is a void*, but contains for each inode,
     44//    the first FAT cluster index (after cast to intptr).
    3545///////////////////////////////////////////////////////////////////////////////////////////
    3646
     
    173183
    174184//////////////////////////////////////////////////////////////////////////////////////////
     185//              FATFS specific but public functions (used by RPC)
     186//////////////////////////////////////////////////////////////////////////////////////////
     187
     188/******************************************************************************************
     189 * This static function scan the FAT (File Allocation Table), stored in the FAT mapper,
     190 * and returns the FATFS cluster index for a given page of a given file.
     191 * It must be called by a thread running in the cluster containing the FAT mapper.
     192 * The FAT is actually an array of uint32_t slots. Each slot in this array contains the
     193 * index of another slot in this array, to form one linked list for each file stored on
     194 * device in the FATFS file system. This index in the FAT array is also the index of the
     195 * FATFS cluster on the device. One FATFS cluster is supposed to contain one PPM page.
     196 * For a given file, the entry point in the FAT is simply the index of the FATFS cluster
     197 * containing the first page of the file. The mapper being a cache, this function
     198 * automatically updates the FAT mapper from informations stored on device in case of miss.
     199 ******************************************************************************************
     200 * @ mapper              : local pointer on the FAT mapper.
     201 * @ first_cluster       : index of the first FATFS cluster allocated to the file.
     202 * @ searched_page   : index of searched page in the file.
     203 * @ cluster         : [out] pointer on buffer for the found FATFS cluster index.
     204 * @ return 0 if success / return EIO if FAT mapper miss cannot be solved.
     205 *****************************************************************************************/
     206error_t fatfs_get_cluster( struct mapper_s * mapper,
     207                           uint32_t          first_cluster,
     208                           uint32_t          searched_page,
     209                           uint32_t        * cluster );
     210
     211
     212
     213
     214//////////////////////////////////////////////////////////////////////////////////////////
    175215// Generic API: These functions are called by the kernel,
    176216//              and must be implemented by all File Systems.
     
    185225
    186226/*****************************************************************************************
    187  * This function access the external boot device, and initialises it
     227 * This function access the boot device, and initialises the FATFS context
    188228 * from informations contained in the boot record.
    189229 *****************************************************************************************
     
    200240
    201241/*****************************************************************************************
    202  * This function moves a page from the mapper to the FATFS file system on device.
     242 * This function moves a page from/to the mapper to/from the FATFS file system on device.
    203243 * It must be called by a thread running in cluster containing the mapper.
    204244 * The pointer on the mapper and the page index in file are registered
    205245 * in the page descriptor.
    206246 *****************************************************************************************
    207  * @ page    : local pointer on page descriptor.
     247 * @ page      : local pointer on page descriptor.
     248 * @ to_mapper : transfer direction
    208249 * @ return 0 if success / return EIO if error.
    209250 ****************************************************************************************/
    210 error_t fatfs_write_page( struct page_s * page );
    211 
    212 /*****************************************************************************************
    213  * This function moves a page from the FATFS file system on device to the mapper.
    214  * It must be called by a thread running in cluster containing the mapper.
    215  * The pointer on the mapper and the page index in file are registered
    216  * in the page descriptor.
    217  *****************************************************************************************
    218  * @ page    : local pointer on page descriptor.
    219  * @ return 0 if success / return EIO if error.
    220  ****************************************************************************************/
    221 error_t fatfs_read_page( struct page_s * page );
    222 
    223 /*****************************************************************************************
    224  * This function scan the FAT (File Allocation Table), stored in the FAT mapper,
    225  * and return the FATFS cluster index for a given page of a given file.
    226  * It must be called by a thread running in the cluster containing the FAT mapper
    227  * (can be a local thread or a RPC thread).
    228  * The FAT is actually an array of uint32_t slots. Each slot in this array contains the
    229  * index of another slot in this array, to form one linked list for each file stored on
    230  * device in the RAMFS file system. This index in the FAT array is also the index of the
    231  * FATFS cluster on the device. One FATFS cluster is supposed to contain one PPM page.
    232  * For a given file, the entry point in the FAT is simply the index of the FATFS cluster
    233  * containing the first page of the file. The mapper being a cache, this function
    234  * automatically updates the FAT mapper from informations stored on device in case of miss.
    235  *****************************************************************************************
    236  * @ mapper              : local pointer on the FAT mapper.
    237  * @ first_cluster       : index of the first FATFS cluster allocated to the file.
    238  * @ searched_page   : index of searched page in the file.
    239  * @ cluster         : [out] pointer on buffer for the found FATFS cluster index.
    240  * @ return 0 if success / return EIO if FAT mapper miss cannot be solved.
    241  ****************************************************************************************/
    242 error_t fatfs_get_cluster( struct mapper_s * mapper,
    243                            uint32_t          first_cluster,
    244                            uint32_t          searched_page,
    245                            uint32_t *        cluster );
     251error_t fatfs_move_page( struct page_s * page,
     252                         bool_t          to_mapper );
     253
     254
     255/*****************************************************************************************
     256 * This function scan an existing parent directory, identified by the <parent> argument,
     257 * to find a directory entry identified by the <name> argument and update the remote
     258 * child inode, identified by the <child_xp> argument.
     259 * It set the "type", "size", and "extend" (FAT cluster index) fields in child inode.
     260 * It must be called by a thread running in the cluster containing the parent inode.
     261 *****************************************************************************************
     262 * @ parent_inode    : local pointer on parent inode (directory).
     263 * @ name            : child name.
     264 * @ child_inode_xp  : extended pointer on remote child inode (file or directory).
     265 * @ return 0 if success / return ENOENT if child not found.
     266 ****************************************************************************************/
     267error_t fatfs_inode_load( struct vfs_inode_s * parent_inode,
     268                          char               * name,
     269                          xptr_t               child_inode_xp );
    246270
    247271#endif  /* _FATFS_H_ */
  • trunk/kernel/vfs/vfs.c

    r222 r238  
    248248}  // end vfs_inode_destroy()
    249249
     250/////////////////////////////////////////////
     251error_t vfs_inode_load( vfs_inode_t * parent,
     252                        char        * name,
     253                        xptr_t        child_xp )
     254{
     255    error_t error = 0;
     256
     257    assert( (parent != NULL) , __FUNCTION__ , "parent pointer is NULL\n");
     258
     259    assert( (child_xp != XPTR_NULL) , __FUNCTION__ , "child pointer is NULL\n");
     260
     261    // get parent inode FS type
     262    vfs_fs_type_t fs_type = parent->ctx->type;
     263
     264    // call relevant FS function
     265    if( fs_type == FS_TYPE_FATFS )
     266    {
     267        error = fatfs_inode_load( parent , name , child_xp );
     268    }
     269    else if( fs_type == FS_TYPE_RAMFS )
     270    {
     271        assert( false , __FUNCTION__ , "should not be called for RAMFS\n" );
     272    }
     273    else if( fs_type == FS_TYPE_DEVFS )
     274    {
     275        assert( false , __FUNCTION__ , "should not be called for DEVFS\n" );
     276    }
     277    else
     278    {
     279        assert( false , __FUNCTION__ , "undefined file system type\n" );
     280    }
     281
     282    return error;
     283
     284} // end vfs_load_inode()
     285
    250286////////////////////////////////////////////
    251287void vfs_inode_remote_up( xptr_t  inode_xp )
     
    594630
    595631    if( error ) return error;
     632
     633    vfs_dmsg("\n[INFO] %s exit for %s / file_id = %d / file_xp = %l / at cycle %d\n",
     634             __FUNCTION__ , path , file_id , file_xp , hal_get_cycles() );
    596635
    597636    // success
     
    11611200    cxy_t              child_cxy;    // cluster for child inode
    11621201    vfs_inode_t      * child_ptr;    // local pointer on child inode 
    1163     vfs_inode_type_t   inode_type;   // child inode type
     1202    vfs_inode_type_t   child_type;   // child inode type
    11641203    vfs_fs_type_t      fs_type;      // File system type
    11651204    vfs_ctx_t        * ctx_ptr;      // local pointer on FS context
     
    12061245                               &child_xp );
    12071246
    1208         if( found == false ) // child inode not found in inode tree => try to load it
     1247        // if a child inode is not found in the inode tree:
     1248        // - we create the missing inode/dentry couple in the inode tree,
     1249        // - we scan the parent mapper to complete the child inode (type and extension),
     1250        // - we return an error if child not found on device.
     1251        // - if the missing child is a directory, we load the child mapper from device
     1252
     1253        // for the last name, the behaviour depends on the "mode" argument:
     1254
     1255        if (found == false ) // directory node not found in inode tree
    12091256        {
    12101257            vfs_dmsg("\n[INFO] %s : <%s> not found, try to load it\n",
     
    12141261            vfs_inode_unlock( parent_xp );
    12151262
    1216             // get cluster and local pointer on parent inode
     1263            // get parent inode FS type
    12171264            parent_cxy = GET_CXY( parent_xp );
    12181265            parent_ptr = (vfs_inode_t *)GET_PTR( parent_xp );
    12191266
    1220             // get local pointer on parent inode context
    1221             ctx_ptr = (vfs_ctx_t *)hal_remote_lpt( XPTR( parent_cxy , &parent_ptr->ctx ) );
    1222 
    1223             // get parent inode FS type
    1224             fs_type = hal_remote_lw( XPTR( parent_cxy , &ctx_ptr->type ) );
    1225 
    1226             // get child inode type
    1227             if( (last == false) || (mode & VFS_LOOKUP_DIR) ) inode_type = INODE_TYPE_DIR;
    1228             else                                             inode_type = INODE_TYPE_FILE;
    1229 
    1230             // select a cluster for child inode
    1231             cxy_t child_cxy = vfs_cluster_random_select();
     1267            ctx_ptr    = (vfs_ctx_t *)hal_remote_lpt( XPTR( parent_cxy ,
     1268                                                            &parent_ptr->ctx ) );
     1269            fs_type    = hal_remote_lw( XPTR( parent_cxy , &ctx_ptr->type ) );
     1270
     1271            // select a cluster for missing inode
     1272            child_cxy = vfs_cluster_random_select();
    12321273                     
    1233 printk("\n@@@ name not found : <%s>\n", name );
    1234 
    12351274            // insert a new child dentry/inode in parent inode
    12361275            error = vfs_add_child_in_parent( child_cxy,
    1237                                              inode_type,
     1276                                             INODE_TYPE_DIR,
    12381277                                             fs_type,
    12391278                                             parent_xp,
    12401279                                             name,
    1241                                              NULL,           // fs_type_specific inode extend
     1280                                             NULL,     // fs_type_specific inode extend
    12421281                                             &child_xp );
    12431282            if( error )
     1283            {
     1284                printk("\n[ERROR] in %s : no memory for inode %s in path %s\n",
     1285                       __FUNCTION__ , name , pathname );
     1286                return ENOMEM;
     1287            }
     1288
     1289            // scan parent mapper to complete the missing inode
     1290            if( parent_cxy == local_cxy )
     1291            {
     1292                error = vfs_inode_load( parent_ptr,
     1293                                        name,
     1294                                        child_xp );
     1295            }
     1296            else
     1297            {
     1298                rpc_vfs_inode_load_client( parent_cxy,
     1299                                           parent_ptr,
     1300                                           name,
     1301                                           child_xp,
     1302                                           &error );
     1303            }
     1304
     1305            if ( error )
    12441306            {
    12451307                printk("\n[ERROR] in %s : node %s not found in path %s\n",
     
    12481310            }
    12491311
     1312            // get child inode type
     1313            child_ptr  = (vfs_inode_t *)GET_PTR( child_xp );
     1314            child_type = hal_remote_lw( XPTR( child_cxy , &child_ptr->type ) );
     1315
     1316            // load child mapper from device if it is a directory
     1317            if( child_type == INODE_TYPE_DIR )
     1318            {
     1319                if( child_cxy == local_cxy )
     1320                {
     1321                    error = vfs_mapper_load_all( child_ptr );
     1322                }
     1323                else
     1324                {
     1325                    rpc_vfs_mapper_load_all_client( child_cxy,
     1326                                                    child_ptr,
     1327                                                    &error );
     1328                }
     1329
     1330                if ( error )
     1331                {
     1332                    printk("\n[ERROR] in %s : cannot access device for node %s in path %s\n",
     1333                           __FUNCTION__ , name , pathname );
     1334                    return EIO;
     1335                }
     1336            }
     1337
     1338            // TODO handle lookup mode here [AG]
     1339
    12501340            // take lock on parent inode
    12511341            vfs_inode_lock( parent_xp );
    12521342        }
    12531343
    1254 vfs_inode_display( child_xp );
    1255 
    1256 vfs_display( parent_xp );
    1257 
    12581344        vfs_dmsg("\n[INFO] %s : found <%s> / parent = %l / child = %l / last = %d\n",
    1259                  __FUNCTION__ , name , parent_xp , child_xp , last );
     1345                     __FUNCTION__ , name , parent_xp , child_xp , last );
    12601346
    12611347        // TODO check access rights
     
    12691355        // }
    12701356
    1271         // TODO TODO TODO access device and load inode mapper if required...
    1272 
    1273         // take lock on child inode if not last
    1274         if( last == false ) vfs_inode_lock( child_xp );
    1275 
    1276         // release lock on parent inode
     1357        // take lock on child inode and release lock on parent
     1358        vfs_inode_lock( child_xp );
    12771359        vfs_inode_unlock( parent_xp );
    12781360
     
    12801362        parent_xp = child_xp;
    12811363        current   = next;
    1282 
    1283         vfs_dmsg("\n[INFO] %s : complete node <%s> / last = %d\n",
    1284                  __FUNCTION__ , name , last );
    1285 
    12861364    }
    12871365    while( last == false );
    12881366
    1289     vfs_dmsg("\n[INFO] in %s : searched inode found for %s\n",
    1290                  __FUNCTION__ , pathname );
    1291 
    1292     // get cluster and local pointer on child inode
    1293     child_cxy = GET_CXY( child_xp );
    1294     child_ptr = (vfs_inode_t *)GET_PTR( child_xp );
    1295 
    1296     // return searched pointers
     1367    // release lock
     1368    vfs_inode_unlock( parent_xp );
     1369
     1370    vfs_dmsg("\n[INFO] in %s : exit / %s found / inode = %l\n",
     1371                 __FUNCTION__ , pathname , child_xp );
     1372
     1373    // return searched pointer
    12971374    *inode_xp = child_xp;
    12981375
     
    13851462    cxy_t           parent_cxy;  // parent inode cluster identifier
    13861463    vfs_inode_t   * parent_ptr;  // parent inode local pointer
    1387     vfs_ctx_t     * parent_ctx;  // parent inode context local pointer
    13881464
    13891465    // get parent inode cluster and local pointer
     
    14711547}  // end vfs_add_child_in_parent()
    14721548
    1473 
    1474 
    1475 
    14761549//////////////////////////////////////////////////////////////////////////////////////////
    14771550//            Mapper related functions
    14781551//////////////////////////////////////////////////////////////////////////////////////////
    14791552
    1480 ////////////////////////////////////////////////
    1481 error_t vfs_move_page_to_mapper( page_t * page )
     1553////////////////////////////////////////////
     1554error_t vfs_mapper_move_page( page_t * page,
     1555                              bool_t   to_mapper )
    14821556{
    14831557    error_t error = 0;
     
    14921566    vfs_fs_type_t fs_type = mapper->inode->ctx->type;
    14931567
    1494     // update mapper if permitted by file system type
     1568    // call relevant FS function
    14951569    if( fs_type == FS_TYPE_FATFS )
    14961570    {
    1497         // get mapper lock in WRITE_MODE
    14981571        rwlock_wr_lock( &mapper->lock );
    1499 
    1500         error = fatfs_read_page( page );
    1501 
    1502         // release mapper lock
     1572        error = fatfs_move_page( page , to_mapper );
    15031573        rwlock_wr_unlock( &mapper->lock );
    15041574    }
     
    15181588    return error;
    15191589
    1520 }  // end vfs_move_page_to_mapper()
     1590}  // end vfs_move_page()
    15211591
    15221592//////////////////////////////////////////////////
    1523 error_t vfs_move_page_from_mapper( page_t * page )
    1524 {
    1525     error_t         error = 0;
    1526 
    1527     assert( (page != NULL) , __FUNCTION__ , "page pointer is NULL\n" );
    1528 
    1529     mapper_t * mapper = page->mapper;
     1593error_t vfs_mapper_load_all( vfs_inode_t * inode )
     1594{
     1595    assert( (inode != NULL) , __FUNCTION__ , "page pointer is NULL\n" );
     1596
     1597    uint32_t   index;
     1598    page_t   * page;
     1599
     1600    mapper_t * mapper = inode->mapper;
     1601    uint32_t   size   = inode->size;
    15301602
    15311603    assert( (mapper != NULL) , __FUNCTION__ , "no mapper for page\n" );
    15321604
    1533     // get FS type
    1534     vfs_fs_type_t  fs_type = mapper->inode->ctx->type;
    1535 
    1536     // update file system if permitted by file system type
    1537     if( fs_type == FS_TYPE_FATFS )
    1538     {
    1539             if( page_is_flag( page , PG_DIRTY ) )
    1540             {
    1541             // get mapper lock in READ_MODE
    1542             rwlock_rd_lock( &mapper->lock );
    1543 
    1544             error = fatfs_write_page( page );
    1545 
    1546             // release mapper lock from READ_MODE
    1547             rwlock_rd_unlock( &mapper->lock );
    1548 
    1549             // clear dirty bit if success
    1550                     if( error == 0 ) page_undo_dirty( page );
    1551          }
    1552     }
    1553     else if( fs_type == FS_TYPE_RAMFS )
    1554     {
    1555         assert( false , __FUNCTION__ , "should not be called for RAMFS\n" );
    1556     }
    1557     else if( fs_type == FS_TYPE_DEVFS )
    1558     {
    1559         assert( false , __FUNCTION__ , "should not be called for DEVFS\n" );
    1560     }
    1561     else
    1562     {
    1563         assert( false , __FUNCTION__ , "undefined file system type\n" );
    1564     }
    1565        
    1566     return error;
    1567 
    1568 }  // end vfs_move_page_from_mapper()
    1569 
    1570 
     1605    assert( (size != 0) , __FUNCTION__ , "size cannot be 0\n");
     1606
     1607    uint32_t npages = size >> CONFIG_PPM_PAGE_SHIFT;
     1608    if( size & CONFIG_PPM_PAGE_MASK ) npages++;
     1609
     1610    // loop on all pages
     1611    for( index = 0 ; index < npages ; index ++ )
     1612    {
     1613        // this function allocates the missing page in mapper,
     1614        // and call the vfs_mapper_move_page() to load the page from device
     1615        page = mapper_get_page( mapper , index );
     1616
     1617        if( page == NULL ) return EIO;
     1618    }
     1619
     1620    return 0;
     1621
     1622}  // end vfs_mapper_load_all()
     1623
  • trunk/kernel/vfs/vfs.h

    r204 r238  
    399399void vfs_inode_destroy( vfs_inode_t *  inode ); 
    400400
     401/******************************************************************************************
     402 * This function scan an existing parent inode directory, identified by the <parent>
     403 * argument to find a directory entry identified by the <name> argument, and update
     404 * the remote child inode, identified by the <child_xp> argument.
     405 * Depending on the file system type, it calls the relevant, FS specific function,
     406 * to scan the directory, and set the "type", "size", and "extend" fields.
     407 * It must be called by a thread running in the cluster containing the parent inode.
     408 ******************************************************************************************
     409 * @ parent    : local pointer on parent inode (directory).
     410 * @ name      : child name.
     411 * @ child_xp  : extended pointer on remote child inode (file or directory)
     412 * @ return 0 if success / return ENOENT if not found.
     413 *****************************************************************************************/
     414error_t vfs_inode_load( vfs_inode_t * parent,
     415                        char        * name,
     416                        xptr_t        child_xp );
     417
    401418/******************************************************************************************
    402419 * This function atomically increment/decrement the inode refcount.
     
    617634 * @ pathname    : path in kernel space (can be relative or absolute).
    618635 * @ lookup_mode : flags defining the working mode (defined above in this file).
    619  * @ inode_xp    : [out] buffer for extended pointer on inode.
     636 * @ inode_xp    : [out] buffer for extended pointer on searched inode.
    620637 * @ return 0 if success / ENOENT if inode not found , EACCES if permissopn denied,
    621638 *                        EAGAIN if a new complete lookup must be made
     
    635652 * 2) The inode and its associated mapper are created in cluster identified by <child_cxy>.
    636653 *    The new inode and the parent inode can have different FS types.
    637  * 3) The "child_xp" field in created dentry (pointing on thecreated inode) is updated.
     654 * 3) The "child_xp" field in created dentry (pointing on the created inode) is updated.
    638655 ******************************************************************************************
    639656 * @ child_cxy  : target cluster for child inode.
     
    666683 * This recursive function diplays a complete inode/dentry sub-tree.
    667684 * Any inode can be selected as the sub-tree root.
    668  * TODO this function is not ptotected against a concurrent node removal...
     685 * TODO this function is not protected against a concurrent inode/dentry removal...
    669686 ******************************************************************************************
    670687 * @ inode_xp   : extended pointer on sub-tree root inode.
     
    857874
    858875/******************************************************************************************
    859  * This function makes an I/O operation to move one page from VFS to a given mapper,
    860  * in case of MISS on the mapper cache.
     876 * This function makes an I/O operation to move one page to/from device from/to the mapper.
     877 * It is used in case of MISS on the mapper, or when a dirty page in the mapper must
     878 * be updated in the File System.
    861879 * Depending on the file system type, it calls the proper, FS specific function.
    862880 * It must be executed by a thread running in the cluster containing the mapper.
     
    864882 * It takes the mapper lock before launching the IO operation.
    865883 ******************************************************************************************
    866  * @ page   : local pointer on the page descriptor.
     884 * @ page      : local pointer on the page descriptor.
     885 * @ to_mapper : transfer direction.
    867886 * @ returns 0 if success / return EINVAL if it cannot access the external device.
    868887 *****************************************************************************************/
    869 error_t vfs_move_page_to_mapper( struct page_s * page );
    870 
    871 /******************************************************************************************
    872  * This function makes an I/0 operation to move one page from a given mapper to VFS,
    873  * when a dirty page in the mapper cache must be updated in the File System.
     888error_t vfs_mapper_move_page( struct page_s * page,
     889                              bool_t          to_mapper );
     890
     891/******************************************************************************************
     892 * This function makes an I/O operation to move, from device to mapper, all pages covering
     893 * a given inode, identified by the <inode> argument. It can be a directory or a file,
     894 * but is mainly used to load (prefetch) a complete directory in the inode mapper.
    874895 * Depending on the file system type, it calls the proper, FS specific function.
    875896 * It must be executed by a thread running in the cluster containing the mapper.
    876  * The mapper pointer is obtained from the page descriptor.
     897 * The mapper pointer is obtained from the inode descriptor.
    877898 * It takes the mapper lock before launching the IO operation.
    878  * It does nothing if the page is not dirty. If the page is dirty, it clear the page
    879  * dirty bit, and remove the page from the PPM dirty list.
    880  ******************************************************************************************
    881  * @ page   : local pointer on the page descriptor.
    882  * @ returns 0 if success / return EINVAL if it cannot access the external device.
    883  *****************************************************************************************/
    884 error_t vfs_move_page_from_mapper( struct page_s * page );       
    885 
    886 
    887 
    888 
    889 
    890 
    891 ///////////////////////////////////////////////////////////////////////////////////////////
    892 // These typedef define the FS specific operations that must be implemented by any
    893 // specific file system to be supported by the ALMOS_MKH VFS.
    894 // These typedef are not actually used, and are only defined for documentation
    895 ///////////////////////////////////////////////////////////////////////////////////////////
    896 
    897 typedef error_t (fs_init_t)          ( xptr_t vfs_root_xp );
    898 
    899 typedef error_t (fs_inode_extend_t)  ( struct vfs_inode_s * inode,
    900                                        void               * extend );
    901  
    902 typedef void    (fs_inode_release_t) ( struct vfs_inode_s * inode );
    903 
    904 typedef error_t (fs_write_page_t)    ( struct page_s * page );
    905 
    906 typedef error_t (fs_read_page_t)     ( struct page_s * page );
    907 
    908 
    909 
    910 
    911 
     899 ******************************************************************************************
     900 * @ inode  : local pointer on inode.
     901 * @ return 0 if success / return EIO if device access failure.
     902 *****************************************************************************************/
     903error_t vfs_mapper_load_all( vfs_inode_t * inode );
    912904
    913905
Note: See TracChangeset for help on using the changeset viewer.