+struct vnop_compound_open_args {
+ struct vnodeop_desc *a_desc;
+ vnode_t a_dvp;
+ vnode_t *a_vpp;
+ struct componentname *a_cnp;
+ int32_t a_flags;
+ int32_t a_fmode;
+ struct vnode_attr *a_vap;
+ vfs_context_t a_context;
+ void *a_reserved;
+};
+#endif /* 0 */
+
+int
+VNOP_COMPOUND_OPEN(vnode_t dvp, vnode_t *vpp, struct nameidata *ndp, int32_t flags, int32_t fmode, uint32_t *statusp, struct vnode_attr *vap, vfs_context_t ctx)
+{
+ int _err;
+ struct vnop_compound_open_args a;
+ int did_create = 0;
+ int want_create;
+ uint32_t tmp_status = 0;
+ struct componentname *cnp = &ndp->ni_cnd;
+
+ want_create = (flags & VNOP_COMPOUND_OPEN_DO_CREATE);
+
+ a.a_desc = &vnop_compound_open_desc;
+ a.a_dvp = dvp;
+ a.a_vpp = vpp; /* Could be NULL */
+ a.a_cnp = cnp;
+ a.a_flags = flags;
+ a.a_fmode = fmode;
+ a.a_status = (statusp != NULL) ? statusp : &tmp_status;
+ a.a_vap = vap;
+ a.a_context = ctx;
+ a.a_open_create_authorizer = vn_authorize_create;
+ a.a_open_existing_authorizer = vn_authorize_open_existing;
+ a.a_reserved = NULL;
+
+ if (dvp == NULLVP) {
+ panic("No dvp?");
+ }
+ if (want_create && !vap) {
+ panic("Want create, but no vap?");
+ }
+ if (!want_create && vap) {
+ panic("Don't want create, but have a vap?");
+ }
+
+ _err = (*dvp->v_op[vnop_compound_open_desc.vdesc_offset])(&a);
+ if (want_create) {
+ if (_err == 0 && *vpp) {
+ DTRACE_FSINFO(compound_open, vnode_t, *vpp);
+ } else {
+ DTRACE_FSINFO(compound_open, vnode_t, dvp);
+ }
+ } else {
+ DTRACE_FSINFO(compound_open, vnode_t, *vpp);
+ }
+
+ did_create = (*a.a_status & COMPOUND_OPEN_STATUS_DID_CREATE);
+
+ if (did_create && !want_create) {
+ panic("Filesystem did a create, even though none was requested?");
+ }
+
+ if (did_create) {
+#if CONFIG_APPLEDOUBLE
+ if (!NATIVE_XATTR(dvp)) {
+ /*
+ * Remove stale Apple Double file (if any).
+ */
+ xattrfile_remove(dvp, cnp->cn_nameptr, ctx, 0);
+ }
+#endif /* CONFIG_APPLEDOUBLE */
+ /* On create, provide kqueue notification */
+ post_event_if_success(dvp, _err, NOTE_WRITE);
+ }
+
+ lookup_compound_vnop_post_hook(_err, dvp, *vpp, ndp, did_create);
+#if 0 /* FSEvents... */
+ if (*vpp && _err && _err != EKEEPLOOKING) {
+ vnode_put(*vpp);
+ *vpp = NULLVP;
+ }
+#endif /* 0 */
+
+ return (_err);
+
+}
+
+#if 0