* stage2/fsys_fat.c (fat_superblock): clust_eof_marker added.

(fat_mount): Initialize clust_eof_marker to 0xff8, 0xfff8, or
0xffffff8, depending on fat size.  Support for single active FAT
added (FAT32 extension). Changed the boundary between FAT12 and
FAT16, again.  The Microsoft KB article Q65541 seems to be wrong
here, I go with mtools and the previous behaviour of grub: FAT12
iff number of clusters (without counting the two nonexisting
clusters) is less or equal 4095.
(fat_read): Report error if cluster number is too big, but not
greater or equal clust_eof_marker.
* stage2/fsys_reiserfs.c (journal_init): Fixed calculation of
journal_transaction.
This commit is contained in:
jochen 2000-08-04 09:11:28 +00:00
parent bef3d7d863
commit 028049bbd4
3 changed files with 80 additions and 46 deletions

View file

@ -1,3 +1,18 @@
2000-08-04 Jochen Hoenicke <jochen@gnu.org>
* stage2/fsys_fat.c (fat_superblock): clust_eof_marker added.
(fat_mount): Initialize clust_eof_marker to 0xff8, 0xfff8, or
0xffffff8, depending on fat size. Support for single active FAT
added (FAT32 extension). Changed the boundary between FAT12 and
FAT16, again. The Microsoft KB article Q65541 seems to be wrong
here, I go with mtools and the previous behaviour of grub: FAT12
iff number of clusters (without counting the two nonexisting
clusters) is less or equal 4095.
(fat_read): Report error if cluster number is too big, but not
greater or equal clust_eof_marker.
* stage2/fsys_reiserfs.c (journal_init): Fixed calculation of
journal_transaction.
2000-08-01 Jochen Hoenicke <jochen@gnu.org> 2000-08-01 Jochen Hoenicke <jochen@gnu.org>
* stage2/fsys_reiserfs.c: Symlink support added. * stage2/fsys_reiserfs.c: Symlink support added.

View file

@ -35,6 +35,7 @@ struct fat_superblock
int num_sectors; int num_sectors;
int num_clust; int num_clust;
int clust_eof_marker;
int sects_per_clust; int sects_per_clust;
int sectsize_bits; int sectsize_bits;
int clustsize_bits; int clustsize_bits;
@ -115,8 +116,21 @@ fat_mount (void)
/* This is a FAT32 */ /* This is a FAT32 */
if (FAT_CVT_U16(bpb.dir_entries)) if (FAT_CVT_U16(bpb.dir_entries))
return 0; return 0;
if (bpb.flags & 0x0080)
{
/* FAT mirroring is disabled, get active FAT */
int active_fat = bpb.flags & 0x000f;
if (active_fat >= bpb.num_fats)
return 0;
FAT_SUPER->fat_offset += active_fat * FAT_SUPER->fat_length;
}
FAT_SUPER->fat_size = 8; FAT_SUPER->fat_size = 8;
FAT_SUPER->root_cluster = bpb.root_cluster; FAT_SUPER->root_cluster = bpb.root_cluster;
/* Yes the following is correct. FAT32 should be called FAT28 :) */
FAT_SUPER->clust_eof_marker = 0xffffff8;
} }
else else
{ {
@ -124,10 +138,16 @@ fat_mount (void)
return 0; return 0;
FAT_SUPER->root_cluster = -1; FAT_SUPER->root_cluster = -1;
if (FAT_SUPER->num_clust >= FAT_MAX_12BIT_CLUST) if (FAT_SUPER->num_clust > FAT_MAX_12BIT_CLUST)
FAT_SUPER->fat_size = 4; {
FAT_SUPER->fat_size = 4;
FAT_SUPER->clust_eof_marker = 0xfff8;
}
else else
FAT_SUPER->fat_size = 3; {
FAT_SUPER->fat_size = 3;
FAT_SUPER->clust_eof_marker = 0xff8;
}
} }
@ -178,52 +198,51 @@ fat_read (char *buf, int len)
{ {
int sector; int sector;
while (logical_clust > FAT_SUPER->current_cluster_num) while (logical_clust > FAT_SUPER->current_cluster_num)
{ {
/* calculate next cluster */ /* calculate next cluster */
int fat_entry = int fat_entry =
FAT_SUPER->current_cluster * FAT_SUPER->fat_size; FAT_SUPER->current_cluster * FAT_SUPER->fat_size;
int next_cluster; int next_cluster;
int cached_pos = (fat_entry - FAT_SUPER->cached_fat); int cached_pos = (fat_entry - FAT_SUPER->cached_fat);
if (cached_pos < 0 || if (cached_pos < 0 ||
(cached_pos + FAT_SUPER->fat_size) > 2*FAT_CACHE_SIZE) (cached_pos + FAT_SUPER->fat_size) > 2*FAT_CACHE_SIZE)
{ {
FAT_SUPER->cached_fat = (fat_entry & ~(2*SECTOR_SIZE - 1)); FAT_SUPER->cached_fat = (fat_entry & ~(2*SECTOR_SIZE - 1));
cached_pos = (fat_entry - FAT_SUPER->cached_fat); cached_pos = (fat_entry - FAT_SUPER->cached_fat);
sector = FAT_SUPER->fat_offset sector = FAT_SUPER->fat_offset
+ FAT_SUPER->cached_fat / (2*SECTOR_SIZE); + FAT_SUPER->cached_fat / (2*SECTOR_SIZE);
if (!devread (sector, 0, FAT_CACHE_SIZE, (char*) FAT_BUF)) if (!devread (sector, 0, FAT_CACHE_SIZE, (char*) FAT_BUF))
return 0; return 0;
} }
next_cluster = * (unsigned long *) (FAT_BUF + (cached_pos >> 1)); next_cluster = * (unsigned long *) (FAT_BUF + (cached_pos >> 1));
if (FAT_SUPER->fat_size == 3) if (FAT_SUPER->fat_size == 3)
{ {
if (cached_pos & 1) if (cached_pos & 1)
next_cluster >>= 4; next_cluster >>= 4;
next_cluster &= 0xFFF; next_cluster &= 0xFFF;
} }
else if (FAT_SUPER->fat_size == 4) else if (FAT_SUPER->fat_size == 4)
next_cluster &= 0xFFFF; next_cluster &= 0xFFFF;
if (next_cluster < 2) if (next_cluster >= FAT_SUPER->clust_eof_marker)
{ return ret;
errnum = ERR_FSYS_CORRUPT; if (next_cluster < 2 || next_cluster >= FAT_SUPER->num_clust)
return 0; {
} errnum = ERR_FSYS_CORRUPT;
return 0;
if (next_cluster >= FAT_SUPER->num_clust) }
return ret;
FAT_SUPER->current_cluster = next_cluster;
FAT_SUPER->current_cluster = next_cluster; FAT_SUPER->current_cluster_num++;
FAT_SUPER->current_cluster_num++; }
}
sector = FAT_SUPER->data_offset + sector = FAT_SUPER->data_offset +
((FAT_SUPER->current_cluster - 2) << (FAT_SUPER->clustsize_bits ((FAT_SUPER->current_cluster - 2) << (FAT_SUPER->clustsize_bits
- FAT_SUPER->sectsize_bits)); - FAT_SUPER->sectsize_bits));
size = (1 << FAT_SUPER->clustsize_bits) - offset; size = (1 << FAT_SUPER->clustsize_bits) - offset;
if (size > len) if (size > len)
size = len; size = len;
#ifndef STAGE1_5 #ifndef STAGE1_5
disk_read_func = disk_read_hook; disk_read_func = disk_read_hook;

View file

@ -504,7 +504,6 @@ journal_init (void)
desc.j_trans_id, desc.j_mount_id, desc_block); desc.j_trans_id, desc.j_mount_id, desc_block);
#endif #endif
INFO->journal_transactions++;
next_trans_id++; next_trans_id++;
if (journal_table < JOURNAL_END) if (journal_table < JOURNAL_END)
{ {
@ -549,7 +548,8 @@ journal_init (void)
desc.j_trans_id, desc.j_mount_id, desc_block); desc.j_trans_id, desc.j_mount_id, desc_block);
#endif #endif
INFO->journal_transactions = next_trans_id - header.j_last_flush_trans_id; INFO->journal_transactions
= next_trans_id - header.j_last_flush_trans_id - 1;
return errnum == 0; return errnum == 0;
} }