sdev_vnops.c revision de442498e34e37fe9b61cfe5beaacdecd06c6a1c
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * CDDL HEADER START
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * The contents of this file are subject to the terms of the
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Common Development and Distribution License (the "License").
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * You may not use this file except in compliance with the License.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * See the License for the specific language governing permissions
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * and limitations under the License.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * When distributing Covered Code, include this CDDL HEADER in each
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * If applicable, add the following below this CDDL HEADER, with the
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * fields enclosed by brackets "[]" replaced with your own identifying
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * information: Portions Copyright [yyyy] [name of copyright owner]
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * CDDL HEADER END
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Copyright (c) 2013, Joyent, Inc. All rights reserved.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * vnode ops for the /dev filesystem
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * - VDIR, VCHR, CBLK, and VLNK are considered must supported files
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * - VREG and VDOOR are used for some internal implementations in
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * the global zone, e.g. devname and devfsadm communication
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * - other file types are unusual in this namespace and
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * not supported for now
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * sdev has a few basic goals:
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * o Provide /dev for the global zone as well as various non-global zones.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * o Provide the basic functionality that devfsadm might need (mknod,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * symlinks, etc.)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * o Allow persistent permissions on files in /dev.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * o Allow for dynamic directories and nodes for use by various services (pts,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * zvol, net, etc.)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * The sdev file system is primarily made up of sdev_node_t's which is sdev's
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * counterpart to the vnode_t. There are two different classes of sdev_node_t's
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * that we generally care about, dynamic and otherwise.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Persisting Information
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * ----------------------
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * When sdev is mounted, it keeps track of the underlying file system it is
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * mounted over. In certain situations, sdev will go and create entries in that
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * underlying file system. These underlying 'back end' nodes are used as proxies
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * for various changes in permissions. While specific sets of nodes, such as
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * dynamic ones, are exempt, this process stores permission changes against
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * these back end nodes. The point of all of this is to allow for these settings
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * to persist across host and zone reboots. As an example, consider the entry
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * /dev/dsk/c0t0d0 which is a character device and that / is in UFS. Upon
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * changing the permissions on c0t0d0 you'd have the following logical
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * relationships:
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * +------------------+ sdev_vnode +--------------+
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * | sdev_node_t |<---------------->| vnode_t |
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * | /dev/dsk/c0t0d0 |<---------------->| for sdev |
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * +------------------+ +--------------+
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * | sdev_attrvp
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * | +---------------------+
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * +--->| vnode_t for UFS|ZFS |
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * +---------------------+
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * sdev is generally in memory. Therefore when a lookup happens and there is no
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * entry already inside of a directory cache, it will next check the backing
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * store. If the backing store exists, we will reconstitute the sdev_node based
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * on the information that we persisted. When we create the backing store node,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * we use the struct vattr information that we already have in sdev_node_t.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Because of this, we already know if the entry was previously a symlink,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * directory, or some other kind of type. Note that not all types of nodes are
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * supported. Currently only VDIR, VCHR, VBLK, VREG, VDOOR, and VLNK are
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * eligible to be persisted.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * When the sdev_node is created and the lookup is done, we grab a hold on the
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * underlying vnode as part of the call to VOP_LOOKUP. That reference is held
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * until the sdev_node becomes inactive. Once its reference count reaches one
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * and the VOP_INACTIVE callback fires leading to the destruction of the node,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * the reference on the underlying vnode will be released.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * The backing store node will be deleted only when the node itself is deleted
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * through the means of a VOP_REMOVE, VOP_RMDIR, or similar call.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Not everything can be persisted, see The Rules section for more details.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Dynamic Nodes
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * -------------
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Dynamic nodes allow for specific interactions with various kernel subsystems
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * when looking up directory entries. This allows the lookup and readdir
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * functions to check against the kernel subsystem's for validity. eg. does a
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * zvol or nic still exist.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * More specifically, when we create various directories we check if the
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * directory name matches that of one of the names in the vtab[] (sdev_subr.c).
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * If it does, we swap out the vnode operations into a new set which combine the
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * normal sdev vnode operations with the dynamic set here.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * In addition, various dynamic nodes implement a verification entry point. This
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * verification entry is used as a part of lookup and readdir. The goal for
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * these dynamic nodes is to allow them to check with the underlying subsystems
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * to ensure that these devices are still present, or if they have gone away, to
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * remove them from the results. This is indicated by using the SDEV_VTOR flag
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * in vtab[].
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Dynamic nodes have additional restrictions placed upon them. They may only
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * appear at the top level directory of the file system. In addition, users
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * cannot create dirents below any leve of a dynamic node aside from its special
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Profiles exist for the purpose of non-global zones. They work with the zone
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * brands and zoneadmd to set up a filter of allowed devices that can appear in
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * a non-global zone's /dev. These are sent to sdev by means of libdevinfo and a
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * modctl system call. Specifically it allows one to add patterns of device
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * paths to include and exclude. It allows for a collection of symlinks to be
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * added and it allows for remapping names.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * When operating in a non-global zone, several of the sdev vnops are redirected
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * to the profile versions. These impose additional restrictions such as
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * enforcing that a non-global zone's /dev is read only.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * sdev_node_t States
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * ------------------
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * A given sdev_node_t has a field called the sdev_state which describes where
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * in the sdev life cycle it is. There are three primary states: SDEV_INIT,
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * SDEV_READY, and SDEV_ZOMBIE.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * SDEV_INIT: When a new /dev file is first looked up, a sdev_node
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * is allocated, initialized and added to the directory's
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * sdev_node cache. A node at this state will also
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * have the SDEV_LOOKUP flag set.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Other threads that are trying to look up a node at
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * this state will be blocked until the SDEV_LOOKUP flag
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * is cleared.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * When the SDEV_LOOKUP flag is cleared, the node may
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * transition into the SDEV_READY state for a successful
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * lookup or the node is removed from the directory cache
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * and destroyed if the named node can not be found.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * An ENOENT error is returned for the second case.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * SDEV_READY: A /dev file has been successfully looked up and
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * associated with a vnode. The /dev file is available
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * for the supported /dev file system operations.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * SDEV_ZOMBIE: Deletion of a /dev file has been explicitly issued
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * to an SDEV_READY node. The node is transitioned into
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * the SDEV_ZOMBIE state if the vnode reference count
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * is still held. A SDEV_ZOMBIE node does not support
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * any of the /dev file system operations. A SDEV_ZOMBIE
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * node is immediately removed from the directory cache
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * and destroyed once the reference count reaches zero.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Historically nodes that were marked SDEV_ZOMBIE were not removed from the
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * underlying directory caches. This has been the source of numerous bugs and
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * thus to better mimic what happens on a real file system, it is no longer the
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * The following state machine describes the life cycle of a given node and its
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * associated states:
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * node is . . . . .
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * allocated via . +-------------+ . . . . . . . vnode_t refcount
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * sdev_nodeinit() . | Unallocated | . reaches zero and
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * +--------*-----| Memory |<--------*---+ sdev_inactive is
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * | +-------------+ | called.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * | +------------^ | called.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * +-----------+ * . . sdev_nodeready() +-------------+
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * | SDEV_INIT | | or related setup | SDEV_ZOMBIE |
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * +-----------+ | failure +-------------+
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * | | +------------+ |
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * +-*----------->| SDEV_READY |--------*-----+
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * . +------------+ . The node is no longer
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * . . node successfully . . . . . valid or we've been
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * inserted into the asked to remove it.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * directory cache This happens via
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * and sdev_nodready() sdev_dirdelete().
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * call successful.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Adding and Removing Dirents, Zombie Nodes
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * -----------------------------------------
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * As part of doing a lookup, readdir, or an explicit creation operation like
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * mkdir or create, nodes may be created. Every directory has an avl tree which
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * contains its children, the sdev_entries tree. This is only used if the type
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * is VDIR. Access to this is controlled by the sdev_node_t's contents_lock and
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * it is managed through sdev_cache_update().
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * Every sdev_node_t has a field sdev_state, which describes the current state
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * of the node. A node is generally speaking in the SDEV_READY state. When it is
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * there, it can be looked up, accessed, and operations performed on it. When a
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * node is going to be removed from the directory cache it is marked as a
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * zombie. Once a node becomes a zombie, no other file system operations will
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * succeed and it will continue to exist as a node until the vnode count on the
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * node reaches zero. At that point, the node will be freed. However, once a
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * node has been marked as a zombie, it will be removed immediately from the
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * directory cache such that no one else may find it again. This means that
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * someone else can insert a new entry into that directory with the same name
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * and without a problem.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * To remove a node, see the section on that in The Rules.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * These are the rules to live by when working in sdev. These are not
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * exhaustive.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * - Set 1: Working with Backing Nodes
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * o If there is a SDEV_READY sdev_node_t, it knows about its backing node.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * o If we find a backing node when looking up an sdev_node_t for the first
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * time, we use its attributes to build our sdev_node_t.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * o If there is a found backing node, or we create a backing node, that's
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * when we grab the hold on its vnode.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * o If we mark an sdev_node_t a ZOMBIE, we must remove its backing node from
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * the underlying file system. It must not be searchable or findable.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * o We release our hold on the backing node vnode when we destroy the
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * sdev_node_t.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * - Set 2: Locking rules for sdev (not exhaustive)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * o The majority of nodes contain an sdev_contents rw lock. You must hold it
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * for read or write if manipulating its contents appropriately.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * o You must lock your parent before yourself.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * o If you need your vnode's v_lock and the sdev_contents rw lock, you must
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * grab the v_lock before the sdev_contents rw_lock.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * o If you release a lock on the node as a part of upgrading it, you must
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * verify that the node has not become a zombie as a part of this process.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * - Set 3: Zombie Status and What it Means
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * o If you encounter a node that is a ZOMBIE, that means that it has been
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * unlinked from the backing store.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * o If you release your contents lock and acquire it again (say as part of
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * trying to grab a write lock) you must check that the node has not become
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * o You should VERIFY that a looked up node is not a zombie. This follows
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * from the following logic. To mark something as a zombie means that it is
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * removed from the parents directory cache. To do that, you must have a
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * write lock on the parent's sdev_contents. To lookup through that
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * directory you must have a read lock. This then becomes a simple ordering
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * problem. If you've been granted the lock then the other operation cannot
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * be in progress or must have already succeeded.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * - Set 4: Removing Directory Entries (aka making nodes Zombies)
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * o Write lock must be held on the directory
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * o Write lock must be held on the node
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * o Remove the sdev_node_t from its parent cache
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * o Remove the corresponding backing store node, if it exists, eg. use
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * VOP_REMOVE or VOP_RMDIR.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * o You must NOT make any change in the vnode reference count! Nodes should
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * only be cleaned up through VOP_INACTIVE callbacks.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * o VOP_INACTIVE is the only one responsible for doing the final vn_rele of
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * the backing store vnode that was grabbed during lookup.
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * - Set 5: What Nodes may be Persisted
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * o The root, /dev is always persisted
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * o Any node in vtab which is marked SDEV_DYNAMIC, may not be persisted
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * unless it is also marked SDEV_PERSIST
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * o Anything whose parent directory is marked SDEV_PERSIST will pass that
422009fe5b15e31e7f5d09212bd1480121a1464eEvan Hunt * along to the child as long as it does not contradict the above rules
int error = 0;
return (ENOTSUP);
return (ENOENT);
return (ENOTSUP);
return (ENOENT);
return (error);
return (ENOTSUP);
return (ENOTSUP);
int error;
return (EINVAL);
return (EISDIR);
return (EINVAL);
return (error);
int error = 0;
return (EINVAL);
return (EISDIR);
return (EINVAL);
if (error == 0) {
AT_MTIME);
return (error);
return (ENOTTY);
return (EINVAL);
int error = 0;
return (error);
int error;
return (ENOSYS);
return (error);
int error;
return (fs_nosys());
if (error) {
return (fs_nosys());
return (error);
* used as part of the secpolicy_vnode_setattr calls in sdev_subr.c. Because it
int shift = 0;
int ret;
if (ret)
return (ret);
int ret;
return (ret);
int error;
return (error);
int error = 0;
return (ENOTSUP);
return (ENOENT);
return (error);
if (error == 0) {
if (error) {
return (error);
if (error) {
return (error);
return (error);
return (error);
return (ENOTSUP);
if (error) {
if (self)
return (error);
return (error);
int error;
int len;
int bkstore;
return (EINVAL);
return (EEXIST);
return (ENOTSUP);
return (error);
return (ENOENT);
return (ENOENT);
return (error);
return (ENOENT);
return (EBUSY);
if (bkstore) {
error = 0;
return (error);
int error = 0;
int bkstore = 0;
return (EINVAL);
return (ENOENT);
return (ENOTSUP);
return (ENOENT);
if (error) {
onm));
return (error);
return (error);
return (error);
return (error);
return (EXDEV);
if (error) {
return (error);
if (!samedir) {
if (error) {
return (error);
return (EACCES);
if (error) {
return (error);
error));
error = 0;
if (bkstore) {
if (error) {
error = 0;
int error;
return (ENOENT);
return (ENOTSUP);
return (error);
if (error == 0) {
return (EEXIST);
return (error);
return (error);
if (error) {
if (self)
return (error);
int error;
return (ENOENT);
return (error);
if (error == 0) {
return (EEXIST);
return (error);
return (error);
if (error) {
if (self)
return (error);
int error = 0;
return (EINVAL);
return (ENOTSUP);
return (error);
return (ENOENT);
return (ENOENT);
return (EINVAL);
return (ENOTDIR);
return (EBUSY);
return (EBUSY);
return (ENOTEMPTY);
if (error)
error = 0;
return (error);
int error = 0;
return (error);
return (ENOENT);
int error;
return (EACCES);
return (error);
return (ENOSPC);
int error;
return (error);
switch (cmd) {
case _PC_ACL_ENABLED: