From d75f204b28cb3135261b939394bff5ad4151818f Mon Sep 17 00:00:00 2001 From: nyan Date: Thu, 27 Jan 2000 14:43:07 +0000 Subject: Supported non-512 bytes/sector format. PR: misc/12992 Submitted by: chi@bd.mbn.or.jp (Chiharu Shibata) and Dmitrij Tejblum Reviewed by: Dmitrij Tejblum --- sys/fs/msdosfs/msdosfs_denode.c | 2 +- sys/fs/msdosfs/msdosfs_fat.c | 5 +- sys/fs/msdosfs/msdosfs_vfsops.c | 117 +++++++++++++++++----------------------- sys/fs/msdosfs/msdosfsmount.h | 7 +++ 4 files changed, 61 insertions(+), 70 deletions(-) (limited to 'sys/fs/msdosfs') diff --git a/sys/fs/msdosfs/msdosfs_denode.c b/sys/fs/msdosfs/msdosfs_denode.c index d864ddb..ea82539 100644 --- a/sys/fs/msdosfs/msdosfs_denode.c +++ b/sys/fs/msdosfs/msdosfs_denode.c @@ -299,7 +299,7 @@ deget(pmp, dirclust, diroffset, depp) /* de_FileSize will be filled in further down */ else { ldep->de_StartCluster = MSDOSFSROOT; - ldep->de_FileSize = pmp->pm_rootdirsize * pmp->pm_BytesPerSec; + ldep->de_FileSize = pmp->pm_rootdirsize * DEV_BSIZE; } /* * fill in time and date so that dos2unixtime() doesn't diff --git a/sys/fs/msdosfs/msdosfs_fat.c b/sys/fs/msdosfs/msdosfs_fat.c index fae0027..1caad93 100644 --- a/sys/fs/msdosfs/msdosfs_fat.c +++ b/sys/fs/msdosfs/msdosfs_fat.c @@ -109,7 +109,7 @@ fatblock(pmp, ofs, bnp, sizep, bop) bn = ofs / pmp->pm_fatblocksize * pmp->pm_fatblocksec; size = min(pmp->pm_fatblocksec, pmp->pm_FATsecs - bn) - * pmp->pm_BytesPerSec; + * DEV_BSIZE; bn += pmp->pm_fatblk + pmp->pm_curfat * pmp->pm_FATsecs; if (bnp) @@ -364,7 +364,8 @@ updatefats(pmp, bp, fatbn) + ffs(pmp->pm_inusemap[cn / N_INUSEBITS] ^ (u_int)-1) - 1; } - if (bread(pmp->pm_devvp, pmp->pm_fsinfo, 1024, NOCRED, &bpn) != 0) { + if (bread(pmp->pm_devvp, pmp->pm_fsinfo, fsi_size(pmp), + NOCRED, &bpn) != 0) { /* * Ignore the error, but turn off FSInfo update for the future. */ diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c index 94578e8..3c7b6b3 100644 --- a/sys/fs/msdosfs/msdosfs_vfsops.c +++ b/sys/fs/msdosfs/msdosfs_vfsops.c @@ -69,6 +69,17 @@ #include #include +#if 1 /*def PC98*/ +/* + * XXX - The boot signature formatted by NEC PC-98 DOS looks like a + * garbage or a random value :-{ + * If you want to use that broken-signatured media, define the + * following symbol even though PC/AT. + * (ex. mount PC-98 DOS formatted FD on PC/AT) + */ +#define MSDOSFS_NOCHECKSIG +#endif + MALLOC_DEFINE(M_MSDOSFSMNT, "MSDOSFS mount", "MSDOSFS mount structure"); static MALLOC_DEFINE(M_MSDOSFSFAT, "MSDOSFS FAT", "MSDOSFS file allocation table"); @@ -423,12 +434,10 @@ mountmsdosfs(devvp, mp, p, argp) /* * Read the boot sector of the filesystem, and then check the * boot signature. If not a dos boot sector then error out. + * + * NOTE: 2048 is a maximum sector size in current... */ -#ifdef PC98 - error = bread(devvp, 0, 1024, NOCRED, &bp); -#else - error = bread(devvp, 0, 512, NOCRED, &bp); -#endif + error = bread(devvp, 0, 2048, NOCRED, &bp); if (error) goto error_exit; bp->b_flags |= B_AGE; @@ -440,22 +449,13 @@ mountmsdosfs(devvp, mp, p, argp) #ifndef __FreeBSD__ if (!(argp->flags & MSDOSFSMNT_GEMDOSFS)) { #endif -#ifdef PC98 - if ((bsp->bs50.bsBootSectSig0 != BOOTSIG0 - || bsp->bs50.bsBootSectSig1 != BOOTSIG1) - && (bsp->bs50.bsBootSectSig0 != 0 /* PC98 DOS 3.3x */ - || bsp->bs50.bsBootSectSig1 != 0) - && (bsp->bs50.bsBootSectSig0 != 0x90 /* PC98 DOS 5.0 */ - || bsp->bs50.bsBootSectSig1 != 0x3d) - && (bsp->bs50.bsBootSectSig0 != 0x46 /* PC98 DOS 3.3B */ - || bsp->bs50.bsBootSectSig1 != 0xfa)) { -#else +#ifndef MSDOSFS_NOCHECKSIG if (bsp->bs50.bsBootSectSig0 != BOOTSIG0 || bsp->bs50.bsBootSectSig1 != BOOTSIG1) { -#endif error = EINVAL; goto error_exit; } +#endif #ifndef __FreeBSD__ } #endif @@ -480,6 +480,9 @@ mountmsdosfs(devvp, mp, p, argp) pmp->pm_Heads = getushort(b50->bpbHeads); pmp->pm_Media = b50->bpbMedia; + /* calculate the ratio of sector size to DEV_BSIZE */ + pmp->pm_BlkPerSec = pmp->pm_BytesPerSec / DEV_BSIZE; + #ifndef __FreeBSD__ if (!(argp->flags & MSDOSFSMNT_GEMDOSFS)) { #endif @@ -538,67 +541,46 @@ mountmsdosfs(devvp, mp, p, argp) } else pmp->pm_flags |= MSDOSFS_FATMIRROR; -#ifndef __FreeBSD__ - if (argp->flags & MSDOSFSMNT_GEMDOSFS) { - if (FAT32(pmp)) { - /* - * GEMDOS doesn't know fat32. - */ - error = EINVAL; - 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 = 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; + /* + * 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 < DEV_BSIZE) + || (pmp->pm_BytesPerSec & (pmp->pm_BytesPerSec - 1)) + || (pmp->pm_HugeSectors == 0) + ) { + error = EINVAL; + goto error_exit; } -#endif - pmp->pm_fatblk = pmp->pm_ResSectors; + + pmp->pm_HugeSectors *= pmp->pm_BlkPerSec; + pmp->pm_HiddenSects *= pmp->pm_BlkPerSec; /* XXX not used? */ + pmp->pm_FATsecs *= pmp->pm_BlkPerSec; + SecPerClust *= pmp->pm_BlkPerSec; + + pmp->pm_fatblk = pmp->pm_ResSectors * pmp->pm_BlkPerSec; + if (FAT32(pmp)) { pmp->pm_rootdirblk = getulong(b710->bpbRootClust); pmp->pm_firstcluster = pmp->pm_fatblk + (pmp->pm_FATs * pmp->pm_FATsecs); - pmp->pm_fsinfo = getushort(b710->bpbFSInfo); + pmp->pm_fsinfo = getushort(b710->bpbFSInfo) * pmp->pm_BlkPerSec; } else { pmp->pm_rootdirblk = pmp->pm_fatblk + (pmp->pm_FATs * pmp->pm_FATsecs); pmp->pm_rootdirsize = (pmp->pm_RootDirEnts * sizeof(struct direntry) - + pmp->pm_BytesPerSec - 1) - / pmp->pm_BytesPerSec;/* in sectors */ + + DEV_BSIZE - 1) + / DEV_BSIZE; /* in blocks */ pmp->pm_firstcluster = pmp->pm_rootdirblk + pmp->pm_rootdirsize; } pmp->pm_maxcluster = (pmp->pm_HugeSectors - pmp->pm_firstcluster) / SecPerClust + 1; - pmp->pm_fatsize = pmp->pm_FATsecs * pmp->pm_BytesPerSec; + pmp->pm_fatsize = pmp->pm_FATsecs * DEV_BSIZE; /* XXX not used? */ #ifndef __FreeBSD__ if (argp->flags & MSDOSFSMNT_GEMDOSFS) { @@ -647,14 +629,14 @@ mountmsdosfs(devvp, mp, p, argp) else pmp->pm_fatblocksize = DFLTBSIZE; - pmp->pm_fatblocksec = pmp->pm_fatblocksize / pmp->pm_BytesPerSec; - pmp->pm_bnshift = ffs(pmp->pm_BytesPerSec) - 1; + pmp->pm_fatblocksec = pmp->pm_fatblocksize / DEV_BSIZE; + pmp->pm_bnshift = ffs(DEV_BSIZE) - 1; /* * Compute mask and shift value for isolating cluster relative byte * offsets and cluster numbers from a file offset. */ - pmp->pm_bpcluster = SecPerClust * pmp->pm_BytesPerSec; + pmp->pm_bpcluster = SecPerClust * DEV_BSIZE; pmp->pm_crbomask = pmp->pm_bpcluster - 1; pmp->pm_cnshift = ffs(pmp->pm_bpcluster) - 1; @@ -679,7 +661,8 @@ mountmsdosfs(devvp, mp, p, argp) if (pmp->pm_fsinfo) { struct fsinfo *fp; - if ((error = bread(devvp, pmp->pm_fsinfo, 1024, NOCRED, &bp)) != 0) + if ((error = bread(devvp, pmp->pm_fsinfo, fsi_size(pmp), + NOCRED, &bp)) != 0) goto error_exit; fp = (struct fsinfo *)bp->b_data; if (!bcmp(fp->fsisig1, "RRaA", 4) diff --git a/sys/fs/msdosfs/msdosfsmount.h b/sys/fs/msdosfs/msdosfsmount.h index 4b6ade1..59cc7c9 100644 --- a/sys/fs/msdosfs/msdosfsmount.h +++ b/sys/fs/msdosfs/msdosfsmount.h @@ -68,6 +68,7 @@ struct msdosfsmount { mode_t pm_mask; /* mask to and with file protection bits */ struct vnode *pm_devvp; /* vnode for block device mntd */ struct bpb50 pm_bpb; /* BIOS parameter blk for this fs */ + u_long pm_BlkPerSec; /* How many DEV_BSIZE blocks fit inside a physical sector */ u_long pm_FATsecs; /* actual number of fat sectors */ u_long pm_fatblk; /* block # of first FAT */ u_long pm_rootdirblk; /* block # (cluster # for FAT32) of root directory number */ @@ -190,6 +191,12 @@ struct msdosfsmount { ? roottobn((pmp), (dirofs)) \ : cntobn((pmp), (dirclu))) +/* + * Calculate fsinfo block size + */ +#define fsi_size(pmp) \ + (1024 << ((pmp)->pm_BlkPerSec >> 2)) + int msdosfs_init __P((struct vfsconf *vfsp)); int msdosfs_mountroot __P((void)); -- cgit v1.1