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:
+12
-7
@@ -122,6 +122,7 @@ static void file_init(File *f, uint64_t chunk_size)
|
|||||||
{
|
{
|
||||||
f->chunk_size = chunk_size;
|
f->chunk_size = chunk_size;
|
||||||
f->num_chunks = 0;
|
f->num_chunks = 0;
|
||||||
|
f->file_size = 0;
|
||||||
f->chunks = NULL;
|
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++)
|
for (uint64_t i = first_chunk_index; i <= last_chunk_index; i++)
|
||||||
f->chunks[i] = hashes[i - first_chunk_index];
|
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
|
// Now check which old hashes are no longer used
|
||||||
// anywhere in the tree
|
// anywhere in the tree
|
||||||
//
|
//
|
||||||
@@ -432,14 +438,11 @@ int file_tree_read(FileTree *ft, string path,
|
|||||||
|
|
||||||
*chunk_size = f->chunk_size;
|
*chunk_size = f->chunk_size;
|
||||||
|
|
||||||
// Calculate file size (number of chunks * chunk size)
|
// Calculate actual bytes that can be read based on actual file size
|
||||||
uint64_t file_size = f->num_chunks * f->chunk_size;
|
if (off >= f->file_size) {
|
||||||
|
|
||||||
// Calculate actual bytes that can be read
|
|
||||||
if (off >= file_size) {
|
|
||||||
*actual_bytes = 0;
|
*actual_bytes = 0;
|
||||||
} else if (off + len > file_size) {
|
} else if (off + len > f->file_size) {
|
||||||
*actual_bytes = file_size - off;
|
*actual_bytes = f->file_size - off;
|
||||||
} else {
|
} else {
|
||||||
*actual_bytes = len;
|
*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->chunk_size);
|
||||||
sc_write_u64(sc, f->num_chunks);
|
sc_write_u64(sc, f->num_chunks);
|
||||||
|
sc_write_u64(sc, f->file_size);
|
||||||
for (uint64_t i = 0; i < f->num_chunks; i++)
|
for (uint64_t i = 0; i < f->num_chunks; i++)
|
||||||
sc_write_hash(sc, f->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->chunk_size);
|
||||||
dc_read_u64(dc, &f->num_chunks);
|
dc_read_u64(dc, &f->num_chunks);
|
||||||
|
dc_read_u64(dc, &f->file_size);
|
||||||
|
|
||||||
f->chunks = sys_malloc(f->num_chunks * sizeof(SHA256));
|
f->chunks = sys_malloc(f->num_chunks * sizeof(SHA256));
|
||||||
if (f->chunks == NULL) {
|
if (f->chunks == NULL) {
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ typedef struct Entity Entity;
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
uint64_t chunk_size; // TODO: this should be an u32
|
uint64_t chunk_size; // TODO: this should be an u32
|
||||||
uint64_t num_chunks; // TODO: and this too
|
uint64_t num_chunks; // TODO: and this too
|
||||||
|
uint64_t file_size; // Offset of last byte written + 1
|
||||||
SHA256 *chunks;
|
SHA256 *chunks;
|
||||||
} File;
|
} File;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user