Changeset 773 for soft/giet_vm/giet_fat32/fat32.c
- Timestamp:
- Feb 4, 2016, 4:55:22 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_fat32/fat32.c
r772 r773 1 ///////////////////////////////////////////////////////////////////////////////// /1 ///////////////////////////////////////////////////////////////////////////////// 2 2 // Date : 01/06/2015 3 3 // Authors : Alain Greiner … … 78 78 79 79 80 /////////////////////////////////////////////////////////////////////////////////// 81 // This debug function displays the content of a 512 bytes buffer "buf", 82 // with an identifier defined by the "string" and "block_id" arguments. 83 /////////////////////////////////////////////////////////////////////////////////// 84 85 #if GIET_DEBUG_FAT 86 static void _display_one_block( unsigned char* buf, 87 char* string, 88 unsigned int block_id ); 89 #endif 90 91 ////////////////////////////////////////////////////////////////////////////////// 92 // This debug function displays the FAT descriptor. 93 ////////////////////////////////////////////////////////////////////////////////// 94 95 #if GIET_DEBUG_FAT 80 #if GIET_DEBUG_FAT 81 96 82 static void _display_fat_descriptor(); 97 #endif 98 99 ///////////////////////////////////////////////////////////////////////////////// 100 // The following function transfers one or several blocks between the device 101 // and a memory buffer identified by a virtual address. 102 // It computes the memory buffer physical address, and calls the proper 103 // IOC driver depending on the subtype (BDV / HBA / SDC / SPI / RDK). 104 // The use_irq argument allows to activate the descheduling mode, 105 // if it supported by the IOC driver subtype 106 // It returns 0 on success. 107 // It returns -1 on error. 108 ///////////////////////////////////////////////////////////////////////////////// 109 110 static int _fat_ioc_access( unsigned int use_irq, 111 unsigned int to_mem, 112 unsigned int lba, 113 unsigned int buf_vaddr, 114 unsigned int count ); 115 116 //////////////////////////////////////////////////////////////////////////////// 117 // This function extract a (partial) name from a LFN directory entry. 118 //////////////////////////////////////////////////////////////////////////////// 83 84 static void _display_clusters_list(); 85 86 #endif 119 87 120 88 static void _get_name_from_long( unsigned char* buffer, 121 89 char* name ); 122 90 123 ////////////////////////////////////////////////////////////////////////////////124 // The following function extract a name from a NORMAL directory entry.125 ////////////////////////////////////////////////////////////////////////////////126 127 91 static void _get_name_from_short( unsigned char* buffer, 128 92 char* name ); 129 93 130 //////////////////////////////////////////////////////////////////////////////////131 // This function returns the number of levels of a File-Cache (or Fat-Cache)132 // from the size of the file (or FAT).133 //////////////////////////////////////////////////////////////////////////////////134 135 94 static inline unsigned int _get_levels_from_size( unsigned int size ); 136 137 ///////////////////////////////////////////////////////////////////////////////////138 // The following function analyses the "pathname" argument, from the character139 // defined by the "nb_read" argument.140 // It copies the found name in the "name" buffer (without '/'),141 // and updates the "nb_read" argument.142 // It returns 0 on success.143 // It returns 1 if one name length > NAME_MAX_SIZE characters144 ///////////////////////////////////////////////////////////////////////////////////145 95 146 96 static unsigned int _get_name_from_path( char* pathname, … … 148 98 unsigned int* nb_read ); 149 99 150 ////////////////////////////////////////////////////////////////////////////////151 // The following function scan the "pathname" argument, and copies in the152 // "name" buffer the last name in path (leaf name).153 // It returns 0 on success.154 // It returns 1 if one name length > NAME_MAX_SIZE characters155 ////////////////////////////////////////////////////////////////////////////////156 100 static unsigned int _get_last_name( char* pathname, 157 101 char* name ); 158 102 159 //////////////////////////////////////////////////////////////////////////////////160 // The following function accesses the Fat-Cache and returns in the "value"161 // argument the content of the FAT slot identified by the "cluster" argument.162 // It loads the missing cluster from block device into cache in case of miss.163 // It returns 0 on success.164 // It returns 1 on error.165 //////////////////////////////////////////////////////////////////////////////////166 167 103 static unsigned int _get_fat_entry( unsigned int cluster, 168 104 unsigned int* value ); 169 105 170 //////////////////////////////////////////////////////////////////////////////////171 // The following function writes a new "value" in the Fat-Cache, in the slot172 // identified by the "cluster" argument.173 // It loads the missing cluster from block device into cache in case of miss.174 // It returns 0 on success,175 // It returns 1 on error.176 //////////////////////////////////////////////////////////////////////////////////177 178 106 static unsigned int _set_fat_entry( unsigned int cluster, 179 107 unsigned int value ); 180 108 181 //////////////////////////////////////////////////////////////////////////////////182 // The following function introduces the inode identified by the <child> argument,183 // as a new child of the <parent> inode in the Inode-Tree.184 // All checking are supposed to be done by the caller.185 // Nor the File-Cache, neither the block device are modified.186 //////////////////////////////////////////////////////////////////////////////////187 188 109 static void _add_inode_in_tree( fat_inode_t* child, 189 110 fat_inode_t* parent ); 190 111 191 //////////////////////////////////////////////////////////////////////////////////192 // The following function removes one inode identified by the <inode> argument193 // from the Inode-Tree. All checking are supposed to be done by the caller.194 // Nor the File-Cache, neither the block device are modified.195 //////////////////////////////////////////////////////////////////////////////////196 197 112 static void _remove_inode_from_tree( fat_inode_t* inode ); 198 199 //////////////////////////////////////////////////////////////////////////////////200 // This recursive function scan one File-Cache (or Fat-Cache) from root to leaves,201 // to writes all dirty clusters to block device, and reset the dirty bits.202 // The cache is identified by the <root> an <levels> arguments.203 // The <string> argument is only used for debug : inode name or Fat.204 // It returns 0 on success.205 // It returns 1 on error.206 //////////////////////////////////////////////////////////////////////////////////207 113 208 114 static unsigned int _update_device_from_cache( unsigned int levels, … … 210 116 char* string ); 211 117 212 //////////////////////////////////////////////////////////////////////////////////213 // The following function accesses directly the FS_INFO block on the block device,214 // to update the "first_free_cluster" and "free_clusters_number" values,215 // using only the Fat-Descriptor single block buffer.216 // It return 0 on success.217 // It return 1 on error.218 //////////////////////////////////////////////////////////////////////////////////219 220 118 static unsigned int _update_fs_info(); 221 222 //////////////////////////////////////////////////////////////////////////////223 // The following function read a data field (from one to four bytes)224 // from an unsigned char[] buffer, taking endianness into account.225 // The analysed field is defined by the <offset> and <size> arguments.226 //////////////////////////////////////////////////////////////////////////////227 119 228 120 static unsigned int _read_entry( unsigned int offset, … … 231 123 unsigned int little_indian ); 232 124 233 //////////////////////////////////////////////////////////////////////////////////234 // The following function returns the lba of first sector in DATA region235 // from the cluster index. The cluster index must be larger than 2.236 //////////////////////////////////////////////////////////////////////////////////237 238 125 static unsigned int _cluster_to_lba( unsigned int cluster ); 239 240 //////////////////////////////////////////////////////////////////////////////////241 // The following function returns in the "nb_entries" argument the number of files242 // (or directories) contained in a directory identified by the "inode " pointer.243 // It returns 0 on success.244 // It returns 1 on error.245 //////////////////////////////////////////////////////////////////////////////////246 126 247 127 static unsigned int _get_nb_entries( fat_inode_t* inode, 248 128 unsigned int* nb_entries ); 249 250 //////////////////////////////////////////////////////////////////////////////////251 // The following function search in the directory identified by the <parent>252 // inode pointer a child (file or directory) identified by its <name>.253 // It returns in the <inode> argument the searched child inode pointer.254 // If the searched name is not found in the Inode-Tree, the function accesses255 // the File-cache associated to the parent directory.256 // If the child exists on block device, the Inode-Tree is updated, and257 // a success code is returned.258 // If the file/dir does not exist on block device, a error code is returned.259 // It returns 0 if inode found.260 // It returns 1 if inode not found.261 // It returns 2 on error in cache access.262 //////////////////////////////////////////////////////////////////////////////////263 129 264 130 static unsigned int _get_child_from_parent( fat_inode_t* parent, … … 266 132 fat_inode_t** inode ); 267 133 268 /////////////////////////////////////////////////////////////////////////////////269 // For a file (or a directory) identified by the "pathname" argument, the270 // following function returns in the "inode" argument the inode pointer271 // associated to the searched file (or directory), with code (0).272 // If the searched file (or directory) is not found, but the parent directory273 // is found, it returns in the "inode" argument the pointer on the parent inode,274 // with code (1). Finally, code (2) and code (3) are error codes.275 // Both the Inode-Tree and the involved Cache-Files are updated from the block276 // device in case of miss on one inode during the search in path.277 // Neither the Fat-Cache, nor the block device are updated.278 // It returns 0 if searched inode found279 // It returns 1 if searched inode not found but parent directory found280 // It returns 2 if searched inode not found and parent directory not found281 // It returns 3 if one name too long282 /////////////////////////////////////////////////////////////////////////////////283 284 134 static unsigned int _get_inode_from_path( char* pathname, 285 135 fat_inode_t** inode ); 286 136 287 //////////////////////////////////////////////////////////////////////////////////288 // The following function checks if node "a" is an ancestor of inode "b".289 // It returns 0 on failure.290 // It returns 1 otherwise.291 //////////////////////////////////////////////////////////////////////////////////292 293 137 static unsigned int _is_ancestor( fat_inode_t* a, 294 138 fat_inode_t* b); 295 139 296 ////////////////////////////////////////////////////////////////////////////////// 297 // This function computes the length and the number of LFN entries required 298 // to store a node name in the "length" and "nb_lfn" arguments. 299 // Short name (less than 13 characters) require 1 LFN entry. 300 // Medium names (from 14 to 26 characters require 2 LFN entries. 301 // Large names (up to 31 characters) require 3 LFN entries. 302 // It returns 0 on success. 303 // It returns 1 if length larger than 31 characters. 304 ////////////////////////////////////////////////////////////////////////////////// 305 306 static unsigned int _check_name_length( char* name, 307 unsigned int* length, 308 unsigned int* nb_lfn ); 309 310 ////////////////////////////////////////////////////////////////////////////////// 311 // For a node identified by the "inode" argument, this function updates the 312 // "size" and "cluster" values in the entry of the parent directory File-Cache. 313 // It set the dirty bit in the modified buffer of the parent directory File-Cache. 314 ////////////////////////////////////////////////////////////////////////////////// 140 static unsigned int _get_sfn_name( char* name, 141 unsigned int* length, 142 unsigned int* nb_lfn, 143 char* sfn, 144 unsigned char* checksum ); 315 145 316 146 static unsigned int _update_dir_entry( fat_inode_t* inode ); 317 318 //////////////////////////////////////////////////////////////////////////////////319 // The following function add new "child" in Cache-File of "parent" directory.320 // It accesses the File_Cache associated to the parent directory, and scan the321 // clusters allocated to this directory to find the NO_MORE entry.322 // This entry will be the first modified entry in the directory.323 // Regarding the name storage, it uses LFN entries for all names.324 // Therefore, it writes 1, 2, or 3 LFN entries (depending on the child name325 // actual length, it writes one NORMAL entry, and writes the new NOMORE entry.326 // It updates the dentry field in the child inode.327 // It set the dirty bit for all modified File-Cache buffers.328 // The block device is not modified by this function.329 //////////////////////////////////////////////////////////////////////////////////330 147 331 148 static unsigned int _add_dir_entry( fat_inode_t* child, 332 149 fat_inode_t* parent ); 333 150 334 //////////////////////////////////////////////////////////////////////////////////335 // The following function invalidates all dir_entries associated to the "inode"336 // argument from its parent directory.337 // It set the dirty bit for all modified buffers in parent directory Cache-File.338 // The inode itself is not modified by this function.339 // The block device is not modified by this function.340 //////////////////////////////////////////////////////////////////////////////////341 342 151 static unsigned int _remove_dir_entry( fat_inode_t* inode ); 343 344 //////////////////////////////////////////////////////////////////////////////////345 // The following function add the special entries "." and ".." in the File-Cache346 // of the directory identified by the "child" argument.347 // The parent directory is defined by the "parent" argument.348 // The child directory File-Cache is supposed to be empty.349 // We use two NORMAL entries for these "." and ".." entries.350 // The block device is not modified by this function.351 //////////////////////////////////////////////////////////////////////////////////352 152 353 153 static void _add_special_directories( fat_inode_t* child, 354 154 fat_inode_t* parent ); 355 155 356 ////////////////////////////////////////////////////////////////////////////////// 357 // The following function releases all clusters allocated to a file or directory, 358 // from the cluster index defined by the <cluster> argument, until the end 359 // of the FAT linked list. 360 // It calls _get_fat_entry() and _set_fat_entry() functions to scan the FAT, 361 // and to update the clusters chaining. 362 // The FAT region on block device is updated. 363 // It returns 0 on success. 364 // It returns 1 on error. 365 ////////////////////////////////////////////////////////////////////////////////// 366 367 static unsigned int _clusters_release( unsigned int cluster ); 368 369 ////////////////////////////////////////////////////////////////////////////////// 370 // This function allocate one cluster in FAT to a file (or directory) identified 371 // by the <inode> pointer. The allocated cluster index is returned in the 372 // <cluster> argument. 373 // It allocates also the associated buffers and buffer descriptors in Cache-File. 374 // It calls _get_fat_entry() and _set_fat_entry() functions to update the 375 // clusters chaining in the Cache-Fat. The FAT region on block device is updated. 376 // It returns 0 on success. 377 // It returns 1 on error. 378 ////////////////////////////////////////////////////////////////////////////////// 156 static unsigned int _clusters_release( fat_inode_t* inode ); 379 157 380 158 static unsigned int _cluster_allocate( fat_inode_t* inode, 381 159 unsigned int* cluster ); 382 160 383 //////////////////////////////////////////////////////////////////////////////////384 // This recursive function scans one File-Cache (or Fat-Cache) from root to385 // leaves. All memory allocated for 4KB buffers, and buffer descriptors (in386 // leaves) is released, along with the 64-Tree structure (root node is kept).387 // The cache is identified by the "root" and "levels" arguments.388 // It should not contain any dirty clusters.389 //////////////////////////////////////////////////////////////////////////////////390 391 161 static void _release_cache_memory( fat_cache_node_t* root, 392 162 unsigned int levels ); 393 163 394 //////////////////////////////////////////////////////////////////////////////////395 // The following function allocates and initializes a new cache node.396 // Its first child can be specified (used when adding a cache level).397 // The 63 other children are set to NULL.398 // It returns a pointer to a new Fat-Cache node.399 //////////////////////////////////////////////////////////////////////////////////400 401 164 static fat_cache_node_t* _allocate_one_cache_node( fat_cache_node_t* first_child ); 402 403 //////////////////////////////////////////////////////////////////////////////////404 // The following function allocates and initializes a new inode,405 // using the values defined by the arguments.406 // If the "cache_allocate" argument is true, an empty cache is allocated.407 // It returns a pointer on the new inode.408 //////////////////////////////////////////////////////////////////////////////////409 165 410 166 static fat_inode_t* _allocate_one_inode( char* name, … … 416 172 unsigned int cache_allocate ); 417 173 418 //////////////////////////////////////////////////////////////////////////////////419 // The following function allocates a 4 Kbytes buffer and the associated cluster420 // descriptor for the file (or directory) identified by the <inode> argument,421 // and updates the Cache_File slot identified by the <cluster_id> argument.422 // The File-Cache slot must be empty.423 // It updates the buffer descriptor, using the <cluster> argument, that is424 // the cluster index in FAT. The cluster descriptor dirty field is set.425 // It traverse the 64-tree Cache-file from top to bottom to find the last level.426 //////////////////////////////////////////////////////////////////////////////////427 428 174 static void _allocate_one_buffer( fat_inode_t* inode, 429 175 unsigned int cluster_id, 430 176 unsigned int cluster ); 431 177 432 //////////////////////////////////////////////////////////////////////////////////433 // The following function allocates one free cluster from the FAT434 // and returns the cluster index in the <cluster> argument.435 // It updates the FAT slot, and the two FAT global variables: first_free_cluster,436 // and free_clusters_number.437 // It returns 0 on success.438 // It returns 1 on error.439 //////////////////////////////////////////////////////////////////////////////////440 441 178 static unsigned int _allocate_one_cluster( unsigned int* cluster ); 442 179 443 /////////////////////////////////////////////////////////////////////////////444 // This function remove from the file system a file or a directory445 // identified by the <inode> argument.446 // The remove condition must be checked by the caller.447 // The relevant lock(s) must have been taken by te caller.448 // It returns 0 on success.449 // It returns 1 on error.450 /////////////////////////////////////////////////////////////////////////////451 452 180 static unsigned int _remove_node_from_fs( fat_inode_t* inode ); 453 454 /////////////////////////////////////////////////////////////////////////////455 // This function return the cluster index and the size for a file456 // identified by the "pathname" argument, scanning directly the block457 // device DATA region.458 // It is intended to be called only by the _fat_load_no_cache() function,459 // it does not use the dynamically allocated File Caches, but uses only460 // the 4 Kbytes _fat_buffer_data.461 // It returns 0 on success.462 // It returns 1 on error.463 /////////////////////////////////////////////////////////////////////////////464 181 465 182 static unsigned int _file_info_no_cache( char* pathname, … … 467 184 unsigned int* file_size ); 468 185 469 /////////////////////////////////////////////////////////////////////////////470 // This function scan directly the FAT region on the block device,471 // and returns in the "next" argument the value stored in the fat slot472 // identified by the "cluster" argument.473 // It is intended to be called only by the _fat_load_no_cache() function,474 // as it does not use the dynamically allocated Fat-Cache, but uses only475 // the 4 Kbytes _fat_buffer_fat.476 // It returns 0 on success.477 // It returns 1 on error.478 /////////////////////////////////////////////////////////////////////////////479 480 186 static unsigned int _next_cluster_no_cache( unsigned int cluster, 481 187 unsigned int* next ); 482 188 483 484 //////////////////////////////////////////////////////////////////////////////////485 // The following functions return the the size (bytes) of a FAT field,486 // identified by an (offset,length) mnemonic defined in the fat32.h file.487 //////////////////////////////////////////////////////////////////////////////////488 489 189 static inline int get_length( int offset , int length ) { return length; } 490 190 491 191 static inline int get_offset( int offset , int length ) { return offset; } 492 493 //////////////////////////////////////////////////////////////////////////////////494 // The following function returns in the <desc> argument a pointer on a buffer495 // descriptor contained in the Fat_Cache.496 // The <cluster_id> argument is the buffer index in the FAT_Cache.497 // In case of miss, a 4 Kbytesbuffer and a buffer descriptor are allocated498 // from the local heap, and the missing cluster is loaded in the Fat_Cache.499 // It returns 0 on success.500 // It returns 1 on error.501 //////////////////////////////////////////////////////////////////////////////////502 503 static unsigned int _get_fat_cache_buffer( unsigned int cluster_id,504 fat_cache_desc_t** desc );505 506 192 507 193 … … 512 198 ////////////////////////////////////////////////////////////////////////////////// 513 199 ////////////////////////////////////////////////////////////////////////////////// 514 515 #if GIET_DEBUG_FAT516 ///////////////////////////////////////////////////517 static void _display_one_block( unsigned char* buf,518 char* string,519 unsigned int block_id )520 {521 unsigned int line;522 unsigned int word;523 524 _printf("\n*** <%s> block %x ***********************************\n",525 string , block_id );526 527 for ( line = 0 ; line < 16 ; line++ )528 {529 // display line index530 _printf("%x : ", line );531 532 // display 8*4 bytes hexa533 for ( word=0 ; word<8 ; word++ )534 {535 unsigned int byte = (line<<5) + (word<<2);536 unsigned int hexa = (buf[byte ]<<24) |537 (buf[byte+1]<<16) |538 (buf[byte+2]<< 8) |539 (buf[byte+3] );540 _printf(" %X |", hexa );541 }542 _printf("\n");543 }544 _printf("*******************************************************************\n");545 } // end _display_one_block()546 #endif547 548 200 549 201 … … 579 231 580 232 581 582 #if 0 233 #if GIET_DEBUG_FAT 583 234 //////////////////////////////////////////////////////// 584 235 static void _display_clusters_list( fat_inode_t* inode ) 585 236 { 586 _printf("\n**************** clusters for <%s> ***********************\n", inode->name ); 587 unsigned int next; 588 unsigned int n = 0; 589 unsigned int current = inode->cluster; 590 while( (current < END_OF_CHAIN_CLUSTER_MIN) && (n < 1024) ) 591 { 237 unsigned int next = 0; 238 unsigned int cluster_id = 0; 239 unsigned int current = inode->cluster; 240 241 _printf("\n --- clusters for <%s> ---\n", 242 inode->name ); 243 244 while( current < END_OF_CHAIN_CLUSTER_MIN ) 245 { 246 if ( (current < 2) || (cluster_id >= 1024) ) 247 { 248 _printf("\n[FAT ERROR] in _display_clusters_list()\n"); 249 _exit(); 250 } 251 592 252 _get_fat_entry( current , &next ); 593 253 _printf(" > %X", current ); 594 n++;595 if ( ( n& 0x7) == 0 ) _printf("\n");254 cluster_id++; 255 if ( (cluster_id & 0x7) == 0 ) _printf("\n"); 596 256 current = next; 597 257 } … … 599 259 } // end _display_clusters_list() 600 260 #endif 601 602 603 604 /////////////////////////////////////////////////////////////////////////////////605 static int _fat_ioc_access( unsigned int use_irq, // descheduling if non zero606 unsigned int to_mem, // read / write607 unsigned int lba, // first sector on device608 unsigned int buf_vaddr, // memory buffer vaddr609 unsigned int count ) // number of sectors610 {611 // compute memory buffer physical address612 unsigned int flags; // for _v2p_translate613 unsigned long long buf_paddr; // buffer physical address614 615 if ( ((_get_mmu_mode() & 0x4) == 0 ) || USE_IOC_RDK ) // identity616 {617 buf_paddr = (unsigned long long)buf_vaddr;618 }619 else // V2P translation required620 {621 buf_paddr = _v2p_translate( buf_vaddr , &flags );622 }623 624 #if (GIET_DEBUG_FAT & 1)625 if ( _get_proctime() > GIET_DEBUG_FAT )626 _printf("\n[DEBUG FAT] _fat_ioc_access(): enters at cycle %d\n"627 " to_mem = %d / vaddr = %x / paddr = %l / sectors = %d / lba = %x\n",628 _get_proctime(), to_mem, buf_vaddr, buf_paddr, count, lba );629 #endif630 631 632 #if GIET_NO_HARD_CC // L1 cache inval (virtual addresses)633 if ( to_mem ) _dcache_buf_invalidate( buf_vaddr, count<<9 );634 #endif635 636 637 #if ( USE_IOC_BDV ) // call the proper driver638 return( _bdv_access( use_irq , to_mem , lba , buf_paddr , count ) );639 #elif ( USE_IOC_HBA )640 return( _hba_access( use_irq , to_mem , lba , buf_paddr , count ) );641 #elif ( USE_IOC_SDC )642 return( _sdc_access( use_irq , to_mem , lba , buf_paddr , count ) );643 #elif ( USE_IOC_SPI )644 return( _spi_access( use_irq , to_mem , lba , buf_paddr , count ) );645 #elif ( USE_IOC_RDK )646 return( _rdk_access( use_irq , to_mem , lba , buf_paddr , count ) );647 #else648 _printf("\n[FAT ERROR] _fat_ioc_access(): no IOC driver\n");649 _exit();650 #endif651 652 } // end _fat_ioc_access()653 654 261 655 262 … … 956 563 957 564 958 959 960 961 962 963 565 ///////////////////////////////////// 964 566 static unsigned int _update_fs_info() … … 998 600 } 999 601 1000 #if (GIET_DEBUG_FAT & 1)602 #if GIET_DEBUG_FAT 1001 603 if ( _get_proctime() > GIET_DEBUG_FAT ) 1002 604 _printf("\n[DEBUG FAT] _update_fs_info(): nb_free = %x / first_free = %x\n", … … 1006 608 return 0; 1007 609 } // end _update_fs_info() 1008 1009 610 1010 611 … … 1013 614 unsigned int* value ) 1014 615 { 1015 // compute cluster_id & entry_id in FAT 1016 // a FAT cluster is an array of 1024 unsigned int entries616 // compute cluster_id & entry_id in FAT from cluster index 617 // a FAT buffer is an array of 1024 unsigned int entries 1017 618 unsigned int cluster_id = cluster >> 10; 1018 619 unsigned int entry_id = cluster & 0x3FF; … … 1037 638 unsigned int value ) 1038 639 { 1039 // compute cluster_id & entry_id in FAT 640 // compute cluster_id & entry_id in FAT from cluster index 1040 641 // a FAT cluster is an array of 1024 unsigned int entries 1041 642 unsigned int cluster_id = cluster >> 10; … … 1064 665 { 1065 666 1066 #if (GIET_DEBUG_FAT & 1)667 #if GIET_DEBUG_FAT 1067 668 if ( _get_proctime() > GIET_DEBUG_FAT ) 1068 669 _printf("\n[DEBUG FAT] _allocate_one_buffer(): in cache <%s> for cluster_id %d\n", … … 1074 675 { 1075 676 1076 #if (GIET_DEBUG_FAT & 1)677 #if GIET_DEBUG_FAT 1077 678 if ( _get_proctime() > GIET_DEBUG_FAT ) 1078 679 _printf("\n[DEBUG FAT] _allocate_one_buffer(): adding a cache level\n" ); … … 1105 706 } 1106 707 1107 #if (GIET_DEBUG_FAT & 1)708 #if GIET_DEBUG_FAT 1108 709 if ( _get_proctime() > GIET_DEBUG_FAT ) 1109 710 _printf("\n[DEBUG FAT] _allocate_one_buffer(): buffer allocated to <%s> for cluster_id %d\n", … … 1155 756 // get FAT entry indexed by current 1156 757 if ( _get_fat_entry( current , &value ) ) return 1; 758 1157 759 // test if free 1158 760 if ( value == FREE_CLUSTER ) found = 1; … … 1174 776 _fat.first_free_cluster = current; 1175 777 1176 #if (GIET_DEBUG_FAT & 1)778 #if GIET_DEBUG_FAT 1177 779 if ( _get_proctime() > GIET_DEBUG_FAT ) 1178 780 _printf("\n[DEBUG FAT] _allocate_one_cluster(): allocated cluster = %x / first_free = %x\n", … … 1221 823 pdesc->dirty = 0; 1222 824 1223 #if (GIET_DEBUG_FAT & 1)825 #if GIET_DEBUG_FAT 1224 826 if ( _get_proctime() > GIET_DEBUG_FAT ) 1225 827 _printf("\n[DEBUG FAT] _update_device_from_cache(): cluster_id = %d for <%s>\n", … … 1347 949 } 1348 950 1349 // update the FAT on blockdevice951 // update the FAT on device 1350 952 if ( _update_device_from_cache( _fat.fat_cache_levels, 1351 953 _fat.fat_cache_root, 1352 954 "FAT" ) ) return 1; 1353 #if (GIET_DEBUG_FAT & 1) 1354 if ( _get_proctime() > GIET_DEBUG_FAT ) 1355 _printf("\n[DEBUG FAT] _cluster_allocate(): for <%s> / current_clusters = %d" 1356 " / last_cluster = %x / new_cluster = %x\n", 955 956 // update FS-INFO sector on device 957 if ( _update_fs_info() ) return 1; 958 959 #if GIET_DEBUG_FAT 960 if ( _get_proctime() > GIET_DEBUG_FAT ) 961 _printf("\n[DEBUG FAT] _cluster_allocate(): for <%s>\n" 962 " nb_clusters = %d / last_cluster = %x / new_cluster = %x\n", 1357 963 inode->name , nb_current_clusters , last , new ); 1358 964 #endif … … 1366 972 1367 973 1368 /////////////////////////////////////////////////////////// ///1369 static unsigned int _clusters_release( unsigned int cluster)974 /////////////////////////////////////////////////////////// 975 static unsigned int _clusters_release( fat_inode_t* inode ) 1370 976 { 1371 977 // scan the FAT 1372 unsigned int current = cluster;978 unsigned int current = inode->cluster; 1373 979 unsigned int next; 1374 980 do … … 1393 999 _fat.fat_cache_root, 1394 1000 "FAT" ) ) return 1; 1001 1002 // update FS-INFO sector on device 1003 if ( _update_fs_info() ) return 1; 1004 1005 #if GIET_DEBUG_FAT 1006 if ( _get_proctime() > GIET_DEBUG_FAT ) 1007 _printf("\n[DEBUG FAT] _clusters_release(): for file <%s>\n", inode->name ); 1008 #endif 1009 1395 1010 return 0; 1396 1011 } // end _clusters_release() … … 1473 1088 1474 1089 //////////////////////////////////////////////////////////// 1475 static unsigned int _check_name_length( char* name, 1476 unsigned int* length, 1477 unsigned int* nb_lfn ) 1478 { 1479 unsigned int len = _strlen( name ); 1480 if ( len <= 13 ) 1481 { 1482 *length = len; 1090 static unsigned int _get_sfn_name( char* name, 1091 unsigned int* length, 1092 unsigned int* nb_lfn, 1093 char* sfn, 1094 unsigned char* checksum ) 1095 { 1096 // compute name length 1097 unsigned int name_length = _strlen( name ); 1098 1099 // compute prefix and suffix length 1100 // only the last '.' is taken into account 1101 unsigned int suffix_length = 0; 1102 unsigned int prefix_length = 0; 1103 unsigned int dot_found = 0; 1104 unsigned int i; 1105 for ( i=0 ; i<name_length ; i++ ) 1106 { 1107 if (name[i] == '.' ) 1108 { 1109 if ( dot_found ) 1110 { 1111 prefix_length += suffix_length + 1; 1112 suffix_length = 0; 1113 } 1114 else 1115 { 1116 dot_found = 1; 1117 } 1118 } 1119 else 1120 { 1121 if ( dot_found) 1122 { 1123 suffix_length++; 1124 } 1125 else 1126 { 1127 prefix_length++; 1128 } 1129 } 1130 } 1131 1132 // build SFN prefix (8bits) 1133 if (prefix_length <= 8) 1134 { 1135 for( i=0 ; i<8 ; i++) 1136 { 1137 if ( i<prefix_length ) sfn[i] = _to_upper( name[i] ); 1138 else sfn[i] = 0x20; 1139 } 1140 } 1141 else 1142 { 1143 for( i=0 ; i<6 ; i++) 1144 { 1145 sfn[i] = _to_upper( name[i] ); 1146 } 1147 sfn[6] = 0x7E; 1148 sfn[7] = 0x31; 1149 } 1150 1151 // build SFN suffix (3 bits) 1152 if ( suffix_length == 0 ) 1153 { 1154 sfn[8] = 0x20; 1155 sfn[9] = 0x20; 1156 sfn[10] = 0x20; 1157 } 1158 else if ( suffix_length == 1 ) 1159 { 1160 sfn[8] = _to_upper( name[name_length-1] ); 1161 sfn[9] = 0x20; 1162 sfn[10] = 0x20; 1163 } 1164 else if ( suffix_length == 2 ) 1165 { 1166 sfn[8] = _to_upper( name[name_length-2] ); 1167 sfn[9] = _to_upper( name[name_length-1] ); 1168 sfn[10] = 0x20; 1169 } 1170 else 1171 { 1172 sfn[8] = _to_upper( name[name_length-suffix_length] ); 1173 sfn[9] = _to_upper( name[name_length-suffix_length+1] ); 1174 sfn[10] = _to_upper( name[name_length-suffix_length+2] ); 1175 } 1176 1177 // compute 8 bits checksum 1178 unsigned char sum = 0; 1179 for ( i=0 ; i<11 ; i++ ) 1180 { 1181 sum = (((sum & 0x01)<<7) | ((sum & 0xFE)>>1)) + sfn[i]; 1182 } 1183 *checksum = sum; 1184 1185 // set nb_lfn and length values 1186 if ( name_length <= 13 ) 1187 { 1188 *length = name_length; 1483 1189 *nb_lfn = 1; 1484 1190 return 0; 1485 1191 } 1486 else if ( len<= 26 )1487 { 1488 *length = len;1192 else if ( name_length <= 26 ) 1193 { 1194 *length = name_length; 1489 1195 *nb_lfn = 2; 1490 1196 return 0; 1491 1197 } 1492 else if ( len<= 31 )1493 { 1494 *length = len;1198 else if ( name_length <= 31 ) 1199 { 1200 *length = name_length; 1495 1201 *nb_lfn = 3; 1496 1202 return 0; … … 1500 1206 return 1; 1501 1207 } 1502 } // _ check_name_length()1208 } // _get_sfn_name() 1503 1209 1504 1210 … … 1565 1271 1566 1272 return 0; 1567 } // end dir_not_empty() 1273 } // end _get_nb_entries() 1274 1275 1276 1277 //////////////////////////////////////////////////////////// 1278 static unsigned int _update_dir_entry( fat_inode_t* inode ) 1279 { 1280 // get Cache-File buffer containing the parent directory entry 1281 // 128 directories entries in one 4 Kbytes buffer 1282 fat_cache_desc_t* pdesc; 1283 unsigned char* buffer; 1284 unsigned int cluster_id = inode->dentry>>7; 1285 unsigned int offset = (inode->dentry & 0x7F)<<5; 1286 1287 if ( _get_file_cache_buffer( inode->parent, 1288 cluster_id, 1289 0, 1290 &pdesc ) ) return 1; 1291 buffer = pdesc->buffer; 1292 pdesc->dirty = 1; 1293 1294 // update size field 1295 buffer[offset + 28] = inode->size>>0; // size.B0 1296 buffer[offset + 29] = inode->size>>8; // size.B1 1297 buffer[offset + 30] = inode->size>>16; // size.B2 1298 buffer[offset + 31] = inode->size>>24; // size.B3 1299 1300 // update cluster field 1301 buffer[offset + 26] = inode->cluster>>0; // cluster.B0 1302 buffer[offset + 27] = inode->cluster>>8; // cluster.B1 1303 buffer[offset + 20] = inode->cluster>>16; // cluster.B2 1304 buffer[offset + 21] = inode->cluster>>24; // cluster.B3 1305 1306 return 0; 1307 } // end _update_dir_entry() 1308 1568 1309 1569 1310 … … 1578 1319 unsigned int cluster = child->cluster; 1579 1320 1580 // compute number of required entries to store child->name 1581 // - Short name (less than 13 characters) require 3 entries: 1582 // one LFN entry / one NORMAL entry / one NO_MORE_ENTRY entry. 1583 // - Longer names (up to 31 characters) can require 4 or 5 entries: 1584 // 2 or 3 LFN entries / one NORMAL entry / one NO_MORE entry. 1585 unsigned int length; 1586 unsigned int nb_lfn; 1587 if ( _check_name_length( child->name, 1321 // compute number of required 32 bytes entries to store 1322 // the complete child name and a legal 8.3 SFN name. 1323 unsigned int length; 1324 unsigned int nb_lfn; 1325 char sfn[11]; 1326 unsigned char checksum; 1327 if ( _get_sfn_name( child->name, 1588 1328 &length, 1589 &nb_lfn ) ) return 1; 1590 1591 #if (GIET_DEBUG_FAT & 1) 1329 &nb_lfn, 1330 sfn, 1331 &checksum ) ) return 1; 1332 1333 #if GIET_DEBUG_FAT 1592 1334 if ( _get_proctime() > GIET_DEBUG_FAT ) 1593 1335 _printf("\n[DEBUG FAT] _add_dir_entry(): try to add <%s> in <%s> / nb_lfn = %d\n", … … 1607 1349 while ( found == 0 ) 1608 1350 { 1609 // get one 4 Kytes buffer from File_Cache1351 // get the 4 Kytes buffer from File_Cache 1610 1352 if ( _get_file_cache_buffer( parent, 1611 1353 cluster_id, … … 1628 1370 } 1629 1371 } // end loop on entries 1372 1630 1373 if ( found == 0 ) 1631 1374 { … … 1635 1378 } // end loop on clusters 1636 1379 1637 #if (GIET_DEBUG_FAT & 1)1380 #if GIET_DEBUG_FAT 1638 1381 if ( _get_proctime() > GIET_DEBUG_FAT ) 1639 1382 _printf("\n[DEBUG FAT] _add_dir_entry(): get NO_MORE directory entry : " … … 1679 1422 entry = buffer + offset; 1680 1423 1681 #if (GIET_DEBUG_FAT & 1)1424 #if GIET_DEBUG_FAT 1682 1425 if ( _get_proctime() > GIET_DEBUG_FAT ) 1683 1426 _printf("\n[DEBUG FAT] _add_dir_entry(): FSM step = %d /" … … 1708 1451 } 1709 1452 else if (i == 11) entry[i] = 0x0F; 1710 else if (i == 1 2) entry[i] = 0xCA;1453 else if (i == 13) entry[i] = checksum; 1711 1454 else entry[i] = 0x00; 1712 1455 } … … 1734 1477 } 1735 1478 else if (i == 11) entry[i] = 0x0F; 1736 else if (i == 1 2) entry[i] = 0xCA;1479 else if (i == 13) entry[i] = checksum; 1737 1480 else entry[i] = 0x00; 1738 1481 } … … 1760 1503 } 1761 1504 else if (i == 11) entry[i] = 0x0F; 1762 else if (i == 1 2) entry[i] = 0xCA;1505 else if (i == 13) entry[i] = checksum; 1763 1506 else entry[i] = 0x00; 1764 1507 } … … 1768 1511 case 2: // write NORMAL entry 1769 1512 { 1770 c = 0;1771 1513 // scan the 32 bytes in dir_entry 1772 1514 for ( i = 0 ; i < 32 ; i++ ) 1773 1515 { 1774 if ( (i < 8) && (c < length) ) //SFN1516 if ( i < 11 ) // 8.3 SFN 1775 1517 { 1776 entry[i] = _to_upper( name[c] ); 1777 c++; 1518 entry[i] = sfn[i]; 1778 1519 } 1779 else if (i < 11) entry[i] = 0x20; // EXT1780 1520 else if (i == 11) // ATTR 1781 1521 { … … 1810 1550 } // exit while => exit FSM 1811 1551 1812 #if (GIET_DEBUG_FAT & 1)1552 #if GIET_DEBUG_FAT 1813 1553 if ( _get_proctime() > GIET_DEBUG_FAT ) 1814 1554 { … … 1827 1567 { 1828 1568 // compute number of LFN entries 1829 unsigned int length;1830 1569 unsigned int nb_lfn; 1831 if ( _check_name_length( inode->name, 1832 &length, 1833 &nb_lfn ) ) return 1; 1570 unsigned int name_length = _strlen( inode->name ); 1571 if ( name_length <= 13 ) nb_lfn = 1; 1572 else if ( name_length <= 26 ) nb_lfn = 2; 1573 else nb_lfn = 3; 1834 1574 1835 1575 // get cluster_id and offset in parent directory cache … … 1887 1627 1888 1628 1889 ////////////////////////////////////////////////////////////1890 static unsigned int _update_dir_entry( fat_inode_t* inode )1891 {1892 // get Cache-File buffer containing the parent directory entry1893 // 128 directories entries in one 4 Kbytes buffer1894 fat_cache_desc_t* pdesc;1895 unsigned char* buffer;1896 unsigned int cluster_id = inode->dentry>>7;1897 unsigned int offset = (inode->dentry & 0x7F)<<5;1898 1899 if ( _get_file_cache_buffer( inode->parent,1900 cluster_id,1901 0,1902 &pdesc ) ) return 1;1903 buffer = pdesc->buffer;1904 pdesc->dirty = 1;1905 1906 // update size field1907 buffer[offset + 28] = inode->size>>0; // size.B01908 buffer[offset + 29] = inode->size>>8; // size.B11909 buffer[offset + 30] = inode->size>>16; // size.B21910 buffer[offset + 31] = inode->size>>24; // size.B31911 1912 // update cluster field1913 buffer[offset + 26] = inode->cluster>>0; // cluster.B01914 buffer[offset + 27] = inode->cluster>>8; // cluster.B11915 buffer[offset + 20] = inode->cluster>>16; // cluster.B21916 buffer[offset + 21] = inode->cluster>>24; // cluster.B31917 1918 return 0;1919 } // end _update_dir_entry()1920 1921 1922 1923 1924 1629 ////////////////////////////////////////////////////////////////// 1925 1630 static unsigned int _get_child_from_parent( fat_inode_t* parent, … … 1929 1634 fat_inode_t* current; 1930 1635 1931 #if (GIET_DEBUG_FAT & 1)1636 #if GIET_DEBUG_FAT 1932 1637 if ( _get_proctime() > GIET_DEBUG_FAT ) 1933 1638 _printf("\n[DEBUG FAT] _get_child_from_parent(): search <%s> in directory <%s>\n", … … 1941 1646 { 1942 1647 1943 #if (GIET_DEBUG_FAT & 1)1944 if ( _get_proctime() > GIET_DEBUG_FAT ) 1945 _printf("\n[DEBUG FAT] _get_child_from_parent(): found inode <%s> in directory<%s>\n",1648 #if GIET_DEBUG_FAT 1649 if ( _get_proctime() > GIET_DEBUG_FAT ) 1650 _printf("\n[DEBUG FAT] _get_child_from_parent(): found inode for <%s> in <%s>\n", 1946 1651 name , parent->name ); 1947 1652 #endif … … 1972 1677 int found = 0; // not found (0) / name found (1) / end of dir (-1) 1973 1678 1974 #if (GIET_DEBUG_FAT & 1)1975 if ( _get_proctime() > GIET_DEBUG_FAT ) 1976 _printf("\n[DEBUG FAT] _get_child_from_parent(): does not found inode <%s>"1977 " in directory <%s> => search incache\n", name , parent->name );1679 #if GIET_DEBUG_FAT 1680 if ( _get_proctime() > GIET_DEBUG_FAT ) 1681 _printf("\n[DEBUG FAT] _get_child_from_parent(): child <%s> in <%s> not found in Inode-Tree\n" 1682 " search in parent cache\n", name , parent->name ); 1978 1683 #endif 1979 1684 … … 2034 1739 _strcpy( cname + 26 , lfn3 ); 2035 1740 } 2036 2037 // get d ir-entry arguments if extracted name == searched name1741 1742 // get dentry arguments if extracted name == searched name 2038 1743 if ( _strcmp( name , cname ) == 0 ) 2039 1744 { … … 2044 1749 size = _read_entry( DIR_FILE_SIZE , buffer + offset , 1 ); 2045 1750 found = 1; 2046 2047 // adjust size for a directory :2048 // size must be non-zero and rounded to a multiple of 4 Kbytes2049 if ( is_dir )2050 {2051 if ( size == 0 ) size = 4096;2052 else if ( size & 0xFFF ) size = ((size>>12) + 1)<<12;2053 }2054 1751 } 2055 1752 offset = offset + 32; … … 2064 1761 { 2065 1762 2066 #if (GIET_DEBUG_FAT & 1)1763 #if GIET_DEBUG_FAT 2067 1764 if ( _get_proctime() > GIET_DEBUG_FAT ) 2068 1765 _printf("\n[DEBUG FAT] _get_child_from_parent(): found end of directory in <%s>\n", … … 2086 1783 _add_inode_in_tree( *inode , parent ); 2087 1784 2088 #if (GIET_DEBUG_FAT & 1)1785 #if GIET_DEBUG_FAT 2089 1786 if ( _get_proctime() > GIET_DEBUG_FAT ) 2090 1787 _printf("\n[DEBUG FAT] _get_child_from_parent(): found <%s> on device\n", name ); … … 2108 1805 unsigned int code; // return value 2109 1806 2110 #if (GIET_DEBUG_FAT & 1)1807 #if GIET_DEBUG_FAT 2111 1808 if ( _get_proctime() > GIET_DEBUG_FAT ) 2112 1809 _printf("\n[DEBUG FAT] _get_inode_from_path(): enters for path <%s>\n", pathname ); … … 2117 1814 { 2118 1815 2119 #if (GIET_DEBUG_FAT & 1)1816 #if GIET_DEBUG_FAT 2120 1817 if ( _get_proctime() > GIET_DEBUG_FAT ) 2121 1818 _printf("\n[DEBUG FAT] _get_inode_from_path(): found root inode for <%s>\n", … … 2145 1842 last = (pathname[nb_read] == 0); 2146 1843 2147 #if (GIET_DEBUG_FAT & 1)1844 #if GIET_DEBUG_FAT 2148 1845 if ( _get_proctime() > GIET_DEBUG_FAT ) 2149 1846 _printf("\n[DEBUG FAT] _get_inode_from_path(): got name <%s>\n", name ); … … 2176 1873 { 2177 1874 2178 #if (GIET_DEBUG_FAT & 1)1875 #if GIET_DEBUG_FAT 2179 1876 if ( _get_proctime() > GIET_DEBUG_FAT ) 2180 1877 _printf("\n[DEBUG FAT] _get_inode_from_path(): neither parent, nor child found for <%s>\n", … … 2194 1891 { 2195 1892 2196 #if (GIET_DEBUG_FAT & 1)1893 #if GIET_DEBUG_FAT 2197 1894 if ( _get_proctime() > GIET_DEBUG_FAT ) 2198 1895 _printf("\n[DEBUG FAT] _get_inode_from_path(): found inode for <%s>\n", … … 2204 1901 { 2205 1902 2206 #if (GIET_DEBUG_FAT & 1)1903 #if GIET_DEBUG_FAT 2207 1904 if ( _get_proctime() > GIET_DEBUG_FAT ) 2208 1905 _printf("\n[DEBUG FAT] _get_inode_from_path(): found only parent inode for <%s>\n", … … 2234 1931 2235 1932 // release clusters allocated to file/dir in DATA region 2236 if ( _clusters_release( inode ->cluster) ) return 1;1933 if ( _clusters_release( inode ) ) return 1; 2237 1934 2238 1935 // release File-Cache … … 2295 1992 { 2296 1993 2297 #if (GIET_DEBUG_FAT & 1)1994 #if GIET_DEBUG_FAT 2298 1995 if ( _get_proctime() > GIET_DEBUG_FAT ) 2299 1996 _printf("\n[DEBUG FAT] _file_info_no_cache(): enters for path <%s>\n", pathname ); … … 2332 2029 if ( _get_name_from_path( pathname, name, &nb_read ) ) return 1; 2333 2030 2334 #if (GIET_DEBUG_FAT & 1)2031 #if GIET_DEBUG_FAT 2335 2032 if ( _get_proctime() > GIET_DEBUG_FAT ) 2336 2033 _printf("\n[DEBUG FAT] _file_info_no_cache(): search name <%s>" … … 2451 2148 } // end loop on names 2452 2149 2453 #if (GIET_DEBUG_FAT & 1)2150 #if GIET_DEBUG_FAT 2454 2151 if ( _get_proctime() > GIET_DEBUG_FAT ) 2455 2152 _printf("\n[DEBUG FAT] _file_info_no_cache(): success for <%s> / " … … 2465 2162 2466 2163 2467 ////////////////////////////////////////////////////////////////////////// 2468 static unsigned int _get_fat_cache_buffer( unsigned int cluster_id, 2469 fat_cache_desc_t** desc ) 2470 { 2471 // get cache pointer and number of levels 2472 fat_cache_node_t* node = _fat.fat_cache_root; 2473 unsigned int level = _fat.fat_cache_levels; 2474 2475 if ( _get_levels_from_size( (cluster_id + 1) * 4096 ) > level ) 2476 { 2477 _printf("\n[FAT ERROR] in _get_fat_cache_buffer() : " 2478 "cluster_id %d too large", cluster_id ); 2164 2165 ///////////////////////////// 2166 unsigned int _set_fs_info() 2167 { 2168 2169 #if GIET_DEBUG_FAT 2170 if ( _get_proctime() > GIET_DEBUG_FAT ) 2171 _printf("\n[DEBUG FAT] _set_fs_info(): enters at cycle %d\n", _get_proctime() ); 2172 #endif 2173 2174 // load FS_INFO sector into FAT buffer 2175 if ( _fat_ioc_access( 0, // no descheduling 2176 1, // read 2177 _fat.fs_info_lba, // lba 2178 (unsigned int)_fat.block_buffer, 2179 1 ) ) // one block 2180 { 2181 _printf("\n[FAT ERROR] _set_fs_info(): cannot load FS_INFO Sector\n"); 2479 2182 return 1; 2480 2183 } 2481 2184 2482 // search the 64-tree cache from top to bottom 2483 while ( level ) 2484 { 2485 // compute child index at each level 2486 unsigned int index = (cluster_id >> (6*(level-1))) & 0x3F; 2487 2488 if ( level == 1 ) // last level => children are buffer descriptors 2489 { 2490 fat_cache_desc_t* pdesc = (fat_cache_desc_t*)node->children[index]; 2491 2492 if ( pdesc == NULL ) // miss 2185 _fat.block_buffer_lba = _fat.fs_info_lba; 2186 2187 #if GIET_DEBUG_FAT 2188 if ( _get_proctime() > GIET_DEBUG_FAT ) 2189 _printf("\n[DEBUG FAT] _set_fs_info(): FS-INFO sector loaded\n"); 2190 #endif 2191 2192 // get general info from FAT descriptor 2193 unsigned int fat_blocks = _fat.fat_sectors; 2194 unsigned int data_blocks = _fat.data_sectors; 2195 unsigned int lba = _fat.fat_lba; 2196 unsigned int* buf = (unsigned int*)_fat.block_buffer; 2197 2198 // initialise <free_clusters_number> from FS-INFO sector 2199 unsigned int free_clusters = _read_entry( FS_FREE_CLUSTERS, _fat.block_buffer, 1); 2200 if ( free_clusters >= (data_blocks>>3) ) 2201 { 2202 _printf("\n[FAT ERROR] _set_fs_info(): illegal FS_FREE_CLUSTERS in FS-INFO\n" 2203 " fs_free_clusters = %x / total_clusters = %x\n", 2204 free_clusters , (data_blocks>>3) ); 2205 return 1; 2206 } 2207 2208 _fat.free_clusters_number = free_clusters; 2209 2210 // scan FAT on device from FS-FREE_CLUSTER_HINT to initialise <first_free_cluster> 2211 unsigned int free_cluster_hint = _read_entry( FS_FREE_CLUSTER_HINT, _fat.block_buffer, 1); 2212 if ( free_cluster_hint > (data_blocks>>3) ) 2213 { 2214 _printf("\n[FAT ERROR] _set_fs_info(): illegal FS_FREE_CLUSTER_HINT in FS-INFO\n" 2215 " fs_free_cluster_hint = %x / total_clusters = %x\n", 2216 free_cluster_hint , (data_blocks>>3) ); 2217 return 1; 2218 } 2219 2220 unsigned int block_id = free_cluster_hint>>7; 2221 unsigned int first_entry = free_cluster_hint & 0x7F; 2222 unsigned int search = 1; 2223 unsigned int first_free = 0; 2224 2225 // loop on the FAT blocks from free_cluster_hint 2226 // until free cluster found or end of FAT region 2227 while ( search && (block_id < fat_blocks) ) 2228 { 2229 // read one FAT block from device 2230 if ( _fat_ioc_access( 0, // no_irq 2231 1, // to_mem, 2232 lba + block_id, // lba 2233 (unsigned int)buf, // FAT local buffer 2234 1 ) ) // one block 2235 { 2236 _printf("\n[FAT_ERROR] _set_fs_info() : cannot read FAT block %d\n", block_id); 2237 return 1; 2238 } 2239 2240 _fat.block_buffer_lba = lba + block_id; 2241 2242 // scan the entries in block from first_entry to 128 2243 unsigned int entry; 2244 for ( entry = first_entry ; entry < 128 ; entry++ ) 2245 { 2246 if ( buf[entry] == FREE_CLUSTER ) 2493 2247 { 2248 first_free = (block_id<<7) + entry; 2249 search = 0; 2250 break; 2251 } 2252 } // end loop on entries 2253 2254 block_id++; 2255 first_entry = 0; 2256 } // end loop on blocks 2257 2258 if ( search ) // no free cluster 2259 { 2260 _printf("\n[FAT_ERROR] _set_fs_info() : No free cluster found in FAT\n"); 2261 return 1; 2262 } 2263 else // update fat descriptor 2264 { 2265 _fat.first_free_cluster = first_free; 2266 2267 #if GIET_DEBUG_FAT 2268 if ( _get_proctime() > GIET_DEBUG_FAT ) 2269 _printf("\n[DEBUG FAT] _set_fs_info() completes : free_clusters = %x / first_free = %x\n", 2270 free_clusters , first_free ); 2271 #endif 2272 2273 return 0; 2274 } 2275 } // end _set_fs_info() 2276 2277 2278 /////////////////////////////////////////////////////////////////////////////// 2279 /////////////////////////////////////////////////////////////////////////////// 2280 // Extern functions 2281 /////////////////////////////////////////////////////////////////////////////// 2282 /////////////////////////////////////////////////////////////////////////////// 2283 2284 ///////////////////////////////////////////////////////////////////////////// 2285 int _fat_ioc_access( unsigned int use_irq, // descheduling if non zero 2286 unsigned int to_mem, // read / write 2287 unsigned int lba, // first sector on device 2288 unsigned int buf_vaddr, // memory buffer vaddr 2289 unsigned int count ) // number of sectors 2290 { 2291 // compute memory buffer physical address 2292 unsigned int flags; // for _v2p_translate 2293 unsigned long long buf_paddr; // buffer physical address 2294 2295 if ( ((_get_mmu_mode() & 0x4) == 0 ) || USE_IOC_RDK ) // identity 2296 { 2297 buf_paddr = (unsigned long long)buf_vaddr; 2298 } 2299 else // V2P translation required 2300 { 2301 buf_paddr = _v2p_translate( buf_vaddr , &flags ); 2302 } 2494 2303 2495 2304 #if (GIET_DEBUG_FAT & 1) 2496 2305 if ( _get_proctime() > GIET_DEBUG_FAT ) 2497 _printf("\n[DEBUG FAT] _get_fat_cache_buffer(): miss for cluster_id %d\n", cluster_id ); 2498 #endif 2499 // compute missing cluster lba 2500 unsigned int lba = _fat.fat_lba + (cluster_id << 3); 2501 2502 // allocate a 4 Kbytes buffer and a buffer descriptor 2503 void* buf = _malloc( 4096 ); 2504 pdesc = _malloc( sizeof(fat_cache_desc_t) ); 2505 pdesc->lba = lba; 2506 pdesc->buffer = buf; 2507 pdesc->dirty = 0; 2508 node->children[index] = pdesc; 2509 2510 // load cluster from device 2511 if ( _fat_ioc_access( 1, // descheduling 2512 1, // to memory 2513 lba, 2514 (unsigned int)buf, 2515 8 ) ) 2516 { 2517 _free( buf ); 2518 _free( pdesc ); 2519 _printf("\n[FAT ERROR] in _get_fat_cache_buffer() : " 2520 ": cannot access block device for lba = %x\n", lba ); 2521 return 1; 2522 } 2523 2524 } 2525 2526 #if (GIET_DEBUG_FAT & 1) 2527 if ( _get_proctime() > GIET_DEBUG_FAT ) 2528 _printf("\n[DEBUG FAT] _get_fat_cache_buffer() : found buffer = %x\n", 2529 (unsigned int)pdesc->buffer ); 2530 #endif 2531 // return pdesc pointer 2532 *desc = pdesc; 2533 2534 // prepare next iteration 2535 level--; 2536 } 2537 else // not last level => children are 64-tree nodes 2538 { 2539 fat_cache_node_t* child = (fat_cache_node_t*)node->children[index]; 2540 if ( child == NULL ) // miss 2541 { 2542 // allocate a cache node if miss 2543 child = _allocate_one_cache_node( NULL ); 2544 node->children[index] = child; 2545 } 2546 2547 // prepare next iteration 2548 node = child; 2549 level--; 2550 } 2551 } // end while 2552 2553 return 0; 2554 } // end _get_fat_cache_buffer() 2555 2556 2557 2558 ///////////////////////////////////////////////////////////////////////////// 2559 ///////////////////////////////////////////////////////////////////////////// 2560 // Extern functions 2561 ///////////////////////////////////////////////////////////////////////////// 2562 ///////////////////////////////////////////////////////////////////////////// 2563 2564 2565 ///////////////////////////////////////////////////////////////////////////// 2566 // This function initializes the FAT structures. 2567 // - The Fat-Descriptor is initialized in both boot and kernel modes. 2568 // - The dynamically allocated structures (the Inode-Tre, the Fat_Cache, 2569 // and the File-Cache for the root directory) are only allocated 2570 // and initialized if the "kernel_mode" argument is set. 2571 ///////////////////////////////////////////////////////////////////////////// 2572 // Implementation note: 2573 // This function is called twice, by the boot-loader, and by the kernel_init. 2574 // It does not use dynamic memory allocation from the distributed heap. 2575 // It use informations found in the boot sector and FS-INFO sector. 2576 // that are loaded in the Fat-Descriptor temporary block_buffer. 2577 ///////////////////////////////////////////////////////////////////////////// 2578 // Returns GIET_FAT32_OK on success. 2579 // Returns a negative value on error: 2580 // GIET_FAT32_IO_ERROR, 2581 // GIET_FAT32_INVALID_BOOT_SECTOR 2582 ///////////////////////////////////////////////////////////////////////////// 2306 _printf("\n[DEBUG FAT] _fat_ioc_access(): enters at cycle %d\n" 2307 " to_mem = %d / vaddr = %x / paddr = %l / sectors = %d / lba = %x\n", 2308 _get_proctime(), to_mem, buf_vaddr, buf_paddr, count, lba ); 2309 #endif 2310 2311 2312 #if GIET_NO_HARD_CC // L1 cache inval (virtual addresses) 2313 if ( to_mem ) _dcache_buf_invalidate( buf_vaddr, count<<9 ); 2314 #endif 2315 2316 2317 #if ( USE_IOC_BDV ) // call the proper driver 2318 return( _bdv_access( use_irq , to_mem , lba , buf_paddr , count ) ); 2319 #elif ( USE_IOC_HBA ) 2320 return( _hba_access( use_irq , to_mem , lba , buf_paddr , count ) ); 2321 #elif ( USE_IOC_SDC ) 2322 return( _sdc_access( use_irq , to_mem , lba , buf_paddr , count ) ); 2323 #elif ( USE_IOC_SPI ) 2324 return( _spi_access( use_irq , to_mem , lba , buf_paddr , count ) ); 2325 #elif ( USE_IOC_RDK ) 2326 return( _rdk_access( use_irq , to_mem , lba , buf_paddr , count ) ); 2327 #else 2328 _printf("\n[FAT ERROR] _fat_ioc_access(): no IOC driver\n"); 2329 _exit(); 2330 #endif 2331 2332 } // end _fat_ioc_access() 2333 2334 2335 2336 ///////////////////////////////////////// 2583 2337 int _fat_init( unsigned int kernel_mode ) 2584 2338 { … … 2613 2367 { 2614 2368 _printf("\n[DEBUG FAT] _fat_init(): Boot sector loaded\n"); 2615 _display_one_block( _fat.block_buffer, "block device", _fat.block_buffer_lba );2616 2369 } 2617 2370 #endif … … 2656 2409 _fat.initialized = FAT_INITIALIZED; 2657 2410 2658 // load FS_INFO sector into FAT buffer 2659 if ( _fat_ioc_access( 0, // no descheduling 2660 1, // read 2661 _fat.fs_info_lba, // lba 2662 (unsigned int)_fat.block_buffer, 2663 1 ) ) // one block 2664 { 2665 _printf("\n[FAT ERROR] _fat_init(): cannot load FS_INFO Sector\n"); 2666 return GIET_FAT32_IO_ERROR; 2667 } 2668 2669 _fat.block_buffer_lba = _fat.fs_info_lba; 2670 2671 #if GIET_DEBUG_FAT 2672 if ( _get_proctime() > GIET_DEBUG_FAT ) 2673 { 2674 _printf("\n[DEBUG FAT] _fat_init(): FS-INFO sector loaded\n"); 2675 _display_one_block( _fat.block_buffer, "block device", _fat.block_buffer_lba ); 2676 } 2677 #endif 2678 2679 // initialise Fat-Descriptor from FS_INFO 2680 _fat.free_clusters_number = _read_entry( FS_FREE_CLUSTERS , _fat.block_buffer, 1); 2681 _fat.first_free_cluster = _read_entry( FS_FREE_CLUSTER_HINT, _fat.block_buffer, 1); 2682 2411 ///////////////////////////////////////////////////////////////////// 2683 2412 // This is done only when the _fat_init() is called in kernel mode 2684 2413 2685 2414 if ( kernel_mode ) 2686 2415 { 2687 unsigned int i; 2416 // initialise <free_clusters_number> and <first_free_cluster in FAT descriptor 2417 if ( _set_fs_info() ) return GIET_FAT32_IO_ERROR; 2688 2418 2689 2419 // create Inode-Tree root … … 2700 2430 2701 2431 // initialize File Descriptor Array 2432 unsigned int i; 2702 2433 for( i = 0 ; i < GIET_OPEN_FILES_MAX ; i++ ) _fat.fd[i].allocated = 0; 2703 2434 … … 2718 2449 2719 2450 2720 /////////////////////////////////////////////////////////////////////////////// 2721 // This function implements the giet_fat_open() system call. 2722 // The semantic is similar to the UNIX open() function, with some limitations: 2723 // - only the O_CREAT, O_RDONLY, and O_TRUNC flags are supported. 2724 // - the UNIX access rights are not supported. 2725 // If the file does not exist in the specified directory, it is created when 2726 // the O_CREAT flag is set. 2727 // If the specified directory does not exist, an error is returned. 2728 // It allocates a file descriptor to the calling task, for the file identified 2729 // by the <pathname> argument. If several tasks try to open the same file, 2730 // each task obtains a private file descriptor. 2731 // A node name (file or directory) cannot be larger than 31 characters. 2732 /////////////////////////////////////////////////////////////////////////////// 2733 // Returns a file descriptor index on success. 2734 // Returns a negative value on error: 2735 // GIET_FAT32_NOT_INITIALIZED, 2736 // GIET_FAT32_FILE_NOT_FOUND, 2737 // GIET_FAT32_NAME_TOO_LONG, 2738 // GIET_FAT32_IO_ERROR, 2739 // GIET_FAT32_TOO_MANY_OPEN_FILES 2740 /////////////////////////////////////////////////////////////////////////////// 2451 //////////////////////////////////////////////////////////////////// 2741 2452 int _fat_open( char* pathname, // absolute path from root 2742 2453 unsigned int flags ) // O_CREAT and O_RDONLY … … 2759 2470 unsigned int p = procid & ((1<<P_WIDTH)-1); 2760 2471 if ( _get_proctime() > GIET_DEBUG_FAT ) 2761 _printf("\n[DEBUG FAT] _fat_open(): P[%d,%d,%d] enters for path <%s> /"2762 " create = %d / read_only = %d \n",2763 x, y, p, pathname , create , read_only );2472 _printf("\n[DEBUG FAT] _fat_open(): P[%d,%d,%d] enters for path <%s>\n" 2473 " create = %d / read_only = %d / truncate = %d\n", 2474 x, y, p, pathname , create , read_only , truncate ); 2764 2475 #endif 2765 2476 … … 2798 2509 return GIET_FAT32_NAME_TOO_LONG; 2799 2510 } 2800 else if ( (code == 1) && (create == 0) ) // inode not found2511 else if ( (code == 1) && (create == 0) ) // child inode not found 2801 2512 { 2802 2513 _spin_lock_release( &_fat.fat_lock ); … … 2807 2518 return GIET_FAT32_FILE_NOT_FOUND; 2808 2519 } 2809 else if ( (code == 1) && (create != 0) ) // inode not found => create2520 else if ( (code == 1) && (create != 0) ) // child inode not found => create 2810 2521 { 2811 2522 // set parent inode pointer … … 2871 2582 } 2872 2583 2873 // update FS_INFO sector2874 if ( _update_fs_info() )2875 {2876 _spin_lock_release( &_fat.fat_lock );2877 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );2878 2879 _printf("\n[FAT ERROR] _fat_open(): cannot update FS-INFO"2880 " for file <%s>\n", pathname );2881 return GIET_FAT32_IO_ERROR;2882 }2883 2884 2584 // no need to truncate a new file 2885 2585 truncate = 0; … … 2910 2610 #if GIET_DEBUG_FAT 2911 2611 if ( _get_proctime() > GIET_DEBUG_FAT ) 2912 _printf("\n[DEBUG FAT] _fat_open(): P[%d,%d,%d] found file <%s> on device : inode = %x\n", 2913 x , y , p , pathname , child ); 2914 #endif 2612 { 2613 _printf("\n[DEBUG FAT] _fat_open(): P[%d,%d,%d] found file <%s>\n" 2614 " inode = %x / size = %x\n", 2615 x , y , p , pathname , (unsigned int)child , child->size ); 2616 2617 _display_clusters_list( child ); 2618 } 2619 #endif 2620 2915 2621 } 2916 2622 … … 2952 2658 2953 2659 // release clusters allocated to file/dir in DATA region 2954 if ( _clusters_release( child ->cluster) )2660 if ( _clusters_release( child ) ) 2955 2661 { 2956 2662 _spin_lock_release( &_fat.fat_lock ); … … 2974 2680 #if GIET_DEBUG_FAT 2975 2681 if ( _get_proctime() > GIET_DEBUG_FAT ) 2976 _printf("\n[DEBUG FAT] _fat_open(): P[%d,%d,%d] got fd = %d for <%s> / " 2977 "size = %x / read_only = %d\n", 2978 x , y , p , fd_id , pathname , read_only ); 2682 _printf("\n[DEBUG FAT] _fat_open(): P[%d,%d,%d] get fd = %d for <%s>\n" 2683 " inode = %x / offset = %x / read_only = %d / size = %x / cluster = %x\n", 2684 x , y , p , fd_id , pathname , 2685 (unsigned int)_fat.fd[fd_id].inode, 2686 _fat.fd[fd_id].seek, 2687 _fat.fd[fd_id].read_only, 2688 _fat.fd[fd_id].inode->size, 2689 _fat.fd[fd_id].inode->cluster ); 2979 2690 #endif 2980 2691 … … 2989 2700 2990 2701 2991 ///////////////////////////////////////////////////////////////////////////////// 2992 // This function implements the "giet_fat_close()" system call. 2993 // It decrements the inode reference count, and release the fd_id entry 2994 // in the file descriptors array. 2995 // If the reference count is zero, it writes all dirty clusters on block device, 2996 // and releases the memory allocated to the File_Cache. 2997 ///////////////////////////////////////////////////////////////////////////////// 2998 // Returns GIET_FAT32_OK on success. 2999 // Returns a negative value on error: 3000 // GIET_FAT32_NOT_INITIALIZED, 3001 // GIET_FAT32_INVALID_FD, 3002 // GIET_FAT32_NOT_OPEN, 3003 // GIET_FAT32_IO_ERROR 3004 ///////////////////////////////////////////////////////////////////////////////// 2702 //////////////////////////////////// 3005 2703 int _fat_close( unsigned int fd_id ) 3006 2704 { … … 3096 2794 #endif 3097 2795 3098 } 2796 } // end if (refcount == 0) 2797 3099 2798 3100 2799 // release fd_id entry in file descriptor array … … 3111 2810 3112 2811 3113 ///////////////////////////////////////////////////////////////////////////////// 3114 // This function implements the giet_fat_file_info() system call. 3115 // It returns the size, the current offset and the directory info for a file 3116 // identified by the "fd_id" argument. 3117 ///////////////////////////////////////////////////////////////////////////////// 3118 // Returns GIET_FAT32_OK on success. 3119 // Returns a negative value on error: 3120 // GIET_FAT32_NOT_INITIALIZED, 3121 // GIET_FAT32_INVALID_FD, 3122 // GIET_FAT32_NOT_OPEN 3123 ///////////////////////////////////////////////////////////////////////////////// 2812 //////////////////////////////////////////// 3124 2813 int _fat_file_info( unsigned int fd_id, 3125 2814 fat_file_info_t* info ) … … 3153 2842 3154 2843 3155 /////////////////////////////////////////////////////////////////////////////////// 3156 // The following function implements the "giet_fat_read()" and "giet_fat_pread')" 3157 // system calls, but can also be used by the kernel in physical addressing mode. 3158 // It transfers <count> bytes from the File_Cache associated to the file 3159 // identified by <fd_id>, to the destination buffer defined by <vaddr>. 3160 // It uses the current file offset defined in the file descriptor. 3161 // If the <extend> 16 MSB bits are non zero, it uses physical addressing: 3162 // the physical address is computed as extend[15:0] | vaddr[31:0] 3163 // In case of miss in the File_Cache, it loads all involved clusters into cache. 3164 /////////////////////////////////////////////////////////////////////////////////// 3165 // Returns the number of bytes actually transfered on success. 3166 // Returns a negative value on error: 3167 // GIET_FAT32_NOT_INITIALIZED, 3168 // GIET_FAT32_INVALID_FD, 3169 // GIET_FAT32_NOT_OPEN, 3170 // GIET_FAT32_IO_ERROR 3171 ///////////////////////////////////////////////////////////////////////////////// 2844 ///////////////////////////////////////////////////////////////////// 3172 2845 int _fat_read( unsigned int fd_id, // file descriptor index 3173 2846 unsigned int vaddr, // destination buffer vaddr … … 3346 3019 3347 3020 3348 ///////////////////////////////////////////////////////////////////////////////// 3349 // The following function implements the "giet_fat_write()" system call, 3350 // but can also be used by the kernel in physical addressing mode. 3351 // It transfers <count> bytes to the File_Cache associated to the file 3352 // identified by <fd_id>, from the source buffer defined by <vaddr>. 3353 // It uses the current file offset defined in the file descriptor. 3354 // If required by the <modes> argument, the physical address is computed 3355 // as extend[15:0] | vaddr[31:0] 3356 // It increases the file size and allocate new clusters if (count + offset) 3357 // is larger than the current file size. Then it loads and updates all 3358 // involved clusters in the cache. 3359 ///////////////////////////////////////////////////////////////////////////////// 3360 // Returns number of bytes actually written on success. 3361 // Returns a negative value on error: 3362 // GIET_FAT32_NOT_INITIALIZED, 3363 // GIET_FAT32_INVALID_FD, 3364 // GIET_FAT32_NOT_OPEN, 3365 // GIET_FAT32_READ_ONLY, 3366 // GIET_FAT32_NO_FREE_SPACE, 3367 // GIET_FAT32_IO_ERROR 3368 ///////////////////////////////////////////////////////////////////////////////// 3021 //////////////////////////////////////////////////////////////// 3369 3022 int _fat_write( unsigned int fd_id, // file descriptor index 3370 3023 unsigned int vaddr, // source buffer vaddr … … 3436 3089 #endif 3437 3090 3438 // che k if file size must be incremented3091 // check if file size must be incremented 3439 3092 // and allocate new clusters from FAT if required 3440 3093 unsigned int old_size = inode->size; … … 3607 3260 3608 3261 3609 ///////////////////////////////////////////////////////////////////////////////// 3610 // The following function implements the "giet_fat_lseek()" system call. 3611 // It repositions the seek in the file descriptor "fd_id", according to 3612 // the "seek" and "whence" arguments. 3613 // It has the same semantic as the UNIX lseek() function. 3614 // Accepted values for whence are SEEK_SET / SEEK_CUR / SEEK_END. 3615 ///////////////////////////////////////////////////////////////////////////////// 3616 // Returns new seek value (in bytes) on success. 3617 // Returns a negative value on error: 3618 // GIET_FAT32_NOT_INITIALIZED, 3619 // GIET_FAT32_INVALID_FD, 3620 // GIET_FAT32_NOT_OPEN, 3621 // GIET_FAT32_INVALID_ARG 3622 ///////////////////////////////////////////////////////////////////////////////// 3262 /////////////////////////////////// 3623 3263 int _fat_lseek( unsigned int fd_id, 3624 3264 unsigned int seek, … … 3693 3333 3694 3334 3695 ///////////////////////////////////////////////////////////////////////////////// 3696 // The following function implements the giet_fat_remove() system call. 3697 // It deletes the file/directory identified by the "pathname" argument from 3698 // the file system, if the remove condition is fulfilled (directory empty, 3699 // or file not referenced). 3700 // All clusters allocated in the block device DATA region are released. 3701 // The FAT region is updated on the block device. 3702 // The Inode-Tree is updated. 3703 // The associated File_Cache is released. 3704 // The Fat_Cache is updated. 3705 ///////////////////////////////////////////////////////////////////////////////// 3706 // Returns GIET_FAT32_OK on success. 3707 // Returns a negative value on error: 3708 // GIET_FAT32_NOT_INITIALIZED, 3709 // GIET_FAT32_FILE_NOT_FOUND, 3710 // GIET_FAT32_NAME_TOO_LONG, 3711 // GIET_FAT32_IS_DIRECTORY, 3712 // GIET_FAT32_NOT_A_DIRECTORY, 3713 // GIET_FAT32_IS_OPEN, 3714 // GIET_FAT32_IO_ERROR, 3715 // GIET_FAT32_DIRECTORY_NOT_EMPTY 3716 ///////////////////////////////////////////////////////////////////////////////// 3335 /////////////////////////////////////// 3717 3336 int _fat_remove( char* pathname, 3718 3337 unsigned int should_be_dir ) … … 3868 3487 3869 3488 3870 ///////////////////////////////////////////////////////////////////////////////// 3871 // This function implements the giet_fat_rename() system call. 3872 // It moves an existing file or directory from one node (defined by "old_path" 3873 // argument) to another node (defined by "new_path" argument) in the FS tree. 3874 // The type (file/directory) and content are not modified. 3875 // If the new_path file/dir exist, it is removed from the file system, but only 3876 // if the remove condition is respected (directory empty / file not referenced). 3877 // The removed entry is only removed after the new entry is actually created. 3878 ///////////////////////////////////////////////////////////////////////////////// 3879 // Returns GIET_FAT32_OK on success. 3880 // Returns a negative value on error: 3881 // GIET_FAT32_NOT_INITIALIZED, 3882 // GIET_FAT32_FILE_NOT_FOUND, 3883 // GIET_FAT32_MOVE_INTO_SUBDIR, 3884 // GIET_FAT32_IO_ERROR, 3885 // GIET_FAT32_DIRECTORY_NOT_EMPTY, 3886 // GIET_FAT32_IS_OPEN 3887 ///////////////////////////////////////////////////////////////////////////////// 3489 ///////////////////////////////// 3888 3490 int _fat_rename( char* old_path, 3889 3491 char* new_path ) … … 4133 3735 4134 3736 4135 ///////////////////////////////////////////////////////////////////////////////// 4136 // The following function implements the giet_fat_mkdir() system call. 4137 // It creates in file system the directory specified by the "pathname" argument. 4138 // The Inode-Tree is updated. 4139 // One cluster is allocated to the new directory. 4140 // The associated File-Cache is created. 4141 // The FAT region on block device is updated. 4142 // The DATA region on block device is updated. 4143 ///////////////////////////////////////////////////////////////////////////////// 4144 // Returns GIET_FAT32_OK on success. 4145 // Returns a negative value on error: 4146 // GIET_FAT32_NOT_INITIALIZED, 4147 // GIET_FAT32_FILE_NOT_FOUND, 4148 // GIET_FAT32_NAME_TOO_LONG, 4149 // GIET_FAT32_FILE_EXISTS, 4150 // GIET_FAT32_NO_FREE_SPACE, 4151 // GIET_FAT32_IO_ERROR 4152 ///////////////////////////////////////////////////////////////////////////////// 3737 //////////////////////////////// 4153 3738 int _fat_mkdir( char* pathname ) 4154 3739 { … … 4240 3825 1, // it's a directory 4241 3826 cluster, 4242 4096, // one bufferfor a directory3827 0, // size = 0 for a directory 4243 3828 0, // count 4244 3829 0, // dentry set by _add_dir_entry() … … 4293 3878 } 4294 3879 4295 // update FS_INFO sector4296 if ( _update_fs_info() )4297 {4298 _spin_lock_release( &_fat.fat_lock );4299 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );4300 4301 _printf("\n[FAT ERROR] _fat_mkdir(): cannot update FS-INFO"4302 " for directory <%s>\n", pathname );4303 return GIET_FAT32_IO_ERROR;4304 }4305 4306 3880 // update DATA region on block device for the new directory 4307 3881 if ( _update_device_from_cache( child->levels, … … 4328 3902 4329 3903 4330 /////////////////////////////////////////////////////////////////////////////// 4331 // This function implements the giet_fat_opendir() system call. 4332 // The semantic is similar to the UNIX opendir() function. 4333 // If the specified directory does not exist, an error is returned. 4334 // It allocates a file descriptor to the calling task, for the directory 4335 // identified by "pathname". If several tasks try to open the same directory, 4336 // each task obtains a private file descriptor. 4337 // A node name cannot be larger than 31 characters. 4338 /////////////////////////////////////////////////////////////////////////////// 4339 // Returns a file descriptor for the directory index on success 4340 // Returns a negative value on error: 4341 // GIET_FAT32_NOT_INITIALIZED, 4342 // GIET_FAT32_NAME_TOO_LONG, 4343 // GIET_FAT32_FILE_NOT_FOUND, 4344 // GIET_FAT32_TOO_MANY_OPEN_FILES, 4345 // GIET_FAT32_NOT_A_DIRECTORY 4346 /////////////////////////////////////////////////////////////////////////////// 3904 ///////////////////////////////////////// 4347 3905 extern int _fat_opendir( char* pathname ) 4348 3906 { … … 4365 3923 4366 3924 4367 ///////////////////////////////////////////////////////////////////////////////// 4368 // This function implements the "giet_fat_closedir()" system call. 4369 // Same behavior as _fat_close(), no check for directory. 4370 ///////////////////////////////////////////////////////////////////////////////// 4371 // Returns GIET_FAT32_OK on success. 4372 // Returns a negative value on error: 4373 // GIET_FAT32_NOT_INITIALIZED, 4374 // GIET_FAT32_INVALID_FD, 4375 // GIET_FAT32_NOT_OPEN, 4376 // GIET_FAT32_IO_ERROR 4377 ///////////////////////////////////////////////////////////////////////////////// 3925 ////////////////////////////////////////////// 4378 3926 extern int _fat_closedir( unsigned int fd_id ) 4379 3927 { … … 4384 3932 4385 3933 4386 ///////////////////////////////////////////////////////////////////////////////// 4387 // This function implements the "giet_fat_readdir()" system call. 4388 // It reads one directory entry from the file descriptor opened by 4389 // "giet_fat_opendir()" and writes its info to the "entry" argument. 4390 // This includes the cluster, size, is_dir and name info for each entry. 4391 ///////////////////////////////////////////////////////////////////////////////// 4392 // Returns GIET_FAT32_OK on success. 4393 // Returns a negative value on error: 4394 // GIET_FAT32_NOT_INITIALIZED, 4395 // GIET_FAT32_INVALID_FD, 4396 // GIET_FAT32_NOT_OPEN, 4397 // GIET_FAT32_NOT_A_DIRECTORY, 4398 // GIET_FAT32_IO_ERROR, 4399 // GIET_FAT32_NO_MORE_ENTRIES 4400 ///////////////////////////////////////////////////////////////////////////////// 3934 ///////////////////////////////////////////// 4401 3935 extern int _fat_readdir( unsigned int fd_id, 4402 3936 fat_dirent_t* entry ) … … 4506 4040 4507 4041 4508 /////////////////////////////////////////////////////////////////////////////// 4509 // This function loads a file identified by the "pathname" argument into the 4510 // memory buffer defined by the "buffer_vbase" and "buffer_size" arguments. 4511 // It is intended to be called by the boot-loader, as it does not use the 4512 // dynamically allocated FAT structures (Inode-Tree, Fat_Cache or File-Cache, 4513 // File-Descriptor-Array). 4514 // It uses only the 512 bytes buffer defined in the FAT descriptor. 4515 /////////////////////////////////////////////////////////////////////////////// 4516 // Returns GIET_FAT32_OK on success. 4517 // Returns negative value on error: 4518 // GIET_FAT32_NOT_INITIALIZED 4519 // GIET_FAT32_FILE_NOT_FOUND 4520 // GIET_FAT32_BUFFER_TOO_SMALL 4521 // GIET_FAT32_IO_ERROR 4522 /////////////////////////////////////////////////////////////////////////////// 4042 /////////////////////////////////////////////// 4523 4043 int _fat_load_no_cache( char* pathname, 4524 4044 unsigned int buffer_vbase, … … 4613 4133 4614 4134 4615 ////////////////////////////////////////////////////////////////////////////////// 4616 // The following function returns in the <desc> argument a pointer on a buffer 4617 // descriptor contained in a File_Cache. 4618 // The searched buffer is idenfified by the <inode> and <cluster_id> arguments. 4619 // The <cluster_id> argument is the buffer index in the file. 4620 // The <writable> argument define the behaviour in case of miss in File-Cache: 4621 // - if [all clusters (from 0 to cluster_id) are already allocated in FAT] 4622 // we scan the FAT to find the cluster index on device, and we load the 4623 // missing cluster in the File-Cache, marked as dirty if writable is set. 4624 // - else if [writable is not set] we return an error. 4625 // - else [writable set, but all clusters (from 0 to cluster_id) not allocated] 4626 // we allocate in FAT all required clusters, we update the size in the inode 4627 // and dentry, and we allocate a buffer descriptor for the missing cluster, 4628 // marked as dirty. 4629 // This function can be called by the FAT functions, and by _sys_fat_mmap(). 4630 // It does not take the FAT lock, that must be taken by the caller. 4631 ////////////////////////////////////////////////////////////////////////////////// 4632 // It returns 0 on success. 4633 // It returns 1 on error. 4634 ////////////////////////////////////////////////////////////////////////////////// 4135 ////////////////////////////////////////////////////////// 4136 int _get_fat_cache_buffer( unsigned int cluster_id, 4137 fat_cache_desc_t** desc ) 4138 { 4139 // get cache pointer and number of levels 4140 fat_cache_node_t* node = _fat.fat_cache_root; 4141 unsigned int level = _fat.fat_cache_levels; 4142 4143 if ( _get_levels_from_size( (cluster_id + 1) * 4096 ) > level ) 4144 { 4145 _printf("\n[FAT ERROR] in _get_fat_cache_buffer() : " 4146 "cluster_id %d too large", cluster_id ); 4147 return GIET_FAT32_IO_ERROR; 4148 } 4149 4150 // search the 64-tree cache from top to bottom 4151 while ( level ) 4152 { 4153 // compute child index at each level 4154 unsigned int index = (cluster_id >> (6*(level-1))) & 0x3F; 4155 4156 if ( level == 1 ) // last level => children are buffer descriptors 4157 { 4158 fat_cache_desc_t* pdesc = (fat_cache_desc_t*)node->children[index]; 4159 4160 if ( pdesc == NULL ) // miss 4161 { 4162 4163 #if GIET_DEBUG_FAT 4164 if ( _get_proctime() > GIET_DEBUG_FAT ) 4165 _printf("\n[DEBUG FAT] _get_fat_cache_buffer(): miss for cluster_id %d\n", cluster_id ); 4166 #endif 4167 // compute missing cluster lba 4168 unsigned int lba = _fat.fat_lba + (cluster_id << 3); 4169 4170 // allocate a 4 Kbytes buffer and a buffer descriptor 4171 void* buf = _malloc( 4096 ); 4172 pdesc = _malloc( sizeof(fat_cache_desc_t) ); 4173 pdesc->lba = lba; 4174 pdesc->buffer = buf; 4175 pdesc->dirty = 0; 4176 node->children[index] = pdesc; 4177 4178 // load cluster from device 4179 if ( _fat_ioc_access( 1, // descheduling 4180 1, // to memory 4181 lba, 4182 (unsigned int)buf, 4183 8 ) ) 4184 { 4185 _free( buf ); 4186 _free( pdesc ); 4187 _printf("\n[FAT ERROR] in _get_fat_cache_buffer() : " 4188 ": cannot access block device for lba = %x\n", lba ); 4189 return GIET_FAT32_IO_ERROR; 4190 } 4191 4192 } 4193 4194 // return pdesc pointer 4195 *desc = pdesc; 4196 4197 // prepare next iteration 4198 level--; 4199 } 4200 else // not last level => children are 64-tree nodes 4201 { 4202 fat_cache_node_t* child = (fat_cache_node_t*)node->children[index]; 4203 if ( child == NULL ) // miss 4204 { 4205 // allocate a cache node if miss 4206 child = _allocate_one_cache_node( NULL ); 4207 node->children[index] = child; 4208 } 4209 4210 // prepare next iteration 4211 node = child; 4212 level--; 4213 } 4214 } // end while 4215 4216 return 0; 4217 } // end _get_fat_cache_buffer() 4218 4219 4220 4221 4222 ////////////////////////////////////////////////////// 4635 4223 int _get_file_cache_buffer( fat_inode_t* inode, 4636 4224 unsigned int cluster_id, … … 4639 4227 { 4640 4228 4641 #if (GIET_DEBUG_FAT & 1)4642 if ( _get_proctime() > GIET_DEBUG_FAT ) 4643 _printf("\n[DEBUG FAT] _get_file_cache_buffer() : enters in File-Cache <%s>"4229 #if GIET_DEBUG_FAT 4230 if ( _get_proctime() > GIET_DEBUG_FAT ) 4231 _printf("\n[DEBUG FAT] _get_file_cache_buffer() : enters in File-Cache <%s>" 4644 4232 " for cluster_id = %d\n size = %x / cache = %x / desc[%d] = %x\n", 4645 4233 inode->name , cluster_id , … … 4666 4254 { 4667 4255 4668 #if (GIET_DEBUG_FAT & 1)4256 #if GIET_DEBUG_FAT 4669 4257 if ( _get_proctime() > GIET_DEBUG_FAT ) 4670 4258 _printf("\n[DEBUG FAT] _get_file_cache_buffer() : add a File-Cache level\n" ); … … 4675 4263 } 4676 4264 4677 // get File-Cache 4678 fat_cache_node_t* node = inode->cache; 4679 unsigned int level = inode->levels; 4680 4265 // get inode type, size, and File-Cache 4266 unsigned int size = inode->size; 4267 unsigned int is_dir = inode->is_dir; 4268 fat_cache_node_t* node = inode->cache; 4269 unsigned int level = inode->levels; 4681 4270 4682 4271 // search the 64-tree cache from top to bottom … … 4688 4277 if ( level == 1 ) // last level => children are buffer descriptors 4689 4278 { 4690 fat_cache_desc_t* pdesc = (fat_cache_desc_t*)node->children[index]; 4691 unsigned int current = inode->cluster; 4279 fat_cache_desc_t* pdesc = (fat_cache_desc_t*)node->children[index]; 4692 4280 unsigned int next = 0; 4693 4281 unsigned int prev = 0; 4282 unsigned int current; 4694 4283 unsigned int cid; 4695 4284 unsigned int lba; 4696 4697 if ( pdesc == NULL ) // miss in File-Cache 4285 unsigned int cluster_allocated; 4286 4287 // File-Cache miss handling: 4288 // In case of miss, the missing buffer is allocated, 4289 // and the missing cluster is loaded from block device. 4290 // A new cluster is allocated from FAT if required, when 4291 // the writable argument is set. 4292 if ( pdesc == NULL ) 4698 4293 { 4699 4294 4700 #if (GIET_DEBUG_FAT & 1) 4701 if ( _get_proctime() > GIET_DEBUG_FAT ) 4702 _printf("\n[DEBUG FAT] _get_file_cache_buffer() : miss in cache <%s> for cluster_id = %d\n" 4703 " cluster = %x / size = %x / cache = %x / desc[%d] = %x\n", 4704 inode->name , cluster_id , inode-> cluster , inode->size , 4295 #if GIET_DEBUG_FAT 4296 if ( _get_proctime() > GIET_DEBUG_FAT ) 4297 _printf("\n[DEBUG FAT] _get_file_cache_buffer() : miss in File-Cache <%s> " 4298 " for cluster_id = %d\n" 4299 " cluster = %x / size = %x / is_dir = %d / cache = %x / desc[%d] = %x\n", 4300 inode->name , cluster_id , inode->cluster , inode->size , inode->is_dir , 4705 4301 (unsigned int)inode->cache , cluster_id , 4706 4302 (unsigned int)inode->cache->children[cluster_id] ); 4707 4303 #endif 4708 if ( inode->size > (cluster_id<<12) ) // all clusters allocated in FAT 4304 // compute cluster_allocated condition, depending on file / dir type 4305 if ( is_dir ) cluster_allocated = ( cluster_id < is_dir ); 4306 else cluster_allocated = ( (cluster_id<<12) < size ); 4307 4308 if ( cluster_allocated ) // cluster already allocated => allocate buffer 4709 4309 { 4710 4310 // scan the FAT to find the cluster index for cluster_id 4311 current = inode->cluster; 4711 4312 for ( cid = 0 ; cid < cluster_id ; cid++ ) 4712 4313 { … … 4745 4346 } 4746 4347 } 4747 else if ( writable == 0 ) 4348 else if ( writable == 0 ) // not writable and cluster not allocated in FAT 4748 4349 { 4749 4350 _printf("\n[FAT ERROR] in _get_file_cache_buffer() : " … … 4753 4354 return GIET_FAT32_IO_ERROR; 4754 4355 } 4755 else // writable and all clusters NOT allocated in FAT4356 else // writable and cluster NOT allocated in FAT => allocate cluster & buffer 4756 4357 { 4757 4358 // scan the FAT to allocate all required clusters 4359 current = inode->cluster; 4758 4360 for ( cid = 0 ; cid <= cluster_id ; cid++ ) 4759 4361 { … … 4782 4384 } 4783 4385 4784 // update size in inode and directory entry 4785 inode->size = (cluster_id + 1)<<12; 4386 // update size or is_dir attributes in inode 4387 if ( is_dir ) inode->is_dir = cluster_id; 4388 else inode->size = (cluster_id + 1)<<12; 4389 4390 // update directory entry from inode 4786 4391 _update_dir_entry( inode ); 4787 4392 … … 4800 4405 node->children[index] = pdesc; 4801 4406 } 4802 } 4407 } // end File-Cache miss handling 4803 4408 4804 4409 // return pdesc pointer 4805 4410 *desc = pdesc; 4806 4411 4807 #if (GIET_DEBUG_FAT & 1)4808 if ( _get_proctime() > GIET_DEBUG_FAT ) 4809 _printf("\n[DEBUG FAT] _ fat_buffer_from_cache(): found buffer = %x "4412 #if GIET_DEBUG_FAT 4413 if ( _get_proctime() > GIET_DEBUG_FAT ) 4414 _printf("\n[DEBUG FAT] _get_file_cache_buffer(): found buffer = %x " 4810 4415 " in file <%s> for cluster_id %d\n", 4811 4416 (unsigned int)pdesc->buffer , inode->name , cluster_id ); … … 4834 4439 } // end _get_file_cache_buffer() 4835 4440 4441 4442 4443 4444 4445 4836 4446 // Local Variables: 4837 4447 // tab-width: 4
Note: See TracChangeset
for help on using the changeset viewer.