Skip to content

Commit

Permalink
ADDFILE should never make first block sparse
Browse files Browse the repository at this point in the history
When checking if a file block can be sparse (i.e. not actually
allocated on disk), ensure the test always fails for the first
block of the file, as this would violate the ProDOS file system
specification, and makes ProDOS-8 unhappy.

Additionally, when loading a volume, log if files are encountered
that have sparse first blocks.

mach-kernel#42
  • Loading branch information
inexorabletash committed Jul 22, 2024
1 parent 22660ba commit 09cc114
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 4 deletions.
9 changes: 9 additions & 0 deletions Src/Dc_Prodos.c
Original file line number Diff line number Diff line change
Expand Up @@ -1090,6 +1090,9 @@ static int GetFileDataResourceSize(struct prodos_image *current_image, struct fi
if(tab_block[i] == 0)
file_entry->nb_sparse++;

if(tab_block[0] == 0)
logf_error(" Warning : Block 0 is sparse in file: '%s'.\n", file_entry->file_path);

/* Table des blocs utilisés */
file_entry->tab_used_block = BuildUsedBlockTable(nb_block,tab_block,nb_index_block,tab_index_block,&file_entry->nb_used_block);
if(file_entry->tab_used_block == NULL)
Expand Down Expand Up @@ -1180,6 +1183,9 @@ static int GetFileDataResourceSize(struct prodos_image *current_image, struct fi
if(tab_block[i] == 0)
file_entry->nb_sparse++;

if(tab_block[0] == 0)
logf_error(" Warning : Block 0 is sparse in data fork of file: '%s'.\n", file_entry->file_path);

/* Table des blocs utilisés (Data) */
tab_used_block_data = BuildUsedBlockTable(nb_block,tab_block,nb_index_block,tab_index_block,&nb_used_block_data);
if(tab_used_block_data == NULL)
Expand Down Expand Up @@ -1250,6 +1256,9 @@ static int GetFileDataResourceSize(struct prodos_image *current_image, struct fi
if(tab_block[i] == 0)
file_entry->nb_sparse++;

if(tab_block[0] == 0)
logf_error(" Warning : Block 0 is sparse in resource fork of file: '%s'.\n", file_entry->file_path);

/* Table des blocs utilisés (Resource) */
tab_used_block_resource = BuildUsedBlockTable(nb_block,tab_block,nb_index_block,tab_index_block,&nb_used_block_resource);
if(tab_used_block_resource == NULL)
Expand Down
16 changes: 12 additions & 4 deletions Src/Prodos_Add.c
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,9 @@ static void ComputeFileBlockUsage(struct prodos_file *current_file)
for(i=0; i<current_file->data_length; i+=BLOCK_SIZE)
{
/* Recherche les plages de 0 */
if(i+BLOCK_SIZE <= current_file->data_length)
if(i == 0)
result = 1; /* Block 0 ne doit pas être Sparse */
else if(i+BLOCK_SIZE <= current_file->data_length)
result = memcmp(&current_file->data[i],empty_block,BLOCK_SIZE);
else
result = memcmp(&current_file->data[i],empty_block,current_file->data_length-i);
Expand All @@ -586,7 +588,9 @@ static void ComputeFileBlockUsage(struct prodos_file *current_file)
for(i=0; i<current_file->resource_length; i+=BLOCK_SIZE)
{
/* Recherche les plages de 0 */
if(i+BLOCK_SIZE <= current_file->resource_length)
if(i == 0)
result = 1; /* Block 0 ne doit pas être Sparse */
else if(i+BLOCK_SIZE <= current_file->resource_length)
result = memcmp(&current_file->resource[i],empty_block,BLOCK_SIZE);
else
result = memcmp(&current_file->resource[i],empty_block,current_file->resource_length-i);
Expand Down Expand Up @@ -883,7 +887,9 @@ static WORD CreateSaplingContent(struct prodos_image *current_image, struct prod
for(i=0,j=1,k=0; i<data_length; i+=BLOCK_SIZE,k++)
{
/* Recherche les plages de 0 */
if(i+BLOCK_SIZE <= data_length)
if(i == 0)
is_empty = 0; /* Block 0 ne doit pas être Sparse */
else if(i+BLOCK_SIZE <= data_length)
is_empty = !memcmp(&data[i],empty_block,BLOCK_SIZE);
else
is_empty = !memcmp(&data[i],empty_block,data_length-i);
Expand Down Expand Up @@ -1006,7 +1012,9 @@ static WORD CreateTreeContent(struct prodos_image *current_image, struct prodos_
for(i=0,j=index_data,k=0,l=0; i<data_length; i+=BLOCK_SIZE,k++)
{
/* Recherche les plages de 0 */
if(i+BLOCK_SIZE <= data_length)
if(i == 0)
is_empty = 0; /* Block 0 ne doit pas être Sparse */
else if(i+BLOCK_SIZE <= data_length)
is_empty = !memcmp(&data[i],empty_block,BLOCK_SIZE);
else
is_empty = !memcmp(&data[i],empty_block,data_length-i);
Expand Down

0 comments on commit 09cc114

Please sign in to comment.