When compiling a 32-bit version of dosfstools on an x86_64 machine,
the resulting applications report strange errors on "large" (> 2 GiB) partitions: Seek to -2118967808:Invalid argument Warning: Filesystem is FAT32 according to fat_length and fat32_length fields, but has only 8613 clusters, less than the required minimum of 65525. This may lead to problems on some systems. This appears to be due to compilation with a 32-bit off_t and lseek() library function. Use lseek64 for positioning, and change some suspect uses of off_t to loff_t. Signed-off-by: Daniel Baumann <mail@daniel-baumann.ch>
This commit is contained in:
parent
bbb25bf11a
commit
a5961d7344
16
src/boot.c
16
src/boot.c
@ -167,7 +167,7 @@ static void check_backup_boot(DOS_FS *fs, struct boot_sector *b, int lss)
|
|||||||
fs->backupboot_start = bbs*lss;
|
fs->backupboot_start = bbs*lss;
|
||||||
b->backup_boot = CT_LE_W(bbs);
|
b->backup_boot = CT_LE_W(bbs);
|
||||||
fs_write(fs->backupboot_start,sizeof(*b),b);
|
fs_write(fs->backupboot_start,sizeof(*b),b);
|
||||||
fs_write((off_t)offsetof(struct boot_sector,backup_boot),
|
fs_write((loff_t)offsetof(struct boot_sector,backup_boot),
|
||||||
sizeof(b->backup_boot),&b->backup_boot);
|
sizeof(b->backup_boot),&b->backup_boot);
|
||||||
printf( "Created backup of boot sector in sector %d\n", bbs );
|
printf( "Created backup of boot sector in sector %d\n", bbs );
|
||||||
return;
|
return;
|
||||||
@ -242,9 +242,9 @@ static void read_fsinfo(DOS_FS *fs, struct boot_sector *b,int lss)
|
|||||||
if (s != CF_LE_W(b->backup_boot)) break;
|
if (s != CF_LE_W(b->backup_boot)) break;
|
||||||
if (s > 0 && s < CF_LE_W(b->reserved)) {
|
if (s > 0 && s < CF_LE_W(b->reserved)) {
|
||||||
init_fsinfo(&i);
|
init_fsinfo(&i);
|
||||||
fs_write((off_t)s*lss,sizeof(i),&i);
|
fs_write((loff_t)s*lss,sizeof(i),&i);
|
||||||
b->info_sector = CT_LE_W(s);
|
b->info_sector = CT_LE_W(s);
|
||||||
fs_write((off_t)offsetof(struct boot_sector,info_sector),
|
fs_write((loff_t)offsetof(struct boot_sector,info_sector),
|
||||||
sizeof(b->info_sector),&b->info_sector);
|
sizeof(b->info_sector),&b->info_sector);
|
||||||
if (fs->backupboot_start)
|
if (fs->backupboot_start)
|
||||||
fs_write(fs->backupboot_start+
|
fs_write(fs->backupboot_start+
|
||||||
@ -299,7 +299,7 @@ void read_boot(DOS_FS *fs)
|
|||||||
unsigned total_sectors;
|
unsigned total_sectors;
|
||||||
unsigned short logical_sector_size, sectors;
|
unsigned short logical_sector_size, sectors;
|
||||||
unsigned fat_length;
|
unsigned fat_length;
|
||||||
off_t data_size;
|
loff_t data_size;
|
||||||
|
|
||||||
fs_read(0,sizeof(b),&b);
|
fs_read(0,sizeof(b),&b);
|
||||||
logical_sector_size = GET_UNALIGNED_W(b.sector_size);
|
logical_sector_size = GET_UNALIGNED_W(b.sector_size);
|
||||||
@ -321,17 +321,17 @@ void read_boot(DOS_FS *fs)
|
|||||||
total_sectors = sectors ? sectors : CF_LE_L(b.total_sect);
|
total_sectors = sectors ? sectors : CF_LE_L(b.total_sect);
|
||||||
if (verbose) printf("Checking we can access the last sector of the filesystem\n");
|
if (verbose) printf("Checking we can access the last sector of the filesystem\n");
|
||||||
/* Can't access last odd sector anyway, so round down */
|
/* Can't access last odd sector anyway, so round down */
|
||||||
fs_test((off_t)((total_sectors & ~1)-1)*(off_t)logical_sector_size,
|
fs_test((loff_t)((total_sectors & ~1)-1)*(loff_t)logical_sector_size,
|
||||||
logical_sector_size);
|
logical_sector_size);
|
||||||
fat_length = CF_LE_W(b.fat_length) ?
|
fat_length = CF_LE_W(b.fat_length) ?
|
||||||
CF_LE_W(b.fat_length) : CF_LE_L(b.fat32_length);
|
CF_LE_W(b.fat_length) : CF_LE_L(b.fat32_length);
|
||||||
fs->fat_start = (off_t)CF_LE_W(b.reserved)*logical_sector_size;
|
fs->fat_start = (loff_t)CF_LE_W(b.reserved)*logical_sector_size;
|
||||||
fs->root_start = ((off_t)CF_LE_W(b.reserved)+b.fats*fat_length)*
|
fs->root_start = ((loff_t)CF_LE_W(b.reserved)+b.fats*fat_length)*
|
||||||
logical_sector_size;
|
logical_sector_size;
|
||||||
fs->root_entries = GET_UNALIGNED_W(b.dir_entries);
|
fs->root_entries = GET_UNALIGNED_W(b.dir_entries);
|
||||||
fs->data_start = fs->root_start+ROUND_TO_MULTIPLE(fs->root_entries <<
|
fs->data_start = fs->root_start+ROUND_TO_MULTIPLE(fs->root_entries <<
|
||||||
MSDOS_DIR_BITS,logical_sector_size);
|
MSDOS_DIR_BITS,logical_sector_size);
|
||||||
data_size = (off_t)total_sectors*logical_sector_size-fs->data_start;
|
data_size = (loff_t)total_sectors*logical_sector_size-fs->data_start;
|
||||||
fs->clusters = data_size/fs->cluster_size;
|
fs->clusters = data_size/fs->cluster_size;
|
||||||
fs->root_cluster = 0; /* indicates standard, pre-FAT32 root dir */
|
fs->root_cluster = 0; /* indicates standard, pre-FAT32 root dir */
|
||||||
fs->fsinfo_start = 0; /* no FSINFO structure */
|
fs->fsinfo_start = 0; /* no FSINFO structure */
|
||||||
|
|||||||
10
src/io.c
10
src/io.c
@ -29,6 +29,8 @@
|
|||||||
/* FAT32, VFAT, Atari format support, and various fixes additions May 1998
|
/* FAT32, VFAT, Atari format support, and various fixes additions May 1998
|
||||||
* by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */
|
* by Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> */
|
||||||
|
|
||||||
|
#define _LARGEFILE64_SOURCE
|
||||||
|
#include <sys/types.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -60,8 +62,7 @@ unsigned device_no;
|
|||||||
|
|
||||||
#ifdef __DJGPP__
|
#ifdef __DJGPP__
|
||||||
#include "volume.h" /* DOS lowlevel disk access functions */
|
#include "volume.h" /* DOS lowlevel disk access functions */
|
||||||
#undef llseek
|
loff_t llseek(int fd, loff_t offset, int whence)
|
||||||
static loff_t llseek( int fd, loff_t offset, int whence )
|
|
||||||
{
|
{
|
||||||
if ((whence != SEEK_SET) || (fd == 4711)) return -1; /* only those supported */
|
if ((whence != SEEK_SET) || (fd == 4711)) return -1; /* only those supported */
|
||||||
return VolumeSeek(offset);
|
return VolumeSeek(offset);
|
||||||
@ -70,6 +71,11 @@ static loff_t llseek( int fd, loff_t offset, int whence )
|
|||||||
#define close CloseVolume
|
#define close CloseVolume
|
||||||
#define read(a,b,c) ReadVolume(b,c)
|
#define read(a,b,c) ReadVolume(b,c)
|
||||||
#define write(a,b,c) WriteVolume(b,c)
|
#define write(a,b,c) WriteVolume(b,c)
|
||||||
|
#else
|
||||||
|
loff_t llseek(int fd, loff_t offset, int whence)
|
||||||
|
{
|
||||||
|
return (loff_t) lseek64(fd, (off64_t)offset, whence);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void fs_open(char *path,int rw)
|
void fs_open(char *path,int rw)
|
||||||
|
|||||||
6
src/io.h
6
src/io.h
@ -29,9 +29,9 @@
|
|||||||
|
|
||||||
#include <sys/types.h> /* for loff_t */
|
#include <sys/types.h> /* for loff_t */
|
||||||
|
|
||||||
/* In earlier versions, an own llseek() was used, but glibc lseek() is
|
loff_t llseek(int fd, loff_t offset, int whence);
|
||||||
* sufficient (or even better :) for 64 bit offsets in the meantime */
|
|
||||||
#define llseek lseek
|
/* lseek() analogue for large offsets. */
|
||||||
|
|
||||||
void fs_open(char *path,int rw);
|
void fs_open(char *path,int rw);
|
||||||
|
|
||||||
|
|||||||
@ -538,7 +538,7 @@ valid_offset (int fd, loff_t offset)
|
|||||||
static unsigned long long
|
static unsigned long long
|
||||||
count_blocks (char *filename)
|
count_blocks (char *filename)
|
||||||
{
|
{
|
||||||
off_t high, low;
|
loff_t high, low;
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
if ((fd = open (filename, O_RDONLY)) < 0)
|
if ((fd = open (filename, O_RDONLY)) < 0)
|
||||||
@ -1731,7 +1731,7 @@ main (int argc, char **argv)
|
|||||||
die ("unable to open %s");
|
die ("unable to open %s");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
off_t offset = blocks*BLOCK_SIZE - 1;
|
loff_t offset = blocks*BLOCK_SIZE - 1;
|
||||||
char null = 0;
|
char null = 0;
|
||||||
/* create the file */
|
/* create the file */
|
||||||
dev = open( device_name, O_EXCL|O_RDWR|O_CREAT|O_TRUNC, 0666 );
|
dev = open( device_name, O_EXCL|O_RDWR|O_CREAT|O_TRUNC, 0666 );
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user