diff options
author | rwatson <rwatson@FreeBSD.org> | 2003-05-15 21:07:33 +0000 |
---|---|---|
committer | rwatson <rwatson@FreeBSD.org> | 2003-05-15 21:07:33 +0000 |
commit | 7e2cfac5e09cab2e6a3c4e05c476c2326bb4ba09 (patch) | |
tree | 4e2cbe329bb2e238e258021517dd161f6d7d58fb /sys | |
parent | 5edcb9f9a820227896e9652d30b26af8c1d9abc9 (diff) | |
download | FreeBSD-src-7e2cfac5e09cab2e6a3c4e05c476c2326bb4ba09.zip FreeBSD-src-7e2cfac5e09cab2e6a3c4e05c476c2326bb4ba09.tar.gz |
Jeff added locking assertions that the VV_ flags on vnodes were modified
only while holding appropriate vnode locks. This patch slides the lock
release for ufs_extattr_enable() to continue to hold the active vnode lock
on a backing file until after the flag change; it also acquires a vnode
lock when disabling an attribute and hence clearing a flag on the backing
vnode. This permits VFS_DEBUG_LOCKS to run UFS1 extended attributes
without panicking, as well as preventing a potential race and vnode flag
problem.
Approved by: re (jhb)
Pointed out by: DEBUG_VFS_LOCKS
Diffstat (limited to 'sys')
-rw-r--r-- | sys/ufs/ufs/ufs_extattr.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/sys/ufs/ufs/ufs_extattr.c b/sys/ufs/ufs/ufs_extattr.c index f715189..cc5a9cc 100644 --- a/sys/ufs/ufs/ufs_extattr.c +++ b/sys/ufs/ufs/ufs_extattr.c @@ -627,28 +627,27 @@ ufs_extattr_enable(struct ufsmount *ump, int attrnamespace, vn_lock(backing_vnode, LK_SHARED | LK_NOPAUSE | LK_RETRY, td); error = VOP_READ(backing_vnode, &auio, IO_NODELOCKED, ump->um_extattr.uepm_ucred); - VOP_UNLOCK(backing_vnode, 0, td); if (error) - goto free_exit; + goto unlock_free_exit; if (auio.uio_resid != 0) { printf("ufs_extattr_enable: malformed attribute header\n"); error = EINVAL; - goto free_exit; + goto unlock_free_exit; } if (attribute->uele_fileheader.uef_magic != UFS_EXTATTR_MAGIC) { printf("ufs_extattr_enable: invalid attribute header magic\n"); error = EINVAL; - goto free_exit; + goto unlock_free_exit; } if (attribute->uele_fileheader.uef_version != UFS_EXTATTR_VERSION) { printf("ufs_extattr_enable: incorrect attribute header " "version\n"); error = EINVAL; - goto free_exit; + goto unlock_free_exit; } ASSERT_VOP_LOCKED(backing_vnode, "ufs_extattr_enable"); @@ -656,8 +655,12 @@ ufs_extattr_enable(struct ufsmount *ump, int attrnamespace, LIST_INSERT_HEAD(&ump->um_extattr.uepm_list, attribute, uele_entries); + VOP_UNLOCK(backing_vnode, 0, td); return (0); +unlock_free_exit: + VOP_UNLOCK(backing_vnode, 0, td); + free_exit: FREE(attribute, M_UFS_EXTATTR); return (error); @@ -682,8 +685,11 @@ ufs_extattr_disable(struct ufsmount *ump, int attrnamespace, LIST_REMOVE(uele, uele_entries); + vn_lock(uele->uele_backing_vnode, LK_SHARED | LK_NOPAUSE | LK_RETRY, + td); ASSERT_VOP_LOCKED(uele->uele_backing_vnode, "ufs_extattr_disable"); uele->uele_backing_vnode->v_vflag &= ~VV_SYSTEM; + VOP_UNLOCK(uele->uele_backing_vnode, 0, td); error = vn_close(uele->uele_backing_vnode, FREAD|FWRITE, td->td_ucred, td); |