diff options
author | Matthew Ahrens <mahrens@delphix.com> | 2016-09-02 21:42:41 -0700 |
---|---|---|
committer | Matthew Ahrens <mahrens@delphix.com> | 2016-09-06 20:21:43 -0700 |
commit | 31d4cf520a749c6f68cc90540de415399538680b (patch) | |
tree | 39c680b914e2ae0dfd7674feda2950515144e9c6 /usr/src | |
parent | a8b0961c456000a55c467b0ba353504803f9c5e2 (diff) | |
download | illumos-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.c | 42 |
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); |