static unsigned int _countBlocks(Fs_t *This, unsigned int block) { unsigned int blocks; unsigned int rel, oldabs, oldrel; blocks = 0; oldabs = oldrel = rel = 0; while (block <= This->last_fat && block != 1 && block) { blocks++; block = fatDecode(This, block); rel++; if(_loopDetect(&oldrel, rel, &oldabs, block) < 0) block = -1; } return blocks; }
int fat_free(Stream_t *Dir, unsigned int fat) { Stream_t *Stream = GetFs(Dir); DeclareThis(Fs_t); unsigned int next_no_step; /* a zero length file? */ if (fat == 0) return(0); /* CONSTCOND */ while (!This->fat_error) { /* get next cluster number */ next_no_step = fatDecode(This,fat); /* mark current cluster as empty */ fatDeallocate(This,fat); if (next_no_step >= This->last_fat) break; fat = next_no_step; } return(0); }
void printFat(Stream_t *Stream) { File_t *This = getUnbufferedFile(Stream); unsigned long n; int rel; unsigned long begin, end; int first; n = This->FirstAbsCluNr; if(!n) { printf("Root directory or empty file\n"); return; } rel = 0; first = 1; begin = end = 0; do { if (first || n != end+1) { if (!first) { if (begin != end) printf("-%lu", end); printf("> "); } begin = end = n; printf("<%lu", begin); } else { end++; } first = 0; n = fatDecode(This->Fs, n); rel++; if(loopDetect(This, rel, n) < 0) n = 1; } while (n <= This->Fs->last_fat && n != 1); if(!first) { if (begin != end) printf("-%lu", end); printf(">"); } }
static int normal_map(File_t *This, off_t where, size_t *len, int mode, mt_off_t *res) { int offset; off_t end; int NrClu; /* number of clusters to read */ unsigned int RelCluNr; unsigned int CurCluNr; unsigned int NewCluNr; unsigned int AbsCluNr; int clus_size; Fs_t *Fs = This->Fs; *res = 0; clus_size = Fs->cluster_size * Fs->sector_size; offset = where % clus_size; if (mode == MT_READ) maximize(*len, This->FileSize - where); if (*len == 0 ) return 0; if (This->FirstAbsCluNr < 2){ if( mode == MT_READ || *len == 0){ *len = 0; return 0; } NewCluNr = get_next_free_cluster(This->Fs, 1); if (NewCluNr == 1 ){ errno = ENOSPC; return -2; } hash_remove(filehash, (void *) This, This->hint); This->FirstAbsCluNr = NewCluNr; hash_add(filehash, (void *) This, &This->hint); fatAllocate(This->Fs, NewCluNr, Fs->end_fat); } RelCluNr = where / clus_size; if (RelCluNr >= This->PreviousRelCluNr){ CurCluNr = This->PreviousRelCluNr; AbsCluNr = This->PreviousAbsCluNr; } else { CurCluNr = 0; AbsCluNr = This->FirstAbsCluNr; } NrClu = (offset + *len - 1) / clus_size; while (CurCluNr <= RelCluNr + NrClu){ if (CurCluNr == RelCluNr){ /* we have reached the beginning of our zone. Save * coordinates */ This->PreviousRelCluNr = RelCluNr; This->PreviousAbsCluNr = AbsCluNr; } NewCluNr = fatDecode(This->Fs, AbsCluNr); if (NewCluNr == 1 || NewCluNr == 0){ fprintf(stderr,"Fat problem while decoding %d %x\n", AbsCluNr, NewCluNr); exit(1); } if(CurCluNr == RelCluNr + NrClu) break; if (NewCluNr > Fs->last_fat && mode == MT_WRITE){ /* if at end, and writing, extend it */ NewCluNr = get_next_free_cluster(This->Fs, AbsCluNr); if (NewCluNr == 1 ){ /* no more space */ errno = ENOSPC; return -2; } fatAppend(This->Fs, AbsCluNr, NewCluNr); } if (CurCluNr < RelCluNr && NewCluNr > Fs->last_fat){ *len = 0; return 0; } if (CurCluNr >= RelCluNr && NewCluNr != AbsCluNr + 1) break; CurCluNr++; AbsCluNr = NewCluNr; if(loopDetect(This, CurCluNr, AbsCluNr)) { errno = EIO; return -2; } } maximize(*len, (1 + CurCluNr - RelCluNr) * clus_size - offset); end = where + *len; if(batchmode && mode == MT_WRITE && end >= This->FileSize) { *len += ROUND_UP(end, clus_size) - end; } if((*len + offset) / clus_size + This->PreviousAbsCluNr-2 > Fs->num_clus) { fprintf(stderr, "cluster too big\n"); exit(1); } *res = sectorsToBytes((Stream_t*)Fs, (This->PreviousAbsCluNr-2) * Fs->cluster_size + Fs->clus_start) + offset; return 1; }