Home | History | Annotate | Download | only in fs
      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  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
     23  * Use is subject to license terms.
     24  */
     25 
     26 #ifndef _SYS_DV_NODE_H
     27 #define	_SYS_DV_NODE_H
     28 
     29 /*
     30  * dv_nodes are the file-system specific part of the
     31  * vnodes for the device filesystem.
     32  *
     33  * The device filesystem exports two node types:
     34  *
     35  * VDIR	nodes		to represent nexus drivers
     36  * VCHR & VBLK nodes	to represent devices
     37  */
     38 
     39 #include <sys/dirent.h>
     40 #include <sys/sunddi.h>
     41 #include <sys/devops.h>
     42 #include <sys/ddi_impldefs.h>
     43 #include <sys/fs/sdev_impl.h>
     44 #include <sys/devpolicy.h>
     45 #include <sys/avl.h>
     46 
     47 #ifdef _KERNEL
     48 #include <sys/vfs_opreg.h>
     49 #endif
     50 
     51 #ifdef __cplusplus
     52 extern "C" {
     53 #endif
     54 
     55 #ifdef _KERNEL
     56 
     57 
     58 /*
     59  * Here's the focal point of this filesystem
     60  */
     61 typedef struct dv_node {
     62 	char		*dv_name;	/* pointer to name */
     63 	size_t		dv_namelen;	/* strlen(dv_name) */
     64 	struct vnode	*dv_vnode;	/* vnode for this dv_node */
     65 
     66 	/*
     67 	 * The dv_contents lock should be held (read) before looking at
     68 	 * any of the fields below, and held (write) before modifying them.
     69 	 */
     70 	krwlock_t	dv_contents;	/* held while anything is changing */
     71 
     72 	dev_info_t	*dv_devi;	/* VDIR: underlying devinfo node */
     73 					/* has ndi_devi_hold on device */
     74 
     75 	struct dv_node	*dv_dotdot;	/* parent: my parent dv_node */
     76 	avl_tree_t	dv_entries;	/* VDIR: contents as avl tree */
     77 	avl_node_t	dv_avllink;	/* avl node linkage */
     78 
     79 	struct vnode	*dv_attrvp;	/* persistent attribute store */
     80 	struct vattr	*dv_attr;	/* attributes not yet persistent */
     81 
     82 	ino64_t		dv_ino;		/* fake inode */
     83 	int		dv_flags;	/* state bits and stuff */
     84 	uint_t		dv_nlink;	/* link count */
     85 	uint_t		dv_busy;	/* directory busy count */
     86 	devplcy_t	*dv_priv;	/* access privilege */
     87 	mode_t		dv_dflt_mode;	/* create_priv_minor_node mode */
     88 	struct sdev_dv	*dv_sdev;	/* sdev node[s] if exists */
     89 } dvnode_t;
     90 
     91 #define	DV_BUILD	0x1		/* directory out-of-date */
     92 #define	DV_NO_FSPERM	0x2		/* ignore fs permissions */
     93 #define	DV_INTERNAL	0x04		/* internal node */
     94 #define	DV_ACL		0x08		/* node has acl */
     95 #define	DV_DFLT_MODE	0x010		/* dv_dflt_mode set */
     96 
     97 #define	DV_ROOTINO	((ino_t)2)	/* root inode no. for devfs */
     98 
     99 #define	DVTOV(n)	((struct vnode *)(n)->dv_vnode)
    100 #define	VTODV(vp)	((struct dv_node *)(vp)->v_data)
    101 #define	DV_STALE(dv)	(dv->dv_devi == NULL)
    102 
    103 #define	DV_UID_DEFAULT	0	/* default uid for devs and dirs */
    104 #define	DV_GID_DEFAULT	3	/* default gid for devs and dirs */
    105 #define	DV_DIRMODE_DEFAULT	(S_IFDIR | 0755)	/* directories */
    106 #define	DV_DEVMODE_DEFAULT	(0600)			/* special files */
    107 #define	DV_DEVMODE_PRIV		(0666)		/* priv based access only */
    108 
    109 /* flags for devfs_clean() */
    110 #define	DV_CLEAN_FORCE	0x01	/* force clean of refed directories */
    111 #define	DV_RESET_PERM	0x02	/* force resetting of node permission */
    112 #define	DV_CLEANDIR_LCK	0x04	/* dv_contents already held */
    113 
    114 struct devfs_data {
    115 	struct	dv_node	*devfs_root;
    116 	struct	vfs	*devfs_vfsp;
    117 };
    118 
    119 #define	VFSTODVFS(vfsp)	((struct devfs_data *)((vfsp)->vfs_data))
    120 
    121 /* dv_fid overlays the fid structure (for VFS_VGET) */
    122 struct dv_fid {
    123 	uint16_t	dvfid_len;
    124 	ino32_t		dvfid_ino;
    125 	int32_t		dvfid_gen;
    126 };
    127 
    128 /*
    129  * Compare a vattr's and mperm_t's minor permissions (uid, gid & mode)
    130  */
    131 #define	VATTRP_MP_CMP(attrp, mp)				\
    132 	(!((attrp->va_uid == mp.mp_uid) &&			\
    133 	(attrp->va_gid == mp.mp_gid) &&				\
    134 	((attrp->va_mode & S_IAMB) == (mp.mp_mode & S_IAMB))))
    135 
    136 /*
    137  * Merge an mperm_t's minor permissions into a vattr
    138  */
    139 #define	VATTR_MP_MERGE(attr, mp)				\
    140 	attr.va_uid = mp.mp_uid;				\
    141 	attr.va_gid = mp.mp_gid;				\
    142 	attr.va_mode = 						\
    143 	    (attr.va_mode & ~S_IAMB) | (mp.mp_mode & S_IAMB);
    144 
    145 #define	VATTRP_MP_MERGE(attrp, mp)				\
    146 	attrp->va_uid = mp.mp_uid;				\
    147 	attrp->va_gid = mp.mp_gid;				\
    148 	attrp->va_mode = 					\
    149 	    (attrp->va_mode & ~S_IAMB) | (mp.mp_mode & S_IAMB);
    150 
    151 /*
    152  * dv_shadow_node flags
    153  */
    154 #define	DV_SHADOW_CREATE	0x01		/* create attribute node */
    155 #define	DV_SHADOW_WRITE_HELD	0x02		/* dv_contents write held */
    156 
    157 /*
    158  * Directory tree traversal
    159  */
    160 #define	DV_FIRST_ENTRY(ddv)	avl_first(&(ddv)->dv_entries)
    161 #define	DV_NEXT_ENTRY(ddv, dv)	AVL_NEXT(&(ddv)->dv_entries, (dv))
    162 
    163 extern uint_t devfs_clean_key;	/* tsd key */
    164 extern const char dvnm[];	/* share some space.. */
    165 extern struct dv_node *dvroot;	/* devfs root node */
    166 
    167 extern void dv_node_cache_init(void);
    168 extern void dv_node_cache_fini(void);
    169 extern struct dv_node *dv_mkdir(struct dv_node *, dev_info_t *, char *);
    170 extern struct dv_node *dv_mkroot(struct vfs *, dev_t);
    171 extern void dv_destroy(struct dv_node *, uint_t);
    172 extern void dv_insert(struct dv_node *, struct dv_node *);
    173 extern void dv_shadow_node(struct vnode *, char *nm, struct vnode *,
    174     struct pathname *, struct vnode *, struct cred *, int);
    175 extern int dv_find(struct dv_node *, char *, struct vnode **,
    176     struct pathname *, struct vnode *, struct cred *, uint_t);
    177 extern void dv_filldir(struct dv_node *);
    178 extern int dv_cleandir(struct dv_node *, char *, uint_t);
    179 extern void dv_vattr_merge(struct dv_node *, struct vattr *);
    180 extern void dv_walk(struct dv_node *, char *,
    181     void (*f)(struct dv_node *, void *), void *);
    182 
    183 extern int devfs_clean(dev_info_t *, char *, uint_t);
    184 extern int devfs_lookupname(char *, vnode_t **, vnode_t **);
    185 extern int devfs_walk(char *, void (*f)(struct dv_node *, void *), void *);
    186 extern int devfs_devpolicy(vnode_t *, devplcy_t **);
    187 extern void devfs_get_defattr(vnode_t *, struct vattr *, int *);
    188 
    189 extern struct dv_node *devfs_dip_to_dvnode(dev_info_t *);
    190 extern int devfs_reset_perm(uint_t);
    191 extern int devfs_remdrv_cleanup(const char *, const char *);
    192 
    193 extern struct vnodeops *dv_vnodeops;
    194 extern const struct fs_operation_def dv_vnodeops_template[];
    195 
    196 
    197 #ifdef DEBUG
    198 extern int devfs_debug;
    199 #define	DV_DEBUG	0x01
    200 #define	DV_DEBUG2	0x02
    201 #define	DV_DEBUG3	0x04
    202 #define	DV_DEBUG4	0x08
    203 #define	DV_DEBUG5	0x10
    204 #define	DV_SYSERR	0x1000
    205 #define	DV_SYSTRACE	0x2000
    206 #define	dcmn_err(args) if (devfs_debug & DV_DEBUG) printf args
    207 #define	dcmn_err2(args) if (devfs_debug & DV_DEBUG2) printf args
    208 #define	dcmn_err3(args) if (devfs_debug & DV_DEBUG3) printf args
    209 #define	dcmn_err4(args) if (devfs_debug & DV_DEBUG4) printf args
    210 #define	dcmn_err5(args) if (devfs_debug & DV_DEBUG5) printf args
    211 
    212 #define	dsysdebug(err, args)				\
    213 	if ((err && (devfs_debug & DV_SYSERR)) ||	\
    214 	    (devfs_debug & DV_SYSTRACE)) printf args
    215 #else
    216 #define	dcmn_err(args) /* nothing */
    217 #define	dcmn_err2(args) /* nothing */
    218 #define	dcmn_err3(args) /* nothing */
    219 #define	dcmn_err4(args) /* nothing */
    220 #define	dcmn_err5(args) /* nothing */
    221 #define	dsysdebug(err, args) /* nothing */
    222 #endif
    223 
    224 
    225 #endif	/* _KERNEL */
    226 
    227 #ifdef __cplusplus
    228 }
    229 #endif
    230 
    231 #endif	/* _SYS_DV_NODE_H */
    232