vold_node.c revision 7a899e493f14afd2d33429677595b4f06475153e
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <rpc/auth_unix.h>
#include <rpcsvc/nfs_prot.h>
#include <locale.h>
#include "vold.h"
struct internal_fh {
/* must be 12 bytes! */
};
static struct q fh_q_hash[FH_HASH_SIZE];
/* extern functions */
/*
* Expose this node to partition.c to compensate
* for poor method factoring in node_findlabel(), which
* has been replaced by find_vvnode_in_db() in partition.c
*/
/* local functions */
static void node_updtime(vvnode_t *);
/* local variables */
/* global var */
#define TMPID_BASE 0x8000000000000000ull
/* default symlink attributes */
#define DEFAULT_SYMLINK_UID 0
#define DEFAULT_SYMLINK_GID 0
#define DEFAULT_SYMLINK_MODE 0777
{
}
return (res);
}
vvnode_t *
node_lookup(char *path)
{
char **sp;
int i;
db_root();
}
for (i = 0; sp[i]; i++) {
break;
}
}
break;
}
}
return (vn);
}
/*
* make a name unique by adding a "#%d", with numbers starting from 1,
* and going ... forever? XXX
*/
static void
{
int iter = 1;
/*CONSTCOND*/
while (1) {
break;
}
}
/*
* The new name is a good one (none others like it),
* give it to the object. Of course, this only applies
* to the "add" operation, because otherwise, we'd have
* to do a change_name().
*/
return;
}
}
/*NOTREACHED*/
}
/*
* given a parent vvnode "dvn" and an object "obj", create a new vvnode
* based on the object
*/
vvnode_t *
{
*err = 0; /* initialize to "no error" */
/*
* Give us the "directory" string.
*/
/* not under the volmgt root (e.g. "/vol") */
} else {
}
}
}
break;
}
}
/*
* If the proposed name is already in the name space,
* and we've been asked to fix it, change the name.
*/
*err = 0;
}
if (*err) {
return (vn);
}
/*
* Adding into the database only fails if there is
* something already there. This will only happen
* with networked databases where someone adds a name
* and we haven't seen it yet.
*/
return (NULL);
}
}
/*
* Allocate the vvnode and link it into the list.
*/
} else {
}
case VV_BLK:
case VV_CHR:
} else {
} else {
}
}
break;
default:
break;
}
}
/* twining code */
}
}
}
/*
* We remember a few of the vvnodes to make some operations
* easier, and set up top level twins.
*/
if (rdskroot) {
}
if (dskroot) {
}
/*
* block tapes a no brainer in the future.
*/
if (mtroot) {
}
if (rmtroot) {
}
}
}
/*
* partitions, what a joy.
*/
case VV_BLK:
case VV_CHR:
case VV_LINK:
}
}
break;
default:
break;
}
/*
* Give this vvnode a file handle
*/
return (vn);
}
/*
* make a symlink, with parent "dvn", named "name", pointing to "to"
*/
vvnode_t *
{
/* XXX: blow off size */
/* create the "symlink" structure */
/* if no attributes were passed in, create our own */
}
} else {
}
} else {
}
} else {
}
} else {
}
} else {
}
if (err) {
return (NULL);
}
return (vn);
}
{
#ifdef notdef
/* why is this not done ?? (wld) */
#endif
}
if (err) {
return (FALSE);
}
return (TRUE);
}
/*
* This removes all flavors of an object from the hierarchy,
* the file handle hash, and (optionally) from the database.
*/
void
{
*err = 0;
/* can't remove a volume thats in a drive */
if (v->v_confirmed) {
return;
}
}
if (dbup) {
return;
}
}
}
}
}
}
/*
* This just takes a vvnode off whatever list it might be
* on and frees it.
*/
void
{
/* get rid of these partitions */
}
}
/* remove this node from its parent's list */
/* it's the first node on it's parent list */
} else {
/* scan for where we are on our parent's list */
/* found us */
break;
}
}
if (lvn) {
} else {
/* we weren't on our parens list! */
dbxtrap("unlink");
return;
}
}
}
/*
* if we're changing directories
* update o_dir
* if we're changing names
* change the name of the object
* update the database
* if we're changing directories
* unlink it from the current directory
* link it into the new directory
* if we're changing names
* change it's name everywhere.
*/
{
static void node_rename(vvnode_t *, char *);
extern void dev_rename(vol_t *);
char *special;
char *path;
char *specpath;
}
}
}
if (oname) {
}
if (odir) {
}
return (FALSE);
}
/*
* cool, the database is updated and all we have to do
* is move around the local data structures...
*/
/* changing the directory */
if (odir) {
}
}
/* changing the name */
if (oname) {
}
}
/*
* tell the dev stuff this has been renamed so
* aliases can be take care of (if necessary).
*/
}
}
}
}
return (TRUE);
}
/*
* Update the names of all children after we've moved a directory.
*/
static void
{
char namebuf[MAXPATHLEN];
}
}
}
/*
* Move a vvnode from one directory to another.
*/
static void
{
/* remove it from the old directory */
} else {
break;
}
}
if (lvn) {
} else {
dbxtrap("dirmove");
return;
}
}
/* add it to the new directory */
}
/*
* This is when we are calling an object something different. It
* just changes the name. It doesn't try to move it.
*/
static void
{
char *path;
char *special;
if (special) {
}
}
}
{
#ifdef DEBUG_NFS
#endif
if (fattr) {
}
goto dun;
}
if (fattr) {
}
goto dun;
}
if (fattr) {
}
goto dun;
}
}
res = NFSERR_NOENT;
dun:
#ifdef DEBUG_NFS
#endif
return (res);
}
static mode_t
node_mapmode(vol_t *v)
{
}
}
/*
* produce the file attributes for a given vnode.
*/
void
{
}
case VV_DIR:
break;
case VV_BLK:
case VV_CHR:
} else {
}
#ifdef DEBUG
debug(11,
#endif
#ifdef DEBUG
#endif
}
else {
}
break;
case VV_PART:
/*
* When a volume turns into a directory, we save the
* vn_type into vn_otype so that later we can come
* along and tell whether its a block or character.
*/
} else {
"node_fattr: partition in non-volume!!\n"));
}
}
else {
}
break;
case VV_SYMLINK:
break;
case VV_LINK: {
/* for now, just return the links attrs... */
break;
}
/* recurse on the new object */
return;
}
default:
break;
}
sizeof (struct nfstime));
sizeof (struct nfstime));
sizeof (struct nfstime));
}
void
{
/*
* Clean all our update flags
*/
return;
}
}
}
/*
* This function marks all nodes from a particular database
* as "seen". Databases that do not provide consistency with
* others will use this function on lookup.
*/
void
{
/*
* Set all the update flags for a particular database.
*/
}
}
}
void
{
/*
* Check all our update flags
*/
return;
}
/*
* if we didn't see it between startupdate and
* now, just axe it
*/
/*
* We start over again because the act of
* doing a node_remove could waste several
* things.
*/
}
}
}
vvnode_t *
{
vol_t *v;
char namebuf[MAXPATHLEN];
/* can we find an entry in the database ?? */
if (v == NULL) {
/* no entry found -- make an entry and leave */
goto dun;
}
/* see if we can find any already existing node */
/* XXX: why would node_findnode() fail above ?? */
(void) node_lookup(namebuf);
}
}
break;
}
}
/* check to see if this volume has already been seen */
if (v->v_confirmed) {
noise("%s named %s already exists in a drive\n",
/* returning null means the volume will get ejected */
}
}
dun:
return (vn);
}
dirat_t *
{
return (da);
}
/*
* find a node with a specific "id", "off", and "dir".
* If either dir or off == FN_ANY, they are treated as a wildcard,
* and will match all dir's and off's.
*
* NOTE: argument "off" is not used (wld)
*/
/*ARGSUSED*/
struct vnwrap *
{
struct internal_fh *ifh;
while (vn) {
/*LINTED: alignment ok*/
sizeof (struct vnwrap));
}
}
return (vw);
}
void
{
while (vw) {
}
}
static void
{
register struct internal_fh *ifh =
/*LINTED: alignment ok*/
static time_t t;
/*
* If the id is not the root directory (always id 1)
* Add in a random number to solve the restart
* problem.
*/
if (t == 0) {
(void) time(&t);
}
} else {
}
}
static void
{
register struct internal_fh *ifh =
/*LINTED: alignment ok*/
}
static void
stale(void)
{
/* do nothing */
}
vvnode_t *
{
struct internal_fh *vifh;
/*LINTED: alignment ok*/
/* find out which hash line will this filehandle go in */
/* scan through hash list of vvnodes for match (for this hash line) */
/*LINTED: alignment ok*/
return (vn); /* this vvnode matches */
}
}
#ifdef DEBUG
debug(11,
"node_fhtovn: ESTALE: fh=[0x%llx/%#o/%#o/%#o]\n",
#endif
stale();
return ((struct vvnode *)0);
}
{
register struct internal_fh *ifh =
/*LINTED: alignment ok*/
/*LINTED: alignment ok*/
}
/*
* Ok, well this is a bit of a hack. The file id
* isn't really useful to NFS, as it really uses
* the file handle. The file id can only be 32
* bits, and our id's are 63 bits. This hack just
* returns a fid that is probably different from
* other real allocated fids.
*/
}
/* not a temp id */
}
/*
* If the "core" objects aren't set up by the database, it
* means that we're blank. Initialize the "core" objects.
*/
void
node_setup(void)
{
}
void
{
vn->vn_dirtype = 0;
/*
* We turn off the tmp bits here so that
* root can remain accessable even if we crashed.
*/
}
}
/*
* update the times of the pointed-to node
*/
static void
{
}