diff options
author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2019-05-22 11:25:06 +0000 |
---|---|---|
committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2019-05-22 11:25:06 +0000 |
commit | 006c23064de517ad172bcb4d24d8fbba01b875ec (patch) | |
tree | b420f32664896ab385844a19ccdfe88bc073d77c /usr/src/lib | |
parent | 3a1da6de2a216503918b00b0a4524e613a8134d8 (diff) | |
parent | 3f1d0a2eaba951f44d96bed559e6ed4487ec298c (diff) | |
download | illumos-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.com | 1 | ||||
-rw-r--r-- | usr/src/lib/smbsrv/libfksmbsrv/common/fake_vop.c | 117 |
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); |