- eliminated get_bitmap_data ()
- eliminated struct bitmap on_disk_lcn_bitmap - speeded up compare_bitmaps() - speeded up advise_on_resize() - ntfs_mapping_pairs_build() prints reason if error happens - print cluster size, device size and more onging operations (Logical change 1.96)edge.strict_endians
parent
fe038bd2dc
commit
5fb3e94ccb
|
@ -473,64 +473,61 @@ void walk_attributes(ntfs_resize_t *resize)
|
|||
ntfs_attr_put_search_ctx(ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* get_bitmap_data
|
||||
*
|
||||
* Read the metadata file $Bitmap into a bitmap struct.
|
||||
* Each cluster on disk is represented by a bit in this file.
|
||||
*/
|
||||
void get_bitmap_data(ntfs_volume *vol, struct bitmap *bm)
|
||||
{
|
||||
ntfs_attr *attr;
|
||||
|
||||
attr = vol->lcnbmp_na;
|
||||
|
||||
bm->size = attr->initialized_size;
|
||||
|
||||
bm->bm = malloc (bm->size);
|
||||
if (!bm->bm)
|
||||
perr_exit ("get_bitmap_data");
|
||||
|
||||
if (ntfs_attr_pread (attr, 0, bm->size, bm->bm) < 0)
|
||||
perr_exit("Couldn't get $Bitmap $DATA");
|
||||
}
|
||||
|
||||
/**
|
||||
* compare_bitmaps
|
||||
*
|
||||
* Compare two bitmaps. In this case, $Bitmap as read from the disk and
|
||||
* lcn_bitmap which we built from the MFT Records.
|
||||
*/
|
||||
void compare_bitmaps(struct bitmap *a, struct bitmap *b)
|
||||
void compare_bitmaps(struct bitmap *a)
|
||||
{
|
||||
u64 i, j, mismatch = 0;
|
||||
s64 i,count;
|
||||
int k, mismatch = 0;
|
||||
char bit;
|
||||
|
||||
if (a->size != b->size)
|
||||
err_exit("$Bitmap file size doesn't match "
|
||||
"calculated size ((%d != %d)\n", a->size, b->size);
|
||||
|
||||
for (i = 0; i < a->size; i++) {
|
||||
u8 bm[NTFS_BUF_SIZE];
|
||||
|
||||
printf("Accounting clusters ...\n");
|
||||
|
||||
i = 0;
|
||||
while (1) {
|
||||
count = ntfs_attr_pread(vol->lcnbmp_na, i, NTFS_BUF_SIZE, bm);
|
||||
if (count == -1)
|
||||
perr_exit("Couldn't get $Bitmap $DATA");
|
||||
|
||||
if (a->bm[i] == b->bm[i])
|
||||
continue;
|
||||
|
||||
for (j = i * 8; j < i * 8 + 8; j++) {
|
||||
if (count == 0) {
|
||||
if (a->size != i)
|
||||
err_exit("$Bitmap file size doesn't match "
|
||||
"calculated size ((%Ld != %Ld)\n",
|
||||
a->size, i);
|
||||
break;
|
||||
}
|
||||
|
||||
bit = ntfs_bit_get(a->bm, j);
|
||||
if (bit != ntfs_bit_get(b->bm, j)) {
|
||||
for (k = 0; k < count; k++) {
|
||||
u64 j;
|
||||
|
||||
if (a->bm[i + k] == bm[k])
|
||||
continue;
|
||||
|
||||
for (j = i * 8; j < i * 8 + 8; j++) {
|
||||
|
||||
bit = ntfs_bit_get(a->bm, j);
|
||||
if (bit != ntfs_bit_get(bm, k + j % 8))
|
||||
continue;
|
||||
|
||||
if (++mismatch > 10)
|
||||
continue;
|
||||
|
||||
printf("Cluster accounting failed at %llu "
|
||||
"(0x%Lx): %s cluster in $Bitmap\n",
|
||||
j, j, bit ? "extra" : "miss");
|
||||
j, j, bit ? "missing" : "extra");
|
||||
}
|
||||
}
|
||||
|
||||
i += count;
|
||||
}
|
||||
|
||||
if (mismatch) {
|
||||
printf("Totally %Lu cluster accounting mismatches.\n"
|
||||
printf("Totally %d cluster accounting mismatches.\n"
|
||||
"You didn't shutdown Windows properly?\n", mismatch);
|
||||
exit(1);
|
||||
}
|
||||
|
@ -620,13 +617,30 @@ void walk_inodes(ntfs_resize_t *resize)
|
|||
*/
|
||||
void advise_on_resize()
|
||||
{
|
||||
u64 i, old_b, new_b, g_b, old_mb, new_mb, g_mb;
|
||||
s64 i, old_b, new_b, g_b, old_mb, new_mb, g_mb;
|
||||
int fragmanted_end;
|
||||
|
||||
for (i = vol->nr_clusters - 1; i > 0; i--)
|
||||
printf("Calculating smallest shrunken size supported ...\n");
|
||||
|
||||
for (i = vol->nr_clusters - 1; i > 0 && (i % 8); i--)
|
||||
if (ntfs_bit_get(lcn_bitmap.bm, i))
|
||||
goto found_used_cluster;
|
||||
|
||||
if (i > 0) {
|
||||
if (ntfs_bit_get(lcn_bitmap.bm, i))
|
||||
goto found_used_cluster;
|
||||
} else
|
||||
goto found_used_cluster;
|
||||
|
||||
for (i -= 8; i >= 0; i -= 8)
|
||||
if (lcn_bitmap.bm[i / 8])
|
||||
break;
|
||||
|
||||
for (i += 7; i > 0; i--)
|
||||
if (ntfs_bit_get(lcn_bitmap.bm, i))
|
||||
break;
|
||||
|
||||
|
||||
found_used_cluster:
|
||||
i += 2; /* first free + we reserve one for the backup boot sector */
|
||||
fragmanted_end = (i >= vol->nr_clusters) ? 1 : 0;
|
||||
|
||||
|
@ -738,7 +752,7 @@ void truncate_badclust_bad_attr(ATTR_RECORD *a, s64 nr_clusters)
|
|||
perr_exit("Couldn't get memory");
|
||||
|
||||
if (ntfs_mapping_pairs_build(vol, mp, mp_size, rl_bad))
|
||||
exit(1);
|
||||
perr_exit("ntfs_mapping_pairs_build");
|
||||
|
||||
memcpy((char *)a + a->mapping_pairs_offset, mp, mp_size);
|
||||
a->highest_vcn = cpu_to_le64(nr_clusters - 1LL);
|
||||
|
@ -1034,18 +1048,21 @@ void update_bootsector(s64 nr_clusters)
|
|||
perr_exit("write() error");
|
||||
}
|
||||
|
||||
|
||||
s64 volume_size(ntfs_volume *vol, s64 nr_clusters)
|
||||
{
|
||||
return nr_clusters * vol->cluster_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* print_volume_size
|
||||
*
|
||||
* Print the volume size in bytes and decimal megabytes.
|
||||
*/
|
||||
void print_volume_size(char *str, ntfs_volume *v, s64 nr_clusters)
|
||||
void print_volume_size(char *str, s64 bytes)
|
||||
{
|
||||
s64 b; /* volume size in bytes */
|
||||
|
||||
b = nr_clusters * v->cluster_size;
|
||||
printf("%s: %lld bytes (%lld MB)\n",
|
||||
str, b, rounded_up_division(b, NTFS_MBYTE));
|
||||
str, bytes, rounded_up_division(bytes, NTFS_MBYTE));
|
||||
}
|
||||
|
||||
void print_disk_usage(ntfs_resize_t *resize)
|
||||
|
@ -1057,7 +1074,7 @@ void print_disk_usage(ntfs_resize_t *resize)
|
|||
free = total - used;
|
||||
relocations = resize->relocations * vol->cluster_size;
|
||||
|
||||
printf("Space in use: %lld MB (%.1f%%) ",
|
||||
printf("Space in use : %lld MB (%.1f%%) ",
|
||||
rounded_up_division(used, NTFS_MBYTE),
|
||||
100.0 * ((float)used / total));
|
||||
|
||||
|
@ -1110,8 +1127,9 @@ void mount_volume()
|
|||
if (ntfs_version_is_supported(vol))
|
||||
perr_exit("Unknown NTFS version");
|
||||
|
||||
Dprintf("Cluster size : %u\n", vol->cluster_size);
|
||||
print_volume_size("Current volume size", vol, vol->nr_clusters);
|
||||
printf("Cluster size : %u bytes\n", vol->cluster_size);
|
||||
print_volume_size("Current volume size",
|
||||
volume_size(vol, vol->nr_clusters));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1148,7 +1166,6 @@ void prepare_volume_fixup()
|
|||
*/
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct bitmap on_disk_lcn_bitmap;
|
||||
ntfs_resize_t resize;
|
||||
s64 new_size = 0; /* in clusters */
|
||||
s64 device_size; /* in bytes */
|
||||
|
@ -1170,6 +1187,8 @@ int main(int argc, char **argv)
|
|||
if (device_size <= 0)
|
||||
err_exit("Couldn't get device size (%Ld)!\n", device_size);
|
||||
|
||||
print_volume_size("Current device size", device_size);
|
||||
|
||||
if (device_size < vol->nr_clusters * vol->cluster_size)
|
||||
err_exit("Current NTFS volume size is bigger than the device "
|
||||
"size (%Ld)!\nCorrupt partition table or incorrect "
|
||||
|
@ -1190,7 +1209,8 @@ int main(int argc, char **argv)
|
|||
new_size = opt.bytes / vol->cluster_size;
|
||||
|
||||
if (!opt.info)
|
||||
print_volume_size("New volume size ", vol, new_size);
|
||||
print_volume_size("New volume size ",
|
||||
volume_size(vol, new_size));
|
||||
|
||||
/* Backup boot sector at the end of device isn't counted in NTFS
|
||||
volume size thus we have to reserve space for. We don't trust
|
||||
|
@ -1211,13 +1231,10 @@ int main(int argc, char **argv)
|
|||
resize.new_volume_size = new_size;
|
||||
|
||||
walk_inodes(&resize);
|
||||
compare_bitmaps(&lcn_bitmap);
|
||||
|
||||
print_disk_usage(&resize);
|
||||
|
||||
get_bitmap_data(vol, &on_disk_lcn_bitmap);
|
||||
compare_bitmaps(&on_disk_lcn_bitmap, &lcn_bitmap);
|
||||
free(on_disk_lcn_bitmap.bm);
|
||||
|
||||
if (opt.info) {
|
||||
advise_on_resize();
|
||||
exit(0);
|
||||
|
|
Loading…
Reference in New Issue