xref: /netbsd-src/external/cddl/osnet/dist/uts/common/fs/vnode.c (revision ba2539a9805a0544ff82c0003cc02fe1eee5603d)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved.
24  */
25 
26 /*	Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T	*/
27 /*	  All Rights Reserved  	*/
28 
29 /*
30  * University Copyright- Copyright (c) 1982, 1986, 1988
31  * The Regents of the University of California
32  * All Rights Reserved
33  *
34  * University Acknowledgment- Portions of this document are derived from
35  * software developed by the University of California, Berkeley, and its
36  * contributors.
37  */
38 
39 #include <sys/types.h>
40 #include <sys/param.h>
41 #include <sys/proc.h>
42 #include <sys/taskq.h>
43 #include <sys/vnode.h>
44 
45 /* Extensible attribute (xva) routines. */
46 
47 /*
48  * Zero out the structure, set the size of the requested/returned bitmaps,
49  * set AT_XVATTR in the embedded vattr_t's va_mask, and set up the pointer
50  * to the returned attributes array.
51  */
52 void
xva_init(xvattr_t * xvap)53 xva_init(xvattr_t *xvap)
54 {
55 	bzero(xvap, sizeof (xvattr_t));
56 	xvap->xva_mapsize = XVA_MAPSIZE;
57 	xvap->xva_magic = XVA_MAGIC;
58 	xvap->xva_vattr.va_mask = AT_XVATTR;
59 	xvap->xva_rtnattrmapp = &(xvap->xva_rtnattrmap)[0];
60 }
61 
62 /*
63  * If AT_XVATTR is set, returns a pointer to the embedded xoptattr_t
64  * structure.  Otherwise, returns NULL.
65  */
66 xoptattr_t *
xva_getxoptattr(xvattr_t * xvap)67 xva_getxoptattr(xvattr_t *xvap)
68 {
69 	xoptattr_t *xoap = NULL;
70 	if (xvap->xva_vattr.va_mask & AT_XVATTR)
71 		xoap = &xvap->xva_xoptattrs;
72 	return (xoap);
73 }
74 
75 #ifdef __FreeBSD__
76 static void
vn_rele_inactive(vnode_t * vp)77 vn_rele_inactive(vnode_t *vp)
78 {
79 	vrele(vp);
80 }
81 
82 /*
83  * Like vn_rele() except if we are going to call VOP_INACTIVE() then do it
84  * asynchronously using a taskq. This can avoid deadlocks caused by re-entering
85  * the file system as a result of releasing the vnode. Note, file systems
86  * already have to handle the race where the vnode is incremented before the
87  * inactive routine is called and does its locking.
88  *
89  * Warning: Excessive use of this routine can lead to performance problems.
90  * This is because taskqs throttle back allocation if too many are created.
91  */
92 void
vn_rele_async(vnode_t * vp,taskq_t * taskq)93 vn_rele_async(vnode_t *vp, taskq_t *taskq)
94 {
95 	VERIFY(vp->v_count > 0);
96 	VI_LOCK(vp);
97 	if (vp->v_count == 1 && !(vp->v_iflag & VI_DOINGINACT)) {
98 		VI_UNLOCK(vp);
99 		VERIFY(taskq_dispatch((taskq_t *)taskq,
100 		    (task_func_t *)vn_rele_inactive, vp, TQ_SLEEP) != 0);
101 		return;
102 	}
103 	refcount_release(&vp->v_usecount);
104 	vdropl(vp);
105 }
106 #endif /* __FreeBSD__ */
107