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
This commit is contained in:
parent
3dd61c212c
commit
1604022248
@ -1137,10 +1137,15 @@ ffs_valloc(pvp, mode, cred, vpp)
|
||||
(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 @@ ffs_valloc(pvp, mode, cred, vpp)
|
||||
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;
|
||||
|
@ -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
|
||||
|
@ -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)),
|
||||
|
Loading…
Reference in New Issue
Block a user