From owner-svn-src-all@freebsd.org Fri Jun 19 01:02:56 2020 Return-Path: Delivered-To: svn-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 31FFF339E7A; Fri, 19 Jun 2020 01:02:56 +0000 (UTC) (envelope-from mckusick@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 49p0sX0pr8z4KjL; Fri, 19 Jun 2020 01:02:56 +0000 (UTC) (envelope-from mckusick@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id F0FF212AEF; Fri, 19 Jun 2020 01:02:55 +0000 (UTC) (envelope-from mckusick@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id 05J12tBv015470; Fri, 19 Jun 2020 01:02:55 GMT (envelope-from mckusick@FreeBSD.org) Received: (from mckusick@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id 05J12rRt015459; Fri, 19 Jun 2020 01:02:53 GMT (envelope-from mckusick@FreeBSD.org) Message-Id: <202006190102.05J12rRt015459@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: mckusick set sender to mckusick@FreeBSD.org using -f From: Kirk McKusick Date: Fri, 19 Jun 2020 01:02:53 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r362358 - in head: sbin/newfs stand/libsa sys/geom/journal sys/geom/label sys/ufs/ffs usr.sbin/fstyp usr.sbin/quot X-SVN-Group: head X-SVN-Commit-Author: mckusick X-SVN-Commit-Paths: in head: sbin/newfs stand/libsa sys/geom/journal sys/geom/label sys/ufs/ffs usr.sbin/fstyp usr.sbin/quot X-SVN-Commit-Revision: 362358 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.33 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 19 Jun 2020 01:02:56 -0000 Author: mckusick Date: Fri Jun 19 01:02:53 2020 New Revision: 362358 URL: https://svnweb.freebsd.org/changeset/base/362358 Log: Move the pointers stored in the superblock into a separate fs_summary_info structure. This change was originally done by the CheriBSD project as they need larger pointers that do not fit in the existing superblock. This cleanup of the superblock eases the task of the commit that immediately follows this one. Suggested by: brooks Reviewed by: kib PR: 246983 Sponsored by: Netflix Modified: head/sbin/newfs/mkfs.c head/stand/libsa/ufs.c head/sys/geom/journal/g_journal_ufs.c head/sys/geom/label/g_label_ufs.c head/sys/ufs/ffs/ffs_snapshot.c head/sys/ufs/ffs/ffs_subr.c head/sys/ufs/ffs/ffs_vfsops.c head/sys/ufs/ffs/fs.h head/usr.sbin/fstyp/ufs.c head/usr.sbin/quot/quot.c Modified: head/sbin/newfs/mkfs.c ============================================================================== --- head/sbin/newfs/mkfs.c Fri Jun 19 00:45:29 2020 (r362357) +++ head/sbin/newfs/mkfs.c Fri Jun 19 01:02:53 2020 (r362358) @@ -134,6 +134,10 @@ mkfs(struct partition *pp, char *fsys) utime = 1000000000; else time(&utime); + if ((sblock.fs_si = malloc(sizeof(struct fs_summary_info))) == NULL) { + printf("Superblock summary info allocation failed.\n"); + exit(18); + } sblock.fs_old_flags = FS_FLAGS_UPDATED; sblock.fs_flags = 0; if (Uflag) @@ -548,6 +552,10 @@ restart: } } } + /* + * Reference the summary information so it will also be written. + */ + sblock.fs_csp = fscs; if (!Nflag && sbput(disk.d_fd, &disk.d_fs, 0) != 0) err(1, "sbput: %s", disk.d_error); if (Xflag == 1) { @@ -611,10 +619,6 @@ restart: printf("** Exiting on Xflag 3\n"); exit(0); } - /* - * Reference the summary information so it will also be written. - */ - sblock.fs_csp = fscs; if (sbput(disk.d_fd, &disk.d_fs, 0) != 0) err(1, "sbput: %s", disk.d_error); /* Modified: head/stand/libsa/ufs.c ============================================================================== --- head/stand/libsa/ufs.c Fri Jun 19 00:45:29 2020 (r362357) +++ head/stand/libsa/ufs.c Fri Jun 19 01:02:53 2020 (r362358) @@ -678,7 +678,11 @@ out: if (rc) { if (fp->f_buf) free(fp->f_buf); - free(fp->f_fs); + if (fp->f_fs != NULL) { + free(fp->f_fs->fs_csp); + free(fp->f_fs->fs_si); + free(fp->f_fs); + } free(fp); } return (rc); @@ -723,7 +727,11 @@ ufs_close(f) } if (fp->f_buf) free(fp->f_buf); - free(fp->f_fs); + if (fp->f_fs != NULL) { + free(fp->f_fs->fs_csp); + free(fp->f_fs->fs_si); + free(fp->f_fs); + } free(fp); return (0); } Modified: head/sys/geom/journal/g_journal_ufs.c ============================================================================== --- head/sys/geom/journal/g_journal_ufs.c Fri Jun 19 00:45:29 2020 (r362357) +++ head/sys/geom/journal/g_journal_ufs.c Fri Jun 19 01:02:53 2020 (r362358) @@ -68,6 +68,7 @@ g_journal_ufs_clean(struct mount *mp) static void g_journal_ufs_dirty(struct g_consumer *cp) { + struct fs_summary_info *fs_si; struct fs *fs; int error; @@ -83,8 +84,12 @@ g_journal_ufs_dirty(struct g_consumer *cp) GJ_DEBUG(0, "clean=%d flags=0x%x", fs->fs_clean, fs->fs_flags); fs->fs_clean = 0; fs->fs_flags |= FS_NEEDSFSCK | FS_UNCLEAN; + fs_si = fs->fs_si; + fs->fs_si = NULL; error = ffs_sbput(cp, fs, fs->fs_sblockloc, g_use_g_write_data); + fs->fs_si = fs_si; g_free(fs->fs_csp); + g_free(fs->fs_si); g_free(fs); if (error != 0) { GJ_DEBUG(0, "Cannot mark file system %s as dirty " Modified: head/sys/geom/label/g_label_ufs.c ============================================================================== --- head/sys/geom/label/g_label_ufs.c Fri Jun 19 00:45:29 2020 (r362357) +++ head/sys/geom/label/g_label_ufs.c Fri Jun 19 01:02:53 2020 (r362358) @@ -122,6 +122,7 @@ g_label_ufs_taste_common(struct g_consumer *cp, char * } out: g_free(fs->fs_csp); + g_free(fs->fs_si); g_free(fs); } Modified: head/sys/ufs/ffs/ffs_snapshot.c ============================================================================== --- head/sys/ufs/ffs/ffs_snapshot.c Fri Jun 19 00:45:29 2020 (r362357) +++ head/sys/ufs/ffs/ffs_snapshot.c Fri Jun 19 01:02:53 2020 (r362358) @@ -480,6 +480,8 @@ restart: */ copy_fs = malloc((u_long)fs->fs_bsize, M_UFSMNT, M_WAITOK); bcopy(fs, copy_fs, fs->fs_sbsize); + copy_fs->fs_si = malloc(sizeof(struct fs_summary_info), M_UFSMNT, + M_ZERO | M_WAITOK); if ((fs->fs_flags & (FS_UNCLEAN | FS_NEEDSFSCK)) == 0) copy_fs->fs_clean = 1; size = fs->fs_bsize < SBLOCKSIZE ? fs->fs_bsize : SBLOCKSIZE; @@ -501,6 +503,7 @@ restart: len, KERNCRED, &bp)) != 0) { brelse(bp); free(copy_fs->fs_csp, M_UFSMNT); + free(copy_fs->fs_si, M_UFSMNT); free(copy_fs, M_UFSMNT); copy_fs = NULL; goto out1; @@ -611,6 +614,7 @@ loop: vdrop(xvp); if (error) { free(copy_fs->fs_csp, M_UFSMNT); + free(copy_fs->fs_si, M_UFSMNT); free(copy_fs, M_UFSMNT); copy_fs = NULL; MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp); @@ -624,6 +628,7 @@ loop: error = softdep_journal_lookup(mp, &xvp); if (error) { free(copy_fs->fs_csp, M_UFSMNT); + free(copy_fs->fs_si, M_UFSMNT); free(copy_fs, M_UFSMNT); copy_fs = NULL; goto out1; @@ -842,6 +847,7 @@ out1: } done: free(copy_fs->fs_csp, M_UFSMNT); + free(copy_fs->fs_si, M_UFSMNT); free(copy_fs, M_UFSMNT); copy_fs = NULL; out: Modified: head/sys/ufs/ffs/ffs_subr.c ============================================================================== --- head/sys/ufs/ffs/ffs_subr.c Fri Jun 19 00:45:29 2020 (r362357) +++ head/sys/ufs/ffs/ffs_subr.c Fri Jun 19 01:02:53 2020 (r362358) @@ -158,6 +158,7 @@ ffs_sbget(void *devfd, struct fs **fsp, off_t altsbloc int (*readfunc)(void *devfd, off_t loc, void **bufp, int size)) { struct fs *fs; + struct fs_summary_info *fs_si; int i, error, size, blks; uint8_t *space; int32_t *lp; @@ -201,7 +202,14 @@ ffs_sbget(void *devfd, struct fs **fsp, off_t altsbloc 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) { + UFS_FREE(fs, filltype); + return (ENOSPC); + } + bzero(fs_si, sizeof(*fs_si)); + fs->fs_si = fs_si; if ((space = UFS_MALLOC(size, filltype, M_WAITOK)) == NULL) { + UFS_FREE(fs->fs_si, filltype); UFS_FREE(fs, filltype); return (ENOSPC); } @@ -217,6 +225,7 @@ ffs_sbget(void *devfd, struct fs **fsp, off_t altsbloc if (buf != NULL) UFS_FREE(buf, filltype); UFS_FREE(fs->fs_csp, filltype); + UFS_FREE(fs->fs_si, filltype); UFS_FREE(fs, filltype); return (error); } @@ -299,7 +308,7 @@ readsuper(void *devfd, struct fs **fsp, off_t sblocklo /* Have to set for old filesystems that predate this field */ fs->fs_sblockactualloc = sblockloc; /* Not yet any summary information */ - fs->fs_csp = NULL; + fs->fs_si = NULL; return (0); } return (ENOENT); @@ -325,7 +334,7 @@ ffs_sbput(void *devfd, struct fs *fs, off_t loc, * If there is summary information, write it first, so if there * is an error, the superblock will not be marked as clean. */ - if (fs->fs_csp != NULL) { + if (fs->fs_si != NULL && fs->fs_csp != NULL) { blks = howmany(fs->fs_cssize, fs->fs_fsize); space = (uint8_t *)fs->fs_csp; for (i = 0; i < blks; i += fs->fs_frag) { Modified: head/sys/ufs/ffs/ffs_vfsops.c ============================================================================== --- head/sys/ufs/ffs/ffs_vfsops.c Fri Jun 19 00:45:29 2020 (r362357) +++ head/sys/ufs/ffs/ffs_vfsops.c Fri Jun 19 01:02:53 2020 (r362358) @@ -885,14 +885,11 @@ ffs_reload(struct mount *mp, struct thread *td, int fl return (EIO); /* XXX needs translation */ } /* - * Copy pointer fields back into superblock before copying in XXX - * new superblock. These should really be in the ufsmount. XXX - * Note that important parameters (eg fs_ncg) are unchanged. + * Preserve the summary information, read-only status, and + * superblock location by copying these fields into our new + * superblock before using it to update the existing superblock. */ - newfs->fs_csp = fs->fs_csp; - newfs->fs_maxcluster = fs->fs_maxcluster; - newfs->fs_contigdirs = fs->fs_contigdirs; - newfs->fs_active = fs->fs_active; + newfs->fs_si = fs->fs_si; newfs->fs_ronly = fs->fs_ronly; sblockloc = fs->fs_sblockloc; bcopy(newfs, fs, (u_int)fs->fs_sbsize); @@ -1309,6 +1306,7 @@ ffs_mountfs(odevvp, mp, td) out: if (fs != NULL) { free(fs->fs_csp, M_UFSMNT); + free(fs->fs_si, M_UFSMNT); free(fs, M_UFSMNT); } if (cp != NULL) { @@ -1546,6 +1544,7 @@ ffs_unmount(mp, mntflags) mp->mnt_gjprovider = NULL; } free(fs->fs_csp, M_UFSMNT); + free(fs->fs_si, M_UFSMNT); free(fs, M_UFSMNT); if (ump->um_fsfail_task != NULL) free(ump->um_fsfail_task, M_UFSMNT); @@ -2294,10 +2293,7 @@ ffs_use_bwrite(void *devfd, off_t loc, void *buf, int bcopy((caddr_t)fs, bp->b_data, (u_int)fs->fs_sbsize); fs = (struct fs *)bp->b_data; ffs_oldfscompat_write(fs, ump); - /* - * Because we may have made changes to the superblock, we need to - * recompute its check-hash. - */ + /* Recalculate the superblock hash */ fs->fs_ckhash = ffs_calc_sbhash(fs); if (devfdp->suspended) bp->b_flags |= B_VALIDSUSPWRT; Modified: head/sys/ufs/ffs/fs.h ============================================================================== --- head/sys/ufs/ffs/fs.h Fri Jun 19 00:45:29 2020 (r362357) +++ head/sys/ufs/ffs/fs.h Fri Jun 19 01:02:53 2020 (r362358) @@ -132,16 +132,18 @@ * of pointers to blocks of struct csum; now there are just a few * pointers and the remaining space is padded with fs_ocsp[]. * - * NOCSPTRS determines the size of this padding. One pointer (fs_csp) - * is taken away to point to a contiguous array of struct csum for - * all cylinder groups; a second (fs_maxcluster) points to an array - * of cluster sizes that is computed as cylinder groups are inspected, - * and the third points to an array that tracks the creation of new - * directories. A fourth pointer, fs_active, is used when creating - * snapshots; it points to a bitmap of cylinder groups for which the - * free-block bitmap has changed since the snapshot operation began. + * NOCSPTRS determines the size of this padding. Historically this + * space was used to store pointers to structures that summaried + * filesystem usage and layout information. However, these pointers + * left various kernel pointers in the superblock which made otherwise + * identical superblocks appear to have differences. So, all the + * pointers in the superblock were moved to a fs_summary_info structure + * reducing the superblock to having only a single pointer to this + * structure. When writing the superblock to disk, this pointer is + * temporarily NULL'ed out so that the kernel pointer will not appear + * in the on-disk copy of the superblock. */ -#define NOCSPTRS ((128 / sizeof(void *)) - 4) +#define NOCSPTRS ((128 / sizeof(void *)) - 1) /* * A summary of contiguous blocks of various sizes is maintained @@ -270,6 +272,32 @@ struct csum_total { }; /* + * Pointers to super block summary information. Placed in a separate + * structure so there is just one pointer in the superblock. + * + * The pointers in this structure are used as follows: + * fs_contigdirs references an array that tracks the creation of new + * directories + * fs_csp references a contiguous array of struct csum for + * all cylinder groups + * fs_maxcluster references an array of cluster sizes that is computed + * as cylinder groups are inspected + * fs_active is used when creating snapshots; it points to a bitmap + * of cylinder groups for which the free-block bitmap has changed + * since the snapshot operation began. + */ +struct fs_summary_info { + uint8_t *si_contigdirs; /* (u) # of contig. allocated dirs */ + struct csum *si_csp; /* (u) cg summary info buffer */ + int32_t *si_maxcluster; /* (u) max cluster in each cyl group */ + u_int *si_active; /* (u) used by snapshots to track fs */ +}; +#define fs_contigdirs fs_si->si_contigdirs +#define fs_csp fs_si->si_csp +#define fs_maxcluster fs_si->si_maxcluster +#define fs_active fs_si->si_active + +/* * Super block for an FFS filesystem. */ struct fs { @@ -340,10 +368,7 @@ struct fs { /* these fields retain the current block allocation info */ int32_t fs_cgrotor; /* last cg searched */ void *fs_ocsp[NOCSPTRS]; /* padding; was list of fs_cs buffers */ - u_int8_t *fs_contigdirs; /* (u) # of contig. allocated dirs */ - struct csum *fs_csp; /* (u) cg summary info buffer */ - int32_t *fs_maxcluster; /* (u) max cluster in each cyl group */ - u_int *fs_active; /* (u) used by snapshots to track fs */ + struct fs_summary_info *fs_si;/* In-core pointer to summary info */ int32_t fs_old_cpc; /* cyl per cycle in postbl */ int32_t fs_maxbsize; /* maximum blocking factor permitted */ int64_t fs_unrefs; /* number of unreferenced inodes */ Modified: head/usr.sbin/fstyp/ufs.c ============================================================================== --- head/usr.sbin/fstyp/ufs.c Fri Jun 19 00:45:29 2020 (r362357) +++ head/usr.sbin/fstyp/ufs.c Fri Jun 19 01:02:53 2020 (r362358) @@ -53,6 +53,9 @@ fstyp_ufs(FILE *fp, char *label, size_t labelsize) switch (sbget(fileno(fp), &fs, STDSB)) { case 0: strlcpy(label, fs->fs_volname, labelsize); + free(fs->fs_csp); + free(fs->fs_si); + free(fs); return (0); case ENOENT: /* Cannot find file system superblock */ Modified: head/usr.sbin/quot/quot.c ============================================================================== --- head/usr.sbin/quot/quot.c Fri Jun 19 00:45:29 2020 (r362357) +++ head/usr.sbin/quot/quot.c Fri Jun 19 01:02:53 2020 (r362358) @@ -567,6 +567,9 @@ quot(char *name, char *mp) printf(" (%s)",mp); putchar('\n'); (*func)(fd, fs, name); + free(fs->fs_csp); + free(fs->fs_si); + free(fs); close(fd); }