Fix file size tracking to use actual written bytes

Previously, file_size was calculated as num_chunks * chunk_size, which
incorrectly treated the file size as the full capacity of all allocated
chunks. The actual file size should be the offset of the last byte
written plus 1.

Changes:
- Added file_size field to File structure to track actual file extent
- Initialize file_size to 0 when creating new files
- Update file_size in file_tree_write() based on write offset + length
- Modified file_tree_read() to use file_size instead of num_chunks * chunk_size
- Updated serialization/deserialization to handle file_size field

This ensures that actual_bytes calculations correctly reflect the true
file size, not just the allocated chunk capacity.
This commit is contained in:
Claude
2025-11-22 22:33:15 +00:00
parent f856bd0e05
commit 7b0b1acf61
2 changed files with 13 additions and 7 deletions
+12 -7
View File
@@ -122,6 +122,7 @@ static void file_init(File *f, uint64_t chunk_size)
{
f->chunk_size = chunk_size;
f->num_chunks = 0;
f->file_size = 0;
f->chunks = NULL;
}
@@ -375,6 +376,11 @@ int file_tree_write(FileTree *ft, string path,
for (uint64_t i = first_chunk_index; i <= last_chunk_index; i++)
f->chunks[i] = hashes[i - first_chunk_index];
// Update file size (last byte written + 1)
uint64_t new_size = off + len;
if (new_size > f->file_size)
f->file_size = new_size;
// Now check which old hashes are no longer used
// anywhere in the tree
//
@@ -432,14 +438,11 @@ int file_tree_read(FileTree *ft, string path,
*chunk_size = f->chunk_size;
// Calculate file size (number of chunks * chunk size)
uint64_t file_size = f->num_chunks * f->chunk_size;
// Calculate actual bytes that can be read
if (off >= file_size) {
// Calculate actual bytes that can be read based on actual file size
if (off >= f->file_size) {
*actual_bytes = 0;
} else if (off + len > file_size) {
*actual_bytes = file_size - off;
} else if (off + len > f->file_size) {
*actual_bytes = f->file_size - off;
} else {
*actual_bytes = len;
}
@@ -539,6 +542,7 @@ static void file_serialize(SerializeContext *sc, File *f)
{
sc_write_u64(sc, f->chunk_size);
sc_write_u64(sc, f->num_chunks);
sc_write_u64(sc, f->file_size);
for (uint64_t i = 0; i < f->num_chunks; i++)
sc_write_hash(sc, f->chunks[i]);
}
@@ -638,6 +642,7 @@ static void file_deserialize(DeserializeContext *dc, File *f)
{
dc_read_u64(dc, &f->chunk_size);
dc_read_u64(dc, &f->num_chunks);
dc_read_u64(dc, &f->file_size);
f->chunks = sys_malloc(f->num_chunks * sizeof(SHA256));
if (f->chunks == NULL) {
+1
View File
@@ -18,6 +18,7 @@ typedef struct Entity Entity;
typedef struct {
uint64_t chunk_size; // TODO: this should be an u32
uint64_t num_chunks; // TODO: and this too
uint64_t file_size; // Offset of last byte written + 1
SHA256 *chunks;
} File;