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 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 * 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 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 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