never upgrade the superblock or set FS_FLAGS_UPDATED in fs_old_flags

add compatibility for filesystems created before FFSv2 integration
these patches are from pr port-macppc/23926 and should also fix
problems discussed in pr kern/21404 and pr kern/21283
This commit is contained in:
dbj 2004-01-09 19:10:22 +00:00
parent 4aeba6790d
commit 01637061e3
3 changed files with 98 additions and 92 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs_alloc.c,v 1.72 2003/12/30 12:33:24 pk Exp $ */
/* $NetBSD: ffs_alloc.c,v 1.73 2004/01/09 19:10:22 dbj Exp $ */
/*
* Copyright (c) 2002 Networks Associates Technology, Inc.
@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ffs_alloc.c,v 1.72 2003/12/30 12:33:24 pk Exp $");
__KERNEL_RCSID(0, "$NetBSD: ffs_alloc.c,v 1.73 2004/01/09 19:10:22 dbj Exp $");
#if defined(_KERNEL_OPT)
#include "opt_ffs.h"
@ -1067,7 +1067,9 @@ ffs_fragextend(ip, cg, bprev, osize, nsize)
return (0);
}
cgp->cg_old_time = ufs_rw32(time.tv_sec, UFS_FSNEEDSWAP(fs));
cgp->cg_time = ufs_rw64(time.tv_sec, UFS_FSNEEDSWAP(fs));
if ((fs->fs_magic != FS_UFS1_MAGIC) ||
(fs->fs_old_flags & FS_FLAGS_UPDATED))
cgp->cg_time = ufs_rw64(time.tv_sec, UFS_FSNEEDSWAP(fs));
bno = dtogd(fs, bprev);
blksfree = cg_blksfree(cgp, UFS_FSNEEDSWAP(fs));
for (i = numfrags(fs, osize); i < frags; i++)
@ -1139,7 +1141,9 @@ ffs_alloccg(ip, cg, bpref, size)
return (0);
}
cgp->cg_old_time = ufs_rw32(time.tv_sec, needswap);
cgp->cg_time = ufs_rw64(time.tv_sec, needswap);
if ((fs->fs_magic != FS_UFS1_MAGIC) ||
(fs->fs_old_flags & FS_FLAGS_UPDATED))
cgp->cg_time = ufs_rw64(time.tv_sec, needswap);
if (size == fs->fs_bsize) {
blkno = ffs_alloccgblk(ip, bp, bpref);
bdwrite(bp);
@ -1257,6 +1261,14 @@ gotit:
ufs_add32(cgp->cg_cs.cs_nbfree, -1, needswap);
fs->fs_cstotal.cs_nbfree--;
fs->fs_cs(fs, ufs_rw32(cgp->cg_cgx, needswap)).cs_nbfree--;
if ((fs->fs_magic == FS_UFS1_MAGIC) &&
((fs->fs_old_flags & FS_FLAGS_UPDATED) == 0)) {
int cylno;
cylno = old_cbtocylno(fs, bno);
ufs_add16(old_cg_blks(fs, cgp, cylno, needswap)[old_cbtorpos(fs, bno)], -1,
needswap);
ufs_add32(old_cg_blktot(cgp, needswap)[cylno], -1, needswap);
}
fs->fs_fmod = 1;
blkno = ufs_rw32(cgp->cg_cgx, needswap) * fs->fs_fpg + bno;
if (DOINGSOFTDEP(ITOV(ip)))
@ -1424,7 +1436,9 @@ ffs_nodealloccg(ip, cg, ipref, mode)
return (0);
}
cgp->cg_old_time = ufs_rw32(time.tv_sec, needswap);
cgp->cg_time = ufs_rw64(time.tv_sec, needswap);
if ((fs->fs_magic != FS_UFS1_MAGIC) ||
(fs->fs_old_flags & FS_FLAGS_UPDATED))
cgp->cg_time = ufs_rw64(time.tv_sec, needswap);
inosused = cg_inosused(cgp, needswap);
if (ipref) {
ipref %= fs->fs_ipg;
@ -1547,7 +1561,9 @@ ffs_blkfree(ip, bno, size)
return;
}
cgp->cg_old_time = ufs_rw32(time.tv_sec, needswap);
cgp->cg_time = ufs_rw64(time.tv_sec, needswap);
if ((fs->fs_magic != FS_UFS1_MAGIC) ||
(fs->fs_old_flags & FS_FLAGS_UPDATED))
cgp->cg_time = ufs_rw64(time.tv_sec, needswap);
cgbno = dtogd(fs, bno);
blksfree = cg_blksfree(cgp, needswap);
if (size == fs->fs_bsize) {
@ -1562,6 +1578,13 @@ ffs_blkfree(ip, bno, size)
ufs_add32(cgp->cg_cs.cs_nbfree, 1, needswap);
fs->fs_cstotal.cs_nbfree++;
fs->fs_cs(fs, cg).cs_nbfree++;
if ((fs->fs_magic == FS_UFS1_MAGIC) &&
((fs->fs_old_flags & FS_FLAGS_UPDATED) == 0)) {
i = old_cbtocylno(fs, cgbno);
ufs_add16(old_cg_blks(fs, cgp, i, needswap)[old_cbtorpos(fs, cgbno)], 1,
needswap);
ufs_add32(old_cg_blktot(cgp, needswap)[i], 1, needswap);
}
} else {
bbase = cgbno - fragnum(fs, cgbno);
/*
@ -1602,6 +1625,13 @@ ffs_blkfree(ip, bno, size)
ufs_add32(cgp->cg_cs.cs_nbfree, 1, needswap);
fs->fs_cstotal.cs_nbfree++;
fs->fs_cs(fs, cg).cs_nbfree++;
if ((fs->fs_magic == FS_UFS1_MAGIC) &&
((fs->fs_old_flags & FS_FLAGS_UPDATED) == 0)) {
i = old_cbtocylno(fs, bbase);
ufs_add16(old_cg_blks(fs, cgp, i, needswap)[old_cbtorpos(fs,
bbase)], 1, needswap);
ufs_add32(old_cg_blktot(cgp, needswap)[i], 1, needswap);
}
}
}
fs->fs_fmod = 1;
@ -1722,7 +1752,9 @@ ffs_freefile(v)
return (0);
}
cgp->cg_old_time = ufs_rw32(time.tv_sec, needswap);
cgp->cg_time = ufs_rw64(time.tv_sec, needswap);
if ((fs->fs_magic != FS_UFS1_MAGIC) ||
(fs->fs_old_flags & FS_FLAGS_UPDATED))
cgp->cg_time = ufs_rw64(time.tv_sec, needswap);
inosused = cg_inosused(cgp, needswap);
ino %= fs->fs_ipg;
if (isclr(inosused, ino)) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs_vfsops.c,v 1.130 2003/12/04 19:38:25 atatat Exp $ */
/* $NetBSD: ffs_vfsops.c,v 1.131 2004/01/09 19:10:22 dbj Exp $ */
/*
* Copyright (c) 1989, 1991, 1993, 1994
@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.130 2003/12/04 19:38:25 atatat Exp $");
__KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.131 2004/01/09 19:10:22 dbj Exp $");
#if defined(_KERNEL_OPT)
#include "opt_ffs.h"
@ -491,10 +491,6 @@ ffs_reload(mountp, cred, p)
}
newfs = malloc(fs->fs_sbsize, M_UFSMNT, M_WAITOK);
memcpy(newfs, bp->b_data, fs->fs_sbsize);
#ifdef SUPPORT_42POSTBLFMT_WRITE
if (fs->fs_old_postblformat == FS_42POSTBLFMT)
memcpy(ump->um_opostsave, &newfs->fs_old_postbl_start, 256);
#endif
#ifdef FFS_EI
if (ump->um_flags & UFS_NEEDSWAP) {
ffs_sb_swap((struct fs*)bp->b_data, newfs);
@ -769,18 +765,6 @@ next_sblock:
memset(ump, 0, sizeof *ump);
ump->um_fs = fs;
if (fs->fs_old_postblformat == FS_42POSTBLFMT) {
#ifdef SUPPORT_FS_42POSTBLFMT_WRITE
ump->um_opostsave = malloc(256, M_UFSMNT, M_WAITOK);
memcpy(ump->um_opostsave, &fs->fs_old_postbl_start, 256);
#else
if ((mp->mnt_flag & MNT_RDONLY) == 0) {
error = EROFS;
goto out;
}
#endif
}
#ifdef FFS_EI
if (needswap) {
ffs_sb_swap((struct fs*)bp->b_data, fs);
@ -789,6 +773,8 @@ next_sblock:
#endif
fs->fs_flags &= ~FS_SWAPPED;
ffs_oldfscompat_read(fs, ump, sblockloc);
if (fs->fs_pendingblocks != 0 || fs->fs_pendinginodes != 0) {
fs->fs_pendingblocks = 0;
fs->fs_pendinginodes = 0;
@ -800,8 +786,6 @@ next_sblock:
brelse(bp);
bp = NULL;
ffs_oldfscompat_read(fs, ump, sblockloc);
/* First check to see if this is tagged as an Apple UFS filesystem
* in the disklabel
*/
@ -946,10 +930,8 @@ out:
(void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, cred, p);
VOP_UNLOCK(devvp, 0);
if (ump) {
#ifdef SUPPORT_FS_42POSTBLFMT_WRITE
if (ump->um_opostsave != NULL)
free(ump->um_opostsave, M_UFSMNT);
#endif
if (ump->um_oldfscompat)
free(ump->um_oldfscompat, M_UFSMNT);
free(ump, M_UFSMNT);
mp->mnt_data = NULL;
}
@ -970,38 +952,46 @@ ffs_oldfscompat_read(fs, ump, sblockloc)
daddr_t sblockloc;
{
off_t maxfilesize;
int old_ufs1;
int32_t *extrasave;
if (fs->fs_magic != FS_UFS1_MAGIC)
if ((fs->fs_magic != FS_UFS1_MAGIC) ||
(fs->fs_old_flags & FS_FLAGS_UPDATED))
return;
/*
* If not yet done, update UFS1 superblock with new wider fields,
* and update fs_flags location and value of fs_sblockloc.
*/
old_ufs1 = fs->fs_maxbsize != fs->fs_bsize;
if (old_ufs1) {
fs->fs_maxbsize = fs->fs_bsize;
fs->fs_time = fs->fs_old_time;
fs->fs_size = fs->fs_old_size;
fs->fs_dsize = fs->fs_old_dsize;
fs->fs_csaddr = fs->fs_old_csaddr;
fs->fs_sblockloc = sblockloc;
fs->fs_flags = fs->fs_old_flags;
fs->fs_old_flags |= FS_FLAGS_UPDATED;
}
if (!ump->um_oldfscompat)
ump->um_oldfscompat = malloc(512 + 3*sizeof(int32_t),
M_UFSMNT, M_WAITOK);
/*
* If the new fields haven't been set yet, or if the filesystem
* was mounted and modified by an old kernel, use the old csum
* totals, and update the flags
memcpy(ump->um_oldfscompat, &fs->fs_old_postbl_start, 512);
extrasave = ump->um_oldfscompat;
extrasave += 512/sizeof(int32_t);
extrasave[0] = fs->fs_old_npsect;
extrasave[1] = fs->fs_old_interleave;
extrasave[2] = fs->fs_old_trackskew;
/* These fields will be overwritten by their
* original values in fs_oldfscompat_write, so it is harmless
* to modify them here.
*/
if (old_ufs1 || fs->fs_time < fs->fs_old_time) {
fs->fs_cstotal.cs_ndir = fs->fs_old_cstotal.cs_ndir;
fs->fs_cstotal.cs_nbfree = fs->fs_old_cstotal.cs_nbfree;
fs->fs_cstotal.cs_nifree = fs->fs_old_cstotal.cs_nifree;
fs->fs_cstotal.cs_nffree = fs->fs_old_cstotal.cs_nffree;
fs->fs_flags |= (fs->fs_old_flags & ~FS_FLAGS_UPDATED);
fs->fs_cstotal.cs_ndir = fs->fs_old_cstotal.cs_ndir;
fs->fs_cstotal.cs_nbfree = fs->fs_old_cstotal.cs_nbfree;
fs->fs_cstotal.cs_nifree = fs->fs_old_cstotal.cs_nifree;
fs->fs_cstotal.cs_nffree = fs->fs_old_cstotal.cs_nffree;
fs->fs_maxbsize = fs->fs_bsize;
fs->fs_time = fs->fs_old_time;
fs->fs_size = fs->fs_old_size;
fs->fs_dsize = fs->fs_old_dsize;
fs->fs_csaddr = fs->fs_old_csaddr;
fs->fs_sblockloc = sblockloc;
fs->fs_flags = fs->fs_old_flags;
if (fs->fs_old_postblformat == FS_42POSTBLFMT) {
fs->fs_old_nrpos = 8;
fs->fs_old_npsect = fs->fs_old_nsect;
fs->fs_old_interleave = 1;
fs->fs_old_trackskew = 0;
}
if (fs->fs_old_inodefmt < FS_44INODEFMT) {
@ -1010,7 +1000,6 @@ ffs_oldfscompat_read(fs, ump, sblockloc)
fs->fs_qfmask = ~fs->fs_fmask;
}
ump->um_savedmaxfilesize = fs->fs_maxfilesize;
maxfilesize = (u_int64_t)0x80000000 * fs->fs_bsize - 1;
if (fs->fs_maxfilesize > maxfilesize)
fs->fs_maxfilesize = maxfilesize;
@ -1020,6 +1009,7 @@ ffs_oldfscompat_read(fs, ump, sblockloc)
fs->fs_avgfilesize = AVFILESIZ;
if (fs->fs_avgfpdir <= 0)
fs->fs_avgfpdir = AFPDIR;
#if 0
if (bigcgs) {
fs->fs_save_cgsize = fs->fs_cgsize;
@ -1040,38 +1030,32 @@ ffs_oldfscompat_write(fs, ump)
struct fs *fs;
struct ufsmount *ump;
{
if (fs->fs_magic != FS_UFS1_MAGIC)
return;
int32_t *extrasave;
/*
* if none of the newer flags are used, copy back fs_flags
* to fs_old_flags
*/
if ((fs->fs_flags & ~(FS_UNCLEAN|FS_DOSOFTDEP)) == 0)
fs->fs_old_flags = fs->fs_flags & (FS_UNCLEAN|FS_DOSOFTDEP);
/*
* OS X somehow still seems to use this field and panic.
* Just set it to zero.
*/
if (ump->um_flags & UFS_ISAPPLEUFS)
fs->fs_old_nrpos = 0;
/*
* Copy back UFS2 updated fields that UFS1 inspects.
*/
if ((fs->fs_magic != FS_UFS1_MAGIC) ||
(fs->fs_old_flags & FS_FLAGS_UPDATED))
return;
fs->fs_old_time = fs->fs_time;
fs->fs_old_cstotal.cs_ndir = fs->fs_cstotal.cs_ndir;
fs->fs_old_cstotal.cs_nbfree = fs->fs_cstotal.cs_nbfree;
fs->fs_old_cstotal.cs_nifree = fs->fs_cstotal.cs_nifree;
fs->fs_old_cstotal.cs_nffree = fs->fs_cstotal.cs_nffree;
fs->fs_maxfilesize = ump->um_savedmaxfilesize;
fs->fs_old_flags = fs->fs_flags;
#if 0
if (bigcgs) {
fs->fs_cgsize = fs->fs_save_cgsize;
fs->fs_save_cgsize = 0;
}
#endif
memcpy(&fs->fs_old_postbl_start, ump->um_oldfscompat, 512);
extrasave = ump->um_oldfscompat;
extrasave += 512/sizeof(int32_t);
fs->fs_old_npsect = extrasave[0];
fs->fs_old_interleave = extrasave[1];
fs->fs_old_trackskew = extrasave[2];
}
/*
@ -1131,10 +1115,8 @@ ffs_unmount(mp, mntflags, p)
vput(ump->um_devvp);
free(fs->fs_csp, M_UFSMNT);
free(fs, M_UFSMNT);
#ifdef SUPPORT_FS_42POSTBLFMT_WRITE
if (ump->um_opostsave != NULL)
free(ump->um_opostsave, M_UFSMNT);
#endif
if (ump->um_oldfscompat != NULL)
free(ump->um_oldfscompat, M_UFSMNT);
free(ump, M_UFSMNT);
mp->mnt_data = NULL;
mp->mnt_flag &= ~MNT_LOCAL;
@ -1604,11 +1586,6 @@ ffs_sbupdate(mp, waitfor)
#ifdef FFS_EI
if (mp->um_flags & UFS_NEEDSWAP)
ffs_sb_swap((struct fs *)bp->b_data, (struct fs *)bp->b_data);
#endif
#ifdef SUPPORT_FS_42POSTBLFMT_WRITE
if (fs->fs_old_postblformat == FS_42POSTBLFMT)
memcpy(&((struct fs *)bp->b_data)->fs_old_postbl_start,
mp->um_opostsave, 256);
#endif
fs->fs_flags |= saveflag;

View File

@ -1,4 +1,4 @@
/* $NetBSD: ufsmount.h,v 1.14 2003/08/07 16:34:48 agc Exp $ */
/* $NetBSD: ufsmount.h,v 1.15 2004/01/09 19:10:22 dbj Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@ -94,10 +94,7 @@ struct ufsmount {
time_t um_itime[MAXQUOTAS]; /* inode quota time limit */
char um_qflags[MAXQUOTAS]; /* quota specific flags */
struct netexport um_export; /* export information */
u_int64_t um_savedmaxfilesize; /* XXX - limit maxfilesize */
#ifdef SUPPORT_42POSTBLFMT_WRITE /* untested */
void *um_opostsave; /* save 4.2 rotbl */
#endif
void *um_oldfscompat; /* save 4.2 rotbl */
};
/* UFS-specific flags */