smbfs_vnops.c revision 42d159821800ff240cc201c8fe07f575b9e8a62b
6029a2d88c01674debfd7c2e16c941a97302b739susans * Copyright (c) 2000-2001 Boris Popov
6029a2d88c01674debfd7c2e16c941a97302b739susans * All rights reserved.
6029a2d88c01674debfd7c2e16c941a97302b739susans * Redistribution and use in source and binary forms, with or without
6029a2d88c01674debfd7c2e16c941a97302b739susans * modification, are permitted provided that the following conditions
6029a2d88c01674debfd7c2e16c941a97302b739susans * 1. Redistributions of source code must retain the above copyright
6029a2d88c01674debfd7c2e16c941a97302b739susans * notice, this list of conditions and the following disclaimer.
6029a2d88c01674debfd7c2e16c941a97302b739susans * 2. Redistributions in binary form must reproduce the above copyright
6029a2d88c01674debfd7c2e16c941a97302b739susans * notice, this list of conditions and the following disclaimer in the
6029a2d88c01674debfd7c2e16c941a97302b739susans * documentation and/or other materials provided with the distribution.
6029a2d88c01674debfd7c2e16c941a97302b739susans * 3. All advertising materials mentioning features or use of this software
6029a2d88c01674debfd7c2e16c941a97302b739susans * must display the following acknowledgement:
6029a2d88c01674debfd7c2e16c941a97302b739susans * This product includes software developed by Boris Popov.
6029a2d88c01674debfd7c2e16c941a97302b739susans * 4. Neither the name of the author nor the names of any co-contributors
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * may be used to endorse or promote products derived from this software
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * without specific prior written permission.
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * SUCH DAMAGE.
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * $Id: smbfs_vnops.c,v 1.128.36.1 2005/05/27 02:35:28 lindak Exp $
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * Use is subject to license terms.
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * We assign directory offsets like the NFS client, where the
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * offset increments by _one_ after each directory entry.
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * Further, the entries "." and ".." are always at offsets
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * zero and one (respectively) and the "real" entries from
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * the server appear at offsets starting with two. This
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * macro is used to initialize the n_dirofs field after
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * setting n_dirseq with a _findopen call.
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * These characters are illegal in NTFS file names.
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * Careful! The check in the XATTR case skips the
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * first character to allow colon in XATTR names.
80679406044c8c1f2c45b5b5f129768d4f5ca59dydstatic const char illegal_chars[] = {
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * Turning this on causes nodes to be created in the cache
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * during directory listings, normally avoiding a second
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * OtW attribute fetch just after a readdir.
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd/* local static function defines */
80679406044c8c1f2c45b5b5f129768d4f5ca59dydstatic int smbfslookup_cache(vnode_t *, char *, int, vnode_t **,
80679406044c8c1f2c45b5b5f129768d4f5ca59dydstatic int smbfslookup(vnode_t *dvp, char *nm, vnode_t **vpp, cred_t *cr,
80679406044c8c1f2c45b5b5f129768d4f5ca59dydstatic int smbfsrename(vnode_t *odvp, char *onm, vnode_t *ndvp, char *nnm,
80679406044c8c1f2c45b5b5f129768d4f5ca59dydstatic int smbfssetattr(vnode_t *, struct vattr *, int, cred_t *);
80679406044c8c1f2c45b5b5f129768d4f5ca59dydstatic int smbfs_readvdir(vnode_t *vp, uio_t *uio, cred_t *cr, int *eofp,
80679406044c8c1f2c45b5b5f129768d4f5ca59dydstatic void smbfs_rele_fid(smbnode_t *, struct smb_cred *);
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * These are the vnode ops routines which implement the vnode interface to
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * the networked file system. These routines just take their parameters,
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * make them look networkish by putting the right info into interface structs,
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * and then calling the appropriate remote routine(s) to do the work.
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * Note on directory name lookup cacheing: If we detect a stale fhandle,
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * we purge the directory cache relative to that vnode. This way, the
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * user won't get burned by the cache repeatedly. See <smbfs/smbnode.h> for
80679406044c8c1f2c45b5b5f129768d4f5ca59dyd * more details on smbnode locking.
80679406044c8c1f2c45b5b5f129768d4f5ca59dydstatic int smbfs_open(vnode_t **, int, cred_t *, caller_context_t *);
80679406044c8c1f2c45b5b5f129768d4f5ca59dydstatic int smbfs_close(vnode_t *, int, int, offset_t, cred_t *,
80679406044c8c1f2c45b5b5f129768d4f5ca59dydstatic int smbfs_read(vnode_t *, struct uio *, int, cred_t *,
80679406044c8c1f2c45b5b5f129768d4f5ca59dydstatic int smbfs_write(vnode_t *, struct uio *, int, cred_t *,
80679406044c8c1f2c45b5b5f129768d4f5ca59dydstatic int smbfs_ioctl(vnode_t *, int, intptr_t, int, cred_t *, int *,
80679406044c8c1f2c45b5b5f129768d4f5ca59dydstatic int smbfs_getattr(vnode_t *, struct vattr *, int, cred_t *,
80679406044c8c1f2c45b5b5f129768d4f5ca59dydstatic int smbfs_setattr(vnode_t *, struct vattr *, int, cred_t *,
80679406044c8c1f2c45b5b5f129768d4f5ca59dydstatic int smbfs_access(vnode_t *, int, int, cred_t *, caller_context_t *);
80679406044c8c1f2c45b5b5f129768d4f5ca59dydstatic int smbfs_fsync(vnode_t *, int, cred_t *, caller_context_t *);
int *, pathname_t *);
vsecattr_t *);
caller_context_t *, int);
caller_context_t *, int);
caller_context_t *, int);
caller_context_t *);
caller_context_t *);
caller_context_t *);
caller_context_t *);
int noop_vnodeop() {
int oldgenid;
int tmperror;
int error = 0;
return (EIO);
return (EIO);
return (EACCES);
return (EINTR);
goto out;
if (error != 0)
goto out;
goto have_fid;
int upgrade = 0;
if (!upgrade) {
goto have_fid;
if (error)
goto out;
if (tmperror)
if (oldcr)
out:
return (error);
return (EIO);
* user's file_t before the closef call (fio.c).
int error;
error = 0;
case VDIR:
case VREG:
if (error) {
int error;
return (EIO);
return (EIO);
return (EISDIR);
return (EINVAL);
return (error);
past_eof = 0;
return (EINTR);
return (error);
return (EIO);
return (EIO);
return (EISDIR);
return (error);
return (EINVAL);
return (EFBIG);
past_limit = 0;
return (EINTR);
if (error == 0) {
return (error);
int error;
return (EIO);
return (EIO);
switch (cmd) {
case _FIOFFS:
case _FIOGDIO:
case _FIOSDIO:
error = 0;
case _FIODIRECTIO:
case SMBFSIO_GETSD:
case SMBFSIO_SETSD:
return (error);
return (EIO);
return (EIO);
/* smbfsgetattr() in smbfs_client.c */
int error;
return (EIO);
return (EIO);
return (EINVAL);
return (EROFS);
if (error)
return (error);
if (error)
return (error);
if (error != 0) {
int error = 0;
unsigned short fid;
int have_fid = 0;
return (EINTR);
rights |=
rights |=
if (error) {
goto out;
if (error) {
if (error) {
out:
if (modified) {
if (have_fid) {
if (cerror)
return (error);
int shift = 0;
return (EROFS);
return (EACCES);
if (mode == 0)
return (EIO);
return (EIO);
int error = 0;
return (EIO);
return (EIO);
return (EINTR);
return (error);
case VNON:
case VDIR:
case VREG:
int error;
return (EPERM);
return (EIO);
return (EINVAL);
return (error);
return (EINTR);
return (error);
int error;
const char *ill;
int rplen;
#ifdef NOT_YET
if (nmlen == 0) {
return (ENOTDIR);
if (error)
return (error);
return (ENAMETOOLONG);
return (EINVAL);
return (error);
while (--rplen >= 0) {
if (rplen <= 0) {
if (cache_ok) {
if (error)
return (error);
if (error)
goto out;
if (error)
goto out;
out:
return (error);
#ifdef DEBUG
int smbfs_lookup_cache_calls = 0;
int smbfs_lookup_cache_error = 0;
int smbfs_lookup_cache_miss = 0;
int smbfs_lookup_cache_stale = 0;
int smbfs_lookup_cache_hits = 0;
int error;
char sep;
#ifdef DEBUG
if (error) {
#ifdef DEBUG
return (error);
#ifdef DEBUG
#ifdef DEBUG
#ifdef DEBUG
int error;
int cerror;
#ifdef NOT_YET
int xattr;
return (EPERM);
return (EIO);
return (EINVAL);
if (nmlen == 0) {
return (EISDIR);
return (EINTR);
if (error == 0) {
goto out;
if (error) {
goto out;
if (error) {
goto out;
#ifdef NOT_YET
goto out;
if (error)
goto out;
if (error)
goto out;
if (error)
goto out;
if (!error) {
if (cerror)
if (error)
goto out;
if (error)
goto out;
error = 0;
out:
return (error);
int flags)
int error;
return (EPERM);
return (EIO);
return (EINTR);
if (error)
goto out;
if (error)
goto out;
goto out;
switch (error) {
case ENOENT:
case ENOTDIR:
out:
return (error);
return (EPERM);
return (EIO);
int error;
int nvp_locked = 0;
return (EINVAL);
return (EXDEV);
return (EINTR);
return (EINTR);
return (EINTR);
return (EINTR);
if (error)
goto out;
if (error)
goto out;
if (error)
goto out;
if (!error) {
goto out;
goto out;
error = 0;
goto out;
goto out;
goto out;
goto out;
goto out;
switch (error) {
case ENOENT:
case ENOTDIR:
if (error)
goto out;
nvp_locked = 0;
if (error == 0)
out:
if (nvp) {
if (nvp_locked)
if (ovp)
return (error);
return (EPERM);
return (EIO);
return (EEXIST);
return (EINVAL);
return (EINTR);
if (error)
goto out;
if (error)
goto out;
if (error)
goto out;
if (error)
goto out;
error = 0;
out:
return (error);
int vp_locked = 0;
int error;
return (EPERM);
return (EIO);
return (EINTR);
if (error)
goto out;
if (error)
goto out;
goto out;
goto out;
goto out;
goto out;
switch (error) {
case ENOENT:
case ENOTDIR:
if (error)
goto out;
out:
if (vp) {
if (vp_locked)
return (error);
int error = 0;
return (EIO);
return (EIO);
if (error)
return (error);
return (EINTR);
return (error);
return (EBADF);
return (EINVAL);
return (EINVAL);
error = 0;
goto out;
if (error) {
if (error)
goto out;
if (error) {
goto out;
if (error != 0)
goto out;
if (error != 0)
goto out;
if (smbfs_fastlookup) {
if (error)
goto out;
out:
error = 0;
if (eofp)
return (error);
if (!write_lock) {
return (V_WRITELOCK_FALSE);
return (V_WRITELOCK_TRUE);
return (EPERM);
return (EIO);
if (*noffp < 0)
return (EINVAL);
return (EIO);
return (ENOSYS);
int error;
return (EIO);
return (EIO);
return (EINVAL);
if (!error) {
return (error);
return (error);
return (EIO);
return (EIO);
switch (cmd) {
case _PC_FILESIZEBITS:
case _PC_LINK_MAX:
case _PC_ACL_ENABLED:
*valp = 0;
case _PC_XATTR_EXISTS:
return (EINVAL);
case _PC_TIMESTAMP_RESOLUTION:
int error;
return (EIO);
return (EIO);
if (mask == 0)
return (ENOSYS);
return (error);
int error;
return (EIO);
return (EIO);
if (mask == 0)
return (ENOSYS);
return (EROFS);
if (error != 0)
return (error);
return (error);
return (EIO);
return (ENOSYS);