grub2: bring back build of aros-side grub2 tools
[AROS.git] / tools / adflib / adf_bitm.c
blobdba598bc2eb50017026e068c51ba8d910bda431d
1 /*
2 * ADF Library. (C) 1997-1999 Laurent Clevy
4 * adf_bitm.c
6 * bitmap code
7 */
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <string.h>
13 #include"adf_raw.h"
14 #include"adf_bitm.h"
15 #include"adf_err.h"
16 #include"adf_disk.h"
17 #include"adf_util.h"
18 #include"defendian.h"
20 extern struct Env adfEnv;
23 * adfUpdateBitmap
26 RETCODE adfUpdateBitmap(struct Volume *vol)
28 int i;
29 struct bRootBlock root;
31 /*printf("adfUpdateBitmap\n");*/
33 if (adfReadRootBlock(vol, vol->rootBlock,&root)!=RC_OK)
34 return RC_ERROR;
36 root.bmFlag = BM_INVALID;
37 if (adfWriteRootBlock(vol,vol->rootBlock,&root)!=RC_OK)
38 return RC_ERROR;
40 for(i=0; i<vol->bitmapSize; i++)
41 if (vol->bitmapBlocksChg[i]) {
42 if (adfWriteBitmapBlock(vol, vol->bitmapBlocks[i], vol->bitmapTable[i])!=RC_OK)
43 return RC_ERROR;
44 vol->bitmapBlocksChg[i] = FALSE;
47 root.bmFlag = BM_VALID;
48 adfTime2AmigaTime(adfGiveCurrentTime(),&(root.days),&(root.mins),&(root.ticks));
49 if (adfWriteRootBlock(vol,vol->rootBlock,&root)!=RC_OK)
50 return RC_ERROR;
52 return RC_OK;
57 * adfCountFreeBlocks
60 ULONG adfCountFreeBlocks(struct Volume* vol)
62 ULONG freeBlocks;
63 int j;
65 freeBlocks = 0L;
66 for(j=vol->reservedBlocks; j<vol->totalBlocks; j++)
67 if ( adfIsBlockFree(vol,j) )
68 freeBlocks++;
70 return freeBlocks;
75 * adfReadBitmap
78 RETCODE adfReadBitmap(struct Volume* vol, struct bRootBlock* root)
80 ULONG nBlock;
81 ULONG mapSize;
82 SECTNUM nSect;
83 ULONG j, i;
84 struct bBitmapExtBlock bmExt;
86 nBlock = vol->totalBlocks - vol->reservedBlocks;
88 mapSize = nBlock / (127*32);
89 if ( (nBlock%(127*32))!=0 )
90 mapSize++;
91 vol->bitmapSize = mapSize;
92 vol->lastAlloc = vol->rootBlock;
94 vol->bitmapTable = (struct bBitmapBlock**) malloc(sizeof(struct bBitmapBlock*)*mapSize);
95 if (!vol->bitmapTable) {
96 (*adfEnv.eFct)("adfReadBitmap : malloc, vol->bitmapTable");
97 return RC_MALLOC;
99 vol->bitmapBlocks = (SECTNUM*) malloc(sizeof(SECTNUM)*mapSize);
100 if (!vol->bitmapBlocks) {
101 free(vol->bitmapTable);
102 (*adfEnv.eFct)("adfReadBitmap : malloc, vol->bitmapBlocks");
103 return RC_MALLOC;
105 vol->bitmapBlocksChg = (BOOL*) malloc(sizeof(BOOL)*mapSize);
106 if (!vol->bitmapBlocksChg) {
107 free(vol->bitmapTable); free(vol->bitmapBlocks);
108 (*adfEnv.eFct)("adfReadBitmap : malloc, vol->bitmapBlocks");
109 return RC_MALLOC;
111 for(i=0; i<mapSize; i++) {
112 vol->bitmapBlocksChg[i] = FALSE;
114 vol->bitmapTable[i] = (struct bBitmapBlock*)malloc(sizeof(struct bBitmapBlock));
115 if (!vol->bitmapTable[i]) {
116 free(vol->bitmapBlocksChg); free(vol->bitmapBlocks);
117 for(j=0; j<i; j++)
118 free(vol->bitmapTable[j]);
119 free(vol->bitmapTable);
120 (*adfEnv.eFct)("adfReadBitmap : malloc, vol->bitmapBlocks");
121 return RC_MALLOC;
125 j=0; i=0;
126 /* bitmap pointers in rootblock : 0 <= i <BM_SIZE */
127 while(i<BM_SIZE && root->bmPages[i]!=0) {
128 vol->bitmapBlocks[j] = nSect = root->bmPages[i];
129 if ( !isSectNumValid(vol,nSect) ) {
130 (*adfEnv.wFct)("adfReadBitmap : sector out of range");
133 if (adfReadBitmapBlock(vol, nSect, vol->bitmapTable[j])!=RC_OK) {
134 adfFreeBitmap(vol);
135 return RC_ERROR;
137 j++; i++;
139 nSect = root->bmExt;
140 while(nSect!=0) {
141 /* bitmap pointers in bitmapExtBlock, j <= mapSize */
142 if (adfReadBitmapExtBlock(vol, nSect, &bmExt)!=RC_OK) {
143 adfFreeBitmap(vol);
144 return RC_ERROR;
146 i=0;
147 while(i<127 && j<mapSize) {
148 nSect = bmExt.bmPages[i];
149 if ( !isSectNumValid(vol,nSect) )
150 (*adfEnv.wFct)("adfReadBitmap : sector out of range");
151 vol->bitmapBlocks[j] = nSect;
153 if (adfReadBitmapBlock(vol, nSect, vol->bitmapTable[j])!=RC_OK) {
154 adfFreeBitmap(vol);
155 return RC_ERROR;
157 i++; j++;
159 nSect = bmExt.nextBlock;
162 return RC_OK;
165 static inline ULONG sectorToMapMask(struct Volume *vol, SECTNUM nSect, ULONG **map, int *pblock)
167 int sectOfMap;
168 int block;
169 int indexInMap;
171 nSect -= vol->reservedBlocks;
172 sectOfMap = nSect & 0x1f;
173 nSect /= 32;
175 block = nSect / 127;
176 indexInMap = nSect % 127;
178 *map = &(vol->bitmapTable[ block ]->map[ indexInMap ]);
179 if (pblock)
180 *pblock = block;
182 return (1UL << (sectOfMap & 0x1f));
186 * adfIsBlockFree
189 BOOL adfIsBlockFree(struct Volume* vol, SECTNUM nSect)
191 ULONG mask, *map;
193 mask = sectorToMapMask(vol, nSect, &map, NULL);
195 // printf("C %08lx %c\n", (unsigned long)(vol->firstBlock + nSect) * 512, (*map & mask) ? '1' : '0');
197 return (*map & mask) ? 1 : 0;
202 * adfSetBlockFree OK
205 void adfSetBlockFree(struct Volume* vol, SECTNUM nSect)
207 ULONG mask, *map;
208 int block;
210 mask = sectorToMapMask(vol, nSect, &map, &block);
212 *map |= mask;
214 vol->bitmapBlocksChg[ block ] = TRUE;
216 // printf("F 0x%08lx\n", (unsigned long)(vol->firstBlock + nSect) * 512);
221 * adfSetBlockUsed
224 void adfSetBlockUsed(struct Volume* vol, SECTNUM nSect)
226 ULONG mask, *map;
227 int block;
229 mask = sectorToMapMask(vol, nSect, &map, &block);
231 *map &= ~mask;
233 vol->bitmapBlocksChg[ block ] = TRUE;
235 // printf("A 0x%08lx\n", (unsigned long)(vol->firstBlock + nSect) * 512);
240 * adfGet1FreeBlock
243 SECTNUM adfGet1FreeBlock(struct Volume *vol) {
244 SECTNUM block[1];
245 if (!adfGetFreeBlocks(vol,1,block))
246 return((SECTNUM)-1);
247 else
248 return(block[0]);
252 * adfGetFreeBlocks
255 BOOL adfGetFreeBlocks(struct Volume* vol, int nbSect, SECTNUM* sectList)
257 int i;
258 ULONG block = vol->lastAlloc;
260 if (nbSect == 0)
261 return TRUE;
263 i = 0;
264 while( i<nbSect ) {
265 if ( adfIsBlockFree(vol, block) ) {
266 sectList[i] = block;
267 i++;
270 block++;
271 if (block == vol->lastAlloc)
272 return FALSE;
274 if (block == vol->totalBlocks)
275 block = vol->reservedBlocks;
278 for(i=0; i<nbSect; i++)
279 adfSetBlockUsed( vol, sectList[i] );
281 vol->lastAlloc = sectList[i-1];
283 return TRUE;
288 * adfCreateBitmap
290 * create bitmap structure in vol
292 RETCODE adfCreateBitmap(struct Volume *vol)
294 ULONG nBlock, mapSize ;
295 int i, j;
297 nBlock = vol->totalBlocks - vol->reservedBlocks;
299 mapSize = nBlock / (127*32);
300 if ( (nBlock%(127*32))!=0 )
301 mapSize++;
302 vol->bitmapSize = mapSize;
303 vol->lastAlloc = vol->rootBlock;
305 vol->bitmapTable = (struct bBitmapBlock**)malloc( sizeof(struct bBitmapBlock*)*mapSize );
306 if (!vol->bitmapTable) {
307 (*adfEnv.eFct)("adfCreateBitmap : malloc, vol->bitmapTable");
308 return RC_MALLOC;
311 vol->bitmapBlocksChg = (BOOL*) malloc(sizeof(BOOL)*mapSize);
312 if (!vol->bitmapBlocksChg) {
313 free(vol->bitmapTable);
314 (*adfEnv.eFct)("adfCreateBitmap : malloc, vol->bitmapBlocksChg");
315 return RC_MALLOC;
318 vol->bitmapBlocks = (SECTNUM*) malloc(sizeof(SECTNUM)*mapSize);
319 if (!vol->bitmapBlocks) {
320 free(vol->bitmapTable); free(vol->bitmapBlocksChg);
321 (*adfEnv.eFct)("adfCreateBitmap : malloc, vol->bitmapBlocks");
322 return RC_MALLOC;
325 for(i=0; i<mapSize; i++) {
326 vol->bitmapTable[i] = (struct bBitmapBlock*)malloc(sizeof(struct bBitmapBlock));
327 if (!vol->bitmapTable[i]) {
328 free(vol->bitmapTable); free(vol->bitmapBlocksChg);
329 for(j=0; j<i; j++)
330 free(vol->bitmapTable[j]);
331 free(vol->bitmapTable);
332 (*adfEnv.eFct)("adfCreateBitmap : malloc");
333 return RC_MALLOC;
337 for(i=vol->reservedBlocks; i < nBlock; i++)
338 adfSetBlockFree(vol, i);
340 adfSetBlockUsed(vol, vol->rootBlock);
342 return RC_OK;
347 * adfWriteNewBitmap
349 * write ext blocks and bitmap
351 * uses vol->bitmapSize,
353 RETCODE adfWriteNewBitmap(struct Volume *vol)
355 struct bBitmapExtBlock bitme;
356 SECTNUM *bitExtBlock;
357 int n, i, k;
358 int nExtBlock;
359 int nBlock;
360 SECTNUM *sectList;
361 struct bRootBlock root;
363 sectList=(SECTNUM*)malloc(sizeof(SECTNUM)*vol->bitmapSize);
364 if (!sectList) {
365 (*adfEnv.eFct)("adfCreateBitmap : sectList");
366 return RC_MALLOC;
369 /* Write out the in-root bitmap blocks */
370 if (adfReadRootBlock(vol, vol->rootBlock, &root)!=RC_OK) {
371 free(sectList);
372 return RC_ERROR;
375 n = min( vol->bitmapSize, BM_SIZE );
376 if (!adfGetFreeBlocks(vol, n, &sectList[0])) {
377 free(sectList);
378 return RC_ERROR;
381 for(i=0; i<n; i++) {
382 root.bmPages[i] = vol->bitmapBlocks[i] = sectList[i];
384 nBlock = n;
386 /* for devices with more than 25*127 blocks == hards disks */
387 if (vol->bitmapSize>BM_SIZE) {
388 nExtBlock = ((vol->bitmapSize-BM_SIZE)+126)/127;
390 bitExtBlock=(SECTNUM*)malloc(sizeof(SECTNUM)*nExtBlock);
391 if (!bitExtBlock) {
392 free(sectList);
393 adfEnv.eFct("adfWriteNewBitmap : malloc failed");
394 return RC_MALLOC;
397 if (!adfGetFreeBlocks(vol, nExtBlock, bitExtBlock)) {
398 adfEnv.eFct("adfWriteNewBitmap : can't get free Ext blocks");
399 free(sectList); free(bitExtBlock);
400 return RC_MALLOC;
403 if (!adfGetFreeBlocks(vol, vol->bitmapSize - n, &sectList[n])) {
404 free(sectList); free(bitExtBlock);
405 return RC_ERROR;
408 k = 0;
409 root.bmExt = bitExtBlock[ k ];
410 while( nBlock<vol->bitmapSize ) {
411 i=0;
412 memset(&bitme, 0, sizeof(bitme));
413 while( i<127 && nBlock<vol->bitmapSize ) {
414 bitme.bmPages[i] = vol->bitmapBlocks[nBlock] = sectList[nBlock];
415 i++;
416 nBlock++;
418 if ( k+1<nExtBlock )
419 bitme.nextBlock = bitExtBlock[ k+1 ];
420 else
421 bitme.nextBlock = 0;
422 if (adfWriteBitmapExtBlock(vol, bitExtBlock[ k ], &bitme)!=RC_OK) {
423 free(sectList); free(bitExtBlock);
424 return RC_ERROR;
426 k++;
428 free( bitExtBlock );
431 free( sectList);
433 if (adfWriteRootBlock(vol,vol->rootBlock,&root)!=RC_OK)
434 return RC_ERROR;
436 return RC_OK;
440 * adfReadBitmapBlock
442 * ENDIAN DEPENDENT
444 RETCODE
445 adfReadBitmapBlock(struct Volume* vol, SECTNUM nSect, struct bBitmapBlock* bitm)
447 unsigned char buf[LOGICAL_BLOCK_SIZE];
449 //printf("bitmap %ld\n",nSect);
450 if (adfReadBlock(vol, nSect, buf)!=RC_OK)
451 return RC_ERROR;
453 memcpy(bitm, buf, LOGICAL_BLOCK_SIZE);
454 #ifdef LITT_ENDIAN
455 /* big to little = 68000 to x86 */
456 swapEndian((unsigned char*)bitm, SWBL_BITMAP);
457 #endif
459 if (bitm->checkSum!=adfNormalSum(buf,0,LOGICAL_BLOCK_SIZE))
460 (*adfEnv.wFct)("adfReadBitmapBlock : invalid checksum");
462 return RC_OK;
467 * adfWriteBitmapBlock
469 * OK
471 RETCODE
472 adfWriteBitmapBlock(struct Volume* vol, SECTNUM nSect, struct bBitmapBlock* bitm)
474 unsigned char buf[LOGICAL_BLOCK_SIZE];
475 ULONG newSum;
477 memcpy(buf,bitm,LOGICAL_BLOCK_SIZE);
478 #ifdef LITT_ENDIAN
479 /* little to big */
480 swapEndian(buf, SWBL_BITMAP);
481 #endif
483 newSum = adfNormalSum(buf, 0, LOGICAL_BLOCK_SIZE);
484 swLong(buf,newSum);
486 /* dumpBlock((unsigned char*)buf);*/
487 if (adfWriteBlock(vol, nSect, (unsigned char*)buf)!=RC_OK)
488 return RC_ERROR;
490 return RC_OK;
495 * adfReadBitmapExtBlock
497 * ENDIAN DEPENDENT
499 RETCODE
500 adfReadBitmapExtBlock(struct Volume* vol, SECTNUM nSect, struct bBitmapExtBlock* bitme)
502 unsigned char buf[LOGICAL_BLOCK_SIZE];
504 if (adfReadBlock(vol, nSect, buf)!=RC_OK)
505 return RC_ERROR;
507 memcpy(bitme, buf, LOGICAL_BLOCK_SIZE);
508 #ifdef LITT_ENDIAN
509 swapEndian((unsigned char*)bitme, SWBL_BITMAP);
510 #endif
512 return RC_OK;
517 * adfWriteBitmapExtBlock
520 RETCODE
521 adfWriteBitmapExtBlock(struct Volume* vol, SECTNUM nSect, struct bBitmapExtBlock* bitme)
523 unsigned char buf[LOGICAL_BLOCK_SIZE];
525 memcpy(buf,bitme, LOGICAL_BLOCK_SIZE);
526 #ifdef LITT_ENDIAN
527 /* little to big */
528 swapEndian(buf, SWBL_BITMAPE);
529 #endif
531 /* dumpBlock((unsigned char*)buf);*/
532 if (adfWriteBlock(vol, nSect, (unsigned char*)buf)!=RC_OK)
533 return RC_ERROR;
535 return RC_OK;
540 * adfFreeBitmap
543 void adfFreeBitmap(struct Volume* vol)
545 int i;
547 for(i=0; i<vol->bitmapSize; i++)
548 free(vol->bitmapTable[i]);
549 vol->bitmapSize = 0;
551 free(vol->bitmapTable);
552 vol->bitmapTable = 0;
554 free(vol->bitmapBlocks);
555 vol->bitmapBlocks = 0;
557 free(vol->bitmapBlocksChg);
558 vol->bitmapBlocksChg = 0;
562 /*#######################################################################################*/