Date: Mon, 30 May 2022 16:33:47 -0600 From: Warner Losh <imp@bsdimp.com> To: Cy Schubert <Cy.Schubert@cschubert.com> Cc: Kirk McKusick <mckusick@freebsd.org>, src-committers <src-committers@freebsd.org>, "<dev-commits-src-all@freebsd.org>" <dev-commits-src-all@freebsd.org>, dev-commits-src-main@freebsd.org, David Wolfskill <david@catwhisker.org>, Toomas Soome <tsoome@me.com> Subject: Re: git: 076002f24d35 - main - Do comprehensive UFS/FFS superblock integrity checks when reading a superblock. Message-ID: <CANCZdfoqpDO9-APZytimd9TpPGsnaj0%2BwJBfdxv%2Bo2NnOX5ZUQ@mail.gmail.com> In-Reply-To: <20220530222402.E22C7114@slippy.cwsent.com> References: <202205271922.24RJMOJ2039923@gitrepo.freebsd.org> <20220530215552.EE5432C@slippy.cwsent.com> <CANCZdfpovXadsxcS_YC2-NpJJX8S62YTfNTSfE9VHqoE6KsJPA@mail.gmail.com> <20220530222402.E22C7114@slippy.cwsent.com>
next in thread | previous in thread | raw e-mail | index | archive | help
--0000000000008603c305e04240eb Content-Type: text/plain; charset="UTF-8" On Mon, May 30, 2022 at 4:24 PM Cy Schubert <Cy.Schubert@cschubert.com> wrote: > Upgrading boot blocks didn't help either. > > It only happened on one of four machines. Likely because the other three > are AMD on Asus MBs while the problem machine is an Acer laptop running > Intel. > David Wolfskill reported the same: some are affected, others not. It's unclear why, exactly, but all the other details you gave track with the troubleshooting tsoome and I have been doing with him. The issue is inside of loader.efi or /boot/loader, not in the earlier boot blocks. Warner > > -- > Cheers, > Cy Schubert <Cy.Schubert@komquats.com> or <Cy.Schubert@cschubert.com> > FreeBSD UNIX: <cy@FreeBSD.org> Web: http://www.FreeBSD.org > NTP: <cy@nwtime.org> Web: https://nwtime.org > > e**(i*pi)+1=0 > > > In message > <CANCZdfpovXadsxcS_YC2-NpJJX8S62YTfNTSfE9VHqoE6KsJPA@mail.gmail.c > om> > , Warner Losh writes: > > --00000000000059353005e041e22c > > Content-Type: text/plain; charset="UTF-8" > > > > David Woofskill also reported this... > > > > Warner > > > > On Mon, May 30, 2022, 3:56 PM Cy Schubert <Cy.Schubert@cschubert.com> > wrote: > > > > > In message <202205271922.24RJMOJ2039923@gitrepo.freebsd.org>, Kirk > > > McKusick > > > wri > > > tes: > > > > The branch main has been updated by mckusick: > > > > > > > > URL: > > > > https://cgit.FreeBSD.org/src/commit/?id=076002f24d35962f0d21f44bfddd34ee > > > > 4d7f015d > > > > > > > > commit 076002f24d35962f0d21f44bfddd34ee4d7f015d > > > > Author: Kirk McKusick <mckusick@FreeBSD.org> > > > > AuthorDate: 2022-05-27 19:21:11 +0000 > > > > Commit: Kirk McKusick <mckusick@FreeBSD.org> > > > > CommitDate: 2022-05-27 19:22:07 +0000 > > > > > > > > Do comprehensive UFS/FFS superblock integrity checks when > reading a > > > super > > > > block. > > > > > > > > Historically only minimal checks were made of a superblock when > it > > > > was read in as it was assumed that fsck would have been run to > > > > correct any errors before attempting to use the filesystem. > Recently > > > > several bug reports have been submitted reporting kernel panics > > > > that can be triggered by deliberately corrupting filesystem > > > superblocks, > > > > see Bug 263979 - [meta] UFS / FFS / GEOM crash (panic) tracking > > > > which is tracking the reported corruption bugs. > > > > > > > > This change upgrades the checks that are performed. These > additional > > > > checks should prevent panics from a corrupted superblock. > Although > > > > it appears in only one place, the new code will apply to the > kernel > > > > modules and (through libufs) user applications that read in > > > superblocks. > > > > > > > > Reported by: Robert Morris and Neeraj > > > > Reviewed by: kib > > > > Tested by: Peter Holm > > > > PR: 263979 > > > > MFC after: 1 month > > > > Differential Revision: https://reviews.freebsd.org/D35219 > > > > --- > > > > sys/ufs/ffs/ffs_subr.c | 163 > > > +++++++++++++++++++++++++++++++++++++++++++---- > > > > -- > > > > 1 file changed, 146 insertions(+), 17 deletions(-) > > > > > > > > diff --git a/sys/ufs/ffs/ffs_subr.c b/sys/ufs/ffs/ffs_subr.c > > > > index 01e9f45e1205..28c2fee1cb37 100644 > > > > --- a/sys/ufs/ffs/ffs_subr.c > > > > +++ b/sys/ufs/ffs/ffs_subr.c > > > > @@ -35,6 +35,7 @@ > > > > __FBSDID("$FreeBSD$"); > > > > > > > > #include <sys/param.h> > > > > +#include <sys/limits.h> > > > > > > > > #ifndef _KERNEL > > > > #include <stdio.h> > > > > @@ -50,6 +51,7 @@ uint32_t ffs_calc_sbhash(struct fs *); > > > > struct malloc_type; > > > > #define UFS_MALLOC(size, type, flags) malloc(size) > > > > #define UFS_FREE(ptr, type) free(ptr) > > > > +#define maxphys MAXPHYS > > > > > > > > #else /* _KERNEL */ > > > > #include <sys/systm.h> > > > > @@ -125,6 +127,7 @@ ffs_update_dinode_ckhash(struct fs *fs, struct > > > ufs2_dinod > > > > e *dip) > > > > static off_t sblock_try[] = SBLOCKSEARCH; > > > > static int readsuper(void *, struct fs **, off_t, int, int, > > > > int (*)(void *, off_t, void **, int)); > > > > +static int validate_sblock(struct fs *, int); > > > > > > > > /* > > > > * Read a superblock from the devfd device. > > > > @@ -141,7 +144,7 @@ static int readsuper(void *, struct fs **, off_t, > > > int, in > > > > t, > > > > * EIO: non-existent or truncated superblock. > > > > * EIO: error reading summary information. > > > > * ENOENT: no usable known superblock found. > > > > - * ENOSPC: failed to allocate space for the superblock. > > > > + * ENOMEM: failed to allocate space for the superblock. > > > > * EINVAL: The previous newfs operation on this volume did not > > > complete. > > > > * The administrator must complete newfs before using this > > > volume. > > > > */ > > > > @@ -152,7 +155,8 @@ ffs_sbget(void *devfd, struct fs **fsp, off_t > > > altsblock, > > > > { > > > > struct fs *fs; > > > > struct fs_summary_info *fs_si; > > > > - int i, error, size, blks; > > > > + int i, error; > > > > + uint64_t size, blks; > > > > uint8_t *space; > > > > int32_t *lp; > > > > char *buf; > > > > @@ -190,17 +194,16 @@ ffs_sbget(void *devfd, struct fs **fsp, off_t > > > altsblock > > > > , > > > > if (fs->fs_contigsumsize > 0) > > > > size += fs->fs_ncg * sizeof(int32_t); > > > > size += fs->fs_ncg * sizeof(u_int8_t); > > > > - /* When running in libufs or libsa, UFS_MALLOC may fail */ > > > > - if ((fs_si = UFS_MALLOC(sizeof(*fs_si), filltype, M_WAITOK)) == > > > NULL) { > > > > + if ((fs_si = UFS_MALLOC(sizeof(*fs_si), filltype, M_NOWAIT)) == > > > NULL) { > > > > UFS_FREE(fs, filltype); > > > > - return (ENOSPC); > > > > + return (ENOMEM); > > > > } > > > > bzero(fs_si, sizeof(*fs_si)); > > > > fs->fs_si = fs_si; > > > > - if ((space = UFS_MALLOC(size, filltype, M_WAITOK)) == NULL) { > > > > + if ((space = UFS_MALLOC(size, filltype, M_NOWAIT)) == NULL) { > > > > UFS_FREE(fs->fs_si, filltype); > > > > UFS_FREE(fs, filltype); > > > > - return (ENOSPC); > > > > + return (ENOMEM); > > > > } > > > > fs->fs_csp = (struct csum *)space; > > > > for (i = 0; i < blks; i += fs->fs_frag) { > > > > @@ -253,16 +256,8 @@ readsuper(void *devfd, struct fs **fsp, off_t > > > sblockloc, > > > > int isaltsblk, > > > > fs = *fsp; > > > > if (fs->fs_magic == FS_BAD_MAGIC) > > > > return (EINVAL); > > > > - if (!(((fs->fs_magic == FS_UFS1_MAGIC && (isaltsblk || > > > > - sblockloc <= SBLOCK_UFS1)) || > > > > - (fs->fs_magic == FS_UFS2_MAGIC && (isaltsblk || > > > > - sblockloc == fs->fs_sblockloc))) && > > > > - fs->fs_ncg >= 1 && > > > > - fs->fs_bsize >= MINBSIZE && > > > > - fs->fs_bsize <= MAXBSIZE && > > > > - fs->fs_bsize >= roundup(sizeof(struct fs), DEV_BSIZE) && > > > > - fs->fs_sbsize <= SBLOCKSIZE)) > > > > - return (ENOENT); > > > > + if ((error = validate_sblock(fs, isaltsblk)) != 0) > > > > + return (error); > > > > /* > > > > * If the filesystem has been run on a kernel without > > > > * metadata check hashes, disable them. > > > > @@ -310,6 +305,140 @@ readsuper(void *devfd, struct fs **fsp, off_t > > > sblockloc > > > > , int isaltsblk, > > > > return (0); > > > > } > > > > > > > > +/* > > > > + * Verify the filesystem values. > > > > + */ > > > > +#define ILOG2(num) (fls(num) - 1) > > > > + > > > > +static int > > > > +validate_sblock(struct fs *fs, int isaltsblk) > > > > +{ > > > > + int i, sectorsize; > > > > + u_int64_t maxfilesize, minfpg, sizepb; > > > > + > > > > + sectorsize = dbtob(1); > > > > + if (fs->fs_magic == FS_UFS2_MAGIC) { > > > > + if ((!isaltsblk && (fs->fs_sblockloc != SBLOCK_UFS2 || > > > > + fs->fs_sblockactualloc != SBLOCK_UFS2)) || > > > > + fs->fs_maxsymlinklen != ((UFS_NDADDR + UFS_NIADDR) > * > > > > + sizeof(ufs2_daddr_t)) || > > > > + fs->fs_nindir != fs->fs_bsize / > sizeof(ufs2_daddr_t) || > > > > + fs->fs_inopb != fs->fs_bsize / sizeof(struct > > > ufs2_dinode)) > > > > + return (ENOENT); > > > > + } else if (fs->fs_magic == FS_UFS1_MAGIC) { > > > > + if ((!isaltsblk && (fs->fs_sblockloc > SBLOCK_UFS1 || > > > > + fs->fs_sblockactualloc != SBLOCK_UFS1)) || > > > > + fs->fs_nindir != fs->fs_bsize / > sizeof(ufs1_daddr_t) || > > > > + fs->fs_inopb != fs->fs_bsize / sizeof(struct > > > ufs1_dinode) | > > > > | > > > > + fs->fs_maxsymlinklen != ((UFS_NDADDR + UFS_NIADDR) > * > > > > + sizeof(ufs1_daddr_t)) || > > > > + fs->fs_old_inodefmt != FS_44INODEFMT || > > > > + fs->fs_old_cgoffset != 0 || > > > > + fs->fs_old_cgmask != 0xffffffff || > > > > + fs->fs_old_size != fs->fs_size || > > > > + fs->fs_old_rotdelay != 0 || > > > > + fs->fs_old_rps != 60 || > > > > + fs->fs_old_nspf != fs->fs_fsize / sectorsize || > > > > + fs->fs_old_cpg != 1 || > > > > + fs->fs_old_interleave != 1 || > > > > + fs->fs_old_trackskew != 0 || > > > > + fs->fs_old_cpc != 0 || > > > > + fs->fs_old_postblformat != 1 || > > > > + fs->fs_old_nrpos != 1 || > > > > + fs->fs_old_spc != fs->fs_fpg * fs->fs_old_nspf || > > > > + fs->fs_old_nsect != fs->fs_old_spc || > > > > + fs->fs_old_npsect != fs->fs_old_spc || > > > > + fs->fs_old_dsize != fs->fs_dsize || > > > > + fs->fs_old_ncyl != fs->fs_ncg) > > > > + return (ENOENT); > > > > + } else { > > > > + return (ENOENT); > > > > + } > > > > + if (fs->fs_bsize < MINBSIZE || fs->fs_bsize > MAXBSIZE || > > > > + fs->fs_bsize < roundup(sizeof(struct fs), DEV_BSIZE) || > > > > + fs->fs_sbsize > SBLOCKSIZE || fs->fs_sbsize < fs->fs_fsize > || > > > > + !powerof2(fs->fs_bsize)) > > > > + return (ENOENT); > > > > + if (fs->fs_fsize < sectorsize || fs->fs_fsize > fs->fs_bsize || > > > > + fs->fs_fsize * MAXFRAG < fs->fs_bsize || > > > !powerof2(fs->fs_fsize)) > > > > + return (ENOENT); > > > > + if (fs->fs_maxbsize < fs->fs_bsize || > !powerof2(fs->fs_maxbsize) || > > > > + fs->fs_maxbsize > FS_MAXCONTIG * fs->fs_bsize) > > > > + return (ENOENT); > > > > + if (fs->fs_bmask != ~(fs->fs_bsize - 1) || > > > > + fs->fs_fmask != ~(fs->fs_fsize - 1) || > > > > + fs->fs_qbmask != ~fs->fs_bmask || > > > > + fs->fs_qfmask != ~fs->fs_fmask || > > > > + fs->fs_bshift != ILOG2(fs->fs_bsize) || > > > > + fs->fs_fshift != ILOG2(fs->fs_fsize) || > > > > + fs->fs_frag != numfrags(fs, fs->fs_bsize) || > > > > + fs->fs_fragshift != ILOG2(fs->fs_frag) || > > > > + fs->fs_frag > MAXFRAG || > > > > + fs->fs_fsbtodb != ILOG2(fs->fs_fsize / sectorsize)) > > > > + return (ENOENT); > > > > + if (fs->fs_sblkno != > > > > + roundup(howmany(fs->fs_sblockloc + SBLOCKSIZE, > > > fs->fs_fsize), > > > > + fs->fs_frag) || > > > > + fs->fs_cblkno != fs->fs_sblkno + > > > > + roundup(howmany(SBLOCKSIZE, fs->fs_fsize), > fs->fs_frag) || > > > > + fs->fs_iblkno != fs->fs_cblkno + fs->fs_frag || > > > > + fs->fs_dblkno != fs->fs_iblkno + fs->fs_ipg / INOPF(fs) || > > > > + fs->fs_cgsize != fragroundup(fs, CGSIZE(fs))) > > > > + return (ENOENT); > > > > + if (fs->fs_csaddr != cgdmin(fs, 0) || > > > > + fs->fs_cssize != > > > > + fragroundup(fs, fs->fs_ncg * sizeof(struct csum)) || > > > > + fs->fs_dsize != fs->fs_size - fs->fs_sblkno - > > > > + fs->fs_ncg * (fs->fs_dblkno - fs->fs_sblkno) - > > > > + howmany(fs->fs_cssize, fs->fs_fsize) || > > > > + fs->fs_metaspace < 0 || fs->fs_metaspace > fs->fs_fpg / 2 > || > > > > + fs->fs_minfree > 99) > > > > + return (ENOENT); > > > > + maxfilesize = fs->fs_bsize * UFS_NDADDR - 1; > > > > + for (sizepb = fs->fs_bsize, i = 0; i < UFS_NIADDR; i++) { > > > > + sizepb *= NINDIR(fs); > > > > + maxfilesize += sizepb; > > > > + } > > > > + if (fs->fs_maxfilesize != maxfilesize) > > > > + return (ENOENT); > > > > + /* > > > > + * These values have a tight interaction with each other that > > > > + * makes it hard to tightly bound them. So we can only check > > > > + * that they are within a broader possible range. > > > > + * > > > > + * Calculate minfpg, the minimum number of fragments that can > be > > > > + * in a cylinder group. The value 12289 is calculated in > newfs(8) > > > > + * when creating the smallest block size UFS version 1 > filesystem > > > > + * (4096 block size) with no fragments (4096 fragment size). > That > > > > + * number may be depressed even further for very small > filesystems > > > > + * since newfs(8) strives to have at least four cylinder > groups. > > > > + */ > > > > + minfpg = MIN(12289, fs->fs_size / 4); > > > > + if (fs->fs_ncg < 1 || fs->fs_ncg > (fs->fs_size / minfpg) + 1 > || > > > > + fs->fs_fpg < minfpg || fs->fs_fpg > fs->fs_size || > > > > + fs->fs_ipg * fs->fs_ncg > (((int64_t)(1)) << 32) - > INOPB(fs) || > > > > + fs->fs_ipg > fs->fs_fpg || fs->fs_size < 8 * fs->fs_frag) > > > > + return (ENOENT); > > > > + if (fs->fs_size <= (fs->fs_ncg - 1) * fs->fs_fpg || > > > > + fs->fs_size > fs->fs_ncg * fs->fs_fpg) > > > > + return (ENOENT); > > > > + /* > > > > + * Maxcontig sets the default for the maximum number of blocks > > > > + * that may be allocated sequentially. With file system > clustering > > > > + * it is possible to allocate contiguous blocks up to the > maximum > > > > + * transfer size permitted by the controller or buffering. > > > > + */ > > > > + if (fs->fs_maxcontig < 1 || > > > > + fs->fs_maxcontig > MAX(1, maxphys / fs->fs_bsize)) > > > > + return (ENOENT); > > > > + if (fs->fs_maxcontig < 0 || > > > > + (fs->fs_maxcontig == 0 && fs->fs_contigsumsize != 0) || > > > > + (fs->fs_maxcontig > 1 && > > > > + fs->fs_contigsumsize != MIN(fs->fs_maxcontig, > FS_MAXCONTIG))) > > > > + return (ENOENT); > > > > + return (0); > > > > +} > > > > + > > > > /* > > > > * Write a superblock to the devfd device from the memory pointed > to by > > > fs. > > > > * Write out the superblock summary information if it is present. > > > > > > > > > > Hi Kirk, > > > > > > This patch broke loader on one of my machines. > > > > > > I get the following error: > > > > > > LUA ERROR: Cannot open /boot/lua/loader.lua: no such file or directory" > > > can't load kernel > > > > > > Of course booting from my rescue worked. > > > > > > Copying loader* from /boot on the rescue disk to /boot works around the > > > problem. > > > > > > Backing up, newfs, and restoring the root filesystem, using my rescue > disk > > > also didn't work around the problem. > > > > > > Reverting this patch provided permanent relief. > > > > > > Loader could read the filesystems on my rescue disk, which had > blocksizes > > > of 16K but not those on my boot disk which had blocksizes of 32K. > > > > > > My three machines downstairs, all AMD gear with UFS blocksize of 32K, > had > > > no no problems with this whereas my laptop, an Intel, had the problem. > > > > > > To repeat, a newly created filesystem restored from backup using my > rescue > > > disk didn't resolve the problem. > > > > > > > > > -- > > > Cheers, > > > Cy Schubert <Cy.Schubert@komquats.com> or <Cy.Schubert@cschubert.com> > > > FreeBSD UNIX: <cy@FreeBSD.org> Web: http://www.FreeBSD.org > > > NTP: <cy@nwtime.org> Web: https://nwtime.org > > > > > > e**(i*pi)+1=0 > > > > > > > > > > > > --0000000000008603c305e04240eb Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr"><div dir=3D"ltr"><br></div><br><div class=3D"gmail_quote">= <div dir=3D"ltr" class=3D"gmail_attr">On Mon, May 30, 2022 at 4:24 PM Cy Sc= hubert <<a href=3D"mailto:Cy.Schubert@cschubert.com">Cy.Schubert@cschube= rt.com</a>> wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"m= argin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left= :1ex">Upgrading boot blocks didn't help either.<br> <br> It only happened on one of four machines. Likely because the other three <b= r> are AMD on Asus MBs while the problem machine is an Acer laptop running <br= > Intel.<br></blockquote><div><br></div><div>David Wolfskill reported the sam= e: some are affected, others not.</div><div>It's unclear why, exactly, = but all the other details you gave track</div><div>with the troubleshooting= tsoome and I have been doing with him.</div><div><br></div><div>The issue = is inside of loader.efi or /boot/loader, not in the earlier</div><div>boot = blocks.</div><div><br></div><div>Warner</div><div>=C2=A0</div><blockquote c= lass=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:1px soli= d rgb(204,204,204);padding-left:1ex"> <br> -- <br> Cheers,<br> Cy Schubert <<a href=3D"mailto:Cy.Schubert@komquats.com" target=3D"_blan= k">Cy.Schubert@komquats.com</a>> or <<a href=3D"mailto:Cy.Schubert@cs= chubert.com" target=3D"_blank">Cy.Schubert@cschubert.com</a>><br> FreeBSD UNIX:=C2=A0 <cy@FreeBSD.org>=C2=A0 =C2=A0Web:=C2=A0 <a href= =3D"http://www.FreeBSD.org" rel=3D"noreferrer" target=3D"_blank">http://www= .FreeBSD.org</a><br> NTP:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0<<a href=3D"mailto:cy@nwtim= e.org" target=3D"_blank">cy@nwtime.org</a>>=C2=A0 =C2=A0 Web:=C2=A0 <a h= ref=3D"https://nwtime.org" rel=3D"noreferrer" target=3D"_blank">https://nwt= ime.org</a><br> <br> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 e**(i*pi)+1=3D0<br> <br> <br> In message <CANCZdfpovXadsxcS_YC2-NpJJX8S62YTfNTSfE9VHqoE6KsJPA@mail.gma= il.c<br> om><br> , Warner Losh writes:<br> > --00000000000059353005e041e22c<br> > Content-Type: text/plain; charset=3D"UTF-8"<br> ><br> > David Woofskill also reported this...<br> ><br> > Warner<br> ><br> > On Mon, May 30, 2022, 3:56 PM Cy Schubert <<a href=3D"mailto:Cy.Sch= ubert@cschubert.com" target=3D"_blank">Cy.Schubert@cschubert.com</a>> wr= ote:<br> ><br> > > In message <<a href=3D"mailto:202205271922.24RJMOJ2039923@gitr= epo.freebsd.org" target=3D"_blank">202205271922.24RJMOJ2039923@gitrepo.free= bsd.org</a>>, Kirk<br> > > McKusick<br> > > wri<br> > > tes:<br> > > > The branch main has been updated by mckusick:<br> > > ><br> > > > URL:<br> > > <a href=3D"https://cgit.FreeBSD.org/src/commit/?id=3D076002f24d35= 962f0d21f44bfddd34ee" rel=3D"noreferrer" target=3D"_blank">https://cgit.Fre= eBSD.org/src/commit/?id=3D076002f24d35962f0d21f44bfddd34ee</a><br> > > > 4d7f015d<br> > > ><br> > > > commit 076002f24d35962f0d21f44bfddd34ee4d7f015d<br> > > > Author:=C2=A0 =C2=A0 =C2=A0Kirk McKusick <mckusick@FreeBS= D.org><br> > > > AuthorDate: 2022-05-27 19:21:11 +0000<br> > > > Commit:=C2=A0 =C2=A0 =C2=A0Kirk McKusick <mckusick@FreeBS= D.org><br> > > > CommitDate: 2022-05-27 19:22:07 +0000<br> > > ><br> > > >=C2=A0 =C2=A0 =C2=A0Do comprehensive UFS/FFS superblock integ= rity checks when reading a<br> > > super<br> > > > block.<br> > > ><br> > > >=C2=A0 =C2=A0 =C2=A0Historically only minimal checks were mad= e of a superblock when it<br> > > >=C2=A0 =C2=A0 =C2=A0was read in as it was assumed that fsck w= ould have been run to<br> > > >=C2=A0 =C2=A0 =C2=A0correct any errors before attempting to u= se the filesystem. Recently<br> > > >=C2=A0 =C2=A0 =C2=A0several bug reports have been submitted r= eporting kernel panics<br> > > >=C2=A0 =C2=A0 =C2=A0that can be triggered by deliberately cor= rupting filesystem<br> > > superblocks,<br> > > >=C2=A0 =C2=A0 =C2=A0see Bug 263979 - [meta] UFS / FFS / GEOM = crash (panic) tracking<br> > > >=C2=A0 =C2=A0 =C2=A0which is tracking the reported corruption= bugs.<br> > > ><br> > > >=C2=A0 =C2=A0 =C2=A0This change upgrades the checks that are = performed. These additional<br> > > >=C2=A0 =C2=A0 =C2=A0checks should prevent panics from a corru= pted superblock. Although<br> > > >=C2=A0 =C2=A0 =C2=A0it appears in only one place, the new cod= e will apply to the kernel<br> > > >=C2=A0 =C2=A0 =C2=A0modules and (through libufs) user applica= tions that read in<br> > > superblocks.<br> > > ><br> > > >=C2=A0 =C2=A0 =C2=A0Reported by:=C2=A0 Robert Morris and Neer= aj<br> > > >=C2=A0 =C2=A0 =C2=A0Reviewed by:=C2=A0 kib<br> > > >=C2=A0 =C2=A0 =C2=A0Tested by:=C2=A0 =C2=A0 Peter Holm<br> > > >=C2=A0 =C2=A0 =C2=A0PR:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0263979<br> > > >=C2=A0 =C2=A0 =C2=A0MFC after:=C2=A0 =C2=A0 1 month<br> > > >=C2=A0 =C2=A0 =C2=A0Differential Revision: <a href=3D"https:/= /reviews.freebsd.org/D35219" rel=3D"noreferrer" target=3D"_blank">https://r= eviews.freebsd.org/D35219</a><br> > > > ---<br> > > >=C2=A0 sys/ufs/ffs/ffs_subr.c | 163<br> > > +++++++++++++++++++++++++++++++++++++++++++----<br> > > > --<br> > > >=C2=A0 1 file changed, 146 insertions(+), 17 deletions(-)<br> > > ><br> > > > diff --git a/sys/ufs/ffs/ffs_subr.c b/sys/ufs/ffs/ffs_subr.c= <br> > > > index 01e9f45e1205..28c2fee1cb37 100644<br> > > > --- a/sys/ufs/ffs/ffs_subr.c<br> > > > +++ b/sys/ufs/ffs/ffs_subr.c<br> > > > @@ -35,6 +35,7 @@<br> > > >=C2=A0 __FBSDID("$FreeBSD$");<br> > > ><br> > > >=C2=A0 #include <sys/param.h><br> > > > +#include <sys/limits.h><br> > > ><br> > > >=C2=A0 #ifndef _KERNEL<br> > > >=C2=A0 #include <stdio.h><br> > > > @@ -50,6 +51,7 @@ uint32_t ffs_calc_sbhash(struct fs *);<br> > > >=C2=A0 struct malloc_type;<br> > > >=C2=A0 #define UFS_MALLOC(size, type, flags) malloc(size)<br> > > >=C2=A0 #define UFS_FREE(ptr, type) free(ptr)<br> > > > +#define maxphys MAXPHYS<br> > > ><br> > > >=C2=A0 #else /* _KERNEL */<br> > > >=C2=A0 #include <sys/systm.h><br> > > > @@ -125,6 +127,7 @@ ffs_update_dinode_ckhash(struct fs *fs, = struct<br> > > ufs2_dinod<br> > > > e *dip)<br> > > >=C2=A0 static off_t sblock_try[] =3D SBLOCKSEARCH;<br> > > >=C2=A0 static int readsuper(void *, struct fs **, off_t, int,= int,<br> > > >=C2=A0 =C2=A0 =C2=A0 =C2=A0int (*)(void *, off_t, void **, in= t));<br> > > > +static int validate_sblock(struct fs *, int);<br> > > ><br> > > >=C2=A0 /*<br> > > >=C2=A0 =C2=A0* Read a superblock from the devfd device.<br> > > > @@ -141,7 +144,7 @@ static int readsuper(void *, struct fs *= *, off_t,<br> > > int, in<br> > > > t,<br> > > >=C2=A0 =C2=A0*=C2=A0 =C2=A0 =C2=A0EIO: non-existent or trunca= ted superblock.<br> > > >=C2=A0 =C2=A0*=C2=A0 =C2=A0 =C2=A0EIO: error reading summary = information.<br> > > >=C2=A0 =C2=A0*=C2=A0 =C2=A0 =C2=A0ENOENT: no usable known sup= erblock found.<br> > > > - *=C2=A0 =C2=A0 =C2=A0ENOSPC: failed to allocate space for = the superblock.<br> > > > + *=C2=A0 =C2=A0 =C2=A0ENOMEM: failed to allocate space for = the superblock.<br> > > >=C2=A0 =C2=A0*=C2=A0 =C2=A0 =C2=A0EINVAL: The previous newfs = operation on this volume did not<br> > > complete.<br> > > >=C2=A0 =C2=A0*=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0The administr= ator must complete newfs before using this<br> > > volume.<br> > > >=C2=A0 =C2=A0*/<br> > > > @@ -152,7 +155,8 @@ ffs_sbget(void *devfd, struct fs **fsp, = off_t<br> > > altsblock,<br> > > >=C2=A0 {<br> > > >=C2=A0 =C2=A0 =C2=A0 =C2=A0struct fs *fs;<br> > > >=C2=A0 =C2=A0 =C2=A0 =C2=A0struct fs_summary_info *fs_si;<br> > > > -=C2=A0 =C2=A0 =C2=A0int i, error, size, blks;<br> > > > +=C2=A0 =C2=A0 =C2=A0int i, error;<br> > > > +=C2=A0 =C2=A0 =C2=A0uint64_t size, blks;<br> > > >=C2=A0 =C2=A0 =C2=A0 =C2=A0uint8_t *space;<br> > > >=C2=A0 =C2=A0 =C2=A0 =C2=A0int32_t *lp;<br> > > >=C2=A0 =C2=A0 =C2=A0 =C2=A0char *buf;<br> > > > @@ -190,17 +194,16 @@ ffs_sbget(void *devfd, struct fs **fsp= , off_t<br> > > altsblock<br> > > > ,<br> > > >=C2=A0 =C2=A0 =C2=A0 =C2=A0if (fs->fs_contigsumsize > 0= )<br> > > >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0size += =3D fs->fs_ncg * sizeof(int32_t);<br> > > >=C2=A0 =C2=A0 =C2=A0 =C2=A0size +=3D fs->fs_ncg * sizeof(u= _int8_t);<br> > > > -=C2=A0 =C2=A0 =C2=A0/* When running in libufs or libsa, UFS= _MALLOC may fail */<br> > > > -=C2=A0 =C2=A0 =C2=A0if ((fs_si =3D UFS_MALLOC(sizeof(*fs_si= ), filltype, M_WAITOK)) =3D=3D<br> > > NULL) {<br> > > > +=C2=A0 =C2=A0 =C2=A0if ((fs_si =3D UFS_MALLOC(sizeof(*fs_si= ), filltype, M_NOWAIT)) =3D=3D<br> > > NULL) {<br> > > >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0UFS_FR= EE(fs, filltype);<br> > > > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return (ENO= SPC);<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return (ENO= MEM);<br> > > >=C2=A0 =C2=A0 =C2=A0 =C2=A0}<br> > > >=C2=A0 =C2=A0 =C2=A0 =C2=A0bzero(fs_si, sizeof(*fs_si));<br> > > >=C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_si =3D fs_si;<br> > > > -=C2=A0 =C2=A0 =C2=A0if ((space =3D UFS_MALLOC(size, filltyp= e, M_WAITOK)) =3D=3D NULL) {<br> > > > +=C2=A0 =C2=A0 =C2=A0if ((space =3D UFS_MALLOC(size, filltyp= e, M_NOWAIT)) =3D=3D NULL) {<br> > > >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0UFS_FR= EE(fs->fs_si, filltype);<br> > > >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0UFS_FR= EE(fs, filltype);<br> > > > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return (ENO= SPC);<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return (ENO= MEM);<br> > > >=C2=A0 =C2=A0 =C2=A0 =C2=A0}<br> > > >=C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_csp =3D (struct csum *)s= pace;<br> > > >=C2=A0 =C2=A0 =C2=A0 =C2=A0for (i =3D 0; i < blks; i +=3D = fs->fs_frag) {<br> > > > @@ -253,16 +256,8 @@ readsuper(void *devfd, struct fs **fsp,= off_t<br> > > sblockloc,<br> > > >=C2=A0 int isaltsblk,<br> > > >=C2=A0 =C2=A0 =C2=A0 =C2=A0fs =3D *fsp;<br> > > >=C2=A0 =C2=A0 =C2=A0 =C2=A0if (fs->fs_magic =3D=3D FS_BAD_= MAGIC)<br> > > >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return= (EINVAL);<br> > > > -=C2=A0 =C2=A0 =C2=A0if (!(((fs->fs_magic =3D=3D FS_UFS1_= MAGIC && (isaltsblk ||<br> > > > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0sblockloc <=3D = SBLOCK_UFS1)) ||<br> > > > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (fs->fs_magic =3D=3D = FS_UFS2_MAGIC && (isaltsblk ||<br> > > > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0sblockloc =3D=3D f= s->fs_sblockloc))) &&<br> > > > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_ncg >=3D 1 &= amp;&<br> > > > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_bsize >=3D M= INBSIZE &&<br> > > > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_bsize <=3D M= AXBSIZE &&<br> > > > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_bsize >=3D r= oundup(sizeof(struct fs), DEV_BSIZE) &&<br> > > > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_sbsize <=3D = SBLOCKSIZE))<br> > > > -=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return (ENO= ENT);<br> > > > +=C2=A0 =C2=A0 =C2=A0if ((error =3D validate_sblock(fs, isal= tsblk)) !=3D 0)<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return (err= or);<br> > > >=C2=A0 =C2=A0 =C2=A0 =C2=A0/*<br> > > >=C2=A0 =C2=A0 =C2=A0 =C2=A0 * If the filesystem has been run = on a kernel without<br> > > >=C2=A0 =C2=A0 =C2=A0 =C2=A0 * metadata check hashes, disable = them.<br> > > > @@ -310,6 +305,140 @@ readsuper(void *devfd, struct fs **fsp= , off_t<br> > > sblockloc<br> > > > , int isaltsblk,<br> > > >=C2=A0 =C2=A0 =C2=A0 =C2=A0return (0);<br> > > >=C2=A0 }<br> > > ><br> > > > +/*<br> > > > + * Verify the filesystem values.<br> > > > + */<br> > > > +#define ILOG2(num) (fls(num) - 1)<br> > > > +<br> > > > +static int<br> > > > +validate_sblock(struct fs *fs, int isaltsblk)<br> > > > +{<br> > > > +=C2=A0 =C2=A0 =C2=A0int i, sectorsize;<br> > > > +=C2=A0 =C2=A0 =C2=A0u_int64_t maxfilesize, minfpg, sizepb;<= br> > > > +<br> > > > +=C2=A0 =C2=A0 =C2=A0sectorsize =3D dbtob(1);<br> > > > +=C2=A0 =C2=A0 =C2=A0if (fs->fs_magic =3D=3D FS_UFS2_MAGI= C) {<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if ((!isalt= sblk && (fs->fs_sblockloc !=3D SBLOCK_UFS2 ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0fs->fs_sblockactualloc !=3D SBLOCK_UFS2)) ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0fs->fs_maxsymlinklen !=3D ((UFS_NDADDR + UFS_NIADDR) *<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0sizeof(ufs2_daddr_t)) ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0fs->fs_nindir !=3D fs->fs_bsize / sizeof(ufs2_daddr_t) ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0fs->fs_inopb !=3D fs->fs_bsize / sizeof(struct<br> > > ufs2_dinode))<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0return (ENOENT);<br> > > > +=C2=A0 =C2=A0 =C2=A0} else if (fs->fs_magic =3D=3D FS_UF= S1_MAGIC) {<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0if ((!isalt= sblk && (fs->fs_sblockloc > SBLOCK_UFS1 ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0fs->fs_sblockactualloc !=3D SBLOCK_UFS1)) ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0fs->fs_nindir !=3D fs->fs_bsize / sizeof(ufs1_daddr_t) ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0fs->fs_inopb !=3D fs->fs_bsize / sizeof(struct<br> > > ufs1_dinode) |<br> > > > |<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0fs->fs_maxsymlinklen !=3D ((UFS_NDADDR + UFS_NIADDR) *<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0sizeof(ufs1_daddr_t)) ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0fs->fs_old_inodefmt !=3D FS_44INODEFMT ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0fs->fs_old_cgoffset !=3D 0 ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0fs->fs_old_cgmask !=3D 0xffffffff ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0fs->fs_old_size !=3D fs->fs_size ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0fs->fs_old_rotdelay !=3D 0 ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0fs->fs_old_rps !=3D 60 ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0fs->fs_old_nspf !=3D fs->fs_fsize / sectorsize ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0fs->fs_old_cpg !=3D 1 ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0fs->fs_old_interleave !=3D 1 ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0fs->fs_old_trackskew !=3D 0 ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0fs->fs_old_cpc !=3D 0 ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0fs->fs_old_postblformat !=3D 1 ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0fs->fs_old_nrpos !=3D 1 ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0fs->fs_old_spc !=3D fs->fs_fpg * fs->fs_old_nspf ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0fs->fs_old_nsect !=3D fs->fs_old_spc ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0fs->fs_old_npsect !=3D fs->fs_old_spc ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0fs->fs_old_dsize !=3D fs->fs_dsize ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0fs->fs_old_ncyl !=3D fs->fs_ncg)<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0return (ENOENT);<br> > > > +=C2=A0 =C2=A0 =C2=A0} else {<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return (ENO= ENT);<br> > > > +=C2=A0 =C2=A0 =C2=A0}<br> > > > +=C2=A0 =C2=A0 =C2=A0if (fs->fs_bsize < MINBSIZE || fs= ->fs_bsize > MAXBSIZE ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_bsize < roun= dup(sizeof(struct fs), DEV_BSIZE) ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_sbsize > SBL= OCKSIZE || fs->fs_sbsize < fs->fs_fsize ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0!powerof2(fs->fs_bsize= ))<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return (ENO= ENT);<br> > > > +=C2=A0 =C2=A0 =C2=A0if (fs->fs_fsize < sectorsize || = fs->fs_fsize > fs->fs_bsize ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_fsize * MAXFRAG= < fs->fs_bsize ||<br> > > !powerof2(fs->fs_fsize))<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return (ENO= ENT);<br> > > > +=C2=A0 =C2=A0 =C2=A0if (fs->fs_maxbsize < fs->fs_b= size || !powerof2(fs->fs_maxbsize) ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_maxbsize > F= S_MAXCONTIG * fs->fs_bsize)<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return (ENO= ENT);<br> > > > +=C2=A0 =C2=A0 =C2=A0if (fs->fs_bmask !=3D ~(fs->fs_bs= ize - 1) ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_fmask !=3D ~(fs= ->fs_fsize - 1) ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_qbmask !=3D ~fs= ->fs_bmask ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_qfmask !=3D ~fs= ->fs_fmask ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_bshift !=3D ILO= G2(fs->fs_bsize) ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_fshift !=3D ILO= G2(fs->fs_fsize) ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_frag !=3D numfr= ags(fs, fs->fs_bsize) ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_fragshift !=3D = ILOG2(fs->fs_frag) ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_frag > MAXFR= AG ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_fsbtodb !=3D IL= OG2(fs->fs_fsize / sectorsize))<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return (ENO= ENT);<br> > > > +=C2=A0 =C2=A0 =C2=A0if (fs->fs_sblkno !=3D<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0roundup(how= many(fs->fs_sblockloc + SBLOCKSIZE,<br> > > fs->fs_fsize),<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0fs->fs_frag) ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_cblkno !=3D fs-= >fs_sblkno +<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0roundup(how= many(SBLOCKSIZE, fs->fs_fsize), fs->fs_frag) ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_iblkno !=3D fs-= >fs_cblkno + fs->fs_frag ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_dblkno !=3D fs-= >fs_iblkno + fs->fs_ipg / INOPF(fs) ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_cgsize !=3D fra= groundup(fs, CGSIZE(fs)))<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return (ENO= ENT);<br> > > > +=C2=A0 =C2=A0 =C2=A0if (fs->fs_csaddr !=3D cgdmin(fs, 0)= ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_cssize !=3D<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fragroundup= (fs, fs->fs_ncg * sizeof(struct csum)) ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_dsize !=3D fs-&= gt;fs_size - fs->fs_sblkno -<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_n= cg * (fs->fs_dblkno - fs->fs_sblkno) -<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0howmany(fs-= >fs_cssize, fs->fs_fsize) ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_metaspace < = 0 || fs->fs_metaspace > fs->fs_fpg / 2 ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_minfree > 99= )<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return (ENO= ENT);<br> > > > +=C2=A0 =C2=A0 =C2=A0maxfilesize =3D fs->fs_bsize * UFS_N= DADDR - 1;<br> > > > +=C2=A0 =C2=A0 =C2=A0for (sizepb =3D fs->fs_bsize, i =3D = 0; i < UFS_NIADDR; i++) {<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0sizepb *=3D= NINDIR(fs);<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0maxfilesize= +=3D sizepb;<br> > > > +=C2=A0 =C2=A0 =C2=A0}<br> > > > +=C2=A0 =C2=A0 =C2=A0if (fs->fs_maxfilesize !=3D maxfiles= ize)<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return (ENO= ENT);<br> > > > +=C2=A0 =C2=A0 =C2=A0/*<br> > > > +=C2=A0 =C2=A0 =C2=A0 * These values have a tight interactio= n with each other that<br> > > > +=C2=A0 =C2=A0 =C2=A0 * makes it hard to tightly bound them.= So we can only check<br> > > > +=C2=A0 =C2=A0 =C2=A0 * that they are within a broader possi= ble range.<br> > > > +=C2=A0 =C2=A0 =C2=A0 *<br> > > > +=C2=A0 =C2=A0 =C2=A0 * Calculate minfpg, the minimum number= of fragments that can be<br> > > > +=C2=A0 =C2=A0 =C2=A0 * in a cylinder group. The value 12289= is calculated in newfs(8)<br> > > > +=C2=A0 =C2=A0 =C2=A0 * when creating the smallest block siz= e UFS version 1 filesystem<br> > > > +=C2=A0 =C2=A0 =C2=A0 * (4096 block size) with no fragments = (4096 fragment size). That<br> > > > +=C2=A0 =C2=A0 =C2=A0 * number may be depressed even further= for very small filesystems<br> > > > +=C2=A0 =C2=A0 =C2=A0 * since newfs(8) strives to have at le= ast four cylinder groups.<br> > > > +=C2=A0 =C2=A0 =C2=A0 */<br> > > > +=C2=A0 =C2=A0 =C2=A0minfpg =3D MIN(12289, fs->fs_size / = 4);<br> > > > +=C2=A0 =C2=A0 =C2=A0if (fs->fs_ncg < 1 || fs->fs_n= cg > (fs->fs_size / minfpg) + 1 ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_fpg < minfpg= || fs->fs_fpg > fs->fs_size ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_ipg * fs->fs= _ncg > (((int64_t)(1)) << 32) - INOPB(fs) ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_ipg > fs->= ;fs_fpg || fs->fs_size < 8 * fs->fs_frag)<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return (ENO= ENT);<br> > > > +=C2=A0 =C2=A0 =C2=A0if (fs->fs_size <=3D (fs->fs_n= cg - 1) * fs->fs_fpg ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_size > fs-&g= t;fs_ncg * fs->fs_fpg)<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return (ENO= ENT);<br> > > > +=C2=A0 =C2=A0 =C2=A0/*<br> > > > +=C2=A0 =C2=A0 =C2=A0 * Maxcontig sets the default for the m= aximum number of blocks<br> > > > +=C2=A0 =C2=A0 =C2=A0 * that may be allocated sequentially. = With file system clustering<br> > > > +=C2=A0 =C2=A0 =C2=A0 * it is possible to allocate contiguou= s blocks up to the maximum<br> > > > +=C2=A0 =C2=A0 =C2=A0 * transfer size permitted by the contr= oller or buffering.<br> > > > +=C2=A0 =C2=A0 =C2=A0 */<br> > > > +=C2=A0 =C2=A0 =C2=A0if (fs->fs_maxcontig < 1 ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_maxcontig > = MAX(1, maxphys / fs->fs_bsize))<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return (ENO= ENT);<br> > > > +=C2=A0 =C2=A0 =C2=A0if (fs->fs_maxcontig < 0 ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(fs->fs_maxcontig =3D= =3D 0 && fs->fs_contigsumsize !=3D 0) ||<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0(fs->fs_maxcontig >= 1 &&<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0fs->fs_contigsumsize != =3D MIN(fs->fs_maxcontig, FS_MAXCONTIG)))<br> > > > +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return (ENO= ENT);<br> > > > +=C2=A0 =C2=A0 =C2=A0return (0);<br> > > > +}<br> > > > +<br> > > >=C2=A0 /*<br> > > >=C2=A0 =C2=A0* Write a superblock to the devfd device from th= e memory pointed to by<br> > > fs.<br> > > >=C2=A0 =C2=A0* Write out the superblock summary information i= f it is present.<br> > > ><br> > ><br> > > Hi Kirk,<br> > ><br> > > This patch broke loader on one of my machines.<br> > ><br> > > I get the following error:<br> > ><br> > > LUA ERROR: Cannot open /boot/lua/loader.lua: no such file or dire= ctory"<br> > > can't load kernel<br> > ><br> > > Of course booting from my rescue worked.<br> > ><br> > > Copying loader* from /boot on the rescue disk to /boot works arou= nd the<br> > > problem.<br> > ><br> > > Backing up, newfs, and restoring the root filesystem, using my re= scue disk<br> > > also didn't work around the problem.<br> > ><br> > > Reverting this patch provided permanent relief.<br> > ><br> > > Loader could read the filesystems on my rescue disk, which had bl= ocksizes<br> > > of 16K but not those on my boot disk which had blocksizes of 32K.= <br> > ><br> > > My three machines downstairs, all AMD gear with UFS blocksize of = 32K, had<br> > > no no problems with this whereas my laptop, an Intel, had the pro= blem.<br> > ><br> > > To repeat, a newly created filesystem restored from backup using = my rescue<br> > > disk didn't resolve the problem.<br> > ><br> > ><br> > > --<br> > > Cheers,<br> > > Cy Schubert <<a href=3D"mailto:Cy.Schubert@komquats.com" targe= t=3D"_blank">Cy.Schubert@komquats.com</a>> or <<a href=3D"mailto:Cy.S= chubert@cschubert.com" target=3D"_blank">Cy.Schubert@cschubert.com</a>><= br> > > FreeBSD UNIX:=C2=A0 <cy@FreeBSD.org>=C2=A0 =C2=A0Web:=C2=A0= <a href=3D"http://www.FreeBSD.org" rel=3D"noreferrer" target=3D"_blank">ht= tp://www.FreeBSD.org</a><br> > > NTP:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0<<a href=3D"mailt= o:cy@nwtime.org" target=3D"_blank">cy@nwtime.org</a>>=C2=A0 =C2=A0 Web:= =C2=A0 <a href=3D"https://nwtime.org" rel=3D"noreferrer" target=3D"_blank">= https://nwtime.org</a><br> > ><br> > >=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0e**(i*pi)+1=3D0<br> > ><br> > ><br> > ><br> <br> <br> </blockquote></div></div> --0000000000008603c305e04240eb--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CANCZdfoqpDO9-APZytimd9TpPGsnaj0%2BwJBfdxv%2Bo2NnOX5ZUQ>