From mwest@zeeb.org  Thu Mar  5 14:58:46 2009
Return-Path: <mwest@zeeb.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 9B0A3106564A
	for <FreeBSD-gnats-submit@freebsd.org>; Thu,  5 Mar 2009 14:58:46 +0000 (UTC)
	(envelope-from mwest@zeeb.org)
Received: from zeeb.org (zeeb.org [88.198.32.244])
	by mx1.freebsd.org (Postfix) with ESMTP id 62E6D8FC13
	for <FreeBSD-gnats-submit@freebsd.org>; Thu,  5 Mar 2009 14:58:45 +0000 (UTC)
	(envelope-from mwest@zeeb.org)
Received: from mwest by zeeb.org with local (Exim 4.69 (FreeBSD))
	(envelope-from <mwest@zeeb.org>)
	id 1LfF0s-000M2Y-4x
	for FreeBSD-gnats-submit@freebsd.org; Thu, 05 Mar 2009 14:57:30 +0000
Message-Id: <E1LfF0s-000M2Y-4x@zeeb.org>
Date: Thu, 05 Mar 2009 14:57:30 +0000
From: Matthew West <freebsd@r.zeeb.org>
Sender: Matthew West <mwest@zeeb.org>
Reply-To:
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: kernel panic in zfs_fuid_create_cred 
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         132337
>Category:       kern
>Synopsis:       [zfs] [panic] kernel panic in zfs_fuid_create_cred
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    pjd
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Mar 05 15:00:13 UTC 2009
>Closed-Date:    Tue Sep 22 12:39:17 UTC 2009
>Last-Modified:  Wed Jan  6 08:20:09 UTC 2010
>Originator:     Matthew West
>Release:        FreeBSD 8.0-CURRENT amd64
>Organization:
>Environment:
FreeBSD foo.internal 8.0-CURRENT FreeBSD 8.0-CURRENT #0: Fri Feb 27 12:43:45 GMT 2009 mwest@foo.internal:/usr/obj/usr/src/sys/DEBUGLOCK amd64

>Description:
panic: zfs_fuid_create_cred
cpuid = 2
KDB: stack backtrace:
db_trace_self_wrapper() at db_trace_self_wrapper+0x2a
panic() at panic+0x182
zfs_fuid_create_cred() at zfs_fuid_create_cred+0x56
zfs_perm_init() at zfs_perm_init+0x84
zfs_mknode() at zfs_mknode+0x24e
zfs_freebsd_create() at zfs_freebsd_create+0x617
VOP_CREATE_APV() at VOP_CREATE_APV+0xb3
nfsrv_create() at nfsrv_create+0x909
nfssvc_program() at nfssvc_program+0x1a1
svc_run_internal() at svc_run_internal+0x62b
svc_thread_start() at svc_thread_start+0xb
fork_exit() at fork_exit+0x12a
fork_trampoline() at fork_trampoline+0xe
--- trap 0xc, rip = 0x800695c4c, rsp = 0x7fffffffe8e8, rbp = 0 ---
Uptime: 26m9s
Physical memory: 3056 MB
Dumping 388 MB: 373 357 341 325 309 293 277 261Error dumping block 0x0

** DUMP FAILED (ERROR 5) **
aac0: shutting down controller...FAILED.
Automatic reboot in 15 seconds - press a key on the console to abort
Rebooting...

>How-To-Repeat:

Set up a directory on an NFS share with chmod 777 permissions.  Run iozone3 on a client machine, in the 777 mode directory.

Sometimes you need to ^C the iozone process and restart it a few times to trigger the panic.

I am guessing the problem lies in some of the unimplemented code in the #ifdef TODO block in zfs_fuid.c.

>Fix:

>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->freebsd-fs 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Thu Mar 5 15:33:31 UTC 2009 
Responsible-Changed-Why:  
Over to maintainer(s). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=132337 

From: Randy Sofia <rsofia@poly.edu>
To: bug-followup@FreeBSD.org, freebsd@r.zeeb.org
Cc:  
Subject: Re: kern/132337: [zfs] [panic] kernel panic in zfs_fuid_create_cred
Date: Fri, 10 Apr 2009 10:27:09 -0400

 touching a file `touch hi` on the 777 mode directory over nfs is the 
 easiest and most guaranteed way to reproduce this panic.

From: Thomas Backman <serenity@exscape.org>
To: bug-followup@FreeBSD.org,
 freebsd@r.zeeb.org
Cc: freebsd-fs@freebsd.org,
 FreeBSD current <freebsd-current@freebsd.org>
Subject: Re: kern/132337: [zfs] [panic] kernel panic in zfs_fuid_create_cred
Date: Thu, 23 Jul 2009 10:22:13 +0200

 Hey all,
 Unfortunately, this PR appears to still be unfixed. Is anyone looking  
 at this?
 I tried to set up a diskless client over NFS yesterday, running ZFS  
 on /, and ran in to this panic (exact same backtrace as the PR (see  
 bottom the this mail)) a lot of times. In the end, I created a ZVOL  
 with UFS on it, and the panics disappeared as expected - since it no  
 longer has to work directly with files on a ZFS *filesystem*.
 It seems to be pretty easy to trigger, as I couldn't finish the boot  
 process on the diskless client more than once until I went with UFS.  
 Since then I've gotten 0 panics.
 
 FWIW, my /etc/exports (I know now R/W NFS root isn't a good idea, but  
 it might be relevant):
 /diskless -maproot=0 -alldirs 192.168.1.6
 
 Regards,
 Thomas
 
 Backtrace:
 
 panic: zfs_fuid_create_cred
 cpuid = x
 KDB: stack backtrace:
 db_trace_self_wrapper() at db_trace_self_wrapper+0x2a
 panic() at panic+0x182
 zfs_fuid_create_cred() at zfs_fuid_create_cred+0x56
 zfs_perm_init() at zfs_perm_init+0x84
 zfs_mknode() at zfs_mknode+0x24e
 zfs_freebsd_create() at zfs_freebsd_create+0x617
 VOP_CREATE_APV() at VOP_CREATE_APV+0xb3
 nfsrv_create() at nfsrv_create+0x909
 nfssvc_program() at nfssvc_program+0x1a1
 svc_run_internal() at svc_run_internal+0x62b
 svc_thread_start() at svc_thread_start+0xb
 fork_exit() at fork_exit+0x12a
 fork_trampoline() at fork_trampoline+0xe

From: Jaakko Heinonen <jh@saunalahti.fi>
To: Thomas Backman <serenity@exscape.org>
Cc: bug-followup@FreeBSD.org, freebsd@r.zeeb.org,
	FreeBSD current <freebsd-current@freebsd.org>
Subject: Re: kern/132337: [zfs] [panic] kernel panic in zfs_fuid_create_cred
Date: Thu, 23 Jul 2009 12:24:36 +0300

 Hi,
 
 On 2009-07-23, Thomas Backman wrote:
 > Unfortunately, this PR appears to still be unfixed. Is anyone looking  
 > at this?
 
 > panic: zfs_fuid_create_cred
 
 This PR is a duplicate of kern/133020. There is a workaround fix in
 pjd's perforce branch but apparently it was never committed to svn.
 
 See:
 
 	http://p4db.freebsd.org/changeView.cgi?CH=159874
 	http://people.freebsd.org/~pjd/patches/zfs_znode.h.patch
 
 -- 
 Jaakko

From: Thomas Backman <serenity@exscape.org>
To: Michael Reifenberger <mike@reifenberger.com>
Cc: Jaakko Heinonen <jh@saunalahti.fi>,
 FreeBSD current <freebsd-current@freebsd.org>,
 bug-followup@FreeBSD.org,
 freebsd@r.zeeb.org
Subject: Re: kern/132337: [zfs] [panic] kernel panic in zfs_fuid_create_cred
Date: Thu, 23 Jul 2009 15:13:51 +0200

 On Jul 23, 2009, at 15:06, Michael Reifenberger wrote:
 
 > On Thu, 23 Jul 2009, Jaakko Heinonen wrote:
 > ...
 >> This PR is a duplicate of kern/133020. There is a workaround fix in
 >> pjd's perforce branch but apparently it was never committed to svn.
 >>
 >> See:
 >>
 >> 	http://p4db.freebsd.org/changeView.cgi?CH=159874
 >> 	http://people.freebsd.org/~pjd/patches/zfs_znode.h.patch
 >>
 > I'm using this patch since march without problems.
 
 I've only used it for hours but it seems to work here too, no longer  
 using ZVOLs.
 Would be nice to have in -RELEASE :)
 
 Jaakko: It's the other way around. 132337 < 133020. This bug was filed  
 Mar 05 2009, while 133020 was filed Mar 24 2009.
 
 Regards,
 Thomas

From: Michael Reifenberger <mike@reifenberger.com>
To: Jaakko Heinonen <jh@saunalahti.fi>
Cc: Thomas Backman <serenity@exscape.org>, 
    FreeBSD current <freebsd-current@freebsd.org>, bug-followup@FreeBSD.org, 
    freebsd@r.zeeb.org
Subject: Re: kern/132337: [zfs] [panic] kernel panic in
 zfs_fuid_create_cred
Date: Thu, 23 Jul 2009 15:06:52 +0200 (CEST)

 On Thu, 23 Jul 2009, Jaakko Heinonen wrote:
 ...
 > This PR is a duplicate of kern/133020. There is a workaround fix in
 > pjd's perforce branch but apparently it was never committed to svn.
 >
 > See:
 >
 > 	http://p4db.freebsd.org/changeView.cgi?CH=159874
 > 	http://people.freebsd.org/~pjd/patches/zfs_znode.h.patch
 >
 I'm using this patch since march without problems.
 
 Bye/2
 ---
 Michael Reifenberger
 Michael@Reifenberger.com
 http://www.Reifenberger.com
 
State-Changed-From-To: open->patched 
State-Changed-By: pjd 
State-Changed-When: pon 27 lip 14:52:49 2009 UTC 
State-Changed-Why:  
Fix committed to HEAD. 


Responsible-Changed-From-To: freebsd-fs->pjd 
Responsible-Changed-By: pjd 
Responsible-Changed-When: pon 27 lip 14:52:49 2009 UTC 
Responsible-Changed-Why:  
I'll take this one. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=132337 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/132337: commit references a PR
Date: Mon, 27 Jul 2009 14:52:44 +0000 (UTC)

 Author: pjd
 Date: Mon Jul 27 14:52:34 2009
 New Revision: 195909
 URL: http://svn.freebsd.org/changeset/base/195909
 
 Log:
   We don't support ephemeral IDs in FreeBSD and without this fix ZFS can
   panic when in zfs_fuid_create_cred() when userid is negative. It is
   converted to unsigned value which makes IS_EPHEMERAL() macro to
   incorrectly report that this is ephemeral ID. The most reasonable
   solution for now is to always report that the given ID is not ephemeral.
   
   PR:		kern/132337
   Submitted by:	Matthew West <freebsd@r.zeeb.org>
   Tested by:	Thomas Backman <serenity@exscape.org>, Michael Reifenberger <mike@reifenberger.com>
   Approved by:	re (kib)
   MFC after:	2 weeks
 
 Modified:
   head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h
 
 Modified: head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h
 ==============================================================================
 --- head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h	Mon Jul 27 14:22:09 2009	(r195908)
 +++ head/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h	Mon Jul 27 14:52:34 2009	(r195909)
 @@ -78,7 +78,11 @@ extern "C" {
  /*
   * Is ID ephemeral?
   */
 +#ifdef TODO
  #define	IS_EPHEMERAL(x)		(x > MAXUID)
 +#else
 +#define	IS_EPHEMERAL(x)		(0)
 +#endif
  
  /*
   * Should we use FUIDs?
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: pjd 
State-Changed-When: wto 22 wrz 2009 12:38:42 UTC 
State-Changed-Why:  
Fix merged to stable/8. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=132337 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/132337: commit references a PR
Date: Wed,  6 Jan 2010 08:19:06 +0000 (UTC)

 Author: netchild
 Date: Wed Jan  6 08:18:49 2010
 New Revision: 201633
 URL: http://svn.freebsd.org/changeset/base/201633
 
 Log:
   MFC several ZFS related commits:
    - taskq changes
    - fixes for race conditions
    - locking fixes
    - bug fixes
    - ...
   
   r185310:
   ---snip---
       Remove unused variable.
   
       Found with:	Coverity Prevent(tm)
       CID:	3669,3671
   ---snip---
   
   r185319:
   ---snip---
       Fix locking (file descriptor table and Giant around VFS).
   
       Most submitted by:	kib
       Reviewed by:	kib
   ---snip---
   
   r192689:
   ---snip---
       Fix comment.
   ---snip---
   
   r193110:
   ---snip---
   	work around snapshot shutdown race reported by Henri Hennebert
   ---snip---
   
   r193440:
   ---snip---
       Support shared vnode locks for write operations when the offset is
       provided on filesystems that support it.  This really improves mysql
       + innodb performance on ZFS.
   
       Reviewed by:	jhb, kmacy, jeffr
   ---snip---
   ATTENTION: this commit to releng7 does not allow shared vnode locks
   (there are some VFS changes needed before it can be enabled), it only
   provides the infrastructure and serves mostly as a diff reduction in
   the ZFS code.
   A comment has been added to the locking part to explain why no shared
   locks are used.
   
   r195627:
   ---snip---
       In nvpair_native_embedded_array(), meaningless pointers are zeroed.
       The programmer was aware that alignment was not guaranteed in the
       packed structure and used bzero() to NULL out the pointers.
       However, on ia64, the compiler is quite agressive in finding ILP
       and calls to bzero() are often replaced by simple assignments (i.e.
       stores). Especially when the width or size in question corresponds
       with a store instruction (i.e. st1, st2, st4 or st8).
   
       The problem here is not a compiler bug. The address of the memory
       to zero-out was given by '&packed->nvl_priv' and given the type of
       the 'packed' pointer the compiler could assume proper alignment for
       the replacement of bzero() with an 8-byte wide store to be valid.
       The problem is with the programmer. The programmer knew that the
       address did not have the alignment guarantees needed for a regular
       assignment, but failed to inform the compiler of that fact. In
       fact, the programmer told the compiler the opposite: alignment is
       guaranteed.
   
       The fix is to avoid using a pointer of type "nvlist_t *" and
       instead use a "char *" pointer as the basis for calculating the
       address. This tells the compiler that only 1-byte alignment can
       be assumed and the compiler will either keep the bzero() call
       or instead replace it with a sequence of byte-wise stores. Both
       are valid.
   ---snip---
   
   r195822:
   ---snip---
       Fix extattr_list_file(2) on ZFS in case the attribute directory
       doesn't exist and user doesn't have write access to the file.
       Without this fix, it returns bogus value instead of 0.  For some
       reason this didn't manifest on my kernel compiled with -O0.
   
       PR:			kern/136601
       Submitted by:	Jaakko Heinonen <jh at saunalahti dot fi>
   ---snip---
   
   r195909
   ---snip---
       We don't support ephemeral IDs in FreeBSD and without this fix ZFS can
       panic when in zfs_fuid_create_cred() when userid is negative. It is
       converted to unsigned value which makes IS_EPHEMERAL() macro to
       incorrectly report that this is ephemeral ID. The most reasonable
       solution for now is to always report that the given ID is not ephemeral.
   
       PR:			kern/132337
       Submitted by:	Matthew West <freebsd@r.zeeb.org>
       Tested by:		Thomas Backman <serenity@exscape.org>, Michael Reifenberger <mike@reifenberger.com>
   ---snip---
   
   r196291:
   ---snip---
       - Fix a race where /dev/zfs control device is created before ZFS is fully
         initialized. Also destroy /dev/zfs before doing other deinitializations.
       - Initialization through taskq is no longer needed and there is a race
         where one of the zpool/zfs command loads zfs.ko and tries to do some work
         immediately, but /dev/zfs is not there yet.
   
       Reported by:	pav
   ---snip---
   
   r196269:
   ---snip---
       Fix misalignment in nvpair_native_embedded() caused by the compiler
       replacing the bzero(). See also revision 195627, which fixed the
       misalignment in nvpair_native_embedded_array().
   ---snip---
   
   r196295:
   ---snip---
       Remove OpenSolaris taskq port (it performs very poorly in our kernel) and
       replace it with wrappers around our taskqueue(9).
       To make it possible implement taskqueue_member() function which returns 1
       if the given thread was created by the given taskqueue.
   ---snip---
   The taskqueue_member() function is different due to kproc/kthread changes
   in releng8 and head, the function was...
   Revieved by:	jhb
   
   r196297:
   ---snip---
       Fix panic in zfs recv code. The last vnode (mountpoint's vnode) can have
       0 usecount.
   
       Reported by:	Thomas Backman <serenity@exscape.org>
   ---snip---
   
   r196299:
   ---snip---
       - We need to recycle vnode instead of freeing znode.
   
       Submitted by:	avg
   
       - Add missing vnode interlock unlock.
       - Remove redundant znode locking.
   ---snip---
   
   r196301:
   ---snip---
       If z_buf is NULL, we should free znode immediately.
   
       Noticed by:	avg
   ---snip---
   
   r196307:
   ---snip---
       Manage asynchronous vnode release just like Solaris.
   
       Discussed with:	kmacy
   ---snip---
 
 Added:
   stable/7/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c
      - copied unchanged from r196295, head/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c
   stable/7/sys/cddl/contrib/opensolaris/uts/common/sys/taskq.h
      - copied unchanged from r196295, head/sys/cddl/contrib/opensolaris/uts/common/sys/taskq.h
 Deleted:
   stable/7/sys/cddl/compat/opensolaris/sys/taskq.h
   stable/7/sys/cddl/compat/opensolaris/sys/taskq_impl.h
   stable/7/sys/cddl/contrib/opensolaris/uts/common/os/taskq.c
 Modified:
   stable/7/sys/cddl/compat/opensolaris/kern/opensolaris_kobj.c
   stable/7/sys/cddl/compat/opensolaris/sys/vnode.h
   stable/7/sys/cddl/contrib/opensolaris/common/nvpair/nvpair.c
   stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/gfs.c
   stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/vnode.c
   stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
   stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c
   stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_pool.h
   stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h
   stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h
   stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
   stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
   stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
   stable/7/sys/cddl/contrib/opensolaris/uts/common/sys/vnode.h
   stable/7/sys/cddl/dev/cyclic/cyclic.c
   stable/7/sys/cddl/dev/dtrace/i386/dtrace_subr.c
   stable/7/sys/kern/subr_taskqueue.c
   stable/7/sys/kern/vfs_vnops.c
   stable/7/sys/modules/zfs/Makefile
   stable/7/sys/sys/mount.h
   stable/7/sys/sys/taskqueue.h
 Directory Properties:
   stable/7/sys/   (props changed)
   stable/7/sys/cddl/contrib/opensolaris/   (props changed)
   stable/7/sys/contrib/dev/acpica/   (props changed)
   stable/7/sys/contrib/pf/   (props changed)
 
 Modified: stable/7/sys/cddl/compat/opensolaris/kern/opensolaris_kobj.c
 ==============================================================================
 --- stable/7/sys/cddl/compat/opensolaris/kern/opensolaris_kobj.c	Wed Jan  6 07:50:27 2010	(r201632)
 +++ stable/7/sys/cddl/compat/opensolaris/kern/opensolaris_kobj.c	Wed Jan  6 08:18:49 2010	(r201633)
 @@ -67,17 +67,25 @@ static void *
  kobj_open_file_vnode(const char *file)
  {
  	struct thread *td = curthread;
 +	struct filedesc *fd;
  	struct nameidata nd;
  	int error, flags;
  
 -	if (td->td_proc->p_fd->fd_rdir == NULL)
 -		td->td_proc->p_fd->fd_rdir = rootvnode;
 -	if (td->td_proc->p_fd->fd_cdir == NULL)
 -		td->td_proc->p_fd->fd_cdir = rootvnode;
 +	fd = td->td_proc->p_fd;
 +	FILEDESC_XLOCK(fd);
 +	if (fd->fd_rdir == NULL) {
 +		fd->fd_rdir = rootvnode;
 +		vref(fd->fd_rdir);
 +	}
 +	if (fd->fd_cdir == NULL) {
 +		fd->fd_cdir = rootvnode;
 +		vref(fd->fd_cdir);
 +	}
 +	FILEDESC_XUNLOCK(fd);
  
  	flags = FREAD;
 -	NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, file, td);
 -	error = vn_open_cred(&nd, &flags, 0, td->td_ucred, NULL);
 +	NDINIT(&nd, LOOKUP, MPSAFE, UIO_SYSSPACE, file, td);
 +	error = vn_open_cred(&nd, &flags, O_NOFOLLOW, td->td_ucred, NULL);
  	NDFREE(&nd, NDF_ONLY_PNBUF);
  	if (error != 0)
  		return (NULL);
 @@ -121,13 +129,15 @@ kobj_get_filesize_vnode(struct _buf *fil
  	struct vnode *vp = file->ptr;
  	struct thread *td = curthread;
  	struct vattr va;
 -	int error;
 +	int error, vfslocked;
  
 +	vfslocked = VFS_LOCK_GIANT(vp->v_mount);
  	vn_lock(vp, LK_SHARED | LK_RETRY, td);
  	error = VOP_GETATTR(vp, &va, td->td_ucred, td);
  	VOP_UNLOCK(vp, 0, td);
  	if (error == 0)
  		*size = (uint64_t)va.va_size;
 +	VFS_UNLOCK_GIANT(vfslocked);
  	return (error);
  }
  
 @@ -160,7 +170,7 @@ kobj_read_file_vnode(struct _buf *file, 
  	struct thread *td = curthread;
  	struct uio auio;
  	struct iovec aiov;
 -	int error;
 +	int error, vfslocked;
  
  	bzero(&aiov, sizeof(aiov));
  	bzero(&auio, sizeof(auio));
 @@ -176,9 +186,11 @@ kobj_read_file_vnode(struct _buf *file, 
  	auio.uio_resid = size;
  	auio.uio_td = td;
  
 +	vfslocked = VFS_LOCK_GIANT(vp->v_mount);
  	vn_lock(vp, LK_SHARED | LK_RETRY, td);
  	error = VOP_READ(vp, &auio, IO_UNIT | IO_SYNC, td->td_ucred);
  	VOP_UNLOCK(vp, 0, td);
 +	VFS_UNLOCK_GIANT(vfslocked);
  	return (error != 0 ? -1 : size - auio.uio_resid);
  }
  
 @@ -212,9 +224,11 @@ kobj_close_file(struct _buf *file)
  	if (file->mounted) {
  		struct vnode *vp = file->ptr;
  		struct thread *td = curthread;
 -		int flags = FREAD;
 +		int vfslocked;
  
 -		vn_close(vp, flags, td->td_ucred, td);
 +		vfslocked = VFS_LOCK_GIANT(vp->v_mount);
 +		vn_close(vp, FREAD, td->td_ucred, td);
 +		VFS_UNLOCK_GIANT(vfslocked);
  	}
  	kmem_free(file, sizeof(*file));
  }
 
 Copied: stable/7/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c (from r196295, head/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c)
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ stable/7/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c	Wed Jan  6 08:18:49 2010	(r201633, copy of r196295, head/sys/cddl/compat/opensolaris/kern/opensolaris_taskq.c)
 @@ -0,0 +1,135 @@
 +/*-
 + * Copyright (c) 2009 Pawel Jakub Dawidek <pjd@FreeBSD.org>
 + * All rights reserved.
 + *
 + * Redistribution and use in source and binary forms, with or without
 + * modification, are permitted provided that the following conditions
 + * are met:
 + * 1. Redistributions of source code must retain the above copyright
 + *    notice, this list of conditions and the following disclaimer.
 + * 2. Redistributions in binary form must reproduce the above copyright
 + *    notice, this list of conditions and the following disclaimer in the
 + *    documentation and/or other materials provided with the distribution.
 + *
 + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 + * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 + * SUCH DAMAGE.
 + */
 +
 +#include <sys/cdefs.h>
 +__FBSDID("$FreeBSD$");
 +
 +#include <sys/param.h>
 +#include <sys/kernel.h>
 +#include <sys/kmem.h>
 +#include <sys/lock.h>
 +#include <sys/mutex.h>
 +#include <sys/queue.h>
 +#include <sys/taskqueue.h>
 +#include <sys/taskq.h>
 +
 +#include <vm/uma.h>
 +
 +static uma_zone_t taskq_zone;
 +
 +struct ostask {
 +	struct task	ost_task;
 +	task_func_t	*ost_func;
 +	void		*ost_arg;
 +};
 +
 +taskq_t *system_taskq = NULL;
 +
 +static void
 +system_taskq_init(void *arg)
 +{
 +
 +	system_taskq = (taskq_t *)taskqueue_thread;
 +	taskq_zone = uma_zcreate("taskq_zone", sizeof(struct ostask),
 +	    NULL, NULL, NULL, NULL, 0, 0);
 +}
 +SYSINIT(system_taskq_init, SI_SUB_CONFIGURE, SI_ORDER_ANY, system_taskq_init, NULL);
 +
 +static void
 +system_taskq_fini(void *arg)
 +{
 +
 +	uma_zdestroy(taskq_zone);
 +}
 +SYSUNINIT(system_taskq_fini, SI_SUB_CONFIGURE, SI_ORDER_ANY, system_taskq_fini, NULL);
 +
 +taskq_t *
 +taskq_create(const char *name, int nthreads, pri_t pri, int minalloc __unused,
 +    int maxalloc __unused, uint_t flags)
 +{
 +	taskq_t *tq;
 +
 +	if ((flags & TASKQ_THREADS_CPU_PCT) != 0) {
 +		/* TODO: Calculate number od threads. */
 +		printf("%s: TASKQ_THREADS_CPU_PCT\n", __func__);
 +	}
 +
 +	tq = kmem_alloc(sizeof(*tq), KM_SLEEP);
 +	tq->tq_queue = taskqueue_create(name, M_WAITOK, taskqueue_thread_enqueue,
 +	    &tq->tq_queue);
 +	(void) taskqueue_start_threads(&tq->tq_queue, nthreads, pri, name);
 +
 +	return ((taskq_t *)tq);
 +}
 +
 +void
 +taskq_destroy(taskq_t *tq)
 +{
 +
 +	taskqueue_free(tq->tq_queue);
 +	kmem_free(tq, sizeof(*tq));
 +}
 +
 +int
 +taskq_member(taskq_t *tq, kthread_t *thread)
 +{
 +
 +	return (taskqueue_member(tq->tq_queue, thread));
 +}
 +
 +static void
 +taskq_run(void *arg, int pending __unused)
 +{
 +	struct ostask *task = arg;
 +
 +	task->ost_func(task->ost_arg);
 +
 +	uma_zfree(taskq_zone, task);
 +}
 +
 +taskqid_t
 +taskq_dispatch(taskq_t *tq, task_func_t func, void *arg, uint_t flags)
 +{
 +	struct ostask *task;
 +	int mflag;
 +
 +	if ((flags & (TQ_SLEEP | TQ_NOQUEUE)) == TQ_SLEEP)
 +		mflag = M_WAITOK;
 +	else
 +		mflag = M_NOWAIT;
 +
 +	task = uma_zalloc(taskq_zone, mflag);
 +	if (task == NULL)
 +		return (0);
 +
 +	task->ost_func = func;
 +	task->ost_arg = arg;
 +
 +	TASK_INIT(&task->ost_task, 0, taskq_run, task);
 +	taskqueue_enqueue(tq->tq_queue, &task->ost_task);
 +
 +	return ((taskqid_t)(void *)task);
 +}
 
 Modified: stable/7/sys/cddl/compat/opensolaris/sys/vnode.h
 ==============================================================================
 --- stable/7/sys/cddl/compat/opensolaris/sys/vnode.h	Wed Jan  6 07:50:27 2010	(r201632)
 +++ stable/7/sys/cddl/compat/opensolaris/sys/vnode.h	Wed Jan  6 08:18:49 2010	(r201633)
 @@ -75,7 +75,6 @@ vn_is_readonly(vnode_t *vp)
  #define	VN_HOLD(v)	vref(v)
  #define	VN_RELE(v)	vrele(v)
  #define	VN_URELE(v)	vput(v)
 -#define	VN_RELE_ASYNC(v, tq)	vn_rele_async(v, tq); 
  
  #define	VOP_REALVP(vp, vpp, ct)	(*(vpp) = (vp), 0)
  
 
 Modified: stable/7/sys/cddl/contrib/opensolaris/common/nvpair/nvpair.c
 ==============================================================================
 --- stable/7/sys/cddl/contrib/opensolaris/common/nvpair/nvpair.c	Wed Jan  6 07:50:27 2010	(r201632)
 +++ stable/7/sys/cddl/contrib/opensolaris/common/nvpair/nvpair.c	Wed Jan  6 08:18:49 2010	(r201633)
 @@ -2523,14 +2523,15 @@ nvpair_native_embedded(nvstream_t *nvs, 
  {
  	if (nvs->nvs_op == NVS_OP_ENCODE) {
  		nvs_native_t *native = (nvs_native_t *)nvs->nvs_private;
 -		nvlist_t *packed = (void *)
 +		char *packed = (void *)
  		    (native->n_curr - nvp->nvp_size + NVP_VALOFF(nvp));
  		/*
  		 * Null out the pointer that is meaningless in the packed
  		 * structure. The address may not be aligned, so we have
  		 * to use bzero.
  		 */
 -		bzero(&packed->nvl_priv, sizeof (packed->nvl_priv));
 +		bzero(packed + offsetof(nvlist_t, nvl_priv),
 +		    sizeof(((nvlist_t *)NULL)->nvl_priv));
  	}
  
  	return (nvs_embedded(nvs, EMBEDDED_NVL(nvp)));
 @@ -2543,7 +2544,6 @@ nvpair_native_embedded_array(nvstream_t 
  		nvs_native_t *native = (nvs_native_t *)nvs->nvs_private;
  		char *value = native->n_curr - nvp->nvp_size + NVP_VALOFF(nvp);
  		size_t len = NVP_NELEM(nvp) * sizeof (uint64_t);
 -		nvlist_t *packed = (nvlist_t *)((uintptr_t)value + len);
  		int i;
  		/*
  		 * Null out pointers that are meaningless in the packed
 @@ -2552,13 +2552,17 @@ nvpair_native_embedded_array(nvstream_t 
  		 */
  		bzero(value, len);
  
 -		for (i = 0; i < NVP_NELEM(nvp); i++, packed++)
 +		value += len;
 +		for (i = 0; i < NVP_NELEM(nvp); i++) {
  			/*
  			 * Null out the pointer that is meaningless in the
  			 * packed structure. The address may not be aligned,
  			 * so we have to use bzero.
  			 */
 -			bzero(&packed->nvl_priv, sizeof (packed->nvl_priv));
 +			bzero(value + offsetof(nvlist_t, nvl_priv),
 +			    sizeof(((nvlist_t *)NULL)->nvl_priv));
 +			value += sizeof(nvlist_t);
 +		}
  	}
  
  	return (nvs_embedded_nvl_array(nvs, nvp, NULL));
 
 Modified: stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/gfs.c
 ==============================================================================
 --- stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/gfs.c	Wed Jan  6 07:50:27 2010	(r201632)
 +++ stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/gfs.c	Wed Jan  6 08:18:49 2010	(r201633)
 @@ -564,8 +564,13 @@ gfs_file_inactive(vnode_t *vp)
  	if (fp->gfs_parent == NULL || (vp->v_flag & V_XATTRDIR))
  		goto found;
  
 -	dp = fp->gfs_parent->v_data;
 -
 +	/*
 +	 * XXX cope with a FreeBSD-specific race wherein the parent's
 +	 * snapshot data can be freed before the parent is
 +	 */
 +	if ((dp = fp->gfs_parent->v_data) == NULL)
 +		return (NULL);
 +		
  	/*
  	 * First, see if this vnode is cached in the parent.
  	 */
 
 Modified: stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/vnode.c
 ==============================================================================
 --- stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/vnode.c	Wed Jan  6 07:50:27 2010	(r201632)
 +++ stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/vnode.c	Wed Jan  6 08:18:49 2010	(r201633)
 @@ -19,7 +19,7 @@
   * 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.
   */
  
 @@ -36,9 +36,6 @@
   * contributors.
   */
  
 -
 -#pragma ident	"%Z%%M%	%I%	%E% SMI"
 -
  #include <sys/types.h>
  #include <sys/param.h>
  #include <sys/kernel.h>
 @@ -76,15 +73,12 @@ xva_getxoptattr(xvattr_t *xvap)
  	return (xoap);
  }
  
 -static STAILQ_HEAD(, vnode) vn_rele_async_list;
 -static struct mtx vn_rele_async_lock;
 -static struct cv vn_rele_async_cv;
 -static int vn_rele_list_length;
 -static int vn_rele_async_thread_exit;
 -
 -typedef struct  {
 -	struct vnode *stqe_next;
 -} vnode_link_t;
 +static void
 +vn_rele_inactive(vnode_t *vp)
 +{
 +
 +	vrele(vp);
 +}
  
  /*
   * Like vn_rele() except if we are going to call VOP_INACTIVE() then do it
 @@ -97,117 +91,16 @@ typedef struct  {
   * This is because taskqs throttle back allocation if too many are created.
   */
  void
 -vn_rele_async(vnode_t *vp, taskq_t *taskq /* unused */)
 +vn_rele_async(vnode_t *vp, taskq_t *taskq)
  {
 -	
 -	KASSERT(vp != NULL, ("vrele: null vp"));
 -	VFS_ASSERT_GIANT(vp->v_mount);
 +	VERIFY(vp->v_count > 0);
  	VI_LOCK(vp);
 -
 -	if (vp->v_usecount > 1 || ((vp->v_iflag & VI_DOINGINACT) &&
 -	    vp->v_usecount == 1)) {
 -		vp->v_usecount--;
 -		vdropl(vp);
 -		return;
 -	}	
 -	if (vp->v_usecount != 1) {
 -#ifdef DIAGNOSTIC
 -		vprint("vrele: negative ref count", vp);
 -#endif
 +	if (vp->v_count == 1 && !(vp->v_iflag & VI_DOINGINACT)) {
  		VI_UNLOCK(vp);
 -		panic("vrele: negative ref cnt");
 -	}
 -	/*
 -	 * We are exiting
 -	 */
 -	if (vn_rele_async_thread_exit != 0) {
 -		vrele(vp);
 +		VERIFY(taskq_dispatch((taskq_t *)taskq,
 +		    (task_func_t *)vn_rele_inactive, vp, TQ_SLEEP) != 0);
  		return;
  	}
 -	
 -	mtx_lock(&vn_rele_async_lock);
 -
 -	/*  STAILQ_INSERT_TAIL 			*/
 -	(*(vnode_link_t *)&vp->v_cstart).stqe_next = NULL;
 -	*vn_rele_async_list.stqh_last = vp;
 -	vn_rele_async_list.stqh_last =
 -	    &((vnode_link_t *)&vp->v_cstart)->stqe_next;
 -
 -	/****************************************/
 -	vn_rele_list_length++;
 -	if ((vn_rele_list_length % 100) == 0)
 -		cv_signal(&vn_rele_async_cv);
 -	mtx_unlock(&vn_rele_async_lock);
 -	VI_UNLOCK(vp);
 -}
 -
 -static void
 -vn_rele_async_init(void *arg)
 -{
 -
 -	mtx_init(&vn_rele_async_lock, "valock", NULL, MTX_DEF);
 -	STAILQ_INIT(&vn_rele_async_list);
 -
 -	/* cv_init(&vn_rele_async_cv, "vacv"); */
 -	vn_rele_async_cv.cv_description = "vacv";
 -	vn_rele_async_cv.cv_waiters = 0;
 -}
 -
 -void
 -vn_rele_async_fini(void)
 -{
 -
 -	mtx_lock(&vn_rele_async_lock);
 -	vn_rele_async_thread_exit = 1;
 -	cv_signal(&vn_rele_async_cv);
 -	while (vn_rele_async_thread_exit != 0)
 -		cv_wait(&vn_rele_async_cv, &vn_rele_async_lock);
 -	mtx_unlock(&vn_rele_async_lock);
 -	mtx_destroy(&vn_rele_async_lock);
 -}
 -
 -
 -static void
 -vn_rele_async_cleaner(void)
 -{
 -	STAILQ_HEAD(, vnode) vn_tmp_list;
 -	struct vnode *curvnode;
 -
 -	STAILQ_INIT(&vn_tmp_list);
 -	mtx_lock(&vn_rele_async_lock);
 -	while (vn_rele_async_thread_exit == 0) {
 -		STAILQ_CONCAT(&vn_tmp_list, &vn_rele_async_list);
 -		vn_rele_list_length = 0;
 -		mtx_unlock(&vn_rele_async_lock);
 -		
 -		while (!STAILQ_EMPTY(&vn_tmp_list)) {
 -			curvnode = STAILQ_FIRST(&vn_tmp_list);
 -
 -			/*   STAILQ_REMOVE_HEAD */
 -			STAILQ_FIRST(&vn_tmp_list) =
 -			    ((vnode_link_t *)&curvnode->v_cstart)->stqe_next;
 -			if (STAILQ_FIRST(&vn_tmp_list) == NULL)
 -				         vn_tmp_list.stqh_last = &STAILQ_FIRST(&vn_tmp_list);
 -			/***********************/
 -			vrele(curvnode);
 -		}
 -		mtx_lock(&vn_rele_async_lock);
 -		if (vn_rele_list_length == 0)
 -			cv_timedwait(&vn_rele_async_cv, &vn_rele_async_lock,
 -			    hz/10);
 -	}
 -
 -	vn_rele_async_thread_exit = 0;
 -	cv_broadcast(&vn_rele_async_cv);
 -	mtx_unlock(&vn_rele_async_lock);
 -	thread_exit();
 +	vp->v_usecount--;
 +	vdropl(vp);
  }
 -
 -static struct proc *vn_rele_async_proc;
 -static struct kproc_desc up_kp = {
 -	"vaclean",
 -	vn_rele_async_cleaner,
 -	&vn_rele_async_proc
 -};
 -SYSINIT(vaclean, SI_SUB_KTHREAD_UPDATE, SI_ORDER_FIRST, kproc_start, &up_kp);
 -SYSINIT(vn_rele_async_setup, SI_SUB_VFS, SI_ORDER_FIRST, vn_rele_async_init, NULL);
 
 Modified: stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c
 ==============================================================================
 --- stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c	Wed Jan  6 07:50:27 2010	(r201632)
 +++ stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c	Wed Jan  6 08:18:49 2010	(r201633)
 @@ -1199,9 +1199,6 @@ dmu_init(void)
  void
  dmu_fini(void)
  {
 -#ifdef _KERNEL
 -	vn_rele_async_fini();
 -#endif
  	arc_fini();
  	dnode_fini();
  	dbuf_fini();
 
 Modified: stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c
 ==============================================================================
 --- stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c	Wed Jan  6 07:50:27 2010	(r201632)
 +++ stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dsl_pool.c	Wed Jan  6 08:18:49 2010	(r201633)
 @@ -91,6 +91,9 @@ dsl_pool_open_impl(spa_t *spa, uint64_t 
  	mutex_init(&dp->dp_lock, NULL, MUTEX_DEFAULT, NULL);
  	mutex_init(&dp->dp_scrub_cancel_lock, NULL, MUTEX_DEFAULT, NULL);
  
 +	dp->dp_vnrele_taskq = taskq_create("zfs_vn_rele_taskq", 1, minclsyspri,
 +	    1, 4, 0);
 +
  	return (dp);
  }
  
 @@ -228,6 +231,7 @@ dsl_pool_close(dsl_pool_t *dp)
  	rw_destroy(&dp->dp_config_rwlock);
  	mutex_destroy(&dp->dp_lock);
  	mutex_destroy(&dp->dp_scrub_cancel_lock);
 +	taskq_destroy(dp->dp_vnrele_taskq);
  	kmem_free(dp, sizeof (dsl_pool_t));
  }
  
 @@ -611,3 +615,9 @@ dsl_pool_create_origin(dsl_pool_t *dp, d
  	dsl_dataset_rele(ds, FTAG);
  	rw_exit(&dp->dp_config_rwlock);
  }
 +
 +taskq_t *
 +dsl_pool_vnrele_taskq(dsl_pool_t *dp)
 +{
 +	return (dp->dp_vnrele_taskq);
 +}
 
 Modified: stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_pool.h
 ==============================================================================
 --- stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_pool.h	Wed Jan  6 07:50:27 2010	(r201632)
 +++ stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/dsl_pool.h	Wed Jan  6 08:18:49 2010	(r201633)
 @@ -57,6 +57,7 @@ typedef struct dsl_pool {
  	struct dsl_dir *dp_mos_dir;
  	struct dsl_dataset *dp_origin_snap;
  	uint64_t dp_root_dir_obj;
 +	struct taskq *dp_vnrele_taskq;
  
  	/* No lock needed - sync context only */
  	blkptr_t dp_meta_rootbp;
 @@ -119,6 +120,8 @@ int dsl_pool_scrub_clean(dsl_pool_t *dp)
  void dsl_pool_scrub_sync(dsl_pool_t *dp, dmu_tx_t *tx);
  void dsl_pool_scrub_restart(dsl_pool_t *dp);
  
 +taskq_t *dsl_pool_vnrele_taskq(dsl_pool_t *dp);
 +
  #ifdef	__cplusplus
  }
  #endif
 
 Modified: stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h
 ==============================================================================
 --- stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h	Wed Jan  6 07:50:27 2010	(r201632)
 +++ stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_context.h	Wed Jan  6 08:18:49 2010	(r201633)
 @@ -49,6 +49,7 @@ extern "C" {
  #include <sys/conf.h>
  #include <sys/mutex.h>
  #include <sys/rwlock.h>
 +#include <sys/kcondvar.h>
  #include <sys/random.h>
  #include <sys/byteorder.h>
  #include <sys/systm.h>
 
 Modified: stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h
 ==============================================================================
 --- stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h	Wed Jan  6 07:50:27 2010	(r201632)
 +++ stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h	Wed Jan  6 08:18:49 2010	(r201633)
 @@ -78,7 +78,11 @@ extern "C" {
  /*
   * Is ID ephemeral?
   */
 +#ifdef TODO
  #define	IS_EPHEMERAL(x)		(x > MAXUID)
 +#else
 +#define	IS_EPHEMERAL(x)		(0)
 +#endif
  
  /*
   * Should we use FUIDs?
 
 Modified: stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c
 ==============================================================================
 --- stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c	Wed Jan  6 07:50:27 2010	(r201632)
 +++ stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ioctl.c	Wed Jan  6 08:18:49 2010	(r201633)
 @@ -3057,44 +3057,35 @@ zfsdev_fini(void)
  		destroy_dev(zfsdev);
  }
  
 -static struct task zfs_start_task;
  static struct root_hold_token *zfs_root_token;
  
 -
  uint_t zfs_fsyncer_key;
  extern uint_t rrw_tsd_key;
  
 -static void
 -zfs_start(void *context __unused, int pending __unused)
 -{
 -
 -	zfsdev_init();
 -	spa_init(FREAD | FWRITE);
 -	zfs_init();
 -	zvol_init();
 -
 -	tsd_create(&zfs_fsyncer_key, NULL);
 -	tsd_create(&rrw_tsd_key, NULL);
 -
 -	printf("ZFS storage pool version " SPA_VERSION_STRING "\n");
 -	root_mount_rel(zfs_root_token);
 -}
 -
  static int
  zfs_modevent(module_t mod, int type, void *unused __unused)
  {
 -	int error;
 +	int error = 0;
  
 -	error = EOPNOTSUPP;
  	switch (type) {
  	case MOD_LOAD:
  		zfs_root_token = root_mount_hold("ZFS");
  		printf("WARNING: ZFS is considered to be an experimental "
  		    "feature in FreeBSD.\n");
 -		TASK_INIT(&zfs_start_task, 0, zfs_start, NULL);
 -		taskqueue_enqueue(taskqueue_thread, &zfs_start_task);
 +
  		mutex_init(&zfs_share_lock, NULL, MUTEX_DEFAULT, NULL);
 -		error = 0;
 +
 +		spa_init(FREAD | FWRITE);
 +		zfs_init();
 +		zvol_init();
 +
 +		tsd_create(&zfs_fsyncer_key, NULL);
 +		tsd_create(&rrw_tsd_key, NULL);
 +
 +		printf("ZFS storage pool version " SPA_VERSION_STRING "\n");
 +		root_mount_rel(zfs_root_token);
 +
 +		zfsdev_init();
  		break;
  	case MOD_UNLOAD:
  		if (spa_busy() || zfs_busy() || zvol_busy() ||
 @@ -3102,14 +3093,19 @@ zfs_modevent(module_t mod, int type, voi
  			error = EBUSY;
  			break;
  		}
 +
 +		zfsdev_fini();
  		zvol_fini();
  		zfs_fini();
  		spa_fini();
 -		zfsdev_fini();
 +
  		tsd_destroy(&zfs_fsyncer_key);
  		tsd_destroy(&rrw_tsd_key);
 +
  		mutex_destroy(&zfs_share_lock);
 -		error = 0;
 +		break;
 +	default:
 +		error = EOPNOTSUPP;
  		break;
  	}
  	return (error);
 
 Modified: stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
 ==============================================================================
 --- stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c	Wed Jan  6 07:50:27 2010	(r201632)
 +++ stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c	Wed Jan  6 08:18:49 2010	(r201633)
 @@ -576,6 +576,7 @@ zfs_domount(vfs_t *vfsp, char *osname)
  	vfsp->mnt_flag |= MNT_LOCAL;
  	vfsp->mnt_kern_flag |= MNTK_MPSAFE;
  	vfsp->mnt_kern_flag |= MNTK_LOOKUP_SHARED;
 +	vfsp->mnt_kern_flag |= MNTK_SHARED_WRITES;
  
  	if (error = dsl_prop_get_integer(osname, "readonly", &readonly, NULL))
  		goto out;
 @@ -924,7 +925,7 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolea
  	for (zp = list_head(&zfsvfs->z_all_znodes); zp != NULL;
  	    zp = list_next(&zfsvfs->z_all_znodes, zp))
  		if (zp->z_dbuf) {
 -			ASSERT(ZTOV(zp)->v_count > 0);
 +			ASSERT(ZTOV(zp)->v_count >= 0);
  			zfs_znode_dmu_fini(zp);
  		}
  	mutex_exit(&zfsvfs->z_znodes_lock);
 
 Modified: stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
 ==============================================================================
 --- stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c	Wed Jan  6 07:50:27 2010	(r201632)
 +++ stable/7/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c	Wed Jan  6 08:18:49 2010	(r201633)
 @@ -925,6 +925,7 @@ zfs_get_done(dmu_buf_t *db, void *vzgd)
  	zgd_t *zgd = (zgd_t *)vzgd;
  	rl_t *rl = zgd->zgd_rl;
  	vnode_t *vp = ZTOV(rl->r_zp);
 +	objset_t *os = rl->r_zp->z_zfsvfs->z_os;
  	int vfslocked;
  
  	vfslocked = VFS_LOCK_GIANT(vp->v_vfsp);
 @@ -934,7 +935,7 @@ zfs_get_done(dmu_buf_t *db, void *vzgd)
  	 * Release the vnode asynchronously as we currently have the
  	 * txg stopped from syncing.
  	 */
 -	VN_RELE_ASYNC(vp, NULL);
 +	VN_RELE_ASYNC(vp, dsl_pool_vnrele_taskq(dmu_objset_pool(os)));
  	zil_add_block(zgd->zgd_zilog, zgd->zgd_bp);
  	kmem_free(zgd, sizeof (zgd_t));
  	VFS_UNLOCK_GIANT(vfslocked);
 @@ -969,8 +970,8 @@ zfs_get_data(void *arg, lr_write_t *lr, 
  		 * Release the vnode asynchronously as we currently have the
  		 * txg stopped from syncing.
  		 */
 -		VN_RELE_ASYNC(ZTOV(zp), NULL);
 -
 +		VN_RELE_ASYNC(ZTOV(zp),
 +		    dsl_pool_vnrele_taskq(dmu_objset_pool(os)));
  		return (ENOENT);
  	}
  
 @@ -1046,7 +1047,7 @@ out:
  	 * Release the vnode asynchronously as we currently have the
  	 * txg stopped from syncing.
  	 */
 -	VN_RELE_ASYNC(ZTOV(zp), NULL);
 +	VN_RELE_ASYNC(ZTOV(zp), dsl_pool_vnrele_taskq(dmu_objset_pool(os)));
  	return (error);
  }
  
 @@ -3709,12 +3710,11 @@ zfs_inactive(vnode_t *vp, cred_t *cr, ca
  		 * The fs has been unmounted, or we did a
  		 * suspend/resume and this file no longer exists.
  		 */
 -		mutex_enter(&zp->z_lock);
  		VI_LOCK(vp);
  		vp->v_count = 0; /* count arrives as 1 */
 -		mutex_exit(&zp->z_lock);
 +		VI_UNLOCK(vp);
 +		vrecycle(vp, curthread);
  		rw_exit(&zfsvfs->z_teardown_inactive_lock);
 -		zfs_znode_free(zp);
  		return;
  	}
  
 @@ -3963,7 +3963,7 @@ static int
  zfs_freebsd_access(ap)
  	struct vop_access_args /* {
  		struct vnode *a_vp;
 -		int  a_accmode;
 +		accmode_t a_accmode;
  		struct ucred *a_cred;
  		struct thread *a_td;
  	} */ *ap;
 @@ -4355,7 +4355,6 @@ zfs_freebsd_reclaim(ap)
  {
  	vnode_t	*vp = ap->a_vp;
  	znode_t	*zp = VTOZ(vp);
 -	zfsvfs_t *zfsvfs;
  
  	ASSERT(zp != NULL);
  
 @@ -4365,13 +4364,18 @@ zfs_freebsd_reclaim(ap)
  	vnode_destroy_vobject(vp);
  
  	mutex_enter(&zp->z_lock);
 -	ASSERT(zp->z_phys);
 +	ASSERT(zp->z_phys != NULL);
  	ZTOV(zp) = NULL;
 -	if (!zp->z_unlinked) {
 +	mutex_exit(&zp->z_lock);
 +
 +	if (zp->z_unlinked)
 +		;	/* Do nothing. */
 +	else if (zp->z_dbuf == NULL)
 +		zfs_znode_free(zp);
 +	else /* if (!zp->z_unlinked && zp->z_dbuf != NULL) */ {
 +		zfsvfs_t *zfsvfs = zp->z_zfsvfs;
  		int locked;
  
 -		zfsvfs = zp->z_zfsvfs;
 -		mutex_exit(&zp->z_lock);
  		locked = MUTEX_HELD(ZFS_OBJ_MUTEX(zfsvfs, zp->z_id)) ? 2 :
  		    ZFS_OBJ_HOLD_TRYENTER(zfsvfs, zp->z_id);
  		if (locked == 0) {
 @@ -4387,8 +4391,6 @@ zfs_freebsd_reclaim(ap)
  				ZFS_OBJ_HOLD_EXIT(zfsvfs, zp->z_id);
  			zfs_znode_free(zp);
  		}
 -	} else {
 -		mutex_exit(&zp->z_lock);
  	}
  	VI_LOCK(vp);
  	vp->v_data = NULL;
 @@ -4702,6 +4704,9 @@ vop_listextattr {
  
  	ZFS_ENTER(zfsvfs);
  
 +	if (sizep != NULL)
 +		*sizep = 0;
 +
  	error = zfs_lookup(ap->a_vp, NULL, &xvp, NULL, 0, ap->a_cred, td,
  	    LOOKUP_XATTR);
  	if (error != 0) {
 @@ -4726,9 +4731,6 @@ vop_listextattr {
  	auio.uio_rw = UIO_READ;
  	auio.uio_offset = 0;
  
 -	if (sizep != NULL)
 -		*sizep = 0;
 -
  	do {
  		u_char nlen;
  
 
 Copied: stable/7/sys/cddl/contrib/opensolaris/uts/common/sys/taskq.h (from r196295, head/sys/cddl/contrib/opensolaris/uts/common/sys/taskq.h)
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ stable/7/sys/cddl/contrib/opensolaris/uts/common/sys/taskq.h	Wed Jan  6 08:18:49 2010	(r201633, copy of r196295, head/sys/cddl/contrib/opensolaris/uts/common/sys/taskq.h)
 @@ -0,0 +1,90 @@
 +/*
 + * CDDL HEADER START
 + *
 + * The contents of this file are subject to the terms of the
 + * Common Development and Distribution License (the "License").
 + * You may not use this file except in compliance with the License.
 + *
 + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 + * or http://www.opensolaris.org/os/licensing.
 + * See the License for the specific language governing permissions
 + * and limitations under the License.
 + *
 + * When distributing Covered Code, include this CDDL HEADER in each
 + * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 + * If applicable, add the following below this CDDL HEADER, with the
 + * fields enclosed by brackets "[]" replaced with your own identifying
 + * information: Portions Copyright [yyyy] [name of copyright owner]
 + *
 + * CDDL HEADER END
 + */
 +/*
 + * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
 + * Use is subject to license terms.
 + */
 +
 +#ifndef	_SYS_TASKQ_H
 +#define	_SYS_TASKQ_H
 +
 +#include <sys/types.h>
 +#include <sys/proc.h>
 +#include <sys/taskqueue.h>
 +
 +#ifdef	__cplusplus
 +extern "C" {
 +#endif
 +
 +#define	TASKQ_NAMELEN	31
 +
 +struct taskqueue;
 +struct taskq {
 +	struct taskqueue	*tq_queue;
 +};
 +
 +typedef struct taskq taskq_t;
 +typedef uintptr_t taskqid_t;
 +typedef void (task_func_t)(void *);
 +
 +/*
 + * Public flags for taskq_create(): bit range 0-15
 + */
 +#define	TASKQ_PREPOPULATE	0x0001	/* Prepopulate with threads and data */
 +#define	TASKQ_CPR_SAFE		0x0002	/* Use CPR safe protocol */
 +#define	TASKQ_DYNAMIC		0x0004	/* Use dynamic thread scheduling */
 +#define	TASKQ_THREADS_CPU_PCT	0x0008	/* number of threads as % of ncpu */
 +
 +/*
 + * Flags for taskq_dispatch. TQ_SLEEP/TQ_NOSLEEP should be same as
 + * KM_SLEEP/KM_NOSLEEP.
 + */
 +#define	TQ_SLEEP	0x00	/* Can block for memory */
 +#define	TQ_NOSLEEP	0x01	/* cannot block for memory; may fail */
 +#define	TQ_NOQUEUE	0x02	/* Do not enqueue if can't dispatch */
 +#define	TQ_NOALLOC	0x04	/* cannot allocate memory; may fail */
 +
 +#ifdef _KERNEL
 +
 +extern taskq_t *system_taskq;
 +
 +extern void	taskq_init(void);
 +extern void	taskq_mp_init(void);
 +
 +extern taskq_t	*taskq_create(const char *, int, pri_t, int, int, uint_t);
 +extern taskq_t	*taskq_create_instance(const char *, int, int, pri_t, int,
 +    int, uint_t);
 +extern taskqid_t taskq_dispatch(taskq_t *, task_func_t, void *, uint_t);
 +extern void	nulltask(void *);
 +extern void	taskq_destroy(taskq_t *);
 +extern void	taskq_wait(taskq_t *);
 +extern void	taskq_suspend(taskq_t *);
 +extern int	taskq_suspended(taskq_t *);
 +extern void	taskq_resume(taskq_t *);
 +extern int	taskq_member(taskq_t *, kthread_t *);
 +
 +#endif	/* _KERNEL */
 +
 +#ifdef	__cplusplus
 +}
 +#endif
 +
 +#endif	/* _SYS_TASKQ_H */
 
 Modified: stable/7/sys/cddl/contrib/opensolaris/uts/common/sys/vnode.h
 ==============================================================================
 --- stable/7/sys/cddl/contrib/opensolaris/uts/common/sys/vnode.h	Wed Jan  6 07:50:27 2010	(r201632)
 +++ stable/7/sys/cddl/contrib/opensolaris/uts/common/sys/vnode.h	Wed Jan  6 08:18:49 2010	(r201633)
 @@ -354,6 +354,11 @@ typedef struct caller_context {
  } caller_context_t;
  
  /*
 + * Structure tags for function prototypes, defined elsewhere.
 + */
 +struct taskq;
 +
 +/*
   * Flags for VOP_LOOKUP
   *
   * Defined in file.h, but also possible, FIGNORECASE
 @@ -370,6 +375,13 @@ typedef struct caller_context {
  #define	V_RDDIR_ENTFLAGS	0x01	/* request dirent flags */
  
  /*
 + * Public vnode manipulation functions.
 + */
 +#ifdef	_KERNEL
 +
 +void	vn_rele_async(struct vnode *vp, struct taskq *taskq);
 +
 +/*
   * Extensible vnode attribute (xva) routines:
   * xva_init() initializes an xvattr_t (zero struct, init mapsize, set AT_XATTR)
   * xva_getxoptattr() returns a ponter to the xoptattr_t section of xvattr_t
 @@ -377,10 +389,12 @@ typedef struct caller_context {
  void		xva_init(xvattr_t *);
  xoptattr_t	*xva_getxoptattr(xvattr_t *);	/* Get ptr to xoptattr_t */
  
 -struct taskq;
 -void	vn_rele_async(struct vnode *vp, struct taskq *taskq);
 -void	vn_rele_async_fini(void);
 -	
 +#define	VN_RELE_ASYNC(vp, taskq)	{ \
 +	vn_rele_async(vp, taskq); \
 +}
 +
 +#endif	/* _KERNEL */
 +
  /*
   * Flags to VOP_SETATTR/VOP_GETATTR.
   */
 
 Modified: stable/7/sys/cddl/dev/cyclic/cyclic.c
 ==============================================================================
 --- stable/7/sys/cddl/dev/cyclic/cyclic.c	Wed Jan  6 07:50:27 2010	(r201632)
 +++ stable/7/sys/cddl/dev/cyclic/cyclic.c	Wed Jan  6 08:18:49 2010	(r201633)
 @@ -1341,12 +1341,11 @@ cyclic_mp_init(void)
  static void
  cyclic_uninit(void)
  {
 -	struct pcpu *pc;
  	cpu_t *c;
  	int id;
  
  	for (id = 0; id <= mp_maxid; id++) {
 -		if ((pc = pcpu_find(id)) == NULL)
 +		if (pcpu_find(id) == NULL)
  			continue;
  
  		c = &solaris_cpu[id];
 
 Modified: stable/7/sys/cddl/dev/dtrace/i386/dtrace_subr.c
 ==============================================================================
 --- stable/7/sys/cddl/dev/dtrace/i386/dtrace_subr.c	Wed Jan  6 07:50:27 2010	(r201632)
 +++ stable/7/sys/cddl/dev/dtrace/i386/dtrace_subr.c	Wed Jan  6 08:18:49 2010	(r201633)
 @@ -408,7 +408,6 @@ dtrace_gethrtime_init(void *arg)
  	uint64_t tsc_f;
  	cpumask_t map;
  	int i;
 -	struct pcpu *cp;
  
  	/*
  	 * Get TSC frequency known at this moment.
 @@ -444,7 +443,7 @@ dtrace_gethrtime_init(void *arg)
  		if (i == curcpu)
  			continue;
  
 -		if ((cp = pcpu_find(i)) == NULL)
 +		if (pcpu_find(i) == NULL)
  			continue;
  
  		map = 0;
 
 Modified: stable/7/sys/kern/subr_taskqueue.c
 ==============================================================================
 --- stable/7/sys/kern/subr_taskqueue.c	Wed Jan  6 07:50:27 2010	(r201632)
 +++ stable/7/sys/kern/subr_taskqueue.c	Wed Jan  6 08:18:49 2010	(r201633)
 @@ -463,3 +463,32 @@ taskqueue_fast_run(void *dummy)
  TASKQUEUE_FAST_DEFINE(fast, taskqueue_fast_enqueue, 0,
  	swi_add(NULL, "Fast task queue", taskqueue_fast_run, NULL,
  	SWI_TQ_FAST, INTR_MPSAFE, &taskqueue_fast_ih));
 +
 +int
 +taskqueue_member(struct taskqueue *queue, struct thread *td)
 +{
 +	int i, j, ret = 0;
 +	struct thread *ptd;
 +
 +	TQ_LOCK(queue);
 +	for (i = 0, j = 0; ; i++) {
 +		if (queue->tq_pproc[i] == NULL)
 +			continue;
 +		ptd = FIRST_THREAD_IN_PROC(queue->tq_pproc[i]);
 +		/*
 +		 * In releng7 all kprocs have only one kthread, so there is
 +		 * no need to use FOREACH_THREAD_IN_PROC instead.
 +		 * If this changes at some point, only the first 'if' needs
 +		 * to be included in the FOREACH_..., the second one can
 +		 * stay as it is.
 +		 */
 +		if (ptd == td) {
 +			ret = 1;
 +			break;
 +		}
 +		if (++j >= queue->tq_pcount)
 +			break;
 +	}
 +	TQ_UNLOCK(queue);
 +	return (ret);
 +}
 
 Modified: stable/7/sys/kern/vfs_vnops.c
 ==============================================================================
 --- stable/7/sys/kern/vfs_vnops.c	Wed Jan  6 07:50:27 2010	(r201632)
 +++ stable/7/sys/kern/vfs_vnops.c	Wed Jan  6 08:18:49 2010	(r201633)
 @@ -351,7 +351,7 @@ vn_rdwr(rw, vp, base, len, offset, segfl
  	struct iovec aiov;
  	struct mount *mp;
  	struct ucred *cred;
 -	int error;
 +	int error, lock_flags;
  
  	VFS_ASSERT_GIANT(vp->v_mount);
  
 @@ -362,12 +362,23 @@ vn_rdwr(rw, vp, base, len, offset, segfl
  			    (error = vn_start_write(vp, &mp, V_WAIT | PCATCH))
  			    != 0)
 
 *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
>Unformatted:
