src/kernel/fs/fat32.c
/**
 * @note read or write a file.
 * @warning must hold writing lock when write and read lock when reading.
 *          don`t hold parent entry`s lock.
 * @param entry
 * @param buffer
 * @param offset
 * @param length
 * @param write
 */
@note read or write a file.
@warning must hold writing lock when write and read lock when reading.
don`t hold parent entry`s lock.
@note read or write a file . @warning must hold writing lock when write and read lock when reading . don ` t hold parent entry ` s lock .
bool entry_rw(entry_t * entry,void * buffer,uint32_t offset, uint32_t length,bool write){
    ASSERT(entry!=NULL);
    if(entry->first_clus_no == 0){
        entry->first_clus_no = _clus_alloc();
    }
    uint32_t file_size;
    file_size = entry->file_size;
    uint32_t clus_cnt = file_size/fat32.byts_per_clus;
    if(file_size%fat32.byts_per_clus!=0){
        clus_cnt++;
    }
    uint32_t allocated_size = clus_cnt * fat32.byts_per_clus;
    uint32_t file_now_size = offset + length;
    if(file_now_size > allocated_size){
        if(write){
            uint32_t alloc_clus_cnt = (file_now_size - allocated_size)/fat32.byts_per_clus;
            if((file_now_size - allocated_size)%fat32.byts_per_clus!=0){
                alloc_clus_cnt++;
            }
            uint32_t probe_clus = entry->first_clus_no;
            for(;_fat_read(probe_clus)!= FAT32_FILE_END;probe_clus = _fat_read(probe_clus));
            for(;alloc_clus_cnt>0;alloc_clus_cnt--){
                uint32_t next = _clus_alloc();
                _fat_write(probe_clus, next);
                probe_clus = next;
            }
        }
        else{
            return false;
        }
    }
    if(file_now_size>entry->file_size){
        entry->file_size = file_now_size;
    }
    return _multi_clus_rw(entry->first_clus_no,buffer,offset,length,write);
}
bool entry_rw ( entry_t * entry , void * buffer , uint32_t offset , uint32_t length , bool write ) { ASSERT ( entry != NULL ) ; if ( entry -> first_clus_no == 0 ) { entry -> first_clus_no = _clus_alloc ( ) ; } uint32_t file_size ; file_size = entry -> file_size ; uint32_t clus_cnt = file_size / fat32 . byts_per_clus ; if ( file_size % fat32 . byts_per_clus != 0 ) { clus_cnt ++ ; } uint32_t allocated_size = clus_cnt * fat32 . byts_per_clus ; uint32_t file_now_size = offset + length ; if ( file_now_size > allocated_size ) { if ( write ) { uint32_t alloc_clus_cnt = ( file_now_size - allocated_size ) / fat32 . byts_per_clus ; if ( ( file_now_size - allocated_size ) % fat32 . byts_per_clus != 0 ) { alloc_clus_cnt ++ ; } uint32_t probe_clus = entry -> first_clus_no ; for ( ; _fat_read ( probe_clus ) != FAT32_FILE_END ; probe_clus = _fat_read ( probe_clus ) ) ; for ( ; alloc_clus_cnt > 0 ; alloc_clus_cnt -- ) { uint32_t next = _clus_alloc ( ) ; _fat_write ( probe_clus , next ) ; probe_clus = next ; } } else { return false ; } } if ( file_now_size > entry -> file_size ) { entry -> file_size = file_now_size ; } return _multi_clus_rw ( entry -> first_clus_no , buffer , offset , length , write ) ; }
@note read or write a file.
@note read or write a file .
// this is a new create file with no cluster allocating. // alloc one //    if(entry->attr==ENTRY_ATTR_ARCHIVE){ //    } //    else{ //        file_size = _get_dir_file_size(entry); //    } // alloc more cluster // find file end // if read out of the file size // do read or write