Changeset 587
- Timestamp:
- Jul 8, 2015, 3:35:36 PM (9 years ago)
- Location:
- soft/giet_vm/giet_fat32
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_fat32/fat32.c
r569 r587 1 1 ////////////////////////////////////////////////////////////////////////////////// 2 // File : fat32.c 3 // Date : 01/09/2013 4 // Authors : Marco Jankovic, Cesar Fuguet & Alain Greiner 2 // Date : 01/06/2015 3 // Authors : Alain Greiner 5 4 // Copyright (c) UPMC-LIP6 6 5 ////////////////////////////////////////////////////////////////////////////////// 7 6 // The fat32.h and fat32.c files define a library of access functions 8 // to a FAT32 disk on a block device. It is intended to be used 9 // by the GIET_VM nano-kernel for boththe boot code and the kernel code.7 // to a FAT32 disk on a block device. It is intended to be used by both 8 // the boot code and the kernel code. 10 9 ////////////////////////////////////////////////////////////////////////////////// 11 10 // Implementation notes: … … 13 12 // the block device. The physical sector size is supposed to be 512 bytes. 14 13 // 2. the "cluster" variable is actually a cluster index. A cluster contains 15 // typically 8 sectors (4K bytes) and the cluster index is a 32 bits word. 16 // 3. This FAT32 library uses a FAT cache whose storage capacity is one sector. 14 // 8 sectors (4K bytes) and the cluster index is a 32 bits word. 15 // 3. Each file or directory referenced by the software is represented 16 // by an "inode". The set of "inodes" is organised as a tree, that is 17 // a sub-tree of the complete file system existing on the block device. 18 // 4. A given file can be referenced by several software tasks, and each task 19 // will use a private handler, called a "file descriptor", allocated by the OS 20 // when the task open the file, that is organised as an indexed array. 21 // 5. This FAT32 library implements (N+1) caches : one private "File_ Cache" 22 // for each referenced file or directory, and a specific "Fat_Cache" for 23 // the FAT itself. Each cache contain a variable number of clusters that are 24 // dynamically allocated when they are accessed, and organised as a 64-Tree. 25 ////////////////////////////////////////////////////////////////////////////////// 26 // General Debug Policy: 27 // The global variable GIET_DEBUG_FAT is defined in the giet_config.h file. 28 // The debug is activated if (proctime > GIET_DEBUG_FAT) && (GIET_DEBUG_FAT != 0) 29 // The GIET_DEBUG_FAT bit 0 defines the level of debug: 30 // if (GIET_DEBUG_FAT & 0x1) => detailed debug 31 // else => external functions only 17 32 ////////////////////////////////////////////////////////////////////////////////// 18 33 … … 22 37 #include <utils.h> 23 38 #include <vmem.h> 39 #include <kernel_malloc.h> 24 40 #include <bdv_driver.h> 25 41 #include <hba_driver.h> … … 30 46 31 47 ////////////////////////////////////////////////////////////////////////////////// 32 // Global variable : internal FAT representation 33 ////////////////////////////////////////////////////////////////////////////////// 34 35 extern fat32_fs_t _fat; 36 37 extern unsigned int _ptabs_vaddr[GIET_NB_VSPACE_MAX][X_SIZE][Y_SIZE]; 38 48 // Global variables 49 ////////////////////////////////////////////////////////////////////////////////// 50 51 // Fat-Descriptor 52 __attribute__((section(".kdata"))) 53 fat_desc_t _fat __attribute__((aligned(64))); 54 55 // buffer used by boot code as a simple cache when scanning FAT 56 __attribute__((section(".kdata"))) 57 unsigned char _fat_buffer_fat[4096] __attribute__((aligned(64))); 58 59 // buffer used by boot code as a simple cache when scanning a directory in DATA region 60 __attribute__((section(".kdata"))) 61 unsigned char _fat_buffer_data[4096] __attribute__((aligned(64))); 62 63 // lba of cluster in fat_buffer_fat 64 __attribute__((section(".kdata"))) 65 unsigned int _fat_buffer_fat_lba; 66 67 // lba of cluster in fat_buffer_data 68 __attribute__((section(".kdata"))) 69 unsigned int _fat_buffer_data_lba; 70 71 ////////////////////////////////////////////////////////////////////////////////// 72 ////////////////////////////////////////////////////////////////////////////////// 73 // Static functions declaration 74 ////////////////////////////////////////////////////////////////////////////////// 75 ////////////////////////////////////////////////////////////////////////////////// 76 77 78 /////////////////////////////////////////////////////////////////////////////////// 79 // This debug function displays the content of a 512 bytes buffer "buf", 80 // with an identifier defined by the "string" and "block_id" arguments. 81 /////////////////////////////////////////////////////////////////////////////////// 82 83 #if GIET_DEBUG_FAT 84 static void _display_one_block( unsigned char* buf, 85 char* string, 86 unsigned int block_id ); 87 #endif 88 89 ////////////////////////////////////////////////////////////////////////////////// 90 // This debug function displays the FAT descriptor. 91 ////////////////////////////////////////////////////////////////////////////////// 92 93 #if GIET_DEBUG_FAT 94 static void _display_fat_descriptor(); 95 #endif 96 39 97 ///////////////////////////////////////////////////////////////////////////////// 40 // This function computes the memory buffer physical address, and calls 41 // the proper IOC driver depending on the subtype (BDV / HBA / SDC / SPI / RDK). 42 // The use_irq argument allows to activate the descheduling mode, if it 43 // supported by the IOC driver subtype 98 // This debug function displays the sequence of clusters allocated to a 99 // file (or directory) identified by the "inode" argument. 44 100 ///////////////////////////////////////////////////////////////////////////////// 45 // Return 0 in case of success, return -1 in case of error 101 102 #if GIET_DEBUG_FAT 103 static void _display_clusters_list( fat_inode_t* inode ); 104 #endif 105 46 106 ///////////////////////////////////////////////////////////////////////////////// 47 static 48 int _fat_ioc_access( unsigned int use_irq, 49 unsigned int to_mem, 50 unsigned int lba, 51 unsigned int buf_vaddr, 52 unsigned int count ) 107 // The following function transfers one or several blocks between the device 108 // and a memory buffer identified by a virtual address. 109 // It computes the memory buffer physical address, and calls the proper 110 // IOC driver depending on the subtype (BDV / HBA / SDC / SPI / RDK). 111 // The use_irq argument allows to activate the descheduling mode, 112 // if it supported by the IOC driver subtype 113 // It returns O in case of success. 114 // It returns -1 in case of error. 115 ///////////////////////////////////////////////////////////////////////////////// 116 117 static int _fat_ioc_access( unsigned int use_irq, 118 unsigned int to_mem, 119 unsigned int lba, 120 unsigned int buf_vaddr, 121 unsigned int count ); 122 123 ////////////////////////////////////////////////////////////////////////////////// 124 // The following function returns in the "desc" argument a pointer on a buffer 125 // descriptor contained in a File_Cache, or in the Fat_Cache. 126 // The searched buffer is idenfified by the "inode" and "cluster_id" arguments. 127 // If the "inode" pointer is not NULL, the searched cache is a File-Cache. 128 // If the "inode" pointer is NULL, the searched cache is the Fat-Cache, 129 // The "cluster_id" argument is the buffer index in the file (or in the FAT). 130 // In case of miss, it allocate a 4 Kbytes buffer and a cluster descriptor 131 // from the local kernel heap, and calls the _fat_ioc_access() function to load 132 // the missing cluster from the block device. 133 // It returns O in case of success. 134 // It returns 1 in case of error. 135 ////////////////////////////////////////////////////////////////////////////////// 136 137 static unsigned int _get_buffer_from_cache( fat_inode_t* inode, 138 unsigned int cluster_id, 139 fat_cache_desc_t** desc ); 140 141 //////////////////////////////////////////////////////////////////////////////// 142 // This function extract a (partial) name from a LFN directory entry. 143 //////////////////////////////////////////////////////////////////////////////// 144 145 static void _get_name_from_long( unsigned char* buffer, 146 char* name ); 147 148 //////////////////////////////////////////////////////////////////////////////// 149 // The following function extract a name from a NORMAL directory entry. 150 //////////////////////////////////////////////////////////////////////////////// 151 152 static void _get_name_from_short( unsigned char* buffer, 153 char* name ); 154 155 ////////////////////////////////////////////////////////////////////////////////// 156 // This function returns the number of levels of a File-Cache (or Fat-Cache) 157 // from the size of the file (or FAT). 158 ////////////////////////////////////////////////////////////////////////////////// 159 160 static inline unsigned int _get_levels_from_size( unsigned int size ); 161 162 /////////////////////////////////////////////////////////////////////////////////// 163 // The following function analyses the "pathname" argument, from the character 164 // defined by the "nb_read" argument. 165 // It copies the found name in the "name" buffer (without '/'), 166 // and updates the "nb_read" argument. 167 // It returns 0 if success. 168 // It returns 1 if one name length > NAME_MAX_SIZE characters 169 /////////////////////////////////////////////////////////////////////////////////// 170 171 static unsigned int _get_name_from_path( char* pathname, 172 char* name, 173 unsigned int* nb_read ); 174 175 //////////////////////////////////////////////////////////////////////////////// 176 // The following function scan the "pathname" argument, and copies in the 177 // "name" buffer the last name in path (leaf name). 178 // It returns 0 if success. 179 // It returns 1 if one name length > NAME_MAX_SIZE characters 180 //////////////////////////////////////////////////////////////////////////////// 181 static unsigned int _get_last_name( char* pathname, 182 char* name ); 183 184 ////////////////////////////////////////////////////////////////////////////////// 185 // The following function access the Fat-Cache and returns in the "value" 186 // argument the content of the FAT slot identified by the "cluster" argument. 187 // It loads the missing cluster from block device into cache in case of miss. 188 // It returns 0 if success. 189 // It returns 1 if error. 190 ////////////////////////////////////////////////////////////////////////////////// 191 192 static unsigned int _get_fat_entry( unsigned int cluster, 193 unsigned int* value ); 194 195 ////////////////////////////////////////////////////////////////////////////////// 196 // The following function writes a new "value" in the Fat-Cache, in the slot 197 // identified by the "cluster" argument. 198 // It loads the missing cluster from block device into cache in case of miss. 199 // It returns 0 if success, 200 // It returns 1 if error. 201 ////////////////////////////////////////////////////////////////////////////////// 202 203 static unsigned int _set_fat_entry( unsigned int cluster, 204 unsigned int value ); 205 206 ////////////////////////////////////////////////////////////////////////////////// 207 // The following function introduces the inode identified by the "child" argument, 208 // as a new child of the "parent" inode in the Inode-Tree. 209 // All checking are supposed to be done by the caller. 210 // Nor the File-Cache, neither the block device are modified. 211 ////////////////////////////////////////////////////////////////////////////////// 212 213 static void _add_inode_in_tree( fat_inode_t* child, 214 fat_inode_t* parent ); 215 216 ////////////////////////////////////////////////////////////////////////////////// 217 // The following function removes one inode identified by the "inode" argument 218 // from the Inode-Tree. All checking are supposed to be done by the caller. 219 // Nor the File-Cache, neither the block device are modified. 220 ////////////////////////////////////////////////////////////////////////////////// 221 222 static void _remove_inode_from_tree( fat_inode_t* inode ); 223 224 ////////////////////////////////////////////////////////////////////////////////// 225 // This recursive function scan one File-Cache (or Fat-Cache) from root to leaves, 226 // to writes all dirty clusters to block device, and reset the dirty bits. 227 // The cache is identified by the "root" an "levels" arguments. 228 // The "string" argument is only used for debug : inode name or Fat. 229 // It returns 0 if success. 230 // It returns 1 if error. 231 ////////////////////////////////////////////////////////////////////////////////// 232 233 static unsigned int _update_device_from_cache( unsigned int levels, 234 fat_cache_node_t* root, 235 char* string ); 236 237 ////////////////////////////////////////////////////////////////////////////////// 238 // The following function access directly the FS_INFO block on the block device, 239 // to update the "first_free_cluster" and "free_clusters_number" values, 240 // using only the Fat-Descriptor single block buffer. 241 // It return 0 in case of success. 242 // It return 1 in case of error. 243 ////////////////////////////////////////////////////////////////////////////////// 244 245 static unsigned int _update_fs_info(); 246 247 ////////////////////////////////////////////////////////////////////////////// 248 // The following function read a data field (from one to four bytes) 249 // from an unsigned char[] buffer, taking endianness into account. 250 // The analysed field is defined by the "offset" and "size" arguments. 251 ////////////////////////////////////////////////////////////////////////////// 252 253 static unsigned int _read_entry( unsigned int offset, 254 unsigned int size, 255 unsigned char* buffer, 256 unsigned int little_indian ); 257 258 ////////////////////////////////////////////////////////////////////////////////// 259 // The following function returns the lba of first sector in DATA region 260 // from the cluster index. The cluster index must be larger than 2. 261 ////////////////////////////////////////////////////////////////////////////////// 262 263 static unsigned int _cluster_to_lba( unsigned int cluster ); 264 265 ////////////////////////////////////////////////////////////////////////////////// 266 // The following function returns in the "nb_entries" argument the number of files 267 // (or directories) contained in a directory identidied by the "inode " pointer. 268 // It returns 0 if success. 269 // It returns 1 if error. 270 ////////////////////////////////////////////////////////////////////////////////// 271 272 static unsigned int _get_nb_entries( fat_inode_t* inode, 273 unsigned int* nb_entries ); 274 275 ////////////////////////////////////////////////////////////////////////////////// 276 // The following function search in the directory identified by the "parent" 277 // inode pointer a child (file or directory) identified by its "name". 278 // It returns in the "inode" argument the searched child inode pointer. 279 // If the searched name is not found in the Inode-Tree, the function access 280 // the "file_cache" associated to the parent directory. 281 // If the child exist on block device, the Inode-Tree is updated, and 282 // a success code is returned. 283 // If the file/dir does not exist on block device, a error code is returned. 284 // It returns 0 if inode found. 285 // It returns 1 if inode not found. 286 // It returns 2 if error in cache access. 287 ////////////////////////////////////////////////////////////////////////////////// 288 289 static unsigned int _get_child_from_parent( fat_inode_t* parent, 290 char* name, 291 fat_inode_t** inode ); 292 293 ///////////////////////////////////////////////////////////////////////////////// 294 // For a file (or a directory) identified by the "pathname" argument, the 295 // following function returns in the "inode" argument the inode pointer 296 // associated to the searched file (or directory), with code (0). 297 // If the searched file (or directory) is not found, but the parent directory 298 // is found, it returns in the "inode" argument the pointer on the parent inode, 299 // with code (1). Finally, code (2) and code (3) are error codes. 300 // Both the Inode-Tree and the involved Cache-Files are updated from the block 301 // device in case of miss on one inode during the search in path. 302 // Neither the Fat-Cache, nor the block device are updated. 303 // It returns 0 if searched inode found 304 // It returns 1 if searched inode not found but parent directory found 305 // It returns 2 if searched inode not found and parent directory not found 306 // It returns 3 if one name too long 307 ///////////////////////////////////////////////////////////////////////////////// 308 309 static unsigned int _get_inode_from_path( char* pathname, 310 fat_inode_t** inode ); 311 312 ////////////////////////////////////////////////////////////////////////////////// 313 // This function computes the length and the number of LFN entries required 314 // to store a node name in the "length" and "nb_lfn" arguments. 315 // Short name (less than 13 characters) require 1 LFN entry. 316 // Medium names (from 14 to 26 characters require 2 LFN entries. 317 // Large names (up to 31 characters) require 3 LFN entries. 318 // It returns 0 if success. 319 // It returns 1 if length larger than 31 characters. 320 ////////////////////////////////////////////////////////////////////////////////// 321 322 static unsigned int _check_name_length( char* name, 323 unsigned int* length, 324 unsigned int* nb_lfn ); 325 326 ////////////////////////////////////////////////////////////////////////////////// 327 // For a node identified by the "inode" argument, this function updates the 328 // "size" and "cluster" values in the entry of the parent directory File-Cache. 329 // It set the dirty bit in the modified buffer of the parent directory File-Cache. 330 ////////////////////////////////////////////////////////////////////////////////// 331 332 static unsigned int _update_dir_entry( fat_inode_t* inode ); 333 334 ////////////////////////////////////////////////////////////////////////////////// 335 // The following function add new "child" in Cache-File of "parent" directory. 336 // It access the File_Cache associated to the parent directory, and scan the 337 // clusters allocated to this directory to find the NO_MORE entry. 338 // This entry will be the first modified entry in the directory. 339 // Regarding the name storage, it uses LFN entries for all names. 340 // Therefore, it writes 1, 2, or 3 LFN entries (depending on the child name 341 // actual length, it writes one NORMAL entry, and writes the new NOMORE entry. 342 // It updates the dentry field in the child inode. 343 // It set the dirty bit for all modified File-Cache buffers. 344 // The block device is not modified by this function. 345 ////////////////////////////////////////////////////////////////////////////////// 346 347 static unsigned int _add_dir_entry( fat_inode_t* child, 348 fat_inode_t* parent ); 349 350 ////////////////////////////////////////////////////////////////////////////////// 351 // The following function invalidates all dir_entries associated to the "inode" 352 // argument from its parent directory. 353 // It set the dirty bit for all modified buffers in parent directory Cache-File. 354 // The inode itself is not modified by this function. 355 // The block device is not modified by this function. 356 ////////////////////////////////////////////////////////////////////////////////// 357 358 static unsigned int _remove_dir_entry( fat_inode_t* inode ); 359 360 ////////////////////////////////////////////////////////////////////////////////// 361 // The following function add the special entries "." and ".." in the File-Cache 362 // of the directory identified by the "child" argument. 363 // The parent directory is defined by the "parent" argument. 364 // The child directory File-Cache is supposed to be empty. 365 // We use two NORMAL entries for these "." and ".." entries. 366 // The block device is not modified by this function. 367 ////////////////////////////////////////////////////////////////////////////////// 368 369 static void _add_special_directories( fat_inode_t* child, 370 fat_inode_t* parent ); 371 372 ////////////////////////////////////////////////////////////////////////////////// 373 // The following function releases all clusters allocated to a file or directory, 374 // from the cluster index defined by the "cluster" argument, until the end 375 // of the FAT linked list. 376 // It calls _get_fat_entry() and _set_fat_entry() functions to scan the FAT, 377 // and to update the clusters chaining. 378 // The FAT region on block device is updated. 379 // It returns 0 if success. 380 // It returns 1 if error. 381 ////////////////////////////////////////////////////////////////////////////////// 382 383 static unsigned int _clusters_release( unsigned int cluster ); 384 385 ////////////////////////////////////////////////////////////////////////////////// 386 // This function allocate "nb_clusters_more" new clusters to a file (or directory) 387 // identified by the "inode" pointer. It allocates also the associated buffers 388 // and buffer descriptors in the Cache-File. 389 // It calls _get_fat_entry() and _set_fat_entry() functions to update the 390 // clusters chaining in the Cache-Fat. The FAT region on block device is updated. 391 // It returns 0 if success. 392 // It returns 1 if error. 393 ////////////////////////////////////////////////////////////////////////////////// 394 395 static unsigned int _clusters_allocate( fat_inode_t* inode, 396 unsigned int nb_clusters_current, 397 unsigned int nb_clusters_more ); 398 399 ////////////////////////////////////////////////////////////////////////////////// 400 // This recursive function scan one File-Cache (or Fat-Cache) from root to leaves. 401 // The cache 64-Tree infrastructure is kept, but all memory allocated for 4 Kbytes 402 // buffers, and for buffer descriptors (in leaves) is released. 403 // The cache is identified by the "root" an "levels" arguments. 404 // It should not contain any dirty clusters. 405 // It returns 0 if success. 406 // It returns 1 if error. 407 ////////////////////////////////////////////////////////////////////////////////// 408 409 static unsigned int _release_cache_memory( fat_cache_node_t* root, 410 unsigned int levels ); 411 412 ////////////////////////////////////////////////////////////////////////////////// 413 // The following function allocates and initializes a new inode, 414 // using the values defined by the arguments. 415 // If the "cache_allocate" argument is true ans empty cache is allocated. 416 // The Fat-Cache is initialised as empty: all children set to NULL. 417 // It returns a pointer on the new inode. 418 ////////////////////////////////////////////////////////////////////////////////// 419 420 static fat_inode_t* _allocate_one_inode( char* name, 421 unsigned int is_dir, 422 unsigned int cluster, 423 unsigned int size, 424 unsigned int count, 425 unsigned int dentry, 426 unsigned int cache_allocate ); 427 428 ////////////////////////////////////////////////////////////////////////////////// 429 // The following function allocates one 4 Kbytes buffer and associated cluster 430 // descriptor for the file (or directory) identified by the "inode" argument, 431 // and updates the Cache_File slot identified by the "cluster_id" argument. 432 // The File-Cache slot must be empty. 433 // It updates the cluster descriptor, using the "cluster" argument, that is 434 // the cluster index in FAT. The cluster descriptor dirty field is set. 435 // It traverse the 64-tree Cache-file from top to bottom to find the last level. 436 ////////////////////////////////////////////////////////////////////////////////// 437 438 static void _allocate_one_buffer( fat_inode_t* inode, 439 unsigned int cluster_id, 440 unsigned int cluster ); 441 442 ////////////////////////////////////////////////////////////////////////////////// 443 // The following function allocates one free cluster from the FAT "heap" of free 444 // clusters, and returns the cluster index in the "cluster" argument. 445 // It updates the FAT slot, and the two FAT global variables: first_free_cluster, 446 // and free_clusters_number. 447 // It returns O if success. 448 // It returns 1 if error. 449 ////////////////////////////////////////////////////////////////////////////////// 450 451 static unsigned int _allocate_one_cluster( unsigned int* cluster ); 452 453 ///////////////////////////////////////////////////////////////////////////// 454 // This function remove from the file system a file or a directory 455 // identified by the "inode" argument. 456 // The remove condition must be checked by the caller. 457 // The relevant lock(s) must have been taken by te caller. 458 // It returns O if success. 459 // It returns 1 if error. 460 ///////////////////////////////////////////////////////////////////////////// 461 462 static unsigned int _remove_node_from_fs( fat_inode_t* inode ); 463 464 ///////////////////////////////////////////////////////////////////////////// 465 // This function return the cluster index and the size for a file 466 // identified by the "pathname" argument, scanning directly the block 467 // device DATA region. 468 // It is intended to be called only by the _fat_load_no_cache() function, 469 // it does not use the dynamically allocated File Caches, but uses only 470 // the 4 Kbytes _fat_buffer_data. 471 // It returns 0 if success. 472 // It returns 1 if error. 473 ///////////////////////////////////////////////////////////////////////////// 474 475 static unsigned int _file_info_no_cache( char* pathname, 476 unsigned int* file_cluster, 477 unsigned int* file_size ); 478 479 ///////////////////////////////////////////////////////////////////////////// 480 // This function scan directly the FAT region on the block device, 481 // and returns in the "next" argument the value stored in the fat slot 482 // identified by the "cluster" argument. 483 // It is intended to be called only by the _fat_load_no_cache() function, 484 // as it does not use the dynamically allocated Fat-Cache, but uses only 485 // the 4 Kbytes _fat_buffer_fat. 486 // It returns 0 if success. 487 // It returns 1 if error. 488 ///////////////////////////////////////////////////////////////////////////// 489 490 static unsigned int _next_cluster_no_cache( unsigned int cluster, 491 unsigned int* next ); 492 493 494 ////////////////////////////////////////////////////////////////////////////////// 495 // The following functions return the length or the size of a FAT field, 496 // identified by an (offset,length) mnemonic defined in the fat32.h file. 497 ////////////////////////////////////////////////////////////////////////////////// 498 499 static inline int get_length( int offset , int length ) { return length; } 500 501 static inline int get_offset( int offset , int length ) { return offset; } 502 503 504 505 506 507 ////////////////////////////////////////////////////////////////////////////////// 508 ////////////////////////////////////////////////////////////////////////////////// 509 // Static functions definition 510 ////////////////////////////////////////////////////////////////////////////////// 511 ////////////////////////////////////////////////////////////////////////////////// 512 513 #if GIET_DEBUG_FAT 514 /////////////////////////////////////////////////// 515 static void _display_one_block( unsigned char* buf, 516 char* string, 517 unsigned int block_id ) 518 { 519 unsigned int line; 520 unsigned int word; 521 522 _printf("\n*** <%s> block %x ***********************************\n", 523 string , block_id ); 524 525 for ( line = 0 ; line < 16 ; line++ ) 526 { 527 // display line index 528 _printf("%x : ", line ); 529 530 // display 8*4 bytes hexa 531 for ( word=0 ; word<8 ; word++ ) 532 { 533 unsigned int byte = (line<<5) + (word<<2); 534 unsigned int hexa = (buf[byte ]<<24) | 535 (buf[byte+1]<<16) | 536 (buf[byte+2]<< 8) | 537 (buf[byte+3] ); 538 _printf(" %X |", hexa ); 539 } 540 _printf("\n"); 541 } 542 _printf("*******************************************************************\n"); 543 } // end _display_one_block() 544 #endif 545 546 547 548 #if GIET_DEBUG_FAT 549 ///////////////////////////////////// 550 static void _display_fat_descriptor() 551 { 552 _printf("\n############### FAT DESCRIPTOR ################################" 553 "\nFAT initialised %x" 554 "\nBlock Size (bytes) %x" 555 "\nCluster Size (bytes) %x" 556 "\nFAT region first lba %x" 557 "\nFAT region size (blocks) %x" 558 "\nDATA region first lba %x" 559 "\nDATA region size (blocks) %x" 560 "\nNumber of free clusters %x" 561 "\nFirst free cluster index %x" 562 "\nFat_cache_levels %d" 563 "\n#################################################################\n", 564 _fat.initialised, 565 _fat.sector_size, 566 _fat.cluster_size, 567 _fat.fat_lba, 568 _fat.fat_sectors, 569 _fat.data_lba, 570 _fat.data_sectors, 571 _fat.free_clusters_number, 572 _fat.first_free_cluster, 573 _fat.fat_cache_levels ); 574 575 } // end _display_fat_descriptor() 576 #endif 577 578 579 580 #if GIET_DEBUG_FAT 581 //////////////////////////////////////////////////////// 582 static void _display_clusters_list( fat_inode_t* inode ) 583 { 584 _printf("\n**************** clusters for <%s> ***********************\n", inode->name ); 585 unsigned int next; 586 unsigned int n = 0; 587 unsigned int current = inode->cluster; 588 while( (current < END_OF_CHAIN_CLUSTER_MIN) && (n < 1024) ) 589 { 590 _get_fat_entry( current , &next ); 591 _printf(" > %X", current ); 592 n++; 593 if ( (n & 0x7) == 0 ) _printf("\n"); 594 current = next; 595 } 596 _printf("\n"); 597 } // end _display_clusters_list() 598 #endif 599 600 601 602 ///////////////////////////////////////////////////////////////////////////////// 603 static int _fat_ioc_access( unsigned int use_irq, // descheduling if non zero 604 unsigned int to_mem, // read / write 605 unsigned int lba, // first sector on device 606 unsigned int buf_vaddr, // memory buffer vaddr 607 unsigned int count ) // number of sectors 53 608 { 54 609 // compute memory buffer physical address … … 57 612 58 613 if ( ((_get_mmu_mode() & 0x4) == 0 ) || USE_IOC_RDK ) // identity 59 { 614 { 60 615 buf_paddr = (unsigned long long)buf_vaddr; 61 616 } … … 65 620 } 66 621 67 #if GIET_DEBUG_FAT 68 unsigned int procid = _get_procid(); 69 unsigned int x = procid >> (Y_WIDTH + P_WIDTH); 70 unsigned int y = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 71 unsigned int p = procid & ((1<<P_WIDTH)-1); 72 if ( _get_proctime() > GIET_DEBUG_FAT ) 73 _printf("\n[DEBUG FAT] P[%d,%d,%d] enters _fat_ioc_access() at cycle %d\n" 622 #if (GIET_DEBUG_FAT & 1) 623 if ( _get_proctime() > GIET_DEBUG_FAT ) 624 _printf("\n[DEBUG FAT] _fat_ioc_access() : enters at cycle %d\n" 74 625 " to_mem = %d / vaddr = %x / paddr = %l / sectors = %d / lba = %x\n", 75 x, y , p,_get_proctime(), to_mem, buf_vaddr, buf_paddr, count, lba );626 _get_proctime(), to_mem, buf_vaddr, buf_paddr, count, lba ); 76 627 #endif 77 628 … … 100 651 101 652 102 ////////////////////////////////////////////////////////////////////////////////// 103 // This function displays the content of the FAT cache 104 ////////////////////////////////////////////////////////////////////////////////// 105 #if GIET_DEBUG_FAT 106 static 107 void _display_fat_cache() 108 { 109 unsigned int line; 110 unsigned int word; 111 unsigned int temp[9]; 112 113 temp[8] = 0; 114 115 _puts("\n*********************** fat_cache_lba = "); 116 _putx( _fat.cache_lba ); 117 _puts(" *****************************\n"); 118 119 for ( line = 0 ; line < 16 ; line++ ) 120 { 121 // display line index 122 _putx( line ); 123 _puts(" : "); 124 125 // display 8*4 bytes hexa 126 for ( word=0 ; word<8 ; word++ ) 127 { 128 unsigned int byte = (line<<5) + (word<<2); 129 unsigned int hexa = (_fat.fat_cache[byte ]<<24) | 130 (_fat.fat_cache[byte+1]<<16) | 131 (_fat.fat_cache[byte+2]<< 8) | 132 (_fat.fat_cache[byte+3]); 133 _putx( hexa ); 134 _puts(" | "); 135 136 // prepare display ascii 137 temp[word] = _fat.fat_cache[byte] | 138 (_fat.fat_cache[byte+1]<<8) | 139 (_fat.fat_cache[byte+2]<<16) | 140 (_fat.fat_cache[byte+3]<<24) ; 141 } 142 143 // display data ascii 144 _puts( (char*)temp ); 145 _puts("\n"); 146 } 147 _puts("***************************************************************************\n"); 148 149 } // end _display_fat_cache() 150 #endif 151 152 ////////////////////////////////////////////////////////////////////////////////// 153 // This function displays the FAT descriptor. 154 ////////////////////////////////////////////////////////////////////////////////// 155 #if GIET_DEBUG_FAT 156 static 157 void _fat_print() 158 { 159 _printf("\n########################## FAT32 ################################" 160 "\nFAT initialised %x" 161 "\nSector Size (bytes) %x" 162 "\nSectors per cluster %x" 163 "\nFAT region first lba %x" 164 "\nData region first lba %x" 165 "\nNumber of sectors for one FAT %x" 166 "\nNumber of free clusters %x" 167 "\nLast allocated cluster %x" 168 "\n#################################################################\n", 169 _fat.initialised, 170 _fat.sector_size, 171 _fat.sectors_per_cluster, 172 _fat.fat_lba, 173 _fat.data_lba, 174 _fat.fat_sectors, 175 _fat.number_free_cluster, 176 _fat.last_cluster_allocated ); 177 } // end _fat_print() 178 #endif 179 180 ////////////////////////////////////////////////////////////////////////////////// 181 // This function returns the length of a FAT field. This field is identified 182 // by an (offset,length) mnemonic defined in fat32.h file. 183 ////////////////////////////////////////////////////////////////////////////////// 184 static inline 185 int get_length( int offset, 186 int length ) 187 { 188 return length; 653 654 655 ///////////////////////////////////////////////////////////////////// 656 static inline unsigned int _get_levels_from_size( unsigned int size ) 657 { 658 if ( size <= (1<<18) ) return 1; // 64 clusters == 256 Kbytes 659 else if ( size <= (1<<24) ) return 2; // 64 * 64 clusters => 16 Mbytes 660 else if ( size <= (1<<30) ) return 3; // 64 * 64 * 64 cluster => 1 Gbytes 661 else return 4; // 64 * 64 * 64 * 64 clusters 189 662 } 190 663 191 ////////////////////////////////////////////////////////////////////////////// 192 // Write one 32 bits word "value" in a char[] buffer. 193 // The modified field in buffer is defined by the offset and size arguments. 194 ////////////////////////////////////////////////////////////////////////////// 195 static 196 void _write_entry( unsigned int offset, 197 unsigned int size, 198 char* buffer, 199 unsigned int value ) 200 { 201 unsigned int turn = 0; 202 unsigned int res = value; 203 unsigned int mask = 0x000000ff; 204 205 while( turn != size - 1 ) 206 { 207 buffer[ offset + turn ] = res & mask; 208 res = res >> 8; 209 turn++; 210 } 211 buffer[offset + turn] = res & mask; 664 665 666 //////////////////////////////////////////////////////// 667 static unsigned int _read_entry( unsigned int offset, 668 unsigned int size, 669 unsigned char* buffer, 670 unsigned int little_endian ) 671 { 672 unsigned int n; 673 unsigned int res = 0; 674 675 if ( little_endian) 676 { 677 for( n = size ; n > 0 ; n-- ) res = (res<<8) | buffer[offset+n-1]; 678 } 679 else 680 { 681 for( n = 0 ; n < size ; n++ ) res = (res<<8) | buffer[offset+n]; 682 } 683 return res; 684 685 } // end _read_entry 686 687 688 689 ////////////////////////////////////////////////////////////////// 690 static inline unsigned int _cluster_to_lba( unsigned int cluster ) 691 { 692 if ( cluster < 2 ) 693 { 694 _printf("\n[FAT ERROR] in _cluster_to_lba() cluster smaller than 2\n"); 695 _exit(); 696 } 697 698 return ((cluster - 2) << 3) + _fat.data_lba; 212 699 } 213 700 214 //////////////////////////////////////////////////////////////////////////////215 // Read one 32 bits word in a char[] buffer, taking endianness into account.216 // The analysed field in buffer is defined by the offset and size arguments.217 //////////////////////////////////////////////////////////////////////////////218 static219 unsigned int _read_entry( unsigned int offset,220 unsigned int size,221 char* buffer,222 unsigned int little_indian )223 {224 unsigned int turn;225 unsigned int res = 0;226 unsigned int mask = 0x000000ff;227 228 if( little_indian )229 {230 turn = size;231 while( turn != 1 )232 {233 res = res | (buffer[offset + (turn-1)] & mask);234 res = res << 8;235 turn--;236 }237 res = (buffer[offset + (turn-1)] & mask) | res;238 }239 else240 {241 turn = 0;242 while( turn != size - 1 )243 {244 245 res = res | (buffer[ offset + turn ] & mask );246 res = res << 8;247 turn++;248 }249 res = res | (buffer[offset + turn] & mask);250 }251 return res;252 }253 254 //////////////////////////////////////////////////////////////////////////////////255 // This function retuns the cluster index from the lba of a DATA sector.256 // The lba must be larger than the lba of the first DATA sector.257 // The DATA region indexing starts a cluster 2.258 //////////////////////////////////////////////////////////////////////////////////259 static inline260 unsigned int lba_to_cluster( unsigned int lba )261 {262 if (lba < _fat.data_lba ) return 0;263 264 return ( (lba - _fat.data_lba) / _fat.sectors_per_cluster) + 2;265 }266 267 //////////////////////////////////////////////////////////////////////////////////268 // This function retuns the lba of first sector in DATA region269 // from the cluster index. The cluster index must be larger than 2.270 //////////////////////////////////////////////////////////////////////////////////271 static inline272 unsigned int cluster_to_lba( unsigned int cluster )273 {274 if ( cluster < 2 ) return 0;275 276 return (_fat.sectors_per_cluster * (cluster - 2)) + _fat.data_lba;277 }278 279 /////////////////////////////////////////////////////////////////////////////////280 // This function search the FAT (using the FAT cache), and returns281 // the next cluster index from the current cluster index in the FAT.282 // remark: a sector of FAT contains 128 cluster indexes.283 /////////////////////////////////////////////////////////////////////////////////284 static285 unsigned int _get_next_cluster( unsigned int use_irq,286 unsigned int cluster )287 {288 // compute lba of the sector containing the cluster index289 unsigned int lba = _fat.fat_lba + (cluster / 128);290 291 if ( lba != _fat.cache_lba ) // miss in fat_cache292 {293 // access fat294 if( _fat_ioc_access( use_irq,295 1, // read296 lba,297 (unsigned int)_fat.fat_cache,298 1 ) ) // one sector299 {300 _printf("[FAT_ERROR] in get_next_cluster_id() : cannot read block %x",301 lba );302 return 1;303 }304 _fat.cache_lba = lba;305 }306 307 unsigned int next = _read_entry( ((cluster % 128) * 4),308 4,309 _fat.fat_cache,310 1 );311 #if GIET_DEBUG_FAT312 unsigned int procid = _get_procid();313 unsigned int x = procid >> (Y_WIDTH + P_WIDTH);314 unsigned int y = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);315 unsigned int p = procid & ((1<<P_WIDTH)-1);316 if ( _get_proctime() > GIET_DEBUG_FAT )317 _printf("\n[DEBUG FAT] P[%d,%d,%d] in _get_next_cluster() : next = %x\n",318 x , y , p , next );319 if ( (_get_proctime() > GIET_DEBUG_FAT) && (GIET_DEBUG_FAT & 0x1) )320 _display_fat_cache();321 #endif322 323 return next;324 }325 701 326 702 ////////////////////////////////////////////////////// 327 static inline unsigned char to_upper(unsigned char c)703 static inline unsigned char _to_upper(unsigned char c) 328 704 { 329 705 if (c >= 'a' && c <= 'z') return (c & ~(0x20)); … … 331 707 } 332 708 333 //////////////////////////////////////////////////////////////// 334 // This function is a filter: 335 // Return the c character if c is a legal short name character 336 // Return the '_' character if c is illegal 337 //////////////////////////////////////////////////////////////// 338 static 339 unsigned char illegal_short(unsigned char c) 340 { 341 const unsigned char illegal_char [] =";+=[]â,\"*\\<>/?:|\0"; 342 short i = 0; 343 while (illegal_char[i]!='\0') 344 { 345 if (c == illegal_char[i]) 346 return '_'; 347 i++; 348 } 349 return c; 350 } 351 352 ///////////////////////////////////////////////////////////////////////////////// 353 // This function test if the string argument is a legal SFN (Short File Name) 354 // and copies this name (removing the .) in the sfn_string argument. 355 // Criteria for a Short File Name are: 356 // - separator is '.' (extension is not mandatory) 357 // - 1 <= name length <= 8 358 // - 0 <= extension length <= 3 359 // - no illegal character (see illega_short() function) 360 // Return 1 if it string is a legal SFN 361 // Return 0 if not legal SFN 362 ///////////////////////////////////////////////////////////////////////////////// 363 static 364 int is_short( char* string, 365 char* sfn_string) 366 { 367 int s_size = 0; 368 int dot_ext = 0; // dot offset in the filename 369 int name_len = 0; // length of file name 370 int ext_len = 0; // length of extension 371 int i = 0; 372 int sc_i = 0; 373 char ch; 374 375 if(string[0] == '.' && string[1] == '\0') 376 { 377 sfn_string[0] = '.'; 378 return 1; 379 } 380 if(string[0] == '.' && string[1] == '.' && string[2] == '\0') 381 { 382 sfn_string[0] = '.'; 383 sfn_string[1] = '.'; 384 return 1; 385 } 386 sfn_string[11] = '\0'; 387 while (string[s_size] != '\0') 388 { 389 if (string[s_size] == '.') 390 { 391 dot_ext = s_size; 392 ext_len = -1; 393 } 394 ext_len++; 395 s_size++; 396 } 397 if (dot_ext != 0) 398 { 399 name_len = s_size - ext_len - 1; 400 } 401 else 402 { 403 name_len = s_size; 404 ext_len = 0; 405 } 406 if ( ext_len > 3 || ( name_len > 8)) 407 { 408 return 0; 409 } 410 if (dot_ext != 0) 411 { 412 while (i != ext_len) 413 { 414 ch = to_upper(string[dot_ext + 1 + i]); 415 ch = illegal_short(ch); 416 sfn_string[8+i] = ch; 417 i++; 418 } 419 } 420 i = 0; 421 sc_i = 0; 422 while (i!= name_len) 423 { 424 ch = to_upper(string[i]); 425 ch = illegal_short(ch); 426 if (ch != '.') sfn_string[sc_i++] = ch; 427 i++; 428 } 429 return 1; 430 } 431 432 /////////////////////////////////////////////////////////////////////// 433 // This function analyses the pathname argument, from the character 434 // defined by the *nb_read argument. 435 // It copies the found name (between '/') in the name[] buffer, 436 // and updates the nb_read argument. 437 // Return 1 if name found, Return 0 if NUL character found, 438 /////////////////////////////////////////////////////////////////////// 439 static 440 int get_name_from_path( char* pathname, 441 char* name, 442 unsigned int* nb_read ) 443 { 444 if ( pathname[*nb_read] == 0 ) return 0; 445 446 int i = (pathname[*nb_read] == '/')? (*nb_read) + 1 : *nb_read; 447 int j = 0; 709 710 711 /////////////////////////////////////////////////////////////////////////// 712 static unsigned int _get_name_from_path( char* pathname, // input 713 char* name, // output 714 unsigned int* nb_read ) // input & output 715 { 716 // skip leading "/" character 717 if ( pathname[*nb_read] == '/' ) *nb_read = *nb_read + 1; 718 719 // initialises current indexes 720 unsigned int i = *nb_read; 721 unsigned int j = 0; 448 722 449 while(pathname[i] != '/' && pathname[i] != '\0') 450 { 451 name[j] = pathname[i]; 452 j++; 453 i++; 454 } 723 while ( (pathname[i] != '/') && (pathname[i] != 0) ) 724 { 725 name[j++] = pathname[i++]; 726 if ( j > NAME_MAX_SIZE ) return 1; 727 } 728 729 // set end of string 455 730 name[j] = 0; 456 731 732 // skip trailing "/" character 457 733 if ( pathname[i] == '/' ) *nb_read += j+1; 458 734 else *nb_read += j; 459 735 460 return 1;736 return 0; 461 737 } 462 738 739 740 741 //////////////////////////////////////////////////////////////////// 742 static unsigned int _get_last_name( char* pathname, // input 743 char* name ) // output 744 { 745 unsigned int nb_read = 0; 746 while ( pathname[nb_read] != 0 ) 747 { 748 if ( _get_name_from_path( pathname, name, &nb_read ) ) return 1; 749 } 750 751 return 0; 752 } // end _get_last_name() 753 754 755 463 756 //////////////////////////////////////////////////////////////////////////////// 464 static int get_name_from_short( char* dir_entry,// input: SFN dir_entry465 char* entry_name ) // output: name757 static void _get_name_from_short( unsigned char* buffer, // input: SFN dir_entry 758 char* name ) // output: name 466 759 { 467 760 unsigned int i = 0; … … 470 763 while ( i < length ) 471 764 { 472 entry_name[i] = dir_entry[i];765 name[i] = buffer[i]; 473 766 i++; 474 767 } 475 entry_name[i] = '\0'; 476 477 return i; 768 name[i] = 0; 478 769 } 479 770 480 771 /////////////////////////////////////////////////////////////////////////////// 481 static int get_name_from_long( char *dir_entry,// input : LFN dir_entry482 char *entry_name )// output : name483 { 484 unsigned int entry_name_offset= 0;485 unsigned int dir_entry_offset= get_length(LDIR_ORD);772 static void _get_name_from_long( unsigned char* buffer, // input : LFN dir_entry 773 char* name ) // output : name 774 { 775 unsigned int name_offset = 0; 776 unsigned int buffer_offset = get_length(LDIR_ORD); 486 777 unsigned int l_name_1 = get_length(LDIR_NAME_1); 487 778 unsigned int l_name_2 = get_length(LDIR_NAME_2); … … 495 786 unsigned int eof = 0; 496 787 497 while ( ( dir_entry_offset != DIR_ENTRY_SIZE) && (!eof) )788 while ( (buffer_offset != DIR_ENTRY_SIZE) && (!eof) ) 498 789 { 499 790 while (j != l_name_1 && !eof ) 500 791 { 501 if ( ( dir_entry[dir_entry_offset] == 0x00) ||502 ( dir_entry[dir_entry_offset] == 0xFF) )792 if ( (buffer[buffer_offset] == 0x00) || 793 (buffer[buffer_offset] == 0xFF) ) 503 794 { 504 795 eof = 1; 505 796 continue; 506 797 } 507 entry_name[entry_name_offset] = dir_entry[dir_entry_offset];508 dir_entry_offset += 2;798 name[name_offset] = buffer[buffer_offset]; 799 buffer_offset += 2; 509 800 j += 2; 510 entry_name_offset++;511 } 512 513 dir_entry_offset += (l_attr + l_type + l_chksum);801 name_offset++; 802 } 803 804 buffer_offset += (l_attr + l_type + l_chksum); 514 805 j = 0; 515 806 516 807 while (j != l_name_2 && !eof ) 517 808 { 518 if ( ( dir_entry[dir_entry_offset] == 0x00) ||519 ( dir_entry[dir_entry_offset] == 0xFF) )809 if ( (buffer[buffer_offset] == 0x00) || 810 (buffer[buffer_offset] == 0xFF) ) 520 811 { 521 812 eof = 1; 522 813 continue; 523 814 } 524 entry_name[entry_name_offset] = dir_entry[dir_entry_offset];525 dir_entry_offset += 2;815 name[name_offset] = buffer[buffer_offset]; 816 buffer_offset += 2; 526 817 j += 2; 527 entry_name_offset++;528 } 529 530 dir_entry_offset += l_rsvd;818 name_offset++; 819 } 820 821 buffer_offset += l_rsvd; 531 822 j = 0; 532 823 533 824 while (j != l_name_3 && !eof ) 534 825 { 535 if ( ( dir_entry[dir_entry_offset] == 0x00) ||536 ( dir_entry[dir_entry_offset] == 0xFF) )826 if ( (buffer[buffer_offset] == 0x00) || 827 (buffer[buffer_offset] == 0xFF) ) 537 828 { 538 829 eof = 1; 539 830 continue; 540 831 } 541 entry_name[entry_name_offset] = dir_entry[dir_entry_offset];542 dir_entry_offset += 2;832 name[name_offset] = buffer[buffer_offset]; 833 buffer_offset += 2; 543 834 j += 2; 544 entry_name_offset++; 545 } 546 } 547 entry_name[entry_name_offset] = '\0'; 548 549 return entry_name_offset; 835 name_offset++; 836 } 837 } 838 name[name_offset] = 0; 550 839 } // end get_name_from_long() 551 840 552 /////////////////////////////////////////////////////////////////////////////////// 553 // This function update a DIR_ENTRY, write a new value into a specific field 554 // (ex : DIR_FILE_SIZE, when we want update the file size after a fat_write) 555 // Return 0 in case of success, > 0 if failure. 556 /////////////////////////////////////////////////////////////////////////////////// 557 // TODO : make this function less complex 558 /////////////////////////////////////////////////////////////////////////////////// 559 static inline 560 unsigned int _update_entry( unsigned int use_irq, 561 unsigned int fd_id, 562 unsigned int field, 563 unsigned int size, 564 unsigned int value ) 565 { 566 char dir_entry[32]; // buffer to store a full directory_entry 567 char name_entry[14]; // buffer to store a 13 characters (partial) name 568 char file_name[256]; // buffer to store the name (not pathname) of the file 569 570 char sfn_string[12] = {[0 ... 10] = ' ', '\0'}; // buffer Short File Name 571 unsigned int lba = _fat.fd[fd_id].lba_dir_entry; // Lba of file dir_entry 572 unsigned int is_sfn; 573 unsigned int attr = 0; // dir entry attribute 574 unsigned int ord = 0; // dir entry sequence 575 unsigned int found = 0; // name found 576 unsigned int offset = 0; // offset in fat_cache 577 unsigned int i = 0; 578 unsigned int nb_read = 0; 579 580 for ( i = 0 ; i < 32 ; i++ ) dir_entry[i] = 0; 581 for ( i = 0 ; i < 14 ; i++ ) name_entry[i] = 0; 582 583 // Get the name of the file. 584 while ( get_name_from_path( _fat.fd[fd_id].name, file_name, &nb_read ) ) 585 { 586 } 587 588 // Format file_name to SFN format 589 is_sfn = is_short( file_name, sfn_string ); 590 591 // access FAT 592 if ( _fat_ioc_access( use_irq, 593 1, // read 594 lba, 595 (unsigned int)_fat.fat_cache, 596 1 ) ) // one sector 597 { 598 _printf("\n[FAT ERROR] in _update_entry() cannot read sector %x\n", 599 lba ); 600 return 1; 601 } 602 _fat.cache_lba = lba; 603 604 // - the offset increment is an integer number of directory entry (32 bytes) 605 // - the exit condition is success (name found) or failure (end of directory) 606 while ( !found ) 607 { 608 attr = _read_entry( DIR_ATTR, _fat.fat_cache + offset, 0 ); 609 ord = _read_entry( LDIR_ORD, _fat.fat_cache + offset, 0 ); 610 611 if ( is_sfn == 1 ) // searched name is short 612 { 613 if ( (ord != FREE_ENTRY ) && 614 (ord != NO_MORE_ENTRY) && 615 (attr == ATTR_LONG_NAME_MASK) ) // LFN entry : skipped 841 842 843 844 //////////////////////////////////////////////////////////// 845 static fat_inode_t* _allocate_one_inode( char* name, 846 unsigned int is_dir, 847 unsigned int cluster, 848 unsigned int size, 849 unsigned int count, 850 unsigned int dentry, 851 unsigned int cache_allocate ) 852 { 853 fat_inode_t* new_inode = _malloc( sizeof(fat_inode_t) ); 854 855 new_inode->parent = NULL; // set by _add_inode_in_tree() 856 new_inode->next = NULL; // set by _add_inode_in_tree() 857 new_inode->child = NULL; // set by _add_inode_in_tree() 858 new_inode->cluster = cluster; 859 new_inode->size = size; 860 new_inode->cache = NULL; 861 new_inode->levels = 0; 862 new_inode->count = count; 863 new_inode->is_dir = (is_dir != 0); 864 new_inode->dentry = dentry; 865 866 _strcpy( new_inode->name , name ); 867 868 if ( cache_allocate ) 869 { 870 fat_cache_node_t* new_cache = _malloc( sizeof(fat_cache_node_t) ); 871 872 new_inode->cache = new_cache; 873 new_inode->levels = _get_levels_from_size( size ); 874 875 unsigned int index; 876 for ( index = 0 ; index < 64 ; index ++ ) new_cache->children[index] = NULL; 877 } 878 879 return new_inode; 880 } // end _allocate_one_inode() 881 882 883 884 885 //////////////////////////////////////////////////// 886 static void _add_inode_in_tree( fat_inode_t* child, 887 fat_inode_t* parent ) 888 { 889 child->parent = parent; 890 child->next = parent->child; 891 parent->child = child; 892 } // end _add_inode-in_tree() 893 894 895 896 897 ////////////////////////////////////////////////////////// 898 static void _remove_inode_from_tree( fat_inode_t* inode ) 899 { 900 fat_inode_t* current; 901 fat_inode_t* prev = inode->parent->child; 902 903 if ( inode == prev ) // removed inode is first in its linked list 904 { 905 inode->parent->child = inode->next; 906 } 907 else // removed inode is not the first 908 { 909 for( current = prev->next ; current ; current = current->next ) 910 { 911 if ( current == inode ) 616 912 { 617 offset = offset + ((ord & 0xF) * DIR_ENTRY_SIZE); 618 continue; 913 prev->next = current->next; 619 914 } 620 else if ( (attr != ATTR_LONG_NAME_MASK) && 621 (ord != FREE_ENTRY) && 622 (ord != NO_MORE_ENTRY ) ) // SFN entry : checked 915 prev = current; 916 } 917 } 918 } // end _delete_one_inode() 919 920 921 922 923 ////////////////////////////////////////////////////////////////////// 924 static unsigned int _get_buffer_from_cache( fat_inode_t* inode, 925 unsigned int cluster_id, 926 fat_cache_desc_t** desc ) 927 { 928 // get cache pointer and levels 929 fat_cache_node_t* node; // pointer on a 64-tree node 930 unsigned int level; // cache level 931 932 if ( inode == NULL ) // searched cache is the Fat-Cache 933 { 934 node = _fat.fat_cache_root; 935 level = _fat.fat_cache_levels; 936 937 #if (GIET_DEBUG_FAT & 1) 938 if ( _get_proctime() > GIET_DEBUG_FAT ) 939 _printf("\n[DEBUG FAT] _get_buffer_from_cache() : enters in FAT-Cache" 940 " for cluster_id = %d\n", cluster_id ); 941 #endif 942 943 } 944 else // searched cache is a File-Cache 945 { 946 node = inode->cache; 947 level = inode->levels; 948 949 #if (GIET_DEBUG_FAT & 1) 950 if ( _get_proctime() > GIET_DEBUG_FAT ) 951 _printf("\n[DEBUG FAT] _get_buffer_from_cache() : enters in File-Cache <%s>" 952 " for cluster_id = %d\n", inode->name , cluster_id ); 953 #endif 954 955 } 956 957 // search the 64-tree cache from top to bottom 958 while ( level ) 959 { 960 // compute child index at each level 961 unsigned int index = (cluster_id >> (6*(level-1))) & 0x3F; 962 963 if ( level == 1 ) // last level => children are cluster descriptors 964 { 965 fat_cache_desc_t* pdesc = (fat_cache_desc_t*)node->children[index]; 966 967 if ( pdesc == NULL ) // miss 623 968 { 624 memcpy( dir_entry, _fat.fat_cache + offset, DIR_ENTRY_SIZE ); 969 // allocate one cluster descriptor and one 4K buffer 970 unsigned char* buf = _malloc( 4096 ); 971 pdesc = _malloc( sizeof(fat_cache_desc_t) ); 972 973 // get missing cluster index lba 974 unsigned int lba; 975 unsigned int next; 976 unsigned int current = inode->cluster; 977 unsigned int count = cluster_id; 978 979 if ( inode == NULL ) // searched cache is the Fat-Cache 980 { 981 982 #if (GIET_DEBUG_FAT & 1) 983 if ( _get_proctime() > GIET_DEBUG_FAT ) 984 _printf("\n[DEBUG FAT] _get_buffer_from_cache() : miss in FAT-Cache for cluster_id %d\n", 985 cluster_id ); 986 #endif 987 lba = _fat.fat_lba + (cluster_id << 3); 988 } 989 else // searched cache is a File-Cache 990 { 991 992 #if (GIET_DEBUG_FAT & 1) 993 if ( _get_proctime() > GIET_DEBUG_FAT ) 994 _printf("\n[DEBUG FAT] _get_buffer_from_cache() : miss in File-Cache <%s> " 995 "for cluster_id %d\n", inode->name, cluster_id ); 996 #endif 997 while ( count ) 998 { 999 if ( _get_fat_entry( current , &next ) ) return 1; 1000 current = next; 1001 count--; 1002 } 1003 lba = _cluster_to_lba( current ); 1004 } 1005 1006 // load one cluster (8 blocks) from block device 1007 if ( _fat_ioc_access( 1, // descheduling 1008 1, // to memory 1009 lba, 1010 (unsigned int)buf, 1011 8 ) ) 1012 { 1013 _printf("\n[FAT ERROR] in _get_buffer_from_cache()" 1014 " : cannot access block device for lba = %x\n", lba ); 1015 return 1; 1016 } 1017 1018 // update cache and buffer descriptor 1019 node->children[index] = pdesc; 1020 pdesc->lba = lba; 1021 pdesc->buffer = buf; 1022 pdesc->dirty = 0; 1023 1024 #if (GIET_DEBUG_FAT & 1) 1025 if ( _get_proctime() > GIET_DEBUG_FAT ) 1026 _printf("\n[DEBUG FAT] _get_buffer_from_cache() : buffer loaded from device" 1027 " at vaddr = %x\n", (unsigned int)buf ); 1028 #endif 625 1029 } 626 else if (ord == NO_MORE_ENTRY ) // end of directory : return 1030 1031 // return pdesc pointer 1032 *desc = pdesc; 1033 1034 // prepare next iteration 1035 level--; 1036 } 1037 else // not last level => children are 64-tree nodes 1038 { 1039 fat_cache_node_t* child = (fat_cache_node_t*)node->children[index]; 1040 if ( child == NULL ) // miss 627 1041 { 628 _printf("\n[FAT ERROR] in _update_entry() : reaches end\n"); 629 return 1; 1042 // allocate a cache node if miss 1043 child = (fat_cache_node_t*)_malloc( sizeof(fat_cache_node_t) ); 1044 node->children[index] = child; 630 1045 } 631 else // free entry : skipped 632 { 633 offset = offset + DIR_ENTRY_SIZE; 634 continue; 635 } 636 } 637 else // searched name is long 638 { 639 if ( (attr == ATTR_LONG_NAME_MASK) && 640 (ord != FREE_ENTRY) && 641 (ord != NO_MORE_ENTRY) ) // LFN entry : checked 642 { 643 memcpy( dir_entry, _fat.fat_cache + offset, DIR_ENTRY_SIZE ); 644 } 645 else if ( (attr != ATTR_LONG_NAME_MASK) && 646 (ord != FREE_ENTRY) && 647 (ord != NO_MORE_ENTRY)) // SFN entry : skipped 648 { 649 offset = offset + DIR_ENTRY_SIZE; 650 continue; 651 } 652 else if (ord == NO_MORE_ENTRY ) // end of directory : return 653 { 654 _printf("\n[FAT ERROR] in _update_entry() reaches end\n"); 655 return 1; 656 } 657 else // free entry : skipped 658 { 659 offset = offset + DIR_ENTRY_SIZE; 660 continue; 661 } 662 } 663 664 // testing the name extracted from dir entry 665 666 if ( is_sfn == 1 ) // searched name is short 667 { 668 get_name_from_short( dir_entry, name_entry ); 669 670 if ( _strncmp( (char*)sfn_string, (char*)name_entry, 13 ) == 0 ) 671 { 672 _write_entry(offset + field, size, _fat.fat_cache, value); 673 found = 1; 674 } 675 else // no matching : skip 676 { 677 offset = offset + DIR_ENTRY_SIZE; 678 } 679 } 680 else // searched name is long 681 { 682 get_name_from_long( dir_entry, name_entry ); 683 684 unsigned shift = ((ord & 0xf) - 1) * 13; 685 if ( _strncmp( (char*)(file_name + shift), 686 (char*)name_entry, 13 ) == 0 ) 687 { 688 if ( (ord & 0xf) == 1 ) 689 { 690 offset = offset + DIR_ENTRY_SIZE; 691 _write_entry(offset + field, size, _fat.fat_cache, value); 692 found = 1; 693 } 694 offset = offset + DIR_ENTRY_SIZE; 695 continue; 696 } 697 else // no matching : skip 698 { 699 offset = offset + ((ord & 0xf) * DIR_ENTRY_SIZE) + DIR_ENTRY_SIZE; 700 } 701 } 702 } 703 704 // write block to FAT 705 if ( _fat_ioc_access( use_irq, 706 0, // write 707 lba, 708 (unsigned int)_fat.fat_cache, 709 1 ) ) // one sector 710 { 711 _printf("\n[FAT ERROR] in _update_entry() cannot write sector %x\n", 712 lba ); 713 return 1; 714 } 1046 1047 // prepare next iteration 1048 node = child; 1049 level--; 1050 } 1051 } // end while 715 1052 716 1053 return 0; 717 } // end _update_entry() 718 719 720 ////////////////////////////////////////////////////////////////////////////////// 721 // This function update the FS_INFO block: 722 // last cluster allocated and number of free cluster. 723 // Return 0 in case of success, > 0 if failure. 724 ////////////////////////////////////////////////////////////////////////////////// 725 static inline 726 unsigned int _update_fs_info( unsigned int use_irq ) 727 { 728 unsigned int lba = _fat.fs_info_lba; 729 730 #if GIET_DEBUG_FAT 731 if ( _get_proctime() > GIET_DEBUG_FAT ) 732 _printf("\n[DEBUG FAT] _update_fs_info()\n"); 733 #endif 734 735 // update FAT cache in case of miss 736 if ( lba != _fat.cache_lba ) 737 { 738 if ( _fat_ioc_access( use_irq, 1054 } // end _get_buffer_from_cache() 1055 1056 1057 1058 1059 ///////////////////////////////////// 1060 static unsigned int _update_fs_info() 1061 { 1062 // update buffer if miss 1063 if ( _fat.fs_info_lba != _fat.block_buffer_lba ) 1064 { 1065 if ( _fat_ioc_access( 1, // descheduling 739 1066 1, // read 740 lba,741 (unsigned int)_fat. fat_cache,742 1 ) ) // one sector1067 _fat.fs_info_lba, 1068 (unsigned int)_fat.block_buffer, 1069 1 ) ) // one block 743 1070 { 744 1071 _printf("\n[FAT_ERROR] in _update_fs_info() cannot read block\n"); 745 1072 return 1; 746 1073 } 747 _fat.cache_lba = lba; 748 } 749 750 _write_entry( FS_FREE_CLUSTER , _fat.fat_cache, _fat.number_free_cluster ); 751 _write_entry( FS_FREE_CLUSTER_HINT, _fat.fat_cache, _fat.last_cluster_allocated ); 1074 _fat.block_buffer_lba = _fat.fs_info_lba; 1075 } 1076 1077 // update FAT buffer 1078 unsigned int* ptr; 1079 ptr = (unsigned int*)(_fat.block_buffer + get_offset(FS_FREE_CLUSTERS) ); 1080 *ptr = _fat.free_clusters_number; 1081 1082 ptr = (unsigned int*)(_fat.block_buffer + get_offset(FS_FREE_CLUSTER_HINT) ); 1083 *ptr = _fat.first_free_cluster; 752 1084 753 1085 // write bloc to FAT 754 if ( _fat_ioc_access( use_irq,1086 if ( _fat_ioc_access( 1, // descheduling 755 1087 0, // write 756 lba,757 (unsigned int)_fat. fat_cache,758 1 ) ) // one sector1088 _fat.fs_info_lba, 1089 (unsigned int)_fat.block_buffer, 1090 1 ) ) // one block 759 1091 { 760 1092 _printf("\n[FAT_ERROR] in _update_fs_info() cannot write block\n"); … … 762 1094 } 763 1095 1096 #if (GIET_DEBUG_FAT & 1) 1097 if ( _get_proctime() > GIET_DEBUG_FAT ) 1098 _printf("\n[DEBUG FAT] _update_fs_info() : nb_free = %x / first_free = %x\n", 1099 _fat.free_clusters_number , _fat.first_free_cluster ); 1100 #endif 1101 764 1102 return 0; 765 1103 } // end _update_fs_info() 766 1104 767 ////////////////////////////////////////////////////////////////////////////////// 768 // This function update FAT, write a new value into cluster index. 769 // Used by the function _fat_allocate to update the chaining of clusters. 770 // Return 0 in case of success, > 0 if failure. 771 ////////////////////////////////////////////////////////////////////////////////// 772 static inline 773 unsigned int _update_fat( unsigned int use_irq, 774 unsigned int cluster, 775 unsigned int value ) 776 { 777 unsigned int lba = _fat.fat_lba + (cluster / 128); 1105 1106 1107 ///////////////////////////////////////////////////////////////// 1108 static inline unsigned int _get_fat_entry( unsigned int cluster, 1109 unsigned int* value ) 1110 { 1111 // compute cluster_id & entry_id in FAT 1112 // a FAT cluster is an array of 1024 unsigned int entries 1113 unsigned int cluster_id = cluster >> 10; 1114 unsigned int entry_id = cluster & 0x3FF; 1115 1116 // get pointer on the relevant cluster descriptor in FAT cache 1117 fat_cache_desc_t* pdesc; 1118 unsigned int* buffer; 1119 if ( _get_buffer_from_cache( NULL, // Fat-Cache 1120 cluster_id, 1121 &pdesc ) ) return 1; 1122 1123 // get value from FAT slot 1124 buffer = (unsigned int*)pdesc->buffer; 1125 *value = buffer[entry_id]; 1126 1127 return 0; 1128 } // end _get_fat_entry() 1129 1130 1131 1132 //////////////////////////////////////////////////////////////// 1133 static inline unsigned int _set_fat_entry( unsigned int cluster, 1134 unsigned int value ) 1135 { 1136 // compute cluster_id & entry_id in FAT 1137 // a FAT cluster is an array of 1024 unsigned int entries 1138 unsigned int cluster_id = cluster >> 10; 1139 unsigned int entry_id = cluster & 0x3FF; 1140 1141 // get pointer on the relevant cluster descriptor in FAT cache 1142 fat_cache_desc_t* pdesc; 1143 unsigned int* buffer; 1144 if ( _get_buffer_from_cache( NULL, // Fat-Cache 1145 cluster_id, 1146 &pdesc ) ) return 1; 1147 1148 // set value into FAT slot 1149 buffer = (unsigned int*)pdesc->buffer; 1150 buffer[entry_id] = value; 1151 pdesc->dirty = 1; 1152 1153 return 0; 1154 } // end _set_fat_entry() 1155 1156 1157 1158 ////////////////////////////////////////////////////// 1159 static void _allocate_one_buffer( fat_inode_t* inode, 1160 unsigned int cluster_id, 1161 unsigned int cluster ) 1162 { 1163 // search the 64-tree cache from top to bottom 1164 fat_cache_node_t* node = inode->cache; 1165 unsigned int level = inode->levels; 1166 1167 while ( level ) 1168 { 1169 // compute child index 1170 unsigned int index = (cluster_id >> (6*(level-1))) & 0x3F; 1171 1172 if ( level == 1 ) // last level => children are cluster descriptors 1173 { 1174 fat_cache_desc_t* pdesc = (fat_cache_desc_t*)node->children[index]; 1175 if ( pdesc != NULL ) // slot not empty!!! 1176 { 1177 _printf("\n[FAT ERROR] in allocate_one buffer() : slot not empty " 1178 "in File-Cache <%s> / cluster_id = %d\n", inode->name , cluster_id ); 1179 _exit(); 1180 } 1181 1182 // allocate a cluster descriptor and a 4K buffer 1183 pdesc = _malloc( sizeof(fat_cache_desc_t) ); 1184 unsigned char* buffer = _malloc( 4096 ); 1185 1186 #if (GIET_DEBUG_FAT & 1) 1187 if ( _get_proctime() > GIET_DEBUG_FAT ) 1188 _printf("\n[DEBUG FAT] _allocate_one_buffer() : buffer allocated to <%s> for cluster_id %d\n", 1189 inode->name, cluster_id ); 1190 #endif 1191 1192 // update cache and pdesc 1193 node->children[index] = pdesc; 1194 pdesc->lba = _cluster_to_lba( cluster ); 1195 pdesc->buffer = buffer; 1196 pdesc->dirty = 1; 1197 1198 // prepare next iteration 1199 level--; 1200 } 1201 else // not last level => children are 64-tree nodes 1202 { 1203 fat_cache_node_t* child = (fat_cache_node_t*)node->children[index]; 1204 if ( child == NULL ) // miss 1205 { 1206 // allocate a cache node if miss 1207 child = (fat_cache_node_t*)_malloc( sizeof(fat_cache_node_t) ); 1208 node->children[index] = child; 1209 } 1210 1211 // prepare next iteration 1212 node = child; 1213 level--; 1214 } 1215 } // end while 1216 } // end _allocate_one_buffer 1217 1218 1219 1220 1221 /////////////////////////////////////////////////////////////////// 1222 static unsigned int _allocate_one_cluster( unsigned int* cluster ) 1223 { 1224 unsigned int nb_free = _fat.free_clusters_number; 1225 unsigned int free = _fat.first_free_cluster; 1226 1227 // scan FAT to get next free cluster index 1228 unsigned int current = free; 1229 unsigned int found = 0; 1230 unsigned int max = (_fat.data_sectors >> 3); 1231 unsigned int value; 1232 do 1233 { 1234 // increment current 1235 current++; 1236 1237 // get FAT entry indexed by current 1238 if ( _get_fat_entry( current , &value ) ) return 1; 1239 // test if free 1240 if ( value == FREE_CLUSTER ) found = 1; 1241 } 1242 while ( (current < max) && (found == 0) ); 1243 1244 // check found 1245 if ( found == 0 ) 1246 { 1247 _printf("\n[FAT_ERROR] in _allocate_one_cluster() : unconsistent FAT state"); 1248 return 1; 1249 } 1250 1251 // update allocated FAT slot 1252 if ( _set_fat_entry( free , END_OF_CHAIN_CLUSTER_MAX ) ) return 1; 1253 1254 // update FAT descriptor global variables 1255 _fat.free_clusters_number = nb_free - 1; 1256 _fat.first_free_cluster = current; 1257 1258 #if (GIET_DEBUG_FAT & 1) 1259 if ( _get_proctime() > GIET_DEBUG_FAT ) 1260 _printf("\n[DEBUG FAT] _allocate_one_cluster() : cluster = %x / first_free = %x\n", 1261 free , current ); 1262 #endif 1263 1264 // returns free cluster index 1265 *cluster = free; 1266 return 0; 1267 1268 } // end _allocate_one_cluster() 1269 1270 1271 1272 1273 ////////////////////////////////////////////////////////////////////////// 1274 static unsigned int _update_device_from_cache( unsigned int levels, 1275 fat_cache_node_t* root, 1276 char* string ) 1277 { 1278 unsigned int index; 1279 unsigned int ret = 0; 1280 1281 if ( levels == 1 ) // last level => children are cluster descriptors 1282 { 1283 for( index = 0 ; index < 64 ; index++ ) 1284 { 1285 fat_cache_desc_t* pdesc = root->children[index]; 1286 if ( pdesc != NULL ) 1287 { 1288 // update cluster on device if dirty 1289 if ( pdesc->dirty ) 1290 { 1291 if ( _fat_ioc_access( 1, // descheduling 1292 0, // to block device 1293 pdesc->lba, 1294 (unsigned int)pdesc->buffer, 1295 8 ) ) 1296 { 1297 _printf("\n[FAT_ERROR] in _update_device from_cache() : " 1298 " cannot access lba = %x\n", pdesc->lba ); 1299 ret = 1; 1300 } 1301 else 1302 { 1303 pdesc->dirty = 0; 1304 1305 #if (GIET_DEBUG_FAT & 1) 1306 if ( _get_proctime() > GIET_DEBUG_FAT ) 1307 _printf("\n[DEBUG FAT] _update_device_from_cache() : cluster_id = %d for <%s>\n", 1308 index , string ); 1309 #endif 1310 1311 } 1312 } 1313 } 1314 } 1315 } 1316 else // not the last level = recursive call on each children 1317 { 1318 for( index = 0 ; index < 64 ; index++ ) 1319 { 1320 fat_cache_node_t* pnode = root->children[index]; 1321 if ( pnode != NULL ) 1322 { 1323 if ( _update_device_from_cache( levels - 1, 1324 root->children[index], 1325 string ) ) ret = 1; 1326 } 1327 } 1328 } 1329 return ret; 1330 } // end _update_device_from_cache() 1331 1332 1333 1334 /////////////////////////////////////////////////////////////////// 1335 static unsigned int _release_cache_memory( fat_cache_node_t* root, 1336 unsigned int levels ) 1337 { 1338 unsigned int index; 1339 unsigned int ret = 0; 1340 1341 if ( levels == 1 ) // last level => children are cluster descriptors 1342 { 1343 for( index = 0 ; index < 64 ; index++ ) 1344 { 1345 fat_cache_desc_t* pdesc = root->children[index]; 1346 1347 if ( pdesc != NULL ) 1348 { 1349 // check dirty 1350 if ( pdesc->dirty ) 1351 { 1352 _printf("\n[FAT_ERROR] in _release_cache_memory() : dirty cluster\n"); 1353 ret = 1; 1354 } 1355 else 1356 { 1357 _free( pdesc->buffer ); 1358 _free( pdesc ); 1359 root->children[index] = NULL; 1360 } 1361 } 1362 } 1363 } 1364 else // not the last level = recursive call on each children 1365 { 1366 for( index = 0 ; index < 64 ; index++ ) 1367 { 1368 fat_cache_node_t* cnode = root->children[index]; 1369 1370 if ( cnode != NULL ) ret = _release_cache_memory( root->children[index], 1371 levels - 1 ); 1372 } 1373 } 1374 return ret; 1375 } // end _release_cache_memory() 1376 1377 1378 1379 1380 1381 ///////////////////////////////////////////////////////////// 1382 static unsigned int _clusters_allocate( fat_inode_t* inode, 1383 unsigned int nb_current_clusters, 1384 unsigned int nb_required_clusters ) 1385 { 1386 // Check if FAT contains enough free clusters 1387 if ( nb_required_clusters > _fat.free_clusters_number ) 1388 { 1389 _printf("\n[FAT ERROR] in _clusters_allocate() : required_clusters = %d" 1390 " / free_clusters = %d\n", nb_required_clusters , _fat.free_clusters_number ); 1391 return 1; 1392 } 1393 1394 #if (GIET_DEBUG_FAT & 1) 1395 if ( _get_proctime() > GIET_DEBUG_FAT ) 1396 _printf("\n[DEBUG FAT] _clusters_allocate() : enters for <%s> / nb_current_clusters = %d " 1397 "/ nb_required_clusters = %d\n", 1398 inode->name , nb_current_clusters , nb_required_clusters ); 1399 #endif 1400 1401 // compute last allocated cluster index when (nb_current_clusters > 0) 1402 unsigned int current = inode->cluster; 1403 unsigned int next; 1404 unsigned int last; 1405 if ( nb_current_clusters ) // clusters allocated => search last 1406 { 1407 while ( current < END_OF_CHAIN_CLUSTER_MIN ) 1408 { 1409 // get next cluster 1410 if ( _get_fat_entry( current , &next ) ) return 1; 1411 last = current; 1412 current = next; 1413 } 1414 } 1415 1416 // Loop on the new clusters to be allocated 1417 // if (nb_current_clusters == 0) the first new cluster index must 1418 // be written in inode->cluster field 1419 // if (nb_current_clusters > 0) the first new cluster index must 1420 // be written in FAT[last] 1421 unsigned int cluster_id; 1422 unsigned int new; 1423 for ( cluster_id = nb_current_clusters ; 1424 cluster_id < (nb_current_clusters + nb_required_clusters) ; 1425 cluster_id ++ ) 1426 { 1427 // allocate one cluster on block device 1428 if ( _allocate_one_cluster( &new ) ) return 1; 1429 1430 // allocate one 4K buffer to File-Cache 1431 _allocate_one_buffer( inode, 1432 cluster_id, 1433 new ); 1434 1435 if ( cluster_id == 0 ) // update inode 1436 { 1437 inode->cluster = new; 1438 } 1439 else // update FAT 1440 { 1441 if ( _set_fat_entry( last , new ) ) return 1; 1442 } 1443 1444 #if (GIET_DEBUG_FAT & 1) 1445 if ( _get_proctime() > GIET_DEBUG_FAT ) 1446 _printf("\n[DEBUG FAT] _clusters_allocate() : done for cluster_id = %d / cluster = %x\n", 1447 cluster_id , new ); 1448 #endif 1449 1450 // update loop variables 1451 last = new; 1452 1453 } // end for loop 1454 1455 // update FAT : last slot should contain END_OF_CHAIN_CLUSTER_MAX 1456 if ( _set_fat_entry( last , END_OF_CHAIN_CLUSTER_MAX ) ) return 1; 1457 1458 // update the FAT on block device 1459 if ( _update_device_from_cache( _fat.fat_cache_levels, 1460 _fat.fat_cache_root, 1461 "FAT" ) ) return 1; 1462 return 0; 1463 } // end _clusters_allocate() 1464 1465 1466 1467 ////////////////////////////////////////////////////////////// 1468 static unsigned int _clusters_release( unsigned int cluster ) 1469 { 1470 // scan the FAT 1471 unsigned int current = cluster; 1472 unsigned int next; 1473 do 1474 { 1475 // get next_cluster index 1476 if ( _get_fat_entry( current , &next ) ) return 1; 1477 1478 // release current_cluster 1479 if ( _set_fat_entry( current , FREE_CLUSTER ) ) return 1; 1480 1481 // update first_free_cluster and free_clusters_number in FAT descriptor 1482 _fat.free_clusters_number = _fat.free_clusters_number + 1; 1483 if ( _fat.first_free_cluster > current ) _fat.first_free_cluster = current; 1484 1485 // update loop variable 1486 current = next; 1487 } 1488 while ( next < END_OF_CHAIN_CLUSTER_MIN ); 1489 1490 // update the FAT on block device 1491 if ( _update_device_from_cache( _fat.fat_cache_levels, 1492 _fat.fat_cache_root, 1493 "FAT" ) ) return 1; 1494 return 0; 1495 } // end _clusters_release() 1496 1497 1498 1499 /////////////////////////////////////////////////////////// 1500 static void _add_special_directories( fat_inode_t* child, 1501 fat_inode_t* parent ) 1502 { 1503 // get first File-Cache buffer for child 1504 fat_cache_desc_t* pdesc = (fat_cache_desc_t*)child->cache->children[0]; 1505 unsigned char* entry; 1506 1507 unsigned int i; 1508 unsigned int cluster; 1509 unsigned int size; 1510 1511 // set "." entry (32 bytes) 1512 cluster = child->cluster; 1513 size = child->size; 1514 entry = pdesc->buffer; 1515 1516 for ( i = 0 ; i < 32 ; i++ ) 1517 { 1518 if (i == 0 ) entry[i] = 0x2E; // SFN 1519 else if (i < 11) entry[i] = 0x20; // SFN 1520 else if (i == 11) entry[i] = 0x10; // ATTR == dir 1521 else if (i == 20) entry[i] = cluster>>16; // cluster.B2 1522 else if (i == 21) entry[i] = cluster>>24; // cluster.B3 1523 else if (i == 26) entry[i] = cluster>>0; // cluster.B0 1524 else if (i == 27) entry[i] = cluster>>8; // cluster.B1 1525 else if (i == 28) entry[i] = size>>0; // size.B0 1526 else if (i == 29) entry[i] = size>>8; // size.B1 1527 else if (i == 30) entry[i] = size>>16; // size.B2 1528 else if (i == 31) entry[i] = size>>24; // size.B3 1529 else entry[i] = 0x00; 1530 } 1531 1532 // set ".." entry (32 bytes) 1533 cluster = parent->cluster; 1534 size = parent->size; 1535 entry = pdesc->buffer + 32; 1536 1537 for ( i = 0 ; i < 32 ; i++ ) 1538 { 1539 if (i < 2 ) entry[i] = 0x2E; // SFN 1540 else if (i < 11) entry[i] = 0x20; // SFN 1541 else if (i == 11) entry[i] = 0x10; // ATTR == dir 1542 else if (i == 20) entry[i] = cluster>>16; // cluster.B2 1543 else if (i == 21) entry[i] = cluster>>24; // cluster.B3 1544 else if (i == 26) entry[i] = cluster>>0; // cluster.B0 1545 else if (i == 27) entry[i] = cluster>>8; // cluster.B1 1546 else if (i == 28) entry[i] = size>>0; // size.B0 1547 else if (i == 29) entry[i] = size>>8; // size.B1 1548 else if (i == 30) entry[i] = size>>16; // size.B2 1549 else if (i == 31) entry[i] = size>>24; // size.B3 1550 else entry[i] = 0x00; 1551 } 1552 } // end _add_special_directories 1553 1554 1555 1556 //////////////////////////////////////////////////////////// 1557 static unsigned int _check_name_length( char* name, 1558 unsigned int* length, 1559 unsigned int* nb_lfn ) 1560 { 1561 unsigned int len = _strlen( name ); 1562 if ( len <= 13 ) 1563 { 1564 *length = len; 1565 *nb_lfn = 1; 1566 return 0; 1567 } 1568 else if ( len <= 26 ) 1569 { 1570 *length = len; 1571 *nb_lfn = 2; 1572 return 0; 1573 } 1574 else if ( len <= 31 ) 1575 { 1576 *length = len; 1577 *nb_lfn = 3; 1578 return 0; 1579 } 1580 else 1581 { 1582 return 1; 1583 } 1584 } // _check_name_length() 1585 1586 1587 1588 1589 /////////////////////////////////////////////////////////// 1590 static unsigned int _get_nb_entries( fat_inode_t* inode, 1591 unsigned int* nb_entries ) 1592 { 1593 // scan directory until "end of directory" with two embedded loops: 1594 // - scan the clusters allocated to this directory 1595 // - scan the entries to find NO_MORE_ENTRY 1596 fat_cache_desc_t* pdesc; // pointer on buffer descriptor 1597 unsigned char* buffer; // 4 Kbytes buffer (one cluster) 1598 unsigned int ord; // ORD field in directory entry 1599 unsigned int attr; // ATTR field in directory entry 1600 unsigned int cluster_id = 0; // cluster index in directory 1601 unsigned int offset = 0; // position in scanned buffer 1602 unsigned int found = 0; // NO_MORE_ENTRY found 1603 unsigned int count = 0; // number of valid NORMAL entries 1604 1605 // loop on clusters allocated to directory 1606 while ( found == 0 ) 1607 { 1608 // get one 4 Kytes buffer from File_Cache 1609 if ( _get_buffer_from_cache( inode, 1610 cluster_id, 1611 &pdesc ) ) return 1; 1612 1613 buffer = pdesc->buffer; 1614 1615 // loop on directory entries in buffer 1616 while ( (offset < 4096) && (found == 0) ) 1617 { 1618 attr = _read_entry( DIR_ATTR , buffer + offset , 0 ); 1619 ord = _read_entry( LDIR_ORD , buffer + offset , 0 ); 1620 1621 if ( ord == NO_MORE_ENTRY ) 1622 { 1623 found = 1; 1624 } 1625 else if ( ord == FREE_ENTRY ) // free entry => skip 1626 { 1627 offset = offset + 32; 1628 } 1629 else if ( attr == ATTR_LONG_NAME_MASK ) // LFN entry => skip 1630 { 1631 offset = offset + 32; 1632 } 1633 else // NORMAL entry 1634 { 1635 count++; 1636 } 1637 1638 offset = offset + 32; 1639 1640 } // end loop on directory entries 1641 1642 cluster_id++; 1643 offset = 0; 1644 1645 } // end loop on clusters 1646 1647 // return nb_entries 1648 *nb_entries = count; 1649 1650 return 0; 1651 } // end dir_not_empty() 1652 1653 1654 1655 /////////////////////////////////////////////////////////// 1656 static unsigned int _add_dir_entry( fat_inode_t* child, 1657 fat_inode_t* parent ) 1658 { 1659 // get child attributes 1660 unsigned int is_dir = child->is_dir; 1661 unsigned int size = child->size; 1662 unsigned int cluster = child->cluster; 1663 1664 // compute number of required entries to store child->name 1665 // - Short name (less than 13 characters) require 3 entries: 1666 // one LFN entry / one NORMAL entry / one NO_MORE_ENTRY entry. 1667 // - Longer names (up to 31 characters) can require 4 or 5 entries: 1668 // 2 or 3 LFN entries / one NORMAL entry / one NO_MORE entry. 1669 unsigned int length; 1670 unsigned int nb_lfn; 1671 if ( _check_name_length( child->name, 1672 &length, 1673 &nb_lfn ) ) return 1; 1674 1675 #if (GIET_DEBUG_FAT & 1) 1676 if ( _get_proctime() > GIET_DEBUG_FAT ) 1677 _printf("\n[DEBUG FAT] _add_dir_entry() : try to add <%s> in <%s> / nb_lfn = %d\n", 1678 child->name , parent->name, nb_lfn ); 1679 #endif 1680 1681 // Find end of directory : two embedded loops: 1682 // - scan the clusters allocated to this directory 1683 // - scan the entries to find NO_MORE_ENTRY 1684 fat_cache_desc_t* pdesc; // pointer on buffer descriptor 1685 unsigned char* buffer; // 4 Kbytes buffer (one cluster) 1686 unsigned int cluster_id = 0; // cluster index in directory 1687 unsigned int offset = 0; // position in scanned buffer 1688 unsigned int found = 0; // NO_MORE_ENTRY found 1689 1690 // loop on clusters allocated to directory 1691 while ( found == 0 ) 1692 { 1693 // get one 4 Kytes buffer from File_Cache 1694 if ( _get_buffer_from_cache( parent, 1695 cluster_id, 1696 &pdesc ) ) return 1; 1697 1698 buffer = pdesc->buffer; 1699 1700 // loop on directory entries in buffer 1701 while ( (offset < 4096) && (found == 0) ) 1702 { 1703 if ( _read_entry( LDIR_ORD , buffer + offset , 0 ) == NO_MORE_ENTRY ) 1704 { 1705 found = 1; 1706 pdesc->dirty = 1; 1707 } 1708 else 1709 { 1710 offset = offset + 32; 1711 } 1712 } // end loop on entries 1713 if ( found == 0 ) 1714 { 1715 cluster_id++; 1716 offset = 0; 1717 } 1718 } // end loop on clusters 1719 1720 #if (GIET_DEBUG_FAT & 1) 1721 if ( _get_proctime() > GIET_DEBUG_FAT ) 1722 _printf("\n[DEBUG FAT] _add_dir_entry() : get NO_MORE directory entry : " 1723 " buffer = %x / offset = %x / cluster_id = %d\n", 1724 (unsigned int)buffer , offset , cluster_id ); 1725 #endif 1726 1727 // enter FSM : 1728 // The new child requires to write 3, 4, or 5 directory entries. 1729 // To actually register the new child, we use a 5 steps FSM 1730 // (one state per entry to be written), that is traversed as: 1731 // LFN3 -> LFN2 -> LFN1 -> NORMAL -> NOMORE 1732 // The buffer and first directory entry to be written are identified 1733 // by the variables : buffer / cluster_id / offset 1734 1735 unsigned char* name = (unsigned char*)child->name; 1736 1737 unsigned int step; // FSM state 1738 1739 if ( nb_lfn == 1 ) step = 3; 1740 else if ( nb_lfn == 2 ) step = 4; 1741 else if ( nb_lfn == 3 ) step = 5; 1742 1743 unsigned int i; // byte index in 32 bytes directory 1744 unsigned int c; // character index in name 1745 unsigned char* entry; // buffer + offset; 1746 1747 while ( step ) 1748 { 1749 // get another buffer if required 1750 if ( offset >= 4096 ) // new buffer required 1751 { 1752 if ( cluster_id == 63 ) // we need to increase depth of File-Cache 1753 { 1754 _printf("\n[FAT ERROR] in add_dir_entry() File Cache depth extension " 1755 " not implemented\n" ); 1756 _exit(); // TODO 1757 } 1758 else 1759 { 1760 if ( _get_buffer_from_cache( parent, 1761 cluster_id + 1, 1762 &pdesc ) ) return 1; 1763 buffer = pdesc->buffer; 1764 pdesc->dirty = 1; 1765 offset = 0; 1766 } 1767 } 1768 1769 // compute directory entry address 1770 entry = buffer + offset; 1771 1772 #if (GIET_DEBUG_FAT & 1) 1773 if ( _get_proctime() > GIET_DEBUG_FAT ) 1774 _printf("\n[DEBUG FAT] _add_dir_entry() : FSM step = %d /" 1775 " offset = %x / nb_lfn = %d\n", step, offset, nb_lfn ); 1776 #endif 1777 1778 // write one 32 bytes directory entry per iteration 1779 switch ( step ) 1780 { 1781 case 5: // write LFN3 entry 1782 { 1783 c = 26; 1784 // scan the 32 bytes in dir_entry 1785 for ( i = 0 ; i < 32 ; i++ ) 1786 { 1787 if (i == 0) 1788 { 1789 if ( nb_lfn == 3) entry[i] = 0x43; 1790 else entry[i] = 0x03; 1791 } 1792 else if ( ( ((i >= 1 ) && (i<=10) && ((i&1)==1)) || 1793 ((i >= 14) && (i<=25) && ((i&1)==0)) || 1794 ((i >= 28) && (i<=31) && ((i&1)==0)) ) && 1795 ( c < length ) ) 1796 { 1797 entry[i] = name[c]; 1798 c++; 1799 } 1800 else if (i == 11) entry[i] = 0x0F; 1801 else if (i == 12) entry[i] = 0xCA; 1802 else entry[i] = 0x00; 1803 } 1804 step--; 1805 break; 1806 } 1807 case 4: // write LFN2 entry 1808 { 1809 c = 13; 1810 // scan the 32 bytes in dir_entry 1811 for ( i = 0 ; i < 32 ; i++ ) 1812 { 1813 if (i == 0) 1814 { 1815 if ( nb_lfn == 2) entry[i] = 0x42; 1816 else entry[i] = 0x02; 1817 } 1818 else if ( ( ((i >= 1 ) && (i<=10) && ((i&1)==1)) || 1819 ((i >= 14) && (i<=25) && ((i&1)==0)) || 1820 ((i >= 28) && (i<=31) && ((i&1)==0)) ) && 1821 ( c < length ) ) 1822 { 1823 entry[i] = name[c]; 1824 c++; 1825 } 1826 else if (i == 11) entry[i] = 0x0F; 1827 else if (i == 12) entry[i] = 0xCA; 1828 else entry[i] = 0x00; 1829 } 1830 step--; 1831 break; 1832 } 1833 case 3: // Write LFN1 entry 1834 { 1835 c = 0; 1836 // scan the 32 bytes in dir_entry 1837 for ( i = 0 ; i < 32 ; i++ ) 1838 { 1839 if (i == 0) 1840 { 1841 if ( nb_lfn == 1) entry[i] = 0x41; 1842 else entry[i] = 0x01; 1843 } 1844 else if ( ( ((i >= 1 ) && (i<=10) && ((i&1)==1)) || 1845 ((i >= 14) && (i<=25) && ((i&1)==0)) || 1846 ((i >= 28) && (i<=31) && ((i&1)==0)) ) && 1847 ( c < length ) ) 1848 { 1849 entry[i] = name[c]; 1850 c++; 1851 } 1852 else if (i == 11) entry[i] = 0x0F; 1853 else if (i == 12) entry[i] = 0xCA; 1854 else entry[i] = 0x00; 1855 } 1856 step--; 1857 break; 1858 } 1859 case 2: // write NORMAL entry 1860 { 1861 c = 0; 1862 // scan the 32 bytes in dir_entry 1863 for ( i = 0 ; i < 32 ; i++ ) 1864 { 1865 if ( (i < 8) && (c < length) ) // SFN 1866 { 1867 entry[i] = _to_upper( name[c] ); 1868 c++; 1869 } 1870 else if (i < 11) entry[i] = 0x20; // EXT 1871 else if (i == 11) // ATTR 1872 { 1873 if (is_dir) entry[i] = 0x10; 1874 else entry[i] = 0x20; 1875 } 1876 else if (i == 20) entry[i] = cluster>>16; // cluster.B2 1877 else if (i == 21) entry[i] = cluster>>24; // cluster.B3 1878 else if (i == 26) entry[i] = cluster>>0; // cluster.B0 1879 else if (i == 27) entry[i] = cluster>>8; // cluster.B1 1880 else if (i == 28) entry[i] = size>>0; // size.B0 1881 else if (i == 29) entry[i] = size>>8; // size.B1 1882 else if (i == 30) entry[i] = size>>16; // size.B2 1883 else if (i == 31) entry[i] = size>>24; // size.B3 1884 else entry[i] = 0x00; 1885 } 1886 1887 // update the dentry field in child inode 1888 child->dentry = ((cluster_id<<12) + offset)>>5; 1889 1890 step--; 1891 break; 1892 } 1893 case 1: // write NOMORE entry 1894 { 1895 step--; 1896 entry [0] = 0x00; 1897 break; 1898 } 1899 } // end switch step 1900 offset += 32; 1901 } // exit while => exit FSM 1902 1903 #if (GIET_DEBUG_FAT & 1) 1904 if ( _get_proctime() > GIET_DEBUG_FAT ) 1905 { 1906 _printf("\n[DEBUG FAT] _add_dir_entry() : <%s> successfully added in <%s>\n", 1907 child->name , parent->name ); 1908 } 1909 #endif 1910 1911 return 0; 1912 } // end _add_dir_entry 1913 1914 1915 1916 //////////////////////////////////////////////////////////// 1917 static unsigned int _remove_dir_entry( fat_inode_t* inode ) 1918 { 1919 // compute number of LFN entries 1920 unsigned int length; 1921 unsigned int nb_lfn; 1922 if ( _check_name_length( inode->name, 1923 &length, 1924 &nb_lfn ) ) return 1; 1925 1926 // get cluster_id and offset in parent directory cache 1927 unsigned int dentry = inode->dentry; 1928 unsigned int cluster_id = dentry >> 7; 1929 unsigned int offset = (dentry & 0x7F)<<5; 1930 1931 // get buffer from parent directory cache 1932 unsigned char* buffer; 1933 fat_cache_desc_t* pdesc; 1934 1935 if ( _get_buffer_from_cache( inode->parent, 1936 cluster_id, 1937 &pdesc ) ) return 1; 1938 buffer = pdesc->buffer; 1939 pdesc->dirty = 1; 1940 1941 // invalidate NORMAL entry in directory cache 1942 buffer[offset] = 0xE5; 1943 1944 // invalidate LFN entries 1945 while ( nb_lfn ) 1946 { 1947 if (offset == 0) // me must load buffer for (cluster_id - 1) 1948 { 1949 if ( _get_buffer_from_cache( inode->parent, 1950 cluster_id - 1, 1951 &pdesc ) ) return 1; 1952 buffer = pdesc->buffer; 1953 pdesc->dirty = 1; 1954 offset = 4064; 1955 } 1956 else 1957 { 1958 offset = offset - 32; 1959 } 1960 1961 // invalidate LFN entry 1962 buffer[offset] = 0xE5; 1963 1964 nb_lfn--; 1965 } 1966 1967 return 0; 1968 } // end _remove_dir_entry 1969 1970 1971 1972 1973 //////////////////////////////////////////////////////////// 1974 static unsigned int _update_dir_entry( fat_inode_t* inode ) 1975 { 1976 // get Cache-File buffer containing the parent directory entry 1977 // 128 directories entries in one 4 Kbytes buffer 1978 fat_cache_desc_t* pdesc; 1979 unsigned char* buffer; 1980 unsigned int cluster_id = inode->dentry>>7; 1981 unsigned int offset = (inode->dentry & 0x3F)<<5; 1982 1983 if ( _get_buffer_from_cache( inode->parent, 1984 cluster_id, 1985 &pdesc ) ) return 1; 1986 buffer = pdesc->buffer; 1987 pdesc->dirty = 1; 1988 1989 // update size field 1990 buffer[offset + 28] = inode->size>>0; // size.B0 1991 buffer[offset + 29] = inode->size>>8; // size.B1 1992 buffer[offset + 30] = inode->size>>16; // size.B2 1993 buffer[offset + 31] = inode->size>>24; // size.B3 1994 1995 // update cluster field 1996 buffer[offset + 26] = inode->cluster>>0; // cluster.B0 1997 buffer[offset + 27] = inode->cluster>>8; // cluster.B1 1998 buffer[offset + 20] = inode->cluster>>16; // cluster.B2 1999 buffer[offset + 21] = inode->cluster>>24; // cluster.B3 2000 2001 return 0; 2002 } // end _update_dir_entry() 2003 2004 2005 2006 2007 ////////////////////////////////////////////////////////////////// 2008 static unsigned int _get_child_from_parent( fat_inode_t* parent, 2009 char* name, 2010 fat_inode_t** inode ) 2011 { 2012 fat_inode_t* current; 2013 2014 #if (GIET_DEBUG_FAT & 1) 2015 if ( _get_proctime() > GIET_DEBUG_FAT ) 2016 _printf("\n[DEBUG FAT] _get_child_from_parent() : search <%s> in directory <%s>\n", 2017 name , parent->name ); 2018 #endif 2019 2020 // compute name lenth 2021 unsigned int length = _strlen( name ); 2022 2023 // scan inodes in the parent directory 2024 for ( current = parent->child ; current ; current = current->next ) 2025 { 2026 if ( _strncmp( name , current->name , length ) == 0 ) 2027 { 2028 2029 #if (GIET_DEBUG_FAT & 1) 2030 if ( _get_proctime() > GIET_DEBUG_FAT ) 2031 _printf("\n[DEBUG FAT] _get_child_from_parent() : found inode <%s> in directory <%s>\n", 2032 name , parent->name ); 2033 #endif 2034 *inode = current; 2035 return 0; // name found 2036 } 2037 } 2038 2039 // not found in Inode-Tree => access the parent directory 2040 // file_cache. Two embedded loops: 2041 // - scan the clusters allocated to this directory 2042 // - scan the directory entries in each 4 Kbytes buffer 2043 2044 unsigned char* buffer; // pointer on one cache buffer 2045 char cname[32]; // buffer for one full entry name 2046 char lfn1[16]; // buffer for one partial name 2047 char lfn2[16]; // buffer for one partial name 2048 char lfn3[16]; // buffer for one partial name 2049 unsigned int size; // searched file/dir size (bytes) 2050 unsigned int cluster; // searched file/dir cluster index 2051 unsigned int is_dir; // searched file/dir type 2052 unsigned int attr; // directory entry ATTR field 2053 unsigned int ord; // directory entry ORD field 2054 unsigned int lfn; // LFN entries number 2055 unsigned int dentry; // directory entry index 2056 unsigned int offset = 0; // byte offset in buffer 2057 unsigned int cluster_id = 0; // cluster index in directory 2058 int found = 0; // not found (0) / name found (1) / end of dir (-1) 2059 2060 #if (GIET_DEBUG_FAT & 1) 2061 if ( _get_proctime() > GIET_DEBUG_FAT ) 2062 _printf("\n[DEBUG FAT] _get_child_from_parent() : does not found inode <%s>" 2063 " in directory <%s> => search in cache\n", name , parent->name ); 2064 #endif 2065 2066 // scan the clusters allocated to parent directory 2067 while ( found == 0 ) 2068 { 2069 // get one 4 Kytes buffer from parent File_Cache 2070 fat_cache_desc_t* pdesc; 2071 if ( _get_buffer_from_cache( parent, 2072 cluster_id, 2073 &pdesc ) ) return 2; 2074 buffer = pdesc->buffer; 2075 2076 // scan this buffer until end of directory, end of buffer, or name found 2077 while( (offset < 4096) && (found == 0) ) 2078 { 2079 2080 #if (GIET_DEBUG_FAT & 1) 2081 if ( _get_proctime() > GIET_DEBUG_FAT ) 2082 _printf("\n[DEBUG FAT] _get_child_from_parent() : scan buffer %d for <%s>\n", 2083 cluster_id , name ); 2084 #endif 2085 attr = _read_entry( DIR_ATTR , buffer + offset , 0 ); 2086 ord = _read_entry( LDIR_ORD , buffer + offset , 0 ); 2087 2088 if (ord == NO_MORE_ENTRY) // no more entry in directory => break 2089 { 2090 found = -1; 2091 } 2092 else if ( ord == FREE_ENTRY ) // free entry => skip 2093 { 2094 offset = offset + 32; 2095 } 2096 else if ( attr == ATTR_LONG_NAME_MASK ) // LFN entry => get partial name 2097 { 2098 unsigned int seq = ord & 0x3; 2099 lfn = (seq > lfn) ? seq : lfn; 2100 if ( seq == 1 ) _get_name_from_long( buffer + offset, lfn1 ); 2101 else if ( seq == 2 ) _get_name_from_long( buffer + offset, lfn2 ); 2102 else if ( seq == 3 ) _get_name_from_long( buffer + offset, lfn3 ); 2103 offset = offset + 32; 2104 } 2105 else // NORMAL entry 2106 { 2107 // build the extracted name 2108 if ( lfn == 0 ) 2109 { 2110 _get_name_from_short( buffer + offset , cname ); 2111 } 2112 else if ( lfn == 1 ) 2113 { 2114 _strcpy( cname , lfn1 ); 2115 } 2116 else if ( lfn == 2 ) 2117 { 2118 _strcpy( cname , lfn1 ); 2119 _strcpy( cname + 13 , lfn2 ); 2120 } 2121 else if ( lfn == 3 ) 2122 { 2123 _strcpy( cname , lfn1 ); 2124 _strcpy( cname + 13 , lfn2 ); 2125 _strcpy( cname + 26 , lfn3 ); 2126 } 2127 2128 // test if extracted name == searched name 2129 if ( _strncmp( name , cname , length ) == 0 ) 2130 { 2131 cluster = (_read_entry( DIR_FST_CLUS_HI , buffer + offset , 1 ) << 16) | 2132 (_read_entry( DIR_FST_CLUS_LO , buffer + offset , 1 ) ) ; 2133 dentry = ((cluster_id<<12) + offset)>>5; 2134 is_dir = ((attr & ATTR_DIRECTORY) == ATTR_DIRECTORY); 2135 size = _read_entry( DIR_FILE_SIZE , buffer + offset , 1 ); 2136 found = 1; 2137 } 2138 offset = offset + 32; 2139 lfn = 0; 2140 } 2141 } // end loop on directory entries 2142 cluster_id++; 2143 offset = 0; 2144 } // end loop on buffers 2145 2146 if ( found == -1 ) // found end of directory in parent directory 2147 { 2148 2149 #if (GIET_DEBUG_FAT & 1) 2150 if ( _get_proctime() > GIET_DEBUG_FAT ) 2151 _printf("\n[DEBUG FAT] _get_child_from_parent() : found end of directory in <%s>\n", 2152 parent->name ); 2153 #endif 2154 *inode = NULL; 2155 return 1; 2156 } 2157 else // found searched name in parent directory 2158 { 2159 // allocate a new inode and an empty Cache-File 2160 *inode = _allocate_one_inode( name, 2161 is_dir, 2162 cluster, 2163 size, 2164 0, // count 2165 dentry, 2166 1 ); // cache_allocate 2167 2168 // introduce it in Inode-Tree 2169 _add_inode_in_tree( *inode , parent ); 2170 2171 #if (GIET_DEBUG_FAT & 1) 2172 if ( _get_proctime() > GIET_DEBUG_FAT ) 2173 _printf("\n[DEBUG FAT] _get_child_from_parent() : found <%s> on device\n", name ); 2174 #endif 2175 return 0; 2176 } 2177 } // end _get_child_from_parent() 2178 2179 2180 2181 2182 ////////////////////////////////////////////////////////////////// 2183 static unsigned int _get_inode_from_path( char* pathname, 2184 fat_inode_t** inode ) 2185 { 2186 char name[32]; // buffer for one name in pathname 2187 unsigned int nb_read; // number of characters written in name[] 2188 fat_inode_t* parent; // parent inode 2189 fat_inode_t* child; // child inode 2190 unsigned int last; // while exit condition 2191 unsigned int code; // return value 2192 2193 #if (GIET_DEBUG_FAT & 1) 2194 if ( _get_proctime() > GIET_DEBUG_FAT ) 2195 _printf("\n[DEBUG FAT] _get_inode_from_path() : enters for path <%s>\n", pathname ); 2196 #endif 2197 2198 // handle root directory case 2199 if ( _strncmp( pathname , "/" , 2 ) == 0 ) 2200 { 2201 2202 #if (GIET_DEBUG_FAT & 1) 2203 if ( _get_proctime() > GIET_DEBUG_FAT ) 2204 _printf("\n[DEBUG FAT] _get_inode_from_path() : found root inode for <%s>\n", 2205 pathname ); 2206 #endif 2207 *inode = _fat.inode_tree_root; 2208 return 0; 2209 } 2210 2211 // If the pathname is not "/", we traverse the inode tree from the root. 2212 // We use _get_name_from_path() to scan pathname and extract inode names. 2213 // We use _get_child_from_parent() to scan each directory in the path. 2214 2215 last = 0; 2216 nb_read = 0; // number of characters analysed in path 2217 parent = _fat.inode_tree_root; // Inode-Tree root 2218 2219 while ( last == 0 ) 2220 { 2221 // get searched file/dir name 2222 if ( _get_name_from_path( pathname, name, &nb_read ) ) 2223 { 2224 return 3; // error : name too long 2225 } 2226 2227 // compute last iteration condition 2228 last = (pathname[nb_read] == 0); 2229 2230 #if (GIET_DEBUG_FAT & 1) 2231 if ( _get_proctime() > GIET_DEBUG_FAT ) 2232 _printf("\n[DEBUG FAT] _get_inode_from_path() : got name <%s>\n", name ); 2233 #endif 2234 2235 // get child inode from parent directory 2236 code = _get_child_from_parent( parent, 2237 name, 2238 &child ); 2239 2240 // we need to find the child inode for all non terminal names 2241 if ( (code == 2) || ((code == 1 ) && (last == 0)) ) 2242 { 2243 2244 #if (GIET_DEBUG_FAT & 1) 2245 if ( _get_proctime() > GIET_DEBUG_FAT ) 2246 _printf("\n[DEBUG FAT] _get_inode_from_path() : neither parent, nor child found for <%s>\n", 2247 pathname ); 2248 #endif 2249 return 2; // error : parent inode not found 2250 } 2251 2252 // update parent if not the last iteration 2253 if ( last == 0 ) parent = child; 2254 2255 } // end while 2256 2257 // returns inode pointer 2258 if (code == 0 ) 2259 { 2260 2261 #if (GIET_DEBUG_FAT & 1) 2262 if ( _get_proctime() > GIET_DEBUG_FAT ) 2263 _printf("\n[DEBUG FAT] _get_inode_from_path() : found inode for <%s>\n", 2264 pathname ); 2265 #endif 2266 *inode = child; 2267 } 2268 else 2269 { 2270 2271 #if (GIET_DEBUG_FAT & 1) 2272 if ( _get_proctime() > GIET_DEBUG_FAT ) 2273 _printf("\n[DEBUG FAT] _get_inode_from_path() : found only parent inode for <%s>\n", 2274 pathname ); 2275 #endif 2276 *inode = parent; 2277 } 2278 2279 return code; // can be 0 (found) or 1 (not found) 2280 2281 } // end _get_inode_from_path() 2282 2283 2284 2285 2286 ////////////////////////////////////////////////////////////// 2287 static unsigned int _remove_node_from_fs( fat_inode_t* inode ) 2288 { 2289 // remove entry in parent directory 2290 if ( _remove_dir_entry( inode ) ) return 1; 2291 2292 // update parent directory on device 2293 if ( _update_device_from_cache( inode->parent->levels, 2294 inode->parent->cache, 2295 inode->parent->name ) ) return 1; 2296 2297 // release clusters allocated to file/dir in DATA region 2298 if ( _clusters_release( inode->cluster ) ) return 1; 2299 2300 // release File-Cache 2301 if ( _release_cache_memory( inode->cache, 2302 inode->levels ) ) return 1; 2303 2304 // remove inode from Inode-Tree 2305 _remove_inode_from_tree( inode ); 2306 2307 // release inode 2308 _free ( inode ); 2309 2310 return 0; 2311 } // end _remove_node_from_fs() 2312 2313 2314 ////////////////////////////////////////////////////////////////// 2315 static unsigned int _next_cluster_no_cache( unsigned int cluster, 2316 unsigned int* next ) 2317 { 2318 // compute cluster_id and slot_id 2319 // each cluster contains 1024 slots (4 bytes per slot) 2320 unsigned int cluster_id = cluster >> 10; 2321 unsigned int slot_id = cluster & 0x3FF; 2322 2323 // compute lba of cluster identified by cluster_id 2324 unsigned int lba = _fat.fat_lba + (cluster_id << 3); 2325 2326 // get cluster containing the adressed FAT slot in FAT buffer 2327 if ( _fat_buffer_fat_lba != lba ) 2328 { 2329 if ( _fat_ioc_access( 0, // no descheduling 2330 1, // read 2331 lba, 2332 (unsigned int)_fat_buffer_fat, 2333 8 ) ) 2334 { 2335 _printf("\n[FAT ERROR] in _next_cluster_no_cache() : " 2336 "cannot load lba = %x into fat_buffer\n", lba ); 2337 return 1; 2338 } 2339 2340 _fat_buffer_fat_lba = lba; 2341 } 2342 2343 // return next cluster index 2344 unsigned int* buf = (unsigned int*)_fat_buffer_fat; 2345 *next = buf[slot_id]; 2346 return 0; 2347 2348 } // end _next_cluster_no_cache() 2349 2350 2351 2352 2353 ///////////////////////////////////////////////////////////////// 2354 static unsigned int _file_info_no_cache( char* pathname, 2355 unsigned int* file_cluster, 2356 unsigned int* file_size ) 2357 { 2358 2359 #if (GIET_DEBUG_FAT & 1) 2360 if ( _get_proctime() > GIET_DEBUG_FAT ) 2361 _printf("\n[DEBUG FAT] _file_info_no_cache() : enters for path <%s>\n", pathname ); 2362 #endif 2363 2364 char name[32]; // buffer for one name in the analysed pathname 2365 char lfn1[16]; // buffer for a partial name in LFN entry 2366 char lfn2[16]; // buffer for a partial name in LFN entry 2367 char lfn3[16]; // buffer for a partial name in LFN entry 2368 char cname[32]; // buffer for a full name in a directory entry 2369 unsigned int nb_read; // number of characters analysed in path 2370 unsigned int length; // searched name length 2371 unsigned int parent_cluster; // cluster index for the parent directory 2372 unsigned int child_cluster; // cluster index for the searched file/dir 2373 unsigned int child_size; // size of the searched file/dir 2374 unsigned int child_is_dir; // type of the searched file/dir 2375 unsigned int offset; // offset in a 4 Kbytes buffer 2376 unsigned int ord; // ORD field in a directory entry 2377 unsigned int attr; // ATTR field in a directory entry 2378 unsigned int lfn; // number of lfn entries 2379 unsigned char* buf; // pointer on a 4 Kbytes buffer 2380 unsigned int found; // name found in current directory entry 2381 2382 // Three embedded loops: 2383 // - scan pathname to extract file/dir names, 2384 // - for each name, scan the clusters of the parent directory 2385 // - for each cluster, scan the 4 Kbytes buffer to find the file/dir name 2386 // The starting point is the root directory (cluster 2) 2387 2388 nb_read = 0; 2389 parent_cluster = 2; 2390 2391 // scan pathname 2392 while ( pathname[nb_read] != 0 ) 2393 { 2394 // get searched file/dir name 2395 if ( _get_name_from_path( pathname, name, &nb_read ) ) return 1; 2396 2397 #if (GIET_DEBUG_FAT & 1) 2398 if ( _get_proctime() > GIET_DEBUG_FAT ) 2399 _printf("\n[DEBUG FAT] _file_info_no_cache() : search name <%s>" 2400 " in cluster %x\n", name , parent_cluster ); 2401 #endif 2402 found = 0; 2403 length = _strlen( name ); 2404 2405 // scan clusters containing the parent directory 2406 while ( found == 0 ) 2407 { 2408 // compute lba 2409 unsigned int lba = _cluster_to_lba( parent_cluster ); 2410 2411 // load one cluster of the parent directory into data_buffer 2412 if ( _fat_buffer_data_lba != lba ) 2413 { 2414 if ( _fat_ioc_access( 0, // no descheduling 2415 1, // read 2416 lba, 2417 (unsigned int)_fat_buffer_data, 2418 8 ) ) 2419 { 2420 _printf("\n[FAT ERROR] in _file_info_no_cache() : " 2421 "cannot load lba = %x into data_buffer\n", lba ); 2422 return 1; 2423 } 2424 2425 _fat_buffer_data_lba = lba; 2426 } 2427 2428 offset = 0; 2429 2430 // scan this 4 Kbytes buffer 2431 while ( (offset < 4096) && (found == 0) ) 2432 { 2433 buf = _fat_buffer_data + offset; 2434 attr = _read_entry( DIR_ATTR , buf , 0 ); 2435 ord = _read_entry( LDIR_ORD , buf , 0 ); 2436 2437 if (ord == NO_MORE_ENTRY) // no more entry => break 2438 { 2439 found = 2; 2440 } 2441 else if ( ord == FREE_ENTRY ) // free entry => skip 2442 { 2443 offset = offset + 32; 2444 } 2445 else if ( attr == ATTR_LONG_NAME_MASK ) // LFN entry => get partial name 2446 { 2447 unsigned int seq = ord & 0x3; 2448 lfn = (seq > lfn) ? seq : lfn; 2449 if ( seq == 1 ) _get_name_from_long( buf, lfn1 ); 2450 else if ( seq == 2 ) _get_name_from_long( buf, lfn2 ); 2451 else if ( seq == 3 ) _get_name_from_long( buf, lfn3 ); 2452 offset = offset + 32; 2453 } 2454 else // NORMAL entry 2455 { 2456 // build the full mame for current directory entry 2457 if ( lfn == 0 ) 2458 { 2459 _get_name_from_short( buf , cname ); 2460 } 2461 else if ( lfn == 1 ) 2462 { 2463 _strcpy( cname , lfn1 ); 2464 } 2465 else if ( lfn == 2 ) 2466 { 2467 _strcpy( cname , lfn1 ); 2468 _strcpy( cname + 13 , lfn2 ); 2469 } 2470 else if ( lfn == 3 ) 2471 { 2472 _strcpy( cname , lfn1 ); 2473 _strcpy( cname + 13 , lfn2 ); 2474 _strcpy( cname + 26 , lfn3 ); 2475 } 2476 2477 // test if extracted name == searched name 2478 if ( _strncmp( name , cname , length ) == 0 ) 2479 { 2480 child_cluster = (_read_entry( DIR_FST_CLUS_HI , buf , 1 ) << 16) | 2481 (_read_entry( DIR_FST_CLUS_LO , buf , 1 ) ) ; 2482 child_is_dir = ((attr & ATTR_DIRECTORY) == ATTR_DIRECTORY); 2483 child_size = _read_entry( DIR_FILE_SIZE , buf , 1 ); 2484 found = 1; 2485 } 2486 offset = offset + 32; 2487 lfn = 0; 2488 } 2489 } // en loop on directory entries 2490 2491 // compute next cluster index 2492 unsigned int next; 2493 if ( _next_cluster_no_cache ( parent_cluster , &next ) ) return 1; 2494 parent_cluster = next; 2495 } // end loop on clusters 2496 2497 if ( found == 2 ) // found end of directory => error 2498 { 2499 _printf("\n[FAT ERROR] in _file_info_no_cache() : <%s> not found\n", 2500 name ); 2501 return 1; 2502 } 2503 2504 // check type 2505 if ( ((pathname[nb_read] == 0) && (child_is_dir != 0)) || 2506 ((pathname[nb_read] != 0) && (child_is_dir == 0)) ) 2507 { 2508 _printf("\n[FAT ERROR] in _file_info_no_cache() : illegal type for <%s>\n", name ); 2509 return 1; 2510 } 2511 2512 // update parent_cluster for next name 2513 parent_cluster = child_cluster; 2514 2515 } // end loop on names 2516 2517 #if (GIET_DEBUG_FAT & 1) 2518 if ( _get_proctime() > GIET_DEBUG_FAT ) 2519 _printf("\n[DEBUG FAT] _file_info_no_cache() : success for <%s> / " 2520 "file_size = %x / file_cluster = %x\n", pathname, child_size, child_cluster ); 2521 #endif 2522 2523 // return file cluster and size 2524 *file_size = child_size; 2525 *file_cluster = child_cluster; 2526 return 0; 2527 2528 } // end _file_info_no_cache() 2529 2530 2531 2532 ///////////////////////////////////////////////////////////////////////////// 2533 ///////////////////////////////////////////////////////////////////////////// 2534 // Extern functions 2535 ///////////////////////////////////////////////////////////////////////////// 2536 ///////////////////////////////////////////////////////////////////////////// 2537 2538 2539 ///////////////////////////////////////////////////////////////////////////// 2540 // This function initializes the FAT structures. 2541 // - The Fat-Descriptor is always initialised. 2542 // - The dynamically allocated structures (the Inode-Tre, the Fat_Cache, 2543 // and the File-Cache for the root directory) are only allocated 2544 // and initialised if the "kernel_mode" argument is set. 2545 ///////////////////////////////////////////////////////////////////////////// 2546 // Implementation note: 2547 // This function is called twice, by the boot-loader, and by the kernel_init. 2548 // It does not use dynamic memory allocation from the distributed heap. 2549 // It use informations found in the boot sector and FS-INFO sector. 2550 // that are loaded in the Fat-Descriptor temporary block_buffer. 2551 ///////////////////////////////////////////////////////////////////////////// 2552 // Returns 0 if success. 2553 // Returns -1 if error. 2554 ///////////////////////////////////////////////////////////////////////////// 2555 int _fat_init( unsigned int kernel_mode ) 2556 { 778 2557 779 2558 #if GIET_DEBUG_FAT 780 2559 if ( _get_proctime() > GIET_DEBUG_FAT ) 781 _printf("\n[DEBUG FAT] _update_fat() : cluster = %x / value = %x\n", 782 cluster, value ); 783 #endif 784 785 // update FAT cache in case of miss 786 if ( lba != _fat.cache_lba ) 787 { 788 if ( _fat_ioc_access( use_irq, 789 1, // read 790 lba, 791 (unsigned int)_fat.fat_cache, 792 1 ) ) // one sector 793 { 794 _printf("\n[FAT_ERROR] in _update_fat() cannot read block %x\n", 795 lba ); 796 return 1; 797 } 798 _fat.cache_lba = lba; 799 } 800 801 _write_entry( ((cluster % 128) << 2), 4, _fat.fat_cache, value ); 802 803 // write bloc to FAT 804 if ( _fat_ioc_access( use_irq, 805 0, // write 806 lba, 807 (unsigned int)_fat.fat_cache, 808 1 ) ) // one sector 809 { 810 _printf("\n[FAT_ERROR] in _update_fat() cannot write block %x\n", 811 lba ); 812 return 1; 813 } 2560 _printf("\n[DEBUG FAT] _fat_init() : enters at cycle %d\n", _get_proctime() ); 2561 #endif 2562 2563 // FAT initialisation should be done only once 2564 if ( _fat.initialised == FAT_INITIALISED ) 2565 { 2566 _printf("\n[FAT ERROR] in _fat_init() : FAT already initialised\n"); 2567 return -1; 2568 } 2569 2570 // load Boot sector (VBR) into FAT buffer 2571 if ( _fat_ioc_access( 0, // no descheduling 2572 1, // read 2573 0, // block index 2574 (unsigned int)_fat.block_buffer, 2575 1 ) ) // one block 2576 { 2577 _printf("\n[FAT ERROR] in _fat_init() cannot load VBR\n"); 2578 return -1; 2579 } 2580 2581 _fat.block_buffer_lba = 0; 2582 2583 #if GIET_DEBUG_FAT 2584 if ( _get_proctime() > GIET_DEBUG_FAT ) 2585 { 2586 _printf("\n[DEBUG FAT] _fat_init() : Boot sector loaded\n"); 2587 _display_one_block( _fat.block_buffer, "block device", _fat.block_buffer_lba ); 2588 } 2589 #endif 2590 2591 // checking various FAT32 assuptions from boot sector 2592 if( _read_entry( BPB_BYTSPERSEC, _fat.block_buffer, 1 ) != 512 ) 2593 { 2594 _printf("\n[FAT ERROR] The sector size must be 512 bytes\n"); 2595 return -1; 2596 } 2597 if( _read_entry( BPB_SECPERCLUS, _fat.block_buffer, 1 ) != 8 ) 2598 { 2599 _printf("\n[FAT ERROR] The cluster size must be 8 blocks\n"); 2600 return -1; 2601 } 2602 if( _read_entry( BPB_NUMFATS, _fat.block_buffer, 1 ) != 1 ) 2603 { 2604 _printf("\n[FAT ERROR] The number of FAT copies in FAT region must be 1\n"); 2605 return -1; 2606 } 2607 if( (_read_entry( BPB_FAT32_FATSZ32, _fat.block_buffer, 1 ) & 0xF) != 0 ) 2608 { 2609 _printf("\n[FAT ERROR] The FAT region must be multiple of 16 sectors\n"); 2610 return -1; 2611 } 2612 if( _read_entry( BPB_FAT32_ROOTCLUS, _fat.block_buffer, 1 ) != 2 ) 2613 { 2614 _printf("\n[FAT ERROR] The root directory must be at cluster 2\n"); 2615 return -1; 2616 } 2617 2618 // initialise Fat-Descriptor from VBR 2619 _fat.sector_size = 512; 2620 _fat.cluster_size = 4096; 2621 _fat.fat_sectors = _read_entry( BPB_FAT32_FATSZ32 , _fat.block_buffer , 1 ); 2622 _fat.fat_lba = _read_entry( BPB_RSVDSECCNT , _fat.block_buffer , 1 ); 2623 _fat.data_sectors = _fat.fat_sectors << 10; 2624 _fat.data_lba = _fat.fat_lba + _fat.fat_sectors; 2625 _fat.fs_info_lba = _read_entry( BPB_FAT32_FSINFO , _fat.block_buffer , 1 ); 2626 _fat_buffer_fat_lba = 0xFFFFFFFF; 2627 _fat_buffer_data_lba = 0xFFFFFFFF; 2628 _fat.initialised = FAT_INITIALISED; 2629 2630 // load FS_INFO sector into FAT buffer 2631 if ( _fat_ioc_access( 0, // no descheduling 2632 1, // read 2633 _fat.fs_info_lba, // lba 2634 (unsigned int)_fat.block_buffer, 2635 1 ) ) // one block 2636 { 2637 _printf("\n[FAT ERROR] in _fat_init() cannot load FS_INFO Sector\n"); 2638 return -1; 2639 } 2640 2641 _fat.block_buffer_lba = _fat.fs_info_lba; 2642 2643 #if GIET_DEBUG_FAT 2644 if ( _get_proctime() > GIET_DEBUG_FAT ) 2645 { 2646 _printf("\n[DEBUG FAT] _fat_init() : FS-INFO sector loaded\n"); 2647 _display_one_block( _fat.block_buffer, "block device", _fat.block_buffer_lba ); 2648 } 2649 #endif 2650 2651 // initialise Fat-Descriptor from FS_INFO 2652 _fat.free_clusters_number = _read_entry( FS_FREE_CLUSTERS , _fat.block_buffer, 1); 2653 _fat.first_free_cluster = _read_entry( FS_FREE_CLUSTER_HINT, _fat.block_buffer, 1); 2654 2655 // This is done only when the _fat_init() is called in kernel mode 2656 2657 if ( kernel_mode ) 2658 { 2659 unsigned int n; 2660 2661 // allocate and initialise the Inode-Tree root 2662 fat_inode_t* inode = _malloc( sizeof(fat_inode_t) ); 2663 fat_cache_node_t* cache = _malloc( sizeof(fat_cache_node_t) ); 2664 2665 inode->parent = NULL; // no parent 2666 inode->next = NULL; // no brother 2667 inode->child = NULL; // children come later 2668 inode->cache = cache; // empty cache 2669 inode->cluster = 2; // forced value 2670 inode->size = 0; // no size for a directory 2671 inode->count = 0; // children come later 2672 inode->dentry = 0; // no parent => no dentry 2673 inode->levels = 1; // one level cache 2674 inode->is_dir = 1; // it's a directory 2675 _strcpy( inode->name , "/" ); 2676 2677 for ( n = 0 ; n < 64 ; n ++ ) cache->children[n] = NULL; 2678 2679 _fat.inode_tree_root = inode; 2680 2681 // initialise the lock 2682 _spin_lock_init( &_fat.fat_lock ); 2683 2684 // initialise File Descriptor Array 2685 for( n = 0 ; n < GIET_OPEN_FILES_MAX ; n++ ) _fat.fd[n].allocated = 0; 2686 2687 // initialise fat_cache root 2688 fat_cache_node_t* fat_cache_root = _malloc( sizeof(fat_cache_node_t) ); 2689 _fat.fat_cache_root = fat_cache_root; 2690 _fat.fat_cache_levels = _get_levels_from_size( _fat.fat_sectors << 9 ); 2691 for ( n = 0 ; n < 64 ; n++ ) _fat.fat_cache_root->children[n] = NULL; 2692 2693 } // end if kernel_mode 2694 2695 #if GIET_DEBUG_FAT 2696 if ( _get_proctime() > GIET_DEBUG_FAT ) 2697 _display_fat_descriptor(); 2698 #endif 814 2699 815 2700 return 0; 816 } // end update_fat() 817 818 ////////////////////////////////////////////////////////////////////////////////// 819 // This function allocate count clusters to a file by calling the 820 // _update_fat function that takes care to update the chaining of clusters. 821 // return 0 if success, -1 if failure 822 ////////////////////////////////////////////////////////////////////////////////// 823 static inline 824 int _fat_allocate( unsigned int use_irq, 825 unsigned int fd_id, 826 unsigned int count ) 827 { 828 unsigned int next_cluster = _fat.fd[fd_id].first_cluster; // first cluster 829 unsigned int cluster_to_allocate = count; // to allocate 830 unsigned int last_cluster_file; // Last cluster 831 unsigned int free_cluster = _fat.last_cluster_allocated + 1; // First free 832 833 // Check if free_cluster is really free (must be true) 834 if ( _get_next_cluster( use_irq , free_cluster ) != FREE_CLUSTER) 835 { 836 _printf("\n[FAT ERROR] in _fat_allocate() : first free cluster not free\n"); 837 return -1; 838 } 839 // Check if FAT contains enough cluster free for this allocation 840 if ( count > _fat.number_free_cluster ) 841 { 842 _printf("\n[FAT ERROR] in _fat_allocate() : Not enough free cluster(s)\n"); 843 return -1; 844 } 845 846 #if GIET_DEBUG_FAT 847 if ( _get_proctime() > GIET_DEBUG_FAT ) 848 _printf("\n[DEBUG FAT] _fat_allocate() for fd = %d\n", fd_id ); 849 #endif 850 851 // Get the last cluster allocated for the file (seek END_OF_CHAIN_CLUSTER). 852 do 853 { 854 last_cluster_file = next_cluster; 855 next_cluster = _get_next_cluster( use_irq , next_cluster ); 856 } 857 while ( next_cluster < END_OF_CHAIN_CLUSTER ); 858 859 // Loop on the number of clusters to be allocated 860 while ( cluster_to_allocate > 0 ) 861 { 862 863 #if GIET_DEBUG_FAT 864 if ( _get_proctime() > GIET_DEBUG_FAT ) 865 _printf("\n[DEBUG FAT] cluster to update = %x / free cluster = %x / count = %d\n", 866 last_cluster_file , free_cluster , cluster_to_allocate ); 867 #endif 868 869 // update, in the FAT, the value of last cluster allocated by the index 870 // of free cluster. 871 if ( _update_fat( use_irq , last_cluster_file , free_cluster ) ) 872 { 873 _printf("\n[FAT ERROR] in _fat_allocate() : update fat failed\n"); 874 return -1; 875 } 876 877 cluster_to_allocate = cluster_to_allocate - 1; 878 // Last cluster allocated is then free_cluster 879 last_cluster_file = free_cluster; 880 881 // Last cluster to allocate done, then we must close the chain of clusters 882 if ( cluster_to_allocate == 0 ) 883 { 884 // update, in the FAT, the value of the last cluster allocated by 885 // END_OF_CHAIN_CLUSTER 886 if ( _update_fat( use_irq , last_cluster_file , END_OF_CHAIN_CLUSTER ) ) 887 { 888 _printf("\n[FAT ERROR] in _fat_allocate() : update fat failed\n"); 889 return -1; 890 } 891 } 892 893 free_cluster = free_cluster + 1; 894 895 // Check if free_cluster is really free (must be true) 896 if ( _get_next_cluster( use_irq , free_cluster ) != FREE_CLUSTER) 897 { 898 _printf("\n[FAT ERROR] in _fat_allocate() : free_cluster not free\n"); 899 return -1; 900 } 901 } 902 903 // Update field number_free_cluster and last_cluster_allocated 904 // of structure fat for next fat_allocate 905 _fat.last_cluster_allocated = last_cluster_file; 906 _fat.number_free_cluster = _fat.number_free_cluster - count; 907 908 if ( _update_fs_info( use_irq ) ) 909 { 910 _printf("\n[FAT ERROR] in _fat_allocate() : update fs_info failed\n"); 911 return -1; 912 } 913 914 return 0; 915 } // end _fat_allocate() 916 917 ////////////////////////////////////////////////////////////////////////////////// 918 // This function read the blocks defined by the cluster index argument, in a data 919 // region containing a directory to search the name of a file/firectory. 920 // It returns the cluster index of the file/directory when the name has been found, 921 // as well as the file size, and the lba. 922 // We consider 3 types of directory entries: 923 // - SFN : directory entry associated to a Short File Name (8.3) 924 // - LFN : directory entry associated to a Long File Name 925 // - XTN : directory entry containing only a name extension for a Long File Name 926 // The cluster index is always stored in a SFN or LFN entry. 927 // Return cluster index if name found / Return -1 if not found. 928 ////////////////////////////////////////////////////////////////////////////////// 929 static 930 int _scan_directory( unsigned int use_irq, // use descheduling mode 931 unsigned int cluster, // cluster of dir_entry 932 char* file_name, // searched file/dir name 933 unsigned int* file_size, // file size 934 unsigned int* lba_dir_entry ) // lba of dir_entry 935 { 936 char dir_entry[32]; // buffer to store a full directory_entry 937 char name_entry[14]; // buffer to store a 13 characters (partial) name 938 939 char sfn_string[12] = {[0 ... 10] = ' ', '\0'}; // buffer Short File Name 940 unsigned int is_sfn = is_short(file_name, sfn_string); // file_name is short 941 unsigned int offset = 0; // byte offset in block 942 unsigned int block_id = _fat.sectors_per_cluster; // sector index 943 unsigned int lba = cluster_to_lba(cluster); // lba of cluster 944 unsigned int attr = 0; // dir entry attribute 945 unsigned int ord = 0; // dir entry sequence 946 unsigned int found = 0; // searched name found 947 unsigned int long_name_found = 0; // matching XTN found 948 unsigned int searched_cluster; // searched cluster index 2701 } // end _fat_init() 2702 2703 2704 2705 2706 /////////////////////////////////////////////////////////////////////////////// 2707 // This function implements the giet_fat_open() system call. 2708 // The semantic is similar to the UNIX open() function, but only the O_CREATE 2709 // and O_RDONLY flags are supported. The UNIX access rights are not supported. 2710 // If the file does not exist in the specified directory, it is created. 2711 // If the specified directory does not exist, an error is returned. 2712 // It allocates a file descriptor to the calling task, for the file identified 2713 // by "pathname". If several tasks try to open the same file, each task 2714 // obtains a private file descriptor. 2715 // A node name (file or directory) cannot be larger than 31 characters. 2716 /////////////////////////////////////////////////////////////////////////////// 2717 // Returns file descriptor index if success 2718 // Returns a negative value if error: 2719 // -1 : "fat not initialised" 2720 // -2 : "path to parent not found" 2721 // -3 : "one name in path too long" 2722 // -4 : "file not found" 2723 // -5 : "Cannot update parent directory" 2724 // -6 : "Cannot update DATA region" 2725 // -7 : "Cannot update FAT region" 2726 // -8 : "Cannot update FS_INFO sector" 2727 // -9 : "file descriptor array full" 2728 /////////////////////////////////////////////////////////////////////////////// 2729 int _fat_open( char* pathname, // absolute path from root 2730 unsigned int flags ) // O_CREATE and O_RDONLY 2731 { 2732 unsigned int fd_id; // index in File-Descriptor-Array 2733 unsigned int code; // error code 2734 fat_inode_t* inode; // anonymous inode pointer 2735 fat_inode_t* child; // pointer on searched file inode 2736 fat_inode_t* parent; // pointer on parent directory inode 2737 2738 // get flags 2739 unsigned int create = ((flags & O_CREATE) != 0); 2740 unsigned int read_only = ((flags & O_RDONLY) != 0); 949 2741 950 2742 #if GIET_DEBUG_FAT … … 954 2746 unsigned int p = procid & ((1<<P_WIDTH)-1); 955 2747 if ( _get_proctime() > GIET_DEBUG_FAT ) 956 _printf("\n[DEBUG FAT] _scan_directory() : P[%d,%d,%d] enters for %s\n", 957 x, y, p, file_name ); 958 #endif 959 960 unsigned int i; 961 for( i = 0 ; i < 32 ; i++ ) dir_entry[i] = 0; 962 for( i = 0 ; i < 14 ; i++ ) name_entry[i] = 0; 963 964 // load first sector from DATA region into FAT cache 965 // other sectors will be loaded inside loop as required 966 if( _fat_ioc_access( use_irq, 967 1, // read 968 lba, 969 (unsigned int)_fat.fat_cache, 970 1 ) ) // one sector 971 { 972 _printf("[\nFAT ERROR] in _scan_directory() : cannot read sector %x\n", 973 lba ); 2748 _printf("\n[DEBUG FAT] _fat_open() : P[%d,%d,%d] enters for path <%s> / " 2749 " create = %d / read_only = %d\n", 2750 x, y, p, pathname , create , read_only ); 2751 #endif 2752 2753 // checking FAT initialised 2754 if( _fat.initialised != FAT_INITIALISED ) 2755 { 2756 _printf("\n[FAT ERROR] in _fat_open() : FAT not initialised\n"); 974 2757 return -1; 975 2758 } 976 _fat.cache_lba = lba; 977 978 #if GIET_DEBUG_FAT 979 if ( (_get_proctime() > GIET_DEBUG_FAT) && (GIET_DEBUG_FAT & 0x1) ) 980 _display_fat_cache(); 981 #endif 982 983 // in this loop we scan all names in the directory identified by cluster index 984 // - the offset increment is an integer number of directory entry (32 bytes) 985 // - the exit condition is success (name found) or failure (end of directory) 986 while( found == 0 ) 987 { 988 // load a new sector if required 989 if (offset >= 512) 990 { 991 if ( block_id ) // not a new cluster 992 { 993 lba += 1; 994 block_id --; 995 } 996 else // get next cluster 997 { 998 cluster = _get_next_cluster( use_irq , cluster ); 999 1000 if ( cluster >= END_OF_CHAIN_CLUSTER ) return END_OF_CHAIN_CLUSTER; 1001 1002 lba = cluster_to_lba(cluster); 1003 block_id = _fat.sectors_per_cluster; 1004 } 1005 if( _fat_ioc_access( use_irq, 1006 1, // read 1007 lba, 1008 (unsigned int)_fat.fat_cache, 1009 1 ) ) // one sector 1010 { 1011 _printf("\n[FAT ERROR] in _scan_directory() : cannot read sector %x\n", 1012 lba); 1013 return -1; 1014 } 1015 _fat.cache_lba = lba; 1016 block_id--; 1017 offset = offset % 512; 1018 } 1019 1020 // store the directory entry pointed by offset in dir_entry buffer, 1021 // if it a possible candidate for the searched name 1022 1023 attr = _read_entry( DIR_ATTR, _fat.fat_cache + offset, 0); 1024 ord = _read_entry( LDIR_ORD, _fat.fat_cache + offset, 0); 1025 1026 if ( is_sfn == 1 ) // searched name is short 1027 { 1028 if ( (ord != FREE_ENTRY ) && 1029 (ord != NO_MORE_ENTRY) && 1030 (attr == ATTR_LONG_NAME_MASK) ) // EXT entry : skipped 1031 { 1032 offset = offset + ((ord & 0xF) * DIR_ENTRY_SIZE); 1033 } 1034 else if ( (attr != ATTR_LONG_NAME_MASK) && 1035 (ord != FREE_ENTRY) && 1036 (ord != NO_MORE_ENTRY ) ) // SFN entry : to be checked 1037 { 1038 memcpy( dir_entry, _fat.fat_cache + offset, DIR_ENTRY_SIZE ); 1039 1040 get_name_from_short( dir_entry, name_entry ); 1041 1042 if ( _strncmp( (char*)sfn_string, 1043 (char*)name_entry, 13 ) == 0 ) // short name found 1044 { 1045 found = 1; 1046 } 1047 else 1048 { 1049 offset = offset + DIR_ENTRY_SIZE; 1050 } 1051 } 1052 else if (ord == NO_MORE_ENTRY ) // end of directory : return 1053 { 1054 return END_OF_CHAIN_CLUSTER; 1055 } 1056 } 1057 else // searched name is long 1058 { 1059 if( (attr == ATTR_LONG_NAME_MASK) && 1060 (ord != FREE_ENTRY) && 1061 (ord != NO_MORE_ENTRY) ) // EXT entry : to be checked 1062 { 1063 memcpy( dir_entry, _fat.fat_cache + offset, DIR_ENTRY_SIZE ); 1064 1065 get_name_from_long( dir_entry, name_entry ); 1066 1067 unsigned shift = ((ord & 0xf) - 1) * 13; 1068 if ( _strncmp( (char*)(file_name + shift), 1069 (char*)name_entry, 13 ) == 0 ) // matching EXT 1070 { 1071 if( (ord & 0xf) == 1 ) // long name found 1072 { 1073 long_name_found = 1; 1074 } 1075 } 1076 offset = offset + DIR_ENTRY_SIZE; 1077 } 1078 else if( (attr != ATTR_LONG_NAME_MASK) && 1079 (ord != FREE_ENTRY) && 1080 (ord != NO_MORE_ENTRY) ) 1081 { 1082 if ( long_name_found ) // LFN entry 1083 { 1084 memcpy( dir_entry, _fat.fat_cache + offset, DIR_ENTRY_SIZE ); 1085 found = 1; 1086 } 1087 else // SFN entry: must be skipped 1088 { 1089 offset = offset + DIR_ENTRY_SIZE; 1090 } 1091 } 1092 else if (ord == NO_MORE_ENTRY ) // end of directory : return 1093 { 1094 return END_OF_CHAIN_CLUSTER; 1095 } 1096 } 1097 } // end while 1098 1099 // returns cluster index 1100 *file_size = _read_entry( DIR_FILE_SIZE, dir_entry, 1 ); 1101 *lba_dir_entry = lba; 1102 searched_cluster = (_read_entry( DIR_FST_CLUS_HI, dir_entry, 1 ) << 16) | 1103 (_read_entry( DIR_FST_CLUS_LO, dir_entry, 1 ) ) ; 2759 2760 // takes the lock 2761 _spin_lock_acquire( &_fat.fat_lock ); 2762 2763 // get inode pointer 2764 code = _get_inode_from_path( pathname , &inode ); 2765 2766 if ( code == 2 ) 2767 { 2768 _spin_lock_release( &_fat.fat_lock ); 2769 _printf("\n[FAT ERROR] in _fat_open() : path to parent not found" 2770 " for file <%s>\n", pathname ); 2771 return -2; 2772 } 2773 else if ( code == 3 ) 2774 { 2775 _spin_lock_release( &_fat.fat_lock ); 2776 _printf("\n[FAT ERROR] in _fat_open() : one name in path too long" 2777 " for file <%s>\n", pathname ); 2778 return -3; 2779 } 2780 else if ( (code == 1) && (create == 0) ) 2781 { 2782 _spin_lock_release( &_fat.fat_lock ); 2783 _printf("\n[FAT ERROR] in _fat_open() : file not found" 2784 " for file <%s>\n", pathname ); 2785 return -4; 2786 } 2787 else if ( (code == 1) && (create != 0) ) // file name not found => create 2788 { 2789 // set parent inode pointer 2790 parent = inode; 1104 2791 1105 2792 #if GIET_DEBUG_FAT 1106 2793 if ( _get_proctime() > GIET_DEBUG_FAT ) 1107 _printf("\n[DEBUG FAT] _scan_directory() : P[%d,%d,%d] found %s" 1108 " : cluster = %x\n", x, y, p, file_name, searched_cluster ); 1109 #endif 1110 1111 return searched_cluster; 1112 } // end _scan_directory() 1113 1114 1115 ////////////////////////////////////////////////////////////////////// 1116 // This function create a new entry in a directory identified 1117 // by "dir_cluster". The name is defined by "name". 1118 // The type (dir/file) is defined by "is_file". 1119 // Returns cluster index if success, Returns -1 if error. 1120 ////////////////////////////////////////////////////////////////////// 1121 static int _fat_create( char* name, 1122 unsigned int is_file, 1123 unsigned int dir_cluster ) 1124 { 1125 _printf("\n[FAT ERROR] _fat_create() not implemented\n"); 2794 _printf("\n[DEBUG FAT] _fat_open() : P[%d,%d,%d] create a new file <%s>\n", 2795 x , y , p , pathname ); 2796 #endif 2797 2798 // get new file name / error check already done by _get_inode_from_path() 2799 char name[32]; 2800 _get_last_name( pathname , name ); 2801 2802 // allocate a new inode and an empty Cache-File 2803 child = _allocate_one_inode( name, 2804 0, // not a directory 2805 END_OF_CHAIN_CLUSTER_MAX, // no cluster allocated 2806 0, // size : new file is empty 2807 0, // count incremented later 2808 0, // dentry set by add_dir_entry 2809 1 ); // cache_allocate 2810 2811 // introduce inode into Inode-Tree 2812 _add_inode_in_tree( child , parent ); 2813 2814 // add an entry in the parent directory Cache_file 2815 if ( _add_dir_entry( child , parent ) ) 2816 { 2817 _spin_lock_release( &_fat.fat_lock ); 2818 _printf("\n[FAT ERROR] in _fat_open() : cannot update parent directory" 2819 " for file <%s>\n" , pathname ); 2820 return -5; 2821 } 2822 2823 // update DATA region on block device for parent directory 2824 if ( _update_device_from_cache( parent->levels, 2825 parent->cache, 2826 parent->name ) ) 2827 { 2828 _spin_lock_release( &_fat.fat_lock ); 2829 _printf("\n[FAT ERROR] in _fat_open() : cannot update DATA region " 2830 " for parent of file <%s>\n", pathname ); 2831 return -6; 2832 } 2833 2834 // update FAT region on block device 2835 if ( _update_device_from_cache( _fat.fat_cache_levels, 2836 _fat.fat_cache_root, 2837 "FAT" ) ) 2838 { 2839 _spin_lock_release( &_fat.fat_lock ); 2840 _printf("\n[FAT ERROR] in _fat_open() : cannot update FAT region" 2841 " for file <%s>\n", pathname ); 2842 return -7; 2843 } 2844 2845 // update FS_INFO sector 2846 if ( _update_fs_info() ) 2847 { 2848 _spin_lock_release( &_fat.fat_lock ); 2849 _printf("\n[FAT ERROR] in _fat_open() : cannot update FS-INFO" 2850 " for file <%s>\n", pathname ); 2851 return -8; 2852 } 2853 } 2854 else // code == 0 2855 { 2856 // set searched file inode pointer 2857 child = inode; 2858 2859 #if GIET_DEBUG_FAT 2860 if ( _get_proctime() > GIET_DEBUG_FAT ) 2861 _printf("\n[DEBUG FAT] _fat_open() : P[%d,%d,%d] found file <%s> on device : inode = %x\n", 2862 x , y , p , pathname , child ); 2863 #endif 2864 2865 } 2866 2867 // Search an empty slot in file descriptors array 2868 fd_id = 0; 2869 while ( (_fat.fd[fd_id].allocated) != 0 && (fd_id < GIET_OPEN_FILES_MAX) ) 2870 { 2871 fd_id++; 2872 } 2873 2874 // set file descriptor if an empty slot has been found 2875 if ( fd_id < GIET_OPEN_FILES_MAX ) 2876 { 2877 // update file descriptor 2878 _fat.fd[fd_id].allocated = 1; 2879 _fat.fd[fd_id].seek = 0; 2880 _fat.fd[fd_id].read_only = read_only; 2881 _fat.fd[fd_id].inode = child; 2882 2883 // increment the refcount 2884 child->count = child->count + 1; 2885 2886 // releases the lock 2887 _spin_lock_release( &_fat.fat_lock ); 2888 2889 #if GIET_DEBUG_FAT 2890 if ( _get_proctime() > GIET_DEBUG_FAT ) 2891 _printf("\n[DEBUG FAT] _fat_open() : P[%d,%d,%d] got fd = %d for <%s> / " 2892 "read_only = %d\n", 2893 x , y , p , fd_id , pathname , read_only ); 2894 #endif 2895 return fd_id; 2896 } 2897 else 2898 { 2899 _spin_lock_release( &_fat.fat_lock ); 2900 _printf("\n[FAT ERROR] in _fat_open() : File-Descriptors-Array full\n"); 2901 return -9; 2902 } 2903 } // end _fat_open() 2904 2905 2906 2907 2908 ///////////////////////////////////////////////////////////////////////////////// 2909 // This function implements the "giet_fat_close()" system call. 2910 // It decrements the inode reference count, and release the fd_id entry 2911 // in the file descriptors array. 2912 // If the reference count is zero, it writes all dirty clusters on block device, 2913 // and releases the memory allocated to the file_cache: The cache 64-Tree 2914 // infrastructure (depending on file size) is kept, but all buffers and all 2915 // buffer descriptors are released. 2916 ///////////////////////////////////////////////////////////////////////////////// 2917 // Returns 0 on success. 2918 // Returns negative value if error: 2919 // -1 : "FAT not initialised" 2920 // -2 : "Illegal file descriptor" 2921 // -3 : "Cannot update DATA region for closed file" 2922 // -4 : "Cannot release memory" 2923 ///////////////////////////////////////////////////////////////////////////////// 2924 int _fat_close( unsigned int fd_id ) 2925 { 2926 // checking FAT initialised 2927 if( _fat.initialised != FAT_INITIALISED ) 2928 { 2929 _printf("\n[FAT ERROR] in _fat_close() : FAT not initialised\n"); 2930 return -1; 2931 } 2932 2933 if( (fd_id >= GIET_OPEN_FILES_MAX) ) 2934 { 2935 _printf("\n[FAT ERROR] in _fat_close() : illegal file descriptor index\n"); 2936 return -2; 2937 } 2938 2939 // takes lock 2940 _spin_lock_acquire( &_fat.fat_lock ); 2941 2942 // get the inode pointer 2943 fat_inode_t* inode = _fat.fd[fd_id].inode; 2944 2945 // decrement reference count 2946 inode->count = inode->count - 1; 2947 2948 #if GIET_DEBUG_FAT 2949 if ( _get_proctime() > GIET_DEBUG_FAT ) 2950 _printf("\n[FAT DEBUG] _fat_close() for file <%s> : refcount = %d\n", 2951 inode->name , inode->count ); 2952 #endif 2953 2954 // update block device and release File-Cache if no more references 2955 if ( inode->count == 0 ) 2956 { 2957 // update all dirty clusters for closed file 2958 if ( _update_device_from_cache( inode->levels, 2959 inode->cache, 2960 inode->name ) ) 2961 { 2962 _spin_lock_release( &_fat.fat_lock ); 2963 _printf("\n[FAT ERROR] in _fat_close() : cannot write dirty clusters " 2964 "for file <%s>\n", inode->name ); 2965 return -3; 2966 } 2967 2968 #if GIET_DEBUG_FAT 2969 if ( _get_proctime() > GIET_DEBUG_FAT ) 2970 _printf("\n[FAT DEBUG] _fat_close() update device for file <%s>\n", inode->name ); 2971 #endif 2972 2973 // update directory dirty clusters for parent directory 2974 if ( _update_device_from_cache( inode->parent->levels, 2975 inode->parent->cache, 2976 inode->parent->name ) ) 2977 { 2978 _spin_lock_release( &_fat.fat_lock ); 2979 _printf("\n[FAT ERROR] in _fat_close() : cannot write dirty clusters " 2980 "for directory <%s>\n", inode->parent->name ); 2981 return -4; 2982 } 2983 2984 #if GIET_DEBUG_FAT 2985 if ( _get_proctime() > GIET_DEBUG_FAT ) 2986 _printf("\n[FAT DEBUG] _fat_close() update device for parent directory <%s>\n", 2987 inode->parent->name ); 2988 #endif 2989 2990 // release memory allocated to File-Cache 2991 if ( _release_cache_memory( inode->cache, 2992 inode-> levels ) ) 2993 { 2994 _spin_lock_release( &_fat.fat_lock ); 2995 _printf("\n[FAT ERROR] in _fat_close() : cannot release cache memory " 2996 "for file <%s>\n", _fat.fd[fd_id].inode->name ); 2997 return -5; 2998 } 2999 3000 #if GIET_DEBUG_FAT 3001 if ( _get_proctime() > GIET_DEBUG_FAT ) 3002 _printf("\n[FAT DEBUG] _fat_close() release memory for File-Cache <%s>\n", 3003 inode->name ); 3004 #endif 3005 3006 } 3007 3008 // release fd_id entry in file descriptor array 3009 _fat.fd[fd_id].allocated = 0; 3010 3011 // release lock 3012 _spin_lock_release( &_fat.fat_lock ); 3013 1126 3014 return 0; 1127 } //end _fat_create() 1128 1129 1130 1131 ////////////// Extern functions ////////////////////////////////////////// 1132 1133 ////////////////////////////////////////////////////////////////////////// 1134 // This function initializes the FAT structure, including the open 1135 // files descriptors array and the lock protecting the FAT, 1136 // from informations found in the boot record. 1137 // This should be done only once. 1138 ////////////////////////////////////////////////////////////////////////// 1139 // Return 0 if success, exit if failure 1140 ////////////////////////////////////////////////////////////////////////// 1141 int _fat_init( unsigned int use_irq ) 1142 { 3015 } // end fat_close() 3016 3017 3018 3019 3020 ///////////////////////////////////////////////////////////////////////////////// 3021 // This function implements the giet_fat_file_info() system call. 3022 // It returns the size and the current offset value for a file identified 3023 // by the "fd_id" argument. 3024 ///////////////////////////////////////////////////////////////////////////////// 3025 // Returns 0 if success. 3026 // Returns negative value if error. 3027 // -1 : "FAT not initialised" 3028 // -2 : "Illegal file descriptor" 3029 // -3 : "File not open" 3030 ///////////////////////////////////////////////////////////////////////////////// 3031 int _fat_file_info( unsigned int fd_id, 3032 unsigned int* size, 3033 unsigned int* offset ) 3034 { 3035 // checking FAT initialised 3036 if( _fat.initialised != FAT_INITIALISED ) 3037 { 3038 _printf("\n[FAT ERROR] in _fat_file_info() : FAT not initialised\n"); 3039 return -1; 3040 } 3041 3042 3043 if( fd_id >= GIET_OPEN_FILES_MAX ) 3044 { 3045 _printf("\n[FAT ERROR] in _fat_file_info() : illegal file descriptor index\n"); 3046 return -2; 3047 } 3048 3049 if ( _fat.fd[fd_id].allocated == 0 ) 3050 { 3051 _printf("\n[FAT ERROR] in _fat_file_info() : file <%s> not open\n", 3052 _fat.fd[fd_id].inode->name ); 3053 return -3; 3054 } 3055 3056 *size = _fat.fd[fd_id].inode->size; 3057 *offset = _fat.fd[fd_id].seek; 3058 return 0; 3059 3060 } // end _fat_file_info() 3061 3062 3063 3064 3065 ///////////////////////////////////////////////////////////////////////////////// 3066 // The following function implements the "giet_fat_read()" system call. 3067 // It transfers "count" bytes from the File_Cache associated to the file 3068 // identified by "fd_id", to the user "buffer", from the current file offset. 3069 // It has the same semantic as the UNIX "read()" function. 3070 // In case of miss in the File_Cache, it loads all involved clusters into cache. 3071 ///////////////////////////////////////////////////////////////////////////////// 3072 // Returns number of bytes actually transfered if success . 3073 // Returns 0 if EOF encountered (offset + count > file_size). 3074 // Returns a negative value if error: 3075 // -1 : "fat not initialised" 3076 // -2 : "file not open" 3077 // -3 : "cannot load file from device" 3078 ///////////////////////////////////////////////////////////////////////////////// 3079 int _fat_read( unsigned int fd_id, // file descriptor index 3080 void* buffer, // destination buffer 3081 unsigned int count ) // number of bytes to read 3082 { 3083 // checking FAT initialised 3084 if( _fat.initialised != FAT_INITIALISED ) 3085 { 3086 _printf("\n[FAT ERROR] in _fat_write() : FAT not initialised\n"); 3087 return -1; 3088 } 3089 3090 // check fd_id overflow 3091 if ( fd_id >= GIET_OPEN_FILES_MAX ) 3092 { 3093 _printf("\n[FAT ERROR] in _fat_read() : illegal file descriptor\n"); 3094 return -1; 3095 } 3096 3097 // check file is open 3098 if ( _fat.fd[fd_id].allocated == 0 ) 3099 { 3100 _printf("\n[FAT ERROR] in _fat_read() : file not open\n"); 3101 return -2; 3102 } 3103 3104 // takes lock 3105 _spin_lock_acquire( &_fat.fat_lock ); 3106 3107 // get file inode pointer and offset 3108 fat_inode_t* inode = _fat.fd[fd_id].inode; 3109 unsigned int seek = _fat.fd[fd_id].seek; 3110 3111 // check count & seek versus file size 3112 if ( count + seek > inode->size ) 3113 { 3114 _spin_lock_release( &_fat.fat_lock ); 3115 _printf("\n[FAT ERROR] in _fat_read() : file too small" 3116 " / seek = %x / count = %x / file_size = %x\n", 3117 seek , count , inode->size ); 3118 return 0; 3119 } 3120 3121 // compute first_cluster_id and first_byte_to_move 3122 unsigned int first_cluster_id = seek >> 12; 3123 unsigned int first_byte_to_move = seek & 0xFFF; 3124 3125 // compute last_cluster and last_byte_to_move 3126 unsigned int last_cluster_id = (seek + count - 1) >> 12; 3127 unsigned int last_byte_to_move = (seek + count - 1) & 0xFFF; 1143 3128 1144 3129 #if GIET_DEBUG_FAT … … 1148 3133 unsigned int p = procid & ((1<<P_WIDTH)-1); 1149 3134 if ( _get_proctime() > GIET_DEBUG_FAT ) 1150 _printf("\n[DEBUG FAT] P[%d,%d,%d] enters _fat_init\n",x,y,p); 1151 #endif 1152 1153 // FAT initialisation should be done only once 1154 if ( _fat.initialised == FAT_INITIALISED ) 1155 { 1156 _printf("\n[FAT ERROR] Strange, FAT already initialised...\n"); 1157 _exit(); 1158 } 1159 1160 // load Boot Record (VBR) into fat cache 1161 if ( _fat_ioc_access( use_irq, 1162 1, // read 1163 0, // sector index 1164 (unsigned int)_fat.fat_cache, 1165 1 ) ) // one sector 1166 { 1167 _printf("\n[FAT ERROR] in _fat_init() cannot load VBR\n"); 1168 _exit(); 1169 } 1170 _fat.cache_lba = 0; 1171 1172 #if GIET_DEBUG_FAT > 1 1173 if ( _get_proctime() > GIET_DEBUG_FAT ) 1174 _printf("\n[DEBUG FAT] _fat_init() : Boot Sector Loaded\n"); 1175 if ( (_get_proctime() > GIET_DEBUG_FAT) && (GIET_DEBUG_FAT & 0x1) ) 1176 _display_fat_cache(); 1177 #endif 1178 1179 // checking various FAT32 assuptions from boot sector 1180 if( _read_entry( BPB_BYTSPERSEC, _fat.fat_cache, 1 ) != 512 ) 1181 { 1182 _printf("\n[FAT ERROR] The sector size must be 512 bytes\n"); 1183 _exit(); 1184 } 1185 if( _read_entry( BPB_NUMFATS, _fat.fat_cache, 1 ) != 1 ) 1186 { 1187 _printf("\n[FAT ERROR] The number of FAT copies in FAT region must be 1\n"); 1188 _exit(); 1189 } 1190 if( (_read_entry( BPB_FAT32_FATSZ32, _fat.fat_cache, 1 ) & 0xF) != 0 ) 1191 { 1192 _printf("\n[FAT ERROR] The FAT region must be multiple of 32 sectors\n"); 1193 _exit(); 1194 } 1195 if( _read_entry( BPB_FAT32_ROOTCLUS, _fat.fat_cache, 1 ) != 2 ) 1196 { 1197 _printf("\n[FAT ERROR] The first cluster index must be 2\n"); 1198 _exit(); 1199 } 1200 // FS Info always in sector 1 1201 _fat.fs_info_lba = _read_entry( BPB_FAT32_FSINFO, _fat.fat_cache, 1 ); 1202 1203 // initialise fat descriptor from VBR 1204 _fat.sectors_per_cluster = _read_entry( BPB_SECPERCLUS, _fat.fat_cache, 1 ); 1205 _fat.sector_size = _read_entry( BPB_BYTSPERSEC, _fat.fat_cache, 1 ); 1206 _fat.cluster_size = _fat.sectors_per_cluster * 512; 1207 _fat.fat_sectors = _read_entry( BPB_FAT32_FATSZ32, _fat.fat_cache, 1 ); 1208 _fat.fat_lba = _read_entry( BPB_RSVDSECCNT, _fat.fat_cache, 1 ); 1209 _fat.data_lba = _fat.fat_lba + _fat.fat_sectors; 1210 _fat.initialised = FAT_INITIALISED; 1211 1212 // initalise the lock protecting the FAT 1213 _spin_lock_init( &_fat.fat_lock ); 1214 1215 // initialise file descriptor array 1216 unsigned int n; 1217 for( n = 0 ; n < GIET_OPEN_FILES_MAX ; n++ ) _fat.fd[n].used = 0; 3135 _printf("\n[DEBUG FAT] _fat_read() : P[%d,%d,%d] enters for file <%s> " 3136 " / bytes = %x / offset = %x\n" 3137 "first_cluster_id = %x / first_byte_to_move = %x" 3138 " / last_cluster_id = %x / last_byte_to_move = %x\n", 3139 x , y , p , inode->name , count , seek , 3140 first_cluster_id , first_byte_to_move , last_cluster_id , last_byte_to_move ); 3141 #endif 3142 3143 // loop on all cluster covering the requested transfer 3144 unsigned int cluster_id; 3145 unsigned int done = 0; 3146 for ( cluster_id = first_cluster_id ; cluster_id <= last_cluster_id ; cluster_id++ ) 3147 { 3148 // get pointer on the cluster_id buffer in cache 3149 unsigned char* cbuf; 3150 fat_cache_desc_t* pdesc; 3151 if ( _get_buffer_from_cache( inode, 3152 cluster_id, 3153 &pdesc ) ) 3154 { 3155 _spin_lock_release( &_fat.fat_lock ); 3156 _printf("\n[FAT ERROR] in _fat_read() : cannot load file <%s>\n", 3157 inode->name ); 3158 return -3; 3159 } 3160 cbuf = pdesc->buffer; 1218 3161 1219 3162 #if GIET_DEBUG_FAT 1220 3163 if ( _get_proctime() > GIET_DEBUG_FAT ) 1221 _printf("\n[DEBUG FAT] _fat_init() : FS_INFO Sector = %x\n", _fat.fs_info_lba ); 1222 #endif 1223 1224 // load FS_INFO into fat cache 1225 if ( _fat_ioc_access( use_irq, 1226 1, // read 1227 _fat.fs_info_lba, 1228 (unsigned int)_fat.fat_cache, 1229 1 ) ) // one sector 1230 { 1231 _printf("\n[FAT ERROR] in _fat_init() cannot load FS_INFO Sector\n"); 1232 _exit(); 1233 } 1234 _fat.cache_lba = _fat.fs_info_lba; 1235 1236 _fat.number_free_cluster = _read_entry( FS_FREE_CLUSTER , _fat.fat_cache, 1); 1237 _fat.last_cluster_allocated = _read_entry( FS_FREE_CLUSTER_HINT, _fat.fat_cache, 1); 3164 _printf("\n[DEBUG FAT] _fat_read() : P[%d,%d,%d] moves cluster_id %d from Cache-File <%s>\n", 3165 x , y , p , cluster_id, inode->name ); 3166 #endif 3167 3168 // compute memcpy arguments 3169 unsigned char* source; 3170 unsigned int nbytes; 3171 unsigned char* dest = (unsigned char*)buffer + done; 3172 if ( (cluster_id == first_cluster_id) && (cluster_id == last_cluster_id) ) 3173 { 3174 source = cbuf + first_byte_to_move; 3175 nbytes = last_byte_to_move - first_byte_to_move + 1; 3176 } 3177 else if ( cluster_id == first_cluster_id ) 3178 { 3179 source = cbuf + first_byte_to_move; 3180 nbytes = 4096 - first_byte_to_move; 3181 } 3182 else if ( cluster_id == last_cluster_id ) 3183 { 3184 source = cbuf; 3185 nbytes = last_byte_to_move + 1; 3186 } 3187 else // not first / not last 3188 { 3189 source = cbuf; 3190 nbytes = 4096; 3191 } 3192 3193 // move data 3194 memcpy( dest , source , nbytes ); 3195 done = done + nbytes; 3196 } 1238 3197 1239 3198 #if GIET_DEBUG_FAT 1240 3199 if ( _get_proctime() > GIET_DEBUG_FAT ) 1241 _fat_print(); 1242 _printf("\n[DEBUG FAT] P[%d,%d,%d] exit _fat_init()\n", x,y,p ); 1243 #endif 1244 1245 return 0; 1246 } // end _fat_init() 1247 1248 /////////////////////////////////////////////////////////////////////////////// 1249 // This function checks that the kernel FAT structure has been initialised. 1250 // It searches a file identified by the "pathname" argument. 1251 // It starts from root (cluster 2) to scan successively each subdirectory. 1252 // When the file is not found, but the path is found, and "creat" is set, 1253 // a new file is created and introduced in the directory. 1254 // Finally, it sets a new open file in the file descriptors array. 1255 // The same file can be open several times by differents tasks. 1256 /////////////////////////////////////////////////////////////////////////////// 1257 // Returns file descriptor index if success, returns -1 if error. 1258 /////////////////////////////////////////////////////////////////////////////// 1259 int _fat_open( unsigned int use_irq, // use descheduling mode if possible 1260 char* pathname, 1261 unsigned int creat ) 1262 { 1263 char name[256]; // buffer for one name in pathname 1264 unsigned int nb_read; // number of characters written in name[] 1265 unsigned int cluster; // current cluster index when scanning FAT 1266 unsigned int dir_cluster; // previous cluster index when scanning FAT 1267 unsigned int fd_id; // index when scanning file descriptors array 1268 unsigned int file_size = 0; // number of bytes 1269 unsigned int last_name = 0; // directory containing file name is reached 1270 unsigned int lba = 0; // lba of dir_entry for this file 1271 3200 _printf("\n[DEBUG FAT] _fat_read() : P[%d,%d,%d] loaded file <%s> from Cache-File\n", 3201 x , y , p , inode->name ); 3202 #endif 3203 3204 // update seek 3205 _fat.fd[fd_id].seek += done; 3206 3207 // release lock 3208 _spin_lock_release( &_fat.fat_lock ); 3209 3210 return done; 3211 } // end _fat_read() 3212 3213 3214 3215 3216 ///////////////////////////////////////////////////////////////////////////////// 3217 // The following function implements the "giet_fat_write()" system call. 3218 // It transfers "count" bytes to the fat_cache associated to the file 3219 // identified by "fd_id", from the user "buffer", using the current file offset. 3220 // It has the same semantic as the UNIX "write()" function. 3221 // It increases the file size and allocate new clusters if (count + offset) 3222 // is larger than the current file size. Then it loads and updates all 3223 // involved clusters in the cache. 3224 ///////////////////////////////////////////////////////////////////////////////// 3225 // Returns number of bytes actually written if success. 3226 // Returns a negative value if error: 3227 // -1 : "FAT not initialised" 3228 // -2 : "Illegal file descriptor" 3229 // -3 : "File not open" 3230 // -4 : "File not writable" 3231 // -5 : "No free clusters" 3232 // -6 : "Cannot update parent directory entry" 3233 // -7 : "Cannot access File-Cache" 3234 ///////////////////////////////////////////////////////////////////////////////// 3235 int _fat_write( unsigned int fd_id, // file descriptor index 3236 void* buffer, // source buffer 3237 unsigned int count ) // number of bytes to write 3238 { 3239 // checking FAT initialised 3240 if( _fat.initialised != FAT_INITIALISED ) 3241 { 3242 _printf("\n[FAT ERROR] in _fat_write() : FAT not initialised\n"); 3243 return -1; 3244 } 3245 3246 // takes lock 3247 _spin_lock_acquire( &_fat.fat_lock ); 3248 3249 // check fd_id overflow 3250 if ( fd_id >= GIET_OPEN_FILES_MAX ) 3251 { 3252 _spin_lock_release( &_fat.fat_lock ); 3253 _printf("\n[FAT ERROR] in _fat_write() : illegal file descriptor\n"); 3254 return -2; 3255 } 3256 3257 // check file open 3258 if ( _fat.fd[fd_id].allocated == 0 ) 3259 { 3260 _spin_lock_release( &_fat.fat_lock ); 3261 _printf("\n[FAT ERROR] in _fat_write() : file not open\n" ); 3262 return -3; 3263 } 3264 3265 // check file writable 3266 if ( _fat.fd[fd_id].read_only ) 3267 { 3268 _spin_lock_release( &_fat.fat_lock ); 3269 _printf("\n[FAT ERROR] in _fat_write() : file <%s> is read-only\n", 3270 _fat.fd[fd_id].inode->name ); 3271 return -4; 3272 } 3273 3274 // get file inode pointer and seek 3275 fat_inode_t* inode = _fat.fd[fd_id].inode; 3276 unsigned int seek = _fat.fd[fd_id].seek; 3277 1272 3278 #if GIET_DEBUG_FAT 1273 3279 unsigned int procid = _get_procid(); … … 1276 3282 unsigned int p = procid & ((1<<P_WIDTH)-1); 1277 3283 if ( _get_proctime() > GIET_DEBUG_FAT ) 1278 _printf("\n[DEBUG FAT] _fat_open() : P[%d,%d,%d] enters for path %s\n", 1279 x, y, p, pathname ); 1280 #endif 1281 1282 // checking creat argument 1283 if ( creat ) 1284 { 1285 _printf("\n[FAT ERROR] in _fat_open() : create not supported yet\n"); 1286 return -1; 1287 } 1288 3284 _printf("\n[DEBUG FAT] _fat_write() : P[%d,%d,%d] enters for file <%s> " 3285 " / bytes = %x / seek = %x\n", 3286 x , y , p , inode->name , count , seek ); 3287 #endif 3288 3289 // chek if file size must be incremented 3290 // and allocate new clusters from FAT if required 3291 unsigned int old_size = inode->size; 3292 unsigned int new_size = seek + count; 3293 if ( new_size > old_size ) 3294 { 3295 // update size in inode 3296 inode->size = new_size; 3297 3298 // compute current and required numbers of clusters 3299 unsigned old_clusters = old_size >> 12; 3300 if ( old_size & 0xFFF ) old_clusters++; 3301 3302 unsigned new_clusters = new_size >> 12; 3303 if ( new_size & 0xFFF ) new_clusters++; 3304 3305 // allocate new clusters from FAT if required 3306 if ( new_clusters > old_clusters ) 3307 { 3308 3309 #if GIET_DEBUG_FAT 3310 if ( _get_proctime() > GIET_DEBUG_FAT ) 3311 _printf("\n[DEBUG FAT] _fat_write() : P[%d,%d,%d] allocates new clusters for file <%s>" 3312 " / current = %d / required = %d\n", 3313 x , y , p , inode->name , old_clusters , new_clusters ); 3314 #endif 3315 // allocate missing clusters 3316 if ( _clusters_allocate( inode, 3317 old_clusters, 3318 new_clusters - old_clusters ) ) 3319 { 3320 _spin_lock_release( &_fat.fat_lock ); 3321 _printf("\n[FAT ERROR] in _fat_write() : no free clusters" 3322 " for file <%s>\n", _fat.fd[fd_id].inode->name ); 3323 return -5; 3324 } 3325 } 3326 3327 // update parent directory entry (size an cluster index) 3328 if ( _update_dir_entry( inode ) ) 3329 { 3330 _spin_lock_release( &_fat.fat_lock ); 3331 _printf("\n[FAT ERROR] in _fat_write() : cannot update parent directory entry" 3332 " for file <%s>\n", _fat.fd[fd_id].inode->name ); 3333 return -6; 3334 } 3335 3336 3337 #if GIET_DEBUG_FAT 3338 if ( _get_proctime() > GIET_DEBUG_FAT ) 3339 _printf("\n[DEBUG FAT] _fat_write() : P[%d,%d,%d] updates size for file <%s> / size = %x\n", 3340 x , y , p , inode->name , (new_size - old_size) ); 3341 #endif 3342 3343 } 3344 3345 // compute first_cluster_id and first_byte_to_move 3346 unsigned int first_cluster_id = seek >> 12; 3347 unsigned int first_byte_to_move = seek & 0xFFF; 3348 3349 // compute last_cluster and last_byte_to_move 3350 unsigned int last_cluster_id = (seek + count - 1) >> 12; 3351 unsigned int last_byte_to_move = (seek + count - 1) & 0xFFF; 3352 3353 #if GIET_DEBUG_FAT 3354 if ( _get_proctime() > GIET_DEBUG_FAT ) 3355 _printf("\n[DEBUG FAT] _fat_write() : P[%d,%d,%d] starts loop on clusters for file <%s>\n" 3356 " first_cluster_id = %d / first_byte_to_move = %x" 3357 " / last_cluster_id = %d / last_byte_to_move = %x\n", 3358 x , y , p , inode->name , 3359 first_cluster_id , first_byte_to_move , last_cluster_id , last_byte_to_move ); 3360 #endif 3361 3362 // loop on all clusters covering the requested transfer 3363 unsigned int cluster_id; 3364 unsigned int done = 0; 3365 for ( cluster_id = first_cluster_id ; cluster_id <= last_cluster_id ; cluster_id++ ) 3366 { 3367 // get pointer on one 4K buffer in File-Cache 3368 unsigned char* cbuf; 3369 fat_cache_desc_t* pdesc; 3370 if ( _get_buffer_from_cache( inode, 3371 cluster_id, 3372 &pdesc ) ) 3373 { 3374 _spin_lock_release( &_fat.fat_lock ); 3375 _printf("\n[FAT ERROR] in _fat_write() : cannot load file <%s>\n", 3376 inode->name ); 3377 return -7; 3378 } 3379 3380 cbuf = pdesc->buffer; 3381 pdesc->dirty = 1; 3382 3383 #if GIET_DEBUG_FAT 3384 if ( _get_proctime() > GIET_DEBUG_FAT ) 3385 _printf("\n[DEBUG FAT] _fat_write() : P[%d,%d,%d] move cluster_id %d to Cache-file <%s>\n", 3386 x , y , p , cluster_id, inode->name ); 3387 #endif 3388 3389 // compute memcpy arguments 3390 unsigned char* source = (unsigned char*)buffer + done; 3391 unsigned char* dest; 3392 unsigned int nbytes; 3393 if ( (cluster_id == first_cluster_id) && (cluster_id == last_cluster_id) ) 3394 { 3395 dest = cbuf + first_byte_to_move; 3396 nbytes = last_byte_to_move - first_byte_to_move + 1; 3397 } 3398 else if ( cluster_id == first_cluster_id ) 3399 { 3400 dest = cbuf + first_byte_to_move; 3401 nbytes = 4096 - first_byte_to_move; 3402 } 3403 else if ( cluster_id == last_cluster_id ) 3404 { 3405 dest = cbuf; 3406 nbytes = last_byte_to_move + 1; 3407 } 3408 else 3409 { 3410 dest = cbuf; 3411 nbytes = 4096; 3412 } 3413 3414 //move date 3415 memcpy( dest , source , nbytes ); 3416 done = done + nbytes; 3417 3418 } // end for clusters 3419 3420 // update seek 3421 _fat.fd[fd_id].seek += done; 3422 3423 #if GIET_DEBUG_FAT 3424 if ( _get_proctime() > GIET_DEBUG_FAT ) 3425 _printf("\n[DEBUG FAT] _fat_write() : P[%d,%d,%d] store file <%s> into Cache-File\n", 3426 x , y , p , inode->name ); 3427 #endif 3428 3429 // release lock 3430 _spin_lock_release( &_fat.fat_lock ); 3431 3432 return done; 3433 } // end _fat_write() 3434 3435 3436 3437 ///////////////////////////////////////////////////////////////////////////////// 3438 // The following function implements the "giet_fat_lseek()" system call. 3439 // It repositions the seek in the file descriptor "fd_id", according to 3440 // the "seek" and "whence" arguments. 3441 // It has the same semantic as the UNIX lseek() function. 3442 // Accepted values for whence are SEEK_SET and SEEK_CUR. 3443 ///////////////////////////////////////////////////////////////////////////////// 3444 // Returns new seek value (bytes) if success. 3445 // Returns negative value if error: 3446 // -1 : "FAT not initialised" 3447 // -2 : "Illegal file descriptor" 3448 // -3 : "File not open" 3449 // -4 : "Illegal whence argument" 3450 ///////////////////////////////////////////////////////////////////////////////// 3451 int _fat_lseek( unsigned int fd_id, 3452 unsigned int seek, 3453 unsigned int whence ) 3454 { 1289 3455 // checking FAT initialised 1290 3456 if( _fat.initialised != FAT_INITIALISED ) 1291 3457 { 1292 _printf("\n[FAT ERROR] in _fat_ open() : FAT not initialised\n");3458 _printf("\n[FAT ERROR] in _fat_lseek() : FAT not initialised\n"); 1293 3459 return -1; 1294 3460 } 1295 // takes the FAT lock for exclusive access 3461 3462 // check fd_id overflow 3463 if ( fd_id >= GIET_OPEN_FILES_MAX ) 3464 { 3465 _printf("\n[FAT ERROR] in _fat_lseek() : illegal file descriptor\n"); 3466 return -2; 3467 } 3468 3469 // takes lock 1296 3470 _spin_lock_acquire( &_fat.fat_lock ); 1297 3471 1298 #if GIET_DEBUG_FAT 1299 if ( _get_proctime() > GIET_DEBUG_FAT ) 1300 _printf("\n[DEBUG FAT] _fat_open() : P[%d,%d,%d] takes the FAT lock\n", 1301 x, y, p ); 1302 #endif 1303 1304 // Scan the directories, starting from the root directory (cluster 2) 1305 // - The get_name_from_path() function extracts (successively) 1306 // each directory name from the pathname, and store it in name[] buffer 1307 // - The _scan_directory() function scan one (or several) cluster(s) containing 1308 // a directory looking for name[], and return the cluster index 1309 // corresponding to the directory/file found. 1310 nb_read = 0; 1311 cluster = 2; 1312 last_name = 0; 1313 while ( get_name_from_path( pathname, name, &nb_read) ) 1314 { 1315 1316 #if GIET_DEBUG_FAT 1317 if ( _get_proctime() > GIET_DEBUG_FAT ) 1318 _printf("\n[DEBUG FAT] _fat_open() : P[%d,%d,%d] search file/dir %s\n", 1319 x, y, p, name ); 1320 #endif 1321 1322 // test if we reach the last name (file name) 1323 if( pathname[nb_read] == 0 ) 1324 { 1325 last_name = 1; 1326 dir_cluster = cluster; // this is the lowest directory 1327 } 1328 1329 // scan current directory 1330 cluster = _scan_directory( use_irq , cluster , name , &file_size , &lba ); 1331 1332 if( cluster == END_OF_CHAIN_CLUSTER && last_name && creat ) 1333 { 1334 cluster = _fat_create( name, 1, dir_cluster ); 1335 } 1336 else if ( cluster == END_OF_CHAIN_CLUSTER ) 1337 { 1338 _printf("\n[FAT ERROR] in _fat_open() cannot found %s\n", name ); 1339 _spin_lock_release( &_fat.fat_lock ); 1340 return -1; 1341 } 1342 } 1343 1344 #if GIET_DEBUG_FAT 1345 if ( _get_proctime() > GIET_DEBUG_FAT ) 1346 _printf("\n[DEBUG FAT] P[%d,%d,%d] in _fat_open() : cluster for %s = %x\n", 1347 x, y, p, pathname, cluster ); 1348 #endif 1349 1350 // check the next value for cluster index found 1351 unsigned next = _get_next_cluster( use_irq , cluster ); 1352 1353 if ( (next != BAD_CLUSTER) && (next != FREE_CLUSTER) ) 1354 { 1355 // Search an empty slot scanning open file descriptors array 1356 fd_id = 0; 1357 while ( _fat.fd[fd_id].used != 0 && fd_id < GIET_OPEN_FILES_MAX ) 1358 { 1359 fd_id++; 1360 } 1361 1362 // set file descriptor if found empty slot 1363 if ( fd_id < GIET_OPEN_FILES_MAX ) 1364 { 1365 _fat.fd[fd_id].used = 1; 1366 _fat.fd[fd_id].first_cluster = cluster; 1367 _fat.fd[fd_id].file_size = file_size; 1368 _fat.fd[fd_id].lba_dir_entry = lba; 1369 _strcpy( _fat.fd[fd_id].name, pathname ); 1370 1371 #if GIET_DEBUG_FAT 1372 if ( _get_proctime() > GIET_DEBUG_FAT ) 1373 _printf("\n[DEBUG FAT] _fat_open() : P[%d,%d,%d] exit : fd = %d for file %s\n", 1374 x, y, p, fd_id, pathname ); 1375 #endif 1376 1377 // release FAT lock 1378 _spin_lock_release( &_fat.fat_lock ); 1379 1380 return fd_id; 1381 } 1382 else 1383 { 1384 _printf("\n[FAT ERROR] in _fat_open() for file %s : fd array full\n", 1385 pathname ); 1386 _spin_lock_release( &_fat.fat_lock ); 1387 return -1; 1388 } 1389 } 3472 // check file open 3473 if ( _fat.fd[fd_id].allocated == 0 ) 3474 { 3475 _spin_lock_release( &_fat.fat_lock ); 3476 _printf("\n[FAT ERROR] in _fat_lseek() : file not open\n"); 3477 return -3; 3478 } 3479 3480 unsigned int new_seek; 3481 3482 // compute new seek 3483 if ( whence == SEEK_CUR ) new_seek = _fat.fd[fd_id].seek + seek; 3484 else if ( whence == SEEK_SET ) new_seek = seek; 1390 3485 else 1391 3486 { 1392 _printf("\n[FAT ERROR] in _fat_open() for file %s : bad cluster\n",1393 pathname );1394 3487 _spin_lock_release( &_fat.fat_lock ); 1395 return -1; 1396 } 1397 } // end _fat_open() 1398 1399 /////////////////////////////////////////////////////////////////////////////// 1400 // For an open file, identified by the file descriptor index, transfer 1401 // an integer number of sectors from block device to a memory buffer. 1402 // If the number of requested sectors exceeds the file size, it is reduced. 1403 /////////////////////////////////////////////////////////////////////////////// 1404 // Returns number of sectors transfered if success, < 0 if error. 1405 /////////////////////////////////////////////////////////////////////////////// 1406 int _fat_read( unsigned int use_irq, // use descheduling mode if possible 1407 unsigned int fd_id, // file descriptor 1408 void* buffer, // target buffer base address 1409 unsigned int count, // number of sector to read 1410 unsigned int offset ) // nuber of sectors to skip in file 1411 { 1412 unsigned int spc = _fat.sectors_per_cluster; 1413 1414 unsigned int file_size; // number of bytes in file 1415 unsigned int file_sectors; // number of sectors in file 1416 unsigned int total_sectors; // actual number of sectors to be transfered 1417 unsigned int cluster; // cluster index 1418 unsigned int clusters_to_skip; // number of clusters to skip because offset 1419 unsigned int sectors_to_skip; // number of sectors to skip in first iteration 1420 1421 // arguments checking 1422 if ( fd_id >= GIET_OPEN_FILES_MAX ) 1423 { 1424 _printf("\n[FAT ERROR] in _fat_read() : illegal file descriptor index\n"); 1425 return -1; 1426 } 1427 if ( _fat.fd[fd_id].used != 1 ) 1428 { 1429 _printf("\n[FAT ERROR] in _fat_read() : file not open\n"); 1430 return -1; 1431 } 1432 if ( ((unsigned int)buffer & 0x1FF) != 0 ) 1433 { 1434 _printf("\n[FAT ERROR] in _fat_read() : memory buffer not sector aligned\n"); 1435 return -1; 1436 } 1437 1438 // compute file size as a number of sectors 1439 file_size = _fat.fd[fd_id].file_size; 1440 if ( file_size & 0x1FF ) file_sectors = (file_size >> 9) + 1; 1441 else file_sectors = (file_size >> 9); 1442 1443 if ( offset >= file_sectors ) 1444 { 1445 _printf("\n[FAT ERROR] offset larger than number of sectors\n"); 1446 return -1; 1447 } 1448 1449 // compute total number of sectors to read 1450 if ( file_sectors < (offset + count) ) total_sectors = file_sectors - offset; 1451 else total_sectors = count; 1452 1453 // compute clusters and sectors to be skipped 1454 clusters_to_skip = offset / spc; 1455 sectors_to_skip = offset % spc; 1456 1457 // get first cluster index 1458 cluster = _fat.fd[fd_id].first_cluster; 3488 _printf("\n[FAT ERROR] in _fat_user_lseek() : illegal whence valuel\n"); 3489 return -4; 3490 } 3491 3492 // update file descriptor offset 3493 _fat.fd[fd_id].seek = new_seek; 1459 3494 1460 3495 #if GIET_DEBUG_FAT … … 1464 3499 unsigned int p = procid & ((1<<P_WIDTH)-1); 1465 3500 if ( _get_proctime() > GIET_DEBUG_FAT ) 1466 _printf("\n[DEBUG FAT] _fat_read() : P[%d,%d,%d] enters for file %s\n" 1467 " - buffer vbase = %x\n" 1468 " - skipped sectors = %x\n" 1469 " - read sectors = %x\n" 1470 " - first cluster = %x\n" 1471 " - skipped clusters = %x\n", 1472 x, y, p, _fat.fd[fd_id].name, (unsigned int)buffer, 1473 offset, count, cluster, clusters_to_skip ); 1474 #endif 1475 1476 // compute index of first cluster to be loaded 1477 while ( clusters_to_skip ) 1478 { 1479 cluster = _get_next_cluster( use_irq , cluster ); 1480 clusters_to_skip--; 1481 } 1482 1483 // variables used in the loop on clusters 1484 int todo_sectors; // number of sectors still to be loaded 1485 unsigned int lba; // first sector index on device 1486 unsigned int iter_sectors; // number of sectors to load in iteration 1487 unsigned int dst; // pointer on target buffer 1488 1489 // initialize these variables for the first iteration 1490 todo_sectors = total_sectors; 1491 dst = (unsigned int)buffer; 1492 lba = cluster_to_lba(cluster) + sectors_to_skip; 1493 if( total_sectors < (spc - sectors_to_skip) ) iter_sectors = total_sectors; 1494 else iter_sectors = spc - sectors_to_skip; 1495 1496 // loop on the clusters: one IOC access per cluster 1497 while ( todo_sectors > 0 ) 1498 { 1499 1500 #if GIET_DEBUG_FAT 1501 if ( _get_proctime() > GIET_DEBUG_FAT ) 1502 _printf("\n[DEBUG FAT] _fat_read() : P[%d,%d,%d] makes an IOC read\n" 1503 " cluster = %x / buffer = %x / lba = %x / sectors = %d\n", 1504 x, y, p, cluster, dst, lba, iter_sectors ); 1505 #endif 1506 1507 if( _fat_ioc_access( use_irq, 1508 1, // read 1509 lba, 1510 dst, // buffer address 1511 iter_sectors ) ) // number of sectors 1512 { 1513 _printf("\n[FAT ERROR] in _fat_read() cannot load block %x", lba ); 1514 return -1; 1515 } 1516 1517 // update variables for next iteration 1518 cluster = _get_next_cluster( use_irq , cluster ); 1519 todo_sectors = todo_sectors - iter_sectors; 1520 dst = dst + (iter_sectors << 9); 1521 lba = cluster_to_lba(cluster); 1522 if ( todo_sectors > spc ) iter_sectors = spc; 1523 else iter_sectors = todo_sectors; 1524 } 1525 1526 // returns number of sectors actually transfered 1527 return total_sectors; 1528 1529 } // end _fat_read() 1530 1531 /////////////////////////////////////////////////////////////////////////////// 1532 // For an open file, identified by the file descriptor index, transfer 1533 // an integer number of sectors from a memory buffer to block device. 1534 // Allocate new clusters if the offset+count larger than current file size, 1535 // but the offset should be smaller than the current file size... 1536 /////////////////////////////////////////////////////////////////////////////// 1537 // Returns number of sectors written if success, < 0 if error. 1538 /////////////////////////////////////////////////////////////////////////////// 1539 int _fat_write( unsigned int use_irq, // use descheduling mode if possible 1540 unsigned int fd_id, // file descriptor 1541 void* buffer, // target buffer base address 1542 unsigned int count, // number of sector to write 1543 unsigned int offset ) // nuber of sectors to skip in file 1544 { 1545 1546 unsigned int spc = _fat.sectors_per_cluster; 1547 1548 unsigned int file_size; // number of bytes in file 1549 unsigned int file_sectors; // number of sectors in file 1550 unsigned int cluster; // cluster index 1551 unsigned int clusters_to_skip; // number of clusters to skip because offset 1552 unsigned int sectors_to_skip; // number of sectors to skip in first iteration 1553 unsigned int allocate; // need allocate or not 1554 unsigned int current_cluster; // number of cluster allocated to the file 1555 unsigned int required_cluster; // number of cluster needed for the write 1556 1557 // compute file size as a number of sectors 1558 file_size = _fat.fd[fd_id].file_size; 1559 if ( file_size & 0x1FF ) file_sectors = (file_size >> 9) + 1; 1560 else file_sectors = (file_size >> 9); 1561 1562 // Compute the number of clusters occupied by the file 1563 current_cluster = file_sectors / spc; 1564 1565 // Compute the number of clusters that will occupy the file (after fat_write) 1566 required_cluster = (count + offset) / spc; 1567 1568 // Check if we need to allocate new cluster(s) for the file 1569 allocate = ( required_cluster > current_cluster ); 3501 _printf("\n[DEBUG FAT] _fat_lseek() : P[%d,%d,%d] set seek = %x for file <%s>\n", 3502 x , y , p , new_seek , _fat.fd[fd_id].inode->name ); 3503 #endif 3504 3505 // release lock 3506 _spin_lock_release( &_fat.fat_lock ); 3507 3508 return new_seek; 3509 } // end _fat_lseek() 3510 3511 3512 3513 ///////////////////////////////////////////////////////////////////////////////// 3514 // The following function implements the giet_fat_remove() system call. 3515 // It deletes the file/directory identified by the "pathname" argument from 3516 // the file system, if the remove condition is fulfilled (directory empty, 3517 // or file not referenced). 3518 // All clusters allocated in the block device DATA region are released. 3519 // The FAT region is updated on the block device. 3520 // The Inode-Tree is updated. 3521 // The associated File_Cache is released. 3522 // The Fat_Cache is updated. 3523 ///////////////////////////////////////////////////////////////////////////////// 3524 // Returns 0 if success. 3525 // Returns negative value if error 3526 // -1 : "FAT not initialised" 3527 // -2 : "File/Directory not found" 3528 // -3 : "Name too long in path" 3529 // -4 : "Has the wrong type" 3530 // -5 : "File still open" 3531 // -6 : "Cannot scan directory" 3532 // -7 : "Directory not empty" 3533 // -8 : "Cannot remove file/dir from FS" 3534 ///////////////////////////////////////////////////////////////////////////////// 3535 int _fat_remove( char* pathname, 3536 unsigned int should_be_dir ) 3537 { 3538 fat_inode_t* inode; // searched file inode pointer 1570 3539 1571 3540 #if GIET_DEBUG_FAT … … 1575 3544 unsigned int p = procid & ((1<<P_WIDTH)-1); 1576 3545 if ( _get_proctime() > GIET_DEBUG_FAT ) 1577 _printf("\n[DEBUG FAT] _fat_write() : P[%d,%d,%d] enters for file %s\n" 1578 " - buffer vbase = %x\n" 1579 " - skipped sectors = %x\n" 1580 " - write sectors = %x\n" 1581 " - file sectors = %x\n" 1582 " - need_allocate = %d\n", 1583 x, y, p, _fat.fd[fd_id].name, (unsigned int)buffer, 1584 offset, count, file_sectors, allocate ); 1585 #endif 1586 1587 // arguments checking 1588 if ( fd_id >= GIET_OPEN_FILES_MAX ) 1589 { 1590 _printf("\n[FAT ERROR] in _fat_write() : illegal file descriptor index\n"); 3546 _printf("\n[DEBUG FAT] _fat_remove() : P[%d,%d,%d] enters for path <%s>\n", 3547 x, y, p, pathname ); 3548 #endif 3549 3550 // checking FAT initialised 3551 if( _fat.initialised != FAT_INITIALISED ) 3552 { 3553 _printf("\n[FAT ERROR] in _fat_remove() : FAT not initialised\n"); 1591 3554 return -1; 1592 3555 } 1593 if ( _fat.fd[fd_id].used != 1 ) 1594 { 1595 _printf("\n[FAT ERROR] in _fat_write() : file not open\n"); 3556 3557 // take the lock 3558 _spin_lock_acquire( &_fat.fat_lock ); 3559 3560 // get searched file inode 3561 unsigned int code = _get_inode_from_path( pathname , &inode ); 3562 3563 #if GIET_DEBUG_FAT 3564 if ( _get_proctime() > GIET_DEBUG_FAT ) 3565 _printf("\n[DEBUG FAT] _fat_remove() : P[%d,%d,%d] found inode %x for <%s> / code = %d\n", 3566 x , y , p , (unsigned int)inode , pathname , code ); 3567 #endif 3568 3569 if ( (code == 1) || (code == 2) ) 3570 { 3571 _spin_lock_release( &_fat.fat_lock ); 3572 _printf("\n[FAT ERROR] in _fat_remove() : file <%s> not found\n", 3573 pathname ); 3574 return -2; 3575 } 3576 else if ( code == 3 ) 3577 { 3578 _spin_lock_release( &_fat.fat_lock ); 3579 _printf("\n[FAT ERROR] in _fat_remove() : name too long in <%s>\n", 3580 pathname ); 3581 return -3; 3582 } 3583 3584 // check inode type 3585 if ( (inode->is_dir != 0) && (should_be_dir == 0) ) 3586 { 3587 _spin_lock_release( &_fat.fat_lock ); 3588 _printf("\n[FAT ERROR] in _fat_remove() : <%s> is a directory\n", 3589 pathname ); 3590 return -4; 3591 } 3592 if ( (inode->is_dir == 0) && (should_be_dir != 0) ) 3593 { 3594 _spin_lock_release( &_fat.fat_lock ); 3595 _printf("\n[FAT ERROR] in _fat_remove() : <%s> is not a directory\n", 3596 pathname ); 3597 return -4; 3598 } 3599 3600 #if GIET_DEBUG_FAT 3601 if ( _get_proctime() > GIET_DEBUG_FAT ) 3602 _printf("\n[DEBUG FAT] _fat_remove() : P[%d,%d,%d] checked inode type for <%s>\n", 3603 x , y , p , pathname ); 3604 #endif 3605 3606 // check references count for a file 3607 if ( (inode->is_dir == 0) && (inode->count != 0) ) 3608 { 3609 _spin_lock_release( &_fat.fat_lock ); 3610 _printf("\n[FAT ERROR] in _fat_remove() : file <%s> still referenced\n", 3611 pathname ); 3612 return -5; 3613 } 3614 3615 // check empty for a directory 3616 if ( inode->is_dir ) 3617 { 3618 unsigned int entries; 3619 if ( _get_nb_entries( inode , &entries ) ) 3620 { 3621 _spin_lock_release( &_fat.fat_lock ); 3622 _printf("\n[FAT ERROR] in _fat_remove() : cannot scan directory <%s>\n", 3623 pathname ); 3624 return -6; 3625 } 3626 else if ( entries > 2 ) 3627 { 3628 _spin_lock_release( &_fat.fat_lock ); 3629 _printf("\n[FAT ERROR] in _fat_remove() : directory <%s> not empty\n", 3630 pathname ); 3631 return -7; 3632 } 3633 } 3634 3635 #if GIET_DEBUG_FAT 3636 if ( _get_proctime() > GIET_DEBUG_FAT ) 3637 _printf("\n[DEBUG FAT] _fat_remove() : P[%d,%d,%d] checked remove condition OK for <%s>\n", 3638 x , y , p , pathname ); 3639 #endif 3640 3641 // remove the file or directory from the file system 3642 if ( _remove_node_from_fs( inode ) ) 3643 { 3644 _spin_lock_release( &_fat.fat_lock ); 3645 _printf("\n[FAT ERROR] in _fat_remove() : cannot remove <%s> from FS\n", 3646 pathname ); 3647 return -8; 3648 } 3649 3650 // release lock and return success 3651 _spin_lock_release( &_fat.fat_lock ); 3652 3653 #if GIET_DEBUG_FAT 3654 if ( _get_proctime() > GIET_DEBUG_FAT ) 3655 _printf("\n[DEBUG FAT] _fat_remove() : P[%d,%d,%d] removed <%s> from FS\n", 3656 x, y, p, pathname ); 3657 #endif 3658 3659 return 0; 3660 3661 } // end _fat_remove() 3662 3663 3664 3665 3666 3667 ///////////////////////////////////////////////////////////////////////////////// 3668 // This function implements the giet_fat_rename() system call. 3669 // It moves an existing file or directory from one node (defined by "old_path" 3670 // argument) to another node (defined by "new_path" argument) in the FS tree. 3671 // The type (file/directory) and content are not modified. 3672 // If the new_path file/dir exist, it is removed from the file system, but only 3673 // if the remove condition is respected (directory empty / file not referenced). 3674 // The removed entry is only removed after the new entry is actually created. 3675 ///////////////////////////////////////////////////////////////////////////////// 3676 // Returns 0 if success. 3677 // Returns a negative value if error: 3678 // -1 : "FAT not initialised" 3679 // -2 : "old_path not found" 3680 // -3 : "new_path not found" 3681 // -4 : "cannot scan to_remove directory" 3682 // -5 : "to_remove directory not empty" 3683 // -6 : "to_remove file still referenced" 3684 // -7 : "cannot add new node to new_parent directory" 3685 // -8 : "cannot update new_parent directory on device" 3686 // -9 : "cannot remove old node from old_parent directory" 3687 // -10 : "cannot update old_parent directory on device" 3688 // -11 : "cannot remove to_remove node from FS" 3689 ///////////////////////////////////////////////////////////////////////////////// 3690 int _fat_rename( char* old_path, 3691 char* new_path ) 3692 { 3693 fat_inode_t* inode; // anonymous inode pointer 3694 fat_inode_t* old; // inode identified by old_path => to be deleted 3695 fat_inode_t* new; // inode identified by new_path => to be created 3696 fat_inode_t* old_parent; // parent inode in old_path => to be modified 3697 fat_inode_t* new_parent; // parent inode in new_path => to be modified 3698 fat_inode_t* to_remove; // previouly identified by new_path => to be removed 3699 unsigned int code; 3700 3701 #if GIET_DEBUG_FAT 3702 unsigned int procid = _get_procid(); 3703 unsigned int x = procid >> (Y_WIDTH + P_WIDTH); 3704 unsigned int y = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 3705 unsigned int p = procid & ((1<<P_WIDTH)-1); 3706 if ( _get_proctime() > GIET_DEBUG_FAT ) 3707 _printf("\n[DEBUG FAT] _fat_rename() : P[%d,%d,%d] enters to move <%s> to <%s>\n", 3708 x , y , p , old_path , new_path ); 3709 #endif 3710 3711 // checking FAT initialised 3712 if( _fat.initialised != FAT_INITIALISED ) 3713 { 3714 _printf("\n[FAT ERROR] in _fat_rename() : FAT not initialised\n"); 1596 3715 return -1; 1597 3716 } 1598 if ( ((unsigned int)buffer & 0x1FF) != 0 ) 1599 { 1600 _printf("\n[FAT ERROR] in _fat_write() : memory buffer not sector aligned\n"); 3717 3718 // take the lock 3719 _spin_lock_acquire( &_fat.fat_lock ); 3720 3721 // get "old" and "old_parent" inode pointers 3722 if ( _get_inode_from_path( old_path , &inode ) ) 3723 { 3724 _spin_lock_release( &_fat.fat_lock ); 3725 _printf("\n[FAT ERROR] in _fat_rename() : <%s> not found\n", old_path ); 3726 return -2; 3727 } 3728 else 3729 { 3730 old = inode; 3731 old_parent = inode->parent; 3732 } 3733 3734 // get "to_removed" and "new_parent" inode pointers 3735 code = _get_inode_from_path( new_path , &inode ); 3736 3737 if ( code == 0 ) // new_path inode already exist 3738 { 3739 to_remove = inode; 3740 new_parent = inode->parent; 3741 } 3742 else if ( code == 1 ) // to_remove does not exist but parent exist 3743 { 3744 to_remove = NULL; 3745 new_parent = inode; 3746 } 3747 else // parent directory in new_path not found 3748 { 3749 _spin_lock_release( &_fat.fat_lock ); 3750 _printf("\n[FAT ERROR] in _fat_rename() : <%s> not found\n", new_path ); 3751 return -3; 3752 } 3753 3754 #if GIET_DEBUG_FAT 3755 if ( _get_proctime() > GIET_DEBUG_FAT ) 3756 { 3757 if ( to_remove ) 3758 _printf("\n[DEBUG FAT] _fat_rename() : old_parent = %s / old = %s / new_parent = %s " 3759 "/ to_remove = %s\n", 3760 old_parent->name , old->name , new_parent->name , to_remove->name ); 3761 else 3762 _printf("\n[DEBUG FAT] _fat_rename() : old_parent = %s / old = %s / new_parent = %s " 3763 "/ no remove\n", 3764 old_parent->name , old->name , new_parent->name ); 3765 } 3766 #endif 3767 3768 // check remove condition for "to_remove" inode 3769 if ( to_remove ) 3770 { 3771 if ( to_remove->is_dir ) // it's a directory 3772 { 3773 unsigned int entries; 3774 if ( _get_nb_entries( to_remove , &entries ) ) 3775 { 3776 _spin_lock_release( &_fat.fat_lock ); 3777 _printf("\n[FAT ERROR] in _fat_rename() : cannot scan directory <%s>\n", 3778 to_remove->name ); 3779 return -4; 3780 } 3781 else if ( entries > 2 ) 3782 { 3783 _spin_lock_release( &_fat.fat_lock ); 3784 _printf("\n[FAT ERROR] in _fat_rename() : directory <%s> not empty\n", 3785 to_remove->name ); 3786 return -5; 3787 } 3788 } 3789 else // it's a file 3790 { 3791 if ( to_remove->count ) 3792 { 3793 _spin_lock_release( &_fat.fat_lock ); 3794 _printf("\n[FAT ERROR] in _fat_rename() : file <%s> still referenced\n", 3795 to_remove->name ); 3796 return -6; 3797 } 3798 } 3799 } 3800 3801 #if GIET_DEBUG_FAT 3802 if ( _get_proctime() > GIET_DEBUG_FAT ) 3803 _printf("\n[FAT DEBUG] _fat_rename() : P[%d,%d,%d] checked remove condition OK\n", 3804 x , y , p ); 3805 #endif 3806 3807 // get new last name / error checking already done by _get_inode_from_path() 3808 char new_name[32]; 3809 _get_last_name( new_path , new_name ); 3810 3811 // allocate "new" inode 3812 new = _allocate_one_inode( new_name, 3813 old->is_dir, 3814 old->cluster, 3815 old->size, 3816 0, // count 3817 0, // dentry 3818 0 ); // no cache_allocate 3819 3820 // give the "old" File-Cache to the "new inode 3821 new->levels = old->levels; 3822 new->cache = old->cache; 3823 3824 // add "new" to "new_parent" directory File-Cache 3825 if ( _add_dir_entry( new , new_parent ) ) 3826 { 3827 _spin_lock_release( &_fat.fat_lock ); 3828 _printf("\n[FAT ERROR] in _fat_rename() : cannot add <%s> into <%s>\n", 3829 new->name , new_parent->name ); 3830 return -7; 3831 } 3832 3833 // add "new" to "new_parent" directory in Inode-Tree 3834 _add_inode_in_tree( new , new_parent ); 3835 3836 // updates "new_parent" directory on device 3837 if ( _update_device_from_cache( new_parent->levels, 3838 new_parent->cache, 3839 new_parent->name ) ) 3840 { 3841 _spin_lock_release( &_fat.fat_lock ); 3842 _printf("\n[FAT ERROR] in _fat_rename() : cannot update <%s> on device\n", 3843 new_parent->name ); 3844 return -8; 3845 } 3846 3847 // remove "old" from "old_parent" File-Cache 3848 if ( _remove_dir_entry( old ) ) 3849 { 3850 _spin_lock_release( &_fat.fat_lock ); 3851 _printf("\n[FAT ERROR] in _fat_rename() : cannot remove <%s> from <%s>\n", 3852 old->name , old_parent->name ); 3853 return -9; 3854 } 3855 3856 // remove "old" inode from Inode-Tree 3857 _remove_inode_from_tree( old ); 3858 3859 // updates "old_parent" directory on device 3860 if ( _update_device_from_cache( old_parent->levels, 3861 old_parent->cache, 3862 old_parent->name ) ) 3863 { 3864 _spin_lock_release( &_fat.fat_lock ); 3865 _printf("\n[FAT ERROR] in _fat_rename() : cannot update <%s> on device\n", 3866 old_parent->name ); 3867 return -10; 3868 } 3869 3870 // remove "to_remove" from File System (if required) 3871 if ( to_remove ) 3872 { 3873 if ( _remove_node_from_fs( to_remove ) ) 3874 { 3875 _spin_lock_release( &_fat.fat_lock ); 3876 _printf("\n[FAT ERROR] in _fat_rename() : cannot remove <%s> from FS\n", 3877 to_remove->name ); 3878 return -11; 3879 } 3880 } 3881 3882 // release lock 3883 _spin_lock_release( &_fat.fat_lock ); 3884 3885 return 0; 3886 } // end _fat_rename() 3887 3888 3889 3890 3891 ///////////////////////////////////////////////////////////////////////////////// 3892 // The following function implements the giet_fat_mkdir() system call. 3893 // It creates in file system the directory specified by the "pathname" argument. 3894 // The Inode-Tree is updated. 3895 // One cluster is allocated to the new directory. 3896 // The associated File-Cache is created. 3897 // The FAT region on block device is updated. 3898 // The DATA region on block device is updated. 3899 ///////////////////////////////////////////////////////////////////////////////// 3900 // Returns 0 if success. 3901 // Returns a negative value if error: 3902 // -1 : "Fat not initialised" 3903 // -2 : "Path to parent not found" 3904 // -3 : "One name in path too long" 3905 // -4 : "Directory already exist" 3906 // -5 : "No free cluster" 3907 // -6 : "Cannot update parent directory" 3908 // -7 : "Cannot update parent DATA region" 3909 // -8 : "Cannot update FAT region" 3910 // -9 : "Cannot update FS-INFO" 3911 // -10 : "Cannot update directory DATA region" 3912 ///////////////////////////////////////////////////////////////////////////////// 3913 int _fat_mkdir( char* pathname ) 3914 { 3915 fat_inode_t* inode; // anonymous inode pointer 3916 fat_inode_t* child; // searched directory inode pointer 3917 fat_inode_t* parent; // parent directory inode pointer 3918 3919 #if GIET_DEBUG_FAT 3920 unsigned int procid = _get_procid(); 3921 unsigned int x = procid >> (Y_WIDTH + P_WIDTH); 3922 unsigned int y = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 3923 unsigned int p = procid & ((1<<P_WIDTH)-1); 3924 if ( _get_proctime() > GIET_DEBUG_FAT ) 3925 _printf("\n[DEBUG FAT] _fat_mkdir() : P[%d,%d,%d] enters for path <%s>\n", 3926 x, y, p, pathname ); 3927 #endif 3928 3929 // checking FAT initialised 3930 if( _fat.initialised != FAT_INITIALISED ) 3931 { 3932 _printf("\n[FAT ERROR] in _fat_mkdir() : FAT not initialised\n"); 1601 3933 return -1; 1602 3934 } 1603 3935 1604 if ( allocate ) 1605 { 1606 if ( _fat_allocate( use_irq , fd_id, (required_cluster-current_cluster) ) ) 1607 { 1608 _printf("\n[FAT ERROR] in _fat_write() : fat_allocate failed\n"); 1609 return -1; 1610 } 1611 } 1612 1613 // compute clusters and sectors to be skipped 1614 clusters_to_skip = offset / spc; 1615 sectors_to_skip = offset % spc; 3936 // takes the lock 3937 _spin_lock_acquire( &_fat.fat_lock ); 1616 3938 1617 // get first cluster index 1618 cluster = _fat.fd[fd_id].first_cluster; 3939 // get inode 3940 unsigned int code = _get_inode_from_path( pathname , &inode ); 3941 3942 if ( code == 2 ) 3943 { 3944 _spin_lock_release( &_fat.fat_lock ); 3945 _printf("\n[FAT ERROR] in _fat_mkdir() : path to parent not found" 3946 " for directory <%s>\n", pathname ); 3947 return -2; 3948 } 3949 else if ( code == 3 ) 3950 { 3951 _spin_lock_release( &_fat.fat_lock ); 3952 _printf("\n[FAT ERROR] in _fat_mkdir() : one name in path too long" 3953 " for directory <%s>\n", pathname ); 3954 return -3; 3955 } 3956 else if ( code == 0 ) 3957 { 3958 _spin_lock_release( &_fat.fat_lock ); 3959 _printf("\n[FAT ERROR] in _fat_mkdir() : directory <%s> already exist\n", 3960 pathname ); 3961 return -4; 3962 } 3963 else if ( code == 1 ) // directory not found => create 3964 { 3965 parent = inode; 1619 3966 1620 3967 #if GIET_DEBUG_FAT 1621 3968 if ( _get_proctime() > GIET_DEBUG_FAT ) 1622 _printf("\n[DEBUG FAT] _fat_write() : P[%d,%d,%d] get cluster %x\n", 1623 x, y, p, cluster ); 1624 #endif 1625 1626 // compute index of first cluster to be loaded 1627 while ( clusters_to_skip ) 1628 { 1629 cluster = _get_next_cluster( use_irq , cluster ); 1630 clusters_to_skip--; 1631 } 1632 1633 // variables used in the loop on clusters 1634 int todo_sectors; // number of sectors still to be loaded 1635 unsigned int lba; // first sector index on device 1636 unsigned int iter_sectors; // number of sectors to load in iteration 1637 unsigned int src; // pointer on target buffer 1638 1639 // initialize these variables for the first iteration 1640 todo_sectors = count; 1641 src = (unsigned int)buffer; 1642 lba = cluster_to_lba(cluster) + sectors_to_skip; 1643 if( count < (spc - sectors_to_skip) ) iter_sectors = count; 1644 else iter_sectors = spc - sectors_to_skip; 1645 1646 // loop on the clusters 1647 while ( todo_sectors > 0 ) 1648 { 3969 _printf("\n[DEBUG FAT] _fat_mkdir() : P[%d,%d,%d] create new directory <%s>\n", 3970 x , y , p , pathname ); 3971 #endif 3972 3973 // get directory name / error check already done by _get_inode_from_path() 3974 char name[32]; 3975 _get_last_name( pathname , name ); 3976 3977 // allocate one cluster from FAT for the new directory 3978 unsigned int cluster; 3979 if ( _allocate_one_cluster( &cluster ) ) 3980 { 3981 _spin_lock_release( &_fat.fat_lock ); 3982 _printf("\n[FAT ERROR] in _fat_mkdir() : no free cluster" 3983 " for directory <%s>\n" , pathname ); 3984 return -5; 3985 } 3986 3987 // allocate a new inode and an empty Cache-File 3988 child = _allocate_one_inode( name, 3989 1, // it's a directory 3990 cluster, 3991 0, // size not defined 3992 0, // count 3993 0, // dentry set by _add_dir_entry() 3994 1 ); // cache_allocate 3995 3996 // introduce inode in Inode-Tree 3997 _add_inode_in_tree( child , parent ); 3998 3999 // allocate and initialise one 4 Kbytes buffer and associated descriptor 4000 _allocate_one_buffer( child, 4001 0, // cluster_id, 4002 cluster ); 4003 4004 _add_special_directories( child, 4005 parent ); 4006 4007 // add an entry in the parent directory Cache_file 4008 if ( _add_dir_entry( child , parent ) ) 4009 { 4010 _spin_lock_release( &_fat.fat_lock ); 4011 _printf("\n[FAT ERROR] in _fat_mkdir() : cannot update parent directory" 4012 " for directory <%s>\n" , pathname ); 4013 return -6; 4014 } 4015 4016 // update DATA region on block device for parent directory 4017 if ( _update_device_from_cache( parent->levels, 4018 parent->cache, 4019 parent->name ) ) 4020 { 4021 _spin_lock_release( &_fat.fat_lock ); 4022 _printf("\n[FAT ERROR] in _fat_mkdir() : cannot update DATA region " 4023 " for parent of directory <%s>\n", pathname ); 4024 return -7; 4025 } 4026 4027 // update FAT region on block device 4028 if ( _update_device_from_cache( _fat.fat_cache_levels, 4029 _fat.fat_cache_root, 4030 "FAT" ) ) 4031 { 4032 _spin_lock_release( &_fat.fat_lock ); 4033 _printf("\n[FAT ERROR] in _fat_mkdir() : cannot update FAT region" 4034 " for directory <%s>\n", pathname ); 4035 return -8; 4036 } 4037 4038 // update FS_INFO sector 4039 if ( _update_fs_info() ) 4040 { 4041 _spin_lock_release( &_fat.fat_lock ); 4042 _printf("\n[FAT ERROR] in _fat_mkdir() : cannot update FS-INFO" 4043 " for directory <%s>\n", pathname ); 4044 return -9; 4045 } 4046 4047 // update DATA region on block device for the new directory 4048 if ( _update_device_from_cache( child->levels, 4049 child->cache, 4050 child->name ) ) 4051 { 4052 _spin_lock_release( &_fat.fat_lock ); 4053 _printf("\n[FAT ERROR] in _fat_mkdir() : cannot update DATA region" 4054 " for directory <%s>\n", pathname ); 4055 return -10; 4056 } 4057 } // end create directory 4058 4059 return 0; 4060 } // end _fat_mkdir() 4061 4062 4063 4064 4065 4066 ///////////////////////////////////////////////////////////////////////////////// 4067 // The following function implements the giet_fat_list() system call. 4068 // It displays the content of a directory identified by the "pathname" argument. 4069 // It returns an error code if the pathname is not a directory. 4070 ///////////////////////////////////////////////////////////////////////////////// 4071 // Returns 0 if success. 4072 // Returns a negative value if error: 4073 // -1 : "FAT not initialised 4074 // -2 : "Directory not found" 4075 // -3 : "Name in path too long 4076 // -4 : "Not a directory" 4077 // -5 : "Cannot access directory" 4078 // -6 : "Name too long truncated" 4079 ///////////////////////////////////////////////////////////////////////////////// 4080 int _fat_list( char* pathname ) 4081 { 4082 fat_inode_t* inode; 4083 4084 // checking FAT initialised 4085 if( _fat.initialised != FAT_INITIALISED ) 4086 { 4087 _printf("\n[FAT ERROR] in _fat_list() : FAT not initialised\n"); 4088 return -1; 4089 } 1649 4090 1650 4091 #if GIET_DEBUG_FAT 1651 if ( _get_proctime() > GIET_DEBUG_FAT ) 1652 _printf("\n[DEBUG FAT] _fat_write() : P[%d,%d,%d] makes an IOC write" 1653 " cluster = %x / buffer = %x / lba = %x / sectors = %d\n", 1654 x, y, p, cluster, src, lba, iter_sectors ); 1655 #endif 1656 1657 if( _fat_ioc_access( use_irq, 1658 0, // write 4092 unsigned int procid = _get_procid(); 4093 unsigned int x = procid >> (Y_WIDTH + P_WIDTH); 4094 unsigned int y = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 4095 unsigned int p = procid & ((1<<P_WIDTH)-1); 4096 if ( _get_proctime() > GIET_DEBUG_FAT ) 4097 _printf("\n[DEBUG FAT] _fat_list() : P[%d,%d,%d] enters for path <%s>\n", 4098 x, y, p, pathname ); 4099 #endif 4100 4101 // get inode 4102 unsigned int code = _get_inode_from_path( pathname , &inode ); 4103 4104 if ( (code == 1) || (code == 2) ) 4105 { 4106 _printf("\n[FAT ERROR] in _fat_list() : directory <%s> not found\n", pathname ); 4107 return -2; 4108 } 4109 if ( code == 3 ) 4110 { 4111 _printf("\n[FAT ERROR] in _fat_list() : name too long in path <%s>\n", pathname ); 4112 return -3; 4113 } 4114 4115 // check found inode is a directory 4116 if ( inode->is_dir == 0 ) 4117 { 4118 _printf("\n[FAT ERROR] in _fat_list() : <%s> is not a directory\n", pathname ); 4119 return -4; 4120 } 4121 4122 #if GIET_DEBUG_FAT 4123 if ( _get_proctime() > GIET_DEBUG_FAT ) 4124 _printf("\n[DEBUG FAT] _fat_list() : P[%d,%d,%d] found inode for path <%s>\n", 4125 x, y, p, pathname ); 4126 #endif 4127 4128 // scan directory up to end of directory / two embedded loops : 4129 // - loop on the clusters allocated to the directory 4130 // - loop on the directory entries in each 4 Kbytes buffer 4131 unsigned char* buffer; 4132 fat_cache_desc_t* pdesc; 4133 unsigned int cluster_id = 0; // cluster index in directory 4134 unsigned int offset = 0; // position in scanned buffer 4135 unsigned int lfn = 0; // number of lfn entries 4136 unsigned int nb_entries = 0; // number of directory entries 4137 unsigned int done = 0; // end of directory found 4138 unsigned int attr; // ATTR field value 4139 unsigned int ord; // ORD field value 4140 char lfn1[16]; // temporary buffer for string in LFN1 4141 char lfn2[16]; // temporary buffer for string in LFN2 4142 char lfn3[16]; // temporary buffer for string in LFN3 4143 char name[36]; // directory entry full name 4144 unsigned int cluster; // directory entry cluster index 4145 unsigned int size; // directory entry size 4146 unsigned int is_dir; // directory entry is a directory 4147 unsigned int is_vid; // directory entry is volume_id 4148 4149 // TODO : define a method to transfer this information to user mode 4150 _printf("\n<%s> cluster = %x / lba = %x\n", pathname , 4151 inode->cluster , _cluster_to_lba( inode->cluster) ); 4152 4153 while ( done == 0 ) 4154 { 4155 // get one 4 Kytes buffer 4156 if ( _get_buffer_from_cache( inode, 4157 cluster_id, 4158 &pdesc ) ) 4159 { 4160 _printf("\n[FAT ERROR] in _fat_list() : cannot access <%s>\n", pathname ); 4161 return -5; 4162 } 4163 buffer = pdesc->buffer; 4164 4165 // scan this 4 Kbytes buffer 4166 while ( (offset < 4096) && (done == 0) ) 4167 { 4168 attr = _read_entry( DIR_ATTR , buffer + offset , 0 ); 4169 ord = _read_entry( LDIR_ORD , buffer + offset , 0 ); 4170 4171 if (ord == NO_MORE_ENTRY) // no more entry in directory => break 4172 { 4173 done = 1; 4174 } 4175 else if ( ord == FREE_ENTRY ) // free entry => skip 4176 { 4177 offset = offset + 32; 4178 } 4179 else if ( attr == ATTR_LONG_NAME_MASK ) // LFN entry => get partial names 4180 { 4181 unsigned int seq = ord & 0x3; 4182 lfn = (seq > lfn) ? seq : lfn; 4183 if ( seq == 1 ) _get_name_from_long( buffer + offset, lfn1 ); 4184 else if ( seq == 2 ) _get_name_from_long( buffer + offset, lfn2 ); 4185 else if ( seq == 3 ) _get_name_from_long( buffer + offset, lfn3 ); 4186 offset = offset + 32; 4187 } 4188 else // NORMAL entry 4189 { 4190 if ( lfn == 0 ) 4191 { 4192 _get_name_from_short( buffer + offset , name ); 4193 } 4194 else if ( lfn == 1 ) 4195 { 4196 _strcpy( name , lfn1 ); 4197 } 4198 else if ( lfn == 2 ) 4199 { 4200 _strcpy( name , lfn1 ); 4201 _strcpy( name + 13 , lfn2 ); 4202 } 4203 else if ( lfn == 3 ) 4204 { 4205 _strcpy( name , lfn1 ); 4206 _strcpy( name + 13 , lfn2 ); 4207 _strcpy( name + 26 , lfn3 ); 4208 } 4209 4210 is_dir = ((attr & ATTR_DIRECTORY) == ATTR_DIRECTORY); 4211 is_vid = ((attr & ATTR_VOLUME_ID) == ATTR_VOLUME_ID); 4212 size = (_read_entry( DIR_FILE_SIZE , buffer + offset , 1 ) ) ; 4213 cluster = (_read_entry( DIR_FST_CLUS_HI , buffer + offset , 1 ) << 16) | 4214 (_read_entry( DIR_FST_CLUS_LO , buffer + offset , 1 ) ) ; 4215 4216 if ( is_vid == 0 ) 4217 { 4218 // TODO : define a method to transfer this information to user mode 4219 if (is_dir) _printf(" DIR | size = %X | cluster = %X | %s\n", 4220 size , cluster, name ); 4221 else _printf(" FILE | size = %X | cluster = %X | %s\n", 4222 size , cluster, name ); 4223 nb_entries++; 4224 } 4225 4226 offset = offset + 32; 4227 lfn = 0; 4228 } 4229 } // end loop on directory entries 4230 4231 if ( done == 0 ) 4232 { 4233 cluster_id++; 4234 offset = 0; 4235 } 4236 } // end loop on buffers 4237 4238 // TODO : define a method to transfer this information to user mode 4239 _printf(" total = %d entries\n", nb_entries ); 4240 4241 return 0; 4242 } // end _fat_list() 4243 4244 4245 4246 4247 4248 /////////////////////////////////////////////////////////////////////////////// 4249 // This functiond load a file identified by the "pathname" argument into the 4250 // memory buffer defined by the "buffer_vbase" and "buffer_size" arguments. 4251 // It is intended to be called by the boot-loader, as it does not use the 4252 // dynamically allocated FAT structures (Inode-Tree, Fat_Cache or File-Cache, 4253 // File-Descriptor-Array). 4254 // It uses only the 512 bytes buffer defined in the FAT descriptor. 4255 /////////////////////////////////////////////////////////////////////////////// 4256 // Returns 0 if success. 4257 // Returns negative value if error: 4258 // -1 : "FAT not initialised" 4259 // -2 : "File not found" 4260 // -3 : "Buffer too small" 4261 // -4 : "Cannot access block device" 4262 // -5 : "Cannot access FAT on block device" 4263 /////////////////////////////////////////////////////////////////////////////// 4264 int _fat_load_no_cache( char* pathname, 4265 unsigned int buffer_vbase, 4266 unsigned int buffer_size ) 4267 { 4268 // checking FAT initialised 4269 if( _fat.initialised != FAT_INITIALISED ) 4270 { 4271 _printf("\n[FAT ERROR] in _fat_load_no_cache() : FAT not initialised\n"); 4272 return -1; 4273 } 4274 4275 unsigned int file_size; 4276 unsigned int cluster; 4277 4278 #if GIET_DEBUG_FAT 4279 unsigned int procid = _get_procid(); 4280 unsigned int x = procid >> (Y_WIDTH + P_WIDTH); 4281 unsigned int y = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1); 4282 unsigned int p = procid & ((1<<P_WIDTH)-1); 4283 if ( _get_proctime() > GIET_DEBUG_FAT ) 4284 _printf("\n[DEBUG FAT] _fat_load_no_cache() : P[%d,%d,%d] enters for file <%s>\n", 4285 x , y , p , pathname ); 4286 #endif 4287 4288 // get file size, and cluster index in FAT 4289 if ( _file_info_no_cache( pathname, 4290 &cluster, 4291 &file_size ) ) 4292 { 4293 _printf("\n[FAT ERROR] in _fat_load_no_cache() : file <%s> not found\n", 4294 pathname ); 4295 return -2; 4296 } 4297 4298 // check buffer size 4299 if ( file_size > buffer_size ) 4300 { 4301 _printf("\n[FAT ERROR] in _fat_load_no_cache() : buffer too small : " 4302 "file_size = %x / buffer_size = %x", file_size , buffer_size ); 4303 return -3; 4304 } 4305 4306 // compute total number of clusters to read 4307 unsigned int nb_clusters = file_size >> 12; 4308 if ( file_size & 0xFFF ) nb_clusters++; 4309 4310 // initialise buffer address 4311 unsigned int dst = buffer_vbase; 4312 4313 // loop on the clusters containing the file 4314 while ( nb_clusters > 0 ) 4315 { 4316 unsigned int lba = _cluster_to_lba( cluster ); 4317 4318 if( _fat_ioc_access( 0, // no descheduling 4319 1, // read 1659 4320 lba, 1660 src, // source buffer address1661 iter_sectors ) ) // number of sectors1662 { 1663 _printf("\n[FAT ERROR] in _fat_ write() cannot write block %x\n", lba );1664 return - 1;4321 dst, 4322 8 ) ) // 8 blocks 4323 { 4324 _printf("\n[FAT ERROR] in _fat_no _cache_read() : cannot load lba %x", lba ); 4325 return -4; 1665 4326 } 1666 4327 4328 4329 // compute next cluster index 4330 unsigned int next; 4331 if ( _next_cluster_no_cache( cluster , &next ) ) 4332 { 4333 _printf("\n[FAT ERROR] in _fat_no _cache_read() : cannot get next cluster " 4334 " for cluster = %x\n", cluster ); 4335 return -5; 4336 } 4337 1667 4338 // update variables for next iteration 1668 cluster = _get_next_cluster( use_irq , cluster ); 1669 todo_sectors = todo_sectors - iter_sectors; 1670 src = src + (iter_sectors << 9); 1671 lba = cluster_to_lba(cluster); 1672 if ( todo_sectors > spc ) iter_sectors = spc; 1673 else iter_sectors = todo_sectors; 1674 } 1675 1676 // Update structure file descriptor, field file_size with 1677 // the new file size if the file is bigger than the previous file 1678 if ( ( offset + count ) > file_sectors ) 1679 { 1680 _fat.fd[fd_id].file_size = (count + offset) << 9; 1681 } 1682 1683 // Update entry of directory with the new value 1684 // of file size (Field : DIR_FILE_SIZE) 1685 if ( _update_entry( use_irq, fd_id , DIR_FILE_SIZE , _fat.fd[fd_id].file_size ) ) 1686 { 1687 _printf("\n[FAT ERROR] in _fat_write() update entry failed\n"); 1688 return -1; 4339 nb_clusters = nb_clusters - 1; 4340 dst = dst + 4096; 4341 cluster = next; 1689 4342 } 1690 4343 1691 // returns number of sectors actually transfered 1692 return count; 1693 } // end _fat_write() 1694 1695 ///////////////////////////////////////////////////////////////////////////////// 1696 // Return stats of a file identified by "fd". 1697 // (Only the file_size in sectors for this moment) 1698 ///////////////////////////////////////////////////////////////////////////////// 1699 // Returns file size (on sectors) on success, -1 on failure. 1700 ///////////////////////////////////////////////////////////////////////////////// 1701 int _fat_fstat( unsigned int fd_id ) 1702 { 1703 unsigned int file_size = 0; 1704 unsigned int file_sectors = 0; 1705 1706 if( (fd_id < GIET_OPEN_FILES_MAX) ) 1707 { 1708 file_size = _fat.fd[fd_id].file_size; 1709 1710 if ( file_size & 0x1FF ) file_sectors = (file_size >> 9) + 1; 1711 else file_sectors = (file_size >> 9); 1712 1713 return file_sectors; 1714 } 1715 else 1716 { 1717 _printf("\n[FAT ERROR] in _fat_fstat() : illegal file descriptor index\n"); 1718 return -1; 1719 } 1720 } // end _fat_fstat() 1721 1722 ///////////////////////////////////////////////////////////////////////////////// 1723 // Close the file identified by the file_descriptor index. 1724 ///////////////////////////////////////////////////////////////////////////////// 1725 // Returns 0 on success, -1 on failure. 1726 ///////////////////////////////////////////////////////////////////////////////// 1727 int _fat_close( unsigned int fd_id ) 1728 { 1729 if( (fd_id < GIET_OPEN_FILES_MAX) ) 1730 { 1731 _fat.fd[fd_id].used = 0; 1732 return 0; 1733 } 1734 else 1735 { 1736 _printf("\n[FAT ERROR] in _fat_close() : illegal file descriptor index\n"); 1737 return -1; 1738 } 1739 } // end fat_close() 1740 1741 ///////////////////////////////////////////////////////////////////////////////// 1742 // The following function implement the user_level system call. 1743 // The flags argument is not used, as file access modes are not implemented yet. 1744 ///////////////////////////////////////////////////////////////////////////////// 1745 // Return the file descriptor index if success / return -1 if failure 1746 ///////////////////////////////////////////////////////////////////////////////// 1747 int _fat_user_open( char* pathname, // absolute pathname from root 1748 unsigned int flags ) // unused: TODO 1749 { 1750 return _fat_open( 1, // use descheduling mode if possible 1751 pathname, 1752 0 ); // no creation if not found 1753 } 1754 1755 ///////////////////////////////////////////////////////////////////////////////// 1756 // The following function implement the user_level system call. 1757 // This function should be modified to respect the UNIX specification. 1758 ///////////////////////////////////////////////////////////////////////////////// 1759 // Return number of sectors actually transfered if success / return -1 if failure 1760 ///////////////////////////////////////////////////////////////////////////////// 1761 int _fat_user_read( unsigned int fd, // file descriptor index 1762 void* buffer, // destination buffer 1763 unsigned int count, // number of sectors to read 1764 unsigned int offset ) // number of sectors to skip 1765 { 1766 return _fat_read( 1, // use descheduling mode if possible 1767 fd, 1768 buffer, 1769 count, 1770 offset ); 1771 } 1772 1773 ///////////////////////////////////////////////////////////////////////////////// 1774 // The following function implement the user_level system call. 1775 // This function should be modified to respect the UNIX specification. 1776 ///////////////////////////////////////////////////////////////////////////////// 1777 // Return number of sectors actually transfered if success / return -1 if failure 1778 ///////////////////////////////////////////////////////////////////////////////// 1779 int _fat_user_write( unsigned int fd, // file descriptor 1780 void* buffer, // source buffer 1781 unsigned int count, // number of sectors to write 1782 unsigned int offset ) // number of sectors to skip on file 1783 { 1784 return _fat_write( 1, // use descheduling mode if possible 1785 fd, 1786 buffer, 1787 count, 1788 offset ); 1789 } 1790 1791 ///////////////////////////////////////////////////////////////////////////////// 1792 int _fat_user_lseek( unsigned int fd_id, 1793 unsigned int offset, 1794 unsigned int whence ) 1795 { 1796 _printf("\n[GIET ERROR] _fat_user_lseek() not implemented\n"); 1797 _exit(); 4344 #if GIET_DEBUG_FAT 4345 if ( _get_proctime() > GIET_DEBUG_FAT ) 4346 _printf("\n[DEBUG FAT] _fat_load_no_cache() : P[%d,%d,%d] loaded <%s> at vaddr = %x" 4347 " / size = %x\n", x , y , p , pathname , buffer_vbase , file_size ); 4348 #endif 4349 1798 4350 return 0; 1799 } 4351 } // end _fat_load_no_cache() 4352 1800 4353 1801 4354 -
soft/giet_vm/giet_fat32/fat32.h
r530 r587 2 2 // File : fat32.h 3 3 // Date : 01/09/2013 4 // Author : Marco Jankovic / Alain Greiner4 // Author : Alain Greiner / Marco Jankovic 5 5 // Copyright (c) UPMC-LIP6 6 6 //////////////////////////////////////////////////////////////////////////////// … … 68 68 #define FS_SIGNATURE_POSITION_2 484 , 4 69 69 #define FS_SIGNATURE_POSITION_3 508 , 4 70 #define FS_FREE_CLUSTER 70 #define FS_FREE_CLUSTERS 488 , 4 71 71 #define FS_FREE_CLUSTER_HINT 492 , 4 72 72 /*******************************************************************************/ … … 74 74 #define DIR_ENTRY_SIZE 32 75 75 76 #define NAME_MAX_SIZE 31 77 76 78 /******* Directory Entry Structure (32 bytes) **********************************/ 77 // offset | length78 #define DIR_NAME 0 , 11 // dir_entry name79 #define DIR_ATTR 11 , 1 // attributes80 #define DIR_NTRES 12 , 1 // reserved for the OS81 #define DIR_CRT_TIMES_TENTH 13 , 182 #define DIR_FST_CLUS_HI 20 , 2 // cluster index 16 MSB bits83 #define DIR_WRT_TIME 22 , 2 // time of last write84 #define DIR_WRT_DATE 24 , 2 // date of last write85 #define DIR_FST_CLUS_LO 26 , 2 // cluster index 16 LSB bit86 #define DIR_FILE_SIZE 28 , 4 // file size (up to 4 giga bytes)79 // offset | length 80 #define DIR_NAME 0 , 11 // dir_entry name 81 #define DIR_ATTR 11 , 1 // attributes 82 #define DIR_NTRES 12 , 1 // reserved for the OS 83 #define DIR_CRT_TIMES_TENTH 13 , 1 84 #define DIR_FST_CLUS_HI 20 , 2 // cluster index 16 MSB bits 85 #define DIR_WRT_TIME 22 , 2 // time of last write 86 #define DIR_WRT_DATE 24 , 2 // date of last write 87 #define DIR_FST_CLUS_LO 26 , 2 // cluster index 16 LSB bit 88 #define DIR_FILE_SIZE 28 , 4 // file size (up to 4 giga bytes) 87 89 /*******************************************************************************/ 88 90 89 91 /******* LFN Directory Entry Structure (32 bytes) *****************************/ 90 // offset | length91 #define LDIR_ORD 0 , 1 // Sequence number (from 0x01 to 0x0f)92 #define LDIR_NAME_1 1 , 10 // name broken into 3 parts93 #define LDIR_ATTR 11 , 1 // attributes (must be 0x0F)94 #define LDIR_TYPE 12 , 1 // directory type (must be 0x00)95 #define LDIR_CHKSUM 13 , 1 // checksum of name in short dir96 #define LDIR_NAME_2 14 , 1297 #define LDIR_RSVD 26 , 2 // artifact of previous fat (must be 0)98 #define LDIR_NAME_3 28 , 492 // offset | length 93 #define LDIR_ORD 0 , 1 // Sequence number (from 0x01 to 0x0f) 94 #define LDIR_NAME_1 1 , 10 // name broken into 3 parts 95 #define LDIR_ATTR 11 , 1 // attributes (must be 0x0F) 96 #define LDIR_TYPE 12 , 1 // directory type (must be 0x00) 97 #define LDIR_CHKSUM 13 , 1 // checksum of name in short dir 98 #define LDIR_NAME_2 14 , 12 99 #define LDIR_RSVD 26 , 2 // artifact of previous fat (must be 0) 100 #define LDIR_NAME_3 28 , 4 99 101 /*******************************************************************************/ 100 102 101 103 /*********************** DIR_ATTR values (attributes) ************************/ 102 #define ATTR_READ_ONLY 0x01103 #define ATTR_HIDDEN 0x02104 #define ATTR_SYSTEM 0x04105 #define ATTR_VOLUME_ID 0x08106 #define ATTR_DIRECTORY 0x10107 #define ATTR_ARCHIVE 0x20108 #define ATTR_LONG_NAME_MASK 0x0f // READ_ONLY|HIDDEN|SYSTEM|VOLUME_ID104 #define ATTR_READ_ONLY 0x01 105 #define ATTR_HIDDEN 0x02 106 #define ATTR_SYSTEM 0x04 107 #define ATTR_VOLUME_ID 0x08 108 #define ATTR_DIRECTORY 0x10 109 #define ATTR_ARCHIVE 0x20 110 #define ATTR_LONG_NAME_MASK 0x0f // READ_ONLY|HIDDEN|SYSTEM|VOLUME_ID 109 111 /*******************************************************************************/ 110 112 111 113 /********************* DIR_ORD special values **********************************/ 112 #define FREE_ENTRY 0xE5 // this entry is free in the directory113 #define NO_MORE_ENTRY 0x00 // no more entry in the directory114 #define FREE_ENTRY 0xE5 // this entry is free in the directory 115 #define NO_MORE_ENTRY 0x00 // no more entry in the directory 114 116 /*******************************************************************************/ 115 117 116 118 /******************** CLuster Index Special Values *****************************/ 117 #define FREE_CLUSTER 0x00000000 118 #define RESERVED_CLUSTER 0x00000001 119 #define BAD_CLUSTER 0x0FFFFFF7 120 #define END_OF_CHAIN_CLUSTER 0x0ffffff8 121 /*******************************************************************************/ 119 #define FREE_CLUSTER 0x00000000 120 #define RESERVED_CLUSTER 0x00000001 121 #define BAD_CLUSTER 0x0FFFFFF7 122 #define END_OF_CHAIN_CLUSTER_MIN 0x0ffffff8 123 #define END_OF_CHAIN_CLUSTER_MAX 0x0fffffff 124 /*******************************************************************************/ 125 126 127 #define SEEK_SET 0 128 #define SEEK_CUR 1 122 129 123 130 #define FAT_INITIALISED 0xBABEF00D 124 131 125 /************ This struct defines a file descriptor ****************************/ 126 typedef struct file_descriptor_s 127 { 128 unsigned int used; // descriptor contains an open file 129 unsigned int first_cluster; // first cluster index on disk 130 unsigned int file_size; // number of bytes 131 unsigned int lba_dir_entry; // lba of dir_entry for an open file 132 char name[244]; // pathname 133 } file_desc_t; 134 /*******************************************************************************/ 135 136 /************ This struct describes a FAT32 disk *******************************/ 137 typedef struct fat32_fs_s 138 { 139 char fat_cache[512]; // FAT cache: 1 sector 140 spin_lock_t fat_lock; // lock protecting exclusive access 141 file_desc_t fd[GIET_OPEN_FILES_MAX]; // file descriptors array 142 unsigned int initialised; // 0xBABEF00D when FAT initialised 143 unsigned int sector_size; // number of bytes (power of 2) 144 unsigned int sectors_per_cluster; // power of 2 (must be greater than 4) 145 unsigned int cluster_size; // sector_size * sector_per_cluster 146 unsigned int fat_sectors; // number of sectors for 1 FAT copy 147 unsigned int fat_lba; // lba of first FAT sector 148 unsigned int data_lba; // lba of first data sector 149 unsigned int cache_lba; // lba of sector loaded in fat_cache 150 unsigned int last_cluster_allocated; // Last known cluster allocated 151 unsigned int number_free_cluster; // number of free clusters 152 unsigned int fs_info_lba; // lba of fs_info 153 } fat32_fs_t; 154 /*******************************************************************************/ 132 #define O_RDONLY 0x01 133 #define O_CREATE 0x20 134 135 /******************************************************************************** 136 This struct defines a non terminal node in a 64-tree implementing a File-Cache 137 associated to an open file, or the Fat-Cache, associated to the FAT itself. 138 Each node has 64 children, and we use the void* type, because the children 139 can be non-terminal (fat_cache_node_t) or terminal (fat_cache_cluster_t). 140 ********************************************************************************/ 141 142 typedef struct fat_cache_node_s 143 { 144 void* children[64]; // pointers on the 64 children 145 } fat_cache_node_t; 146 147 148 /******************************************************************************** 149 This struct defines a cluster descriptor, that is a leaf cell in a 64-tree. 150 Each cluster descriptor contains a pointer on a 4K bytes buffer, and the 151 lba on block device. 152 ********************************************************************************/ 153 154 typedef struct fat_cache_desc_s 155 { 156 unsigned int lba; // cluster lba on block device 157 unsigned int dirty; // modified if non zero 158 unsigned char* buffer; // pointer on the 4 Kbytes buffer 159 } fat_cache_desc_t; 160 161 162 /******************************************************************************** 163 This struct defines a file/directory inode / size = 64 bytes 164 ********************************************************************************/ 165 166 typedef struct fat_inode_s 167 { 168 struct fat_inode_s* parent; // parent directory inode 169 struct fat_inode_s* next; // next inode in same directory 170 struct fat_inode_s* child; // first children inode (dir only) 171 fat_cache_node_t* cache; // pointer on the file_cache root 172 unsigned int cluster; // first cluster index in FAT 173 unsigned int size; // number of bytes (file only) 174 unsigned int count; // number open if file / 0 if dir 175 unsigned short dentry; // directory entry index in parent 176 unsigned char levels; // number of levels in file_cache 177 unsigned char is_dir; // directory if non zero 178 char name[32]; // file directory name 179 } fat_inode_t; 180 181 /******************************************************************************** 182 This struct defines a file descriptor (handler) / size = 16 bytes 183 ********************************************************************************/ 184 185 typedef struct fat_file_desc_s 186 { 187 unsigned int seek; // current offset value (bytes) 188 fat_inode_t* inode; // pointer on inode 189 char allocated; // file descriptor allocated 190 char read_only; // write protected 191 char reserved[6]; // reserved 192 } fat_file_desc_t; 193 194 /******************************************************************************** 195 This struct defines a FAT32 File system descriptor 196 *******************************************************************************/ 197 198 typedef struct fat_desc_s 199 { 200 unsigned char block_buffer[512]; // one block buffer (for FS_INFO) 201 fat_file_desc_t fd[GIET_OPEN_FILES_MAX]; // file descriptors array 202 spin_lock_t fat_lock; // global lock protecting FAT 203 fat_inode_t* inode_tree_root; // Inode-Tree root pointer 204 fat_cache_node_t* fat_cache_root; // Fat_Cache root pointer 205 unsigned int fat_cache_levels; // number of levels in Fat-Cache 206 unsigned int block_buffer_lba; // lba of block in block_buffer 207 unsigned int initialised; // 0xBABEF00D when FAT initialised 208 unsigned int sector_size; // must be 512 209 unsigned int cluster_size; // must be 4096 210 unsigned int fat_lba; // lba of first FAT sector 211 unsigned int fat_sectors; // number of sectors in FAT region 212 unsigned int data_lba; // lba of first DATA sector 213 unsigned int data_sectors; // number of sectors inf DATA region 214 unsigned int fs_info_lba; // lba of fs_info 215 unsigned int first_free_cluster; // free cluster with smallest index 216 unsigned int free_clusters_number; // total number of free clusters 217 } fat_desc_t; 218 155 219 156 220 /*********************** Extern Functions *************************************/ 157 221 158 extern int _fat_init( unsigned int use_irq ); // use IRQ if possible 159 160 extern int _fat_open( unsigned int use_irq, // use IRQ if possible 161 char* pathname, // file pathname from root 162 unsigned int create ); // create new file if non zero 163 164 extern int _fat_read( unsigned int use_irq, // use IRQ if possible 165 unsigned int fd_id, // file descriptor index 166 void* buffer, // destination buffer 167 unsigned int count, // number of sectors to read 168 unsigned int offset ); // offset sector in file 169 170 extern int _fat_write( unsigned int use_irq, // use IRQ if possible 171 unsigned int fd_id, // file descriptor index 172 void* buffer, // source buffer 173 unsigned int count, // number of sectors to write 174 unsigned int offset ); // offset sector in file 175 176 extern int _fat_fstat( unsigned int fd_id ); // file descriptor index 177 178 extern int _fat_close( unsigned int fd_id ); // file descriptor index 179 180 181 extern int _fat_user_open( char* pathname, // file pathname from root 182 unsigned int flags ); // unused 183 184 extern int _fat_user_read( unsigned int fd_id, // file descriptor index 185 void* buffer, // destination buffer 186 unsigned int count, // number of sectors to read 187 unsigned int offset ); // sectors to skip in file 188 189 extern int _fat_user_write( unsigned int fd_id, // file descriptor index 190 void* buffer, // source buffer 191 unsigned int count, // number of sectors to write 192 unsigned int offset ); // sectors to skip in file 193 194 extern int _fat_user_lseek( unsigned int fd_id, 195 unsigned int offset, 196 unsigned int whence ); 222 extern int _fat_init(); 223 224 extern int _fat_open( char* pathname, // path from root 225 unsigned int flags ); // O_CREATE/O_RDONLY 226 227 extern int _fat_close( unsigned int fd_id ); // file descriptor 228 229 extern int _fat_file_info( unsigned int fd_id, // file descriptor 230 unsigned int* size, // file size 231 unsigned int* offset ); // current offset 232 233 extern int _fat_read( unsigned int fd_id, // file descriptor 234 void* buffer, // destination buffer 235 unsigned int count ); // number of bytes 236 237 extern int _fat_write( unsigned int fd_id, // file descriptor 238 void* buffer, // source buffer 239 unsigned int count ); // number of bytes 240 241 extern int _fat_lseek( unsigned int fd_id, // file descriptor 242 unsigned int offset, // new offset value 243 unsigned int whence ); // command type 244 245 extern int _fat_remove( char* pathname, // path from root 246 unsigned int should_be_dir ); // for checking 247 248 extern int _fat_rename( char* old_path, // path from root 249 char* new_path ); // path from root 250 251 extern int _fat_mkdir( char* pathname ); // path from root 252 253 extern int _fat_list( char* pathname ); // path from root 254 255 extern int _fat_load_no_cache( char* pathname, // path from root 256 unsigned int buffer_vbase, // buffer base 257 unsigned int buffer_size ); // buffer size 197 258 198 259 /*******************************************************************************/
Note: See TracChangeset
for help on using the changeset viewer.