Fix size differences between architectures of the UFS/FFS CGSIZE macro value.
The cylinder group header structure ended with `u_int8_t cg_space[1]' representing the beginning of the inode bitmap array. Some architectures like the i386 rounded this up to a 4-byte boundry while other architectures like the amd64 rounded it up to an 8-byte boundry. Thus sizeof(struct cg) was four bytes bigger on an amd64 machine than on an i386 machine. If a filesystem created on an i386 machine was moved to an amd64 machine, the size of the cylinder group calculated by the CGSIZE macro would appear to grow by four bytes. Filesystems whose cylinder groups were exactly equal to the block size on an i386 machine would appear to have a cylinder group that was four bytes too big when moved to an amd64 machine. Note that although the structure appears to be too big, it in fact is fine. It is just the calaculation of its size that is in error. The fix is to remove the cg_space element from the cylinder-group structure so that the calculated size of the structure is the same size on all architectures. Reported by: Tijl Coosemans Tested by: Tijl Coosemans and Peter Holm MFC after: 1 week Sponsored by: The FreeBSD Foundation
This commit is contained in:
parent
b68588618b
commit
0a6e34e950
@ -1038,7 +1038,7 @@ check_cgmagic(int cg, struct bufarea *cgbp)
|
|||||||
CHK(cgp->cg_ndblk, !=, sblock.fs_size - cgbase(&sblock, cg),
|
CHK(cgp->cg_ndblk, !=, sblock.fs_size - cgbase(&sblock, cg),
|
||||||
"%jd");
|
"%jd");
|
||||||
}
|
}
|
||||||
start = &cgp->cg_space[0] - (u_char *)(&cgp->cg_firstfield);
|
start = sizeof(*cgp);
|
||||||
if (sblock.fs_magic == FS_UFS2_MAGIC) {
|
if (sblock.fs_magic == FS_UFS2_MAGIC) {
|
||||||
CHK(cgp->cg_iusedoff, !=, start, "%jd");
|
CHK(cgp->cg_iusedoff, !=, start, "%jd");
|
||||||
} else if (sblock.fs_magic == FS_UFS1_MAGIC) {
|
} else if (sblock.fs_magic == FS_UFS1_MAGIC) {
|
||||||
@ -1098,7 +1098,7 @@ rebuild_cg(int cg, struct bufarea *cgbp)
|
|||||||
cgp->cg_ndblk = sblock.fs_fpg;
|
cgp->cg_ndblk = sblock.fs_fpg;
|
||||||
else
|
else
|
||||||
cgp->cg_ndblk = sblock.fs_size - cgbase(&sblock, cg);
|
cgp->cg_ndblk = sblock.fs_size - cgbase(&sblock, cg);
|
||||||
start = &cgp->cg_space[0] - (u_char *)(&cgp->cg_firstfield);
|
start = sizeof(*cgp);
|
||||||
if (sblock.fs_magic == FS_UFS2_MAGIC) {
|
if (sblock.fs_magic == FS_UFS2_MAGIC) {
|
||||||
cgp->cg_iusedoff = start;
|
cgp->cg_iusedoff = start;
|
||||||
} else if (sblock.fs_magic == FS_UFS1_MAGIC) {
|
} else if (sblock.fs_magic == FS_UFS1_MAGIC) {
|
||||||
|
@ -116,7 +116,7 @@ pass5(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
basesize = &newcg->cg_space[0] - (u_char *)(&newcg->cg_firstfield);
|
basesize = sizeof(*newcg);
|
||||||
if (sblock.fs_magic == FS_UFS2_MAGIC) {
|
if (sblock.fs_magic == FS_UFS2_MAGIC) {
|
||||||
newcg->cg_iusedoff = basesize;
|
newcg->cg_iusedoff = basesize;
|
||||||
} else {
|
} else {
|
||||||
@ -131,7 +131,7 @@ pass5(void)
|
|||||||
fs->fs_old_cpg * sizeof(int32_t);
|
fs->fs_old_cpg * sizeof(int32_t);
|
||||||
newcg->cg_iusedoff = newcg->cg_old_boff +
|
newcg->cg_iusedoff = newcg->cg_old_boff +
|
||||||
fs->fs_old_cpg * fs->fs_old_nrpos * sizeof(u_int16_t);
|
fs->fs_old_cpg * fs->fs_old_nrpos * sizeof(u_int16_t);
|
||||||
memset(&newcg->cg_space[0], 0, newcg->cg_iusedoff - basesize);
|
memset(&newcg[1], 0, newcg->cg_iusedoff - basesize);
|
||||||
}
|
}
|
||||||
inomapsize = howmany(fs->fs_ipg, CHAR_BIT);
|
inomapsize = howmany(fs->fs_ipg, CHAR_BIT);
|
||||||
newcg->cg_freeoff = newcg->cg_iusedoff + inomapsize;
|
newcg->cg_freeoff = newcg->cg_iusedoff + inomapsize;
|
||||||
|
@ -338,7 +338,7 @@ initcg(int cylno, time_t modtime, int fso, unsigned int Nflag)
|
|||||||
acg.cg_ndblk = dmax - cbase;
|
acg.cg_ndblk = dmax - cbase;
|
||||||
if (sblock.fs_contigsumsize > 0)
|
if (sblock.fs_contigsumsize > 0)
|
||||||
acg.cg_nclusterblks = acg.cg_ndblk / sblock.fs_frag;
|
acg.cg_nclusterblks = acg.cg_ndblk / sblock.fs_frag;
|
||||||
start = &acg.cg_space[0] - (u_char *)(&acg.cg_firstfield);
|
start = sizeof(acg);
|
||||||
if (sblock.fs_magic == FS_UFS2_MAGIC) {
|
if (sblock.fs_magic == FS_UFS2_MAGIC) {
|
||||||
acg.cg_iusedoff = start;
|
acg.cg_iusedoff = start;
|
||||||
} else {
|
} else {
|
||||||
|
@ -721,7 +721,7 @@ initcg(int cylno, time_t utime)
|
|||||||
acg.cg_ndblk = dmax - cbase;
|
acg.cg_ndblk = dmax - cbase;
|
||||||
if (sblock.fs_contigsumsize > 0)
|
if (sblock.fs_contigsumsize > 0)
|
||||||
acg.cg_nclusterblks = acg.cg_ndblk / sblock.fs_frag;
|
acg.cg_nclusterblks = acg.cg_ndblk / sblock.fs_frag;
|
||||||
start = &acg.cg_space[0] - (u_char *)(&acg.cg_firstfield);
|
start = sizeof(acg);
|
||||||
if (Oflag == 2) {
|
if (Oflag == 2) {
|
||||||
acg.cg_iusedoff = start;
|
acg.cg_iusedoff = start;
|
||||||
} else {
|
} else {
|
||||||
@ -749,7 +749,8 @@ initcg(int cylno, time_t utime)
|
|||||||
howmany(fragstoblks(&sblock, sblock.fs_fpg), CHAR_BIT);
|
howmany(fragstoblks(&sblock, sblock.fs_fpg), CHAR_BIT);
|
||||||
}
|
}
|
||||||
if (acg.cg_nextfreeoff > (unsigned)sblock.fs_cgsize) {
|
if (acg.cg_nextfreeoff > (unsigned)sblock.fs_cgsize) {
|
||||||
printf("Panic: cylinder group too big\n");
|
printf("Panic: cylinder group too big by %d bytes\n",
|
||||||
|
acg.cg_nextfreeoff - (unsigned)sblock.fs_cgsize);
|
||||||
exit(37);
|
exit(37);
|
||||||
}
|
}
|
||||||
acg.cg_cs.cs_nifree += sblock.fs_ipg;
|
acg.cg_cs.cs_nifree += sblock.fs_ipg;
|
||||||
|
@ -573,11 +573,11 @@ CTASSERT(sizeof(struct fs) == 1376);
|
|||||||
* cylinder group and the (struct cg) size.
|
* cylinder group and the (struct cg) size.
|
||||||
*/
|
*/
|
||||||
#define CGSIZE(fs) \
|
#define CGSIZE(fs) \
|
||||||
/* base cg */ (sizeof(struct cg) + sizeof(int32_t) + \
|
/* base cg */ (sizeof(struct cg) + \
|
||||||
/* old btotoff */ (fs)->fs_old_cpg * sizeof(int32_t) + \
|
/* old btotoff */ (fs)->fs_old_cpg * sizeof(int32_t) + \
|
||||||
/* old boff */ (fs)->fs_old_cpg * sizeof(u_int16_t) + \
|
/* old boff */ (fs)->fs_old_cpg * sizeof(u_int16_t) + \
|
||||||
/* inode map */ howmany((fs)->fs_ipg, NBBY) + \
|
/* inode map */ howmany((fs)->fs_ipg, NBBY) + \
|
||||||
/* block map */ howmany((fs)->fs_fpg, NBBY) +\
|
/* block map */ howmany((fs)->fs_fpg, NBBY) + sizeof(int32_t) + \
|
||||||
/* if present */ ((fs)->fs_contigsumsize <= 0 ? 0 : \
|
/* if present */ ((fs)->fs_contigsumsize <= 0 ? 0 : \
|
||||||
/* cluster sum */ (fs)->fs_contigsumsize * sizeof(int32_t) + \
|
/* cluster sum */ (fs)->fs_contigsumsize * sizeof(int32_t) + \
|
||||||
/* cluster map */ howmany(fragstoblks(fs, (fs)->fs_fpg), NBBY)))
|
/* cluster map */ howmany(fragstoblks(fs, (fs)->fs_fpg), NBBY)))
|
||||||
@ -624,8 +624,7 @@ struct cg {
|
|||||||
u_int32_t cg_ckhash; /* check-hash of this cg */
|
u_int32_t cg_ckhash; /* check-hash of this cg */
|
||||||
ufs_time_t cg_time; /* time last written */
|
ufs_time_t cg_time; /* time last written */
|
||||||
int64_t cg_sparecon64[3]; /* reserved for future use */
|
int64_t cg_sparecon64[3]; /* reserved for future use */
|
||||||
u_int8_t cg_space[1]; /* space for cylinder group maps */
|
/* actually longer - space used for cylinder group maps */
|
||||||
/* actually longer */
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -634,7 +634,7 @@ initcg(uint32_t cylno, time_t utime, const fsinfo_t *fsopts)
|
|||||||
acg.cg_ndblk = dmax - cbase;
|
acg.cg_ndblk = dmax - cbase;
|
||||||
if (sblock.fs_contigsumsize > 0)
|
if (sblock.fs_contigsumsize > 0)
|
||||||
acg.cg_nclusterblks = acg.cg_ndblk >> sblock.fs_fragshift;
|
acg.cg_nclusterblks = acg.cg_ndblk >> sblock.fs_fragshift;
|
||||||
start = &acg.cg_space[0] - (u_char *)(&acg.cg_firstfield);
|
start = sizeof(acg);
|
||||||
if (Oflag == 2) {
|
if (Oflag == 2) {
|
||||||
acg.cg_iusedoff = start;
|
acg.cg_iusedoff = start;
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user