summaryrefslogtreecommitdiffstats
path: root/sys/fs
diff options
context:
space:
mode:
authornyan <nyan@FreeBSD.org>2000-01-27 14:43:07 +0000
committernyan <nyan@FreeBSD.org>2000-01-27 14:43:07 +0000
commitd75f204b28cb3135261b939394bff5ad4151818f (patch)
tree2c0fec431eddbd5efdb9ddad7a926078823bfd82 /sys/fs
parente3e26fd9df66637e335dad0fb303e80bd6d461b7 (diff)
downloadFreeBSD-src-d75f204b28cb3135261b939394bff5ad4151818f.zip
FreeBSD-src-d75f204b28cb3135261b939394bff5ad4151818f.tar.gz
Supported non-512 bytes/sector format.
PR: misc/12992 Submitted by: chi@bd.mbn.or.jp (Chiharu Shibata) and Dmitrij Tejblum <tejblum@arc.hq.cti.ru> Reviewed by: Dmitrij Tejblum <tejblum@arc.hq.cti.ru>
Diffstat (limited to 'sys/fs')
-rw-r--r--sys/fs/msdosfs/msdosfs_denode.c2
-rw-r--r--sys/fs/msdosfs/msdosfs_fat.c5
-rw-r--r--sys/fs/msdosfs/msdosfs_vfsops.c117
-rw-r--r--sys/fs/msdosfs/msdosfsmount.h7
4 files changed, 61 insertions, 70 deletions
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 <msdosfs/msdosfsmount.h>
#include <msdosfs/fat.h>
+#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));
OpenPOWER on IntegriCloud