Changeset 188 for trunk/kernel/vfs
- Timestamp:
- Jul 12, 2017, 8:12:41 PM (7 years ago)
- Location:
- trunk/kernel/vfs
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/vfs/devfs.c
r50 r188 26 26 #include <hal_special.h> 27 27 #include <printk.h> 28 #include <chdev.h> 29 #include <cluster.h> 30 #include <vfs.h> 28 31 #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>35 32 #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 38 extern vfs_ctx_t fs_context[]; // allocated in kernel_init.c 39 extern chdev_directory_t chdev_dir; // allocated in kernel_init.c 40 41 /////////////////////////////// 42 devfs_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 ///////////////////////////////////////////// 54 void 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 ///////////////////////////////////////////////// 65 void 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 /////////////////////////////////////////////////// 75 void devfs_global_init( xptr_t parent_inode_xp, 76 xptr_t * devfs_root_inode_xp, 77 xptr_t * devfs_external_inode_xp ) 136 78 { 137 79 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 ////////////////////////////////////////////////// 105 void devfs_local_init( xptr_t devfs_root_inode_xp, 106 xptr_t devfs_external_inode_xp ) 107 { 201 108 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; 202 113 uint32_t channel; 203 114 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" 243 116 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 ); 248 124 249 125 // 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 } 255 137 256 138 // 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 } 262 150 263 151 // 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 } 290 184 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 26 26 #define _DEVFS_H_ 27 27 28 ////////////////////////////////////////////////////////////////////////////////////////// /29 // The DEVFS File System contains inodes a ssociated to all chdev descriptors availables30 // 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 devfs32 // file system. The parent inode is the "/" globalroot.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. 33 33 // - 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. 36 36 // - 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. 39 39 // 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 ////////////////////////////////////////////////////////////////////////////////////////// 43 46 44 /************** Forward declarations ************************************************/ 47 /***************************************************************************************** 48 * This structure defines the DEVFS context extension. 49 ****************************************************************************************/ 45 50 46 struct chdev_s; 47 48 /****************************************************************************************** 49 * This structure defines the DEVFS inode descriptor extension. 50 *****************************************************************************************/ 51 52 typedef struct devfs_inode_ext_s 51 typedef struct devfs_ctx_s 53 52 { 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 */ 55 55 } 56 devfs_ inode_t;56 devfs_ctx_t; 57 57 58 58 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 ****************************************************************************************/ 64 devfs_ctx_t * devfs_ctx_alloc(); 95 65 96 66 /***************************************************************************************** 97 * This function initiali zes 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. 99 69 ***************************************************************************************** 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. 102 73 ****************************************************************************************/ 103 error_t devfs_ctx_init( struct vfs_ctx_s * vfs_ctx, 104 xptr_t root_inode_xp ); 74 void devfs_ctx_init( devfs_ctx_t * devfs_ctx, 75 xptr_t devfs_root_inode_xp, 76 xptr_t devfs_external_inode_xp ); 105 77 106 78 /***************************************************************************************** 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. 108 82 ****************************************************************************************/ 109 error_t devfs_ctx_destroy();83 void devfs_ctx_destroy( devfs_ctx_t * devfs_ctx ); 110 84 111 85 /***************************************************************************************** 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>. 114 91 ***************************************************************************************** 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. 117 95 ****************************************************************************************/ 118 error_t devfs_inode_create( struct vfs_inode_s * inode, 119 struct chdev_s * chdev ); 96 void devfs_global_init( xptr_t parent_inode_xp, 97 xptr_t * devfs_root_inode_xp, 98 xptr_t * devfs_external_inode_xp ); 120 99 121 100 /***************************************************************************************** 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. 123 109 ***************************************************************************************** 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. 125 112 ****************************************************************************************/ 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 113 void devfs_local_init( xptr_t devfs_root_inode_xp, 114 xptr_t devfs_external_inode_xp ); 115 140 116 #endif /* _DEVFS_H_ */ -
trunk/kernel/vfs/fatfs.c
r101 r188 46 46 47 47 ////////////////////////////////////////////////////////////////////////////////////////// 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 ////////////////////////////////////////////////////////////////////////////////////////// 59 static inline uint32_t fatfs_lba_from_cluster( fatfs_ctx_t * ctx, 60 uint32_t cluster ) 54 61 { 55 62 return (ctx->cluster_begin_lba + ((cluster - 2) << 3)); … … 200 207 201 208 /////////////////////////////////////////////////////////////////////////////////////// 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. 203 211 /////////////////////////////////////////////////////////////////////////////////////// 204 212 205 206 /////////////////// 207 xptr_t fatfs_init() 213 /////////////////////////////// 214 fatfs_ctx_t * fatfs_ctx_alloc() 208 215 { 209 216 kmem_req_t req; 210 fatfs_ctx_t * fatfs_ctx; // local pointer on FATFS context211 vfs_ctx_t * vfs_ctx; // local pointer on VFS context212 xptr_t root_inode_xp; // extended pointer on root inode213 error_t error;214 215 // get local pointer on VFS context for FATFS216 vfs_ctx = &fs_context[FS_TYPE_FATFS];217 218 // get number of kernel instances and extended pointer on global barrier219 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 context224 225 // allocate memory for FATFS context extension226 217 req.type = KMEM_FATFS_CTX; 227 218 req.size = sizeof(fatfs_ctx_t); 228 219 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 } 294 223 295 224 ////////////////////////////////////////////// 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; 225 void 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" ); 303 243 304 244 // allocate a 512 bytes buffer to store the boot record … … 306 246 req.flags = AF_KERNEL | AF_ZERO; 307 247 buffer = (uint8_t *)kmem_alloc( &req ); 248 249 nolock_assert( (buffer != NULL) , __FUNCTION__ , 250 "cannot allocate memory for 512 bytes buffer\n" ); 308 251 309 fatfs_dmsg("\n[INFO] %s : enters with buffer = %x\n",310 __FUNCTION__ , (intptr_t)buffer );311 312 252 // load the boot record from device 313 253 // using a synchronous access to IOC device 314 254 error = dev_ioc_sync_read( buffer , 0 , 1 ); 315 255 316 assert( (error == 0) , __FUNCTION__ , "cannot access boot record" ); 256 nolock_assert( (error == 0) , __FUNCTION__ , 257 "cannot access boot record\n" ); 317 258 318 259 #if CONFIG_FATFS_DEBUG … … 336 277 uint32_t sector_size = get_record_from_buffer( BPB_BYTSPERSEC , buffer , 1 ); 337 278 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" ); 339 281 340 282 // check cluster size from boot record 341 283 uint32_t nb_sectors = get_record_from_buffer( BPB_SECPERCLUS , buffer , 1 ); 342 284 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" ); 344 287 345 288 // check number of FAT copies from boot record 346 289 uint32_t nb_fats = get_record_from_buffer( BPB_NUMFATS , buffer , 1 ); 347 290 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" ); 349 293 350 294 // get & check number of sectors in FAT from boot record 351 295 uint32_t fat_sectors = get_record_from_buffer( BPB_FAT32_FATSZ32 , buffer , 1 ); 352 296 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"); 354 299 355 300 // get and check root cluster from boot record 356 301 uint32_t root_cluster = get_record_from_buffer( BPB_FAT32_ROOTCLUS , buffer , 1 ); 357 302 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"); 359 305 360 306 // get FAT lba from boot record … … 375 321 fatfs_ctx->fat_sectors_count = fat_sectors; 376 322 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; 378 324 fatfs_ctx->cluster_begin_lba = fat_lba + fat_sectors; 379 325 fatfs_ctx->root_dir_cluster = 2; … … 396 342 fatfs_ctx->fat_mapper_xp ); 397 343 398 // initialize the VFS context399 vfs_ctx->type = FS_TYPE_FATFS;400 vfs_ctx->attr = 0; // not READ_ONLY / not SYNC401 vfs_ctx->count = fat_sectors << 10; // total number of sectors in data region402 vfs_ctx->blksize = 512; // number of bytes per sector403 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 412 344 } // end fatfs_ctx_init() 413 414 415 416 //////////////////////////////////////////////////// 417 void fatfs_ctx_destroy( struct vfs_ctx_s * vfs_ctx ) 345 346 ///////////////////////////////////////////////// 347 void fatfs_ctx_destroy( fatfs_ctx_t * fatfs_ctx ) 418 348 { 419 349 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; 426 351 req.ptr = fatfs_ctx; 427 352 kmem_free( &req ); 428 353 } 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 extension439 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 inode447 vfs_inode->extend = fatfs_inode;448 449 // initialise FATFS inode450 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 inode462 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 471 354 472 355 //////////////////////////////////////////////// … … 484 367 vfs_inode_t * vfs_inode = mapper->inode; 485 368 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; 494 374 495 375 // get number of sectors -
trunk/kernel/vfs/fatfs.h
r23 r188 160 160 typedef struct fatfs_ctx_s 161 161 { 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 */ 162 165 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; /*! */166 166 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 */ 169 168 uint32_t last_allocated_sector; /*! TODO ??? */ 170 169 uint32_t last_allocated_index; /*! TODO ??? */ … … 173 172 fatfs_ctx_t; 174 173 175 /*****************************************************************************************176 * This structure defines the FATFS specific inode (extension to VFS inode).177 ****************************************************************************************/178 179 typedef struct fatfs_inode_s180 {181 uint32_t first_cluster; /*! first cluster for this file/dir */182 }183 fatfs_inode_t;184 185 186 187 188 174 ////////////////////////////////////////////////////////////////////////////////////////// 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. 190 177 ////////////////////////////////////////////////////////////////////////////////////////// 191 178 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 *****************************************************************************************/ 184 fatfs_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 ****************************************************************************************/ 192 void 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 ****************************************************************************************/ 199 void 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 ****************************************************************************************/ 210 error_t fatfs_write_page( struct page_s * page ); 211 212 /***************************************************************************************** 213 * This function moves a page from the FATFS file system on device to the mapper. 214 * It must be called by a thread running in cluster containing the mapper. 215 * The pointer on the mapper and the page index in file are registered 216 * in the page descriptor. 217 ***************************************************************************************** 218 * @ page : local pointer on page descriptor. 219 * @ return 0 if success / return EIO if error. 220 ****************************************************************************************/ 221 error_t fatfs_read_page( struct page_s * page ); 202 222 203 223 /***************************************************************************************** … … 214 234 * automatically updates the FAT mapper from informations stored on device in case of miss. 215 235 ***************************************************************************************** 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. 220 240 * @ return 0 if success / return EIO if FAT mapper miss cannot be solved. 221 241 ****************************************************************************************/ … … 223 243 uint32_t first_cluster, 224 244 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 ); 327 246 328 247 #endif /* _FATFS_H_ */ -
trunk/kernel/vfs/ramfs.c
r23 r188 32 32 33 33 34 35 36 37 ///////////////////////////////////////////////////////////////////////////////////////38 // The following functions are called by the VFS.39 ///////////////////////////////////////////////////////////////////////////////////////40 41 34 ////////////////////////////////////////////// 42 35 error_t ramfs_mount( xptr_t parent_inode_xp, 43 36 char * ramfs_root_name ) 44 37 { 45 xptr_t 38 xptr_t root_inode_xp; // unused 46 39 40 cxy_t cxy = vfs_cluster_random_select(); 41 47 42 // 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, 49 45 FS_TYPE_RAMFS, 50 46 parent_inode_xp, 51 47 ramfs_root_name, 48 NULL, 52 49 &root_inode_xp ); 53 50 } 54 51 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 SYNC63 vfs_ctx->count = 0; // unused for RAMFS64 vfs_ctx->blksize = 512; // unused for RAMFS65 vfs_ctx->root_xp = root_inode_xp;66 vfs_ctx->extend = NULL; // unused for DEVFS67 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 27 27 28 28 /////////////////////////////////////////////////////////////////////////////////////////// 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. 30 30 // It stores the dynamically created files and directories in the VFS mappers. 31 31 // 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 // 33 34 // There is no RAMFS context extension, and no RAMFS inode extension. 34 35 /////////////////////////////////////////////////////////////////////////////////////////// 35 36 36 37 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();48 38 49 39 /****************************************************************************************** … … 52 42 * and create a new VFS inode in another cluster. 53 43 ****************************************************************************************** 54 * @ parent_inode_xp : extended pointer on the parent inode .44 * @ parent_inode_xp : extended pointer on the parent inode in VFS. 55 45 * @ ramfs_root_name : RAMFS root directory name. 56 46 *****************************************************************************************/ … … 58 48 char * ramfs_root_name ); 59 49 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 93 50 #endif /* _RAMFS_H_ */ -
trunk/kernel/vfs/vfs.c
r124 r188 52 52 ////////////////////////////////////////////////////////////////////////////////////////// 53 53 54 extern vfs_ctx_t fs_context[FS_TYPES_NR]; // allocate in kernel_init.c 54 extern vfs_ctx_t fs_context[FS_TYPES_NR]; // allocated in kernel_init.c 55 55 56 56 57 ////////////////////////////////////////////////////////////////////////////////////////// 57 58 // Context related functions 58 59 ////////////////////////////////////////////////////////////////////////////////////////// 60 61 //////////////////////////////////////// 62 void 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 } 59 82 60 83 //////////////////////////////////////////// … … 101 124 ////////////////////////////////////////////////////////////////////////////////////////// 102 125 126 char * 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 103 138 ////////////////////////////////////////////////////// 104 105 139 error_t vfs_inode_create( xptr_t dentry_xp, 106 140 vfs_fs_type_t fs_type, 107 141 vfs_inode_type_t inode_type, 142 void * extend, 108 143 uint32_t attr, 109 144 uint32_t rights, … … 175 210 inode->ctx = ctx; 176 211 inode->mapper = NULL; 212 inode->extend = extend; 177 213 178 214 // initialise threads waiting queue … … 307 343 kmem_req_t req; // request to kernel memory allocator 308 344 309 // check type andget pointer on context345 // get pointer on context 310 346 if ( fs_type == FS_TYPE_FATFS ) ctx = &fs_context[FS_TYPE_FATFS]; 311 347 else if( fs_type == FS_TYPE_RAMFS ) ctx = &fs_context[FS_TYPE_RAMFS]; … … 349 385 xhtab_insert( XPTR( local_cxy , &parent->children ), 350 386 name, 351 XPTR( local_cxy , &dentry-> xlist ) );387 XPTR( local_cxy , &dentry->list ) ); 352 388 353 389 // return extended pointer on dentry … … 372 408 kmem_free( &req ); 373 409 } 410 374 411 375 412 … … 797 834 798 835 799 ///////////////////////////////////////////////////////////////////////////////////////// r836 ////////////////////////////////////////////////////////////////////////////////////////// 800 837 // Inode Tree functions 801 838 ////////////////////////////////////////////////////////////////////////////////////////// 839 840 ///////////////////////////////// 841 cxy_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 ////////////////////////////////////////////////////////////////////////// 857 static 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 /////////////////////////////////// 946 void 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 953 printk("\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() 802 985 803 986 ////////////////////////////////////////////////////////////////////////////////////////// … … 913 1096 return 0; 914 1097 } 915 1098 916 1099 ////////////////////////////////////////////// 917 1100 error_t vfs_lookup( xptr_t cwd_xp, … … 993 1176 else inode_type = INODE_TYPE_FILE; 994 1177 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, 997 1184 fs_type, 998 1185 parent_xp, 1186 NULL, // fs_type_specific inode extend 999 1187 name, 1000 1188 &child_xp ); … … 1002 1190 if( error ) 1003 1191 { 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", 1005 1193 __FUNCTION__ , name , pathname ); 1006 1194 return ENOENT; … … 1024 1212 // } 1025 1213 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... 1028 1215 1029 1216 // take lock on child inode if not last 1030 1217 if( last == false ) vfs_inode_lock( child_xp ); 1031 1218 1032 printk("\n@@@ bloup 1\n");1033 1034 1219 // release lock on parent inode 1035 1220 vfs_inode_unlock( parent_xp ); 1036 1037 printk("\n@@@ bloup 2\n");1038 1221 1039 1222 // update loop variables … … 1060 1243 1061 1244 } // end vfs_lookup() 1062 1063 1245 1064 1246 //////////////////////////////////////////// … … 1131 1313 } // end vfs_get_path() 1132 1314 1133 /////////////////////////////////////////////////////////////// 1134 error_t vfs_add_child_in_parent( vfs_inode_type_t inode_type, 1315 1316 ////////////////////////////////////////////////////////////// 1317 error_t vfs_add_child_in_parent( cxy_t child_cxy, 1318 vfs_inode_type_t inode_type, 1135 1319 vfs_fs_type_t fs_type, 1136 1320 xptr_t parent_xp, 1137 1321 char * name, 1322 void * extend, 1138 1323 xptr_t * child_xp ) 1139 1324 { … … 1174 1359 printk("\n[ERROR] in %s : cannot create dentry in cluster %x\n", 1175 1360 __FUNCTION__ , parent_cxy ); 1176 1177 1361 return error; 1178 1362 } 1179 1363 1180 // select a target cluster for child inode1181 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 1189 1364 // create child inode TODO : define attr / mode / uid / gid 1190 1365 uint32_t attr = 0; … … 1198 1373 fs_type, 1199 1374 inode_type, 1375 extend, 1200 1376 attr, 1201 1377 mode, … … 1210 1386 fs_type, 1211 1387 inode_type, 1388 extend, 1212 1389 attr, 1213 1390 mode, -
trunk/kernel/vfs/vfs.h
r101 r188 132 132 vfs_fs_type_t type; /*! File System type */ 133 133 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 */ 137 137 spinlock_t lock; /*! lock protecting inum allocator */ 138 138 uint32_t bitmap[BITMAP_SIZE(CONFIG_VFS_MAX_INODES)]; /* inum allocator */ … … 160 160 typedef enum 161 161 { 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 ET = 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 */ 169 169 } 170 170 vfs_inode_type_t; … … 182 182 typedef struct vfs_inode_s 183 183 { 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 */ 204 203 } 205 204 vfs_inode_t; … … 214 213 typedef struct vfs_dentry_s 215 214 { 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 */ 225 223 } 226 224 vfs_dentry_t; … … 231 229 * the inode, when a thread makes an open() or opendir() system call. 232 230 * 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. 234 232 * is replicated in all process descriptors, we need a references counter. 235 233 *****************************************************************************************/ … … 313 311 314 312 /*****************************************************************************************/ 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 *****************************************************************************************/ 326 void 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 ); 317 332 318 333 /****************************************************************************************** … … 355 370 * @ fs_type : file system type. 356 371 * @ inode_type : inode type. 372 * @ extend : local pointer on vs_type_specific extension. 357 373 * @ attr : inode attributes. 358 374 * @ rights : inode access rights. … … 365 381 vfs_fs_type_t fs_type, 366 382 vfs_inode_type_t inode_type, 383 void * extend, 367 384 uint32_t attr, 368 385 uint32_t rights, … … 550 567 /******************* Inode-Tree related functions ****************************************/ 551 568 /*****************************************************************************************/ 569 570 /****************************************************************************************** 571 * This function randomly selects a cluster for a new inode. 572 ****************************************************************************************** 573 * @ returns the selected cluster identifier. 574 *****************************************************************************************/ 575 cxy_t vfs_cluster_random_select(); 552 576 553 577 /****************************************************************************************** … … 594 618 * uses the rpc_dentry_create_client() and rpc_inode_create client() if required. 595 619 * - 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>. 597 621 * - The new dentry name is defined by the <name> argument. 598 622 * - The new inode and the parent inode can have different FS types. 599 623 ****************************************************************************************** 624 * @ child_cxy : target cluster for child inode. 600 625 * @ inode_type : new inode type 601 626 * @ fs_type : new inode FS type. 602 627 * @ parent_xp : extended pointer on parent inode. 603 628 * @ name : new directory entry name. 629 * @ extend : fs_type_specific inode extension. 604 630 * @ child_xp : [out] buffer for extended pointer on child inode. 605 631 * @ return 0 if success / ENOENT if entry not found in parent directory 606 632 *****************************************************************************************/ 607 error_t vfs_add_child_in_parent( vfs_inode_type_t inode_type, 633 error_t vfs_add_child_in_parent( cxy_t child_cxy, 634 vfs_inode_type_t inode_type, 608 635 vfs_fs_type_t fs_type, 609 636 xptr_t parent_xp, 610 637 char * name, 638 void * extend, 611 639 xptr_t * child_xp ); 612 640 … … 620 648 error_t vfs_remove_child_from_parent( xptr_t child_xp ); 621 649 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 *****************************************************************************************/ 657 void vfs_display( xptr_t inode_xp ); 622 658 623 659
Note: See TracChangeset
for help on using the changeset viewer.