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.
Responsible Changed From-To: freebsd-bugs->freebsd-fs Over to maintainer(s).
touching a file `touch hi` on the 777 mode directory over nfs is the easiest and most guaranteed way to reproduce this panic.
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
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
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
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
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"
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"
State Changed From-To: open->patched Fix committed to HEAD.
Responsible Changed From-To: freebsd-fs->pjd I'll take this one.
State Changed From-To: patched->closed Fix merged to stable/8.