aboutsummaryrefslogtreecommitdiff
path: root/sbin/fsck_ifs
diff options
context:
space:
mode:
authorIan Dowse <iedowse@FreeBSD.org>2001-01-15 18:30:40 +0000
committerIan Dowse <iedowse@FreeBSD.org>2001-01-15 18:30:40 +0000
commitf55ff3f3efac63d2f4e5125ccdb454cc52f3eff1 (patch)
treed528333229386b8a7a7684fd3cf3be758d6a83cc /sbin/fsck_ifs
parent8fbaa337ac67eeed4c7729ef073413bb037fdc32 (diff)
downloadsrc-f55ff3f3efac63d2f4e5125ccdb454cc52f3eff1.tar.gz
src-f55ff3f3efac63d2f4e5125ccdb454cc52f3eff1.zip
The ffs superblock includes a 128-byte region for use by temporary
in-core pointers to summary information. An array in this region (fs_csp) could overflow on filesystems with a very large number of cylinder groups (~16000 on i386 with 8k blocks). When this happens, other fields in the superblock get corrupted, and fsck refuses to check the filesystem. Solve this problem by replacing the fs_csp array in 'struct fs' with a single pointer, and add padding to keep the length of the 128-byte region fixed. Update the kernel and userland utilities to use just this single pointer. With this change, the kernel no longer makes use of the superblock fields 'fs_csshift' and 'fs_csmask'. Add a comment to newfs/mkfs.c to indicate that these fields must be calculated for compatibility with older kernels. Reviewed by: mckusick
Notes
Notes: svn path=/head/; revision=71073
Diffstat (limited to 'sbin/fsck_ifs')
-rw-r--r--sbin/fsck_ifs/fsutil.c2
-rw-r--r--sbin/fsck_ifs/setup.c7
2 files changed, 5 insertions, 4 deletions
diff --git a/sbin/fsck_ifs/fsutil.c b/sbin/fsck_ifs/fsutil.c
index 2cdb25253b4b..2217f3c8a85b 100644
--- a/sbin/fsck_ifs/fsutil.c
+++ b/sbin/fsck_ifs/fsutil.c
@@ -249,7 +249,7 @@ flush(fd, bp)
if (bp != &sblk)
return;
for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) {
- bwrite(fswritefd, (char *)sblock.fs_csp[j],
+ bwrite(fswritefd, (char *)sblock.fs_csp + i,
fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag),
sblock.fs_cssize - i < sblock.fs_bsize ?
sblock.fs_cssize - i : sblock.fs_bsize);
diff --git a/sbin/fsck_ifs/setup.c b/sbin/fsck_ifs/setup.c
index b9c3148c8ba5..52fb8490e2fc 100644
--- a/sbin/fsck_ifs/setup.c
+++ b/sbin/fsck_ifs/setup.c
@@ -258,11 +258,11 @@ setup(dev)
* read in the summary info.
*/
asked = 0;
+ sblock.fs_csp = calloc(1, sblock.fs_cssize);
for (i = 0, j = 0; i < sblock.fs_cssize; i += sblock.fs_bsize, j++) {
size = sblock.fs_cssize - i < sblock.fs_bsize ?
sblock.fs_cssize - i : sblock.fs_bsize;
- sblock.fs_csp[j] = (struct csum *)calloc(1, (unsigned)size);
- if (bread(fsreadfd, (char *)sblock.fs_csp[j],
+ if (bread(fsreadfd, (char *)sblock.fs_csp + i,
fsbtodb(&sblock, sblock.fs_csaddr + j * sblock.fs_frag),
size) != 0 && !asked) {
pfatal("BAD SUMMARY INFORMATION");
@@ -382,7 +382,8 @@ readsb(listerr)
altsblock.fs_optim = sblock.fs_optim;
altsblock.fs_rotdelay = sblock.fs_rotdelay;
altsblock.fs_maxbpg = sblock.fs_maxbpg;
- memmove(altsblock.fs_csp, sblock.fs_csp, sizeof sblock.fs_csp);
+ memmove(altsblock.fs_ocsp, sblock.fs_ocsp, sizeof sblock.fs_ocsp);
+ altsblock.fs_csp = sblock.fs_csp;
altsblock.fs_maxcluster = sblock.fs_maxcluster;
memmove(altsblock.fs_fsmnt, sblock.fs_fsmnt, sizeof sblock.fs_fsmnt);
memmove(altsblock.fs_snapinum, sblock.fs_snapinum,