1185029Spjd/*
2185029Spjd * CDDL HEADER START
3185029Spjd *
4185029Spjd * The contents of this file are subject to the terms of the
5185029Spjd * Common Development and Distribution License (the "License").
6185029Spjd * You may not use this file except in compliance with the License.
7185029Spjd *
8185029Spjd * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9185029Spjd * or http://www.opensolaris.org/os/licensing.
10185029Spjd * See the License for the specific language governing permissions
11185029Spjd * and limitations under the License.
12185029Spjd *
13185029Spjd * When distributing Covered Code, include this CDDL HEADER in each
14185029Spjd * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15185029Spjd * If applicable, add the following below this CDDL HEADER, with the
16185029Spjd * fields enclosed by brackets "[]" replaced with your own identifying
17185029Spjd * information: Portions Copyright [yyyy] [name of copyright owner]
18185029Spjd *
19185029Spjd * CDDL HEADER END
20185029Spjd */
21219089Spjd
22185029Spjd/*
23219089Spjd * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
24185029Spjd */
25185029Spjd
26185029Spjd/*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
27185029Spjd/*	  All Rights Reserved  	*/
28185029Spjd
29185029Spjd/*
30185029Spjd * University Copyright- Copyright (c) 1982, 1986, 1988
31185029Spjd * The Regents of the University of California
32185029Spjd * All Rights Reserved
33185029Spjd *
34185029Spjd * University Acknowledgment- Portions of this document are derived from
35185029Spjd * software developed by the University of California, Berkeley, and its
36185029Spjd * contributors.
37185029Spjd */
38185029Spjd
39185029Spjd#include <sys/types.h>
40185029Spjd#include <sys/param.h>
41191900Skmacy#include <sys/proc.h>
42196307Spjd#include <sys/taskq.h>
43185029Spjd#include <sys/vnode.h>
44185029Spjd
45185029Spjd/* Extensible attribute (xva) routines. */
46185029Spjd
47185029Spjd/*
48185029Spjd * Zero out the structure, set the size of the requested/returned bitmaps,
49185029Spjd * set AT_XVATTR in the embedded vattr_t's va_mask, and set up the pointer
50185029Spjd * to the returned attributes array.
51185029Spjd */
52185029Spjdvoid
53185029Spjdxva_init(xvattr_t *xvap)
54185029Spjd{
55185029Spjd	bzero(xvap, sizeof (xvattr_t));
56185029Spjd	xvap->xva_mapsize = XVA_MAPSIZE;
57185029Spjd	xvap->xva_magic = XVA_MAGIC;
58185029Spjd	xvap->xva_vattr.va_mask = AT_XVATTR;
59185029Spjd	xvap->xva_rtnattrmapp = &(xvap->xva_rtnattrmap)[0];
60185029Spjd}
61185029Spjd
62185029Spjd/*
63185029Spjd * If AT_XVATTR is set, returns a pointer to the embedded xoptattr_t
64185029Spjd * structure.  Otherwise, returns NULL.
65185029Spjd */
66185029Spjdxoptattr_t *
67185029Spjdxva_getxoptattr(xvattr_t *xvap)
68185029Spjd{
69185029Spjd	xoptattr_t *xoap = NULL;
70185029Spjd	if (xvap->xva_vattr.va_mask & AT_XVATTR)
71185029Spjd		xoap = &xvap->xva_xoptattrs;
72185029Spjd	return (xoap);
73185029Spjd}
74191900Skmacy
75196307Spjdstatic void
76196307Spjdvn_rele_inactive(vnode_t *vp)
77196307Spjd{
78196307Spjd	vrele(vp);
79196307Spjd}
80191900Skmacy
81191900Skmacy/*
82191900Skmacy * Like vn_rele() except if we are going to call VOP_INACTIVE() then do it
83191900Skmacy * asynchronously using a taskq. This can avoid deadlocks caused by re-entering
84191900Skmacy * the file system as a result of releasing the vnode. Note, file systems
85191900Skmacy * already have to handle the race where the vnode is incremented before the
86191900Skmacy * inactive routine is called and does its locking.
87191900Skmacy *
88191900Skmacy * Warning: Excessive use of this routine can lead to performance problems.
89191900Skmacy * This is because taskqs throttle back allocation if too many are created.
90191900Skmacy */
91191900Skmacyvoid
92196307Spjdvn_rele_async(vnode_t *vp, taskq_t *taskq)
93191900Skmacy{
94196307Spjd	VERIFY(vp->v_count > 0);
95191900Skmacy	VI_LOCK(vp);
96196307Spjd	if (vp->v_count == 1 && !(vp->v_iflag & VI_DOINGINACT)) {
97191900Skmacy		VI_UNLOCK(vp);
98196307Spjd		VERIFY(taskq_dispatch((taskq_t *)taskq,
99196307Spjd		    (task_func_t *)vn_rele_inactive, vp, TQ_SLEEP) != 0);
100191900Skmacy		return;
101191900Skmacy	}
102196307Spjd	vp->v_usecount--;
103196307Spjd	vdropl(vp);
104191900Skmacy}
105