+
+ if ( (error = vnode_getwithref(vp)) == 0 ) {
+ if (FILEGLOB_DTYPE(fg) == DTYPE_VNODE &&
+ ((fg->fg_flag & FHASLOCK) != 0 ||
+ (fg->fg_lflags & FG_HAS_OFDLOCK) != 0)) {
+ struct flock lf = {
+ .l_whence = SEEK_SET,
+ .l_start = 0,
+ .l_len = 0,
+ .l_type = F_UNLCK
+ };
+
+ if ((fg->fg_flag & FHASLOCK) != 0)
+ (void) VNOP_ADVLOCK(vp, (caddr_t)fg,
+ F_UNLCK, &lf, F_FLOCK, ctx, NULL);
+
+ if ((fg->fg_lflags & FG_HAS_OFDLOCK) != 0)
+ (void) VNOP_ADVLOCK(vp, (caddr_t)fg,
+ F_UNLCK, &lf, F_OFD_LOCK, ctx, NULL);
+ }
+ error = vn_close(vp, fg->fg_flag, ctx);
+ (void) vnode_put(vp);
+ }
+ return (error);
+}
+
+/*
+ * Returns: 0 Success
+ * VNOP_PATHCONF:???
+ */
+int
+vn_pathconf(vnode_t vp, int name, int32_t *retval, vfs_context_t ctx)
+{
+ int error = 0;
+ struct vfs_attr vfa;
+
+ switch(name) {
+ case _PC_EXTENDED_SECURITY_NP:
+ *retval = vfs_extendedsecurity(vnode_mount(vp)) ? 1 : 0;
+ break;
+ case _PC_AUTH_OPAQUE_NP:
+ *retval = vfs_authopaque(vnode_mount(vp));
+ break;
+ case _PC_2_SYMLINKS:
+ *retval = 1; /* XXX NOTSUP on MSDOS, etc. */
+ break;
+ case _PC_ALLOC_SIZE_MIN:
+ *retval = 1; /* XXX lie: 1 byte */
+ break;
+ case _PC_ASYNC_IO: /* unistd.h: _POSIX_ASYNCHRONUS_IO */
+ *retval = 1; /* [AIO] option is supported */
+ break;
+ case _PC_PRIO_IO: /* unistd.h: _POSIX_PRIORITIZED_IO */
+ *retval = 0; /* [PIO] option is not supported */
+ break;
+ case _PC_REC_INCR_XFER_SIZE:
+ *retval = 4096; /* XXX go from MIN to MAX 4K at a time */
+ break;
+ case _PC_REC_MIN_XFER_SIZE:
+ *retval = 4096; /* XXX recommend 4K minimum reads/writes */
+ break;
+ case _PC_REC_MAX_XFER_SIZE:
+ *retval = 65536; /* XXX recommend 64K maximum reads/writes */
+ break;
+ case _PC_REC_XFER_ALIGN:
+ *retval = 4096; /* XXX recommend page aligned buffers */
+ break;
+ case _PC_SYMLINK_MAX:
+ *retval = 255; /* Minimum acceptable POSIX value */
+ break;
+ case _PC_SYNC_IO: /* unistd.h: _POSIX_SYNCHRONIZED_IO */
+ *retval = 0; /* [SIO] option is not supported */
+ break;
+ case _PC_XATTR_SIZE_BITS:
+ /* The number of bits used to store maximum extended
+ * attribute size in bytes. For example, if the maximum
+ * attribute size supported by a file system is 128K, the
+ * value returned will be 18. However a value 18 can mean
+ * that the maximum attribute size can be anywhere from
+ * (256KB - 1) to 128KB. As a special case, the resource
+ * fork can have much larger size, and some file system
+ * specific extended attributes can have smaller and preset
+ * size; for example, Finder Info is always 32 bytes.
+ */
+ memset(&vfa, 0, sizeof(vfa));
+ VFSATTR_INIT(&vfa);
+ VFSATTR_WANTED(&vfa, f_capabilities);
+ if (vfs_getattr(vnode_mount(vp), &vfa, ctx) == 0 &&
+ (VFSATTR_IS_SUPPORTED(&vfa, f_capabilities)) &&
+ (vfa.f_capabilities.capabilities[VOL_CAPABILITIES_INTERFACES] & VOL_CAP_INT_EXTENDED_ATTR) &&
+ (vfa.f_capabilities.valid[VOL_CAPABILITIES_INTERFACES] & VOL_CAP_INT_EXTENDED_ATTR)) {
+ /* Supports native extended attributes */
+ error = VNOP_PATHCONF(vp, name, retval, ctx);