/*
- * Copyright (c) 2000-2010 Apple Inc. All rights reserved.
+ * Copyright (c) 2000-2012 Apple Inc. All rights reserved.
*
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
LIST_HEAD(buflists, buf);
-
-struct unsafe_fsnode {
- lck_mtx_t fsnodelock;
- int32_t fsnode_count;
- void * fsnodeowner;
-};
-
#if CONFIG_TRIGGERS
/*
* VFS Internal (private) trigger vnode resolver info.
lck_mtx_t v_lock; /* vnode mutex */
TAILQ_ENTRY(vnode) v_freelist; /* vnode freelist */
TAILQ_ENTRY(vnode) v_mntvnodes; /* vnodes for mount point */
+ TAILQ_HEAD(, namecache) v_ncchildren; /* name cache entries that regard us as their parent */
LIST_HEAD(, namecache) v_nclinks; /* name cache entries that name this vnode */
- LIST_HEAD(, namecache) v_ncchildren; /* name cache entries that regard us as there parent */
vnode_t v_defer_reclaimlist; /* in case we have to defer the reclaim to avoid recursion */
uint32_t v_listflag; /* flags protected by the vnode_list_lock (see below) */
uint32_t v_flag; /* vnode flags (see below) */
const char *v_name; /* name component of the vnode */
vnode_t v_parent; /* pointer to parent vnode */
struct lockf *v_lockf; /* advisory lock list head */
-#ifndef __LP64__
- struct unsafe_fsnode *v_unsafefs; /* pointer to struct used to lock */
-#else
- int32_t v_reserved1;
- int32_t v_reserved2;
-#endif /* __LP64__ */
int (**v_op)(void *); /* vnode operations vector */
mount_t v_mount; /* ptr to vfs we are in */
void * v_data; /* private data for fs */
/*
* v_listflag
*/
-#define VLIST_RAGE 0x01 /* vnode is currently in the rapid age list */
-#define VLIST_DEAD 0x02 /* vnode is currently in the dead list */
+#define VLIST_RAGE 0x01 /* vnode is currently in the rapid age list */
+#define VLIST_DEAD 0x02 /* vnode is currently in the dead list */
+#define VLIST_ASYNC_WORK 0x04 /* vnode is currently on the deferred async work queue */
/*
* v_lflags
#endif
#define VOPENEVT 0x800000 /* if process is P_CHECKOPENEVT, then or in the O_EVTONLY flag on open */
#define VNEEDSSNAPSHOT 0x1000000
+#define VNOCS 0x2000000 /* is there no code signature available */
+#define VISDIRTY 0x4000000 /* vnode will need IO if reclaimed */
+#define VFASTDEVCANDIDATE 0x8000000 /* vnode is a candidate to store on a fast device */
+#define VAUTOCANDIDATE 0x10000000 /* vnode was automatically marked as a fast-dev candidate */
+/*
+ 0x20000000 not used
+ 0x40000000 not used
+ 0x80000000 not used.
+*/
+
+/*
+ * This structure describes vnode data which is specific to a file descriptor.
+ * It is currently used only for file descriptors which are for opened for
+ * directories.
+ */
+struct fd_vn_data {
+ lck_mtx_t fv_lock; /* Used to serialize directory enumeration on fd */
+ off_t fv_offset; /* Offset to be used */
+ void *fv_dircookie; /* If FS doesn't like offsets in directories */
+ caddr_t fv_buf; /* Temporary buffer to store directory entries */
+ size_t fv_bufsiz; /* Valid size of fv_buf */
+ size_t fv_bufdone; /* How much of fv_buf is processed */
+ size_t fv_bufallocsiz; /* Allocation size determined for Buffer*/
+ off_t fv_soff; /* Starting FS offset for this buffer */
+ off_t fv_eoff; /* Ending FS offset for this buffer */
+ int fv_eofflag;/* Does fv_eoff represent EOF ? */
+};
+
+/*
+ * FV_DIRBUF_START_SIZ is the initial size of the buffer passed to VNOP_READDIR.
+ * That may not be enough for some filesytems so the current algorithm works its
+ * way upto FV_DIRBUF_MAX_SIZ
+ */
+#define FV_DIRBUF_DIRENTRY_SIZ (sizeof(struct direntry))
+#define FV_DIRBUF_START_SIZ FV_DIRBUF_DIRENTRY_SIZ
+#define FV_DIRBUF_MAX_SIZ (4*(sizeof(struct direntry)))
+
+#define FV_LOCK(fvd) lck_mtx_lock(&(((struct fd_vn_data *)fvd)->fv_lock))
+#define FV_UNLOCK(fvd) lck_mtx_unlock(&(((struct fd_vn_data *)fvd)->fv_lock))
/*
* Global vnode data.
*/
#define VDESC_MAX_VPS 16
/* Low order 16 flag bits are reserved for willrele flags for vp arguments. */
-#define VDESC_VP0_WILLRELE 0x0001
-#define VDESC_VP1_WILLRELE 0x0002
-#define VDESC_VP2_WILLRELE 0x0004
-#define VDESC_VP3_WILLRELE 0x0008
-#define VDESC_NOMAP_VPP 0x0100
-#define VDESC_VPP_WILLRELE 0x0200
+#define VDESC_VP0_WILLRELE 0x00001
+#define VDESC_VP1_WILLRELE 0x00002
+#define VDESC_VP2_WILLRELE 0x00004
+#define VDESC_VP3_WILLRELE 0x00008
+#define VDESC_NOMAP_VPP 0x00100
+#define VDESC_VPP_WILLRELE 0x00200
+
+#define VDESC_DISABLED 0x10000 /* descriptor defined but op is unused, has no op slot */
/*
* VDESC_NO_OFFSET is used to identify the end of the offset list
struct ostat;
-#define BUILDPATH_NO_FS_ENTER 0x1 /* Use cache values, do not enter file system */
-#define BUILDPATH_CHECKACCESS 0x2 /* Check if parents have search rights */
-int build_path(vnode_t first_vp, char *buff, int buflen, int *outlen, int flags, vfs_context_t ctx);
-
-int bdevvp(dev_t dev, struct vnode **vpp);
+/* bdevvp moved to vnode.h as private KPI */
void cvtstat(struct stat *st, struct ostat *ost);
void vprint(const char *label, struct vnode *vp);
-__private_extern__ int is_package_name(const char *name, int len);
__private_extern__ int set_package_extensions_table(user_addr_t data, int nentries, int maxwidth);
int vn_rdwr_64(enum uio_rw rw, struct vnode *vp, uint64_t base,
int64_t len, off_t offset, enum uio_seg segflg,
int vn_authorize_rename(struct vnode *fdvp, struct vnode *fvp, struct componentname *fcnp,
struct vnode *tdvp, struct vnode *tvp, struct componentname *tcnp,
vfs_context_t ctx, void *reserved);
+int vn_authorize_renamex(struct vnode *fdvp, struct vnode *fvp, struct componentname *fcnp,
+ struct vnode *tdvp, struct vnode *tvp, struct componentname *tcnp,
+ vfs_context_t ctx, vfs_rename_flags_t flags, void *reserved);
int vn_authorize_rmdir(vnode_t dvp, vnode_t vp, struct componentname *cnp, vfs_context_t ctx, void *reserved);
typedef int (*vn_create_authorizer_t)(vnode_t, struct componentname *, struct vnode_attr *, vfs_context_t, void*);
int vn_authorize_mkdir(vnode_t, struct componentname *, struct vnode_attr *, vfs_context_t, void*);
int vn_authorize_null(vnode_t, struct componentname *, struct vnode_attr *, vfs_context_t, void*);
+int vnode_attr_authorize_dir_clone(struct vnode_attr *vap, kauth_action_t action,
+ struct vnode_attr *dvap, vnode_t sdvp, mount_t mp, dir_clone_authorizer_op_t vattr_op,
+ vfs_context_t ctx, void *reserved);
/* End of authorization subroutines */
#define VN_CREATE_NOAUTH (1<<0)
int vn_removexattr(vnode_t, const char *, int, vfs_context_t);
int vn_listxattr(vnode_t, uio_t, size_t *, int, vfs_context_t);
-int default_getxattr(vnode_t, const char *, uio_t, size_t *, int, vfs_context_t);
-int default_setxattr(vnode_t, const char *, uio_t, int, vfs_context_t);
-int default_removexattr(vnode_t, const char *, int, vfs_context_t);
-
-int check_appledouble_header(vnode_t, vfs_context_t);
-
#if NAMEDSTREAMS
errno_t vnode_getnamedstream(vnode_t, vnode_t *, const char *, enum nsoperation, int, vfs_context_t);
errno_t vnode_makenamedstream(vnode_t, vnode_t *, const char *, int, vfs_context_t);
errno_t vnode_removenamedstream(vnode_t, vnode_t, const char *, int, vfs_context_t);
errno_t vnode_flushnamedstream(vnode_t vp, vnode_t svp, vfs_context_t context);
-errno_t vnode_relenamedstream(vnode_t vp, vnode_t svp, vfs_context_t context);
+errno_t vnode_relenamedstream(vnode_t vp, vnode_t svp);
+errno_t vnode_verifynamedstream (vnode_t vp);
#endif
-void nchinit(void) __attribute__((section("__TEXT, initcode")));
+void nchinit(void);
int resize_namecache(uint32_t newsize);
void name_cache_lock_shared(void);
void name_cache_lock(void);
void cache_enter_with_gen(vnode_t dvp, vnode_t vp, struct componentname *cnp, int gen);
const char *cache_enter_create(vnode_t dvp, vnode_t vp, struct componentname *cnp);
-int vn_pathconf(vnode_t, int, int32_t *, vfs_context_t);
extern int nc_disabled;
#define vnode_lock_convert(v) lck_mtx_convert_spin(&(v)->v_lock)
#define VNODE_REF_FORCE 0x1
int vnode_ref_ext(vnode_t, int, int);
-void vnode_rele_ext(vnode_t, int, int);
void vnode_rele_internal(vnode_t, int, int, int);
#ifdef BSD_KERNEL_PRIVATE
int vnode_getalways(vnode_t);
errno_t vnode_suspend(vnode_t);
+errno_t vnode_mtime(vnode_t, struct timespec *, vfs_context_t);
+errno_t vnode_flags(vnode_t, uint32_t *, vfs_context_t);
+
errno_t vnode_size(vnode_t, off_t *, vfs_context_t);
errno_t vnode_setsize(vnode_t, off_t, int ioflag, vfs_context_t);
int vnode_setattr_fallback(vnode_t vp, struct vnode_attr *vap, vfs_context_t ctx);
void SPECHASH_LOCK(void);
void SPECHASH_UNLOCK(void);
-void vnode_authorize_init(void) __attribute__((section("__TEXT, initcode")));
+void vnode_authorize_init(void);
-void vfsinit(void) __attribute__((section("__TEXT, initcode")));
+void vfsinit(void);
void vnode_lock(vnode_t);
void vnode_unlock(vnode_t);
+void vn_print_state(vnode_t /* vp */, const char * /* fmt */, ...)
+ __printflike(2,3);
+
+#if DEVELOPMENT || DEBUG
+#define VNASSERT(exp, vp, msg) \
+do { \
+ if (__improbable(!(exp))) { \
+ vn_print_state(vp, "VNASSERT failed %s:%d\n", __FILE__, \
+ __LINE__); \
+ panic msg; \
+ } \
+} while (0)
+#else
+#define VNASSERT(exp, vp, msg)
+#endif /* DEVELOPMENT || DEBUG */
+
/*
* XXX exported symbols; should be static
*/
-void vfs_op_init(void) __attribute__((section("__TEXT, initcode")));
-void vfs_opv_init(void) __attribute__((section("__TEXT, initcode")));
-int vfs_sysctl(int *name, uint32_t namelen, user_addr_t oldp, size_t *oldlenp,
- user_addr_t newp, size_t newlen, struct proc *p);
-int sysctl_vnode(struct sysctl_oid *oidp, void *arg1, int arg2, struct sysctl_req *req);
+void vfs_op_init(void);
+void vfs_opv_init(void);
#ifdef BSD_KERNEL_PRIVATE
+int vfs_sysctl_node SYSCTL_HANDLER_ARGS;
void vnode_setneedinactive(vnode_t);
int vnode_hasnamedstreams(vnode_t); /* Does this vnode have associated named streams? */
void nspace_proc_exit(struct proc *p);
+errno_t
+vnode_readdir64(struct vnode *vp, struct uio *uio, int flags, int *eofflag,
+ int *numdirent, vfs_context_t ctxp);
+
+void vnode_setswapmount(vnode_t);
+int64_t vnode_getswappin_avail(vnode_t);
+
+int vnode_get_snapdir(vnode_t , vnode_t *, vfs_context_t);
+
#if CONFIG_TRIGGERS
/* VFS Internal Vnode Trigger Interfaces (Private) */
int vnode_trigger_resolve(vnode_t, struct nameidata *, vfs_context_t);