summaryrefslogtreecommitdiff
path: root/usr
diff options
context:
space:
mode:
authorbatschul <none@none>2009-05-27 08:27:53 -0600
committerbatschul <none@none>2009-05-27 08:27:53 -0600
commit13237b7e1e5bd293e466307b2e06f8e0e2321a0a (patch)
tree4a039c077ef2047007c962d8f72cba938af98fc7 /usr
parentc279fc79e3033aa26abead0dec23a0f7386b4a90 (diff)
downloadillumos-joyent-13237b7e1e5bd293e466307b2e06f8e0e2321a0a.tar.gz
6818559 deadlock between acct_find()/ufs_check_lockfs() if process accounting enabled when lockfs -w /var
Diffstat (limited to 'usr')
-rw-r--r--usr/src/uts/common/fs/ufs/ufs_lockfs.c40
1 files changed, 20 insertions, 20 deletions
diff --git a/usr/src/uts/common/fs/ufs/ufs_lockfs.c b/usr/src/uts/common/fs/ufs/ufs_lockfs.c
index 5f560aab39..4410a7ae67 100644
--- a/usr/src/uts/common/fs/ufs/ufs_lockfs.c
+++ b/usr/src/uts/common/fs/ufs/ufs_lockfs.c
@@ -19,12 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#include <sys/t_lock.h>
#include <sys/param.h>
@@ -885,20 +883,33 @@ ufs__fiolfs(
if (!vp || !vp->v_vfsp || !vp->v_vfsp->vfs_data)
return (EIO);
- if (vp->v_vfsp->vfs_flag & VFS_UNMOUNTED) /* has been unmounted */
+ vfsp = vp->v_vfsp;
+
+ if (vfsp->vfs_flag & VFS_UNMOUNTED) /* has been unmounted */
return (EIO);
/* take the lock and check again */
- vfs_lock_wait(vp->v_vfsp);
- if (vp->v_vfsp->vfs_flag & VFS_UNMOUNTED) {
- vfs_unlock(vp->v_vfsp);
+ vfs_lock_wait(vfsp);
+ if (vfsp->vfs_flag & VFS_UNMOUNTED) {
+ vfs_unlock(vfsp);
return (EIO);
}
- vfsp = vp->v_vfsp;
+ /*
+ * Can't wlock or ro/elock fs with accounting or local swap file
+ * We need to check for this before we grab the ul_lock to avoid
+ * deadlocks with the accounting framework.
+ */
+ if ((LOCKFS_IS_WLOCK(lockfsp) || LOCKFS_IS_ELOCK(lockfsp) ||
+ LOCKFS_IS_ROELOCK(lockfsp)) && !from_log) {
+ if (ufs_checkaccton(vp) || ufs_checkswapon(vp)) {
+ vfs_unlock(vfsp);
+ return (EDEADLK);
+ }
+ }
+
ufsvfsp = (struct ufsvfs *)vfsp->vfs_data;
ulp = &ufsvfsp->vfs_ulockfs;
-
head = (ulockfs_info_t *)tsd_get(ufs_lockfs_key);
SEARCH_ULOCKFSP(head, ulp, info);
@@ -1029,17 +1040,6 @@ ufs__fiolfs(
}
/*
- * can't wlock or (ro)elock fs with accounting or local swap file
- */
- if ((ULOCKFS_IS_WLOCK(ulp) || ULOCKFS_IS_ELOCK(ulp) ||
- ULOCKFS_IS_ROELOCK(ulp)) && !from_log) {
- if (error = ufs_checkaccton(vp))
- goto errout;
- if (error = ufs_checkswapon(vp))
- goto errout;
- }
-
- /*
* save error lock status to pass down to reconcilation
* routines and for later cleanup
*/