summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2010-01-25 10:57:19 -0800
committerH. Peter Anvin <hpa@zytor.com>2010-01-25 10:57:19 -0800
commit67cd8b349590cc0090dffc6ef7439378d8e71206 (patch)
tree7b9aed8557ec2ad5684ee46923a819a250fc34f9
parent313d29da0384a0420c80985da4ae6512525df798 (diff)
downloadsyslinux-67cd8b349590cc0090dffc6ef7439378d8e71206.tar.gz
core/fs: make it more explicit sector size is per filesystem
Sector size is per device, and can vary between filesystems. In particular, it is time to be getting rid of assumptions of 512-byte sectors whereever possible. Signed-off-by: H. Peter Anvin <hpa@zytor.com>
-rw-r--r--core/fs/ext2/ext2.c2
-rw-r--r--core/fs/fat/fat.c26
-rw-r--r--core/fs/fat/fat_fs.h9
-rw-r--r--core/fs/iso9660/iso9660.c8
-rw-r--r--core/include/disk.h3
-rw-r--r--core/include/fs.h10
6 files changed, 33 insertions, 25 deletions
diff --git a/core/fs/ext2/ext2.c b/core/fs/ext2/ext2.c
index 9d4d9ec5..01f32f84 100644
--- a/core/fs/ext2/ext2.c
+++ b/core/fs/ext2/ext2.c
@@ -439,6 +439,8 @@ static int ext2_fs_init(struct fs_info *fs)
fs->sector_shift = disk->sector_shift;
fs->block_shift = sb.s_log_block_size + 10;
+ fs->sector_size = 1 << fs->sector_shift;
+ fs->block_size = 1 << fs->block_shift;
sbi->s_inodes_per_group = sb.s_inodes_per_group;
sbi->s_blocks_per_group = sb.s_blocks_per_group;
diff --git a/core/fs/fat/fat.c b/core/fs/fat/fat.c
index 2ffc303a..c89ed78a 100644
--- a/core/fs/fat/fat.c
+++ b/core/fs/fat/fat.c
@@ -51,14 +51,15 @@ static uint32_t get_next_cluster(struct fs_info *fs, uint32_t clust_num)
uint32_t offset;
int lo, hi;
struct cache_struct *cs;
+ uint32_t sector_mask = SECTOR_SIZE(fs) - 1;
switch(FAT_SB(fs)->fat_type) {
case FAT12:
offset = clust_num + (clust_num >> 1);
- fat_sector = offset >> SECTOR_SHIFT;
- offset &= (1 << SECTOR_SHIFT) - 1;
+ fat_sector = offset >> SECTOR_SHIFT(fs);
+ offset &= sector_mask;
cs = get_fat_sector(fs, fat_sector);
- if (offset == (1 << SECTOR_SHIFT)-1) {
+ if (offset == sector_mask) {
/*
* we got the end of the one fat sector,
* but we have just one byte and we need two,
@@ -80,15 +81,15 @@ static uint32_t get_next_cluster(struct fs_info *fs, uint32_t clust_num)
break;
case FAT16:
- fat_sector = clust_num >> (SECTOR_SHIFT - 1);
- offset = clust_num & ((1 << (SECTOR_SHIFT-1)) -1);
+ fat_sector = clust_num >> (SECTOR_SHIFT(fs) - 1);
+ offset = clust_num & sector_mask;
cs = get_fat_sector(fs, fat_sector);
next_cluster = ((uint16_t *)cs->data)[offset];
break;
case FAT32:
- fat_sector = clust_num >> (SECTOR_SHIFT - 2);
- offset = clust_num & ((1 << (SECTOR_SHIFT-2)) -1);
+ fat_sector = clust_num >> (SECTOR_SHIFT(fs) - 2);
+ offset = clust_num & sector_mask;
cs = get_fat_sector(fs, fat_sector);
next_cluster = ((uint32_t *)cs->data)[offset] & 0x0fffffff;
break;
@@ -141,7 +142,7 @@ static sector_t get_next_sector(struct fs_info* fs, uint32_t sector)
static sector_t get_the_right_sector(struct file *file)
{
int i = 0;
- int sector_pos = file->offset >> SECTOR_SHIFT;
+ int sector_pos = file->offset >> SECTOR_SHIFT(file->fs);
sector_t sector = *file->inode->data;
for (; i < sector_pos; i++)
@@ -192,7 +193,7 @@ static void __getfssec(struct fs_info *fs, char *buf,
/* do read */
disk->rdwr_sectors(disk, buf, frag_start, con_sec_cnt, 0);
- buf += con_sec_cnt << SECTOR_SHIFT;/* adjust buffer pointer */
+ buf += con_sec_cnt << SECTOR_SHIFT(fs);/* adjust buffer pointer */
if (!sectors)
break;
@@ -544,6 +545,8 @@ static struct dirent * vfat_readdir(struct file *file)
cs = get_cache_block(fs->fs_dev, sector);
de = (struct fat_dir_entry *)(cs->data + sec_off);
entries_left = ((1 << fs->sector_shift) - sec_off) >> 5;
+
+ vfat_next = vfat_csum = 0xff;
while (1) {
while(entries_left--) {
@@ -709,6 +712,9 @@ static int vfat_fs_init(struct fs_info *fs)
sector_t total_sectors;
fs->sector_shift = fs->block_shift = disk->sector_shift;
+ fs->sector_size = 1 << fs->sector_shift;
+ fs->block_size = 1 << fs->block_shift;
+
disk->rdwr_sectors(disk, &fat, 0, 1, 0);
sbi = malloc(sizeof(*sbi));
@@ -722,7 +728,7 @@ static int vfat_fs_init(struct fs_info *fs)
sbi->fat = fat.bxResSectors;
sbi->root = sbi->fat + sectors_per_fat * fat.bxFATs;
- sbi->root_size = root_dir_size(&fat);
+ sbi->root_size = root_dir_size(fs, &fat);
sbi->data = sbi->root + sbi->root_size;
sbi->clust_shift = bsr(fat.bxSecPerClust);
diff --git a/core/fs/fat/fat_fs.h b/core/fs/fat/fat_fs.h
index 8d441e34..30bde32c 100644
--- a/core/fs/fat/fat_fs.h
+++ b/core/fs/fat/fat_fs.h
@@ -135,13 +135,10 @@ static inline struct fat_sb_info *FAT_SB(struct fs_info *fs)
/*
* Count the root dir size in sectors
*/
-static inline int root_dir_size(struct fat_bpb *fat)
+static inline int root_dir_size(struct fs_info *fs, struct fat_bpb *fat)
{
- int sector_size = 1 << SECTOR_SHIFT;
-
- return (fat->bxRootDirEnts + sector_size / sizeof(struct fat_dir_entry)
- - 1) >> (SECTOR_SHIFT - 5);
+ return (fat->bxRootDirEnts + SECTOR_SIZE(fs)/32 - 1)
+ >> (SECTOR_SHIFT(fs) - 5);
}
-
#endif /* fat_fs.h */
diff --git a/core/fs/iso9660/iso9660.c b/core/fs/iso9660/iso9660.c
index 1670e607..dc9d0906 100644
--- a/core/fs/iso9660/iso9660.c
+++ b/core/fs/iso9660/iso9660.c
@@ -438,8 +438,12 @@ static int iso_fs_init(struct fs_info *fs)
cdrom_read_blocks(fs->fs_dev->disk, trackbuf, 16, 1);
memcpy(&sbi->root, trackbuf + ROOT_DIR_OFFSET, sizeof(sbi->root));
-
- fs->block_shift = 11;
+
+ fs->sector_shift = fs->fs_dev->disk->sector_shift;
+ fs->block_shift = 11;
+ fs->sector_size = 1 << fs->sector_shift;
+ fs->block_size = 1 << fs->block_shift;
+
return fs->block_shift;
}
diff --git a/core/include/disk.h b/core/include/disk.h
index 55d24fbc..da6555ae 100644
--- a/core/include/disk.h
+++ b/core/include/disk.h
@@ -5,12 +5,9 @@
#include <stdint.h>
#include <stdbool.h>
-#define SECTOR_SHIFT 9
-
typedef uint64_t sector_t;
typedef uint64_t block_t;
-
/*
* struct disk: contains the information about a specific disk and also
* contains the I/O function.
diff --git a/core/include/fs.h b/core/include/fs.h
index c6f9bca2..c90c2152 100644
--- a/core/include/fs.h
+++ b/core/include/fs.h
@@ -21,15 +21,17 @@
#define FILENAME_MAX_LG2 8
#define FILENAME_MAX (1 << FILENAME_MAX_LG2)
-#define BLOCK_SIZE(fs) (1 << fs->block_shift)
-#define SECTOR_SIZE(fs) (1 << fs->sector_shift)
+#define BLOCK_SIZE(fs) ((fs)->block_size)
+#define BLOCK_SHIFT(fs) ((fs)->block_shift)
+#define SECTOR_SIZE(fs) ((fs)->sector_size)
+#define SECTOR_SHIFT(fs) ((fs)->sector_shift)
struct fs_info {
const struct fs_ops *fs_ops;
struct device *fs_dev;
void *fs_info; /* The fs-specific information */
- int sector_shift;
- int block_shift;
+ int sector_shift, sector_size;
+ int block_shift, block_size;
};
extern struct fs_info *this_fs;