Page MenuHomeFreeBSD

D21412.id61446.diff
No OneTemporary

D21412.id61446.diff

Index: head/sys/ufs/ffs/ffs_alloc.c
===================================================================
--- head/sys/ufs/ffs/ffs_alloc.c
+++ head/sys/ufs/ffs/ffs_alloc.c
@@ -1137,10 +1137,15 @@
(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 @@
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;
Index: head/sys/ufs/ffs/ffs_extern.h
===================================================================
--- head/sys/ufs/ffs/ffs_extern.h
+++ head/sys/ufs/ffs/ffs_extern.h
@@ -121,6 +121,7 @@
* Flags to ffs_vgetf
*/
#define FFSV_FORCEINSMQ 0x0001
+#define FFSV_REPLACE 0x0002
/*
* Flags to ffs_reload
Index: head/sys/ufs/ffs/ffs_vfsops.c
===================================================================
--- head/sys/ufs/ffs/ffs_vfsops.c
+++ head/sys/ufs/ffs/ffs_vfsops.c
@@ -1671,9 +1671,17 @@
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 @@
}
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)),

File Metadata

Mime Type
text/plain
Expires
Fri, Feb 13, 1:04 AM (14 h, 14 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28672227
Default Alt Text
D21412.id61446.diff (2 KB)

Event Timeline