Changeset View
Changeset View
Standalone View
Standalone View
head/sys/ufs/ffs/ffs_vfsops.c
Show First 20 Lines • Show All 1,665 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
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; | ||||
MPASS((ffs_flags & FFSV_REPLACE) == 0 || (flags & LK_EXCLUSIVE) != 0); | |||||
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; | ||||
▲ Show 20 Lines • Show All 45 Lines • ▼ Show 20 Lines | #endif | ||||
error = insmntque(vp, mp); | error = insmntque(vp, mp); | ||||
if (error != 0) { | if (error != 0) { | ||||
uma_zfree(uma_inode, ip); | uma_zfree(uma_inode, ip); | ||||
*vpp = NULL; | *vpp = NULL; | ||||
return (error); | return (error); | ||||
} | } | ||||
vp->v_vflag &= ~VV_FORCEINSMQ; | vp->v_vflag &= ~VV_FORCEINSMQ; | ||||
error = vfs_hash_insert(vp, ino, flags, curthread, vpp, NULL, NULL); | error = vfs_hash_insert(vp, ino, flags, curthread, vpp, NULL, NULL); | ||||
if (error || *vpp != NULL) | if (error != 0) | ||||
return (error); | 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. */ | /* Read in the disk contents for the inode, copy into the inode. */ | ||||
error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)), | error = bread(ump->um_devvp, fsbtodb(fs, ino_to_fsba(fs, ino)), | ||||
(int)fs->fs_bsize, NOCRED, &bp); | (int)fs->fs_bsize, NOCRED, &bp); | ||||
if (error) { | if (error) { | ||||
/* | /* | ||||
* The inode does not contain anything useful, so it would | * The inode does not contain anything useful, so it would | ||||
* be misleading to leave it on its hash chain. With mode | * be misleading to leave it on its hash chain. With mode | ||||
▲ Show 20 Lines • Show All 613 Lines • Show Last 20 Lines |