/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (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 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* Simple nfs V3 ops
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include "clnt.h"
#include <errno.h>
#include "nfs_inet.h"
#include <sys/bootdebug.h>
#include "brpc.h"
#include <rpcsvc/nfs_prot.h>
/*
* NFS Version 3 specific functions
*/
{
static int blks_read;
buf_offset = buf;
/* Optimize for reads of less than one block size */
if (nfs_readsize == 0)
if (size < nfs_readsize)
else
do {
/* use the user's buffer to stuff the data into. */
/*
* Handle the case where the file does not end
* on a block boundary.
*/
do {
if (read_stat == RPC_TIMEDOUT) {
dprintf("NFS read(%d) timed out. Retrying...\n",
/*
* If the remote is there and trying to respond,
* but our stack is having trouble reassembling
* the reply, reduce the read size in an
* attempt to compensate. Reset the
* transmission and reply wait timers.
*/
framing_errs++;
if (framing_errs > NFS_MAX_FERRS &&
nfs_readsize /= 2;
dprintf("NFS Read size now %d.\n",
framing_errs = 0;
} else {
else
/* default RPC */
}
}
} while (read_stat == RPC_TIMEDOUT);
if (read_stat != RPC_SUCCESS)
return (-1);
return (-1);
/*
* If we are at EOF, update counts and exit
*/
/*
* Handle the case where the file is smaller than
* the size of the read request, thus the request
* couldn't be completely filled.
*/
#ifdef NFS_OPS_DEBUG
printf("nfs3read(): partial read %d"
" instead of %d\n",
#endif
}
/* update various offsets */
buf_offset += readcnt;
/*
* round and round she goes (though not on every block..
* - OBP's take a fair bit of time to actually print stuff)
*/
if ((blks_read++ & 0x3) == 0)
return (count);
}
int
{
if (getattr_stat != RPC_SUCCESS) {
return (-1);
}
return (getattr_res.status);
}
else
}
}
}
}
return (NFS3_OK);
}
/*
* Display nfs error messages.
*/
/*ARGSUSED*/
void
{
return;
switch (status) {
case NFS3_OK:
printf("NFS: No error.\n");
break;
case NFS3ERR_PERM:
printf("NFS: Not owner.\n");
break;
case NFS3ERR_NOENT:
#ifdef NFS_OPS_DEBUG
printf("NFS: No such file or directory.\n");
#endif /* NFS_OPS_DEBUG */
break;
case NFS3ERR_IO:
printf("NFS: IO ERROR occurred on NFS server.\n");
break;
case NFS3ERR_NXIO:
printf("NFS: No such device or address.\n");
break;
case NFS3ERR_ACCES:
printf("NFS: Permission denied.\n");
break;
case NFS3ERR_EXIST:
printf("NFS: File exists.\n");
break;
case NFS3ERR_XDEV:
printf("NFS: Cross device hard link.\n");
break;
case NFS3ERR_NODEV:
printf("NFS: No such device.\n");
break;
case NFS3ERR_NOTDIR:
printf("NFS: Not a directory.\n");
break;
case NFS3ERR_ISDIR:
printf("NFS: Is a directory.\n");
break;
case NFS3ERR_INVAL:
printf("NFS: Invalid argument.\n");
break;
case NFS3ERR_FBIG:
printf("NFS: File too large.\n");
break;
case NFS3ERR_NOSPC:
printf("NFS: No space left on device.\n");
break;
case NFS3ERR_ROFS:
printf("NFS: Read-only filesystem.\n");
break;
case NFS3ERR_MLINK:
printf("NFS: Too many hard links.\n");
break;
case NFS3ERR_NAMETOOLONG:
printf("NFS: File name too long.\n");
break;
case NFS3ERR_NOTEMPTY:
printf("NFS: Directory not empty.\n");
break;
case NFS3ERR_DQUOT:
printf("NFS: Disk quota exceeded.\n");
break;
case NFS3ERR_STALE:
printf("NFS: Stale file handle.\n");
break;
case NFS3ERR_REMOTE:
printf("NFS: Remote file in path.\n");
break;
case NFS3ERR_BADHANDLE:
printf("NFS: Illegal NFS file handle.\n");
break;
case NFS3ERR_NOT_SYNC:
printf("NFS: Synchronization mismatch.\n");
break;
case NFS3ERR_BAD_COOKIE:
printf("NFS: Stale Cookie.\n");
break;
case NFS3ERR_NOTSUPP:
printf("NFS: Operation is not supported.\n");
break;
case NFS3ERR_TOOSMALL:
printf("NFS: Buffer too small.\n");
break;
case NFS3ERR_SERVERFAULT:
printf("NFS: Server fault.\n");
break;
case NFS3ERR_BADTYPE:
printf("NFS: Unsupported object type.\n");
break;
case NFS3ERR_JUKEBOX:
printf("NFS: Resource temporarily unavailable.\n");
break;
default:
printf("NFS: unknown error.\n");
break;
}
}
struct nfs_file *
{
if (status != RPC_SUCCESS) {
dprintf("lookup: RPC error.\n");
return (NULL);
}
(void) CLNT_FREERES(root_CLIENT,
return (NULL);
}
/*
* Server must supply post_op_attr's
*/
FALSE) {
printf("nfs3lookup: server fails to return post_op_attr\n");
(void) CLNT_FREERES(root_CLIENT,
return (NULL);
}
return (&cd);
}
/*
* Gets symbolic link into pathname.
*/
int
{
/*
* linkres needs a zeroed buffer to place path data into:
*/
if (status != RPC_SUCCESS) {
dprintf("nfs3getsymlink: RPC call failed.\n");
return (-1);
}
}
*path = symlink_path;
return (NFS3_OK);
}