Create a new 32-bit fs_flags word in the superblock. Add code to move
the old 8-bit fs_old_flags to the new location the first time that the filesystem is mounted by a new kernel. One of the unused flags in fs_old_flags is used to indicate that the flags have been moved. Leave the fs_old_flags word intact so that it will work properly if used on an old kernel. Change the fs_sblockloc superblock location field to be in units of bytes instead of in units of filesystem fragments. The old units did not work properly when the fragment size exceeeded the superblock size (8192). Update old fs_sblockloc values at the same time that the flags are moved. Suggested by: BOUWSMA Barry <freebsd-misuser@netscum.dyndns.dk> Sponsored by: DARPA & NAI Labs.
This commit is contained in:
parent
bd32b70236
commit
ada981b228
@ -67,7 +67,7 @@ sbread(struct uufsd *disk)
|
||||
if (fs->fs_magic == FS_UFS1_MAGIC)
|
||||
disk->d_ufs = 1;
|
||||
if ((fs->fs_magic == FS_UFS2_MAGIC) &&
|
||||
(fs->fs_sblockloc == numfrags(fs, superblock)))
|
||||
(fs->fs_sblockloc == superblock))
|
||||
disk->d_ufs = 2;
|
||||
if ((fs->fs_bsize <= MAXBSIZE) &&
|
||||
(fs->fs_bsize >= sizeof(*fs))) {
|
||||
|
@ -144,7 +144,7 @@ main(int argc, char *argv[])
|
||||
rdfs(sblock_try[i] / dev_bsize, SBLOCKSIZE, (char *)fs);
|
||||
if ((fs->fs_magic == FS_UFS1_MAGIC ||
|
||||
(fs->fs_magic == FS_UFS2_MAGIC &&
|
||||
fs->fs_sblockloc == numfrags(fs, sblock_try[i]))) &&
|
||||
fs->fs_sblockloc == sblock_try[i])) &&
|
||||
fs->fs_bsize <= MAXBSIZE &&
|
||||
fs->fs_bsize >= sizeof(struct fs))
|
||||
break;
|
||||
|
@ -102,7 +102,7 @@ main(int argc, char *argv[])
|
||||
sbp = (struct fs *)sblock;
|
||||
if ((sbp->fs_magic == FS_UFS1_MAGIC ||
|
||||
(sbp->fs_magic == FS_UFS2_MAGIC &&
|
||||
sbp->fs_sblockloc == numfrags(sbp, sblock_try[i]))) &&
|
||||
sbp->fs_sblockloc == sblock_try[i])) &&
|
||||
sbp->fs_bsize <= MAXBSIZE &&
|
||||
sbp->fs_bsize >= (int)sizeof(struct fs))
|
||||
break;
|
||||
|
@ -350,8 +350,7 @@ main(int argc, char *argv[])
|
||||
bread(sblock_try[i] >> dev_bshift, (char *) sblock, SBLOCKSIZE);
|
||||
if ((sblock->fs_magic == FS_UFS1_MAGIC ||
|
||||
(sblock->fs_magic == FS_UFS2_MAGIC &&
|
||||
sblock->fs_sblockloc ==
|
||||
numfrags(sblock, sblock_try[i]))) &&
|
||||
sblock->fs_sblockloc == sblock_try[i])) &&
|
||||
sblock->fs_bsize <= MAXBSIZE &&
|
||||
sblock->fs_bsize >= sizeof(struct fs))
|
||||
break;
|
||||
|
@ -130,7 +130,7 @@ dumpfs(const char *name)
|
||||
time = afs.fs_time;
|
||||
printf("magic\t%x (UFS2)\ttime\t%s",
|
||||
afs.fs_magic, ctime(&time));
|
||||
printf("offset\t%qd\tid\t[ %x %x ]\n",
|
||||
printf("superblock location\t%qd\tid\t[ %x %x ]\n",
|
||||
afs.fs_sblockloc, afs.fs_id[0], afs.fs_id[1]);
|
||||
printf("ncg\t%d\tsize\t%qd\tblocks\t%d\n",
|
||||
afs.fs_ncg, fssize, afs.fs_dsize);
|
||||
|
@ -296,9 +296,9 @@ ckfini(int markclean)
|
||||
}
|
||||
flush(fswritefd, &sblk);
|
||||
if (havesb && cursnapshot == 0 && sblock.fs_magic == FS_UFS2_MAGIC &&
|
||||
sblk.b_bno != fsbtodb(&sblock, sblock.fs_sblockloc) &&
|
||||
sblk.b_bno != sblock.fs_sblockloc / dev_bsize &&
|
||||
!preen && reply("UPDATE STANDARD SUPERBLOCK")) {
|
||||
sblk.b_bno = fsbtodb(&sblock, sblock.fs_sblockloc);
|
||||
sblk.b_bno = sblock.fs_sblockloc / dev_bsize;
|
||||
sbdirty();
|
||||
flush(fswritefd, &sblk);
|
||||
}
|
||||
|
@ -313,8 +313,7 @@ readsb(int listerr)
|
||||
return (0);
|
||||
if ((sblock.fs_magic == FS_UFS1_MAGIC ||
|
||||
(sblock.fs_magic == FS_UFS2_MAGIC &&
|
||||
sblock.fs_sblockloc ==
|
||||
numfrags(&sblock, sblock_try[i]))) &&
|
||||
sblock.fs_sblockloc == sblock_try[i])) &&
|
||||
sblock.fs_ncg >= 1 &&
|
||||
sblock.fs_bsize >= MINBSIZE &&
|
||||
sblock.fs_bsize >= sizeof(struct fs))
|
||||
|
@ -152,8 +152,7 @@ fsirand(char *device)
|
||||
}
|
||||
if ((sblock->fs_magic == FS_UFS1_MAGIC ||
|
||||
(sblock->fs_magic == FS_UFS2_MAGIC &&
|
||||
sblock->fs_sblockloc ==
|
||||
numfrags(sblock, sblock_try[i]))) &&
|
||||
sblock->fs_sblockloc == sblock_try[i])) &&
|
||||
sblock->fs_bsize <= MAXBSIZE &&
|
||||
sblock->fs_bsize >= sizeof(struct fs))
|
||||
break;
|
||||
|
@ -2048,8 +2048,7 @@ main(int argc, char **argv)
|
||||
rdfs(sblockloc, (size_t)SBLOCKSIZE, (void *)&(osblock), fsi);
|
||||
if ((osblock.fs_magic == FS_UFS1_MAGIC ||
|
||||
(osblock.fs_magic == FS_UFS2_MAGIC &&
|
||||
osblock.fs_sblockloc ==
|
||||
numfrags(&osblock, sblock_try[i]))) &&
|
||||
osblock.fs_sblockloc == sblock_try[i])) &&
|
||||
osblock.fs_bsize <= MAXBSIZE &&
|
||||
osblock.fs_bsize >= sizeof(struct fs))
|
||||
break;
|
||||
|
@ -149,6 +149,7 @@ mkfs(struct partition *pp, char *fsys)
|
||||
exit(38);
|
||||
}
|
||||
bzero(iobuf, iobufsize);
|
||||
sblock.fs_old_flags = FS_FLAGS_UPDATED;
|
||||
sblock.fs_flags = 0;
|
||||
if (Uflag)
|
||||
sblock.fs_flags |= FS_DOSOFTDEP;
|
||||
@ -243,7 +244,7 @@ mkfs(struct partition *pp, char *fsys)
|
||||
sblock.fs_size = fssize = dbtofsb(&sblock, fssize);
|
||||
if (Oflag == 1) {
|
||||
sblock.fs_magic = FS_UFS1_MAGIC;
|
||||
sblock.fs_sblockloc = numfrags(&sblock, SBLOCK_UFS1);
|
||||
sblock.fs_sblockloc = SBLOCK_UFS1;
|
||||
sblock.fs_nindir = sblock.fs_bsize / sizeof(ufs1_daddr_t);
|
||||
sblock.fs_inopb = sblock.fs_bsize / sizeof(struct ufs1_dinode);
|
||||
sblock.fs_maxsymlinklen = ((NDADDR + NIADDR) *
|
||||
@ -263,15 +264,15 @@ mkfs(struct partition *pp, char *fsys)
|
||||
sblock.fs_old_nrpos = 1;
|
||||
} else {
|
||||
sblock.fs_magic = FS_UFS2_MAGIC;
|
||||
sblock.fs_sblockloc = numfrags(&sblock, SBLOCK_UFS2);
|
||||
sblock.fs_sblockloc = SBLOCK_UFS2;
|
||||
sblock.fs_nindir = sblock.fs_bsize / sizeof(ufs2_daddr_t);
|
||||
sblock.fs_inopb = sblock.fs_bsize / sizeof(struct ufs2_dinode);
|
||||
sblock.fs_maxsymlinklen = ((NDADDR + NIADDR) *
|
||||
sizeof(ufs2_daddr_t));
|
||||
}
|
||||
sblock.fs_sblkno =
|
||||
roundup(howmany(lfragtosize(&sblock, sblock.fs_sblockloc) +
|
||||
SBLOCKSIZE, sblock.fs_fsize), sblock.fs_frag);
|
||||
roundup(howmany(sblock.fs_sblockloc + SBLOCKSIZE, sblock.fs_fsize),
|
||||
sblock.fs_frag);
|
||||
sblock.fs_cblkno = sblock.fs_sblkno +
|
||||
roundup(howmany(SBLOCKSIZE, sblock.fs_fsize), sblock.fs_frag);
|
||||
sblock.fs_iblkno = sblock.fs_cblkno + sblock.fs_frag;
|
||||
@ -476,8 +477,7 @@ mkfs(struct partition *pp, char *fsys)
|
||||
sblock.fs_old_cstotal.cs_nifree = sblock.fs_cstotal.cs_nifree;
|
||||
sblock.fs_old_cstotal.cs_nffree = sblock.fs_cstotal.cs_nffree;
|
||||
}
|
||||
wtfs(lfragtosize(&sblock, sblock.fs_sblockloc) / sectorsize,
|
||||
SBLOCKSIZE, (char *)&sblock);
|
||||
wtfs(sblock.fs_sblockloc / sectorsize, SBLOCKSIZE, (char *)&sblock);
|
||||
for (i = 0; i < sblock.fs_cssize; i += sblock.fs_bsize)
|
||||
wtfs(fsbtodb(&sblock, sblock.fs_csaddr + numfrags(&sblock, i)),
|
||||
sblock.fs_cssize - i < sblock.fs_bsize ?
|
||||
|
@ -291,8 +291,7 @@ chkquota(fsname, mntpt, qnp)
|
||||
bread(sblock_try[i], (char *)&sblock, (long)SBLOCKSIZE);
|
||||
if ((sblock.fs_magic == FS_UFS1_MAGIC ||
|
||||
(sblock.fs_magic == FS_UFS2_MAGIC &&
|
||||
sblock.fs_sblockloc ==
|
||||
numfrags(&sblock, sblock_try[i]))) &&
|
||||
sblock.fs_sblockloc == sblock_try[i])) &&
|
||||
sblock.fs_bsize <= MAXBSIZE &&
|
||||
sblock.fs_bsize >= sizeof(struct fs))
|
||||
break;
|
||||
|
@ -404,7 +404,7 @@ getsb(fs, file)
|
||||
err(4, "%s: bad super block", file);
|
||||
if ((fs->fs_magic == FS_UFS1_MAGIC ||
|
||||
(fs->fs_magic == FS_UFS2_MAGIC &&
|
||||
fs->fs_sblockloc == numfrags(fs, sblock_try[i]))) &&
|
||||
fs->fs_sblockloc == sblock_try[i])) &&
|
||||
fs->fs_bsize <= MAXBSIZE &&
|
||||
fs->fs_bsize >= sizeof(struct fs))
|
||||
break;
|
||||
|
@ -243,7 +243,7 @@ fsread(ino_t inode, void *buf, size_t nbyte)
|
||||
return -1;
|
||||
if ((fs->fs_magic == FS_UFS1_MAGIC ||
|
||||
(fs->fs_magic == FS_UFS2_MAGIC &&
|
||||
fs->fs_sblockloc == numfrags(fs, sblock_try[n]))) &&
|
||||
fs->fs_sblockloc == sblock_try[n])) &&
|
||||
fs->fs_bsize <= MAXBSIZE &&
|
||||
fs->fs_bsize >= sizeof(struct fs))
|
||||
break;
|
||||
|
@ -235,8 +235,8 @@ ffs_snapshot(mp, snapfile)
|
||||
/*
|
||||
* Allocate copies for the superblock and its summary information.
|
||||
*/
|
||||
error = UFS_BALLOC(vp, lfragtosize(fs, fs->fs_sblockloc),
|
||||
fs->fs_sbsize, KERNCRED, 0, &nbp);
|
||||
error = UFS_BALLOC(vp, fs->fs_sblockloc, fs->fs_sbsize, KERNCRED,
|
||||
0, &nbp);
|
||||
if (error)
|
||||
goto out;
|
||||
bawrite(nbp);
|
||||
@ -339,14 +339,14 @@ ffs_snapshot(mp, snapfile)
|
||||
* Grab a copy of the superblock and its summary information.
|
||||
* We delay writing it until the suspension is released below.
|
||||
*/
|
||||
error = bread(vp, fragstoblks(fs, fs->fs_sblockloc), fs->fs_bsize,
|
||||
error = bread(vp, lblkno(fs, fs->fs_sblockloc), fs->fs_bsize,
|
||||
KERNCRED, &sbp);
|
||||
if (error) {
|
||||
brelse(sbp);
|
||||
sbp = NULL;
|
||||
goto out1;
|
||||
}
|
||||
loc = blkoff(fs, lfragtosize(fs, fs->fs_sblockloc));
|
||||
loc = blkoff(fs, fs->fs_sblockloc);
|
||||
copy_fs = (struct fs *)(sbp->b_data + loc);
|
||||
bcopy(fs, copy_fs, fs->fs_sbsize);
|
||||
if ((fs->fs_flags & (FS_UNCLEAN | FS_NEEDSFSCK)) == 0)
|
||||
|
@ -426,7 +426,7 @@ ffs_reload(mp, cred, td)
|
||||
* Step 2: re-read superblock from disk.
|
||||
*/
|
||||
fs = VFSTOUFS(mp)->um_fs;
|
||||
if ((error = bread(devvp, fsbtodb(fs, fs->fs_sblockloc), fs->fs_sbsize,
|
||||
if ((error = bread(devvp, btodb(fs->fs_sblockloc), fs->fs_sbsize,
|
||||
NOCRED, &bp)) != 0)
|
||||
return (error);
|
||||
newfs = (struct fs *)bp->b_data;
|
||||
@ -624,10 +624,11 @@ ffs_mountfs(devvp, mp, td, malloctype)
|
||||
cred, &bp)) != 0)
|
||||
goto out;
|
||||
fs = (struct fs *)bp->b_data;
|
||||
sblockloc = numfrags(fs, sblock_try[i]);
|
||||
sblockloc = sblock_try[i];
|
||||
if ((fs->fs_magic == FS_UFS1_MAGIC ||
|
||||
(fs->fs_magic == FS_UFS2_MAGIC &&
|
||||
fs->fs_sblockloc == sblockloc)) &&
|
||||
(fs->fs_sblockloc == sblockloc ||
|
||||
(fs->fs_old_flags & FS_FLAGS_UPDATED) == 0))) &&
|
||||
fs->fs_bsize <= MAXBSIZE &&
|
||||
fs->fs_bsize >= sizeof(struct fs))
|
||||
break;
|
||||
@ -847,13 +848,19 @@ ffs_oldfscompat_read(fs, ump, sblockloc)
|
||||
{
|
||||
off_t maxfilesize;
|
||||
|
||||
/*
|
||||
* If not yet done, update fs_flags location and value of fs_sblockloc.
|
||||
*/
|
||||
if ((fs->fs_old_flags & FS_FLAGS_UPDATED) == 0) {
|
||||
fs->fs_flags = fs->fs_old_flags;
|
||||
fs->fs_old_flags |= FS_FLAGS_UPDATED;
|
||||
fs->fs_sblockloc = sblockloc;
|
||||
}
|
||||
/*
|
||||
* If not yet done, update UFS1 superblock with new wider fields.
|
||||
*/
|
||||
if (fs->fs_magic == FS_UFS1_MAGIC &&
|
||||
fs->fs_sblockloc != sblockloc) {
|
||||
if (fs->fs_magic == FS_UFS1_MAGIC && fs->fs_size != fs->fs_old_size) {
|
||||
fs->fs_maxbsize = fs->fs_bsize;
|
||||
fs->fs_sblockloc = sblockloc;
|
||||
fs->fs_time = fs->fs_old_time;
|
||||
fs->fs_size = fs->fs_old_size;
|
||||
fs->fs_dsize = fs->fs_old_dsize;
|
||||
@ -1471,8 +1478,8 @@ ffs_sbupdate(mp, waitfor)
|
||||
*/
|
||||
if (allerror)
|
||||
return (allerror);
|
||||
bp = getblk(mp->um_devvp, fsbtodb(fs, fs->fs_sblockloc),
|
||||
(int)fs->fs_sbsize, 0, 0);
|
||||
bp = getblk(mp->um_devvp, btodb(fs->fs_sblockloc), (int)fs->fs_sbsize,
|
||||
0, 0);
|
||||
fs->fs_fmod = 0;
|
||||
fs->fs_time = time_second;
|
||||
bcopy((caddr_t)fs, bp->b_data, (u_int)fs->fs_sbsize);
|
||||
|
@ -302,7 +302,7 @@ struct fs {
|
||||
int8_t fs_fmod; /* super block modified flag */
|
||||
int8_t fs_clean; /* filesystem is clean flag */
|
||||
int8_t fs_ronly; /* mounted read-only flag */
|
||||
int8_t fs_flags; /* see FS_ flags below */
|
||||
int8_t fs_old_flags; /* old FS_ flags */
|
||||
u_char fs_fsmnt[MAXMNTLEN]; /* name mounted on */
|
||||
/* these fields retain the current block allocation info */
|
||||
int32_t fs_cgrotor; /* last cg searched */
|
||||
@ -314,7 +314,7 @@ struct fs {
|
||||
int32_t fs_old_cpc; /* cyl per cycle in postbl */
|
||||
int32_t fs_maxbsize; /* maximum blocking factor permitted */
|
||||
int64_t fs_sparecon64[17]; /* old rotation block list head */
|
||||
int64_t fs_sblockloc; /* location of standard superblock */
|
||||
int64_t fs_sblockloc; /* byte offset of standard superblock */
|
||||
struct csum_total fs_cstotal; /* cylinder summary information */
|
||||
ufs_time_t fs_time; /* last time written */
|
||||
int64_t fs_size; /* number of blocks in fs */
|
||||
@ -326,7 +326,8 @@ struct fs {
|
||||
int32_t fs_avgfilesize; /* expected average file size */
|
||||
int32_t fs_avgfpdir; /* expected # of files per directory */
|
||||
int32_t fs_save_cgsize; /* save real cg size to use fs_bsize */
|
||||
int32_t fs_sparecon32[27]; /* reserved for future constants */
|
||||
int32_t fs_sparecon32[26]; /* reserved for future constants */
|
||||
int32_t fs_flags; /* see FS_ flags below */
|
||||
int32_t fs_contigsumsize; /* size of cluster summary array */
|
||||
int32_t fs_maxsymlinklen; /* max length of an internal symlink */
|
||||
int32_t fs_old_inodefmt; /* format of on-disk inodes */
|
||||
@ -389,6 +390,7 @@ struct fs {
|
||||
#define FS_INDEXDIRS 0x08 /* kernel supports indexed directories */
|
||||
#define FS_ACLS 0x10 /* file system has ACLs enabled */
|
||||
#define FS_MULTILABEL 0x20 /* file system is MAC multi-label */
|
||||
#define FS_FLAGS_UPDATED 0x80 /* flags have been moved to new location */
|
||||
|
||||
/*
|
||||
* Macros to access bits in the fs_active array.
|
||||
|
Loading…
Reference in New Issue
Block a user