- Timestamp:
- Feb 7, 2016, 8:25:16 PM (9 years ago)
- Location:
- soft/giet_vm/giet_fat32
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_fat32/fat32.c
r773 r783 116 116 char* string ); 117 117 118 static unsigned int _set_fs_info(); 119 118 120 static unsigned int _update_fs_info(); 119 121 … … 154 156 fat_inode_t* parent ); 155 157 156 static unsigned int _ clusters_release( fat_inode_t* inode );157 158 static unsigned int _cluster_allocate( fat_inode_t* inode, 159 unsigned int* cluster);158 static unsigned int _one_cluster_allocate( fat_inode_t* inode, 159 unsigned int* cluster ); 160 161 static unsigned int _all_clusters_release( fat_inode_t* inode ); 160 162 161 163 static void _release_cache_memory( fat_cache_node_t* root, … … 176 178 unsigned int cluster ); 177 179 178 static unsigned int _ allocate_one_cluster( unsigned int* cluster );180 static unsigned int _get_free_cluster( unsigned int* cluster ); 179 181 180 182 static unsigned int _remove_node_from_fs( fat_inode_t* inode ); … … 224 226 _fat.data_sectors, 225 227 _fat.free_clusters_number, 226 _fat.f irst_free_cluster,228 _fat.free_cluster_hint, 227 229 _fat.fat_cache_levels ); 228 230 … … 563 565 564 566 565 /////////////////////////////////////566 static unsigned int _update_fs_info()567 {568 // update buffer if miss569 if ( _fat.fs_info_lba != _fat.block_buffer_lba )570 {571 if ( _fat_ioc_access( 1, // descheduling572 1, // read573 _fat.fs_info_lba,574 (unsigned int)_fat.block_buffer,575 1 ) ) // one block576 {577 _printf("\n[FAT_ERROR] _update_fs_info(): cannot read block\n");578 return 1;579 }580 _fat.block_buffer_lba = _fat.fs_info_lba;581 }582 583 // update FAT buffer584 unsigned int* ptr;585 ptr = (unsigned int*)(_fat.block_buffer + get_offset(FS_FREE_CLUSTERS) );586 *ptr = _fat.free_clusters_number;587 588 ptr = (unsigned int*)(_fat.block_buffer + get_offset(FS_FREE_CLUSTER_HINT) );589 *ptr = _fat.first_free_cluster;590 591 // write bloc to FAT592 if ( _fat_ioc_access( 1, // descheduling593 0, // write594 _fat.fs_info_lba,595 (unsigned int)_fat.block_buffer,596 1 ) ) // one block597 {598 _printf("\n[FAT_ERROR] _update_fs_info(): cannot write block\n");599 return 1;600 }601 602 #if GIET_DEBUG_FAT603 if ( _get_proctime() > GIET_DEBUG_FAT )604 _printf("\n[DEBUG FAT] _update_fs_info(): nb_free = %x / first_free = %x\n",605 _fat.free_clusters_number , _fat.first_free_cluster );606 #endif607 608 return 0;609 } // end _update_fs_info()610 611 567 612 568 ///////////////////////////////////////////////////////////////// … … 739 695 740 696 /////////////////////////////////////////////////////////////////// 741 static unsigned int _allocate_one_cluster( unsigned int* cluster ) 742 { 743 unsigned int nb_free = _fat.free_clusters_number; 744 unsigned int free = _fat.first_free_cluster; 745 697 static unsigned int _get_free_cluster( unsigned int* cluster ) 698 { 746 699 // scan FAT to get next free cluster index 747 unsigned int current = free; 748 unsigned int found = 0; 700 unsigned int current = _fat.free_cluster_hint; 749 701 unsigned int max = (_fat.data_sectors >> 3); 750 702 unsigned int value; 751 do 752 { 703 while ( current < max ) 704 { 705 // get FAT entry indexed by current 706 if ( _get_fat_entry( current , &value ) ) return 1; 707 708 // return if free 709 if ( value == FREE_CLUSTER ) 710 { 711 *cluster = current; 712 return 0; 713 } 714 753 715 // increment current 754 716 current++; 755 756 // get FAT entry indexed by current 757 if ( _get_fat_entry( current , &value ) ) return 1; 758 759 // test if free 760 if ( value == FREE_CLUSTER ) found = 1; 761 } 762 while ( (current < max) && (found == 0) ); 717 } 763 718 764 // check found 765 if ( found == 0 ) 766 { 767 _printf("\n[FAT_ERROR] _allocate_one_cluster(): unconsistent FAT state"); 768 return 1; 769 } 770 771 // update allocated FAT slot 772 if ( _set_fat_entry( free , END_OF_CHAIN_CLUSTER_MAX ) ) return 1; 773 774 // update FAT descriptor global variables 775 _fat.free_clusters_number = nb_free - 1; 776 _fat.first_free_cluster = current; 777 778 #if GIET_DEBUG_FAT 779 if ( _get_proctime() > GIET_DEBUG_FAT ) 780 _printf("\n[DEBUG FAT] _allocate_one_cluster(): allocated cluster = %x / first_free = %x\n", 781 free , current ); 782 #endif 783 784 // returns free cluster index 785 *cluster = free; 786 return 0; 787 788 } // end _allocate_one_cluster() 719 // return error if not found 720 return 1; 721 722 } // end _get_free_cluster() 789 723 790 724 … … 896 830 897 831 898 //////////////////////////////////////////////////////////// 899 static unsigned int _ cluster_allocate( fat_inode_t* inode,900 unsigned int* cluster )832 //////////////////////////////////////////////////////////////// 833 static unsigned int _one_cluster_allocate( fat_inode_t* inode, 834 unsigned int* cluster ) 901 835 { 902 836 // Check free cluster available 903 837 if ( _fat.free_clusters_number == 0 ) 904 838 { 905 _printf("\n[FAT ERROR] in _ cluster_allocate(): no more free clusters\n");839 _printf("\n[FAT ERROR] in _one_cluster_allocate(): no more free clusters\n"); 906 840 return 1; 907 841 } 908 842 909 // compute number of already allocated clusters 910 // and last allocated cluster index 843 // scan the Fat-Cache to get last allocated cluster index 911 844 unsigned int nb_current_clusters = 0; 912 845 unsigned int current = inode->cluster; … … 914 847 unsigned int next = 0; 915 848 unsigned int new = 0; 916 917 849 while ( current < END_OF_CHAIN_CLUSTER_MIN ) 918 850 { 919 851 // get next cluster 920 if ( _get_fat_entry( current , &next ) ) return 1; 852 if ( _get_fat_entry( current , &next ) ) 853 { 854 _printf("\n[FAT ERROR] in _one_cluster_allocate() scanning FAT\n"); 855 return 1; 856 } 921 857 922 858 // increment number of allocated clusters … … 929 865 930 866 // allocate one free cluster from FAT 931 if ( _allocate_one_cluster( &new ) ) return 1; 867 if ( _get_free_cluster( &new ) ) 868 { 869 _printf("\n[FAT ERROR] in _one_cluster_allocate() : no more free clusters\n"); 870 return 1; 871 } 932 872 933 873 // allocate one 4K buffer to File-Cache … … 936 876 new ); 937 877 878 // update allocated FAT slot 879 if ( _set_fat_entry( new , END_OF_CHAIN_CLUSTER_MAX ) ) 880 { 881 _printf("\n[FAT ERROR] in _one_cluster_allocate() accessing FAT\n"); 882 return 1; 883 } 884 885 // update FAT descriptor global variables 886 _fat.free_clusters_number--; 887 _fat.free_cluster_hint = new; 888 938 889 if ( nb_current_clusters == 0 ) // first cluster : inode and directory entry 939 890 { … … 946 897 else // update previous last cluster in FAT 947 898 { 948 if ( _set_fat_entry( last , new ) ) return 1; 899 if ( _set_fat_entry( last , new ) ) 900 { 901 _printf("\n[FAT ERROR] in _one_cluster_allocate() accessing FAT\n"); 902 return 1; 903 } 949 904 } 950 905 … … 952 907 if ( _update_device_from_cache( _fat.fat_cache_levels, 953 908 _fat.fat_cache_root, 954 "FAT" ) ) return 1; 909 "FAT" ) ) 910 { 911 _printf("\n[FAT ERROR] in _one_cluster_allocate() updating FAT on device\n"); 912 return 1; 913 } 955 914 956 915 // 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" 916 if ( _update_fs_info() ) 917 { 918 _printf("\n[FAT ERROR] in _one_cluster_allocate() updating FS-INFO sector on device\n"); 919 return 1; 920 } 921 922 #if GIET_DEBUG_FAT 923 if ( _get_proctime() > GIET_DEBUG_FAT ) 924 _printf("\n[DEBUG FAT] _one_cluster_allocate(): for <%s>\n" 962 925 " nb_clusters = %d / last_cluster = %x / new_cluster = %x\n", 963 926 inode->name , nb_current_clusters , last , new ); … … 966 929 // returns allocated cluster index 967 930 *cluster = new; 968 969 931 return 0; 970 } // end _cluster_allocate() 971 972 973 974 /////////////////////////////////////////////////////////// 975 static unsigned int _clusters_release( fat_inode_t* inode ) 976 { 977 // scan the FAT 978 unsigned int current = inode->cluster; 979 unsigned int next; 980 do 981 { 982 // get next_cluster index 983 if ( _get_fat_entry( current , &next ) ) return 1; 984 985 // release current_cluster 986 if ( _set_fat_entry( current , FREE_CLUSTER ) ) return 1; 987 988 // update first_free_cluster and free_clusters_number in FAT descriptor 989 _fat.free_clusters_number = _fat.free_clusters_number + 1; 990 if ( _fat.first_free_cluster > current ) _fat.first_free_cluster = current; 991 992 // update loop variable 993 current = next; 994 } 995 while ( next < END_OF_CHAIN_CLUSTER_MIN ); 996 997 // update the FAT on block device 932 933 } // end _one_cluster_allocate() 934 935 //////////////////////////////////////////////////////////// 936 static unsigned int _cluster_release( unsigned int cluster ) 937 { 938 if ( cluster >= END_OF_CHAIN_CLUSTER_MIN ) // terminal case : nothing to do 939 { 940 return 0; 941 } 942 else // non terminal case : recursive call, then release cluster 943 { 944 // get next cluster 945 unsigned int next; 946 if ( _get_fat_entry( cluster , &next ) ) 947 { 948 _printf("\n[FAT ERROR] in _cluster_release() accessing Fat-Cache" 949 " for cluster %x\n", cluster ); 950 return 1; 951 } 952 953 // call _cluster_release() on next 954 if ( _cluster_release( next ) ) return 1; 955 956 // release current cluster 957 if ( _set_fat_entry( cluster , FREE_CLUSTER ) ) 958 { 959 _printf("\n[FAT ERROR] in _cluster_release() updating Fat-Cache" 960 " for cluster %x\n", cluster ); 961 return 1; 962 } 963 964 // update free_cluster _hint and free_clusters_number in FAT descriptor 965 _fat.free_clusters_number++; 966 if ( cluster < _fat.free_cluster_hint ) _fat.free_cluster_hint = cluster; 967 968 return 0; 969 } 970 } // end _cluster_release() 971 972 /////////////////////////////////////////////////////////////// 973 static unsigned int _all_clusters_release( fat_inode_t* inode ) 974 { 975 // release recursively all clusters in FAT chaining, 976 // starting from last cluster in chain, ending by first. 977 if ( _cluster_release( inode->cluster ) ) 978 { 979 _printf("\n[FAT ERROR] in _all_clusters_release() releasing clusters\n"); 980 return 1; 981 } 982 983 // update FAT on device 998 984 if ( _update_device_from_cache( _fat.fat_cache_levels, 999 985 _fat.fat_cache_root, 1000 "FAT" ) ) return 1; 986 "FAT" ) ) 987 { 988 _printf("\n[FAT ERROR] in _all_clusters_release() updating FAT on device\n"); 989 return 1; 990 } 1001 991 1002 992 // 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 ); 993 if ( _update_fs_info() ) 994 { 995 _printf("\n[FAT ERROR] in _all_clusters_release() updating FS_INFO sector on device\n"); 996 return 1; 997 } 998 999 #if GIET_DEBUG_FAT 1000 if ( _get_proctime() > GIET_DEBUG_FAT ) 1001 _printf("\n[DEBUG FAT] _all_clusters_release() done for file <%s>\n", inode->name ); 1008 1002 #endif 1009 1003 1010 1004 return 0; 1011 } // end _ clusters_release()1005 } // end _all_clusters_release() 1012 1006 1013 1007 … … 1931 1925 1932 1926 // release clusters allocated to file/dir in DATA region 1933 if ( _ clusters_release( inode ) ) return 1;1927 if ( _all_clusters_release( inode ) ) return 1; 1934 1928 1935 1929 // release File-Cache … … 2166 2160 unsigned int _set_fs_info() 2167 2161 { 2168 2169 #if GIET_DEBUG_FAT2170 if ( _get_proctime() > GIET_DEBUG_FAT )2171 _printf("\n[DEBUG FAT] _set_fs_info(): enters at cycle %d\n", _get_proctime() );2172 #endif2173 2174 2162 // load FS_INFO sector into FAT buffer 2175 2163 if ( _fat_ioc_access( 0, // no descheduling … … 2182 2170 return 1; 2183 2171 } 2184 2185 2172 _fat.block_buffer_lba = _fat.fs_info_lba; 2186 2173 2187 #if GIET_DEBUG_FAT2188 if ( _get_proctime() > GIET_DEBUG_FAT )2189 _printf("\n[DEBUG FAT] _set_fs_info(): FS-INFO sector loaded\n");2190 #endif2191 2192 2174 // get general info from FAT descriptor 2193 unsigned int fat_blocks = _fat.fat_sectors;2194 2175 unsigned int data_blocks = _fat.data_sectors; 2195 unsigned int lba = _fat.fat_lba;2196 unsigned int* buf = (unsigned int*)_fat.block_buffer;2197 2176 2198 2177 // initialise <free_clusters_number> from FS-INFO sector … … 2208 2187 _fat.free_clusters_number = free_clusters; 2209 2188 2210 // scan FAT on device from FS-FREE_CLUSTER_HINT to initialise <first_free_cluster>2189 // initialise <free_cluster_hint> from FS_INFO sector 2211 2190 unsigned int free_cluster_hint = _read_entry( FS_FREE_CLUSTER_HINT, _fat.block_buffer, 1); 2212 2191 if ( free_cluster_hint > (data_blocks>>3) ) … … 2218 2197 } 2219 2198 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); 2199 _fat.free_cluster_hint = free_cluster_hint; 2200 2201 #if GIET_DEBUG_FAT 2202 if ( _get_proctime() > GIET_DEBUG_FAT ) 2203 _printf("\n[DEBUG FAT] _set_fs_info() : free_clusters = %x / free_cluster_hint = %x\n", 2204 free_clusters , free_cluster_hint ); 2205 #endif 2206 2207 return 0; 2208 2209 } // end _set_fs_info() 2210 2211 2212 2213 2214 ///////////////////////////////////// 2215 static unsigned int _update_fs_info() 2216 { 2217 // load buffer if miss 2218 if ( _fat.fs_info_lba != _fat.block_buffer_lba ) 2219 { 2220 if ( _fat_ioc_access( 1, // descheduling 2221 1, // read 2222 _fat.fs_info_lba, 2223 (unsigned int)_fat.block_buffer, 2224 1 ) ) // one block 2225 { 2226 _printf("\n[FAT_ERROR] _update_fs_info(): cannot read block\n"); 2237 2227 return 1; 2238 2228 } 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 ) 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"); 2229 _fat.block_buffer_lba = _fat.fs_info_lba; 2230 } 2231 2232 // update buffer 2233 unsigned int* ptr; 2234 2235 ptr = (unsigned int*)(_fat.block_buffer + get_offset(FS_FREE_CLUSTERS) ); 2236 *ptr = _fat.free_clusters_number; 2237 2238 ptr = (unsigned int*)(_fat.block_buffer + get_offset(FS_FREE_CLUSTER_HINT) ); 2239 *ptr = _fat.free_cluster_hint; 2240 2241 // write bloc to FAT 2242 if ( _fat_ioc_access( 1, // descheduling 2243 0, // write 2244 _fat.fs_info_lba, 2245 (unsigned int)_fat.block_buffer, 2246 1 ) ) // one block 2247 { 2248 _printf("\n[FAT_ERROR] _update_fs_info(): cannot write block\n"); 2261 2249 return 1; 2262 2250 } 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() 2251 2252 #if GIET_DEBUG_FAT 2253 if ( _get_proctime() > GIET_DEBUG_FAT ) 2254 _printf("\n[DEBUG FAT] _update_fs_info() : free_clusters = %x / free_cluster_hint = %x\n", 2255 _fat.free_clusters_number , _fat.free_cluster_hint ); 2256 #endif 2257 2258 return 0; 2259 } // end _update_fs_info() 2260 2276 2261 2277 2262 … … 2658 2643 2659 2644 // release clusters allocated to file/dir in DATA region 2660 if ( _ clusters_release( child ) )2645 if ( _all_clusters_release( child ) ) 2661 2646 { 2662 2647 _spin_lock_release( &_fat.fat_lock ); … … 3117 3102 for ( cid = 0 ; cid < (new_clusters - old_clusters) ; cid++ ) 3118 3103 { 3119 if ( _ cluster_allocate( inode , &index ) )3104 if ( _one_cluster_allocate( inode , &index ) ) 3120 3105 { 3121 3106 _spin_lock_release( &_fat.fat_lock ); … … 3809 3794 _get_last_name( pathname , name ); 3810 3795 3811 // allocate one cluster from FAT for the new directory3812 unsigned int cluster;3813 if ( _allocate_one_cluster( &cluster ) )3814 {3815 _spin_lock_release( &_fat.fat_lock );3816 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT );3817 3818 _printf("\n[FAT ERROR] _fat_mkdir(): no free cluster"3819 " for directory <%s>\n" , pathname );3820 return GIET_FAT32_NO_FREE_SPACE;3821 }3822 3823 3796 // allocate a new inode and an empty Cache-File 3824 3797 child = _allocate_one_inode( name, 3825 3798 1, // it's a directory 3826 cluster,3799 0xFFFFFFFF, // cluster index not defined yet 3827 3800 0, // size = 0 for a directory 3828 3801 0, // count … … 3833 3806 _add_inode_in_tree( child , parent ); 3834 3807 3808 // allocate cluster from FAT 3809 unsigned int cluster; 3810 if ( _one_cluster_allocate( inode , &cluster ) ) 3811 { 3812 _spin_lock_release( &_fat.fat_lock ); 3813 _atomic_and( &psched->context[ltid].slot[CTX_LOCKS_ID] , ~LOCKS_MASK_FAT ); 3814 3815 _printf("\n[FAT ERROR] _fat_mkdir(): no free cluster" 3816 " for directory <%s>\n" , pathname ); 3817 return GIET_FAT32_NO_FREE_SPACE; 3818 } 3819 3820 // update cluster index in inode 3821 child->cluster = cluster; 3822 3835 3823 // allocate and initialise one 4 Kbytes buffer and associated descriptor 3836 3824 _allocate_one_buffer( child, … … 4283 4271 unsigned int cid; 4284 4272 unsigned int lba; 4285 unsigned int cluster_allocated;4273 unsigned int one_cluster_allocated; 4286 4274 4287 4275 // File-Cache miss handling: … … 4302 4290 (unsigned int)inode->cache->children[cluster_id] ); 4303 4291 #endif 4304 // compute cluster_allocated condition, depending on file / dir type4305 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 buffer4292 // compute one_cluster_allocated condition, depending on file / dir type 4293 if ( is_dir ) one_cluster_allocated = ( cluster_id < is_dir ); 4294 else one_cluster_allocated = ( (cluster_id<<12) < size ); 4295 4296 if ( one_cluster_allocated ) // cluster already allocated => allocate buffer 4309 4297 { 4310 4298 // scan the FAT to find the cluster index for cluster_id … … 4363 4351 { 4364 4352 // allocate one cluster on device 4365 if ( _ cluster_allocate( inode , ¤t ) )4353 if ( _one_cluster_allocate( inode , ¤t ) ) 4366 4354 { 4367 4355 _printf("\n[FAT ERROR] in _get_file_cache_buffer() : " -
soft/giet_vm/giet_fat32/fat32.h
r773 r783 210 210 unsigned int data_sectors; // number of sectors inf DATA region 211 211 unsigned int fs_info_lba; // lba of fs_info 212 unsigned int f irst_free_cluster; // free cluster with smallest index212 unsigned int free_cluster_hint; // start point to search free cluster 213 213 unsigned int free_clusters_number; // total number of free clusters 214 214 } fat_desc_t;
Note: See TracChangeset
for help on using the changeset viewer.