mft.c: Fix broken free MFT records accounting during bitmap extension.
When the bitmap needs extending, 'vol->free_mft_records' is incremented by 8*8=64 records. This is due to the bitmap's initialized area being extended 8 bytes at a time. However the way 'vol->free_mft_records' is being initialized is that all the bits that are currently allocated to the MFT bitmap are already taken into account at initialization time. This leads to a value for 'vol->free_mft_records' that is larger than the actual available number of MFT records. For example if there are 20 used MFT records and the bitmap has a 4096 byte allocation where 16 bytes are initialized, the number of free MFT records are ((8 * 16) - 20) + (8 * (4096 - 16)) = 32748 records available. If we now expand the bitmap by 8 initialized bytes, we'd be adding 64 MFT entries according to the logic in the function 'ntfs_mft_bitmap_extend_initialized'. However we are expanding it within the bounds of the existing allocation where there is (4096 - 16) bytes free, so they shouldn't be added at all at this stage. The result is that our internal accounting is that we have 32748 + 64 = 32812 available MFT records, but in reality we will have 32748 records available all the time until we expand the allocation beyond 4096 bytes. Fixed by incrementing 'vol->free_mft_records' when the allocation is expanded, not when the initialized size is.edge
parent
241ddb3860
commit
1565b01e21
|
@ -978,7 +978,6 @@ static int ntfs_mft_bitmap_extend_initialized(ntfs_volume *vol)
|
|||
ll = ntfs_attr_pwrite(mftbmp_na, old_initialized_size, 8, &ll);
|
||||
if (ll == 8) {
|
||||
ntfs_log_debug("Wrote eight initialized bytes to mft bitmap.\n");
|
||||
vol->free_mft_records += (8 * 8);
|
||||
ret = 0;
|
||||
goto out;
|
||||
}
|
||||
|
@ -1776,6 +1775,7 @@ retry:
|
|||
(long long)mftbmp_na->initialized_size);
|
||||
if (mftbmp_na->initialized_size + 8 > mftbmp_na->allocated_size) {
|
||||
|
||||
const s64 old_allocated_size = mftbmp_na->allocated_size;
|
||||
int ret = ntfs_mft_bitmap_extend_allocation(vol);
|
||||
|
||||
if (ret == STATUS_ERROR)
|
||||
|
@ -1792,6 +1792,9 @@ retry:
|
|||
(long long)mftbmp_na->allocated_size,
|
||||
(long long)mftbmp_na->data_size,
|
||||
(long long)mftbmp_na->initialized_size);
|
||||
|
||||
vol->free_mft_records +=
|
||||
(mftbmp_na->allocated_size - old_allocated_size) << 3;
|
||||
}
|
||||
/*
|
||||
* We now have sufficient allocated space, extend the initialized_size
|
||||
|
|
Loading…
Reference in New Issue