On Wed, Dec 06, 2006 at 04:44:32AM +0000, Mikolaj Kucharski wrote: > On Tue, Dec 05, 2006 at 09:27:39PM -0700, Chris Kuethe wrote: > > On 12/5/06, Mikolaj Kucharski <[EMAIL PROTECTED]> wrote: > > >sd0 at scsibus1 targ 1 lun 0: <Apple, iPod, 1.62> SCSI0 0/direct removable > > >sd0: 76319MB, 19079 cyl, 64 head, 32 sec, 2048 bytes/sec, 39075372 sec > > >total > > > > 80GB. Maybe it's one of the ipods with 2K sectors. Look in the > > archives for an experimental patch to possibly make this work. > > It looks like perfect answer. Thanks. > > http://marc.theaimsgroup.com/?t=116345681100004&r=1&w=2
I used all patches from thread above (sd, msdosfs, and fdisk patch) and iPod and fdisk are working like a charm. Thanks! $ sysctl -n kern.version OpenBSD 4.0-current (ACPI) #8: Wed Dec 6 03:34:00 MST 2006 [EMAIL PROTECTED]:/usr/src/sys/arch/i386/compile/ACPI Patches attached in this mail too. -- best regards q# Index: sbin/fdisk/cmd.c =================================================================== RCS file: /cvs/src/sbin/fdisk/cmd.c,v retrieving revision 1.42 diff -u -r1.42 cmd.c --- sbin/fdisk/cmd.c 2006/07/27 04:06:13 1.42 +++ sbin/fdisk/cmd.c 2006/12/06 18:34:36 @@ -46,7 +46,7 @@ char buf[DEV_BSIZE]; /* Copy template MBR */ - MBR_make(tt, buf); + MBR_make(tt, buf, disk->real->sec_size); MBR_parse(disk, buf, mbr->offset, mbr->reloffset, mbr); MBR_init(disk, mbr); @@ -321,8 +321,8 @@ printf("Writing MBR at offset %d.\n", offset); fd = DISK_open(disk->name, O_RDWR); - MBR_make(mbr, mbr_buf); - if (MBR_write(fd, offset, mbr_buf) != -1) + MBR_make(mbr, mbr_buf, disk->real->sec_size); + if (MBR_write(fd, offset, mbr_buf, disk->real->sec_size) != -1) ret = CMD_CLEAN; close(fd); return (ret); Index: sbin/fdisk/disk.c =================================================================== RCS file: /cvs/src/sbin/fdisk/disk.c,v retrieving revision 1.25 diff -u -r1.25 disk.c --- sbin/fdisk/disk.c 2006/11/19 20:17:12 1.25 +++ sbin/fdisk/disk.c 2006/12/06 18:34:36 @@ -99,11 +99,21 @@ lm->heads = dl.d_ntracks; lm->sectors = dl.d_nsectors; lm->size = dl.d_secperunit; + lm->sec_size = dl.d_secsize; unit_types[SECTORS].conversion = dl.d_secsize; } DISK_close(fd); } + if (lm && lm->sec_size != 512 && lm->sec_size != 1024 && + lm->sec_size != 2048 && lm->sec_size != 4096 && + lm->sec_size != 8192) { + + warnx("Invalid sector size %d, setting to %d", lm->sec_size, + DEV_BSIZE); + lm->sec_size = DEV_BSIZE; + } + return (lm); } @@ -157,6 +167,7 @@ bm->heads = di.bios_heads; bm->sectors = di.bios_sectors; bm->size = di.bios_cylinders * di.bios_heads * di.bios_sectors; + bm->sec_size = DEV_BSIZE; return (bm); } #else @@ -187,6 +198,13 @@ disk->label = DISK_getlabelmetrics(disk->name); disk->bios = DISK_getbiosmetrics(disk->name); + /* + * If we have a disklabel, the kernel tells us what size sector + * this raw device has. As such, use it. Yes, not pretty. + */ + if (disk->label && disk->bios) + disk->bios->sec_size = disk->label->sec_size; + /* If user supplied, use that */ if (user) { disk->real = user; @@ -236,11 +254,12 @@ size = ((double)disk->real->size * unit_types[SECTORS].conversion) / unit_types[i].conversion; printf("Disk: %s\t", disk->name); - if (disk->real) - printf("geometry: %d/%d/%d [%.0f %s]\n", disk->real->cylinders, + if (disk->real) { + printf("geometry: %d/%d/%d [%.0f %s] ", disk->real->cylinders, disk->real->heads, disk->real->sectors, size, unit_types[i].lname); - else + printf("(%d byte sectors)\n", disk->real->sec_size); + } else printf("geometry: <none>\n"); return (0); Index: sbin/fdisk/disk.h =================================================================== RCS file: /cvs/src/sbin/fdisk/disk.h,v retrieving revision 1.8 diff -u -r1.8 disk.h --- sbin/fdisk/disk.h 2004/08/03 09:22:03 1.8 +++ sbin/fdisk/disk.h 2006/12/06 18:34:36 @@ -34,6 +34,7 @@ u_int32_t heads; u_int32_t sectors; u_int32_t size; + u_int32_t sec_size; } DISK_metrics; typedef struct _disk_t { Index: sbin/fdisk/fdisk.c =================================================================== RCS file: /cvs/src/sbin/fdisk/fdisk.c,v retrieving revision 1.46 diff -u -r1.46 fdisk.c --- sbin/fdisk/fdisk.c 2006/11/09 00:01:10 1.46 +++ sbin/fdisk/fdisk.c 2006/12/06 18:34:43 @@ -78,8 +78,10 @@ char *mbrfile = NULL; #endif mbr_t mbr; - char mbr_buf[DEV_BSIZE]; + char mbr_buf[MBR_MAX_SIZE]; + memset(mbr_buf, 0, sizeof(mbr_buf)); + while ((ch = getopt(argc, argv, "ieuf:c:h:s:y")) != -1) { const char *errstr; @@ -160,9 +162,9 @@ mbrfile == NULL; } if (mbrfile == NULL) { - memcpy(mbr_buf, builtin_mbr, sizeof(mbr_buf)); + memcpy(mbr_buf, builtin_mbr, DEV_BSIZE); } else { - MBR_read(fd, 0, mbr_buf); + MBR_read(fd, 0, mbr_buf, DEV_BSIZE); close(fd); } MBR_parse(&disk, mbr_buf, 0, 0, &mbr); Index: sbin/fdisk/mbr.c =================================================================== RCS file: /cvs/src/sbin/fdisk/mbr.c,v retrieving revision 1.22 diff -u -r1.22 mbr.c --- sbin/fdisk/mbr.c 2006/05/29 05:09:36 1.22 +++ sbin/fdisk/mbr.c 2006/12/06 18:34:43 @@ -97,6 +97,7 @@ mbr->offset = offset; mbr->reloffset = reloff; mbr->signature = getshort(&mbr_buf[MBR_SIG_OFF]); + memcpy(mbr->rest, mbr_buf+DEV_BSIZE, disk->real->sec_size - DEV_BSIZE); for (i = 0; i < NDOSPART; i++) PRT_parse(disk, &mbr_buf[MBR_PART_OFF + MBR_PART_SIZE * i], @@ -104,12 +105,13 @@ } void -MBR_make(mbr_t *mbr, char *mbr_buf) +MBR_make(mbr_t *mbr, char *mbr_buf, int size) { int i; memcpy(mbr_buf, mbr->code, MBR_CODE_SIZE); putshort(&mbr_buf[MBR_SIG_OFF], mbr->signature); + memcpy(mbr_buf+DEV_BSIZE, mbr->rest, size - DEV_BSIZE); for (i = 0; i < NDOSPART; i++) PRT_make(&mbr->part[i], mbr->offset, mbr->reloffset, @@ -132,19 +134,19 @@ } int -MBR_read(int fd, off_t where, char *buf) +MBR_read(int fd, off_t where, char *buf, int size) { off_t off; ssize_t len; - where *= DEV_BSIZE; + where *= size; off = lseek(fd, where, SEEK_SET); if (off != where) return (-1); - len = read(fd, buf, DEV_BSIZE); + len = read(fd, buf, size); if (len == -1) return (-1); - if (len != DEV_BSIZE) { + if (len != size) { /* short read */ errno = EIO; return (-1); @@ -153,19 +155,19 @@ } int -MBR_write(int fd, off_t where, char *buf) +MBR_write(int fd, off_t where, char *buf, int size) { off_t off; ssize_t len; - where *= DEV_BSIZE; + where *= size; off = lseek(fd, where, SEEK_SET); if (off != where) return (-1); - len = write(fd, buf, DEV_BSIZE); + len = write(fd, buf, size); if (len == -1) return (-1); - if (len != DEV_BSIZE) { + if (len != size) { /* short write */ errno = EIO; return (-1); @@ -182,11 +184,12 @@ MBR_pcopy(disk_t *disk, mbr_t *mbr) { int i, fd, offset = 0, reloff = 0; + int size = disk->real->sec_size; mbr_t mbrd; - char mbr_disk[DEV_BSIZE]; + char mbr_disk[size]; fd = DISK_open(disk->name, O_RDONLY); - MBR_read(fd, offset, mbr_disk); + MBR_read(fd, offset, mbr_disk, size); DISK_close(fd); MBR_parse(disk, mbr_disk, offset, reloff, &mbrd); for (i = 0; i < NDOSPART; i++) { Index: sbin/fdisk/mbr.h =================================================================== RCS file: /cvs/src/sbin/fdisk/mbr.h,v retrieving revision 1.11 diff -u -r1.11 mbr.h --- sbin/fdisk/mbr.h 2003/06/03 01:13:19 1.11 +++ sbin/fdisk/mbr.h 2006/12/06 18:34:43 @@ -28,6 +28,7 @@ #ifndef _MBR_H #define _MBR_H +#include <machine/param.h> #include "part.h" /* Various constants */ @@ -35,8 +36,8 @@ #define MBR_PART_SIZE 0x10 #define MBR_PART_OFF 0x1BE #define MBR_SIG_OFF 0x1FE +#define MBR_MAX_SIZE 8192 - /* MBR type */ typedef struct _mbr_t { off_t reloffset; @@ -44,16 +45,17 @@ unsigned char code[MBR_CODE_SIZE]; prt_t part[NDOSPART]; unsigned short signature; + unsigned char rest[MBR_MAX_SIZE-DEV_BSIZE]; } mbr_t; /* Prototypes */ void MBR_print_disk(char *); void MBR_print(mbr_t *, char *); void MBR_parse(disk_t *, char *, off_t, off_t, mbr_t *); -void MBR_make(mbr_t *, char *); +void MBR_make(mbr_t *, char *, int); void MBR_init(disk_t *, mbr_t *); -int MBR_read(int, off_t, char *); -int MBR_write(int, off_t, char *); +int MBR_read(int, off_t, char *, int); +int MBR_write(int, off_t, char *, int); void MBR_pcopy(disk_t *, mbr_t *); /* Sanity check */ Index: sbin/fdisk/user.c =================================================================== RCS file: /cvs/src/sbin/fdisk/user.c,v retrieving revision 1.23 diff -u -r1.23 user.c --- sbin/fdisk/user.c 2006/07/27 04:06:13 1.23 +++ sbin/fdisk/user.c 2006/12/06 18:34:43 @@ -68,7 +68,7 @@ USER_init(disk_t *disk, mbr_t *tt, int preserve) { int fd, yn; - char mbr_buf[DEV_BSIZE]; + char mbr_buf[MBR_MAX_SIZE]; char *msgp = "\nDo you wish to write new MBR?"; char *msgk = "\nDo you wish to write new MBR and partition table?"; @@ -89,8 +89,8 @@ if (yn) { fd = DISK_open(disk->name, O_RDWR); - MBR_make(tt, mbr_buf); - if (MBR_write(fd, 0, mbr_buf) == -1) { + MBR_make(tt, mbr_buf, disk->real->sec_size); + if (MBR_write(fd, 0, mbr_buf, disk->real->sec_size) == -1) { int saved_errno = errno; DISK_close(fd); errno = saved_errno; @@ -109,7 +109,7 @@ USER_modify(disk_t *disk, mbr_t *tt, off_t offset, off_t reloff) { static int editlevel; - char mbr_buf[DEV_BSIZE]; + char mbr_buf[MBR_MAX_SIZE]; mbr_t mbr; cmd_t cmd; int i, st, fd; @@ -122,7 +122,7 @@ /* Read MBR & partition */ fd = DISK_open(disk->name, O_RDONLY); - MBR_read(fd, offset, mbr_buf); + MBR_read(fd, offset, mbr_buf, disk->real->sec_size); DISK_close(fd); /* Parse the sucker */ @@ -173,8 +173,8 @@ if (st == CMD_SAVE) { printf("Writing current MBR to disk.\n"); fd = DISK_open(disk->name, O_RDWR); - MBR_make(&mbr, mbr_buf); - if (MBR_write(fd, offset, mbr_buf) == -1) { + MBR_make(&mbr, mbr_buf, disk->real->sec_size); + if (MBR_write(fd, offset, mbr_buf, disk->real->sec_size) == -1) { warn("error writing MBR"); close(fd); goto again; @@ -193,8 +193,8 @@ int USER_print_disk(disk_t *disk) { - int fd, offset, firstoff, i; - char mbr_buf[DEV_BSIZE]; + int fd, offset, firstoff, i, st = 0; + char mbr_buf[MBR_MAX_SIZE]; mbr_t mbr; fd = DISK_open(disk->name, O_RDONLY); @@ -203,7 +203,9 @@ DISK_printmetrics(disk, NULL); do { - MBR_read(fd, (off_t)offset, mbr_buf); + st = MBR_read(fd, (off_t)offset, mbr_buf, disk->real->sec_size); + if (st == -1) + err(1, "MBR_read"); MBR_parse(disk, mbr_buf, offset, firstoff, &mbr); printf("Offset: %d\t", (int)offset); Index: sys/msdosfs/bpb.h =================================================================== RCS file: /cvs/src/sys/msdosfs/bpb.h,v retrieving revision 1.4 diff -u -r1.4 bpb.h --- sys/msdosfs/bpb.h 2005/09/28 20:53:56 1.4 +++ sys/msdosfs/bpb.h 2006/12/06 18:36:22 @@ -204,6 +204,4 @@ u_int8_t fsinxtfree[4]; u_int8_t fsifill2[12]; u_int8_t fsisig3[4]; - u_int8_t fsifill3[508]; - u_int8_t fsisig4[4]; }; Index: sys/msdosfs/msdosfs_vfsops.c =================================================================== RCS file: /cvs/src/sys/msdosfs/msdosfs_vfsops.c,v retrieving revision 1.42 diff -u -r1.42 msdosfs_vfsops.c --- sys/msdosfs/msdosfs_vfsops.c 2006/11/29 13:35:07 1.42 +++ sys/msdosfs/msdosfs_vfsops.c 2006/12/06 18:36:28 @@ -272,7 +272,7 @@ u_int8_t SecPerClust; int ronly, error, bmapsiz; int bsize = 0, dtype = 0, tmp; - uint32_t dirsperblk; + u_int32_t n_rootsec, n_datasec; /* * Disallow multiple mounts of the same device. @@ -298,6 +298,29 @@ bp = NULL; /* both used in error_exit */ pmp = NULL; + /* + * We need to know sector size of the disk because bread() + * will fail if we try to read not N * secsize + * According to Microsoft documentations (fatget103.pdf) + * allowed sector sizes are 512, 1024, 2048, 4096. + */ + error = VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, NOCRED, p); + if (error) + goto error_exit; + + bsize = dpart.disklab->d_secsize; + switch (bsize) { + case 512: + case 1024: + case 2048: + case 4096: + break; + + default: + error = EINVAL; + goto error_exit; + } + if (argp->flags & MSDOSFSMNT_GEMDOSFS) { /* * We need the disklabel to calculate the size of a FAT entry @@ -309,13 +332,8 @@ * that the size of a disk block will always be 512 bytes. * Let's check it... */ - error = VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, - FREAD, NOCRED, p); - if (error) - goto error_exit; tmp = dpart.part->p_fstype; dtype = dpart.disklab->d_type; - bsize = dpart.disklab->d_secsize; if (bsize != 512 || (dtype!=DTYPE_FLOPPY && tmp!=FS_MSDOS)) { error = EFTYPE; goto error_exit; @@ -324,9 +342,9 @@ /* * Read the boot sector of the filesystem, and then check the - * boot signature. If not a dos boot sector then error out. + * boot signature. If not a dos boot sector then error out. */ - if ((error = bread(devvp, 0, 512, NOCRED, &bp)) != 0) + if ((error = bread(devvp, 0, bsize, NOCRED, &bp)) != 0) goto error_exit; bp->b_flags |= B_AGE; bsp = (union bootsector *)bp->b_data; @@ -343,54 +361,79 @@ * bootsector. Copy in the dos 5 variant of the bpb then fix up * the fields that are different between dos 5 and dos 3.3. */ - SecPerClust = b50->bpbSecPerClust; + pmp->pm_BytesPerSec = getushort(b50->bpbBytesPerSec); + if (pmp->pm_BytesPerSec != bsize) { + printf("msdosfs_mountfs: " + "disk block size != FAT's BytesPerSector\n"); + error = EINVAL; + goto error_exit; + } + + SecPerClust = b50->bpbSecPerClust; pmp->pm_ResSectors = getushort(b50->bpbResSectors); pmp->pm_FATs = b50->bpbFATs; pmp->pm_RootDirEnts = getushort(b50->bpbRootDirEnts); - pmp->pm_Sectors = getushort(b50->bpbSectors); - pmp->pm_FATsecs = getushort(b50->bpbFATsecs); pmp->pm_SecPerTrack = getushort(b50->bpbSecPerTrack); pmp->pm_Heads = getushort(b50->bpbHeads); pmp->pm_Media = b50->bpbMedia; + pmp->pm_HiddenSects = getulong(b50->bpbHiddenSecs); - if (!(argp->flags & MSDOSFSMNT_GEMDOSFS)) { - if (!pmp->pm_BytesPerSec || !SecPerClust - || pmp->pm_SecPerTrack > 63) { - error = EFTYPE; - goto error_exit; - } + if (SecPerClust == 0 || + (SecPerClust & (SecPerClust - 1)) != 0 || pmp->pm_ResSectors == 0) { + error = EFTYPE; + goto error_exit; } - if (pmp->pm_Sectors == 0) { - pmp->pm_HiddenSects = getulong(b50->bpbHiddenSecs); - pmp->pm_HugeSectors = getulong(b50->bpbHugeSectors); - } else { - pmp->pm_HiddenSects = getushort(b33->bpbHiddenSecs); - pmp->pm_HugeSectors = pmp->pm_Sectors; - } + pmp->pm_totalsecs = getushort(b33->bpbSectors); + if (pmp->pm_totalsecs == 0) + pmp->pm_totalsecs = getulong(b50->bpbHugeSectors); - dirsperblk = pmp->pm_BytesPerSec / sizeof(struct direntry); + pmp->pm_FATsecs = getushort(b33->bpbFATsecs); + if (pmp->pm_FATsecs == 0) + pmp->pm_FATsecs = getulong(b710->bpbBigFATsecs); - if (pmp->pm_RootDirEnts == 0) { - if (pmp->pm_Sectors || pmp->pm_FATsecs || - getushort(b710->bpbFSVers)) { - error = EINVAL; + if (pmp->pm_totalsecs == 0 || pmp->pm_FATsecs == 0 || + pmp->pm_totalsecs > dpart.part->p_size) { + printf("msdosfs_mountfs: partition is probably damaged\n"); + error = EFTYPE; + goto error_exit; + } + + if (!(argp->flags & MSDOSFSMNT_GEMDOSFS)) { + if (pmp->pm_SecPerTrack > 63) { + error = EFTYPE; goto error_exit; } - pmp->pm_fatmask = FAT32_MASK; - pmp->pm_fatmult = 4; + } + + /* + * Determine FAT type, according to Microsoft documentations + * (fatgen103.pdf, p.14). + */ + n_rootsec = ((pmp->pm_RootDirEnts * 32) + pmp->pm_BytesPerSec - 1) / + pmp->pm_BytesPerSec; + n_datasec = pmp->pm_totalsecs - + (pmp->pm_ResSectors + pmp->pm_FATsecs * pmp->pm_FATs + n_rootsec); + pmp->pm_nmbrofclusters = n_datasec / SecPerClust; + + if (pmp->pm_nmbrofclusters < 4085) { + /* FAT12 */ + pmp->pm_fatmask = FAT12_MASK; + pmp->pm_fatmult = 3; + pmp->pm_fatdiv = 2; + + pmp->pm_flags |= MSDOSFS_FATMIRROR; + } else if (pmp->pm_nmbrofclusters < 65525) { + /* FAT16 */ + pmp->pm_fatmask = FAT16_MASK; + pmp->pm_fatmult = 2; pmp->pm_fatdiv = 1; - pmp->pm_FATsecs = getulong(b710->bpbBigFATsecs); - if (getushort(b710->bpbExtFlags) & FATMIRROR) - pmp->pm_curfat = getushort(b710->bpbExtFlags) & FATNUM; - else - pmp->pm_flags |= MSDOSFS_FATMIRROR; - } else - pmp->pm_flags |= MSDOSFS_FATMIRROR; - if (argp->flags & MSDOSFSMNT_GEMDOSFS) { - if (FAT32(pmp)) { + pmp->pm_flags |= MSDOSFS_FATMIRROR; + } else { + /* FAT32 */ + if (argp->flags & MSDOSFSMNT_GEMDOSFS) { /* * GEMDOS doesn't know fat32. */ @@ -398,44 +441,29 @@ goto error_exit; } - /* - * Check a few values (could do some more): - * - logical sector size: power of 2, >= block size - * - sectors per cluster: power of 2, >= 1 - * - number of sectors: >= 1, <= size of partition - */ - if ( (SecPerClust == 0) - || (SecPerClust & (SecPerClust - 1)) - || (pmp->pm_BytesPerSec < bsize) - || (pmp->pm_BytesPerSec & (pmp->pm_BytesPerSec - 1)) - || (pmp->pm_HugeSectors == 0) - || (pmp->pm_HugeSectors * (pmp->pm_BytesPerSec / bsize) - > dpart.part->p_size) - ) { - error = EFTYPE; + pmp->pm_fatmask = FAT32_MASK; + pmp->pm_fatmult = 4; + pmp->pm_fatdiv = 1; + + /* Respect FAT32's version */ + if (getushort(b710->bpbFSVers) != 0) { + error = EINVAL; goto error_exit; } - /* - * XXX - Many parts of the msdos fs driver seem to assume that - * the number of bytes per logical sector (BytesPerSec) will - * always be the same as the number of bytes per disk block - * Let's pretend it is. - */ - tmp = pmp->pm_BytesPerSec / bsize; - pmp->pm_BytesPerSec = bsize; - pmp->pm_HugeSectors *= tmp; - pmp->pm_HiddenSects *= tmp; - pmp->pm_ResSectors *= tmp; - pmp->pm_Sectors *= tmp; - pmp->pm_FATsecs *= tmp; - SecPerClust *= tmp; + + if (getushort(b710->bpbExtFlags) & FATMIRROR) + pmp->pm_curfat = getushort(b710->bpbExtFlags) & FATNUM; + else + pmp->pm_flags |= MSDOSFS_FATMIRROR; + + pmp->pm_fsinfo = getushort(b710->bpbFSInfo); } + pmp->pm_fatblk = pmp->pm_ResSectors; if (FAT32(pmp)) { - pmp->pm_rootdirblk = getulong(b710->bpbRootClust); + pmp->pm_rootdirblk = getulong(b710->bpbRootClust); pmp->pm_firstcluster = pmp->pm_fatblk + (pmp->pm_FATs * pmp->pm_FATsecs); - pmp->pm_fsinfo = getushort(b710->bpbFSInfo); } else { pmp->pm_rootdirblk = pmp->pm_fatblk + (pmp->pm_FATs * pmp->pm_FATsecs); @@ -445,8 +473,6 @@ pmp->pm_firstcluster = pmp->pm_rootdirblk + pmp->pm_rootdirsize; } - pmp->pm_nmbrofclusters = (pmp->pm_HugeSectors - pmp->pm_firstcluster) / - SecPerClust; pmp->pm_maxcluster = pmp->pm_nmbrofclusters + 1; pmp->pm_fatsize = pmp->pm_FATsecs * pmp->pm_BytesPerSec; @@ -459,27 +485,12 @@ pmp->pm_fatmult = 3; pmp->pm_fatdiv = 2; } else { - pmp->pm_fatmask = FAT16_MASK; - pmp->pm_fatmult = 2; - pmp->pm_fatdiv = 1; - } - } else if (pmp->pm_fatmask == 0) { - if (pmp->pm_maxcluster - <= ((CLUST_RSRVD - CLUST_FIRST) & FAT12_MASK)) { - /* - * This will usually be a floppy disk. This size makes - * sure that one fat entry will not be split across - * multiple blocks. - */ - pmp->pm_fatmask = FAT12_MASK; - pmp->pm_fatmult = 3; - pmp->pm_fatdiv = 2; - } else { pmp->pm_fatmask = FAT16_MASK; pmp->pm_fatmult = 2; pmp->pm_fatdiv = 1; } } + if (FAT12(pmp)) pmp->pm_fatblocksize = 3 * pmp->pm_BytesPerSec; else @@ -514,16 +525,15 @@ /* * Check FSInfo */ - if (pmp->pm_fsinfo) { + if (pmp->pm_fsinfo > 0) { struct fsinfo *fp; - if ((error = bread(devvp, pmp->pm_fsinfo, 1024, NOCRED, &bp)) != 0) + if ((error = bread(devvp, pmp->pm_fsinfo, bsize, NOCRED, &bp)) != 0) goto error_exit; fp = (struct fsinfo *)bp->b_data; if (!bcmp(fp->fsisig1, "RRaA", 4) && !bcmp(fp->fsisig2, "rrAa", 4) - && !bcmp(fp->fsisig3, "\0\0\125\252", 4) - && !bcmp(fp->fsisig4, "\0\0\125\252", 4)) + && !bcmp(fp->fsisig3, "\0\0\125\252", 4)) pmp->pm_nxtfree = getulong(fp->fsinxtfree); else pmp->pm_fsinfo = 0; Index: sys/msdosfs/msdosfsmount.h =================================================================== RCS file: /cvs/src/sys/msdosfs/msdosfsmount.h,v retrieving revision 1.16 diff -u -r1.16 msdosfsmount.h --- sys/msdosfs/msdosfsmount.h 2004/05/14 04:05:05 1.16 +++ sys/msdosfs/msdosfsmount.h 2006/12/06 18:36:28 @@ -60,6 +60,9 @@ struct vnode *pm_devvp; /* vnode for block device mntd */ struct bpb50 pm_bpb; /* BIOS parameter blk for this fs */ uint32_t pm_FATsecs; /* actual number of fat sectors */ + + u_int32_t pm_totalsecs; /* amount of sectors in the volume */ + uint32_t pm_fatblk; /* block # of first FAT */ uint32_t pm_rootdirblk; /* block # (cluster # for FAT32) of root directory number */ uint32_t pm_rootdirsize; /* size in blocks (not clusters) */ @@ -120,12 +123,10 @@ #define pm_ResSectors pm_bpb.bpbResSectors #define pm_FATs pm_bpb.bpbFATs #define pm_RootDirEnts pm_bpb.bpbRootDirEnts -#define pm_Sectors pm_bpb.bpbSectors #define pm_Media pm_bpb.bpbMedia #define pm_SecPerTrack pm_bpb.bpbSecPerTrack #define pm_Heads pm_bpb.bpbHeads #define pm_HiddenSects pm_bpb.bpbHiddenSecs -#define pm_HugeSectors pm_bpb.bpbHugeSectors /* * Convert pointer to buffer -> pointer to direntry Index: sys/scsi/sd.c =================================================================== RCS file: /cvs/src/sys/scsi/sd.c,v retrieving revision 1.114 diff -u -r1.114 sd.c --- sys/scsi/sd.c 2006/11/28 16:56:50 1.114 +++ sys/scsi/sd.c 2006/12/06 18:36:44 @@ -659,12 +659,8 @@ /* * We have a buf, now we should make a command - * - * First, translate the block to absolute and put it in terms - * of the logical blocksize of the device. */ - blkno = - bp->b_blkno / (sd->sc_dk.dk_label->d_secsize / DEV_BSIZE); + blkno = bp->b_blkno; if (SDPART(bp->b_dev) != RAW_PART) { p = &sd->sc_dk.dk_label->d_partitions[SDPART(bp->b_dev)]; blkno += p->p_offset;