Print this page
NEX-15069 smtorture smb2.create.blob is failed
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-15069 smtorture smb2.create.blob is failed
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-4083 Upstream changes from illumos 5917 and 5995
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
SMB-50 User-mode SMB server
Includes work by these authors:
Thomas Keiser <thomas.keiser@nexenta.com>
Albert Lee <trisk@nexenta.com>
SMB-65 SMB server in non-global zones (use zone_kcred())
SMB-65 SMB server in non-global zones (data structure changes)
Many things move to the smb_server_t object, and
many functions gain an sv arg (which server).
*** 18,28 ****
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
! * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/sunddi.h>
--- 18,28 ----
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
! * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/sunddi.h>
*** 349,363 ****
* in the directory entry.
*
* smb_unmangle should only be called on names for which
* smb_maybe_mangled() is true
*
! * File systems which support VFSFT_EDIRENT_FLAGS will return the
! * directory entries as a buffer of edirent_t structure. Others will
! * return a buffer of dirent64_t structures. A union is used for the
! * the pointer into the buffer (bufptr, edp and dp).
! * The ed_name/d_name is NULL terminated by the file system.
*
* Returns:
* 0 - SUCCESS. Unmangled name is returned in namebuf.
* EINVAL - a parameter was invalid.
* ENOTDIR - dnode is not a directory node.
--- 349,360 ----
* in the directory entry.
*
* smb_unmangle should only be called on names for which
* smb_maybe_mangled() is true
*
! * The flags arg is no longer used, but retained just to avoid
! * changing the many callers of this function.
*
* Returns:
* 0 - SUCCESS. Unmangled name is returned in namebuf.
* EINVAL - a parameter was invalid.
* ENOTDIR - dnode is not a directory node.
*** 366,390 ****
#define SMB_UNMANGLE_BUFSIZE (4 * 1024)
int
smb_unmangle(smb_node_t *dnode, char *name, char *namebuf,
int buflen, uint32_t flags)
{
! int err, eof, bufsize, reclen;
uint64_t offset;
ino64_t ino;
- boolean_t is_edp;
char *namep, *buf;
char shortname[SMB_SHORTNAMELEN];
vnode_t *vp;
! union {
! char *u_bufptr;
! edirent_t *u_edp;
! dirent64_t *u_dp;
! } u;
! #define bufptr u.u_bufptr
! #define edp u.u_edp
! #define dp u.u_dp
if (dnode == NULL || name == NULL || namebuf == NULL || buflen == 0)
return (EINVAL);
ASSERT(smb_maybe_mangled(name) == B_TRUE);
--- 363,383 ----
#define SMB_UNMANGLE_BUFSIZE (4 * 1024)
int
smb_unmangle(smb_node_t *dnode, char *name, char *namebuf,
int buflen, uint32_t flags)
{
! _NOTE(ARGUNUSED(flags)) // avoid changing all callers
! int err, eof, bufsize;
uint64_t offset;
ino64_t ino;
char *namep, *buf;
char shortname[SMB_SHORTNAMELEN];
vnode_t *vp;
! char *bufptr;
! dirent64_t *dp;
! cred_t *cr = zone_kcred();
! int rc = ENOENT;
if (dnode == NULL || name == NULL || namebuf == NULL || buflen == 0)
return (EINVAL);
ASSERT(smb_maybe_mangled(name) == B_TRUE);
*** 392,450 ****
if (!smb_node_is_dir(dnode))
return (ENOTDIR);
vp = dnode->vp;
*namebuf = '\0';
- is_edp = vfs_has_feature(vp->v_vfsp, VFSFT_DIRENTFLAGS);
buf = kmem_alloc(SMB_UNMANGLE_BUFSIZE, KM_SLEEP);
! bufsize = SMB_UNMANGLE_BUFSIZE;
! offset = 0;
! while ((err = smb_vop_readdir(vp, offset, buf, &bufsize,
! &eof, flags, zone_kcred())) == 0) {
if (bufsize == 0) {
! err = ENOENT;
break;
}
-
bufptr = buf;
! reclen = 0;
! while ((bufptr += reclen) < buf + bufsize) {
! if (is_edp) {
! reclen = edp->ed_reclen;
! offset = edp->ed_off;
! ino = edp->ed_ino;
! namep = edp->ed_name;
! } else {
! reclen = dp->d_reclen;
offset = dp->d_off;
ino = dp->d_ino;
namep = dp->d_name;
- }
/* skip non utf8 filename */
if (u8_validate(namep, strlen(namep), NULL,
U8_VALIDATE_ENTIRE, &err) < 0)
continue;
smb_mangle(namep, ino, shortname, SMB_SHORTNAMELEN);
-
if (smb_strcasecmp(name, shortname, 0) == 0) {
(void) strlcpy(namebuf, namep, buflen);
! kmem_free(buf, SMB_UNMANGLE_BUFSIZE);
! return (0);
! }
! }
!
! if (eof) {
! err = ENOENT;
break;
}
-
- bufsize = SMB_UNMANGLE_BUFSIZE;
}
kmem_free(buf, SMB_UNMANGLE_BUFSIZE);
! return (err);
}
--- 385,448 ----
if (!smb_node_is_dir(dnode))
return (ENOTDIR);
vp = dnode->vp;
*namebuf = '\0';
buf = kmem_alloc(SMB_UNMANGLE_BUFSIZE, KM_SLEEP);
! bufptr = buf;
! bufsize = 0;
! offset = 0; // next entry offset
! eof = B_FALSE;
! for (;;) {
! /*
! * Read some entries, if buffer empty or
! * we've scanned all of it. Flags zero
! * (no edirent, no ABE wanted here)
! */
! if (bufsize <= 0) {
! bufsize = SMB_UNMANGLE_BUFSIZE;
! rc = smb_vop_readdir(vp, offset, buf,
! &bufsize, &eof, 0, cr);
! if (rc != 0)
! break; /* error */
if (bufsize == 0) {
! eof = B_TRUE;
! rc = ENOENT;
break;
}
bufptr = buf;
! }
! /* LINTED pointer alignment */
! dp = (dirent64_t *)bufptr;
! /*
! * Partial records are not supposed to happen,
! * but let's be defensive. If this happens,
! * restart at the current offset.
! */
! bufptr += dp->d_reclen;
! bufsize -= dp->d_reclen;
! if (bufsize < 0)
! continue;
!
offset = dp->d_off;
ino = dp->d_ino;
namep = dp->d_name;
/* skip non utf8 filename */
if (u8_validate(namep, strlen(namep), NULL,
U8_VALIDATE_ENTIRE, &err) < 0)
continue;
smb_mangle(namep, ino, shortname, SMB_SHORTNAMELEN);
if (smb_strcasecmp(name, shortname, 0) == 0) {
(void) strlcpy(namebuf, namep, buflen);
! rc = 0;
break;
}
}
kmem_free(buf, SMB_UNMANGLE_BUFSIZE);
! return (rc);
}