Changeset 291 for soft/giet_vm/giet_fat32/fat32.c
- Timestamp:
- Feb 13, 2014, 3:29:33 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_fat32/fat32.c
r289 r291 83 83 } // end display_fat_cache() 84 84 #endif 85 85 86 86 ////////////////////////////////////////////////////////////////////////////////// 87 87 // This function returns the length of a FAT field. This field is identified … … 92 92 { 93 93 return length; 94 } 95 96 ////////////////////////////////////////////////////////////////////////////// 97 // Write one 32 bits word "value" in a char[] buffer. 98 // This field is defined by the offset and size arguments. 99 ////////////////////////////////////////////////////////////////////////////// 100 static void write_entry( unsigned int offset, 101 unsigned int size, 102 char* buffer, 103 unsigned int value ) 104 { 105 unsigned int turn = 0; 106 unsigned int res = value; 107 unsigned int mask = 0x000000ff; 108 109 while( turn != size - 1 ) 110 { 111 buffer[ offset + turn ] = res & mask; 112 res = res >> 8; 113 turn++; 114 } 115 buffer[offset + turn] = res & mask; 94 116 } 95 117 … … 200 222 } 201 223 } 202 203 ///////////////////////////////////////////////////////////////////////////////204 // This function returns the cluster index from a (32 bytes) directory entry205 ///////////////////////////////////////////////////////////////////////////////206 static inline unsigned int read_cluster( char* buf )207 {208 unsigned int cluster = read_entry( DIR_FST_CLUS_HI, buf, 1 ) << 16;209 cluster = cluster | read_entry( DIR_FST_CLUS_LO, buf, 1 );210 return cluster;211 }212 224 213 225 ////////////////////////////////////////////////////// … … 356 368 } 357 369 370 /////////////////////////////////////////////////////////////////////// 371 // This function analyses the pathname argument, from the character 372 // defined by the *nb_read argument. 373 // It copies the found name (between '/') in the name[] buffer, 374 // and updates the nb_read argument. 375 // Return 1 if name found, Return 0 if NUL character found, 376 /////////////////////////////////////////////////////////////////////// 377 static int get_name_from_path( char* pathname, 378 char* name, 379 unsigned int* nb_read ) 380 { 381 if ( pathname[*nb_read] == 0 ) return 0; 382 383 int i = (pathname[*nb_read] == '/')? (*nb_read) + 1 : *nb_read; 384 int j = 0; 385 386 while(pathname[i] != '/' && pathname[i] != '\0') 387 { 388 name[j] = pathname[i]; 389 j++; 390 i++; 391 } 392 name[j] = 0; 393 394 if ( pathname[i] == '/' ) *nb_read += j+1; 395 else *nb_read += j; 396 397 return 1; 398 } 399 358 400 //////////////////////////////////////////////////////////////////////////////// 359 401 static int get_name_from_short( char* dir_entry, // input: SFN dir_entry … … 372 414 return i; 373 415 } 416 374 417 /////////////////////////////////////////////////////////////////////////////// 375 static int get_name_from_long( char *dir_entry, // input : LFN dir_entry376 char *entry_name ) // output : name418 static int get_name_from_long( char *dir_entry, // input : LFN dir_entry 419 char *entry_name ) // output : name 377 420 { 378 421 unsigned int entry_name_offset = 0; … … 444 487 } // end get_name_from_long() 445 488 489 ////////////////////////////////////////////////////////////////////////////////////// 490 // This function update a DIR_ENTRY, write a new value into a specific field 491 // (ex : DIR_FILE_SIZE, when we want update the file size after a fat_write) 492 // Return 0 in case of success, > 0 if failure. 493 ////////////////////////////////////////////////////////////////////////////////////// 494 // TODO : make this function less complex 495 ////////////////////////////////////////////////////////////////////////////////////// 496 static inline unsigned int update_entry( unsigned int fd_id, 497 unsigned int field, 498 unsigned int size, 499 unsigned int value ) 500 { 501 char dir_entry[32]; // buffer to store a full directory_entry 502 char name_entry[14]; // buffer to store a 13 characters (partial) name 503 char file_name[256]; // buffer to store the name (not pathname) of the file 504 char sfn[12] = {[0 ... 10] = ' ', '\0'}; // buffer for a Short File Name 505 506 unsigned int lba = fat.fd[fd_id].lba_dir_entry; // Lba of file dir_entry 507 unsigned int is_sfn; 508 unsigned int attr = 0; // directory entry attribute 509 unsigned int ord = 0; // directory entry sequence 510 unsigned int found = 0; // name found 511 unsigned int offset = 0; 512 unsigned int i = 0; 513 unsigned int nb_read = 0; 514 515 for ( i = 0 ; i < 32 ; i++ ) dir_entry[i] = 0; 516 for ( i = 0 ; i < 14 ; i++ ) name_entry[i] = 0; 517 518 // Get the name of the file. 519 while ( get_name_from_path( fat.fd[fd_id].name, file_name, &nb_read ) ) 520 { 521 } 522 523 // Check if file_name is short 524 is_sfn = is_short( file_name, sfn ); 525 526 if ( _ioc_read( IOC_KERNEL_MODE, // mode for IOC driver 527 lba, // sector index 528 fat.fat_cache, // buffer address 529 1 ) ) // one sector 530 { 531 _tty_get_lock( 0 ); 532 _puts("[FAT ERROR] in update_entry() cannot read sector "); 533 _putd( lba ); 534 _puts("\n"); 535 _tty_release_lock( 0 ); 536 return 1; 537 } 538 fat.cache_lba = lba; 539 540 // - the offset increment is an integer number of directory entry (32 bytes) 541 // - the exit condition is success (name found) or failure (end of directory) 542 while ( !found ) 543 { 544 attr = read_entry( DIR_ATTR, fat.fat_cache + offset, 0 ); 545 ord = read_entry( LDIR_ORD, fat.fat_cache + offset, 0 ); 546 547 if ( is_sfn == 1 ) // searched name is short 548 { 549 if ( (ord != FREE_ENTRY ) && 550 (ord != NO_MORE_ENTRY) && 551 (attr == ATTR_LONG_NAME_MASK) ) // LFN entry : skipped 552 { 553 offset = offset + ((ord & 0xF) * DIR_ENTRY_SIZE); 554 continue; 555 } 556 else if ( (attr != ATTR_LONG_NAME_MASK) && 557 (ord != FREE_ENTRY) && 558 (ord != NO_MORE_ENTRY ) ) // SFN entry : checked 559 { 560 _memcpy( dir_entry, fat.fat_cache + offset, DIR_ENTRY_SIZE ); 561 } 562 else if (ord == NO_MORE_ENTRY ) // end of directory : return 563 { 564 _tty_get_lock( 0 ); 565 _puts("[FAT ERROR] in update_entry() end of directory reaches "); 566 _puts("\n"); 567 _tty_release_lock( 0 ); 568 return 1; 569 } 570 else // free entry : skipped 571 { 572 offset = offset + DIR_ENTRY_SIZE; 573 continue; 574 } 575 } 576 else // searched name is long 577 { 578 if ( (attr == ATTR_LONG_NAME_MASK) && 579 (ord != FREE_ENTRY) && 580 (ord != NO_MORE_ENTRY) ) // LFN entry : checked 581 { 582 _memcpy( dir_entry, fat.fat_cache + offset, DIR_ENTRY_SIZE ); 583 } 584 else if ( (attr != ATTR_LONG_NAME_MASK) && 585 (ord != FREE_ENTRY) && 586 (ord != NO_MORE_ENTRY)) // SFN entry : skipped 587 { 588 offset = offset + DIR_ENTRY_SIZE; 589 continue; 590 } 591 else if (ord == NO_MORE_ENTRY ) // end of directory : return 592 { 593 _tty_get_lock( 0 ); 594 _puts("[FAT ERROR] in update_entry() end of directory reaches "); 595 _puts("\n"); 596 _tty_release_lock( 0 ); 597 return 1; 598 } 599 else // free entry : skipped 600 { 601 offset = offset + DIR_ENTRY_SIZE; 602 continue; 603 } 604 } 605 606 // testing the name extracted from dir entry 607 608 if ( is_sfn == 1 ) // searched name is short 609 { 610 get_name_from_short( dir_entry, name_entry ); 611 612 if ( _strncmp( (char*)sfn, (char*)name_entry, 13 ) == 0 ) 613 { 614 write_entry(offset + field, size, fat.fat_cache, value); 615 found = 1; 616 } 617 else // no matching : skip 618 { 619 offset = offset + DIR_ENTRY_SIZE; 620 } 621 } 622 else // searched name is long 623 { 624 get_name_from_long( dir_entry, name_entry ); 625 626 unsigned shift = ((ord & 0xf) - 1) * 13; 627 if ( _strncmp( (char*)(file_name + shift), (char*)name_entry, 13 ) == 0 ) 628 { 629 if ( (ord & 0xf) == 1 ) 630 { 631 offset = offset + DIR_ENTRY_SIZE; 632 write_entry(offset + field, size, fat.fat_cache, value); 633 found = 1; 634 } 635 offset = offset + DIR_ENTRY_SIZE; 636 continue; 637 } 638 else // no matching : skip 639 { 640 offset = offset + ((ord & 0xf) * DIR_ENTRY_SIZE) + DIR_ENTRY_SIZE; 641 } 642 } 643 } 644 645 return _ioc_write( IOC_KERNEL_MODE, 646 lba, 647 fat.fat_cache, 648 1 ); 649 } 650 ////////////////////////////////////////////////////////////////////////////////// 651 // This function update FS_INFO, for new last cluster allocated and number of free 652 // cluster. 653 // Return 0 in case of success, > 0 if failure. 654 ////////////////////////////////////////////////////////////////////////////////// 655 static inline unsigned int update_fs_info( ) 656 { 657 unsigned int lba = fat.fs_info_lba; 658 659 #if GIET_DEBUG_FAT 660 _tty_get_lock( 0 ); 661 _puts("\n[FAT DEBUG] Enter in update_fs_info()\n"); 662 _tty_release_lock( 0 ); 663 #endif 664 665 if ( lba == fat.cache_lba ) // hit cache 666 { 667 write_entry( FS_FREE_CLUSTER , fat.fat_cache, fat.number_free_cluster ); 668 write_entry( FS_FREE_CLUSTER_HINT, fat.fat_cache, fat.last_cluster_allocated ); 669 } 670 else // miss cache 671 { 672 if ( _ioc_read( IOC_KERNEL_MODE, // mode for IOC driver 673 lba, // sector index 674 fat.fat_cache, // fat cache 675 1 ) ) // one sector 676 { 677 _tty_get_lock( 0 ); 678 _puts("[FAT_ERROR] in update_fat() cannot read block "); 679 _putd( lba ); 680 _puts("\n"); 681 _tty_release_lock( 0 ); 682 return 1; 683 } 684 fat.cache_lba = lba; 685 write_entry( FS_FREE_CLUSTER , fat.fat_cache, fat.number_free_cluster ); 686 write_entry( FS_FREE_CLUSTER_HINT, fat.fat_cache, fat.last_cluster_allocated ); 687 } 688 return _ioc_write( IOC_KERNEL_MODE, 689 lba, 690 fat.fat_cache, 691 1 ); 692 } 693 694 ////////////////////////////////////////////////////////////////////////////////// 695 // This function update FAT, write a new value into cluster index. 696 // Used by the function _fat_allocate to update the chaining of clusters. 697 // Return 0 in case of success, > 0 if failure. 698 ////////////////////////////////////////////////////////////////////////////////// 699 static inline unsigned int update_fat( unsigned int cluster, 700 unsigned int value ) 701 { 702 unsigned int lba = fat.partition_lba + 32 + (cluster / 128); 703 704 #if GIET_DEBUG_FAT 705 _tty_get_lock( 0 ); 706 _puts("\n[FAT DEBUG] Enter in update_fat() :\n"); 707 _puts(" - Cluster to update = "); 708 _putd( cluster ); 709 _puts("\n"); 710 _puts(" - Value to write = "); 711 _putd( value ); 712 _puts("\n"); 713 _tty_release_lock( 0 ); 714 #endif 715 716 if ( lba == fat.cache_lba ) // hit cache 717 { 718 write_entry( ((cluster % 128) << 2), 4, fat.fat_cache, value ); 719 } 720 else // miss cache 721 { 722 if ( _ioc_read( IOC_KERNEL_MODE, // mode for IOC driver 723 lba, // sector index 724 fat.fat_cache, // fat cache 725 1 ) ) // one sector 726 { 727 _tty_get_lock( 0 ); 728 _puts("[FAT_ERROR] in update_fat() cannot read block "); 729 _putd( lba ); 730 _puts("\n"); 731 _tty_release_lock( 0 ); 732 return 1; 733 } 734 fat.cache_lba = lba; 735 write_entry( ((cluster % 128) << 2), 4, fat.fat_cache, value ); 736 } 737 return _ioc_write( IOC_KERNEL_MODE, 738 lba, 739 fat.fat_cache, 740 1 ); 741 } 742 743 ////////////////////////////////////////////////////////////////////////////////// 744 // This function allocate a count number of cluster to a file by calling the 745 // update_fat function that takes care to update the chaining of clusters. 746 // return 0 if success, -1 if failure 747 ////////////////////////////////////////////////////////////////////////////////// 748 static inline int _fat_allocate( unsigned int fd_id, 749 unsigned int count ) 750 { 751 unsigned int next_cluster = fat.fd[fd_id].first_cluster; // Get the first cluster of file 752 unsigned int cluster_to_allocate = count; // Number of cluster to allocate 753 754 unsigned int last_cluster_file; // Last cluster of the file (EOC) 755 756 unsigned int free_cluster = fat.last_cluster_allocated + 1; // First free cluster 757 758 // Check if free_cluster is really free (must be true) 759 if ( get_next_cluster_id( IOC_KERNEL_MODE, free_cluster ) != FREE_CLUSTER) 760 { 761 _tty_get_lock( 0 ); 762 _puts("\n[FAT ERROR] in _fat_allocate() : first free_cluster isnt free\n"); 763 _tty_release_lock( 0 ); 764 return -1; 765 } 766 // Check if FAT contains enough cluster free for this allocation 767 if ( count > fat.number_free_cluster ) 768 { 769 _tty_get_lock( 0 ); 770 _puts("\n[FAT ERROR] in _fat_allocate() : Not enough free cluster(s) for this allocation\n"); 771 _tty_release_lock( 0 ); 772 return -1; 773 } 774 775 #if GIET_DEBUG_FAT 776 _tty_get_lock( 0 ); 777 _puts("\n[FAT DEBUG] Enter in _fat_allocate() :\n"); 778 _puts(" - Need to allocate "); 779 _putd( count ); 780 _puts(" cluster(s) for file "); 781 _putd( fd_id ); 782 _puts("\n"); 783 _tty_release_lock( 0 ); 784 #endif 785 786 // Get the last cluster allocated for the file (seek END_OF_CHAIN_CLUSTER). 787 do{ 788 last_cluster_file = next_cluster; 789 next_cluster = get_next_cluster_id( IOC_KERNEL_MODE, next_cluster ); 790 }while ( next_cluster < END_OF_CHAIN_CLUSTER ); 791 792 // Loop on the number of cluster needed to be allocated 793 while ( cluster_to_allocate > 0 ) 794 { 795 796 #if GIET_DEBUG_FAT 797 _tty_get_lock( 0 ); 798 _puts("\n[FAT DEBUG] Cluster to update is : "); 799 _putd( last_cluster_file ); 800 _puts("\n"); 801 _puts("[FAT DEBUG] Free cluster is : "); 802 _putd( free_cluster ); 803 _puts("\n"); 804 _puts("[FAT DEBUG] Number of cluster need to be allocated : "); 805 _putd( cluster_to_allocate ); 806 _puts("\n"); 807 _tty_release_lock( 0 ); 808 #endif 809 810 // update, in the FAT, the value of last cluster allocated by the index 811 // of free cluster. 812 if ( update_fat( last_cluster_file, free_cluster ) ) 813 { 814 _tty_get_lock( 0 ); 815 _puts("\n[FAT ERROR] in _fat_allocate() : update fat for file "); 816 _putd( fd_id ); 817 _puts(" failed\n"); 818 _tty_release_lock( 0 ); 819 return -1; 820 } 821 822 cluster_to_allocate = cluster_to_allocate - 1; 823 // Last cluster allocated is then free_cluster 824 last_cluster_file = free_cluster; 825 826 // Last cluster to allocate done, then we must close the chain of clusters 827 if ( cluster_to_allocate == 0 ) 828 { 829 // update, in the FAT, the value of the last cluster allocated by 830 // END_OF_CHAIN_CLUSTER 831 if ( update_fat( last_cluster_file, END_OF_CHAIN_CLUSTER ) ) 832 { 833 _tty_get_lock( 0 ); 834 _puts("\n[FAT ERROR] in _fat_allocate() : update fat for file "); 835 _putd( fd_id ); 836 _puts(" failed\n"); 837 _tty_release_lock( 0 ); 838 return -1; 839 } 840 } 841 842 free_cluster = free_cluster + 1; 843 844 // Check if free_cluster is really free (must be true) 845 if ( get_next_cluster_id( IOC_KERNEL_MODE, free_cluster ) != FREE_CLUSTER) 846 { 847 _tty_get_lock( 0 ); 848 _puts("\n[FAT ERROR] in _fat_allocate() : free_cluster isnt free\n"); 849 _tty_release_lock( 0 ); 850 return -1; 851 } 852 } 853 854 // Update field number_free_cluster and last_cluster_allocated 855 // of structure fat for next fat_allocate 856 fat.last_cluster_allocated = last_cluster_file; 857 fat.number_free_cluster = fat.number_free_cluster - count; 858 859 if ( update_fs_info() ) 860 { 861 _tty_get_lock( 0 ); 862 _puts("\n[FAT ERROR] in _fat_allocate() : update fs_info for file "); 863 _putd( fd_id ); 864 _puts(" failed\n"); 865 _tty_release_lock( 0 ); 866 return -1; 867 } 868 869 return 0; 870 } 871 872 /////////////////////////////////////////////////////////////////////////////// 873 // This function returns the cluster index from a (32 bytes) directory entry 874 /////////////////////////////////////////////////////////////////////////////// 875 static inline unsigned int read_cluster( char* buf ) 876 { 877 unsigned int cluster = read_entry( DIR_FST_CLUS_HI, buf, 1 ) << 16; 878 cluster = cluster | read_entry( DIR_FST_CLUS_LO, buf, 1 ); 879 return cluster; 880 } 881 882 446 883 //////////////////////////////////////////////////////////////////////////////////////// 447 884 // This function read the blocks defined by the cluster index argument, in a data … … 450 887 // Return cluster index if name found / Return -1 if not found, 451 888 //////////////////////////////////////////////////////////////////////////////////////// 452 static int scan_directory( unsigned int mode, // mode for IOC driver 453 unsigned int cluster, // cluster containing dir_entry 454 char* file_name, // searched file/directory name 455 unsigned int* file_size ) // file size 889 static int scan_directory( unsigned int mode, // mode for IOC driver 890 unsigned int cluster, // cluster containing dir_entry 891 char* file_name, // searched file/directory name 892 unsigned int* file_size, // file size 893 unsigned int* lba_dir_entry ) // lba of dir_entry 456 894 { 457 895 … … 523 961 block_id = fat.sectors_per_cluster; 524 962 } 525 if( _ioc_read( mode, 526 lba, 963 if( _ioc_read( mode, // mode for IOC driver 964 lba, // sector index 527 965 fat.fat_cache, // buffer address 528 1 ) ) 966 1 ) ) // one sector 529 967 { 530 968 _tty_get_lock( 0 ); … … 607 1045 { 608 1046 *file_size = read_entry( DIR_FILE_SIZE , dir_entry, 1 ); 1047 *lba_dir_entry = lba; 609 1048 return read_cluster( dir_entry ); 610 1049 } … … 631 1070 offset = offset + DIR_ENTRY_SIZE; 632 1071 *file_size = read_entry( DIR_FILE_SIZE, dir_entry, 1 ); 1072 *lba_dir_entry = lba; 633 1073 634 1074 #if GIET_DEBUG_FAT … … 643 1083 } // end scan_directory() 644 1084 645 ///////////////////////////////////////////////////////////////////////646 // This function analyses the pathname argument, from the character647 // defined by the *nb_read argument.648 // It copies the found name (between '/') in the name[] buffer,649 // and updates the nb_read argument.650 // Return 1 if name found, Return 0 if NUL character found,651 ///////////////////////////////////////////////////////////////////////652 static int get_name_from_path( char* pathname,653 char* name,654 unsigned int* nb_read )655 {656 if ( pathname[*nb_read] == 0 ) return 0;657 658 int i = (pathname[*nb_read] == '/')? (*nb_read) + 1 : *nb_read;659 int j = 0;660 661 while(pathname[i] != '/' && pathname[i] != '\0')662 {663 name[j] = pathname[i];664 j++;665 i++;666 }667 name[j] = 0;668 669 if ( pathname[i] == '/' ) *nb_read += j+1;670 else *nb_read += j;671 672 return 1;673 }674 1085 675 1086 ////////////////////////////////////////////////////////////////////// … … 744 1155 745 1156 // load Partition Boot Record (first partition sector) into fat cache 746 if ( _ioc_read( mode, 1157 if ( _ioc_read( mode, // mode for IOC driver 747 1158 fat.partition_lba, // sector index 748 1159 fat.fat_cache, // buffer address 749 1 ) ) 1160 1 ) ) // one sector 750 1161 { 751 1162 _tty_get_lock( 0 ); … … 802 1213 return -1; 803 1214 } 1215 fat.fs_info_lba = read_entry( BPB_FAT32_FSINFO, fat.fat_cache, 1 ) + fat.partition_lba; 804 1216 805 1217 // initialise fat descriptor from partition first sector … … 814 1226 for( n = 0 ; n < GIET_OPEN_FILES_MAX ; n++ ) fat.fd[n].used = 0; 815 1227 816 #if (GIET_DEBUG_FAT == 1) 1228 #if GIET_DEBUG_FAT 1229 _tty_get_lock( 0 ); 1230 _puts("\n[FAT DEBUG] FS_INFO Sector = "); 1231 _putd(fat.fs_info_lba); 1232 _puts("\n"); 1233 _tty_release_lock( 0 ); 1234 #endif 1235 1236 // load FS_INFO into fat cache 1237 if ( _ioc_read( mode, // mode for IOC driver 1238 fat.fs_info_lba, // sector index 1239 fat.fat_cache, // buffer address 1240 1 ) ) // one sector 1241 { 1242 _tty_get_lock( 0 ); 1243 _puts("\n[FAT ERROR] in _fat_init() cannot load FS_INFO Sector\n"); 1244 _tty_release_lock( 0 ); 1245 return -1; 1246 } 1247 fat.cache_lba = fat.fs_info_lba; 1248 1249 fat.number_free_cluster = read_entry( FS_FREE_CLUSTER , fat.fat_cache, 1); 1250 fat.last_cluster_allocated = read_entry( FS_FREE_CLUSTER_HINT, fat.fat_cache, 1); 1251 1252 #if GIET_DEBUG_FAT 1253 _tty_get_lock( 0 ); 1254 _puts("\n[FAT DEBUG] Number of Free Clusters = "); 1255 _putd(fat.number_free_cluster); 1256 _puts("\n"); 1257 _puts("\n[FAT DEBUG] Last known cluster allocated = "); 1258 _putd(fat.last_cluster_allocated); 1259 _puts("\n"); 1260 _puts("\n[FAT DEBUG] FS_INFO Sector Loaded\n"); 1261 _tty_release_lock( 0 ); 1262 #endif 1263 1264 1265 #if GIET_DEBUG_FAT 817 1266 _tty_get_lock( 0 ); 818 1267 _puts("\n[FAT DEBUG] Exit _fat_init()\n"); … … 859 1308 unsigned int file_size; // number of bytes 860 1309 unsigned int last_name; // directory containing file name is reached 1310 unsigned int lba; // lba of dir_entry for this file 861 1311 862 1312 #if GIET_DEBUG_FAT … … 873 1323 if ( _fat_init( mode ) ) 874 1324 { 875 _puts("[FAT ERROR] Cannot initialize FAT descriptor f om Boot Sector\n");1325 _puts("[FAT ERROR] Cannot initialize FAT descriptor from Boot Sector\n"); 876 1326 _exit(); 877 1327 } … … 906 1356 _tty_release_lock( 0 ); 907 1357 #endif 1358 908 1359 // test if we reach the last name (file name) 909 1360 if( pathname[nb_read] == 0 ) … … 914 1365 915 1366 // scan current directory 916 cluster = scan_directory( mode, cluster, name, &file_size );1367 cluster = scan_directory( mode, cluster, name, &file_size, &lba ); 917 1368 918 1369 if( cluster == END_OF_CHAIN_CLUSTER && last_name && creat ) … … 959 1410 fat.fd[fd_id].first_cluster = cluster; 960 1411 fat.fd[fd_id].file_size = file_size; 1412 fat.fd[fd_id].lba_dir_entry = lba; 961 1413 _strcpy( fat.fd[fd_id].name, pathname ); 962 1414 … … 1162 1614 // - mode : mode for the IOC driver 1163 1615 // - fd_id : open file descriptor index 1164 // - fd_id : open file descriptor index1165 1616 // - buffer : base address of the memory buffer (must be sector aligned) 1166 1617 // - offset : number of sectors to skip in file … … 1184 1635 unsigned int sectors_to_skip; // number of sectors to skip in first iteration 1185 1636 unsigned int allocate; // need allocate or not 1637 unsigned int current_cluster; // number of cluster allocated to the file 1638 unsigned int required_cluster; // number of cluster needed for the write 1186 1639 1187 1640 // compute file size as a number of sectors … … 1189 1642 if ( file_size & 0x1FF ) file_sectors = (file_size >> 9) + 1; 1190 1643 else file_sectors = (file_size >> 9); 1191 1192 allocate = ( ((count + offset) / spc) > (file_sectors / spc) ); 1644 1645 // Compute the number of clusters occupied by the file 1646 current_cluster = file_sectors / spc; 1647 1648 // Compute the number of clusters that will occupy the file (after fat_write) 1649 required_cluster = (count + offset) / spc; 1650 1651 // Check if we need to allocate new cluster(s) for the file 1652 allocate = ( required_cluster > current_cluster ); 1193 1653 1194 1654 #if GIET_DEBUG_FAT … … 1205 1665 _putd( file_sectors ); 1206 1666 _puts("\n - need allocate = "); 1207 allocate ? _puts( "True" ) : _puts( "False"); 1208 _tty_release_lock( 0 ); 1209 #endif 1210 1211 if ( allocate ) 1212 { 1213 _tty_get_lock( 0 ); 1214 _puts("\n[FAT ERROR] in _fat_write() : \n"); 1215 _puts("we need to allocate more cluster... But this function is not implemented\n"); 1216 _tty_release_lock( 0 ); 1217 return -1; 1218 } 1667 allocate ? _puts( "True" ) : _puts( "False"); 1668 _tty_release_lock( 0 ); 1669 #endif 1670 1219 1671 // arguments checking 1220 1672 if ( fd_id >= GIET_OPEN_FILES_MAX ) … … 1238 1690 _tty_release_lock( 0 ); 1239 1691 return -1; 1692 } 1693 1694 if ( allocate ) 1695 { 1696 if ( _fat_allocate( fd_id, (required_cluster - current_cluster) ) < 0 ) 1697 { 1698 _tty_get_lock( 0 ); 1699 _puts("\n[FAT ERROR] in _fat_write() : fat_allocate for file "); 1700 _putd( fd_id ); 1701 _puts(" failed\n"); 1702 _tty_release_lock( 0 ); 1703 return -1; 1704 } 1240 1705 } 1241 1706 … … 1314 1779 if ( todo_sectors > spc ) iter_sectors = spc; 1315 1780 else iter_sectors = todo_sectors; 1781 } 1782 1783 // Update structure file descriptor, field file_size with 1784 // the new file size if the file is bigger than the previous file 1785 if ( ( offset + count ) > file_sectors ) 1786 { 1787 fat.fd[fd_id].file_size = (count + offset) << 9; 1788 } 1789 1790 // Update entry of directory with the new value 1791 // of file size (Field : DIR_FILE_SIZE) 1792 if ( update_entry(fd_id, DIR_FILE_SIZE, fat.fd[fd_id].file_size) ) 1793 { 1794 _tty_get_lock( 0 ); 1795 _puts("\n[FAT ERROR] in _fat_write() update entry for file "); 1796 _putd( fd_id ); 1797 _puts(" failed\n"); 1798 _tty_release_lock( 0 ); 1799 return -1; 1316 1800 } 1317 1801
Note: See TracChangeset
for help on using the changeset viewer.