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