2 * Copyright 2001-2008, pinc Software. All Rights Reserved.
3 * Released under the terms of the MIT license.
6 //! handles the BFS block bitmap
18 Bitmap::Bitmap(Disk
*disk
)
47 Bitmap::SetTo(Disk
*disk
)
52 fSize
= divide_roundup(disk
->NumBlocks(),disk
->BlockSize() * 8);
53 fByteSize
= disk
->BlockSize() * disk
->SuperBlock()->num_ags
54 * disk
->SuperBlock()->blocks_per_ag
;
56 fBitmap
= (uint32
*)malloc(fByteSize
);
60 fBackupBitmap
= (uint32
*)malloc(fByteSize
);
61 if (fBackupBitmap
== NULL
)
64 memset(fBackupBitmap
, 0, fByteSize
);
66 // set root block, block bitmap, log as used
67 off_t end
= disk
->ToBlock(disk
->Log()) + disk
->Log().length
;
68 for (off_t block
= 0; block
< end
; block
++) {
69 if (!BackupSetAt(block
, true))
74 if ((size
= disk
->ReadAt(disk
->BlockSize(), fBitmap
, fByteSize
)) < B_OK
) {
83 // calculate used blocks
86 for (uint32 i
= fByteSize
>> 2;i
-- > 0;) {
88 for (int16 j
= 0;j
< 32;j
++,compare
<<= 1) {
89 if (compare
& fBitmap
[i
])
101 return fBitmap
? B_OK
: B_ERROR
;
106 Bitmap::FreeBlocks() const
111 return fDisk
->NumBlocks() - fUsedBlocks
;
116 Bitmap::UsedAt(off_t block
) const
118 uint32 index
= block
/ 32; // 32bit resolution, (beginning with block 1?)
119 if (index
> fByteSize
/ 4)
122 return fBitmap
[index
] & (1L << (block
& 0x1f));
127 Bitmap::BackupUsedAt(off_t block
) const
129 uint32 index
= block
/ 32; // 32bit resolution, (beginning with block 1?)
130 if (index
> fByteSize
/ 4)
133 return fBackupBitmap
[index
] & (1L << (block
& 0x1f));
138 Bitmap::BackupSetAt(off_t block
, bool used
)
140 uint32 index
= block
/ 32;
141 if (index
> fByteSize
/ 4) {
142 fprintf(stderr
, "Bitmap::BackupSetAt(): Block %" B_PRIdOFF
" outside "
147 int32 mask
= 1L << (block
& 0x1f);
149 bool oldUsed
= fBackupBitmap
[index
] & mask
;
152 fBackupBitmap
[index
] |= mask
;
154 fBackupBitmap
[index
] &= ~mask
;
161 Bitmap::BackupSet(Inode
*inode
, bool used
)
163 // set inode and its data-stream
165 // the attributes are ignored for now, because they will
166 // be added anyway since all inodes from disk are collected.
168 // printf("a: %Ld\n",inode->Block());
169 BackupSetAt(inode
->Block(),used
);
171 // the data stream of symlinks is no real data stream
172 if (inode
->IsSymlink() && (inode
->Flags() & INODE_LONG_SYMLINK
) == 0)
177 const bfs_inode
*node
= inode
->InodeBuffer();
178 for (int32 i
= 0; i
< NUM_DIRECT_BLOCKS
; i
++) {
179 if (node
->data
.direct
[i
].IsZero())
182 off_t start
= fDisk
->ToBlock(node
->data
.direct
[i
]);
183 off_t end
= start
+ node
->data
.direct
[i
].length
;
184 for (off_t block
= start
; block
< end
; block
++) {
185 if (!BackupSetAt(block
, used
)) {
194 if (node
->data
.max_indirect_range
== 0 || node
->data
.indirect
.IsZero())
197 // printf("c: %Ld\n",fDisk->ToBlock(node->data.indirect));
198 BackupSetAt(fDisk
->ToBlock(node
->data
.indirect
), used
);
200 DataStream
*stream
= dynamic_cast<DataStream
*>(inode
);
204 // load indirect blocks
205 int32 bytes
= node
->data
.indirect
.length
<< fDisk
->BlockShift();
206 block_run
*indirect
= (block_run
*)malloc(bytes
);
207 if (indirect
== NULL
)
210 if (fDisk
->ReadAt(fDisk
->ToOffset(node
->data
.indirect
), indirect
,
214 int32 runs
= bytes
/ sizeof(block_run
);
215 for (int32 i
= 0; i
< runs
; i
++) {
216 if (indirect
[i
].IsZero())
219 off_t start
= fDisk
->ToBlock(indirect
[i
]);
220 off_t end
= start
+ indirect
[i
].length
;
221 for (off_t block
= start
; block
< end
; block
++) {
222 // printf("d: %Ld\n", block);
223 if (!BackupSetAt(block
, used
))
229 // double indirect blocks
231 if (node
->data
.max_double_indirect_range
== 0
232 || node
->data
.double_indirect
.IsZero())
235 // printf("e: %Ld\n",fDisk->ToBlock(node->data.double_indirect));
236 BackupSetAt(fDisk
->ToBlock(node
->data
.double_indirect
), used
);
238 // FIXME: to be implemented...
239 puts("double indirect blocks to block bitmap requested...");
251 Bitmap::CompareWithBackup()
253 for (int32 i
= fByteSize
/ 4;i
-- > 0;) {
254 if (fBitmap
[i
] != fBackupBitmap
[i
]) {
255 printf("differ at %" B_PRId32
" (block %" B_PRId32
") -> bitmap = "
256 "%08" B_PRIx32
", backup = %08" B_PRIx32
"\n", i
, i
* 32,
257 fBitmap
[i
], fBackupBitmap
[i
]);
265 Bitmap::TrustBlockContaining(off_t
/*block*/) const