From 028049bbd40c63e2e3f60accdac43c2a91c43776 Mon Sep 17 00:00:00 2001 From: jochen Date: Fri, 4 Aug 2000 09:11:28 +0000 Subject: [PATCH] * 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. --- ChangeLog | 15 ++++++ stage2/fsys_fat.c | 107 ++++++++++++++++++++++++----------------- stage2/fsys_reiserfs.c | 4 +- 3 files changed, 80 insertions(+), 46 deletions(-) diff --git a/ChangeLog b/ChangeLog index 9c585e2b5..83ef2eebc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2000-08-04 Jochen Hoenicke + + * 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 * stage2/fsys_reiserfs.c: Symlink support added. diff --git a/stage2/fsys_fat.c b/stage2/fsys_fat.c index 798b90d4c..27644abbd 100644 --- a/stage2/fsys_fat.c +++ b/stage2/fsys_fat.c @@ -35,6 +35,7 @@ struct fat_superblock int num_sectors; int num_clust; + int clust_eof_marker; int sects_per_clust; int sectsize_bits; int clustsize_bits; @@ -115,8 +116,21 @@ fat_mount (void) /* This is a FAT32 */ if (FAT_CVT_U16(bpb.dir_entries)) 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->root_cluster = bpb.root_cluster; + + /* Yes the following is correct. FAT32 should be called FAT28 :) */ + FAT_SUPER->clust_eof_marker = 0xffffff8; } else { @@ -124,10 +138,16 @@ fat_mount (void) return 0; FAT_SUPER->root_cluster = -1; - if (FAT_SUPER->num_clust >= FAT_MAX_12BIT_CLUST) - FAT_SUPER->fat_size = 4; + if (FAT_SUPER->num_clust > FAT_MAX_12BIT_CLUST) + { + FAT_SUPER->fat_size = 4; + FAT_SUPER->clust_eof_marker = 0xfff8; + } 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; while (logical_clust > FAT_SUPER->current_cluster_num) - { - /* calculate next cluster */ - int fat_entry = - FAT_SUPER->current_cluster * FAT_SUPER->fat_size; - int next_cluster; - int cached_pos = (fat_entry - FAT_SUPER->cached_fat); - - if (cached_pos < 0 || - (cached_pos + FAT_SUPER->fat_size) > 2*FAT_CACHE_SIZE) - { - FAT_SUPER->cached_fat = (fat_entry & ~(2*SECTOR_SIZE - 1)); - cached_pos = (fat_entry - FAT_SUPER->cached_fat); - sector = FAT_SUPER->fat_offset - + FAT_SUPER->cached_fat / (2*SECTOR_SIZE); - if (!devread (sector, 0, FAT_CACHE_SIZE, (char*) FAT_BUF)) - return 0; - } - next_cluster = * (unsigned long *) (FAT_BUF + (cached_pos >> 1)); - if (FAT_SUPER->fat_size == 3) - { - if (cached_pos & 1) - next_cluster >>= 4; - next_cluster &= 0xFFF; - } - else if (FAT_SUPER->fat_size == 4) - next_cluster &= 0xFFFF; - - if (next_cluster < 2) - { - 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_num++; - } + { + /* calculate next cluster */ + int fat_entry = + FAT_SUPER->current_cluster * FAT_SUPER->fat_size; + int next_cluster; + int cached_pos = (fat_entry - FAT_SUPER->cached_fat); + + if (cached_pos < 0 || + (cached_pos + FAT_SUPER->fat_size) > 2*FAT_CACHE_SIZE) + { + FAT_SUPER->cached_fat = (fat_entry & ~(2*SECTOR_SIZE - 1)); + cached_pos = (fat_entry - FAT_SUPER->cached_fat); + sector = FAT_SUPER->fat_offset + + FAT_SUPER->cached_fat / (2*SECTOR_SIZE); + if (!devread (sector, 0, FAT_CACHE_SIZE, (char*) FAT_BUF)) + return 0; + } + next_cluster = * (unsigned long *) (FAT_BUF + (cached_pos >> 1)); + if (FAT_SUPER->fat_size == 3) + { + if (cached_pos & 1) + next_cluster >>= 4; + next_cluster &= 0xFFF; + } + else if (FAT_SUPER->fat_size == 4) + next_cluster &= 0xFFFF; + + if (next_cluster >= FAT_SUPER->clust_eof_marker) + return ret; + if (next_cluster < 2 || next_cluster >= FAT_SUPER->num_clust) + { + errnum = ERR_FSYS_CORRUPT; + return 0; + } + + FAT_SUPER->current_cluster = next_cluster; + FAT_SUPER->current_cluster_num++; + } 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)); size = (1 << FAT_SUPER->clustsize_bits) - offset; if (size > len) - size = len; + size = len; #ifndef STAGE1_5 disk_read_func = disk_read_hook; diff --git a/stage2/fsys_reiserfs.c b/stage2/fsys_reiserfs.c index eb1c71564..8cf7a1848 100644 --- a/stage2/fsys_reiserfs.c +++ b/stage2/fsys_reiserfs.c @@ -504,7 +504,6 @@ journal_init (void) desc.j_trans_id, desc.j_mount_id, desc_block); #endif - INFO->journal_transactions++; next_trans_id++; if (journal_table < JOURNAL_END) { @@ -549,7 +548,8 @@ journal_init (void) desc.j_trans_id, desc.j_mount_id, desc_block); #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; }