Changeset 188 for trunk/kernel/vfs


Ignore:
Timestamp:
Jul 12, 2017, 8:12:41 PM (5 years ago)
Author:
alain
Message:

Redefine the PIC device API.

Location:
trunk/kernel/vfs
Files:
8 edited

Legend:

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

    r50 r188  
    2626#include <hal_special.h>
    2727#include <printk.h>
     28#include <chdev.h>
     29#include <cluster.h>
     30#include <vfs.h>
    2831#include <kmem.h>
    29 #include <string.h>
    30 #include <chdev.h>
    31 #include <core.h>
    32 #include <thread.h>
    33 #include <vfs.h>
    34 #include <errno.h>
    3532#include <devfs.h>
    36 #include <rpc.h>
    37 
    38 
    39 //////////////////////////////////////////////////////////////////////////////////////////
    40 //          Extern  variables         
    41 //////////////////////////////////////////////////////////////////////////////////////////
    42 
    43 extern vfs_ctx_t          fs_context[FS_TYPES_NR];   // allocated in vfs.c file
    44 
    45 extern remote_barrier_t   global_barrier;            // allocated in kernel_init.c
    46  
    47 extern chdev_directory_t  chdev_dir;                 // allocated in kernel_init.c
    48 
    49 ////////////////////////////////////////////////////////////////////////////////////////
    50 //                DEVFS private functions
    51 ////////////////////////////////////////////////////////////////////////////////////////
    52 
    53 ////////////////////////////////////////////////////////////////////////////////////////
    54 // This function creates in the local cluster the dentry and the associated inode,
    55 // for a DEVFS directory (level 0 or level 1 in DEVFS tree).
    56 ////////////////////////////////////////////////////////////////////////////////////////
    57 // @ name        : directory entry name.
    58 // @ parent_xp   : extended pointer on parent inode.
    59 // @ inode_xp    : [out] buffer for extended pointer on created inode.
    60 ////////////////////////////////////////////////////////////////////////////////////////
    61 static void devfs_create_directory( char        * name,
    62                                     xptr_t        parent_xp,
    63                                     xptr_t      * inode_xp )
    64 {
    65     error_t       error;
    66     xptr_t        new_dentry_xp;     // extended pointer on created dentry
    67     xptr_t        new_inode_xp;      // extended pointer on created inode
    68  
    69     // get parent inode cluster and local pointer
    70     cxy_t         parent_cxy = GET_CXY( parent_xp );
    71     vfs_inode_t * parent_ptr = (vfs_inode_t *)GET_PTR( parent_xp );
    72 
    73     // create vfs_dentry in cluster containing the parent inode
    74     if( parent_cxy == local_cxy )
    75     {
    76         error = vfs_dentry_create( FS_TYPE_DEVFS,
    77                                    name,
    78                                    parent_ptr,
    79                                    &new_dentry_xp );
    80     }
    81     else
    82     {
    83         rpc_vfs_dentry_create_client( parent_cxy,
    84                                       FS_TYPE_DEVFS,
    85                                       name,
    86                                       parent_ptr,
    87                                       &new_dentry_xp,
    88                                       &error );
    89     }
    90 
    91     if ( error )
    92     {
    93         printk("\n[PANIC] in %s : cannot create dentry for %s in cluster %x/n",
    94                __FUNCTION__ , name , local_cxy );
    95         hal_core_sleep();
    96     }
    97 
    98     // create vfs_inode in local cluster TODO define the 4 arguments below [AG]
    99     uint32_t  attr   = 0;
    100     uint32_t  rights = 0;
    101     uid_t     uid    = 0;
    102     gid_t     gid    = 0;
    103     error = vfs_inode_create( new_dentry_xp,
    104                               FS_TYPE_DEVFS,
    105                               INODE_TYPE_DIR,
    106                               attr,
    107                               rights,
    108                               uid,
    109                               gid,
    110                               &new_inode_xp );
    111     if( error )
    112     {
    113         printk("\n[PANIC] in %s : cannot create inode for %s in cluster %x/n",
    114                __FUNCTION__ , name , local_cxy );
    115         hal_core_sleep();
    116     }
    117 
    118     // return extended pointer on directory inode
    119     *inode_xp = new_inode_xp;
    120 
    121 }  // end devfs_create_directory()
    122                                    
    123 ////////////////////////////////////////////////////////////////////////////////////////
    124 // This function creates in the local cluster the dentry and the associated inode,
    125 // for a chdev (level 2 in DEVFS tree).
    126 ////////////////////////////////////////////////////////////////////////////////////////
    127 // @ chdev    : local pointer on local chdev.
    128 // @ name     : directory entry name.
    129 // @ parent   : local pointer on local parent inode.
    130 // @ inode_xp : [out] buffer for extended pointer on created inode.
    131 ////////////////////////////////////////////////////////////////////////////////////////
    132 static void devfs_register_chdev( chdev_t     * chdev,
    133                                   char        * name,
    134                                   vfs_inode_t * parent,
    135                                   xptr_t      * inode_xp )
     33
     34/////////////////////////////////////////////////////////////////////////////////////////
     35//     Extern variables
     36/////////////////////////////////////////////////////////////////////////////////////////
     37
     38extern vfs_ctx_t            fs_context[];   // allocated in kernel_init.c
     39extern chdev_directory_t    chdev_dir;      // allocated in kernel_init.c
     40
     41///////////////////////////////
     42devfs_ctx_t * devfs_ctx_alloc()
     43{
     44    kmem_req_t    req;
     45
     46        req.type    = KMEM_DEVFS_CTX;
     47        req.size    = sizeof(devfs_ctx_t);
     48    req.flags   = AF_KERNEL | AF_ZERO;
     49
     50        return (devfs_ctx_t *)kmem_alloc( &req );
     51}
     52
     53/////////////////////////////////////////////
     54void devfs_ctx_init( devfs_ctx_t * devfs_ctx,
     55                     xptr_t        devfs_root_inode_xp,
     56                     xptr_t        devfs_external_inode_xp )
     57{
     58    devfs_ctx->root_inode_xp     = devfs_root_inode_xp;
     59    devfs_ctx->external_inode_xp = devfs_external_inode_xp;
     60
     61    fs_context[FS_TYPE_DEVFS].extend = devfs_ctx;
     62}
     63
     64/////////////////////////////////////////////////
     65void devfs_ctx_destroy( devfs_ctx_t * devfs_ctx )
     66{
     67    kmem_req_t    req;
     68
     69    req.type = KMEM_DEVFS_CTX;
     70    req.ptr  = devfs_ctx;
     71    kmem_free( &req );
     72}
     73
     74///////////////////////////////////////////////////
     75void devfs_global_init( xptr_t   parent_inode_xp,
     76                        xptr_t * devfs_root_inode_xp,
     77                        xptr_t * devfs_external_inode_xp )
    13678{
    13779    error_t  error;
    138     xptr_t   new_dentry_xp;
    139     xptr_t   new_inode_xp;
    140 
    141     devfs_dmsg("\n[INFO] %s : create dentry for %s\n", __FUNCTION__ , name );
    142    
    143     // create vfs_dentry in local cluster
    144     error = vfs_dentry_create( FS_TYPE_DEVFS,
    145                                name,
    146                                parent,
    147                                &new_dentry_xp );
    148     if ( error )
    149     {
    150         printk("\n[PANIC] in %s : cannot create dentry for %s in cluster %x/n",
    151                __FUNCTION__ , name , local_cxy );
    152         hal_core_sleep();
    153     }
    154 
    155     devfs_dmsg("\n[INFO] %s : create inode for %s\n", __FUNCTION__ , name );
    156    
    157     // create vfs_inode in local cluster
    158     uint32_t  attr   = 0;
    159     uint32_t  rights = 0;
    160     uid_t     uid    = 0;
    161     gid_t     gid    = 0;
    162     error = vfs_inode_create( new_dentry_xp,
    163                               FS_TYPE_DEVFS,
    164                               INODE_TYPE_DEV,
    165                               attr,
    166                               rights,
    167                               uid,
    168                               gid,
    169                               &new_inode_xp );
    170     if( error )
    171     {
    172         printk("\n[PANIC] in %s : cannot create inode for %s in cluster %x/n",
    173                __FUNCTION__ , name , local_cxy );
    174         hal_core_sleep();
    175     }
    176 
    177     // return extended pointer on chdev inode
    178     *inode_xp = new_inode_xp;
    179    
    180 }  // end devfs_register_chdev()
    181 
    182 
    183 
    184 ///////////////////////////////////////////////////////////////////////////////////////
    185 // Generic API : the following functions are called by the VFS,
    186 //               and must be defined by all supported file systems.
    187 ///////////////////////////////////////////////////////////////////////////////////////
    188 
    189 ////////////////////////////////////////////
    190 
    191 ////////////////////////////////////////////
    192 error_t devfs_mount( xptr_t   parent_inode_xp,
    193                      char   * devfs_root_name )
    194 {
    195     assert( (CURRENT_CORE->lid == 0) , __FUNCTION__ , "only CP0 should do it" );
    196 
    197     vfs_inode_t * parent_inode_ptr;
    198     cxy_t         parent_inode_cxy;
    199     vfs_ctx_t   * vfs_ctx;
    200 
     80
     81    // creates DEVFS "dev" inode in cluster IO
     82    error = vfs_add_child_in_parent( LOCAL_CLUSTER->io_cxy,
     83                                     INODE_TYPE_DIR,
     84                                     FS_TYPE_DEVFS,
     85                                     parent_inode_xp,
     86                                     "dev",
     87                                     NULL,
     88                                     devfs_root_inode_xp );
     89
     90    nolock_assert( (error == 0) , __FUNCTION__ , "cannot create <dev>\n" );
     91
     92    // create DEVFS "external" inode in cluster IO
     93    error = vfs_add_child_in_parent( LOCAL_CLUSTER->io_cxy,
     94                                     INODE_TYPE_DIR,
     95                                     FS_TYPE_DEVFS,
     96                                     *devfs_root_inode_xp,
     97                                     "dev",
     98                                     NULL,
     99                                     devfs_external_inode_xp );
     100
     101    nolock_assert( (error == 0) , __FUNCTION__ , "cannot create <external>\n" );
     102}
     103
     104//////////////////////////////////////////////////
     105void devfs_local_init( xptr_t devfs_root_inode_xp,
     106                       xptr_t devfs_external_inode_xp )
     107{
    201108    char          node_name[16];
     109    xptr_t        chdev_xp;
     110    cxy_t         chdev_cxy;
     111    xptr_t        inode_xp;
     112    xptr_t        internal_inode_xp;
    202113    uint32_t      channel;
    203114
    204     xptr_t        root_inode_xp;
    205     xptr_t        external_inode_xp;
    206     xptr_t        internal_inode_xp;
    207     xptr_t        chdev_inode_xp;
    208 
    209     chdev_t     * chdev_ptr;
    210 
    211     // get number of kernel instances and extended pointer on global barrier
    212     cluster_t * cluster     = LOCAL_CLUSTER;
    213     uint32_t    nb_clusters = cluster->x_size * cluster->y_size;
    214     xptr_t      barrier_xp  = XPTR( cluster->io_cxy , &global_barrier );
    215 
    216     // get VFS root inode cluster and local pointer
    217     parent_inode_cxy = GET_CXY( parent_inode_xp );
    218     parent_inode_ptr = (vfs_inode_t *)GET_PTR( parent_inode_xp );
    219 
    220     // get local pointer on VFS context for DEVFS
    221     vfs_ctx = &fs_context[FS_TYPE_DEVFS];
    222 
    223     ///// step 1 : all clusters initialize local DEVFS context  /////
    224 
    225     devfs_ctx_init( vfs_ctx , parent_inode_xp );
    226 
    227     ///// step 2 : cluster_0 creates DEVFS root    /////
    228 
    229     if( local_cxy == 0 )
    230     {
    231         devfs_create_directory( devfs_root_name,
    232                                 parent_inode_xp,
    233                                 &root_inode_xp );
    234     }
    235 
    236     // synchronize all clusters
    237     remote_barrier( barrier_xp , nb_clusters );
    238 
    239     ///// step 3 : all clusters create "internal" directory and chdevs  /////
    240 
    241     // TODO check device existence : (chdev_xp != XPTR_NULL) in chdev_dir
    242 
     115    // create "internal" directory linked to "dev"
    243116    snprintf( node_name , 16 , "internal_%x" , local_cxy );
    244 
    245     devfs_create_directory( node_name,
    246                             root_inode_xp,
    247                             &internal_inode_xp );
     117    vfs_add_child_in_parent( local_cxy,
     118                             INODE_TYPE_DIR,
     119                             FS_TYPE_DEVFS,
     120                             devfs_root_inode_xp,
     121                             node_name,
     122                             NULL,
     123                             &internal_inode_xp );
    248124
    249125    // create ICU chdev inode
    250     chdev_ptr = (chdev_t *)GET_PTR( chdev_dir.icu[local_cxy] );
    251     devfs_register_chdev( chdev_ptr,
    252                           "icu",
    253                           (vfs_inode_t *)GET_PTR( internal_inode_xp ),
    254                           &chdev_inode_xp );
     126    chdev_xp = chdev_dir.icu[local_cxy];
     127    if( chdev_xp != XPTR_NULL)
     128    {
     129        vfs_add_child_in_parent( local_cxy,
     130                                 INODE_TYPE_DEV,
     131                                 FS_TYPE_DEVFS,
     132                                 internal_inode_xp,
     133                                 "icu",
     134                                 GET_PTR( chdev_xp ),
     135                                 &inode_xp );
     136    }
    255137
    256138    // create MMC chdev inode
    257     chdev_ptr = (chdev_t *)GET_PTR( chdev_dir.mmc[local_cxy] );
    258     devfs_register_chdev( chdev_ptr,
    259                           "mmc",
    260                           (vfs_inode_t *)GET_PTR( internal_inode_xp ),
    261                           &chdev_inode_xp );
     139    chdev_xp = chdev_dir.mmc[local_cxy];
     140    if( chdev_xp != XPTR_NULL)
     141    {
     142        vfs_add_child_in_parent( local_cxy,
     143                                 INODE_TYPE_DEV,
     144                                 FS_TYPE_DEVFS,
     145                                 internal_inode_xp,
     146                                 "mmc",
     147                                 GET_PTR( chdev_xp ),
     148                                 &inode_xp );
     149    }
    262150
    263151    // create DMA chdev inodes (one DMA channel per core)
    264     for( channel = 0 ; channel < cluster->cores_nr ; channel++ )
    265     {
    266         chdev_ptr = (chdev_t *)GET_PTR( chdev_dir.dma[channel] );
    267         snprintf( node_name , 16 , "dma_%d" , channel );
    268         devfs_register_chdev( chdev_ptr,
    269                               node_name,
    270                               (vfs_inode_t *)GET_PTR( internal_inode_xp ),
    271                               &chdev_inode_xp );
    272     }
    273 
    274     ///// step 4 : cluster_io creates "external" directory and chdevs /////
    275 
    276     // TODO check device existence : (chdev_xp != XPTR_NULL) in chdev_dir
    277 
    278     if( local_cxy == cluster->io_cxy )
    279     {
    280         devfs_create_directory( "external",
    281                                 root_inode_xp,
    282                                 &external_inode_xp );
    283 
    284         // create IOB chdev inode
    285         chdev_ptr = (chdev_t *)GET_PTR( chdev_dir.iob );
    286         devfs_register_chdev( chdev_ptr,
    287                               "iob",
    288                               (vfs_inode_t *)GET_PTR( external_inode_xp ),
    289                               &chdev_inode_xp );
     152    for( channel = 0 ; channel < LOCAL_CLUSTER->cores_nr ; channel++ )
     153    {
     154        chdev_xp = chdev_dir.dma[channel];
     155        if( chdev_xp != XPTR_NULL)
     156        {
     157            snprintf( node_name , 16 , "dma_%d" , channel );
     158            vfs_add_child_in_parent( local_cxy,
     159                                     INODE_TYPE_DEV,
     160                                     FS_TYPE_DEVFS,
     161                                     internal_inode_xp,
     162                                     node_name,
     163                                     GET_PTR( chdev_xp ),
     164                                     &inode_xp );
     165        }
     166    }
     167
     168    // create an IOB inode in cluster containing IOB chdev
     169    chdev_xp = chdev_dir.iob;
     170    if( chdev_xp != XPTR_NULL )
     171    {
     172        chdev_cxy = GET_CXY( chdev_xp );
     173        if( chdev_cxy == local_cxy )
     174        {
     175            vfs_add_child_in_parent( local_cxy,
     176                                     INODE_TYPE_DEV,
     177                                     FS_TYPE_DEVFS,
     178                                     devfs_external_inode_xp,
     179                                     "iob",
     180                                     GET_PTR( chdev_xp ),
     181                                     &inode_xp );
     182        }
     183    }
    290184       
    291         // create PIC chdev inode
    292         chdev_ptr = (chdev_t *)GET_PTR( chdev_dir.pic );
    293         devfs_register_chdev( chdev_ptr,
    294                               "pic",
    295                               (vfs_inode_t *)GET_PTR( external_inode_xp ),
    296                               &chdev_inode_xp );
    297 
    298         // create TXT chdev inodes
    299         for( channel = 0 ; channel < CONFIG_MAX_TXT_CHANNELS ; channel++ )
    300         {
    301             chdev_ptr = (chdev_t *)GET_PTR( chdev_dir.txt[channel] );
    302             snprintf( node_name , 16 , "txt_%d" , channel );
    303             devfs_register_chdev( chdev_ptr,
    304                                   node_name,
    305                                   (vfs_inode_t *)GET_PTR( external_inode_xp ),
    306                                   &chdev_inode_xp );
    307         }
    308 
    309         // create IOC chdev inodes
    310         for( channel = 0 ; channel < CONFIG_MAX_IOC_CHANNELS ; channel++ )
    311         {
    312             chdev_ptr = (chdev_t *)GET_PTR( chdev_dir.ioc[channel] );
    313             snprintf( node_name , 16 , "ioc_%d" , channel );
    314             devfs_register_chdev( chdev_ptr,
    315                                   node_name,
    316                                   (vfs_inode_t *)GET_PTR( external_inode_xp ),
    317                                   &chdev_inode_xp );
    318         }
    319 
    320         // create FBF chdev inodes
    321         for( channel = 0 ; channel < CONFIG_MAX_IOC_CHANNELS ; channel++ )
    322         {
    323             chdev_ptr = (chdev_t *)GET_PTR( chdev_dir.ioc[channel] );
    324             snprintf( node_name , 16 , "fbf_%d" , channel );
    325             devfs_register_chdev( chdev_ptr,
    326                                   node_name,
    327                                   (vfs_inode_t *)GET_PTR( external_inode_xp ),
    328                                   &chdev_inode_xp );
    329         }
    330 
    331         // create NIC_RX chdevs
    332         for( channel = 0 ; channel < CONFIG_MAX_NIC_CHANNELS ; channel++ )
    333         {
    334             chdev_ptr = (chdev_t *)GET_PTR( chdev_dir.nic_rx[channel] );
    335             snprintf( node_name , 16 , "nic_rx_%d" , channel );
    336             devfs_register_chdev( chdev_ptr,
    337                                   node_name,
    338                                   (vfs_inode_t *)GET_PTR( external_inode_xp ),
    339                                   &chdev_inode_xp );
    340         }
    341 
    342         // create NIC_TX chdev inodes
    343         for( channel = 0 ; channel < CONFIG_MAX_NIC_CHANNELS ; channel++ )
    344         {
    345             chdev_ptr = (chdev_t *)GET_PTR( chdev_dir.nic_tx[channel] );
    346             snprintf( node_name , 16 , "nic_tx_%d" , channel );
    347             devfs_register_chdev( chdev_ptr,
    348                                   node_name,
    349                                   (vfs_inode_t *)GET_PTR( external_inode_xp ),
    350                                   &chdev_inode_xp );
    351         }
    352     }
    353 
    354     // synchronize all clusters
    355     remote_barrier( barrier_xp , nb_clusters );
    356 
    357     return 0;
    358 
    359 }  // end devfs_init()
    360 
    361 
    362 ////////////////////////////////////////////
    363 error_t devfs_ctx_init( vfs_ctx_t * vfs_ctx,
    364                         xptr_t      root_inode_xp )
    365 {
    366     vfs_ctx->type    = FS_TYPE_DEVFS;
    367     vfs_ctx->attr    = 0;                // not READ_ONLY / not SYNC
    368     vfs_ctx->count   = 0;                // unused for DEVFS
    369     vfs_ctx->blksize = 0;                // unused for DEVFS
    370     vfs_ctx->root_xp = root_inode_xp;
    371     vfs_ctx->extend  = NULL;             // unused for DEVFS
    372 
    373     spinlock_init( &vfs_ctx->lock );
    374 
    375     bitmap_init( vfs_ctx->bitmap , CONFIG_VFS_MAX_INODES );
    376 
    377     return 0;
    378 }
    379 
    380 
    381 ////////////////////////////////////////////////////
    382 error_t devfs_inode_create( vfs_inode_t * vfs_inode,
    383                             chdev_t     * chdev )
    384 {
    385     kmem_req_t      req;
    386     devfs_inode_t * devfs_inode;
    387 
    388     // allocate memory for FATFS inode extension
    389         req.type    = KMEM_DEVFS_INODE;
    390         req.size    = sizeof(devfs_inode_t);
    391     req.flags   = AF_KERNEL | AF_ZERO;
    392         devfs_inode = (devfs_inode_t *)kmem_alloc( &req );
    393 
    394     if( devfs_inode == NULL ) return ENOMEM;
    395 
    396     // link DEVFS inode to VFS inode
    397     vfs_inode->extend = devfs_inode;
    398 
    399     // initialise DEVFS inode 
    400     devfs_inode->chdev = chdev;
    401  
    402     return 0;
    403 }
    404 
    405 ///////////////////////////////////////////////////
    406 void devfs_inode_destroy( vfs_inode_t * vfs_inode )
    407 {
    408     kmem_req_t      req;
    409     devfs_inode_t * devfs_inode;
    410 
    411     // get pointer on DEVFS inode
    412     devfs_inode = (devfs_inode_t *)vfs_inode->extend;
    413 
    414     req.type = KMEM_DEVFS_INODE;
    415     req.ptr  = devfs_inode;
    416     kmem_free( &req );
    417 
    418         vfs_inode->extend = NULL;
    419 }
    420 
    421 
    422 /* deprecated [AG]
    423 
    424 error_t devfs_open_file( vfs_file_t * file,
    425                          void       * extend );
    426 {
    427         error_t err;
    428         register struct devfs_context_s *ctx;
    429         register struct devfs_file_s *info;
    430         chdev_t       * chdev;
    431         vfs_inode_t   * inode;
    432         dev_request_t   rq;
    433         kmem_req_t      req;
    434 
    435         inode = file->inode;
    436 
    437         info = file->fr_pv;
    438         ctx  = (struct devfs_context_s *)&inode->i_ctx->ctx_devfs;
    439 
    440         if(!(inode->i_attr & VFS_DIR))
    441         {
    442                 dev = (struct device_s*)inode->i_pv;
    443    
    444                 if(dev->type == DEV_INTERNAL)
    445                         return EPERM;
    446 
    447                 if(dev->type == DEV_BLK)
    448                         VFS_SET(inode->i_attr,VFS_DEV_BLK);
    449                 else
    450                         VFS_SET(inode->i_attr,VFS_DEV_CHR);
    451  
    452                 if(dev->op.dev.open != NULL)
    453                 {
    454                         rq.fremote = file;
    455                         if((err=dev->op.dev.open(dev, &rq)))
    456                                 return err;
    457                 }
    458 
    459                 priv->dev = (void*)dev;
    460 
    461                 return 0;
    462         }
    463 
    464         if(info == NULL)
    465         {
    466                 req.type  = KMEM_DEVFS_FILE;
    467                 req.size  = sizeof(*info);
    468                 req.flags = AF_KERNEL;
    469                 info      = kmem_alloc(&req);
    470         }
    471 
    472         if(info == NULL) return ENOMEM;
    473 
    474         metafs_iter_init(&devfs_db.root, &info->iter);
    475         info->ctx  = ctx;
    476         file->fr_pv = info;
    477  
    478         metafs_print(&devfs_db.root);
    479         return 0;
    480 }
    481 
    482 #define TMP_BUFF_SZ 512
    483 
    484 //FIXME:
    485 //add a "while" loop for the case where the
    486 //buffer TMP_BUFF_SZ is smaller than
    487 //buffer->size
    488 //////////////////////////////
    489 devfs_read( vfs_file_t * file,
    490             char       * buffer )
    491 {
    492         chdev_t       * chdev;
    493         dev_request_t   rq;
    494         uint32_t        count;
    495     uint8_t         buff[TMP_BUFF_SZ];
    496 
    497     // get pointer on chdev
    498         chdev = (chdev_t *)file->extend;
    499 
    500     if( chdev->func == DEV_FUNC_TXT )
    501     {
    502     }
    503     if( chdev->func == DEV_FUNC_IOC )
    504     {
    505     }
    506     else
    507     {
    508         printk("\n[PANIC] in %s : illegal device functionnal type
    509 
    510         rq.dst   = &buff[0];
    511         rq.count = TMP_BUFF_SZ;
    512         rq.flags = 0;
    513         rq.file  = file;
    514 
    515         if((count = dev->op.dev.read(dev, &rq)) < 0)
    516                 return count;
    517 
    518         buffer->scpy_to_buff(buffer, &buff[0], count);
    519         return count;
    520 }
    521 
    522 //FIXME: To improve this an avoid the extra copy,
    523 //we could set along with the buffer(src and dest)
    524 //the functions to manipulate them, such as in
    525 //do_exec.c
    526 ///////////////////////////////
    527 devfs_write( vfs_file_t * file,
    528              char       * buffer )
    529 {
    530         register struct device_s *dev;
    531         uint8_t buff[TMP_BUFF_SZ];
    532         dev_request_t rq;
    533        
    534         dev = (struct device_s*)file->f_private.dev;
    535        
    536         //FIXME avoid the extra copy ?
    537         buffer->scpy_from_buff(buffer, (void*)&buff[0], TMP_BUFF_SZ);
    538         rq.src   = (void*)&buff[0];
    539         rq.count = buffer->size;
    540         rq.flags = 0;
    541         rq.file  = file;
    542  
    543         return dev->op.dev.write(dev, &rq);
    544 }
    545 
    546 VFS_LSEEK_FILE(devfs_lseek)
    547 {
    548         register struct device_s *dev;
    549         dev_request_t rq;
    550 
    551         dev = (struct device_s*)file->fr_inode->i_pv;
    552 
    553         if(dev->op.dev.lseek == NULL)
    554                 return VFS_ENOTUSED;
    555  
    556         rq.fremote = file;
    557         return dev->op.dev.lseek(dev, &rq);
    558 }
    559 
    560 VFS_CLOSE_FILE(devfs_close)
    561 {
    562         register struct device_s *dev;
    563         dev_request_t rq;
    564 
    565         if(file->fr_inode->i_attr & VFS_DIR)
    566                 return 0;
    567 
    568         dev = (struct device_s*)file->fr_inode->i_pv;
    569 
    570         if(dev->op.dev.close == NULL)
    571                 return 0;
    572  
    573         rq.fremote = file;
    574         return dev->op.dev.close(dev, &rq);
    575 }
    576 
    577 VFS_RELEASE_FILE(devfs_release)
    578 
    579         kmem_req_t req;
    580 
    581         if(file->fr_pv == NULL)
    582                 return 0;
    583  
    584         req.type = KMEM_DEVFS_FILE;
    585         req.ptr  = file->fr_pv;
    586         kmem_free(&req);
    587 
    588         file->fr_pv = NULL;
    589         return 0;
    590 }
    591 
    592 VFS_READ_DIR(devfs_readdir)
    593 {
    594         register struct devfs_file_s *info;
    595         register struct metafs_s *current;
    596         register struct device_s *current_dev;
    597  
    598         info = file->fr_pv;
    599  
    600         if(file->fr_pv == NULL)
    601                 return ENOTDIR;
    602 
    603         if((current = metafs_lookup_next(&devfs_db.root, &info->iter)) == NULL)
    604                 return EEODIR;
    605 
    606         current_dev    = metafs_container(current, struct device_s, node);
    607         dirent->u_attr = (current_dev->type == DEV_BLK) ? VFS_DEV_BLK : VFS_DEV_CHR;
    608 
    609         strcpy((char*)dirent->u_name, metafs_get_name(current));
    610 
    611         dirent->u_ino = (uint_t) current_dev->base_paddr;
    612 
    613         return 0;
    614 }
    615 
    616 VFS_MMAP_FILE(devfs_mmap)
    617 {
    618         register struct device_s *dev;
    619         dev_request_t rq;
    620  
    621         dev = (struct device_s*)file->f_private.dev;
    622 
    623         if(dev->op.dev.mmap == NULL)
    624                 return ENODEV;
    625 
    626         rq.flags  = 0;
    627         rq.file   = file;
    628         rq.region = region;
    629 
    630         return dev->op.dev.mmap(dev, &rq);
    631 }
    632 
    633 VFS_MMAP_FILE(devfs_munmap)
    634 {
    635         register struct device_s *dev;
    636         dev_request_t rq;
    637 
    638         dev = (struct device_s*)file->f_private.dev;
    639 
    640         if(dev->op.dev.munmap == NULL)
    641                 return ENODEV;
    642 
    643         rq.flags  = 0;
    644         rq.file   = file;
    645         rq.region = region;
    646 
    647         return dev->op.dev.munmap(dev, &rq);
    648 }
    649 
    650 
    651 */
    652 
    653 
     185    // create a PIC inode in cluster containing PIC chdev
     186    chdev_xp = chdev_dir.pic;
     187    if( chdev_xp != XPTR_NULL )
     188    {
     189        chdev_cxy = GET_CXY( chdev_xp );
     190        if( chdev_cxy == local_cxy )
     191        {
     192            vfs_add_child_in_parent( local_cxy,
     193                                     INODE_TYPE_DEV,
     194                                     FS_TYPE_DEVFS,
     195                                     devfs_external_inode_xp,
     196                                     "pic",
     197                                     GET_PTR( chdev_xp ),
     198                                     &inode_xp );
     199        }
     200    }
     201
     202    // create a TXT inode in each cluster containing a TXT chdev
     203    for( channel = 0 ; channel < CONFIG_MAX_TXT_CHANNELS ; channel++ )
     204    {
     205        chdev_xp = chdev_dir.txt[channel];
     206        if( chdev_xp != XPTR_NULL )
     207        {
     208            chdev_cxy = GET_CXY( chdev_xp );
     209            if( chdev_cxy == local_cxy )
     210            {
     211                snprintf( node_name , 16 , "txt_%d" , channel );
     212                vfs_add_child_in_parent( local_cxy,
     213                                         INODE_TYPE_DEV,
     214                                         FS_TYPE_DEVFS,
     215                                         devfs_external_inode_xp,
     216                                         node_name,
     217                                         GET_PTR( chdev_xp ),
     218                                         &inode_xp );
     219            }
     220        }
     221    }
     222
     223    // create an IOC inode in each cluster containing an IOC chdev
     224    for( channel = 0 ; channel < CONFIG_MAX_IOC_CHANNELS ; channel++ )
     225    {
     226        chdev_xp = chdev_dir.ioc[channel];
     227        if( chdev_xp != XPTR_NULL )
     228        {
     229            chdev_cxy = GET_CXY( chdev_xp );
     230            if( chdev_cxy == local_cxy )
     231            {
     232                snprintf( node_name , 16 , "ioc_%d" , channel );
     233                vfs_add_child_in_parent( local_cxy,
     234                                         INODE_TYPE_DEV,
     235                                         FS_TYPE_DEVFS,
     236                                         devfs_external_inode_xp,
     237                                         node_name,
     238                                         GET_PTR( chdev_xp ),
     239                                         &inode_xp );
     240            }
     241        }
     242    }
     243
     244    // create a FBF inode in each cluster containing a FBF chdev
     245    for( channel = 0 ; channel < CONFIG_MAX_IOC_CHANNELS ; channel++ )
     246    {
     247        chdev_xp = chdev_dir.fbf[channel];
     248        if( chdev_xp != XPTR_NULL )
     249        {
     250            chdev_cxy = GET_CXY( chdev_xp );
     251            if( chdev_cxy == local_cxy )
     252            {
     253                snprintf( node_name , 16 , "fbf_%d" , channel );
     254                vfs_add_child_in_parent( local_cxy,
     255                                         INODE_TYPE_DEV,
     256                                         FS_TYPE_DEVFS,
     257                                         devfs_external_inode_xp,
     258                                         node_name,
     259                                         GET_PTR( chdev_xp ),
     260                                         &inode_xp );
     261            }
     262        }
     263    }
     264
     265    // create a NIC_RX inode in each cluster containing a NIC_RX chdev
     266    for( channel = 0 ; channel < CONFIG_MAX_NIC_CHANNELS ; channel++ )
     267    {
     268        chdev_xp = chdev_dir.nic_rx[channel];
     269        if( chdev_xp != XPTR_NULL )
     270        {
     271            chdev_cxy = GET_CXY( chdev_xp );
     272            if( chdev_cxy == local_cxy )
     273            {
     274                snprintf( node_name , 16 , "nic_rx_%d" , channel );
     275                vfs_add_child_in_parent( local_cxy,
     276                                         INODE_TYPE_DEV,
     277                                         FS_TYPE_DEVFS,
     278                                         devfs_external_inode_xp,
     279                                         node_name,
     280                                         GET_PTR( chdev_xp ),
     281                                         &inode_xp );
     282            }
     283        }
     284    }
     285
     286    // create a NIC_TX inode in each cluster containing a NIC_TX chdev
     287    for( channel = 0 ; channel < CONFIG_MAX_NIC_CHANNELS ; channel++ )
     288    {
     289        chdev_xp = chdev_dir.nic_tx[channel];
     290        if( chdev_xp != XPTR_NULL )
     291        {
     292            chdev_cxy = GET_CXY( chdev_xp );
     293            if( chdev_cxy == local_cxy )
     294            {
     295                snprintf( node_name , 16 , "nic_tx_%d" , channel );
     296                vfs_add_child_in_parent( local_cxy,
     297                                         INODE_TYPE_DEV,
     298                                         FS_TYPE_DEVFS,
     299                                         devfs_external_inode_xp,
     300                                         node_name,
     301                                         GET_PTR( chdev_xp ),
     302                                         &inode_xp );
     303            }
     304        }
     305    }
     306}  // end devfs_local_init()
     307
  • trunk/kernel/vfs/devfs.h

    r23 r188  
    2626#define _DEVFS_H_
    2727
    28 ///////////////////////////////////////////////////////////////////////////////////////////
    29 // The DEVFS File System contains inodes associated to all chdev descriptors availables
    30 // in the target architecture.  It is a three levels tree structure:
    31 // - The "dev" directory inode is stored in cluster_0. It is the root of the devfs
    32 //   file system. The parent inode is the "/" global root.
     28//////////////////////////////////////////////////////////////////////////////////////////
     29// 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 :
     31// - The "dev" directory inode is stored in cluster_IO. It is the root of the DEVFS
     32//   file system. The parent inode is the "/" VFS root.
    3333// - There is one "internal_cxy" directory inode per cluster, that is the parent of
    34 //   the local children inodes associated to the local chdev descriptors.
    35 //   The parent inode and dentry are stored in cluster_0.
     34//   the local children inodes associated to the local, internal chdev descriptors.
     35//   The parent dentry is stored in cluster_IO.
    3636// - The I/O cluster contains one "external" directory inode, that is the parent of
    37 //   the remote children inodes associated to the remote external descriptors.
    38 //   The parent inode and dentry are stored in cluster_0.
     37//   the remote children inodes associated to the remote external chdev descriptors.
     38//   The parent dentry is stored in cluster_IO.
    3939//
    40 // The DEVFS File system does not require a context extension, but requires an inode
    41 // extension to store the pointer on the associated chdev descriptor.
    42 ///////////////////////////////////////////////////////////////////////////////////////////
     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.
     45//////////////////////////////////////////////////////////////////////////////////////////
    4346
    44 /**************  Forward declarations     ************************************************/
     47/*****************************************************************************************
     48 * This structure defines the DEVFS context extension.
     49 ****************************************************************************************/
    4550
    46 struct chdev_s;
    47 
    48 /******************************************************************************************
    49  * This structure defines the DEVFS inode descriptor extension.
    50  *****************************************************************************************/
    51 
    52 typedef struct devfs_inode_ext_s
     51typedef struct devfs_ctx_s
    5352{
    54     struct chdev_s * chdev;       /* extended pointer on associated chdev                */
     53    xptr_t   root_inode_xp;              /*! extended pointer on DEVFS root inode       */
     54    xptr_t   external_inode_xp;          /*! extended pointer on DEVFS external inode   */
    5555}
    56 devfs_inode_t;
     56devfs_ctx_t;
    5757
    5858
    59 
    60 
    61 
    62 //////////////////////////////////////////////////////////////////////////////////////////
    63 //                 These functions are called by the VFS.
    64 //////////////////////////////////////////////////////////////////////////////////////////
    65 
    66 /******************************************************************************************
    67  * This function  does not exist for the DEVFS file system, as this File System
    68  * cannot be mounted as the root FS.
    69  *****************************************************************************************/
    70 xptr_t devfs_init();
    71 
    72 
    73 /******************************************************************************************
    74  * This function mount the DEVFS file system on the root FS.
    75  * It is executed cooperatively during kernel init by all CP0s in all clusters,
    76  * to create the DEVFS 3-levels tree structure.
    77  * This is a four phases procedure, and it uses the global barrier to synchronize
    78  * the cooperating kernel instances when required.
    79  * - phase 1 : In all clusters, it creates the local extension of the DEVFS context,
    80  *    and initialises it.
    81  * - phase 2 : In cluster_0 only, it creates the dentry and the associated inode for
    82  *   the DEVFS root directory.
    83  * - phase 3 : In all cluster(x,y), it creates the dentry and the associated inode for
    84  *   the "internal_cxy" directory. It also creates the dentry and associated inode
    85  *   for all local internal chdevs.
    86  * - phase 4 : In cluster_io only, it creates the dentry and the associated inode
    87  *   for the "external" directory. It also creates the dentry and associated inode
    88  *   for all external chdevs.
    89  ******************************************************************************************
    90  * @ parent_inode_xp   : extended pointer on the parent inode in root FS.
    91  * @ devfs_root_name   : DEVFS root directory name.
    92  *****************************************************************************************/
    93 error_t devfs_mount( xptr_t   parent_inode_xp,
    94                      char   * devfs_root_name );
     59/*****************************************************************************************
     60 * This fuction allocates memory from local cluster for a DEVFS context descriptor.
     61 *****************************************************************************************
     62 * @ return a pointer on the created context / return NULL if failure.
     63 ****************************************************************************************/
     64devfs_ctx_t * devfs_ctx_alloc();
    9565
    9666/*****************************************************************************************
    97  * This function initializes all fields of the VFS context.
    98  * No extra memory is allocated for a DEVFS context.
     67 * This function initialises the DEVFS context from arguments values, and link it
     68 * to the relevant VFS context in the local cluster.
    9969 *****************************************************************************************
    100  * @ vfs_ctx        : local pointer on VFS context for FATFS.
    101  * @ root_inode_xp  : extended pointer on the VFS root inode.
     70 * @ devfs_ctx               : local pointer on DEVFS context.
     71 * @ devfs_root_inode_xp     : [out] extended pointer on created <dev> inode.
     72 * @ devfs_external_inode_xp : [out] extended pointer on created <external> inode.
    10273 ****************************************************************************************/
    103 error_t devfs_ctx_init( struct vfs_ctx_s * vfs_ctx,
    104                         xptr_t             root_inode_xp );
     74void devfs_ctx_init( devfs_ctx_t * devfs_ctx,
     75                     xptr_t        devfs_root_inode_xp,
     76                     xptr_t        devfs_external_inode_xp );
    10577
    10678/*****************************************************************************************
    107  * This function does not exist for a DEVFS context, as there is no DEVFS context.
     79 * This function releases memory dynamically allocated for the DEVFS context.
     80 *****************************************************************************************
     81 * @ devfs_ctx   : local pointer on DEVFS context.
    10882 ****************************************************************************************/
    109 error_t devfs_ctx_destroy();
     83void devfs_ctx_destroy( devfs_ctx_t * devfs_ctx );
    11084
    11185/*****************************************************************************************
    112  * This function allocates memory for a DEVFS inode, initialise it,
    113  * and link it to the VFS inode.
     86 * This function start to create the DEVFS subtree.
     87 * This function should be called once in the cluster containing the VFS parent inode.
     88 * More precisely, it creates in cluster IO the "dev" and "external" DEVFS directories.
     89 * For each one, it creates the inode and link the associated dentry to parent inode.
     90 * The DEVFS root inode is linked to the VFS parent inode identified by <parent_inode_xp>.
    11491 *****************************************************************************************
    115  * @ inode          : local pointer on the VFS inode.
    116  * @ chdev          : local pointer on the chdev to be inserted in DEVFS.
     92 * @ parent_inode_xp         : extended pointer on the parent VFS inode.
     93 * @ devfs_root_inode_xp     : [out] extended pointer on created <dev> inode.
     94 * @ devfs_external_inode_xp : [out] extended pointer on created <external> inode.
    11795 ****************************************************************************************/
    118 error_t devfs_inode_create( struct vfs_inode_s * inode,
    119                             struct chdev_s     * chdev );
     96void devfs_global_init( xptr_t   parent_inode_xp,
     97                        xptr_t * devfs_root_inode_xp,
     98                        xptr_t * devfs_external_inode_xp );
    12099
    121100/*****************************************************************************************
    122  * This function releases memory allocated for a DEVFS inode.
     101 * This function completes the initialisation of the DEVFS subtree.
     102 * It should be called once in each cluster.
     103 * 1. In each cluster (i), it creates the "internal" directory,
     104 *    linked to the DEVFS "dev" parent directory.
     105 * 2. In each cluster (i), it creates - for each external chdev in cluster (i) -
     106 *    a pseudo-file, linked to the DEVFS "external" parent directory.
     107 * 3. In each cluster (i), it creates - for each internal chdev in cluster (i) -
     108 *    a pseudo-file, linked to the DEVFS "internal" parent directory.
    123109 *****************************************************************************************
    124  * @ inode   : local pointer on vfs_inode.
     110 * @ devfs_root_inode_xp     : extended pointer on DEVFS root inode.
     111 * @ devfs_external_inode_xp : extended pointer on DEVFS external inode.
    125112 ****************************************************************************************/
    126 void devfs_inode_destroy( struct vfs_inode_s * inode );
    127 
    128 /*****************************************************************************************
    129  * This function does not exist for the DEVFS File System.
    130  ****************************************************************************************/
    131 error_t devfs_write_page( struct page_s * page );
    132 
    133 /*****************************************************************************************
    134  * This function does not exist for the DEVFS File System.
    135  ****************************************************************************************/
    136 error_t devfs_read_page( struct page_s * page );
    137 
    138 
    139 
     113void devfs_local_init( xptr_t devfs_root_inode_xp,
     114                       xptr_t devfs_external_inode_xp );
     115                       
    140116#endif  /* _DEVFS_H_ */
  • trunk/kernel/vfs/fatfs.c

    r101 r188  
    4646 
    4747//////////////////////////////////////////////////////////////////////////////////////////
    48 // FATFS specific functions : these functions cannot be called by the VFS
    49 //////////////////////////////////////////////////////////////////////////////////////////
    50 
    51 //////////////////////////////////////////////////////////
    52 inline uint32_t fatfs_lba_from_cluster( fatfs_ctx_t * ctx,
    53                                         uint32_t      cluster )
     48//              FATFS private functions
     49//////////////////////////////////////////////////////////////////////////////////////////
     50
     51//////////////////////////////////////////////////////////////////////////////////////////
     52// This function returns the LBA of the first sector of a FAT cluster.
     53// This function can be called by any thread running in any cluster.
     54//////////////////////////////////////////////////////////////////////////////////////////
     55// @ ctx          :     pointer on FATFS context.
     56// @ cluster  : cluster index in FATFS.
     57// @ return the lba value.
     58//////////////////////////////////////////////////////////////////////////////////////////
     59static inline uint32_t fatfs_lba_from_cluster( fatfs_ctx_t * ctx,
     60                                               uint32_t      cluster )
    5461{
    5562    return (ctx->cluster_begin_lba + ((cluster - 2) << 3));
     
    200207
    201208///////////////////////////////////////////////////////////////////////////////////////
    202 //          The following functions are called by the VFS.
     209// Generic API : the following functions are called by the kernel
     210//               and must be defined by all supported file systems.
    203211///////////////////////////////////////////////////////////////////////////////////////
    204212
    205 
    206 ///////////////////
    207 xptr_t fatfs_init()
     213///////////////////////////////
     214fatfs_ctx_t * fatfs_ctx_alloc()
    208215{
    209216    kmem_req_t    req;
    210     fatfs_ctx_t * fatfs_ctx;       // local pointer on FATFS context
    211     vfs_ctx_t   * vfs_ctx;         // local pointer on VFS context
    212     xptr_t        root_inode_xp;   // extended pointer on root inode
    213     error_t       error;
    214 
    215     // get local pointer on VFS context for FATFS
    216     vfs_ctx = &fs_context[FS_TYPE_FATFS];
    217 
    218     // get number of kernel instances and extended pointer on global barrier
    219     cluster_t * cluster     = LOCAL_CLUSTER;
    220     uint32_t    nb_clusters = cluster->x_size * cluster->y_size;
    221     xptr_t      barrier_xp  = XPTR( cluster->io_cxy , &global_barrier );
    222 
    223     ///// step 1 : all clusters allocate memory for FATFS context
    224 
    225     // allocate memory for FATFS context extension
    226217        req.type    = KMEM_FATFS_CTX;
    227218        req.size    = sizeof(fatfs_ctx_t);
    228219    req.flags   = AF_KERNEL | AF_ZERO;
    229         fatfs_ctx   = (fatfs_ctx_t *)kmem_alloc( &req );
    230 
    231     if( fatfs_ctx == NULL )
    232     {
    233         printk("\n[PANIC] in %s : no memory for FATFS context\n", __FUNCTION__ );
    234         hal_core_sleep();
    235     }
    236    
    237     ///// step 2 : only cluster_0 access device and creates root inode
    238 
    239     if( local_cxy == 0 )
    240     {
    241         // create VFS root inode
    242         error = vfs_inode_create( XPTR_NULL,        // no parent dentry
    243                                   FS_TYPE_FATFS,
    244                                   INODE_TYPE_DIR,
    245                                   0,                // attr
    246                                   0,                // rights
    247                                   0,                // uid
    248                                   0,                // gid
    249                                   &root_inode_xp );
    250 
    251         assert( (error == 0 ) , __FUNCTION__ , "cannot create VFS root inode" );
    252 
    253         // initialize VFS context / access device to initialize FATFS context
    254         error = fatfs_ctx_init( vfs_ctx,
    255                                 fatfs_ctx,
    256                                 root_inode_xp );
    257 
    258         // create FATFS root inode
    259         error = fatfs_inode_create( GET_PTR( root_inode_xp ) ,
    260                                     fatfs_ctx->root_dir_cluster );
    261 
    262         if( error )
    263         {
    264             printk("\n[PANIC] in %s : cannot create FATFS root inode\n", __FUNCTION__ );
    265             hal_core_sleep();
    266         }
    267 
    268     }
    269 
    270     //////////////// synchronize all clusters
    271     remote_barrier( barrier_xp , nb_clusters );
    272 
    273     ///// step 3 : all others clusters initialize both context and extension
    274 
    275     if( local_cxy != 0 )
    276     {
    277         // copy VFS context from remote cluster_0 to local cluster
    278         hal_remote_memcpy( XPTR( local_cxy , vfs_ctx ),
    279                            XPTR( 0 , vfs_ctx ),
    280                            sizeof(vfs_ctx_t) );
    281 
    282         // copy FATFS context from remote cluster_0 to local cluster
    283         hal_remote_memcpy( XPTR( local_cxy , fatfs_ctx ),
    284                            XPTR( 0 , vfs_ctx->extend ) ,
    285                            sizeof(fatfs_ctx_t) );
    286 
    287         // update extend field in local copy of VFS context
    288         vfs_ctx->extend = fatfs_ctx;
    289     }
    290 
    291     return root_inode_xp;
    292 
    293 }  // end fatfs_init()
     220
     221        return (fatfs_ctx_t *)kmem_alloc( &req );
     222}
    294223
    295224//////////////////////////////////////////////
    296 error_t fatfs_ctx_init( vfs_ctx_t   * vfs_ctx,
    297                         fatfs_ctx_t * fatfs_ctx,
    298                         xptr_t        root_inode_xp )
    299 {
    300     error_t     error;
    301     uint8_t   * buffer;
    302     kmem_req_t  req;
     225void fatfs_ctx_init( fatfs_ctx_t * fatfs_ctx )
     226{
     227    error_t       error;
     228    kmem_req_t    req;
     229    uint8_t     * buffer;
     230
     231    fatfs_dmsg("\n[INFO] %s : enters at cycle %d\n",
     232               __FUNCTION__ , hal_get_cycles() );
     233
     234    // allocate memory for FATFS context
     235        req.type    = KMEM_FATFS_CTX;
     236        req.size    = sizeof(fatfs_ctx_t);
     237    req.flags   = AF_KERNEL | AF_ZERO;
     238
     239        fatfs_ctx = (fatfs_ctx_t *)kmem_alloc( &req );
     240
     241    nolock_assert( (fatfs_ctx != NULL) , __FUNCTION__ ,
     242                   "cannot allocate memory for FATFS context\n" );
    303243
    304244    // allocate a 512 bytes buffer to store the boot record
     
    306246    req.flags   = AF_KERNEL | AF_ZERO;
    307247        buffer      = (uint8_t *)kmem_alloc( &req );
     248
     249    nolock_assert( (buffer != NULL) , __FUNCTION__ ,
     250                   "cannot allocate memory for 512 bytes buffer\n" );
    308251     
    309     fatfs_dmsg("\n[INFO] %s : enters with buffer = %x\n",
    310                __FUNCTION__ , (intptr_t)buffer );
    311 
    312252    // load the boot record from device
    313253    // using a synchronous access to IOC device 
    314254    error = dev_ioc_sync_read( buffer , 0 , 1 );
    315255
    316     assert( (error == 0) , __FUNCTION__ , "cannot access boot record" );
     256    nolock_assert( (error == 0) , __FUNCTION__ ,
     257                   "cannot access boot record\n" );
    317258
    318259#if CONFIG_FATFS_DEBUG
     
    336277    uint32_t sector_size = get_record_from_buffer( BPB_BYTSPERSEC , buffer , 1 );
    337278
    338     assert( (sector_size == 512) , __FUNCTION__ , "sector size must be 512 bytes" );
     279    nolock_assert( (sector_size == 512) , __FUNCTION__ ,
     280                   "sector size must be 512 bytes\n" );
    339281
    340282    // check cluster size from boot record
    341283    uint32_t nb_sectors = get_record_from_buffer( BPB_SECPERCLUS , buffer , 1 );
    342284
    343     assert( (nb_sectors == 8) , __FUNCTION__ , "cluster size must be 8 sectors" );
     285    nolock_assert( (nb_sectors == 8) , __FUNCTION__ ,
     286                   "cluster size must be 8 sectors\n" );
    344287
    345288    // check number of FAT copies from boot record
    346289    uint32_t nb_fats = get_record_from_buffer( BPB_NUMFATS , buffer , 1 );
    347290
    348     assert( (nb_fats == 1) , __FUNCTION__ , "number of FAT copies must be 1" );
     291    nolock_assert( (nb_fats == 1) , __FUNCTION__ ,
     292                   "number of FAT copies must be 1\n" );
    349293
    350294    // get & check number of sectors in FAT from boot record
    351295    uint32_t fat_sectors = get_record_from_buffer( BPB_FAT32_FATSZ32 , buffer , 1 );
    352296
    353     assert( ((fat_sectors & 0xF) == 0) , __FUNCTION__ , "FAT not multiple of 16 sectors");
     297    nolock_assert( ((fat_sectors & 0xF) == 0) , __FUNCTION__ ,
     298                   "FAT not multiple of 16 sectors\n");
    354299
    355300    // get and check root cluster from boot record
    356301    uint32_t root_cluster = get_record_from_buffer( BPB_FAT32_ROOTCLUS , buffer , 1 );
    357302
    358     assert( (root_cluster == 2) , __FUNCTION__ , "Root cluster index must be  2");
     303    nolock_assert( (root_cluster == 2) , __FUNCTION__ ,
     304                   "root cluster index must be  2\n");
    359305
    360306    // get FAT lba from boot record
     
    375321    fatfs_ctx->fat_sectors_count     = fat_sectors;
    376322    fatfs_ctx->bytes_per_sector      = sector_size;
    377     fatfs_ctx->bytes_per_cluster     = sector_size * nb_sectors;
     323    fatfs_ctx->sectors_per_cluster   = nb_sectors;
    378324    fatfs_ctx->cluster_begin_lba     = fat_lba + fat_sectors;
    379325    fatfs_ctx->root_dir_cluster      = 2;
     
    396342               fatfs_ctx->fat_mapper_xp );
    397343
    398     // initialize the VFS context
    399     vfs_ctx->type    = FS_TYPE_FATFS;
    400     vfs_ctx->attr    = 0;                    // not READ_ONLY / not SYNC
    401     vfs_ctx->count   = fat_sectors << 10;    // total number of sectors in data region
    402     vfs_ctx->blksize = 512;                  // number of bytes per sector
    403     vfs_ctx->root_xp = root_inode_xp;
    404     vfs_ctx->extend  = fatfs_ctx;
    405 
    406     spinlock_init( &vfs_ctx->lock );
    407 
    408     bitmap_init( vfs_ctx->bitmap , CONFIG_VFS_MAX_INODES );
    409 
    410     return 0;
    411 
    412344}  // end fatfs_ctx_init()
    413  
    414 
    415 
    416 ////////////////////////////////////////////////////
    417 void fatfs_ctx_destroy( struct vfs_ctx_s * vfs_ctx )
     345
     346/////////////////////////////////////////////////
     347void fatfs_ctx_destroy( fatfs_ctx_t * fatfs_ctx )
    418348{
    419349    kmem_req_t    req;
    420     fatfs_ctx_t * fatfs_ctx;
    421 
    422     // get pointer on FATFS context extension
    423     fatfs_ctx = (fatfs_ctx_t *)vfs_ctx->extend;
    424 
    425     req.type = KMEM_FATFS_INODE;
     350    req.type = KMEM_FATFS_CTX;
    426351    req.ptr  = fatfs_ctx;
    427352    kmem_free( &req );
    428353}
    429 
    430 
    431 ////////////////////////////////////////////////////
    432 error_t fatfs_inode_create( vfs_inode_t * vfs_inode,
    433                             uint32_t      first_cluster )
    434 {
    435     kmem_req_t      req;
    436     fatfs_inode_t * fatfs_inode;
    437 
    438     // allocate memory for FATFS inode extension
    439         req.type    = KMEM_FATFS_INODE;
    440         req.size    = sizeof(fatfs_inode_t);
    441     req.flags   = AF_KERNEL | AF_ZERO;
    442         fatfs_inode = (fatfs_inode_t *)kmem_alloc( &req );
    443 
    444     if( fatfs_inode == NULL ) return ENOMEM;
    445 
    446     // link FATFS inode to VFS inode
    447     vfs_inode->extend = fatfs_inode;
    448 
    449     // initialise FATFS inode
    450     fatfs_inode->first_cluster = first_cluster;
    451  
    452     return 0;
    453 }
    454 
    455 ///////////////////////////////////////////////////
    456 void fatfs_inode_destroy( vfs_inode_t * vfs_inode )
    457 {
    458     kmem_req_t      req;
    459     fatfs_inode_t * fatfs_inode;
    460 
    461     // get pointer on FATFS inode
    462     fatfs_inode = (fatfs_inode_t *)vfs_inode->extend;
    463 
    464     req.type = KMEM_FATFS_INODE;
    465     req.ptr  = fatfs_inode;
    466     kmem_free( &req );
    467 
    468         vfs_inode->extend = NULL;
    469 }
    470 
    471354
    472355////////////////////////////////////////////////
     
    484367    vfs_inode_t * vfs_inode = mapper->inode;
    485368
    486     // get FATFS inode pointer for VFS inode
    487     fatfs_inode_t * fatfs_inode = (fatfs_inode_t *)vfs_inode->extend;
    488 
    489     // get first cluster index from FATFS inode
    490     uint32_t  first_cluster = fatfs_inode->first_cluster;
    491 
    492     // get FATFS context pointer from FATFS inode
    493     fatfs_ctx_t * fatfs_ctx = (fatfs_ctx_t *)vfs_inode->ctx->extend;
     369    // get first cluster index from VFS inode
     370    uint32_t  first_cluster = (uint32_t)(intptr_t)vfs_inode->extend;
     371
     372    // get FATFS context pointer from VFS context
     373    fatfs_ctx_t * fatfs_ctx = (fatfs_ctx_t *)fs_context[FS_TYPE_FATFS].extend;
    494374
    495375    // get number of sectors
  • trunk/kernel/vfs/fatfs.h

    r23 r188  
    160160typedef struct fatfs_ctx_s
    161161{
     162    uint32_t          fat_sectors_count;     /*! number of sectors in FAT region        */
     163    uint32_t          bytes_per_sector;      /*! number of bytes per sector             */
     164    uint32_t          sectors_per_cluster;   /*! number of sectors per cluster          */
    162165    uint32_t          fat_begin_lba;         /*! lba of FAT region                      */
    163     uint32_t          fat_sectors_count;     /*! number of sectors in FAT region        */
    164     uint32_t          bytes_per_sector;      /*!                                        */
    165     uint32_t          bytes_per_cluster;     /*!                                        */
    166166    uint32_t          cluster_begin_lba;     /*! lba of data region                     */
    167     uint32_t          sectors_per_cluster;   /*! cluster index for root directory       */
    168     uint32_t          root_dir_cluster;      /*!                                        */
     167    uint32_t          root_dir_cluster;      /*! cluster index for the root directory   */
    169168    uint32_t          last_allocated_sector; /*! TODO ???                               */
    170169    uint32_t          last_allocated_index;  /*! TODO ???                               */
     
    173172fatfs_ctx_t;
    174173
    175 /*****************************************************************************************
    176  * This structure defines the FATFS specific inode (extension to VFS inode).
    177  ****************************************************************************************/
    178 
    179 typedef struct fatfs_inode_s
    180 {
    181         uint32_t          first_cluster;         /*! first cluster for this file/dir        */
    182 }
    183 fatfs_inode_t;
    184 
    185 
    186 
    187 
    188174//////////////////////////////////////////////////////////////////////////////////////////
    189 // These functions are specific to the FATFS, and cannot be called by the VFS.
     175// Generic API: These functions are called by the kernel,
     176//              and must be implemented by all File Systems.
    190177//////////////////////////////////////////////////////////////////////////////////////////
    191178
    192 /*****************************************************************************************
    193  * This function returns the LBA of the first sector of a FAT cluster.
    194  * This function can be called by any thread running in any cluster.
    195  *****************************************************************************************
    196  * @ ctx          :     pointer on FATFS context.
    197  * @ cluster  : cluster index in FATFS.
    198  * @ return the lba value.
    199  ****************************************************************************************/
    200 inline uint32_t fatfs_lba_from_cluster( fatfs_ctx_t * ctx,
    201                                         uint32_t      cluster );
     179/******************************************************************************************
     180 * This fuction allocates memory from local cluster for a FATFS context descriptor.
     181 ******************************************************************************************
     182 * @ return a pointer on the created context / return NULL if failure.
     183 *****************************************************************************************/
     184fatfs_ctx_t * fatfs_ctx_alloc();
     185
     186/*****************************************************************************************
     187 * This function access the external boot device, and initialises it
     188 * from informations contained in the boot record.
     189 *****************************************************************************************
     190 * @ vfs_ctx   : local pointer on VFS context for FATFS.
     191 ****************************************************************************************/
     192void fatfs_ctx_init( fatfs_ctx_t * fatfs_ctx );
     193
     194/*****************************************************************************************
     195 * This function releases memory dynamically allocated for the FATFS context extension.
     196 *****************************************************************************************
     197 * @ vfs_ctx   : local pointer on VFS context.
     198 ****************************************************************************************/
     199void fatfs_ctx_destroy( fatfs_ctx_t * fatfs_ctx );
     200
     201/*****************************************************************************************
     202 * This function moves a page from the mapper to the FATFS file system on device.
     203 * It must be called by a thread running in cluster containing the mapper.
     204 * The pointer on the mapper and the page index in file are registered
     205 * in the page descriptor.
     206 *****************************************************************************************
     207 * @ page    : local pointer on page descriptor.
     208 * @ return 0 if success / return EIO if error.
     209 ****************************************************************************************/
     210error_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 ****************************************************************************************/
     221error_t fatfs_read_page( struct page_s * page );
    202222
    203223/*****************************************************************************************
     
    214234 * automatically updates the FAT mapper from informations stored on device in case of miss.
    215235 *****************************************************************************************
    216  * @ mapper      : local pointer on the FAT mapper.
    217  * @ first       : index of the first FATFS cluster allocated to the file.
    218  * @ page    : index of searched page in the file.
    219  * @ cluster : [out] pointer on buffer for the found FATFS cluster index.
     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.
    220240 * @ return 0 if success / return EIO if FAT mapper miss cannot be solved.
    221241 ****************************************************************************************/
     
    223243                           uint32_t          first_cluster,
    224244                           uint32_t          searched_page,
    225                            uint32_t        * cluster );
    226 
    227 
    228 
    229 
    230 //////////////////////////////////////////////////////////////////////////////////////////
    231 // These functions are called by the VFS, and must be implemented by all File Systems.
    232 //////////////////////////////////////////////////////////////////////////////////////////
    233 
    234 /******************************************************************************************
    235  * This function initializes the FATFS file system as the root FS.
    236  * It is executed cooperatively during kernel init by all CP0s in all clusters.
    237  * The initilisation is made in three phases, separated by synchronisation barrier:     
    238  * - phase 1 : all CP0s in all clusters allocate memory for the local copy of
    239  *   the FATFS context.
    240  * - phase 2 : cluster_0 only creates the root inode descriptor, access the external
    241  *   device to get information stored on the boot record, and initialises both
    242  *   the VFS context, and the FATFS context.
    243  * - phase 3 : all other clusters initialize their local VFS context and FATFS context
    244  *   from values contained in cluster_0, using hal_remote_memcpy().
    245  ******************************************************************************************
    246  * @ return an extended pointer on the created root inode / return XPTR_NULL if failure.
    247  *****************************************************************************************/
    248 xptr_t fatfs_init();
    249 
    250 /******************************************************************************************
    251  * This function mount the FATFS on the root FS.
    252  * TODO not implemented [AG]
    253  ******************************************************************************************
    254  * @ parent_inode_xp : extended pointer on the parent inode.
    255  *****************************************************************************************/
    256 error_t fatfs_mount( xptr_t parent_inode_xp );
    257 
    258 
    259 /*****************************************************************************************
    260  * This function  initializes both the VFS context and the FATFS context.
    261  * Both the VFS context and the FATFS context must have been previously allocated.
    262  * It access the device to read the boot record, and is supposed to be called only
    263  * in cluster_0 (in other clusters these contexts are replicated from values
    264  * contained in cluster_0).
    265  *****************************************************************************************
    266  * @ vfs_ctx        : local pointer on VFS context for FATFS.
    267  * @ fatfs_ctx      : local pointer on specific FATFS context.
    268  * @ root_inode_xp  : extended pointer on VFS root inode.
    269  ****************************************************************************************/
    270 error_t fatfs_ctx_init( struct vfs_ctx_s   * vfs_ctx,
    271                         struct fatfs_ctx_s * fatfs_ctx,
    272                         xptr_t               root_inode_xp );
    273 
    274 /*****************************************************************************************
    275  * This function releases memory dynamically allocated for the FATFS context extension.
    276  *****************************************************************************************
    277  * @ vfs_ctx   : local pointer on VFS context.
    278  ****************************************************************************************/
    279 void fatfs_ctx_destroy( struct vfs_ctx_s * vfs_ctx );
    280 
    281 
    282 
    283 /*****************************************************************************************
    284  * This function allocates memory for a FATFS inode, initializes it,
    285  * and link it to the VFS inode.
    286  *****************************************************************************************
    287  * @ inode         : local pointer on the VFS inode.
    288  * @ first_cluster : first cluster index in the FAT32.
    289  * @ return 0 if success / return ENOMEM if error.
    290  ****************************************************************************************/
    291 error_t fatfs_inode_create( struct vfs_inode_s * inode,
    292                             uint32_t             first_cluster);
    293 
    294 /*****************************************************************************************
    295  * This function releases memory allocated for a FATFS inode.
    296  *****************************************************************************************
    297  * @ inode   : local pointer on vfs_inode.
    298  ****************************************************************************************/
    299 void fatfs_inode_destroy( struct vfs_inode_s * inode );
    300 
    301 
    302 
    303 /*****************************************************************************************
    304  * This function moves a page from the mapper to the FATFS file system on device.
    305  * It must be called by a thread running in cluster containing the mapper.
    306  * The pointer on the mapper and the page index in file are registered
    307  * in the page descriptor.
    308  *****************************************************************************************
    309  * @ page    : local pointer on page descriptor.
    310  * @ return 0 if success / return EIO if error.
    311  ****************************************************************************************/
    312 error_t fatfs_write_page( struct page_s * page );
    313 
    314 /*****************************************************************************************
    315  * This function moves a page from the FATFS file system on device to the mapper.
    316  * It must be called by a thread running in cluster containing the mapper.
    317  * The pointer on the mapper and the page index in file are registered
    318  * in the page descriptor.
    319  *****************************************************************************************
    320  * @ page    : local pointer on page descriptor.
    321  * @ return 0 if success / return EIO if error.
    322  ****************************************************************************************/
    323 error_t fatfs_read_page( struct page_s * page );
    324 
    325 
    326 
     245                           uint32_t *        cluster );
    327246
    328247#endif  /* _FATFS_H_ */
  • trunk/kernel/vfs/ramfs.c

    r23 r188  
    3232
    3333
    34 
    35 
    36 
    37 ///////////////////////////////////////////////////////////////////////////////////////
    38 //             The following functions are called by the VFS.
    39 ///////////////////////////////////////////////////////////////////////////////////////
    40 
    4134//////////////////////////////////////////////
    4235error_t ramfs_mount( xptr_t   parent_inode_xp,
    4336                     char   * ramfs_root_name )
    4437{
    45     xptr_t        root_inode_xp;   // unused                     
     38    xptr_t    root_inode_xp;   // unused                     
    4639 
     40    cxy_t     cxy = vfs_cluster_random_select();
     41
    4742    // create VFS dentry and VFS inode for RAMFS root directory
    48     return  vfs_add_child_in_parent( INODE_TYPE_DIR,
     43    return  vfs_add_child_in_parent( cxy,
     44                                     INODE_TYPE_DIR,
    4945                                     FS_TYPE_RAMFS,
    5046                                     parent_inode_xp,
    5147                                     ramfs_root_name,
     48                                     NULL,
    5249                                     &root_inode_xp );
    5350}
    5451
    55 
    56 ////////////////////////////////////////////
    57 error_t ramfs_ctx_init( vfs_ctx_t * vfs_ctx,
    58                         xptr_t      root_inode_xp )
    59 
    60 {
    61     vfs_ctx->type    = FS_TYPE_RAMFS;
    62     vfs_ctx->attr    = 0;                // not READ_ONLY / not SYNC
    63     vfs_ctx->count   = 0;                // unused for RAMFS
    64     vfs_ctx->blksize = 512;              // unused for RAMFS
    65     vfs_ctx->root_xp = root_inode_xp;
    66     vfs_ctx->extend  = NULL;             // unused for DEVFS
    67 
    68     spinlock_init( &vfs_ctx->lock );
    69 
    70     bitmap_init( vfs_ctx->bitmap , CONFIG_VFS_MAX_INODES );
    71 
    72     return 0;
    73 }
    74 
  • trunk/kernel/vfs/ramfs.h

    r23 r188  
    2727
    2828///////////////////////////////////////////////////////////////////////////////////////////
    29 // The RAMFS File System Rdoes not uses any external device to store data.
     29// The RAMFS File System does not uses any external device to store data.
    3030// It stores the dynamically created files and directories in the VFS mappers.
    3131// The ramfs_read_page() and ramfs_write_page() functions should never be used.
    32 // The RAMFS cannot be used as the root FS.
     32// The RAMFS cannot be used as the root File System.
     33//
    3334// There is no RAMFS context extension, and no RAMFS inode extension.
    3435///////////////////////////////////////////////////////////////////////////////////////////
    3536
    3637
    37 /****  Forward declarations  ****/
    38 
    39 
    40 //////////////////////////////////////////////////////////////////////////////////////////
    41 // These functions are called by the VFS, and must be implemented by all FS.
    42 //////////////////////////////////////////////////////////////////////////////////////////
    43 
    44 /******************************************************************************************
    45  * This function does not exist, as the RAMFS cannot be the root FS.
    46  *****************************************************************************************/
    47 xptr_t ramfs_init();
    4838
    4939/******************************************************************************************
     
    5242 * and create a new VFS inode in another cluster.
    5343 ******************************************************************************************
    54  * @ parent_inode_xp : extended pointer on the parent inode.
     44 * @ parent_inode_xp : extended pointer on the parent inode in VFS.
    5545 * @ ramfs_root_name : RAMFS root directory name.
    5646 *****************************************************************************************/
     
    5848                     char   * ramfs_root_name );
    5949
    60 /*****************************************************************************************
    61  * This function initializes all fields of the VFS context.
    62  * No extra memory is allocated for a RAMFS context.
    63  ****************************************************************************************/
    64 error_t ramfs_ctx_init( struct vfs_ctx_s * vfs_ctx,
    65                         xptr_t             root_inode_xp );
    66 
    67 /*****************************************************************************************
    68  * This function does not exist for a RAMFS context, as there is no RAMFS context.
    69  ****************************************************************************************/
    70 error_t ramfs_ctx_destroy();
    71 
    72 /*****************************************************************************************
    73  * This function does not exist, as the RAMFS does not use a RAMFS inode extension.
    74  ****************************************************************************************/
    75 error_t ramfs_inode_create( struct vfs_inode_s * inode );
    76 
    77 /*****************************************************************************************
    78  * This function does not exist, as the RAMFS does not use a RAMFS inode extension.
    79  ****************************************************************************************/
    80 void ramfs_inode_destroy( struct vfs_inode_s * inode );
    81 
    82 /*****************************************************************************************
    83  * This function does nothing for the RAMFS File System.
    84  ****************************************************************************************/
    85 error_t ramfs_write_page( struct page_s * page );
    86 
    87 /*****************************************************************************************
    88  * This function does not exist for the RAMFS File System.
    89  ****************************************************************************************/
    90 error_t ramfs_read_page( struct page_s * page );
    91 
    92 
    9350#endif  /* _RAMFS_H_ */
  • trunk/kernel/vfs/vfs.c

    r124 r188  
    5252//////////////////////////////////////////////////////////////////////////////////////////
    5353
    54 extern vfs_ctx_t   fs_context[FS_TYPES_NR];    // allocate in kernel_init.c
     54extern vfs_ctx_t   fs_context[FS_TYPES_NR];    // allocated in kernel_init.c
     55
    5556 
    5657//////////////////////////////////////////////////////////////////////////////////////////
    5758//           Context related functions
    5859//////////////////////////////////////////////////////////////////////////////////////////
     60
     61////////////////////////////////////////
     62void vfs_ctx_init( vfs_fs_type_t   type,
     63                   uint32_t        attr,
     64                       uint32_t        total_clusters,
     65                       uint32_t        cluster_size,
     66                       xptr_t          vfs_root_xp,
     67                   void          * extend )
     68{
     69    vfs_ctx_t * vfs_ctx = &fs_context[type];
     70
     71    vfs_ctx->type           = type;
     72    vfs_ctx->attr           = attr;
     73    vfs_ctx->total_clusters = total_clusters;
     74    vfs_ctx->cluster_size   = cluster_size;
     75    vfs_ctx->vfs_root_xp    = vfs_root_xp;
     76    vfs_ctx->extend         = extend;
     77
     78    spinlock_init( &vfs_ctx->lock );
     79
     80    bitmap_init( vfs_ctx->bitmap , BITMAP_SIZE(CONFIG_VFS_MAX_INODES) );
     81}
    5982
    6083////////////////////////////////////////////
     
    101124//////////////////////////////////////////////////////////////////////////////////////////
    102125
     126char * vfs_inode_type_str( uint32_t type )
     127{
     128    if     ( type == INODE_TYPE_FILE ) return "FILE";
     129    else if( type == INODE_TYPE_DIR  ) return "DIR ";
     130    else if( type == INODE_TYPE_FIFO ) return "FIFO";
     131    else if( type == INODE_TYPE_PIPE ) return "PIPE";
     132    else if( type == INODE_TYPE_SOCK ) return "SOCK";
     133    else if( type == INODE_TYPE_DEV  ) return "DEV ";
     134    else if( type == INODE_TYPE_SYML ) return "SYML";
     135    else                               return "undefined";
     136}
     137
    103138//////////////////////////////////////////////////////
    104 
    105139error_t vfs_inode_create( xptr_t            dentry_xp,
    106140                          vfs_fs_type_t     fs_type,
    107141                          vfs_inode_type_t  inode_type,
     142                          void            * extend,
    108143                          uint32_t          attr,
    109144                          uint32_t          rights,
     
    175210    inode->ctx        = ctx;
    176211    inode->mapper     = NULL; 
     212    inode->extend     = extend;
    177213
    178214    // initialise threads waiting queue
     
    307343        kmem_req_t       req;        // request to kernel memory allocator
    308344
    309     // check type and get pointer on context
     345    // get pointer on context
    310346    if     ( fs_type == FS_TYPE_FATFS ) ctx = &fs_context[FS_TYPE_FATFS];
    311347    else if( fs_type == FS_TYPE_RAMFS ) ctx = &fs_context[FS_TYPE_RAMFS];
     
    349385    xhtab_insert( XPTR( local_cxy , &parent->children ),
    350386                  name,
    351                   XPTR( local_cxy , &dentry->xlist ) );
     387                  XPTR( local_cxy , &dentry->list ) );
    352388
    353389    // return extended pointer on dentry
     
    372408        kmem_free( &req );
    373409}
     410
    374411
    375412
     
    797834
    798835
    799 /////////////////////////////////////////////////////////////////////////////////////////r
     836//////////////////////////////////////////////////////////////////////////////////////////
    800837//            Inode Tree functions
    801838//////////////////////////////////////////////////////////////////////////////////////////
     839
     840/////////////////////////////////
     841cxy_t vfs_cluster_random_select()
     842{
     843    uint32_t  x_size    = LOCAL_CLUSTER->x_size;
     844    uint32_t  y_size    = LOCAL_CLUSTER->y_size;
     845    uint32_t  y_width   = LOCAL_CLUSTER->y_width;
     846    uint32_t  index     = ( hal_get_cycles() + hal_get_gid() ) % (x_size * y_size);
     847    uint32_t  x         = index / y_size;   
     848    uint32_t  y         = index % y_size;
     849
     850    return (x<<y_width) + y;
     851}
     852
     853
     854//////////////////////////////////////////////////////////////////////////
     855// This static function is called by the vfs_display() function.
     856//////////////////////////////////////////////////////////////////////////
     857static void vfs_recursive_display( xptr_t   inode_xp,
     858                                   xptr_t   name_xp,
     859                                   uint32_t indent )
     860{
     861    cxy_t              inode_cxy;
     862    vfs_inode_t      * inode_ptr;
     863    vfs_inode_type_t   inode_type;
     864    xptr_t             inode_children_xp;    // extended pointer on children xhtab
     865
     866    xptr_t             dentry_xp;
     867    cxy_t              dentry_cxy;
     868    vfs_dentry_t     * dentry_ptr;
     869
     870    char               name[CONFIG_VFS_MAX_NAME_LENGTH];
     871
     872    xptr_t             child_inode_xp;
     873    xptr_t             dentry_name_xp;
     874
     875    char *             indent_str[] = { "",                                  // level 0
     876                                        "  ",                                // level 1
     877                                        "    ",                              // level 2
     878                                        "      ",                            // level 3
     879                                        "        ",                          // level 4
     880                                        "          ",                        // level 5
     881                                        "            ",                      // level 6
     882                                        "              ",                    // level 7
     883                                        "                ",                  // level 8
     884                                        "                  ",                // level 9
     885                                        "                    ",              // level 10
     886                                        "                      ",            // level 11
     887                                        "                        ",          // level 12
     888                                        "                          ",        // level 13
     889                                        "                            ",      // level 14
     890                                        "                              " };  // level 15
     891
     892    assert( (inode_xp != XPTR_NULL) , __FUNCTION__ , "inode_xp cannot be NULL\n" );
     893    assert( (name_xp  != XPTR_NULL) , __FUNCTION__ , "name_xp cannot be NULL\n" );
     894    assert( (indent < 16)           , __FUNCTION__ , "depth cannot be larger than 15\n" );
     895   
     896    // get inode cluster and local pointer
     897    inode_cxy = GET_CXY( inode_xp );
     898    inode_ptr = (vfs_inode_t *)GET_PTR( inode_xp );
     899
     900    // get inode type
     901    inode_type = hal_remote_lw( XPTR( inode_cxy , &inode_ptr->type ) );
     902
     903    // make a local copy of node name
     904    hal_remote_strcpy( XPTR( local_cxy , name ) , name_xp );
     905
     906    // display inode
     907    printk(" %s %s : %s\n", indent_str[indent], vfs_inode_type_str( inode_type ), name );
     908
     909    // scan directory entries 
     910    if( inode_type == INODE_TYPE_DIR )
     911    {
     912        // get extended pointer on directory entries xhtab
     913        inode_children_xp = hal_remote_lwd( XPTR( inode_cxy , &inode_ptr->children ) );
     914
     915        // get xhtab lock
     916        xhtab_read_lock( inode_children_xp );
     917
     918        // get first dentry from xhtab
     919        dentry_xp = xhtab_get_first( inode_children_xp );
     920
     921        while( dentry_xp != XPTR_NULL )
     922        {
     923            // get dentry cluster and local pointer
     924            dentry_cxy = GET_CXY( dentry_xp );
     925            dentry_ptr = (vfs_dentry_t *)GET_PTR( dentry_xp );
     926
     927            // get extended pointer on child inode
     928            child_inode_xp = hal_remote_lwd( XPTR( dentry_cxy , &dentry_ptr->child_xp ) );
     929
     930            // get extended pointer on dentry name
     931            dentry_name_xp = XPTR( dentry_cxy , &dentry_ptr->name );
     932
     933            // recursive call on child inode
     934            vfs_recursive_display( child_inode_xp , dentry_name_xp , indent+1 );
     935
     936            // get next dentry
     937            dentry_xp = xhtab_get_next( inode_children_xp );
     938        }
     939
     940        // release xhtab lock
     941        xhtab_read_unlock( inode_children_xp );
     942    }
     943}  // end vfs_recursive_display()
     944
     945///////////////////////////////////
     946void vfs_display( xptr_t inode_xp )
     947{
     948    xptr_t         name_xp;      // extended pointer on string containing the inode name
     949    xptr_t         dentry_xp;
     950    cxy_t          dentry_cxy;
     951    vfs_dentry_t * dentry_ptr;
     952
     953printk("\n@@@ %s enters\n", __FUNCTION__ );
     954
     955    // get target inode cluster and local pointer
     956    cxy_t         inode_cxy = GET_CXY( inode_xp );
     957    vfs_inode_t * inode_ptr = (vfs_inode_t *)GET_PTR( inode_xp );
     958
     959    // get extended pointer on associated dentry
     960    dentry_xp = hal_remote_lwd( XPTR( inode_cxy , &inode_ptr->parent_xp ) );
     961
     962    // check if target inode is the File System root
     963    if( dentry_xp == XPTR_NULL )
     964    {
     965        // build extended pointer on root name
     966        name_xp = XPTR( local_cxy , "/" );
     967    }
     968    else
     969    {
     970        // get dentry cluster and local pointer
     971        dentry_cxy = GET_CXY( dentry_xp );
     972        dentry_ptr = (vfs_dentry_t *)GET_PTR( dentry_xp );
     973
     974        // get extended pointer on dentry name
     975        name_xp = XPTR( dentry_cxy , &dentry_ptr->name );
     976    }
     977
     978    // print header
     979    printk("\n*** Current VFS content ***\n");
     980
     981    // call recursive function
     982    vfs_recursive_display( inode_xp , name_xp , 0 );
     983
     984}  // end vfs_diplay()
    802985
    803986//////////////////////////////////////////////////////////////////////////////////////////
     
    9131096    return 0;
    9141097}
    915 
     1098   
    9161099//////////////////////////////////////////////
    9171100error_t vfs_lookup( xptr_t             cwd_xp,
     
    9931176            else                                             inode_type = INODE_TYPE_FILE;
    9941177
    995             // insert a child dentry/inode in parent inode
    996             error = vfs_add_child_in_parent( inode_type,
     1178            // select a cluster for child inode
     1179            cxy_t child_cxy = vfs_cluster_random_select();
     1180                     
     1181            // insert a new child dentry/inode in parent inode
     1182            error = vfs_add_child_in_parent( child_cxy,
     1183                                             inode_type,
    9971184                                             fs_type,
    9981185                                             parent_xp,
     1186                                             NULL,           // fs_type_specific inode extend
    9991187                                             name,
    10001188                                             &child_xp );
     
    10021190            if( error )
    10031191            {
    1004                 printk("\n[ERROR] in %s : inode %s not found in path %s\n",
     1192                printk("\n[ERROR] in %s : node %s not found in path %s\n",
    10051193                       __FUNCTION__ , name , pathname );
    10061194                return ENOENT;
     
    10241212        // }
    10251213
    1026 printk("\n@@@ bloup 0 : parent lock owner = %l / child lock owner = %l\n",
    1027        vfs_inode_owner( parent_xp ) , vfs_inode_owner( child_xp ) );
     1214        // TODO TODO TODO access device and load inode mapper if required...
    10281215
    10291216        // take lock on child inode if not last
    10301217        if( last == false ) vfs_inode_lock( child_xp );
    10311218
    1032 printk("\n@@@ bloup 1\n");
    1033 
    10341219        // release lock on parent inode
    10351220        vfs_inode_unlock( parent_xp );
    1036 
    1037 printk("\n@@@ bloup 2\n");
    10381221
    10391222        // update loop variables
     
    10601243
    10611244}  // end vfs_lookup()
    1062 
    10631245
    10641246////////////////////////////////////////////
     
    11311313}  // end vfs_get_path()
    11321314
    1133 ///////////////////////////////////////////////////////////////
    1134 error_t vfs_add_child_in_parent( vfs_inode_type_t   inode_type,
     1315     
     1316//////////////////////////////////////////////////////////////
     1317error_t vfs_add_child_in_parent( cxy_t              child_cxy,
     1318                                 vfs_inode_type_t   inode_type,
    11351319                                 vfs_fs_type_t      fs_type,
    11361320                                 xptr_t             parent_xp,
    11371321                                 char             * name,
     1322                                 void             * extend,
    11381323                                 xptr_t           * child_xp )
    11391324{
     
    11741359        printk("\n[ERROR] in %s : cannot create dentry in cluster %x\n",
    11751360               __FUNCTION__ , parent_cxy );
    1176 
    11771361        return error;
    11781362    }
    11791363
    1180     // select a target cluster for child inode
    1181     uint32_t  x_size    = LOCAL_CLUSTER->x_size;
    1182     uint32_t  y_size    = LOCAL_CLUSTER->y_size;
    1183     uint32_t  y_width   = LOCAL_CLUSTER->y_width;
    1184     uint32_t  index     = ( hal_get_cycles() + hal_get_gid() ) % (x_size * y_size);
    1185     uint32_t  x         = index / y_size;   
    1186     uint32_t  y         = index % y_size;
    1187     cxy_t     child_cxy = (x<<y_width) + y;
    1188                                      
    11891364    // create child inode TODO : define attr / mode / uid / gid
    11901365    uint32_t attr = 0;
     
    11981373                                  fs_type,
    11991374                                  inode_type,
     1375                                  extend,
    12001376                                  attr,
    12011377                                  mode,
     
    12101386                                     fs_type,
    12111387                                     inode_type,
     1388                                     extend,
    12121389                                     attr,
    12131390                                     mode,
  • trunk/kernel/vfs/vfs.h

    r101 r188  
    132132        vfs_fs_type_t  type;                     /*! File System type                        */
    133133        uint32_t           attr;                     /*! global attributes for all files in FS   */
    134         uint32_t       count;                    /*! total number of clusters on device      */
    135         uint32_t       blksize;                  /*! device cluster size (bytes)             */
    136         xptr_t         root_xp;                  /*! extended pointer on root inode          */
     134        uint32_t       total_clusters;           /*! total number of clusters on device      */
     135        uint32_t       cluster_size;             /*! cluster size on device (bytes)          */
     136        xptr_t         vfs_root_xp;              /*! extended pointer on VFS root inode      */
    137137    spinlock_t     lock;                     /*! lock protecting inum allocator          */
    138138    uint32_t       bitmap[BITMAP_SIZE(CONFIG_VFS_MAX_INODES)];  /* inum allocator        */
     
    160160typedef enum   
    161161{
    162     INODE_TYPE_FILE    =     0x001,      /*! file                                        */
    163     INODE_TYPE_DIR     =     0x002,      /*! directory                                   */
    164     INODE_TYPE_FIFO    =     0x004,      /*! POSIX named pipe                            */
    165     INODE_TYPE_PIPE    =     0x008,      /*! POSIX anonymous pipe                        */
    166     INODE_TYPE_SOCKET  =     0x010,      /*! POSIX socket                                */
    167     INODE_TYPE_DEV     =     0x020,      /*! character peripheral channel                */
    168     INODE_TYPE_SYML    =     0x080,      /*! symbolic link                               */
     162    INODE_TYPE_FILE  =     0x001,      /*! file                                          */
     163    INODE_TYPE_DIR   =     0x002,      /*! directory                                     */
     164    INODE_TYPE_FIFO  =     0x004,      /*! POSIX named pipe                              */
     165    INODE_TYPE_PIPE  =     0x008,      /*! POSIX anonymous pipe                          */
     166    INODE_TYPE_SOCK  =     0x010,      /*! POSIX socket                                  */
     167    INODE_TYPE_DEV   =     0x020,      /*! device channel                                */
     168    INODE_TYPE_SYML  =     0x080,      /*! symbolic link                                 */
    169169}
    170170vfs_inode_type_t;
     
    182182typedef struct vfs_inode_s
    183183{
    184         struct vfs_ctx_s      * ctx;         /*! local pointer on FS context                 */
    185     uint32_t                gc;          /*! generation counter                          */
    186         uint32_t                inum;        /*! inode identifier (unique in file system)    */
    187         uint32_t                attr;        /*! inode attributes (see above)                */
    188         vfs_inode_type_t        type;        /*! inode type (see above)                      */
    189         uint32_t                size;        /*! number of bytes                             */
    190         uint32_t                links;       /*! number of alias dentry                      */
    191         uid_t                   uid;         /*! user owner identifier                       */
    192         gid_t                   gid;         /*! group owner identifier                      */
    193     uint32_t                rights;      /*! access rights                               */
    194         uint32_t                    refcount;    /*! reference counter (all pointers)            */
    195         xptr_t                  parent_xp;   /*! extended pointer on parent dentry           */
    196         xhtab_t                 children;    /*! embedded xhtab of vfs_dentry_t              */
    197         remote_rwlock_t         data_lock;   /*! protect read/write to data and to size      */
    198         remote_spinlock_t       main_lock;   /*! protect inode tree traversal and modifs     */
    199         list_entry_t            list;        /*! member of set of inodes in same cluster     */
    200         xlist_entry_t           wait_root;   /*! root of threads waiting on this inode       */
    201         struct vfs_inode_op_s * op;          /*! TODO ???                                    */
    202         struct mapper_s       * mapper;      /*! associated file cache                       */
    203         void                  * extend;      /*! FS specific inode extension                 */
     184        struct vfs_ctx_s * ctx;              /*! local pointer on FS context                 */
     185    uint32_t           gc;               /*! generation counter                          */
     186        uint32_t           inum;             /*! inode identifier (unique in file system)    */
     187        uint32_t           attr;             /*! inode attributes (see above)                */
     188        vfs_inode_type_t   type;             /*! inode type (see above)                      */
     189        uint32_t           size;             /*! number of bytes                             */
     190        uint32_t           links;            /*! number of alias dentry                      */
     191        uid_t              uid;              /*! user owner identifier                       */
     192        gid_t              gid;              /*! group owner identifier                      */
     193    uint32_t           rights;           /*! access rights                               */
     194        uint32_t               refcount;         /*! reference counter (all pointers)            */
     195        xptr_t             parent_xp;        /*! extended pointer on parent dentry           */
     196        xhtab_t            children;         /*! embedded xhtab of children dentries         */
     197        remote_rwlock_t    data_lock;        /*! protect read/write to data and to size      */
     198        remote_spinlock_t  main_lock;        /*! protect inode tree traversal and modifs     */
     199        list_entry_t       list;             /*! member of set of inodes in same cluster     */
     200        xlist_entry_t      wait_root;        /*! root of threads waiting on this inode       */
     201        struct mapper_s  * mapper;           /*! associated file cache                       */
     202        void             * extend;           /*! fs_type_specific inode extension            */
    204203}
    205204vfs_inode_t;
     
    214213typedef struct vfs_dentry_s
    215214{
    216     struct vfs_ctx_s       * ctx;        /*! local pointer on FS context                 */
    217         char                     name[CONFIG_VFS_MAX_NAME_LENGTH];
    218         uint32_t                 length;     /*! name length (bytes)                         */
    219         uint32_t                 refcount;   /*! reference counter (all pointers)            */
    220     struct vfs_inode_s     * parent;     /*! local pointer on parent inode               */
    221     xptr_t                   child_xp;   /*! extended pointer on child inode             */
    222     xlist_entry_t            xlist;      /*! member of xlist of dentries with same key   */
    223         struct vfs_dentry_op_s * op;         /*! TODO                                        */
    224         void                   * extend;     /*! FS specific extension                       */
     215    struct vfs_ctx_s   * ctx;            /*! local pointer on FS context                 */
     216        char                 name[CONFIG_VFS_MAX_NAME_LENGTH];
     217        uint32_t             length;         /*! name length (bytes)                         */
     218        uint32_t             refcount;       /*! reference counter (all pointers)            */
     219    struct vfs_inode_s * parent;         /*! local pointer on parent inode               */
     220    xptr_t               child_xp;       /*! extended pointer on child inode             */
     221    xlist_entry_t        list;           /*! member of list of dentries with same key    */
     222        void               * extend;         /*! FS specific extension                       */
    225223}
    226224vfs_dentry_t;
     
    231229 * the inode, when a thread makes an open() or opendir() system call.
    232230 * It cannot exist a file structure without an inode structure.
    233  * Aa the fd_array (containing extended pointers on the open file descriptors)
     231 * Aa the fd_array (containing extended pointers on the open file descriptors)* is replicated in all process descriptors, we need a references counter.
    234232 * is replicated in all process descriptors, we need a references counter.
    235233 *****************************************************************************************/
     
    313311
    314312/*****************************************************************************************/
    315 /******************* FS Context related functions ****************************************/
    316 /*****************************************************************************************/
     313/******************* VFS Context related functions ****************************************/
     314/*****************************************************************************************/
     315
     316/******************************************************************************************
     317 * This function initialise a (statically allocated) VFS context in local cluster.
     318 ******************************************************************************************
     319 * @ fs_type        : file system type.
     320 * @ attr           : global attributes (for all files in FS.
     321 * @ total_clusters : total number of clusters on device.
     322 * @ cluster_size   : cluster size on device (bytes).
     323 * @ vfs_root_xp    : extended pointer on VFS root inode.
     324 * @ extend         : fs_type_specific extension.
     325 *****************************************************************************************/
     326void vfs_ctx_init( vfs_fs_type_t   type,
     327                   uint32_t        attr,
     328                       uint32_t        total_clusters,
     329                       uint32_t        cluster_size,
     330                       xptr_t          vfs_root_xp,
     331                   void          * extend );
    317332
    318333/******************************************************************************************
     
    355370 * @ fs_type    : file system type.
    356371 * @ inode_type : inode type.
     372 * @ extend     : local pointer on vs_type_specific extension.
    357373 * @ attr       : inode attributes.
    358374 * @ rights     : inode access rights.
     
    365381                          vfs_fs_type_t     fs_type,
    366382                          vfs_inode_type_t  inode_type,
     383                          void            * extend,
    367384                          uint32_t          attr,
    368385                          uint32_t          rights,
     
    550567/******************* Inode-Tree related functions ****************************************/
    551568/*****************************************************************************************/
     569
     570/******************************************************************************************
     571 * This function randomly selects a cluster for a new inode.
     572 ******************************************************************************************
     573 * @ returns the selected cluster identifier.
     574 *****************************************************************************************/
     575cxy_t vfs_cluster_random_select();
    552576
    553577/******************************************************************************************
     
    594618 * uses the rpc_dentry_create_client() and rpc_inode_create client() if required.
    595619 * - The dentry is created in the cluster containing the existing <parent_xp> inode.
    596  * - the child inode and its associated mapper are created in a randomly selected cluster.
     620 * - the inode and its associated mapper are created in cluster identified by <child_cxy>.
    597621 * - The new dentry name is defined by the <name> argument.
    598622 * - The new inode and the parent inode can have different FS types.
    599623 ******************************************************************************************
     624 * @ child_cxy  : target cluster for child inode.
    600625 * @ inode_type : new inode type
    601626 * @ fs_type    : new inode FS type.
    602627 * @ parent_xp  : extended pointer on parent inode.
    603628 * @ name       : new directory entry name.
     629 * @ extend     : fs_type_specific inode extension.
    604630 * @ child_xp   : [out] buffer for extended pointer on child inode.
    605631 * @ return 0 if success / ENOENT if entry not found in parent directory
    606632 *****************************************************************************************/
    607 error_t vfs_add_child_in_parent( vfs_inode_type_t   inode_type,
     633error_t vfs_add_child_in_parent( cxy_t              child_cxy,
     634                                 vfs_inode_type_t   inode_type,
    608635                                 vfs_fs_type_t      fs_type,
    609636                                 xptr_t             parent_xp,
    610637                                 char             * name,   
     638                                 void             * extend,
    611639                                 xptr_t           * child_xp );
    612640
     
    620648error_t vfs_remove_child_from_parent( xptr_t child_xp );
    621649
     650/******************************************************************************************
     651 * This recursive function diplays a complete inode/dentry sub-tree.
     652 * Any inode can be selected as the sub-tree root.
     653 * TODO this function is not ptotected against a concurrent node removal...
     654 ******************************************************************************************
     655 * @ inode_xp   : extended pointer on sub-tree root inode.
     656 *****************************************************************************************/
     657void vfs_display( xptr_t   inode_xp );
    622658
    623659
Note: See TracChangeset for help on using the changeset viewer.