git: ae15f8ceaa85 - stable/14 - Get consistent updates for UFS superblocks. Formatting and style cleanups.
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 29 Mar 2025 00:43:41 UTC
The branch stable/14 has been updated by mckusick: URL: https://cgit.FreeBSD.org/src/commit/?id=ae15f8ceaa85e6e02e056aa151d965d82e1f200e commit ae15f8ceaa85e6e02e056aa151d965d82e1f200e Author: Kirk McKusick <mckusick@FreeBSD.org> AuthorDate: 2025-03-19 23:32:39 +0000 Commit: Kirk McKusick <mckusick@FreeBSD.org> CommitDate: 2025-03-29 00:41:04 +0000 Get consistent updates for UFS superblocks. Formatting and style cleanups. Differential Revision: https://reviews.freebsd.org/D49276 Sponsored-by: Netflix (cherry picked from commit c2cd605e8c8a15e545dfd3e50aef2f660d460b30) (cherry picked from commit 16649530b7be02a61a32b34d56e6e937734cd247) --- sys/ufs/ffs/ffs_subr.c | 112 +++++++++++++++++++++++++++++------------------ sys/ufs/ffs/ffs_vfsops.c | 42 +++++++----------- 2 files changed, 86 insertions(+), 68 deletions(-) diff --git a/sys/ufs/ffs/ffs_subr.c b/sys/ufs/ffs/ffs_subr.c index c0221c8ee2da..7a010da870db 100644 --- a/sys/ufs/ffs/ffs_subr.c +++ b/sys/ufs/ffs/ffs_subr.c @@ -343,31 +343,36 @@ ffs_oldfscompat_read(struct fs *fs, ufs2_daddr_t sblockloc) 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) { + switch (fs->fs_magic) { + case FS_UFS2_MAGIC: + /* No changes for now */ + break; + + case FS_UFS1_MAGIC: + /* + * If not yet done, update UFS1 superblock with new wider fields + */ + if (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_old_inodefmt < FS_44INODEFMT) { + fs->fs_maxfilesize = ((uint64_t)1 << 31) - 1; + fs->fs_qbmask = ~fs->fs_bmask; + fs->fs_qfmask = ~fs->fs_fmask; + } fs->fs_save_maxfilesize = fs->fs_maxfilesize; maxfilesize = (uint64_t)0x80000000 * fs->fs_bsize - 1; if (fs->fs_maxfilesize > maxfilesize) fs->fs_maxfilesize = maxfilesize; + break; } /* Compatibility for old filesystems */ if (fs->fs_avgfilesize <= 0) @@ -387,16 +392,35 @@ void ffs_oldfscompat_write(struct fs *fs) { - /* - * Copy back UFS2 updated fields that UFS1 inspects. - */ - if (fs->fs_magic == FS_UFS1_MAGIC) { + switch (fs->fs_magic) { + case FS_UFS1_MAGIC: + if (fs->fs_sblockloc != SBLOCK_UFS1 && + (fs->fs_old_flags & FS_FLAGS_UPDATED) == 0) { + printf( + "WARNING: %s: correcting fs_sblockloc from %jd to %d\n", + fs->fs_fsmnt, fs->fs_sblockloc, SBLOCK_UFS1); + fs->fs_sblockloc = SBLOCK_UFS1; + } + /* + * Copy back UFS2 updated fields that UFS1 inspects. + */ 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; + if (fs->fs_save_maxfilesize != 0) + fs->fs_maxfilesize = fs->fs_save_maxfilesize; + break; + case FS_UFS2_MAGIC: + if (fs->fs_sblockloc != SBLOCK_UFS2 && + (fs->fs_old_flags & FS_FLAGS_UPDATED) == 0) { + printf( + "WARNING: %s: correcting fs_sblockloc from %jd to %d\n", + fs->fs_fsmnt, fs->fs_sblockloc, SBLOCK_UFS2); + fs->fs_sblockloc = SBLOCK_UFS2; + } + break; } } @@ -410,9 +434,8 @@ static int prttimechgs = 0; #ifdef _KERNEL SYSCTL_NODE(_vfs, OID_AUTO, ffs, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, "FFS filesystem"); - SYSCTL_INT(_vfs_ffs, OID_AUTO, prttimechgs, CTLFLAG_RWTUN, &prttimechgs, 0, - "print UFS1 time changes made to inodes"); + "print UFS1 time changes made to inodes"); #endif /* _KERNEL */ bool ffs_oldfscompat_inode_read(struct fs *fs, union dinodep dp, time_t now) @@ -934,6 +957,7 @@ int ffs_sbput(void *devfd, struct fs *fs, off_t loc, int (*writefunc)(void *devfd, off_t loc, void *buf, int size)) { + struct fs_summary_info *fs_si; int i, error, blks, size; uint8_t *space; @@ -956,23 +980,27 @@ ffs_sbput(void *devfd, struct fs *fs, off_t loc, } } fs->fs_fmod = 0; -#ifndef _KERNEL - { - struct fs_summary_info *fs_si; - - fs->fs_time = time(NULL); - /* Clear the pointers for the duration of writing. */ - fs_si = fs->fs_si; - fs->fs_si = NULL; - fs->fs_ckhash = ffs_calc_sbhash(fs); - error = (*writefunc)(devfd, loc, fs, fs->fs_sbsize); - fs->fs_si = fs_si; - } -#else /* _KERNEL */ + ffs_oldfscompat_write(fs); +#ifdef _KERNEL fs->fs_time = time_second; +#else /* User Code */ + fs->fs_time = time(NULL); +#endif + /* Clear the pointers for the duration of writing. */ + fs_si = fs->fs_si; + fs->fs_si = NULL; fs->fs_ckhash = ffs_calc_sbhash(fs); error = (*writefunc)(devfd, loc, fs, fs->fs_sbsize); -#endif /* _KERNEL */ + /* + * A negative error code is returned when a copy of the + * superblock has been made which is discarded when the I/O + * is done. So the fs_si field does not and indeed cannot be + * restored after the write is done. Convert the error code + * back to its usual positive value when returning it. + */ + if (error < 0) + return (-error - 1); + fs->fs_si = fs_si; return (error); } diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c index eadd5815eaf7..b387fda14588 100644 --- a/sys/ufs/ffs/ffs_vfsops.c +++ b/sys/ufs/ffs/ffs_vfsops.c @@ -2034,9 +2034,15 @@ ffs_sbupdate(struct ufsmount *ump, int waitfor, int suspended) panic("ffs_sbupdate: write read-only filesystem"); /* * We use the superblock's buf to serialize calls to ffs_sbupdate(). + * Copy superblock to this buffer and have it written out. */ sbbp = getblk(ump->um_devvp, btodb(fs->fs_sblockloc), (int)fs->fs_sbsize, 0, 0, 0); + UFS_LOCK(ump); + fs->fs_fmod = 0; + bcopy((caddr_t)fs, sbbp->b_data, (uint64_t)fs->fs_sbsize); + UFS_UNLOCK(ump); + fs = (struct fs *)sbbp->b_data; /* * Initialize info needed for write function. */ @@ -2062,7 +2068,8 @@ ffs_use_bwrite(void *devfd, off_t loc, void *buf, int size) devfdp = devfd; ump = devfdp->ump; - fs = ump->um_fs; + bp = devfdp->sbbp; + fs = (struct fs *)bp->b_data; /* * Writing the superblock summary information. */ @@ -2079,44 +2086,27 @@ ffs_use_bwrite(void *devfd, off_t loc, void *buf, int size) } /* * Writing the superblock itself. We need to do special checks for it. + * A negative error code is returned to indicate that a copy of the + * superblock has been made and that the copy is discarded when the + * I/O is done. So the the caller should not attempt to restore the + * fs_si field after the write is done. The caller will convert the + * error code back to its usual positive value when returning it. */ - bp = devfdp->sbbp; if (ffs_fsfail_cleanup(ump, devfdp->error)) devfdp->error = 0; if (devfdp->error != 0) { brelse(bp); - return (devfdp->error); - } - if (fs->fs_magic == FS_UFS1_MAGIC && fs->fs_sblockloc != SBLOCK_UFS1 && - (fs->fs_old_flags & FS_FLAGS_UPDATED) == 0) { - printf("WARNING: %s: correcting fs_sblockloc from %jd to %d\n", - fs->fs_fsmnt, fs->fs_sblockloc, SBLOCK_UFS1); - fs->fs_sblockloc = SBLOCK_UFS1; - } - if (fs->fs_magic == FS_UFS2_MAGIC && fs->fs_sblockloc != SBLOCK_UFS2 && - (fs->fs_old_flags & FS_FLAGS_UPDATED) == 0) { - printf("WARNING: %s: correcting fs_sblockloc from %jd to %d\n", - fs->fs_fsmnt, fs->fs_sblockloc, SBLOCK_UFS2); - fs->fs_sblockloc = SBLOCK_UFS2; + return (-devfdp->error - 1); } if (MOUNTEDSOFTDEP(ump->um_mountp)) - softdep_setup_sbupdate(ump, (struct fs *)bp->b_data, bp); - UFS_LOCK(ump); - bcopy((caddr_t)fs, bp->b_data, (uint64_t)fs->fs_sbsize); - UFS_UNLOCK(ump); - fs = (struct fs *)bp->b_data; - fs->fs_fmod = 0; - ffs_oldfscompat_write(fs); - fs->fs_si = NULL; - /* Recalculate the superblock hash */ - fs->fs_ckhash = ffs_calc_sbhash(fs); + softdep_setup_sbupdate(ump, fs, bp); if (devfdp->suspended) bp->b_flags |= B_VALIDSUSPWRT; if (devfdp->waitfor != MNT_WAIT) bawrite(bp); else if ((error = bwrite(bp)) != 0) devfdp->error = error; - return (devfdp->error); + return (-devfdp->error - 1); } static int