Date: Thu, 29 Aug 2019 07:45:24 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r351597 - head/sys/ufs/ffs Message-ID: <201908290745.x7T7jOav075406@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Thu Aug 29 07:45:23 2019 New Revision: 351597 URL: https://svnweb.freebsd.org/changeset/base/351597 Log: UFS: stop reusing the vnode for reallocated inode. In ffs_valloc(), force reclaim existing vnode on inode reuse, instead of trying to re-initialize the same vnode for new purposes. This is done in preparation of changes to the vp->v_object lifecycle handling. A new FFSV_REPLACE flag to ffs_vgetf() directs the function to vgone(9) the vnode if found in vfs hash, instead of returning it. Reviewed by: markj, mckusick Tested by: pho Sponsored by: The FreeBSD Foundation Differential revision: https://reviews.freebsd.org/D21412 Modified: head/sys/ufs/ffs/ffs_alloc.c head/sys/ufs/ffs/ffs_extern.h head/sys/ufs/ffs/ffs_vfsops.c Modified: head/sys/ufs/ffs/ffs_alloc.c ============================================================================== --- head/sys/ufs/ffs/ffs_alloc.c Thu Aug 29 07:39:31 2019 (r351596) +++ head/sys/ufs/ffs/ffs_alloc.c Thu Aug 29 07:45:23 2019 (r351597) @@ -1137,10 +1137,15 @@ retry: (allocfcn_t *)ffs_nodealloccg); if (ino == 0) goto noinodes; - error = ffs_vget(pvp->v_mount, ino, LK_EXCLUSIVE, vpp); + + /* + * Get rid of the cached old vnode, force allocation of a new vnode + * for this inode. + */ + error = ffs_vgetf(pvp->v_mount, ino, LK_EXCLUSIVE, vpp, FFSV_REPLACE); if (error) { error1 = ffs_vgetf(pvp->v_mount, ino, LK_EXCLUSIVE, vpp, - FFSV_FORCEINSMQ); + FFSV_FORCEINSMQ | FFSV_REPLACE); ffs_vfree(pvp, ino, mode); if (error1 == 0) { ip = VTOI(*vpp); @@ -1176,7 +1181,6 @@ dup_alloc: ip->i_din2->di_birthtime = ts.tv_sec; ip->i_din2->di_birthnsec = ts.tv_nsec; } - ufs_prepare_reclaim(*vpp); ip->i_flag = 0; (*vpp)->v_vflag = 0; (*vpp)->v_type = VNON; Modified: head/sys/ufs/ffs/ffs_extern.h ============================================================================== --- head/sys/ufs/ffs/ffs_extern.h Thu Aug 29 07:39:31 2019 (r351596) +++ head/sys/ufs/ffs/ffs_extern.h Thu Aug 29 07:45:23 2019 (r351597) @@ -121,6 +121,7 @@ void process_deferred_inactive(struct mount *mp); * Flags to ffs_vgetf */ #define FFSV_FORCEINSMQ 0x0001 +#define FFSV_REPLACE 0x0002 /* * Flags to ffs_reload Modified: head/sys/ufs/ffs/ffs_vfsops.c ============================================================================== --- head/sys/ufs/ffs/ffs_vfsops.c Thu Aug 29 07:39:31 2019 (r351596) +++ head/sys/ufs/ffs/ffs_vfsops.c Thu Aug 29 07:45:23 2019 (r351597) @@ -1671,9 +1671,17 @@ ffs_vgetf(mp, ino, flags, vpp, ffs_flags) struct vnode *vp; int error; + MPASS((ffs_flags & FFSV_REPLACE) == 0 || (flags & LK_EXCLUSIVE) != 0); + error = vfs_hash_get(mp, ino, flags, curthread, vpp, NULL, NULL); - if (error || *vpp != NULL) + if (error != 0) return (error); + if (*vpp != NULL) { + if ((ffs_flags & FFSV_REPLACE) == 0) + return (0); + vgone(*vpp); + vput(*vpp); + } /* * We must promote to an exclusive lock for vnode creation. This @@ -1735,8 +1743,19 @@ ffs_vgetf(mp, ino, flags, vpp, ffs_flags) } vp->v_vflag &= ~VV_FORCEINSMQ; error = vfs_hash_insert(vp, ino, flags, curthread, vpp, NULL, NULL); - if (error || *vpp != NULL) + if (error != 0) return (error); + if (*vpp != NULL) { + /* + * Calls from ffs_valloc() (i.e. FFSV_REPLACE set) + * operate on empty inode, which must not be found by + * other threads until fully filled. Vnode for empty + * inode must be not re-inserted on the hash by other + * thread, after removal by us at the beginning. + */ + MPASS((ffs_flags & FFSV_REPLACE) == 0); + return (0); + } /* Read in the disk contents for the inode, copy into the inode. */ error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)),
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201908290745.x7T7jOav075406>