/ duct-tape / xnu / bsd / sys / vnode_internal.h
vnode_internal.h
  1  /*
  2   * Copyright (c) 2000-2012 Apple Inc. All rights reserved.
  3   *
  4   * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  5   *
  6   * This file contains Original Code and/or Modifications of Original Code
  7   * as defined in and that are subject to the Apple Public Source License
  8   * Version 2.0 (the 'License'). You may not use this file except in
  9   * compliance with the License. The rights granted to you under the License
 10   * may not be used to create, or enable the creation or redistribution of,
 11   * unlawful or unlicensed copies of an Apple operating system, or to
 12   * circumvent, violate, or enable the circumvention or violation of, any
 13   * terms of an Apple operating system software license agreement.
 14   *
 15   * Please obtain a copy of the License at
 16   * http://www.opensource.apple.com/apsl/ and read it before using this file.
 17   *
 18   * The Original Code and all software distributed under the License are
 19   * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 20   * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 21   * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 22   * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 23   * Please see the License for the specific language governing rights and
 24   * limitations under the License.
 25   *
 26   * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
 27   */
 28  /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
 29  /*
 30   * Copyright (c) 1989, 1993
 31   *	The Regents of the University of California.  All rights reserved.
 32   *
 33   * Redistribution and use in source and binary forms, with or without
 34   * modification, are permitted provided that the following conditions
 35   * are met:
 36   * 1. Redistributions of source code must retain the above copyright
 37   *    notice, this list of conditions and the following disclaimer.
 38   * 2. Redistributions in binary form must reproduce the above copyright
 39   *    notice, this list of conditions and the following disclaimer in the
 40   *    documentation and/or other materials provided with the distribution.
 41   * 3. All advertising materials mentioning features or use of this software
 42   *    must display the following acknowledgement:
 43   *	This product includes software developed by the University of
 44   *	California, Berkeley and its contributors.
 45   * 4. Neither the name of the University nor the names of its contributors
 46   *    may be used to endorse or promote products derived from this software
 47   *    without specific prior written permission.
 48   *
 49   * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 50   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 51   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 52   * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 53   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 54   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 55   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 56   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 57   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 58   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 59   * SUCH DAMAGE.
 60   *
 61   *	@(#)vnode.h	8.17 (Berkeley) 5/20/95
 62   */
 63  /*
 64   * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce
 65   * support for mandatory and extensible security protections.  This notice
 66   * is included in support of clause 2.2 (b) of the Apple Public License,
 67   * Version 2.0.
 68   */
 69  
 70  #ifndef _SYS_VNODE_INTERNAL_H_
 71  #define _SYS_VNODE_INTERNAL_H_
 72  
 73  #include <sys/appleapiopts.h>
 74  #include <sys/cdefs.h>
 75  #include <sys/queue.h>
 76  #include <sys/lock.h>
 77  
 78  #include <sys/time.h>
 79  #include <sys/uio.h>
 80  
 81  #include <sys/vm.h>
 82  #include <sys/systm.h>
 83  #include <kern/locks.h>
 84  #include <vm/vm_kern.h>
 85  #include <sys/vnode.h>
 86  #include <sys/namei.h>
 87  #include <sys/vfs_context.h>
 88  #include <sys/sysctl.h>
 89  
 90  
 91  struct lockf;
 92  struct label;
 93  
 94  LIST_HEAD(buflists, buf);
 95  
 96  #if CONFIG_TRIGGERS
 97  /*
 98   * VFS Internal (private) trigger vnode resolver info.
 99   */
100  struct vnode_resolve {
101  	lck_mtx_t                               vr_lock;   /* protects vnode_resolve_t fields */
102  	trigger_vnode_resolve_callback_t        vr_resolve_func;
103  	trigger_vnode_unresolve_callback_t      vr_unresolve_func;
104  	trigger_vnode_rearm_callback_t          vr_rearm_func;
105  	trigger_vnode_reclaim_callback_t        vr_reclaim_func;
106  	void *                                  vr_data;   /* private data for resolver */
107  	uint32_t                                vr_flags;
108  	uint32_t                                vr_lastseq;
109  };
110  typedef struct vnode_resolve *vnode_resolve_t;
111  
112  /* private vr_flags */
113  #define VNT_RESOLVED        (1UL << 31)
114  #define VNT_VFS_UNMOUNTED   (1UL << 30)
115  #define VNT_EXTERNAL        (1UL << 29)
116  
117  #endif /* CONFIG_TRIGGERS */
118  
119  /*
120   * Reading or writing any of these items requires holding the appropriate lock.
121   * v_freelist is locked by the global vnode_list_lock
122   * v_mntvnodes is locked by the mount_lock
123   * v_nclinks and v_ncchildren are protected by the global name_cache_lock
124   * v_cleanblkhd and v_dirtyblkhd and v_iterblkflags are locked via the global buf_mtx
125   * the rest of the structure is protected by the vnode_lock
126   */
127  struct vnode {
128  	lck_mtx_t v_lock;                       /* vnode mutex */
129  	TAILQ_ENTRY(vnode) v_freelist;          /* vnode freelist */
130  	TAILQ_ENTRY(vnode) v_mntvnodes;         /* vnodes for mount point */
131  	TAILQ_HEAD(, namecache) v_ncchildren;   /* name cache entries that regard us as their parent */
132  	LIST_HEAD(, namecache) v_nclinks;       /* name cache entries that name this vnode */
133  	vnode_t  v_defer_reclaimlist;           /* in case we have to defer the reclaim to avoid recursion */
134  	uint32_t v_listflag;                    /* flags protected by the vnode_list_lock (see below) */
135  	uint32_t v_flag;                        /* vnode flags (see below) */
136  	uint16_t v_lflag;                       /* vnode local and named ref flags */
137  	uint8_t  v_iterblkflags;                /* buf iterator flags */
138  	uint8_t  v_references;                  /* number of times io_count has been granted */
139  	int32_t  v_kusecount;                   /* count of in-kernel refs */
140  	int32_t  v_usecount;                    /* reference count of users */
141  	int32_t  v_iocount;                     /* iocounters */
142  	void *   XNU_PTRAUTH_SIGNED_PTR("vnode.v_owner") v_owner; /* act that owns the vnode */
143  	uint16_t v_type;                        /* vnode type */
144  	uint16_t v_tag;                         /* type of underlying data */
145  	uint32_t v_id;                          /* identity of vnode contents */
146  	union {
147  		struct mount    * XNU_PTRAUTH_SIGNED_PTR("vnode.v_data") vu_mountedhere;  /* ptr to mounted vfs (VDIR) */
148  		struct socket   * XNU_PTRAUTH_SIGNED_PTR("vnode.vu_socket") vu_socket;     /* unix ipc (VSOCK) */
149  		struct specinfo * XNU_PTRAUTH_SIGNED_PTR("vnode.vu_specinfo") vu_specinfo;   /* device (VCHR, VBLK) */
150  		struct fifoinfo * XNU_PTRAUTH_SIGNED_PTR("vnode.vu_fifoinfo") vu_fifoinfo;   /* fifo (VFIFO) */
151  		struct ubc_info * XNU_PTRAUTH_SIGNED_PTR("vnode.vu_ubcinfo") vu_ubcinfo;    /* valid for (VREG) */
152  	} v_un;
153  	struct  buflists v_cleanblkhd;          /* clean blocklist head */
154  	struct  buflists v_dirtyblkhd;          /* dirty blocklist head */
155  	struct klist v_knotes;                  /* knotes attached to this vnode */
156  	/*
157  	 * the following 4 fields are protected
158  	 * by the name_cache_lock held in
159  	 * excluive mode
160  	 */
161  	kauth_cred_t    XNU_PTRAUTH_SIGNED_PTR("vnode.v_cred") v_cred; /* last authorized credential */
162  	kauth_action_t  v_authorized_actions;   /* current authorized actions for v_cred */
163  	int             v_cred_timestamp;       /* determine if entry is stale for MNTK_AUTH_OPAQUE */
164  	int             v_nc_generation;        /* changes when nodes are removed from the name cache */
165  	/*
166  	 * back to the vnode lock for protection
167  	 */
168  	int32_t         v_numoutput;                    /* num of writes in progress */
169  	int32_t         v_writecount;                   /* reference count of writers */
170  	const char *v_name;                     /* name component of the vnode */
171  	vnode_t XNU_PTRAUTH_SIGNED_PTR("vnode.v_parent") v_parent;                       /* pointer to parent vnode */
172  	struct lockf    *v_lockf;               /* advisory lock list head */
173  	int(**v_op)(void *);                    /* vnode operations vector */
174  	mount_t XNU_PTRAUTH_SIGNED_PTR("vnode.v_mount") v_mount;                        /* ptr to vfs we are in */
175  	void *  v_data;                         /* private data for fs */
176  #if CONFIG_MACF
177  	struct label *v_label;                  /* MAC security label */
178  #endif
179  #if CONFIG_TRIGGERS
180  	vnode_resolve_t v_resolve;              /* trigger vnode resolve info (VDIR only) */
181  #endif /* CONFIG_TRIGGERS */
182  #if CONFIG_FIRMLINKS
183  	vnode_t v_fmlink;                       /* firmlink if set (VDIR only), Points to source
184  	                                         *  if VFLINKTARGET is set, if  VFLINKTARGET is not
185  	                                         *  set, points to target */
186  #endif /* CONFIG_FIRMLINKS */
187  #if CONFIG_IO_COMPRESSION_STATS
188  	io_compression_stats_t io_compression_stats;            /* IO compression statistics */
189  #endif /* CONFIG_IO_COMPRESSION_STATS */
190  };
191  
192  #define v_mountedhere   v_un.vu_mountedhere
193  #define v_socket        v_un.vu_socket
194  #define v_specinfo      v_un.vu_specinfo
195  #define v_fifoinfo      v_un.vu_fifoinfo
196  #define v_ubcinfo       v_un.vu_ubcinfo
197  
198  
199  /*
200   * v_iterblkflags
201   */
202  #define VBI_ITER                0x1
203  #define VBI_ITERWANT            0x2
204  #define VBI_CLEAN               0x4
205  #define VBI_DIRTY               0x8
206  #define VBI_NEWBUF              0x10
207  
208  /*
209   * v_listflag
210   */
211  #define VLIST_RAGE                0x01          /* vnode is currently in the rapid age list */
212  #define VLIST_DEAD                0x02          /* vnode is currently in the dead list */
213  #define VLIST_ASYNC_WORK          0x04          /* vnode is currently on the deferred async work queue */
214  
215  /*
216   * v_lflags
217   */
218  #define VL_SUSPENDED    0x0001          /* vnode is suspended */
219  #define VL_DRAIN        0x0002          /* vnode is being drained */
220  #define VL_TERMINATE    0x0004          /* vnode is in the process of being recycled */
221  #define VL_TERMWANT     0x0008          /* there's a waiter  for recycle finish (vnode_getiocount)*/
222  #define VL_DEAD         0x0010          /* vnode is dead, cleaned of filesystem-specific info */
223  #define VL_MARKTERM     0x0020          /* vnode should be recycled when no longer referenced */
224  #define VL_NEEDINACTIVE 0x0080          /* delay VNOP_INACTIVE until iocount goes to 0 */
225  
226  #define VL_LABEL        0x0100          /* vnode is marked for labeling */
227  #define VL_LABELWAIT    0x0200          /* vnode is marked for labeling */
228  #define VL_LABELED      0x0400          /* vnode is labeled */
229  #define VL_LWARNED      0x0800
230  #define VL_HASSTREAMS   0x1000          /* vnode has had at least one associated named stream vnode (may not have one any longer) */
231  
232  #define VNAMED_UBC      0x2000          /* ubc named reference */
233  #define VNAMED_MOUNT    0x4000          /* mount point named reference */
234  #define VNAMED_FSHASH   0x8000          /* FS hash named reference */
235  
236  /*
237   * v_flags
238   */
239  #define VROOT           0x000001        /* root of its file system */
240  #define VTEXT           0x000002        /* vnode is a pure text prototype */
241  #define VSYSTEM         0x000004        /* vnode being used by kernel */
242  #define VISTTY          0x000008        /* vnode represents a tty */
243  #define VRAGE           0x000010        /* vnode is in rapid age state */
244  #define VBDEVVP         0x000020        /* vnode created by bdevvp */
245  #define VDEVFLUSH       0x000040        /* device vnode after vflush */
246  #define VMOUNT          0x000080        /* mount operation in progress */
247  #define VBWAIT          0x000100        /* waiting for output to complete */
248  #define VSHARED_DYLD    0x000200        /* vnode is a dyld shared cache file */
249  #define VNOCACHE_DATA   0x000400        /* don't keep data cached once it's been consumed */
250  #define VSTANDARD       0x000800        /* vnode obtained from common pool */
251  #define VAGE            0x001000        /* Insert vnode at head of free list */
252  #define VRAOFF          0x002000        /* read ahead disabled */
253  #define VNCACHEABLE     0x004000        /* vnode is allowed to be put back in name cache */
254  #if NAMEDSTREAMS
255  #define VISSHADOW       0x008000        /* vnode is a shadow file */
256  #endif
257  #define VSWAP           0x010000        /* vnode is being used as swapfile */
258  #define VTHROTTLED      0x020000        /* writes or pageouts have been throttled */
259  /* wakeup tasks waiting when count falls below threshold */
260  #define VNOFLUSH        0x040000        /* don't vflush() if SKIPSYSTEM */
261  #define VLOCKLOCAL      0x080000        /* this vnode does adv locking in vfs */
262  #define VISHARDLINK     0x100000        /* hard link needs special processing on lookup and in volfs */
263  #define VISUNION        0x200000        /* union special processing */
264  #define VISNAMEDSTREAM  0x400000        /* vnode is a named stream (eg HFS resource fork) */
265  #define VOPENEVT        0x800000        /* if process is P_CHECKOPENEVT, then or in the O_EVTONLY flag on open */
266  #define VNEEDSSNAPSHOT 0x1000000
267  #define VNOCS          0x2000000        /* is there no code signature available */
268  #define VISDIRTY       0x4000000        /* vnode will need IO if reclaimed */
269  #define VFASTDEVCANDIDATE  0x8000000        /* vnode is a candidate to store on a fast device */
270  #define VAUTOCANDIDATE 0x10000000       /* vnode was automatically marked as a fast-dev candidate */
271  #define VFMLINKTARGET  0x20000000       /* vnode is firmlink target */
272  /*
273   *  0x40000000 not used
274   *  0x80000000 not used.
275   */
276  
277  /*
278   * This structure describes vnode data which is specific to a file descriptor.
279   * It is currently used only for file descriptors which are for opened for
280   * directories.
281   */
282  struct fd_vn_data {
283  	lck_mtx_t fv_lock;   /* Used to serialize directory enumeration on fd */
284  	off_t     fv_offset; /* Offset to be used */
285  	void      *fv_dircookie; /* If FS doesn't like offsets in directories */
286  	caddr_t   fv_buf;    /* Temporary buffer to store directory entries */
287  	size_t    fv_bufsiz;  /* Valid size of fv_buf */
288  	size_t    fv_bufdone; /* How much of fv_buf is processed */
289  	size_t    fv_bufallocsiz; /* Allocation size determined for Buffer*/
290  	off_t     fv_soff;   /* Starting FS offset for this buffer */
291  	off_t     fv_eoff;   /* Ending FS offset for this buffer */
292  	int       fv_eofflag;/* Does fv_eoff represent EOF ? */
293  };
294  
295  /*
296   * FV_DIRBUF_START_SIZ is the initial size of the buffer passed to VNOP_READDIR.
297   * That may not be enough for some filesytems so the current algorithm works its
298   * way upto FV_DIRBUF_MAX_SIZ
299   */
300  #define FV_DIRBUF_DIRENTRY_SIZ  (sizeof(struct direntry))
301  #define FV_DIRBUF_START_SIZ     FV_DIRBUF_DIRENTRY_SIZ
302  #define FV_DIRBUF_MAX_SIZ       (4*(sizeof(struct direntry)))
303  
304  #define FV_LOCK(fvd) lck_mtx_lock(&(((struct fd_vn_data *)fvd)->fv_lock))
305  #define FV_UNLOCK(fvd) lck_mtx_unlock(&(((struct fd_vn_data *)fvd)->fv_lock))
306  
307  /*
308   * Global vnode data.
309   */
310  extern  struct vnode *rootvnode;        /* root (i.e. "/") vnode */
311  
312  #ifdef CONFIG_IMGSRC_ACCESS
313  #define MAX_IMAGEBOOT_NESTING   2
314  extern  struct vnode *imgsrc_rootvnodes[];
315  #endif /* CONFIG_IMGSRC_ACCESS */
316  
317  
318  /*
319   * Mods for exensibility.
320   */
321  
322  /*
323   * Flags for vdesc_flags:
324   */
325  #define VDESC_MAX_VPS           16
326  /* Low order 16 flag bits are reserved for willrele flags for vp arguments. */
327  #define VDESC_VP0_WILLRELE      0x00001
328  #define VDESC_VP1_WILLRELE      0x00002
329  #define VDESC_VP2_WILLRELE      0x00004
330  #define VDESC_VP3_WILLRELE      0x00008
331  #define VDESC_NOMAP_VPP         0x00100
332  #define VDESC_VPP_WILLRELE      0x00200
333  
334  #define VDESC_DISABLED          0x10000 /* descriptor defined but op is unused, has no op slot */
335  
336  /*
337   * VDESC_NO_OFFSET is used to identify the end of the offset list
338   * and in places where no such field exists.
339   */
340  #define VDESC_NO_OFFSET -1
341  
342  /*
343   * This structure describes the vnode operation taking place.
344   */
345  struct vnodeop_desc {
346  	int     vdesc_offset;           /* offset in vector--first for speed */
347  	const char *vdesc_name;         /* a readable name for debugging */
348  	int     vdesc_flags;            /* VDESC_* flags */
349  
350  	/*
351  	 * These ops are used by bypass routines to map and locate arguments.
352  	 * Creds and procs are not needed in bypass routines, but sometimes
353  	 * they are useful to (for example) transport layers.
354  	 * Nameidata is useful because it has a cred in it.
355  	 */
356  	int     *vdesc_vp_offsets;      /* list ended by VDESC_NO_OFFSET */
357  	int     vdesc_vpp_offset;       /* return vpp location */
358  	int     vdesc_cred_offset;      /* cred location, if any */
359  	int     vdesc_proc_offset;      /* proc location, if any */
360  	int     vdesc_componentname_offset; /* if any */
361  	int     vdesc_context_offset;   /* context location, if any */
362  	/*
363  	 * Finally, we've got a list of private data (about each operation)
364  	 * for each transport layer.  (Support to manage this list is not
365  	 * yet part of BSD.)
366  	 */
367  	caddr_t *vdesc_transports;
368  };
369  
370  /*
371   * A list of all the operation descs.
372   */
373  extern struct vnodeop_desc *vnodeop_descs[];
374  
375  
376  /*
377   * This macro is very helpful in defining those offsets in the vdesc struct.
378   *
379   * This is stolen from X11R4.  I ingored all the fancy stuff for
380   * Crays, so if you decide to port this to such a serious machine,
381   * you might want to consult Intrisics.h's XtOffset{,Of,To}.
382   */
383  #define VOPARG_OFFSET(p_type, field) \
384  	((int) (((char *) (&(((p_type)NULL)->field))) - ((char *) NULL)))
385  #define VOPARG_OFFSETOF(s_type, field) \
386  	VOPARG_OFFSET(s_type*,field)
387  #define VOPARG_OFFSETTO(S_TYPE, S_OFFSET, STRUCT_P) \
388  	((S_TYPE)(((char*)(STRUCT_P))+(S_OFFSET)))
389  
390  
391  
392  /*
393   * VOCALL calls an op given an ops vector.  We break it out because BSD's
394   * vclean changes the ops vector and then wants to call ops with the old
395   * vector.
396   */
397  #define VOCALL(OPSV, OFF, AP) (( *((OPSV)[(OFF)])) (AP))
398  
399  /*
400   * This call works for vnodes in the kernel.
401   */
402  #define VCALL(VP, OFF, AP) VOCALL((VP)->v_op,(OFF),(AP))
403  #define VDESC(OP) (& __CONCAT(OP,_desc))
404  #define VOFFSET(OP) (VDESC(OP)->vdesc_offset)
405  
406  struct ostat;
407  
408  /* bdevvp moved to vnode.h as private KPI */
409  void    cvtstat(struct stat *st, struct ostat *ost);
410  void    vprint(const char *label, struct vnode *vp);
411  
412  
413  __private_extern__ int set_package_extensions_table(user_addr_t data, int nentries, int maxwidth);
414  int     vn_rdwr_64(enum uio_rw rw, struct vnode *vp, uint64_t base,
415      int64_t len, off_t offset, enum uio_seg segflg,
416      int ioflg, kauth_cred_t cred, int64_t *aresid,
417      struct proc *p);
418  #if CONFIG_MACF
419  int     vn_setlabel(struct vnode *vp, struct label *intlabel,
420      vfs_context_t context);
421  #endif
422  void    fifo_printinfo(struct vnode *vp);
423  int     vn_open(struct nameidata *ndp, int fmode, int cmode);
424  int     vn_open_modflags(struct nameidata *ndp, int *fmode, int cmode);
425  int     vn_open_auth(struct nameidata *ndp, int *fmode, struct vnode_attr *);
426  int     vn_close(vnode_t, int flags, vfs_context_t ctx);
427  errno_t vn_remove(vnode_t dvp, vnode_t *vpp, struct nameidata *ndp, int32_t flags, struct vnode_attr *vap, vfs_context_t ctx);
428  errno_t vn_rename(struct vnode *fdvp, struct vnode **fvpp, struct componentname *fcnp, struct vnode_attr *fvap,
429      struct vnode *tdvp, struct vnode **tvpp, struct componentname *tcnp, struct vnode_attr *tvap,
430      uint32_t flags, vfs_context_t ctx);
431  
432  void    lock_vnode_and_post(vnode_t, int);
433  
434  #define post_event_if_success(_vp, _error, _event) \
435  	do { \
436  	        if (0 == (_error)) {    \
437  	                lock_vnode_and_post((_vp), (_event)); \
438  	        } \
439  	} while (0)
440  
441  /* Authorization subroutines */
442  int     vn_authorize_open_existing(vnode_t vp, struct componentname *cnp, int fmode, vfs_context_t ctx, void *reserved);
443  int     vn_authorize_create(vnode_t, struct componentname *, struct vnode_attr *, vfs_context_t, void*);
444  int     vn_attribute_prepare(vnode_t dvp, struct vnode_attr *vap, uint32_t *defaulted_fieldsp, vfs_context_t ctx);
445  void    vn_attribute_cleanup(struct vnode_attr *vap, uint32_t defaulted_fields);
446  int     vn_authorize_rename(struct vnode *fdvp, struct vnode *fvp, struct componentname *fcnp,
447      struct vnode *tdvp, struct vnode *tvp, struct componentname *tcnp,
448      vfs_context_t ctx, void *reserved);
449  int vn_authorize_renamex(struct vnode *fdvp, struct vnode *fvp, struct componentname *fcnp,
450      struct vnode *tdvp, struct vnode *tvp, struct componentname *tcnp,
451      vfs_context_t ctx, vfs_rename_flags_t flags, void *reserved);
452  int vn_authorize_renamex_with_paths(struct vnode *fdvp, struct vnode *fvp, struct componentname *fcnp, const char *from_path,
453      struct vnode *tdvp, struct vnode *tvp, struct componentname *tcnp, const char *to_path,
454      vfs_context_t ctx, vfs_rename_flags_t flags, void *reserved);
455  
456  typedef int (*vn_create_authorizer_t)(vnode_t, struct componentname *, struct vnode_attr *, vfs_context_t, void*);
457  int vn_authorize_mkdir(vnode_t, struct componentname *, struct vnode_attr *, vfs_context_t, void*);
458  int vn_authorize_null(vnode_t, struct componentname *, struct vnode_attr *, vfs_context_t, void*);
459  int vnode_attr_authorize_dir_clone(struct vnode_attr *vap, kauth_action_t action,
460      struct vnode_attr *dvap, vnode_t sdvp, mount_t mp, dir_clone_authorizer_op_t vattr_op,
461      uint32_t flags, vfs_context_t ctx, void *reserved);
462  /* End of authorization subroutines */
463  
464  void vnode_attr_handle_mnt_ignore_ownership(struct vnode_attr *vap, mount_t mp, vfs_context_t ctx);
465  
466  #define VN_CREATE_NOAUTH                (1<<0)
467  #define VN_CREATE_NOINHERIT             (1<<1)
468  #define VN_CREATE_UNION                 (1<<2)
469  #define VN_CREATE_NOLABEL               (1<<3)
470  #define VN_CREATE_DOOPEN                (1<<4)  /* Open file if a batched operation is available */
471  errno_t vn_create(vnode_t, vnode_t *, struct nameidata *, struct vnode_attr *, uint32_t, int, uint32_t*, vfs_context_t);
472  int     vn_mkdir(vnode_t dvp, vnode_t *vpp, struct nameidata *ndp, struct vnode_attr *vap, vfs_context_t ctx);
473  int     vn_rmdir(vnode_t dvp, vnode_t *vpp, struct nameidata *ndp, struct vnode_attr *vap, vfs_context_t ctx);
474  
475  int     vn_getxattr(vnode_t, const char *, uio_t, size_t *, int, vfs_context_t);
476  int     vn_setxattr(vnode_t, const char *, uio_t, int, vfs_context_t);
477  int     vn_removexattr(vnode_t, const char *, int, vfs_context_t);
478  int     vn_listxattr(vnode_t, uio_t, size_t *, int, vfs_context_t);
479  
480  #if NAMEDSTREAMS
481  errno_t  vnode_getnamedstream(vnode_t, vnode_t *, const char *, enum nsoperation, int, vfs_context_t);
482  errno_t  vnode_makenamedstream(vnode_t, vnode_t *, const char *, int, vfs_context_t);
483  errno_t  vnode_removenamedstream(vnode_t, vnode_t, const char *, int, vfs_context_t);
484  errno_t  vnode_flushnamedstream(vnode_t vp, vnode_t svp, vfs_context_t context);
485  errno_t  vnode_relenamedstream(vnode_t vp, vnode_t svp);
486  errno_t  vnode_verifynamedstream(vnode_t vp);
487  #endif
488  
489  
490  void    nchinit(void);
491  int     resize_namecache(int newsize);
492  void    name_cache_lock_shared(void);
493  void    name_cache_lock(void);
494  void    name_cache_unlock(void);
495  void    cache_enter_with_gen(vnode_t dvp, vnode_t vp, struct componentname *cnp, int gen);
496  const char *cache_enter_create(vnode_t dvp, vnode_t vp, struct componentname *cnp);
497  
498  extern int nc_disabled;
499  
500  #define vnode_lock_convert(v)   lck_mtx_convert_spin(&(v)->v_lock)
501  
502  void    vnode_lock_spin(vnode_t);
503  
504  
505  void    vnode_list_lock(void);
506  void    vnode_list_unlock(void);
507  
508  #define VNODE_REF_FORCE 0x1
509  int     vnode_ref_ext(vnode_t, int, int);
510  
511  void    vnode_rele_internal(vnode_t, int, int, int);
512  #ifdef BSD_KERNEL_PRIVATE
513  int     vnode_getalways(vnode_t);
514  int     vnode_getalways_from_pager(vnode_t);
515  int     vget_internal(vnode_t, int, int);
516  errno_t vnode_getiocount(vnode_t, unsigned int, int);
517  #endif /* BSD_KERNEL_PRIVATE */
518  int     vnode_get_locked(vnode_t);
519  int     vnode_put_locked(vnode_t);
520  #ifdef BSD_KERNEL_PRIVATE
521  int     vnode_put_from_pager(vnode_t);
522  #endif /* BSD_KERNEL_PRIVATE */
523  
524  int     vnode_issock(vnode_t);
525  int     vnode_isaliased(vnode_t);
526  
527  void    unlock_fsnode(vnode_t, int *);
528  int     lock_fsnode(vnode_t, int *);
529  
530  errno_t vnode_resume(vnode_t);
531  errno_t vnode_suspend(vnode_t);
532  
533  
534  errno_t vnode_mtime(vnode_t, struct timespec *, vfs_context_t);
535  errno_t vnode_flags(vnode_t, uint32_t *, vfs_context_t);
536  
537  errno_t vnode_size(vnode_t, off_t *, vfs_context_t);
538  errno_t vnode_setsize(vnode_t, off_t, int ioflag, vfs_context_t);
539  int     vnode_setattr_fallback(vnode_t vp, struct vnode_attr *vap, vfs_context_t ctx);
540  int     vnode_isspec(vnode_t vp);
541  
542  
543  #ifdef BSD_KERNEL_PRIVATE
544  
545  typedef uint32_t compound_vnop_id_t;
546  #define COMPOUND_VNOP_OPEN              0x01
547  #define COMPOUND_VNOP_MKDIR             0x02
548  #define COMPOUND_VNOP_RENAME            0x04
549  #define COMPOUND_VNOP_REMOVE            0x08
550  #define COMPOUND_VNOP_RMDIR             0x10
551  
552  int     vnode_compound_rename_available(vnode_t vp);
553  int     vnode_compound_rmdir_available(vnode_t vp);
554  int     vnode_compound_mkdir_available(vnode_t vp);
555  int     vnode_compound_remove_available(vnode_t vp);
556  int     vnode_compound_open_available(vnode_t vp);
557  int     vnode_compound_op_available(vnode_t, compound_vnop_id_t);
558  #endif /* BSD_KERNEL_PRIVATE */
559  
560  void vn_setunionwait(vnode_t);
561  void vn_checkunionwait(vnode_t);
562  void vn_clearunionwait(vnode_t, int);
563  
564  void SPECHASH_LOCK(void);
565  void SPECHASH_UNLOCK(void);
566  
567  void    vnode_authorize_init(void);
568  
569  void    vfsinit(void);
570  void vnode_lock(vnode_t);
571  void vnode_unlock(vnode_t);
572  
573  void vn_print_state(vnode_t /* vp */, const char * /* fmt */, ...)
574  __printflike(2, 3);
575  
576  #if DEVELOPMENT || DEBUG
577  #define VNASSERT(exp, vp, msg)                                          \
578  do {                                                                    \
579  	if (__improbable(!(exp))) {                                     \
580  	        vn_print_state(vp, "VNASSERT failed %s:%d\n", __FILE__, \
581  	            __LINE__);                                          \
582  	        panic msg;                                              \
583  	}                                                               \
584  } while (0)
585  #else
586  #define VNASSERT(exp, vp, msg)
587  #endif /* DEVELOPMENT || DEBUG */
588  
589  /*
590   * XXX exported symbols; should be static
591   */
592  void    vfs_op_init(void);
593  void    vfs_opv_init(void);
594  
595  #ifdef BSD_KERNEL_PRIVATE
596  int vfs_sysctl_node SYSCTL_HANDLER_ARGS;
597  void vnode_setneedinactive(vnode_t);
598  int     vnode_hasnamedstreams(vnode_t); /* Does this vnode have associated named streams? */
599  
600  errno_t
601  vnode_readdir64(struct vnode *vp, struct uio *uio, int flags, int *eofflag,
602      int *numdirent, vfs_context_t ctxp);
603  
604  void vnode_setswapmount(vnode_t);
605  int64_t vnode_getswappin_avail(vnode_t);
606  
607  int vnode_get_snapdir(vnode_t, vnode_t *, vfs_context_t);
608  
609  #if CONFIG_TRIGGERS
610  /* VFS Internal Vnode Trigger Interfaces (Private) */
611  int vnode_trigger_resolve(vnode_t, struct nameidata *, vfs_context_t);
612  void vnode_trigger_rearm(vnode_t, vfs_context_t);
613  void vfs_nested_trigger_unmounts(mount_t, int, vfs_context_t);
614  #endif /* CONFIG_TRIGGERS */
615  
616  int     build_path_with_parent(vnode_t, vnode_t /* parent */, char *, int, int *, size_t *, int, vfs_context_t);
617  
618  void    nspace_resolver_init(void);
619  void    nspace_resolver_exited(struct proc *);
620  
621  int     vnode_materialize_dataless_file(vnode_t, uint64_t);
622  
623  int     vnode_isinuse_locked(vnode_t, int, int );
624  
625  #endif /* BSD_KERNEL_PRIVATE */
626  
627  #if CONFIG_IO_COMPRESSION_STATS
628  /*
629   * update the IO compression stats tracked at block granularity
630   */
631  int vnode_updateiocompressionblockstats(vnode_t vp, uint32_t size_bucket);
632  
633  /*
634   * update the IO compression stats tracked for the buffer
635   */
636  int vnode_updateiocompressionbufferstats(vnode_t vp, uint64_t uncompressed_size, uint64_t compressed_size, uint32_t size_bucket, uint32_t compression_bucket);
637  
638  #endif /* CONFIG_IO_COMPRESSION_STATS */
639  
640  extern bool rootvp_is_ssd;
641  
642  #endif /* !_SYS_VNODE_INTERNAL_H_ */