The branch stable/13 has been updated by mckusick:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=7317bd0de9731c787f58103bedc049dee7d18db9

commit 7317bd0de9731c787f58103bedc049dee7d18db9
Author:     Kirk McKusick <mckus...@freebsd.org>
AuthorDate: 2022-08-13 20:50:08 +0000
Commit:     Kirk McKusick <mckus...@freebsd.org>
CommitDate: 2022-12-04 05:52:11 +0000

    Explicitly initialize rather than reading newly allocated UFS inodes.
    
    (cherry picked from commit 6b9d4fbb7fe550788d82168e7beeabcd5ad238ce)
    
    Sponsored by: The FreeBSD Foundation
---
 sys/ufs/ffs/ffs_alloc.c  |  2 +-
 sys/ufs/ffs/ffs_extern.h |  1 +
 sys/ufs/ffs/ffs_vfsops.c | 54 +++++++++++++++++++++++++++---------------------
 3 files changed, 33 insertions(+), 24 deletions(-)

diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c
index 6eaec9edf17b..4b0c7b108cb6 100644
--- a/sys/ufs/ffs/ffs_alloc.c
+++ b/sys/ufs/ffs/ffs_alloc.c
@@ -1159,7 +1159,7 @@ retry:
         * return the error.
         */
        if ((error = ffs_vgetf(pvp->v_mount, ino, LK_EXCLUSIVE, vpp,
-           FFSV_FORCEINSMQ | FFSV_REPLACE)) != 0) {
+           FFSV_FORCEINSMQ | FFSV_REPLACE | FFSV_NEWINODE)) != 0) {
                ffs_vfree(pvp, ino, mode);
                return (error);
        }
diff --git a/sys/ufs/ffs/ffs_extern.h b/sys/ufs/ffs/ffs_extern.h
index c835239986ba..1ea473e69f52 100644
--- a/sys/ufs/ffs/ffs_extern.h
+++ b/sys/ufs/ffs/ffs_extern.h
@@ -130,6 +130,7 @@ int ffs_breadz(struct ufsmount *, struct vnode *, daddr_t, 
daddr_t, int,
                                           doomed */
 #define        FFSV_FORCEINODEDEP      0x0008  /* Force allocation of 
inodedep, ignore
                                           MNT_SOFTDEP */
+#define        FFSV_NEWINODE           0x0010  /* Newly allocated inode */
 
 /*
  * Flags to ffs_reload
diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c
index 2d5db7722a0f..3dc6f6d9ee23 100644
--- a/sys/ufs/ffs/ffs_vfsops.c
+++ b/sys/ufs/ffs/ffs_vfsops.c
@@ -1948,40 +1948,48 @@ ffs_vgetf(struct mount *mp,
                MPASS((ffs_flags & FFSV_REPLACE) == 0);
                return (0);
        }
-
-       /* Read in the disk contents for the inode, copy into the inode. */
-       dbn = fsbtodb(fs, ino_to_fsba(fs, ino));
-       error = ffs_breadz(ump, ump->um_devvp, dbn, dbn, (int)fs->fs_bsize,
-           NULL, NULL, 0, NOCRED, 0, NULL, &bp);
-       if (error != 0) {
-               /*
-                * The inode does not contain anything useful, so it would
-                * be misleading to leave it on its hash chain. With mode
-                * still zero, it will be unlinked and returned to the free
-                * list by vput().
-                */
-               vgone(vp);
-               vput(vp);
-               *vpp = NULL;
-               return (error);
-       }
        if (I_IS_UFS1(ip))
                ip->i_din1 = uma_zalloc(uma_ufs1, M_WAITOK);
        else
                ip->i_din2 = uma_zalloc(uma_ufs2, M_WAITOK);
-       if ((error = ffs_load_inode(bp, ip, fs, ino)) != 0) {
+
+       if ((ffs_flags & FFSV_NEWINODE) != 0) {
+               /* New inode, just zero out its contents. */
+               if (I_IS_UFS1(ip))
+                       memset(ip->i_din1, 0, sizeof(struct ufs1_dinode));
+               else
+                       memset(ip->i_din2, 0, sizeof(struct ufs2_dinode));
+       } else {
+               /* Read the disk contents for the inode, copy into the inode. */
+               dbn = fsbtodb(fs, ino_to_fsba(fs, ino));
+               error = ffs_breadz(ump, ump->um_devvp, dbn, dbn,
+                   (int)fs->fs_bsize, NULL, NULL, 0, NOCRED, 0, NULL, &bp);
+               if (error != 0) {
+                       /*
+                        * The inode does not contain anything useful, so it
+                        * would be misleading to leave it on its hash chain.
+                        * With mode still zero, it will be unlinked and
+                        * returned to the free list by vput().
+                        */
+                       vgone(vp);
+                       vput(vp);
+                       *vpp = NULL;
+                       return (error);
+               }
+               if ((error = ffs_load_inode(bp, ip, fs, ino)) != 0) {
+                       bqrelse(bp);
+                       vgone(vp);
+                       vput(vp);
+                       *vpp = NULL;
+                       return (error);
+               }
                bqrelse(bp);
-               vgone(vp);
-               vput(vp);
-               *vpp = NULL;
-               return (error);
        }
        if (DOINGSOFTDEP(vp) && (!fs->fs_ronly ||
            (ffs_flags & FFSV_FORCEINODEDEP) != 0))
                softdep_load_inodeblock(ip);
        else
                ip->i_effnlink = ip->i_nlink;
-       bqrelse(bp);
 
        /*
         * Initialize the vnode from the inode, check for aliases.

Reply via email to