smbfs_node.c revision 91d632c867159b669d90fc7e172295433d0519ef
/*
* Copyright (c) 2000-2001 Boris Popov
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Boris Popov.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: smbfs_node.c,v 1.54.52.1 2005/05/27 02:35:28 lindak Exp $
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <sys/sysmacros.h>
#ifdef APPLE
#include <sys/smb_apple.h>
#else
#include <netsmb/smb_osdep.h>
#endif
#include <netsmb/smb_conn.h>
#include <netsmb/smb_subr.h>
#include <smbfs/smbfs_node.h>
#include <smbfs/smbfs_subr.h>
#define SMBFS_NAME_DEBUG
#endif
/*
* Lack of inode numbers leads us to the problem of generating them.
* with inode numbers generated from the incremented by one counter.
* However this way will require too much kernel memory, gives all
* sorts of locking and consistency problems, not to mentinon counter
* overflows. So, I'm decided to use a hash function to generate
* pseudo random (and [often?] unique) inode numbers.
*/
/* Magic constants for name hashing. */
{
uint32_t v;
v *= FNV_32_PRIME;
}
return (v);
}
{
uint32_t v;
return (v);
}
/*
* This is basically a hash of the full path name, but
* computed without having the full path contiguously.
* The path building logic needs to match what
* smbfs_fullpath does.
*
* Note that smbfs_make_node computes inode numbers by
* calling smbfs_hash on the full path name. This will
* compute the same result given the directory path and
* the last component separately.
*/
{
/* Start with directory hash */
/*
* If not the root, hash a slash.
*/
/* Now hash this component. */
return (ino);
}
char *
{
char *cp;
#ifdef SMBFS_NAME_DEBUG
/*
* Note: The passed length is strlen(name),
* and does NOT include the terminating nul.
* Allocated space holds: (in order)
* (int)strlen
* char 0xFC (1st marker)
* copy of string
* terminating null
* char 0xFE (2nd marker)
*/
/*LINTED*/
cp += sizeof (int);
cp++;
#else
#endif
return (cp);
}
/*
* Note: Passed length does NOT include the nul,
* the same as with smbfs_name_alloc().
*/
void
{
#ifdef SMBFS_NAME_DEBUG
int lnmlen;
char *cp;
/*
* See comment in smbfs_name_alloc
* about the layout of this memory.
*/
cp--;
debug_enter("smbfs_name_free: name[-1] != 0xFC");
}
cp -= sizeof (int);
/*LINTED*/
debug_enter("smbfs_name_free: name[-5] != nmlen");
}
debug_enter("smbfs_name_free: name[nmlen+1] != 0xFE");
}
#else
#endif
}
/*
* smbfs_nget()
*
* NOTES:
*
* It would be nice to be able to pass in a flag when the caller is sure
* that the node does not exist and should just be allocated.
*/
int
{
char sep;
/* Don't expect "." or ".." here anymore. */
DEBUG_ENTER("smbfs_nget: name is '.' or '..'");
return (EINVAL);
}
/*
* See the comment near the top of smbfs_xattr.c about
* the logic for what separators to use where.
*/
/* Find or create the node. */
/*
* We always have a vp now, because
* smbfs_make_node / make_smbnode
* calls kmem_alloc with KM_SLEEP.
*/
/*
* Files in an XATTR dir are also XATTR.
*/
}
#ifdef NOT_YET
/* update the attr_cache info if the file is clean */
/* add entry to DNLC */
}
#endif /* NOT_YET */
/* BSD symlink hack removed (smb_symmagic) */
#ifdef NOT_YET
#endif /* NOT_YET */
return (0);
}
/*
* routines to maintain vnode attributes cache
* smbfs_attr_cacheenter: unpack np.i to vnode_vattr structure
*
* Note that some SMB servers do not exhibit POSIX behaviour
* with regard to the mtime on directories. To work around
* this, we never allow the mtime on a directory to go backwards,
* and bump it forwards elsewhere to simulate the correct
* behaviour.
*/
void
{
int vtype;
SMBVDEBUG("vtype change %d to %d\n",
/*
* Had Darwin ubc_sync_range call here,
* invalidating the truncated range.
* XXX: Solaris equivalent?
*/
SMBVDEBUG("Update size?\n");
}
/*
* Don't allow mtime to go backwards.
* Yes this has its flaws. Better ideas are welcome!
*/
/*CSTYLED*/
goto out;
gethrestime(&ts);
out:
}
int
{
/*
* Determine attrtimeo. It will be something between SMB_MINATTRTIMO and
* SMB_MAXATTRTIMO where recently modified files have a short timeout
* and files that haven't been modified in a long time have a long
* timeout. This is the same algorithm used by NFS.
*/
gethrestime(&ts);
if (attrtimeo < SMB_MINATTRTIMO) {
} else if (attrtimeo > SMB_MAXATTRTIMO)
/* has too much time passed? */
return (ENOENT);
if (!vap)
return (0);
case VREG:
break;
case VLNK:
break;
case VDIR:
break;
default:
return (EINVAL);
}
#ifdef APPLE
/* XXX: Can this block? Drop r_statelock? */
}
}
#endif /* APPLE */
}
}
else /* symlink and regular file */
}
return (0);
}
/*
* Some SMB servers don't exhibit POSIX behaviour with regard to
* updating the directory mtime when the directory's contents
* change.
*
* We force the issue here by updating our cached copy of the mtime
* whenever we perform such an action ourselves, and then mark the
* cache invalid. Subsequently when the invalidated cache entry is
* updated, we disallow an update that would move the mtime backwards.
*
* This preserves correct or near-correct behaviour with a
* compliant server, and gives near-correct behaviour with
* a non-compliant server in the most common case (we are the
* only client changing the directory).
*
* There are also complications if a server's time is ahead
* of our own. We must 'touch' a directory when it is first
* created, to ensure that the timestamp starts out sane,
* however it may have a timestamp well ahead of the 'touch'
* point which will be returned and cached the first time the
* directory's attributes are fetched. Subsequently, the
* directory's mtime will not appear to us to change at all
* until our local time catches up to the server.
*
* Thus, any time a directory is 'touched', the saved timestamp
* must advance at least far enough forwards to be visible to
* the stat(2) interface.
*
* XXX note that better behaviour with non-compliant servers
* could be obtained by bumping the mtime forwards when
* an update for an invalidated entry returns a nonsensical
* mtime.
*/
void
{
/*
* XXX - not sure about this...
* Creep the saved time forwards far enough that
* layers above the kernel will notice.
*/
/*
* If the current time is later than the updated
* saved time, apply it instead.
*/
gethrestime(&ts);
/*CSTYLED*/
/*
* Invalidate the cache, so that we go to the wire
* to check that the server doesn't have a better
* timestamp next time we care.
*/
}