summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorMatthew Ahrens <mahrens@delphix.com>2016-09-02 21:42:41 -0700
committerMatthew Ahrens <mahrens@delphix.com>2016-09-06 20:21:43 -0700
commit31d4cf520a749c6f68cc90540de415399538680b (patch)
tree39c680b914e2ae0dfd7674feda2950515144e9c6 /usr/src
parenta8b0961c456000a55c467b0ba353504803f9c5e2 (diff)
downloadillumos-joyent-31d4cf520a749c6f68cc90540de415399538680b.tar.gz
7339 hang in lufs_unsnarf() due to zfs on files on ufs
Reviewed by: Prakash Surya <prakash.surya@delphix.com> Reviewed by: George Wilson <george.wilson@delphix.com> Reviewed by: Gordon Ross <gordon.w.ross@gmail.com> Approved by: Robert Mustacchi <rm@joyent.com>
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/fs/ufs/lufs_top.c42
1 files changed, 25 insertions, 17 deletions
diff --git a/usr/src/uts/common/fs/ufs/lufs_top.c b/usr/src/uts/common/fs/ufs/lufs_top.c
index e83df88f2e..dde6c6d447 100644
--- a/usr/src/uts/common/fs/ufs/lufs_top.c
+++ b/usr/src/uts/common/fs/ufs/lufs_top.c
@@ -23,7 +23,9 @@
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
+/*
+ * Copyright (c) 2015 by Delphix. All rights reserved.
+ */
#include <sys/systm.h>
#include <sys/types.h>
@@ -134,12 +136,9 @@ top_seterror(ufsvfs_t *ufsvfsp)
* issue a empty sync op to help empty the delta/log map or the log
*/
static void
-top_issue_sync(void *arg)
+top_issue_sync(ufsvfs_t *ufsvfsp)
{
- ufsvfs_t *ufsvfsp = (ufsvfs_t *)arg;
- ml_unit_t *ul = (ml_unit_t *)ufsvfsp->vfs_log;
- mt_map_t *mtm = ul->un_logmap;
- int error = 0;
+ int error = 0;
if ((curthread->t_flag & T_DONTBLOCK) == 0)
curthread->t_flag |= T_DONTBLOCK;
@@ -147,21 +146,30 @@ top_issue_sync(void *arg)
if (!error) {
top_end_sync(ufsvfsp, &error, TOP_COMMIT_ASYNC, 0);
}
+}
+
+static void
+top_issue_from_taskq(void *arg)
+{
+ ufsvfs_t *ufsvfsp = arg;
+ ml_unit_t *ul = ufsvfsp->vfs_log;
+ mt_map_t *mtm = ul->un_logmap;
+
+ top_issue_sync(ufsvfsp);
/*
- * If we are a taskq thread, decrement mtm_taskq_sync_count and
- * wake up the thread waiting on the mtm_cv if the mtm_taskq_sync_count
- * hits zero.
+ * We were called from the taskq_dispatch() in top_begin_async(), so
+ * decrement mtm_taskq_sync_count and wake up the thread waiting
+ * on the mtm_cv if the mtm_taskq_sync_count hits zero.
*/
+ ASSERT(taskq_member(system_taskq, curthread));
- if (taskq_member(system_taskq, curthread)) {
- mutex_enter(&mtm->mtm_lock);
- mtm->mtm_taskq_sync_count--;
- if (mtm->mtm_taskq_sync_count == 0) {
- cv_signal(&mtm->mtm_cv);
- }
- mutex_exit(&mtm->mtm_lock);
+ mutex_enter(&mtm->mtm_lock);
+ mtm->mtm_taskq_sync_count--;
+ if (mtm->mtm_taskq_sync_count == 0) {
+ cv_signal(&mtm->mtm_cv);
}
+ mutex_exit(&mtm->mtm_lock);
}
/*
@@ -408,7 +416,7 @@ retry:
mtm->mtm_taskq_sync_count++;
mutex_exit(&mtm->mtm_lock);
(void) taskq_dispatch(system_taskq,
- top_issue_sync, ufsvfsp, TQ_SLEEP);
+ top_issue_from_taskq, ufsvfsp, TQ_SLEEP);
if (tryasync) {
tryfail_cnt++;
return (EWOULDBLOCK);