nfs2ops.c revision 4a634bb80136cc001d14ab96addd9915105e5223
/*
* 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 ops - open, close, read, and lseek.
*/
#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 2 specific functions
*/
{
int framing_errs = 0; /* stack errors */
char *buf_offset; /* current buffer offset */
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 &&
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);
/*
* Handle the case where the file is simply empty, and
* nothing could be read.
*/
if (readcnt == 0)
break; /* eof */
/*
* 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("nfsread(): 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
{
enum clnt_stat getattr_stat;
if (getattr_stat != RPC_SUCCESS) {
return (-1);
}
return (getattr_res.status);
}
/* adapted from nattr_to_vattr() in nfs_client.c */
else
}
}
}
}
#ifdef NFS_OPS_DEBUG
printf("nfs_getattr(): done.\n");
#endif
return (getattr_res.status);
}
/*
* Display nfs error messages.
*/
/*ARGSUSED*/
void
{
return;
switch (status) {
case NFSERR_PERM:
printf("NFS: Not owner.\n");
break;
case NFSERR_NOENT:
#ifdef NFS_OPS_DEBUG
printf("NFS: No such file or directory.\n");
#endif /* NFS_OPS_DEBUG */
break;
case NFSERR_IO:
printf("NFS: IO ERROR occurred on NFS server.\n");
break;
case NFSERR_NXIO:
printf("NFS: No such device or address.\n");
break;
case NFSERR_ACCES:
printf("NFS: Permission denied.\n");
break;
case NFSERR_EXIST:
printf("NFS: File exists.\n");
break;
case NFSERR_NODEV:
printf("NFS: No such device.\n");
break;
case NFSERR_NOTDIR:
printf("NFS: Not a directory.\n");
break;
case NFSERR_ISDIR:
printf("NFS: Is a directory.\n");
break;
case NFSERR_FBIG:
printf("NFS: File too large.\n");
break;
case NFSERR_NOSPC:
printf("NFS: No space left on device.\n");
break;
case NFSERR_ROFS:
printf("NFS: Read-only filesystem.\n");
break;
case NFSERR_NAMETOOLONG:
printf("NFS: File name too long.\n");
break;
case NFSERR_NOTEMPTY:
printf("NFS: Directory not empty.\n");
break;
case NFSERR_DQUOT:
printf("NFS: Disk quota exceeded.\n");
break;
case NFSERR_STALE:
printf("NFS: Stale file handle.\n");
break;
case NFSERR_WFLUSH:
printf("NFS: server's write cache has been flushed.\n");
break;
default:
printf("NFS: unknown error.\n");
break;
}
}
struct nfs_file *
{
if (status != RPC_SUCCESS) {
dprintf("lookup: RPC error.\n");
return (NULL);
}
return (NULL);
}
return (&cd);
}
/*
* Gets symbolic link into pathname.
*/
int
{
struct readlinkres linkres;
static char symlink_path[NFS_MAXPATHLEN];
/*
* linkres needs a zeroed buffer to place path data into:
*/
if (status != RPC_SUCCESS) {
dprintf("nfsgetsymlink: RPC call failed.\n");
return (-1);
}
}
return (NFS_OK);
}