summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorbp <bp@FreeBSD.org>1999-12-28 15:27:39 +0000
committerbp <bp@FreeBSD.org>1999-12-28 15:27:39 +0000
commit7b78445d14a1cb269afaf69f0d3184074ddc08f6 (patch)
tree9f145b79fd165aba7bf1959568d9fa581995c7a2 /sys
parent91e396f1556284c9b116cc39647735407acc41c5 (diff)
downloadFreeBSD-src-7b78445d14a1cb269afaf69f0d3184074ddc08f6.zip
FreeBSD-src-7b78445d14a1cb269afaf69f0d3184074ddc08f6.tar.gz
It is possible that number of sectors specified in the BPB
will exceed FAT capacity. This will lead to kernel panic while other systems just limit number of clusters. PR: 4381, 15136 Reviewed by: phk
Diffstat (limited to 'sys')
-rw-r--r--sys/fs/msdosfs/msdosfs_vfsops.c19
-rw-r--r--sys/fs/msdosfs/msdosfsmount.h1
-rw-r--r--sys/msdosfs/msdosfs_vfsops.c19
-rw-r--r--sys/msdosfs/msdosfsmount.h1
4 files changed, 28 insertions, 12 deletions
diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c
index 4af4cf3..13272af 100644
--- a/sys/fs/msdosfs/msdosfs_vfsops.c
+++ b/sys/fs/msdosfs/msdosfs_vfsops.c
@@ -364,6 +364,7 @@ mountmsdosfs(devvp, mp, p, argp)
struct byte_bpb50 *b50;
struct byte_bpb710 *b710;
u_int8_t SecPerClust;
+ u_long clusters;
int ronly, error;
/*
@@ -595,14 +596,13 @@ mountmsdosfs(devvp, mp, p, argp)
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_maxcluster = (pmp->pm_HugeSectors - pmp->pm_firstcluster) /
+ SecPerClust + 1;
pmp->pm_fatsize = pmp->pm_FATsecs * pmp->pm_BytesPerSec;
#ifndef __FreeBSD__
if (argp->flags & MSDOSFSMNT_GEMDOSFS) {
- if ((pmp->pm_nmbrofclusters <= (0xff0 - 2))
+ if ((pmp->pm_maxcluster <= (0xff0 - 2))
&& ((dtype == DTYPE_FLOPPY) || ((dtype == DTYPE_VNODE)
&& ((pmp->pm_Heads == 1) || (pmp->pm_Heads == 2))))
) {
@@ -633,6 +633,15 @@ mountmsdosfs(devvp, mp, p, argp)
pmp->pm_fatdiv = 1;
}
}
+
+ clusters = (pmp->pm_fatsize / pmp->pm_fatmult) * pmp->pm_fatdiv;
+ if (pmp->pm_maxcluster >= clusters) {
+ printf("Warning: number of clusters (%ld) exceeds FAT "
+ "capacity (%ld)\n", pmp->pm_maxcluster + 1, clusters);
+ pmp->pm_maxcluster = clusters - 1;
+ }
+
+
if (FAT12(pmp))
pmp->pm_fatblocksize = 3 * pmp->pm_BytesPerSec;
else
@@ -829,7 +838,7 @@ msdosfs_statfs(mp, sbp, p)
pmp = VFSTOMSDOSFS(mp);
sbp->f_bsize = pmp->pm_bpcluster;
sbp->f_iosize = pmp->pm_bpcluster;
- sbp->f_blocks = pmp->pm_nmbrofclusters;
+ sbp->f_blocks = pmp->pm_maxcluster + 1;
sbp->f_bfree = pmp->pm_freeclustercount;
sbp->f_bavail = pmp->pm_freeclustercount;
sbp->f_files = pmp->pm_RootDirEnts; /* XXX */
diff --git a/sys/fs/msdosfs/msdosfsmount.h b/sys/fs/msdosfs/msdosfsmount.h
index 6bd6551..a8c2e5b 100644
--- a/sys/fs/msdosfs/msdosfsmount.h
+++ b/sys/fs/msdosfs/msdosfsmount.h
@@ -73,7 +73,6 @@ struct msdosfsmount {
u_long pm_rootdirblk; /* block # (cluster # for FAT32) of root directory number */
u_long pm_rootdirsize; /* size in blocks (not clusters) */
u_long pm_firstcluster; /* block number of first cluster */
- u_long pm_nmbrofclusters; /* # of clusters in filesystem */
u_long pm_maxcluster; /* maximum cluster number */
u_long pm_freeclustercount; /* number of free clusters */
u_long pm_cnshift; /* shift file offset right this amount to get a cluster number */
diff --git a/sys/msdosfs/msdosfs_vfsops.c b/sys/msdosfs/msdosfs_vfsops.c
index 4af4cf3..13272af 100644
--- a/sys/msdosfs/msdosfs_vfsops.c
+++ b/sys/msdosfs/msdosfs_vfsops.c
@@ -364,6 +364,7 @@ mountmsdosfs(devvp, mp, p, argp)
struct byte_bpb50 *b50;
struct byte_bpb710 *b710;
u_int8_t SecPerClust;
+ u_long clusters;
int ronly, error;
/*
@@ -595,14 +596,13 @@ mountmsdosfs(devvp, mp, p, argp)
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_maxcluster = (pmp->pm_HugeSectors - pmp->pm_firstcluster) /
+ SecPerClust + 1;
pmp->pm_fatsize = pmp->pm_FATsecs * pmp->pm_BytesPerSec;
#ifndef __FreeBSD__
if (argp->flags & MSDOSFSMNT_GEMDOSFS) {
- if ((pmp->pm_nmbrofclusters <= (0xff0 - 2))
+ if ((pmp->pm_maxcluster <= (0xff0 - 2))
&& ((dtype == DTYPE_FLOPPY) || ((dtype == DTYPE_VNODE)
&& ((pmp->pm_Heads == 1) || (pmp->pm_Heads == 2))))
) {
@@ -633,6 +633,15 @@ mountmsdosfs(devvp, mp, p, argp)
pmp->pm_fatdiv = 1;
}
}
+
+ clusters = (pmp->pm_fatsize / pmp->pm_fatmult) * pmp->pm_fatdiv;
+ if (pmp->pm_maxcluster >= clusters) {
+ printf("Warning: number of clusters (%ld) exceeds FAT "
+ "capacity (%ld)\n", pmp->pm_maxcluster + 1, clusters);
+ pmp->pm_maxcluster = clusters - 1;
+ }
+
+
if (FAT12(pmp))
pmp->pm_fatblocksize = 3 * pmp->pm_BytesPerSec;
else
@@ -829,7 +838,7 @@ msdosfs_statfs(mp, sbp, p)
pmp = VFSTOMSDOSFS(mp);
sbp->f_bsize = pmp->pm_bpcluster;
sbp->f_iosize = pmp->pm_bpcluster;
- sbp->f_blocks = pmp->pm_nmbrofclusters;
+ sbp->f_blocks = pmp->pm_maxcluster + 1;
sbp->f_bfree = pmp->pm_freeclustercount;
sbp->f_bavail = pmp->pm_freeclustercount;
sbp->f_files = pmp->pm_RootDirEnts; /* XXX */
diff --git a/sys/msdosfs/msdosfsmount.h b/sys/msdosfs/msdosfsmount.h
index 6bd6551..a8c2e5b 100644
--- a/sys/msdosfs/msdosfsmount.h
+++ b/sys/msdosfs/msdosfsmount.h
@@ -73,7 +73,6 @@ struct msdosfsmount {
u_long pm_rootdirblk; /* block # (cluster # for FAT32) of root directory number */
u_long pm_rootdirsize; /* size in blocks (not clusters) */
u_long pm_firstcluster; /* block number of first cluster */
- u_long pm_nmbrofclusters; /* # of clusters in filesystem */
u_long pm_maxcluster; /* maximum cluster number */
u_long pm_freeclustercount; /* number of free clusters */
u_long pm_cnshift; /* shift file offset right this amount to get a cluster number */
OpenPOWER on IntegriCloud