diff options
| -rw-r--r-- | sys/ufs/ffs/ffs_alloc.c | 2 | ||||
| -rw-r--r-- | sys/ufs/ffs/ffs_extern.h | 1 | ||||
| -rw-r--r-- | 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 4f17b71dd20f..5bfc88aa5d19 100644 --- a/sys/ufs/ffs/ffs_extern.h +++ b/sys/ufs/ffs/ffs_extern.h @@ -132,6 +132,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 38d5be895318..4768d610b287 100644 --- a/sys/ufs/ffs/ffs_vfsops.c +++ b/sys/ufs/ffs/ffs_vfsops.c @@ -1928,40 +1928,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. |
