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;