summaryrefslogtreecommitdiff
path: root/usr/src/lib
diff options
context:
space:
mode:
authorJerry Jelinek <jerry.jelinek@joyent.com>2019-05-22 11:25:06 +0000
committerJerry Jelinek <jerry.jelinek@joyent.com>2019-05-22 11:25:06 +0000
commit006c23064de517ad172bcb4d24d8fbba01b875ec (patch)
treeb420f32664896ab385844a19ccdfe88bc073d77c /usr/src/lib
parent3a1da6de2a216503918b00b0a4524e613a8134d8 (diff)
parent3f1d0a2eaba951f44d96bed559e6ed4487ec298c (diff)
downloadillumos-joyent-006c23064de517ad172bcb4d24d8fbba01b875ec.tar.gz
[illumos-gate merge]release-20190523
commit 3f1d0a2eaba951f44d96bed559e6ed4487ec298c 10608 zfs tests could be more reliable (fix packaging) commit 130d76529cb137edd96e5cb68f129e459d784703 11045 libstand: smatch errors in dosfs and zfs reader commit ee2f9ca4ea24f72b05598c92aad7f42fb77b1345 11051 zfs miscounts BP_IS_EMBEDDED blocks during scan. commit 31779036e45a28bb1be446d3d65113584ccb7989 10335 mdb: fix fpcw2str() commit d082c87763acd6b9390ffaefe9062d481a085d6c 10975 Want SMB2 Apple extensions commit c5f48fa536d16d8fe59d1bb62faa7eb8e891610c 10974 SMB1 create file should support extended_response format commit 3bd40d9837ed643779c04bcc9d85d24be281ef29 10973 SMB server declines EA support incorrectly commit 593e4726be8e43f7def1376a7c6b9fb2f448d01e 10972 SMB1 tree connect missing some features
Diffstat (limited to 'usr/src/lib')
-rw-r--r--usr/src/lib/smbsrv/libfksmbsrv/Makefile.com1
-rw-r--r--usr/src/lib/smbsrv/libfksmbsrv/common/fake_vop.c117
2 files changed, 114 insertions, 4 deletions
diff --git a/usr/src/lib/smbsrv/libfksmbsrv/Makefile.com b/usr/src/lib/smbsrv/libfksmbsrv/Makefile.com
index 168343801b..8512488b42 100644
--- a/usr/src/lib/smbsrv/libfksmbsrv/Makefile.com
+++ b/usr/src/lib/smbsrv/libfksmbsrv/Makefile.com
@@ -122,6 +122,7 @@ OBJS_FS_SMBSRV = \
smb_vss.o \
smb_write.o \
\
+ smb2_aapl.o \
smb2_dispatch.o \
smb2_cancel.o \
smb2_change_notify.o \
diff --git a/usr/src/lib/smbsrv/libfksmbsrv/common/fake_vop.c b/usr/src/lib/smbsrv/libfksmbsrv/common/fake_vop.c
index 41c301fbaa..fdb1d82f5c 100644
--- a/usr/src/lib/smbsrv/libfksmbsrv/common/fake_vop.c
+++ b/usr/src/lib/smbsrv/libfksmbsrv/common/fake_vop.c
@@ -10,11 +10,12 @@
*/
/*
- * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
*/
#include <sys/types.h>
#include <sys/param.h>
+#include <sys/systm.h>
#include <sys/t_lock.h>
#include <sys/errno.h>
#include <sys/cred.h>
@@ -27,9 +28,11 @@
#include <sys/stat.h>
#include <sys/mode.h>
#include <sys/kmem.h>
+#include <sys/cmn_err.h>
#include <sys/debug.h>
#include <sys/atomic.h>
#include <sys/acl.h>
+#include <sys/filio.h>
#include <sys/flock.h>
#include <sys/nbmlock.h>
#include <sys/fcntl.h>
@@ -50,6 +53,7 @@ int stat_to_vattr(const struct stat *, vattr_t *);
int fop__getxvattr(vnode_t *, xvattr_t *);
int fop__setxvattr(vnode_t *, xvattr_t *);
+static void fake_inactive_xattrdir(vnode_t *);
/* ARGSUSED */
int
@@ -305,6 +309,75 @@ fop_access(
return (0);
}
+/*
+ * Conceptually like xattr_dir_lookup()
+ */
+static int
+fake_lookup_xattrdir(
+ vnode_t *dvp,
+ vnode_t **vpp)
+{
+ int len, fd;
+ int omode = O_RDWR | O_NOFOLLOW;
+ vnode_t *vp;
+
+ *vpp = NULL;
+
+ if (dvp->v_type != VDIR && dvp->v_type != VREG)
+ return (EINVAL);
+
+ /*
+ * If we're already in sysattr space, don't allow creation
+ * of another level of sysattrs.
+ */
+ if (dvp->v_flag & V_SYSATTR)
+ return (EINVAL);
+
+ mutex_enter(&dvp->v_lock);
+ if (dvp->v_xattrdir != NULL) {
+ *vpp = dvp->v_xattrdir;
+ VN_HOLD(*vpp);
+ mutex_exit(&dvp->v_lock);
+ return (0);
+ }
+ mutex_exit(&dvp->v_lock);
+
+ omode = O_RDONLY|O_XATTR;
+ fd = openat(dvp->v_fd, ".", omode);
+ if (fd < 0)
+ return (errno);
+
+ vp = vn_alloc(KM_SLEEP);
+ vp->v_fd = fd;
+ vp->v_flag = V_XATTRDIR|V_SYSATTR;
+ vp->v_type = VDIR;
+ vp->v_vfsp = dvp->v_vfsp;
+
+ /* Set v_path to parent path + "/@" (like NFS) */
+ len = strlen(dvp->v_path) + 3;
+ vp->v_path = kmem_alloc(len, KM_SLEEP);
+ (void) snprintf(vp->v_path, len, "%s/@", dvp->v_path);
+
+ /*
+ * Keep a pointer to the parent and a hold on it.
+ * Both are cleaned up in fake_inactive_xattrdir
+ */
+ vp->v_data = dvp;
+ vn_hold(dvp);
+
+ mutex_enter(&dvp->v_lock);
+ if (dvp->v_xattrdir == NULL) {
+ *vpp = dvp->v_xattrdir = vp;
+ mutex_exit(&dvp->v_lock);
+ } else {
+ *vpp = dvp->v_xattrdir;
+ mutex_exit(&dvp->v_lock);
+ fake_inactive_xattrdir(vp);
+ }
+
+ return (0);
+}
+
/* ARGSUSED */
int
fop_lookup(
@@ -325,7 +398,7 @@ fop_lookup(
struct stat st;
if (flags & LOOKUP_XATTR)
- return (ENOENT);
+ return (fake_lookup_xattrdir(dvp, vpp));
/*
* If lookup is for "", just return dvp.
@@ -681,7 +754,43 @@ fop_inactive(
cred_t *cr,
caller_context_t *ct)
{
- vncache_inactive(vp);
+ if (vp->v_flag & V_XATTRDIR) {
+ fake_inactive_xattrdir(vp);
+ } else {
+ vncache_inactive(vp);
+ }
+}
+
+/*
+ * The special xattr directories are not in the vncache AVL, but
+ * hang off the parent's v_xattrdir field. When vn_rele finds
+ * an xattr dir at v_count == 1 it calls here, but until we
+ * take locks on both the parent and the xattrdir, we don't
+ * know if we're really at the last reference. So in here we
+ * take both locks, re-check the count, and either bail out
+ * or proceed with "inactive" vnode cleanup. Part of that
+ * cleanup includes releasing the hold on the parent and
+ * clearing the parent's v_xattrdir field, which were
+ * setup in fake_lookup_xattrdir()
+ */
+static void
+fake_inactive_xattrdir(vnode_t *vp)
+{
+ vnode_t *dvp = vp->v_data; /* parent */
+ mutex_enter(&dvp->v_lock);
+ mutex_enter(&vp->v_lock);
+ if (vp->v_count > 1) {
+ /* new ref. via v_xattrdir */
+ mutex_exit(&vp->v_lock);
+ mutex_exit(&dvp->v_lock);
+ return;
+ }
+ ASSERT(dvp->v_xattrdir == vp);
+ dvp->v_xattrdir = NULL;
+ mutex_exit(&vp->v_lock);
+ mutex_exit(&dvp->v_lock);
+ vn_rele(dvp);
+ vn_free(vp);
}
/* ARGSUSED */
@@ -1267,7 +1376,7 @@ vn_rele(vnode_t *vp)
mutex_enter(&vp->v_lock);
if (vp->v_count == 1) {
mutex_exit(&vp->v_lock);
- vncache_inactive(vp);
+ fop_inactive(vp, NULL, NULL);
} else {
vp->v_count--;
mutex_exit(&vp->v_lock);