/* * 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 (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* * University Copyright- Copyright (c) 1982, 1986, 1988 * The Regents of the University of California * All Rights Reserved * * University Acknowledgment- Portions of this document are derived from * software developed by the University of California, Berkeley, and its * contributors. */ #include #include #include #include #include /* Extensible attribute (xva) routines. */ /* * Zero out the structure, set the size of the requested/returned bitmaps, * set AT_XVATTR in the embedded vattr_t's va_mask, and set up the pointer * to the returned attributes array. */ void xva_init(xvattr_t *xvap) { bzero(xvap, sizeof (xvattr_t)); xvap->xva_mapsize = XVA_MAPSIZE; xvap->xva_magic = XVA_MAGIC; xvap->xva_vattr.va_mask = AT_XVATTR; xvap->xva_rtnattrmapp = &(xvap->xva_rtnattrmap)[0]; } /* * If AT_XVATTR is set, returns a pointer to the embedded xoptattr_t * structure. Otherwise, returns NULL. */ xoptattr_t * xva_getxoptattr(xvattr_t *xvap) { xoptattr_t *xoap = NULL; if (xvap->xva_vattr.va_mask & AT_XVATTR) xoap = &xvap->xva_xoptattrs; return (xoap); } 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 * asynchronously using a taskq. This can avoid deadlocks caused by re-entering * the file system as a result of releasing the vnode. Note, file systems * already have to handle the race where the vnode is incremented before the * inactive routine is called and does its locking. * * Warning: Excessive use of this routine can lead to performance problems. * This is because taskqs throttle back allocation if too many are created. */ void vn_rele_async(vnode_t *vp, taskq_t *taskq) { VERIFY(vp->v_count > 0); VI_LOCK(vp); if (vp->v_count == 1 && !(vp->v_iflag & VI_DOINGINACT)) { VI_UNLOCK(vp); VERIFY(taskq_dispatch((taskq_t *)taskq, (task_func_t *)vn_rele_inactive, vp, TQ_SLEEP) != 0); return; } vp->v_usecount--; vdropl(vp); }