2 * Copyright 2001-2008, pinc Software. All Rights Reserved.
5 //! handles the BFS block bitmap
17 Bitmap::Bitmap(Disk
*disk
)
46 Bitmap::SetTo(Disk
*disk
)
51 fSize
= divide_roundup(disk
->NumBlocks(),disk
->BlockSize() * 8);
52 fByteSize
= disk
->BlockSize() * disk
->SuperBlock()->num_ags
53 * disk
->SuperBlock()->blocks_per_ag
;
55 fBitmap
= (uint32
*)malloc(fByteSize
);
59 fBackupBitmap
= (uint32
*)malloc(fByteSize
);
60 if (fBackupBitmap
== NULL
)
63 memset(fBackupBitmap
, 0, fByteSize
);
65 // set root block, block bitmap, log as used
66 off_t end
= disk
->ToBlock(disk
->Log()) + disk
->Log().length
;
67 for (off_t block
= 0; block
< end
; block
++) {
68 if (!BackupSetAt(block
, true))
73 if ((size
= disk
->ReadAt(disk
->BlockSize(), fBitmap
, fByteSize
)) < B_OK
) {
82 // calculate used blocks
85 for (uint32 i
= fByteSize
>> 2;i
-- > 0;) {
87 for (int16 j
= 0;j
< 32;j
++,compare
<<= 1) {
88 if (compare
& fBitmap
[i
])
100 return fBitmap
? B_OK
: B_ERROR
;
105 Bitmap::FreeBlocks() const
110 return fDisk
->NumBlocks() - fUsedBlocks
;
115 Bitmap::UsedAt(off_t block
) const
117 uint32 index
= block
/ 32; // 32bit resolution, (beginning with block 1?)
118 if (index
> fByteSize
/ 4)
121 return fBitmap
[index
] & (1L << (block
& 0x1f));
126 Bitmap::BackupUsedAt(off_t block
) const
128 uint32 index
= block
/ 32; // 32bit resolution, (beginning with block 1?)
129 if (index
> fByteSize
/ 4)
132 return fBackupBitmap
[index
] & (1L << (block
& 0x1f));
137 Bitmap::BackupSetAt(off_t block
, bool used
)
139 uint32 index
= block
/ 32;
140 if (index
> fByteSize
/ 4) {
141 fprintf(stderr
, "Bitmap::BackupSetAt(): Block %" B_PRIdOFF
" outside "
146 int32 mask
= 1L << (block
& 0x1f);
148 bool oldUsed
= fBackupBitmap
[index
] & mask
;
151 fBackupBitmap
[index
] |= mask
;
153 fBackupBitmap
[index
] &= ~mask
;
160 Bitmap::BackupSet(Inode
*inode
, bool used
)
162 // set inode and its data-stream
164 // the attributes are ignored for now, because they will
165 // be added anyway since all inodes from disk are collected.
167 // printf("a: %Ld\n",inode->Block());
168 BackupSetAt(inode
->Block(),used
);
170 // the data stream of symlinks is no real data stream
171 if (inode
->IsSymlink() && (inode
->Flags() & INODE_LONG_SYMLINK
) == 0)
176 const bfs_inode
*node
= inode
->InodeBuffer();
177 for (int32 i
= 0; i
< NUM_DIRECT_BLOCKS
; i
++) {
178 if (node
->data
.direct
[i
].IsZero())
181 off_t start
= fDisk
->ToBlock(node
->data
.direct
[i
]);
182 off_t end
= start
+ node
->data
.direct
[i
].length
;
183 for (off_t block
= start
; block
< end
; block
++) {
184 if (!BackupSetAt(block
, used
)) {
193 if (node
->data
.max_indirect_range
== 0 || node
->data
.indirect
.IsZero())
196 // printf("c: %Ld\n",fDisk->ToBlock(node->data.indirect));
197 BackupSetAt(fDisk
->ToBlock(node
->data
.indirect
), used
);
199 DataStream
*stream
= dynamic_cast<DataStream
*>(inode
);
203 // load indirect blocks
204 int32 bytes
= node
->data
.indirect
.length
<< fDisk
->BlockShift();
205 block_run
*indirect
= (block_run
*)malloc(bytes
);
206 if (indirect
== NULL
)
209 if (fDisk
->ReadAt(fDisk
->ToOffset(node
->data
.indirect
), indirect
,
213 int32 runs
= bytes
/ sizeof(block_run
);
214 for (int32 i
= 0; i
< runs
; i
++) {
215 if (indirect
[i
].IsZero())
218 off_t start
= fDisk
->ToBlock(indirect
[i
]);
219 off_t end
= start
+ indirect
[i
].length
;
220 for (off_t block
= start
; block
< end
; block
++) {
221 // printf("d: %Ld\n", block);
222 if (!BackupSetAt(block
, used
))
228 // double indirect blocks
230 if (node
->data
.max_double_indirect_range
== 0
231 || node
->data
.double_indirect
.IsZero())
234 // printf("e: %Ld\n",fDisk->ToBlock(node->data.double_indirect));
235 BackupSetAt(fDisk
->ToBlock(node
->data
.double_indirect
), used
);
237 // FIXME: to be implemented...
238 puts("double indirect blocks to block bitmap requested...");
250 Bitmap::CompareWithBackup()
252 for (int32 i
= fByteSize
/ 4;i
-- > 0;) {
253 if (fBitmap
[i
] != fBackupBitmap
[i
]) {
254 printf("differ at %" B_PRId32
" (block %" B_PRId32
") -> bitmap = "
255 "%08" B_PRIx32
", backup = %08" B_PRIx32
"\n", i
, i
* 32,
256 fBitmap
[i
], fBackupBitmap
[i
]);
264 Bitmap::TrustBlockContaining(off_t
/*block*/) const