Changeset View
Changeset View
Standalone View
Standalone View
sys/ufs/ffs/ffs_vfsops.c
Show First 20 Lines • Show All 1,664 Lines • ▼ Show 20 Lines | ffs_vgetf(mp, ino, flags, vpp, ffs_flags) | ||||
int ffs_flags; | int ffs_flags; | ||||
{ | { | ||||
struct fs *fs; | struct fs *fs; | ||||
struct inode *ip; | struct inode *ip; | ||||
struct ufsmount *ump; | struct ufsmount *ump; | ||||
struct buf *bp; | struct buf *bp; | ||||
struct vnode *vp; | struct vnode *vp; | ||||
int error; | int error; | ||||
markj: We should probably assert (flags & LK_EXCLUSIVE) != 0 if FFSV_REPLACE is set. | |||||
error = vfs_hash_get(mp, ino, flags, curthread, vpp, NULL, NULL); | error = vfs_hash_get(mp, ino, flags, curthread, vpp, NULL, NULL); | ||||
if (error || *vpp != NULL) | if (error != 0) | ||||
return (error); | 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 | * We must promote to an exclusive lock for vnode creation. This | ||||
* can happen if lookup is passed LOCKSHARED. | * can happen if lookup is passed LOCKSHARED. | ||||
*/ | */ | ||||
if ((flags & LK_TYPE_MASK) == LK_SHARED) { | if ((flags & LK_TYPE_MASK) == LK_SHARED) { | ||||
flags &= ~LK_TYPE_MASK; | flags &= ~LK_TYPE_MASK; | ||||
flags |= LK_EXCLUSIVE; | flags |= LK_EXCLUSIVE; | ||||
} | } | ||||
/* | /* | ||||
* We do not lock vnode creation as it is believed to be too | * We do not lock vnode creation as it is believed to be too | ||||
* expensive for such rare case as simultaneous creation of vnode | * expensive for such rare case as simultaneous creation of vnode | ||||
* for same ino by different processes. We just allow them to race | * for same ino by different processes. We just allow them to race | ||||
* and check later to decide who wins. Let the race begin! | * and check later to decide who wins. Let the race begin! | ||||
markjUnsubmitted Done Inline ActionsHmm, so isn't it possible for two threads to race to allocate the same inode, and the losing thread calls vgone() on the newly created vnode? markj: Hmm, so isn't it possible for two threads to race to allocate the same inode, and the losing… | |||||
kibAuthorUnsubmitted Done Inline ActionsIt is only possible for fully allocated inode, I believe. If inode is not yet allocated, only one thread can successfully allocate it, and then no other thread should instantiating the vnode. In other words, the described race is vald, but not for FFSV_REPLACE. kib: It is only possible for fully allocated inode, I believe. If inode is not yet allocated, only… | |||||
markjUnsubmitted Done Inline ActionsIs it valid to add the following assertion below? error = vfs_hash_insert(...); if (error != 0) return (error); if (*vpp != NULL) { MPASS((ffs_flags & FFSV_REPLACE) == 0); return (0); } markj: Is it valid to add the following assertion below?
```
error = vfs_hash_insert(...);
if (error ! | |||||
kibAuthorUnsubmitted Done Inline ActionsI think yes, it should be correct. I added it with some comment explaining the assumption about freshly allocated inode. kib: I think yes, it should be correct. I added it with some comment explaining the assumption… | |||||
*/ | */ | ||||
ump = VFSTOUFS(mp); | ump = VFSTOUFS(mp); | ||||
fs = ump->um_fs; | fs = ump->um_fs; | ||||
ip = uma_zalloc(uma_inode, M_WAITOK | M_ZERO); | ip = uma_zalloc(uma_inode, M_WAITOK | M_ZERO); | ||||
/* Allocate a new vnode/inode. */ | /* Allocate a new vnode/inode. */ | ||||
error = getnewvnode("ufs", mp, fs->fs_magic == FS_UFS1_MAGIC ? | error = getnewvnode("ufs", mp, fs->fs_magic == FS_UFS1_MAGIC ? | ||||
▲ Show 20 Lines • Show All 661 Lines • Show Last 20 Lines |
We should probably assert (flags & LK_EXCLUSIVE) != 0 if FFSV_REPLACE is set.