The branch stable/14 has been updated by mckusick:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=26c483aec039b01182bfef468fd7979895bcb645

commit 26c483aec039b01182bfef468fd7979895bcb645
Author:     Kirk McKusick <mckus...@freebsd.org>
AuthorDate: 2025-01-16 18:43:48 +0000
Commit:     Kirk McKusick <mckus...@freebsd.org>
CommitDate: 2025-01-23 06:39:45 +0000

    Fix backward compatibility with UFS1 filesystems created before June 2002
    
    Reviewed-by: kib
    Tested-by:   Peter Holm
    Differential-Revision: https://reviews.freebsd.org/D48472
    (cherry picked from commit 661ca921e8cd56b17fc6615bc7e596e56e0e7c31)
---
 sbin/growfs/debug.c        |  2 -
 sys/ufs/ffs/ffs_extern.h   |  2 +-
 sys/ufs/ffs/ffs_snapshot.c |  2 +-
 sys/ufs/ffs/ffs_softdep.c  |  4 +-
 sys/ufs/ffs/ffs_subr.c     | 81 +++++++++++++++++++++++++++++++++++++-
 sys/ufs/ffs/ffs_vfsops.c   | 96 +---------------------------------------------
 sys/ufs/ffs/fs.h           |  5 ++-
 7 files changed, 88 insertions(+), 104 deletions(-)

diff --git a/sbin/growfs/debug.c b/sbin/growfs/debug.c
index 456e67dbc5c2..ab4539d06a69 100644
--- a/sbin/growfs/debug.c
+++ b/sbin/growfs/debug.c
@@ -305,8 +305,6 @@ dbg_dump_fs(struct fs *sb, const char *comment)
            sb->fs_avgfilesize);
        fprintf(dbg_log, "avgfpdir          int32_t          0x%08x\n",
            sb->fs_avgfpdir);
-       fprintf(dbg_log, "save_cgsize       int32_t          0x%08x\n",
-           sb->fs_save_cgsize);
        fprintf(dbg_log, "flags             int32_t          0x%08x\n",
            sb->fs_flags);
        fprintf(dbg_log, "contigsumsize     int32_t          0x%08x\n",
diff --git a/sys/ufs/ffs/ffs_extern.h b/sys/ufs/ffs/ffs_extern.h
index f0c6eaaa1088..56e2fdd6ce51 100644
--- a/sys/ufs/ffs/ffs_extern.h
+++ b/sys/ufs/ffs/ffs_extern.h
@@ -84,7 +84,7 @@ int   ffs_inotovp(struct mount *, ino_t, uint64_t, int, 
struct vnode **,
            int);
 int    ffs_isblock(struct fs *, uint8_t *, ufs1_daddr_t);
 int    ffs_isfreeblock(struct fs *, uint8_t *, ufs1_daddr_t);
-void   ffs_oldfscompat_write(struct fs *, struct ufsmount *);
+void   ffs_oldfscompat_write(struct fs *);
 int    ffs_own_mount(const struct mount *mp);
 int    ffs_sbsearch(void *, struct fs **, int, struct malloc_type *,
            int (*)(void *, off_t, void **, int));
diff --git a/sys/ufs/ffs/ffs_snapshot.c b/sys/ufs/ffs/ffs_snapshot.c
index ae3b444a19e9..77480f36e827 100644
--- a/sys/ufs/ffs/ffs_snapshot.c
+++ b/sys/ufs/ffs/ffs_snapshot.c
@@ -840,7 +840,7 @@ resumefs:
                copy_fs->fs_fmod = 0;
                bpfs = (struct fs *)&nbp->b_data[loc];
                bcopy((caddr_t)copy_fs, (caddr_t)bpfs, (uint64_t)fs->fs_sbsize);
-               ffs_oldfscompat_write(bpfs, ump);
+               ffs_oldfscompat_write(bpfs);
                bpfs->fs_ckhash = ffs_calc_sbhash(bpfs);
                bawrite(nbp);
        }
diff --git a/sys/ufs/ffs/ffs_softdep.c b/sys/ufs/ffs/ffs_softdep.c
index fa2b0bf24366..316c978e1bdf 100644
--- a/sys/ufs/ffs/ffs_softdep.c
+++ b/sys/ufs/ffs/ffs_softdep.c
@@ -9941,7 +9941,7 @@ clear_unlinked_inodedep( struct inodedep *inodedep)
                if (pino == 0) {
                        bcopy((caddr_t)fs, bp->b_data, (uint64_t)fs->fs_sbsize);
                        bpfs = (struct fs *)bp->b_data;
-                       ffs_oldfscompat_write(bpfs, ump);
+                       ffs_oldfscompat_write(bpfs);
                        softdep_setup_sbupdate(ump, bpfs, bp);
                        /*
                         * Because we may have made changes to the superblock,
@@ -9973,7 +9973,7 @@ clear_unlinked_inodedep( struct inodedep *inodedep)
                            (int)fs->fs_sbsize, 0, 0, 0);
                        bcopy((caddr_t)fs, bp->b_data, (uint64_t)fs->fs_sbsize);
                        bpfs = (struct fs *)bp->b_data;
-                       ffs_oldfscompat_write(bpfs, ump);
+                       ffs_oldfscompat_write(bpfs);
                        softdep_setup_sbupdate(ump, bpfs, bp);
                        /*
                         * Because we may have made changes to the superblock,
diff --git a/sys/ufs/ffs/ffs_subr.c b/sys/ufs/ffs/ffs_subr.c
index fc43b4c06e7f..1792e1628a48 100644
--- a/sys/ufs/ffs/ffs_subr.c
+++ b/sys/ufs/ffs/ffs_subr.c
@@ -126,6 +126,7 @@ ffs_update_dinode_ckhash(struct fs *fs, struct ufs2_dinode 
*dip)
 static off_t sblock_try[] = SBLOCKSEARCH;
 static int readsuper(void *, struct fs **, off_t, int,
        int (*)(void *, off_t, void **, int));
+static void ffs_oldfscompat_read(struct fs *, ufs2_daddr_t);
 static int validate_sblock(struct fs *, int);
 
 /*
@@ -271,6 +272,7 @@ readsuper(void *devfd, struct fs **fsp, off_t sblockloc, 
int flags,
        if (fs->fs_magic == FS_UFS1_MAGIC && (flags & UFS_ALTSBLK) == 0 &&
            fs->fs_bsize == SBLOCK_UFS2 && sblockloc == SBLOCK_UFS2)
                return (ENOENT);
+       ffs_oldfscompat_read(fs, sblockloc);
        if ((error = validate_sblock(fs, flags)) > 0)
                return (error);
        /*
@@ -319,6 +321,83 @@ readsuper(void *devfd, struct fs **fsp, off_t sblockloc, 
int flags,
        return (0);
 }
 
+/*
+ * Sanity checks for loading old filesystem superblocks.
+ * See ffs_oldfscompat_write below for unwound actions.
+ *
+ * XXX - Parts get retired eventually.
+ * Unfortunately new bits get added.
+ */
+static void
+ffs_oldfscompat_read(struct fs *fs, ufs2_daddr_t sblockloc)
+{
+       uint64_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_maxbsize != fs->fs_bsize) {
+               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_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;
+       }
+       if (fs->fs_magic == FS_UFS1_MAGIC &&
+           fs->fs_old_inodefmt < FS_44INODEFMT) {
+               fs->fs_maxfilesize = ((uint64_t)1 << 31) - 1;
+               fs->fs_qbmask = ~fs->fs_bmask;
+               fs->fs_qfmask = ~fs->fs_fmask;
+       }
+       if (fs->fs_magic == FS_UFS1_MAGIC) {
+               fs->fs_save_maxfilesize = fs->fs_maxfilesize;
+               maxfilesize = (uint64_t)0x80000000 * fs->fs_bsize - 1;
+               if (fs->fs_maxfilesize > maxfilesize)
+                       fs->fs_maxfilesize = maxfilesize;
+       }
+       /* Compatibility for old filesystems */
+       if (fs->fs_avgfilesize <= 0)
+               fs->fs_avgfilesize = AVFILESIZ;
+       if (fs->fs_avgfpdir <= 0)
+               fs->fs_avgfpdir = AFPDIR;
+}
+
+/*
+ * Unwinding superblock updates for old filesystems.
+ * See ffs_oldfscompat_read above for details.
+ *
+ * XXX - Parts get retired eventually.
+ * Unfortunately new bits get added.
+ */
+void
+ffs_oldfscompat_write(struct fs *fs)
+{
+
+       /*
+        * Copy back UFS2 updated fields that UFS1 inspects.
+        */
+       if (fs->fs_magic == FS_UFS1_MAGIC) {
+               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 = fs->fs_save_maxfilesize;
+       }
+}
+
 /*
  * Verify the filesystem values.
  */
@@ -564,7 +643,7 @@ validate_sblock(struct fs *fs, int flags)
                sizepb *= NINDIR(fs);
                maxfilesize += sizepb;
        }
-       WCHK(fs->fs_maxfilesize, !=, maxfilesize, %jd);
+       WCHK(fs->fs_maxfilesize, >, maxfilesize, %jd);
        /*
         * These values have a tight interaction with each other that
         * makes it hard to tightly bound them. So we can only check
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index 2b7353d157e2..16a955bc7f6d 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -85,8 +85,6 @@ static uma_zone_t uma_inode, uma_ufs1, uma_ufs2;
 VFS_SMR_DECLARE;
 
 static int     ffs_mountfs(struct vnode *, struct mount *, struct thread *);
-static void    ffs_oldfscompat_read(struct fs *, struct ufsmount *,
-                   ufs2_daddr_t);
 static void    ffs_ifree(struct ufsmount *ump, struct inode *ip);
 static int     ffs_sync_lazy(struct mount *mp);
 static int     ffs_use_bread(void *devfd, off_t loc, void **bufp, int size);
@@ -797,7 +795,6 @@ ffs_reload(struct mount *mp, int flags)
        fs = VFSTOUFS(mp)->um_fs = newfs;
        ump->um_bsize = fs->fs_bsize;
        ump->um_maxsymlinklen = fs->fs_maxsymlinklen;
-       ffs_oldfscompat_read(fs, VFSTOUFS(mp), fs->fs_sblockloc);
        UFS_LOCK(ump);
        if (fs->fs_pendingblocks != 0 || fs->fs_pendinginodes != 0) {
                printf("WARNING: %s: reload pending error: blocks %jd "
@@ -1012,7 +1009,6 @@ ffs_mountfs(struct vnode *odevvp, struct mount *mp, 
struct thread *td)
                ump->um_check_blkno = NULL;
        mtx_init(UFS_MTX(ump), "FFS", "FFS Lock", MTX_DEF);
        sx_init(&ump->um_checkpath_lock, "uchpth");
-       ffs_oldfscompat_read(fs, ump, fs->fs_sblockloc);
        fs->fs_ronly = ronly;
        fs->fs_active = NULL;
        mp->mnt_data = ump;
@@ -1221,96 +1217,6 @@ ffs_use_bread(void *devfd, off_t loc, void **bufp, int 
size)
        return (0);
 }
 
-static int bigcgs = 0;
-SYSCTL_INT(_debug, OID_AUTO, bigcgs, CTLFLAG_RW, &bigcgs, 0, "");
-
-/*
- * Sanity checks for loading old filesystem superblocks.
- * See ffs_oldfscompat_write below for unwound actions.
- *
- * XXX - Parts get retired eventually.
- * Unfortunately new bits get added.
- */
-static void
-ffs_oldfscompat_read(struct fs *fs,
-       struct ufsmount *ump,
-       ufs2_daddr_t 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_maxbsize != fs->fs_bsize) {
-               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_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;
-       }
-       if (fs->fs_magic == FS_UFS1_MAGIC &&
-           fs->fs_old_inodefmt < FS_44INODEFMT) {
-               fs->fs_maxfilesize = ((uint64_t)1 << 31) - 1;
-               fs->fs_qbmask = ~fs->fs_bmask;
-               fs->fs_qfmask = ~fs->fs_fmask;
-       }
-       if (fs->fs_magic == FS_UFS1_MAGIC) {
-               ump->um_savedmaxfilesize = fs->fs_maxfilesize;
-               maxfilesize = (uint64_t)0x80000000 * fs->fs_bsize - 1;
-               if (fs->fs_maxfilesize > maxfilesize)
-                       fs->fs_maxfilesize = maxfilesize;
-       }
-       /* Compatibility for old filesystems */
-       if (fs->fs_avgfilesize <= 0)
-               fs->fs_avgfilesize = AVFILESIZ;
-       if (fs->fs_avgfpdir <= 0)
-               fs->fs_avgfpdir = AFPDIR;
-       if (bigcgs) {
-               fs->fs_save_cgsize = fs->fs_cgsize;
-               fs->fs_cgsize = fs->fs_bsize;
-       }
-}
-
-/*
- * Unwinding superblock updates for old filesystems.
- * See ffs_oldfscompat_read above for details.
- *
- * XXX - Parts get retired eventually.
- * Unfortunately new bits get added.
- */
-void
-ffs_oldfscompat_write(struct fs *fs, struct ufsmount *ump)
-{
-
-       /*
-        * Copy back UFS2 updated fields that UFS1 inspects.
-        */
-       if (fs->fs_magic == FS_UFS1_MAGIC) {
-               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;
-       }
-       if (bigcgs) {
-               fs->fs_cgsize = fs->fs_save_cgsize;
-               fs->fs_save_cgsize = 0;
-       }
-}
-
 /*
  * unmount system call
  */
@@ -2194,7 +2100,7 @@ ffs_use_bwrite(void *devfd, off_t loc, void *buf, int 
size)
        UFS_UNLOCK(ump);
        fs = (struct fs *)bp->b_data;
        fs->fs_fmod = 0;
-       ffs_oldfscompat_write(fs, ump);
+       ffs_oldfscompat_write(fs);
        fs->fs_si = NULL;
        /* Recalculate the superblock hash */
        fs->fs_ckhash = ffs_calc_sbhash(fs);
diff --git a/sys/ufs/ffs/fs.h b/sys/ufs/ffs/fs.h
index 5769cd7776b4..c634c73e9a39 100644
--- a/sys/ufs/ffs/fs.h
+++ b/sys/ufs/ffs/fs.h
@@ -413,7 +413,8 @@ struct fs {
        int64_t  fs_unrefs;             /* number of unreferenced inodes */
        int64_t  fs_providersize;       /* size of underlying GEOM provider */
        int64_t  fs_metaspace;          /* size of area reserved for metadata */
-       int64_t  fs_sparecon64[13];     /* old rotation block list head */
+       uint64_t fs_save_maxfilesize;   /* save old UFS1 maxfilesize */
+       int64_t  fs_sparecon64[12];     /* old rotation block list head */
        int64_t  fs_sblockactualloc;    /* byte offset of this superblock */
        int64_t  fs_sblockloc;          /* byte offset of standard superblock */
        struct  csum_total fs_cstotal;  /* (u) cylinder summary information */
@@ -426,7 +427,7 @@ struct fs {
        uint32_t fs_snapinum[FSMAXSNAP];/* list of snapshot inode numbers */
        uint32_t fs_avgfilesize;        /* expected average file size */
        uint32_t fs_avgfpdir;           /* expected # of files per directory */
-       int32_t  fs_save_cgsize;        /* save real cg size to use fs_bsize */
+       uint32_t fs_available_spare;    /* old scratch space */
        ufs_time_t fs_mtime;            /* Last mount or fsck time. */
        int32_t  fs_sujfree;            /* SUJ free list */
        int32_t  fs_sparecon32[21];     /* reserved for future constants */

Reply via email to