Remove the unmaintained University of Michigan NFSv4 client from 8.x

prior to 8.0-RELEASE.  Rick Macklem's new and more feature-rich NFSv234
client and server are replacing it.

Discussed with:	rmacklem
This commit is contained in:
Robert Watson 2009-05-22 12:35:12 +00:00
parent 9ce13065db
commit 86ce6a83d1
48 changed files with 19 additions and 11185 deletions

View File

@ -1,18 +0,0 @@
#!/bin/sh
#
# $FreeBSD$
#
# PROVIDE: idmapd
# REQUIRE: rpcbind
# KEYWORD: nojail shutdown
. /etc/rc.subr
name="idmapd"
load_rc_config $name
rcvar="idmapd_enable"
command="${idmapd:-/sbin/${name}}"
eval ${name}_flags=\"${idmapd_flags}\"
run_rc_command "$1"

View File

@ -36,7 +36,6 @@ SUBDIR= adjkerntz \
ggate \
growfs \
gvinum \
idmapd \
ifconfig \
init \
${_ipf} \

View File

@ -1,11 +0,0 @@
# @(#)Makefile 8.2 (Berkeley) 3/27/94
#
# $FreeBSD$
PROG= idmapd
MAN= idmapd.8
CFLAGS+= -DNFS -I${.CURDIR}/../../sys
WARNS?= 2
.include <bsd.prog.mk>

View File

@ -1,63 +0,0 @@
.\" copyright (c) 2003
.\" the regents of the university of michigan
.\" all rights reserved
.\"
.\" permission is granted to use, copy, create derivative works and redistribute
.\" this software and such derivative works for any purpose, so long as the name
.\" of the university of michigan is not used in any advertising or publicity
.\" pertaining to the use or distribution of this software without specific,
.\" written prior authorization. if the above copyright notice or any other
.\" identification of the university of michigan is included in any copy of any
.\" portion of this software, then the disclaimer below must also be included.
.\"
.\" this software is provided as is, without representation from the university
.\" of michigan as to its fitness for any purpose, and without warranty by the
.\" university of michigan of any kind, either express or implied, including
.\" without limitation the implied warranties of merchantability and fitness for
.\" a particular purpose. the regents of the university of michigan shall not be
.\" liable for any damages, including special, indirect, incidental, or
.\" consequential damages, with respect to any claim arising out of or in
.\" connection with the use of the software, even if it has been or is hereafter
.\" advised of the possibility of such damages.
.\"
.\" $FreeBSD$
.\"
.Dd October 15, 2006
.Dt IDMAPD 8
.Os
.Sh NAME
.Nm idmapd
.Nd name/UID mapper for NFSv4
.Sh SYNOPSIS
.Nm
.Op Fl v
.Op Fl d Ar domainname
.Sh DESCRIPTION
The
.Nm
daemon normally runs in the background and services UID/GID-to-name and
name-to-UID/GID mapping
requests from the NFSv4 client kernel threads.
.Pp
The options are:
.Bl -tag -width indent
.It Fl d
Set the domain part of the name string to the specified string.
.It Fl v
Be verbose, and do not run in the background.
.El
.Sh FILES
.Bl -tag -width ".Pa /etc/master.passwd" -compact
.It Pa /etc/pwd.db
The insecure password database file.
.It Pa /etc/spwd.db
The secure password database file.
.It Pa /etc/master.passwd
The current password file.
.It Pa /etc/passwd
A Version 7 format password file.
.El
.Sh SEE ALSO
.Xr getpwnam 3 ,
.Xr getpwuid 3 ,
.Xr mount_nfs4 8

View File

@ -1,418 +0,0 @@
/* $FreeBSD$ */
/* $Id: idmapd.c,v 1.5 2003/11/05 14:58:58 rees Exp $ */
/*
* copyright (c) 2003
* the regents of the university of michigan
* all rights reserved
*
* permission is granted to use, copy, create derivative works and redistribute
* this software and such derivative works for any purpose, so long as the name
* of the university of michigan is not used in any advertising or publicity
* pertaining to the use or distribution of this software without specific,
* written prior authorization. if the above copyright notice or any other
* identification of the university of michigan is included in any copy of any
* portion of this software, then the disclaimer below must also be included.
*
* this software is provided as is, without representation from the university
* of michigan as to its fitness for any purpose, and without warranty by the
* university of michigan of any kind, either express or implied, including
* without limitation the implied warranties of merchantability and fitness for
* a particular purpose. the regents of the university of michigan shall not be
* liable for any damages, including special, indirect, incidental, or
* consequential damages, with respect to any claim arising out of or in
* connection with the use of the software, even if it has been or is hereafter
* advised of the possibility of such damages.
*/
/* XXX ignores the domain of received names. */
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/syscall.h>
#include <sys/errno.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/queue.h>
#include <nfs4client/nfs4_dev.h>
#include <nfs4client/nfs4_idmap.h>
#include <stdio.h>
#include <fcntl.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#define DEV_PATH "/dev/nfs4"
#define DOMAIN "@FreeBSD.org"
#define BADUSER "nobody"
#define BADGROUP "nogroup"
#define BADUID 65534
#define BADGID 65533
struct idmap_e {
struct nfs4dev_msg msg;
TAILQ_ENTRY(idmap_e) next;
};
int fd, verbose;
char *domain = DOMAIN;
TAILQ_HEAD(, idmap_e) upcall_q;
#define add_idmap_e(E) do { \
assert(E != NULL); \
TAILQ_INSERT_TAIL(&upcall_q, E, next); \
} while(0)
#define remove_idmap_e(E) do { \
assert(E != NULL && !TAILQ_EMPTY(&upcall_q)); \
E = TAILQ_FIRST(&upcall_q); \
TAILQ_REMOVE(&upcall_q, E, next); \
} while(0)
#define get_idmap_e(E) do { \
if ((E = (struct idmap_e *) malloc(sizeof(struct idmap_e))) == NULL) {\
fprintf(stderr, "get_idmap_e(): error in malloc\n");\
} } while(0)
#define put_idmap_e(E) free(E)
/* from marius */
int
validateascii(char *string, u_int32_t len)
{
int i;
for (i = 0; i < len; i++) {
if (string[i] == '\0')
break;
if (string[i] & 0x80)
return (-1);
}
if (string[i] != '\0')
return (-1);
return (i + 1);
}
char *
idmap_prune_domain(struct idmap_msg * m)
{
size_t i;
size_t len;
char * ret = NULL;
if (m == NULL)
return NULL;
len = m->id_namelen;
if (validateascii(m->id_name, len) < 0) {
fprintf(stderr, "msg has invalid ascii\n");
return NULL;
}
for (i=0; i < len && m->id_name[i] != '@' ; i++);
ret = (char *)malloc(i+1);
if (ret == NULL)
return NULL;
bcopy(m->id_name, ret, i);
ret[i] = '\0';
return ret;
}
int
idmap_add_domain(struct idmap_msg * m, char * name)
{
size_t len, nlen;
if (m == NULL || name == NULL)
return -1;
len = strlen(name);
nlen = len + strlen(domain);
if (nlen > IDMAP_MAXNAMELEN)
return -1;
bcopy(name, &m->id_name[0], len);
bcopy(domain, &m->id_name[len], strlen(domain));
m->id_name[nlen] = '\0';
m->id_namelen = nlen;
return 0;
}
int
idmap_name(struct idmap_msg * m, char *name)
{
if (m == NULL || name == NULL || m->id_namelen != 0)
return -1;
if (idmap_add_domain(m, name))
return -1;
return 0;
}
int
idmap_id(struct idmap_msg * m, ident_t id)
{
if (m == NULL || m->id_namelen == 0) {
fprintf(stderr, "idmap_id: bad msg\n");
return -1;
}
switch(m->id_type) {
case IDMAP_TYPE_UID:
m->id_id.uid = id.uid;
break;
case IDMAP_TYPE_GID:
m->id_id.gid = id.gid;
break;
default:
return -1;
break;
};
return 0;
}
int
idmap_service(struct idmap_e * e)
{
struct idmap_msg * m;
struct passwd * pwd;
struct group * grp;
ident_t id;
char * name;
if (e == NULL) {
fprintf(stderr, "bad entry\n");
return -1;
}
if (e->msg.msg_vers != NFS4DEV_VERSION) {
fprintf(stderr, "kernel/userland version mismatch! %d/%d\n",
e->msg.msg_vers, NFS4DEV_VERSION);
return -1;
}
if (e->msg.msg_type != NFS4DEV_TYPE_IDMAP) {
fprintf(stderr, "bad type!\n");
return -1;
}
if (e->msg.msg_len != sizeof(struct idmap_msg)) {
fprintf(stderr, "bad message length: %zu/%zu\n", e->msg.msg_len,
sizeof(struct idmap_msg));
return -1;
}
if (verbose)
printf("servicing msg xid: %x\n", e->msg.msg_xid);
m = (struct idmap_msg *)e->msg.msg_data;
if (m->id_namelen != 0 && m->id_namelen != strlen(m->id_name)) {
fprintf(stderr, "bad name length in idmap_msg\n");
return -1;
}
switch (m->id_type) {
case IDMAP_TYPE_UID:
if (m->id_namelen == 0) {
/* id to name */
pwd = getpwuid(m->id_id.uid);
if (pwd == NULL) {
fprintf(stderr, "unknown uid %d!\n",
(uint32_t)m->id_id.uid);
name = BADUSER;
} else
name = pwd->pw_name;
if (idmap_name(m, name))
return -1;
} else {
/* name to id */
name = idmap_prune_domain(m);
if (name == NULL)
return -1;
pwd = getpwnam(name);
if (pwd == NULL) {
fprintf(stderr, "unknown username %s!\n", name);
id.uid = (uid_t)BADUID;
} else
id.uid = pwd->pw_uid;
free(name);
if (idmap_id(m, id))
return -1;
}
break;
case IDMAP_TYPE_GID:
if (m->id_namelen == 0) {
/* id to name */
grp = getgrgid(m->id_id.gid);
if (grp == NULL) {
fprintf(stderr, "unknown gid %d!\n",
(uint32_t)m->id_id.gid);
name = BADGROUP;
} else
name = grp->gr_name;
if (idmap_name(m, name))
return -1;
} else {
/* name to id */
name = idmap_prune_domain(m);
if (name == NULL)
return -1;
grp = getgrnam(name);
if (grp == NULL) {
fprintf(stderr, "unknown groupname %s!\n", name);
id.gid = (gid_t)BADGID;
} else
id.gid = grp->gr_gid;
free(name);
if (idmap_id(m, id))
return -1;
}
break;
default:
fprintf(stderr, "bad idmap type: %d\n", m->id_type);
return -1;
break;
}
return 0;
}
int
main(int argc, char ** argv)
{
int error = 0;
struct idmap_e * entry;
fd_set read_fds, write_fds;
int maxfd;
int ret, ch;
while ((ch = getopt(argc, argv, "d:v")) != -1) {
switch (ch) {
case 'd':
domain = optarg;
break;
case 'v':
verbose = 1;
break;
default:
fprintf(stderr, "usage: %s [-v] [-d domain]\n", argv[0]);
exit(1);
break;
}
}
TAILQ_INIT(&upcall_q);
fd = open(DEV_PATH, O_RDWR, S_IRUSR | S_IWUSR);
if (fd < 0) {
perror(DEV_PATH);
exit(1);
}
if (!verbose)
daemon(0,0);
maxfd = fd;
for (;;) {
struct timeval timo = {1, 0};
do {
FD_ZERO(&read_fds);
FD_ZERO(&write_fds);
FD_SET(fd, &read_fds);
FD_SET(fd, &write_fds);
ret = select(maxfd+1, &read_fds, &write_fds, NULL, &timo);
} while (ret < 0 && errno == EINTR);
if (ret <= 0) {
if (ret != 0)
perror("select");
continue;
}
if (FD_ISSET(fd, &read_fds)) {
for (;;) {
get_idmap_e(entry);
error = ioctl(fd, NFS4DEVIOCGET, &entry->msg);
if (error == -1) {
if (errno != EAGAIN)
perror("get ioctl:");
put_idmap_e(entry);
break;
}
switch (entry->msg.msg_type ) {
case NFS4DEV_TYPE_IDMAP:
if (idmap_service(entry))
entry->msg.msg_error = EIO;
break;
default:
fprintf(stderr, "unknown nfs4dev_msg type\n");
entry->msg.msg_error = EIO;
break;
}
add_idmap_e(entry);
}
}
if (FD_ISSET(fd, &write_fds)) {
while (!TAILQ_EMPTY(&upcall_q)) {
remove_idmap_e(entry);
error = ioctl(fd, NFS4DEVIOCPUT, &entry->msg);
if (error == -1) {
if (errno != EAGAIN)
perror("put ioctl");
break;
}
put_idmap_e(entry);
}
}
}
/* never reached */
exit(1);
}

View File

@ -5,15 +5,13 @@
PROG= mount_nfs
SRCS= mount_nfs.c getmntopts.c mounttab.c
MAN= mount_nfs.8
MLINKS= mount_nfs.8 mount_nfs4.8
MLINKS= mount_nfs.8
MOUNT= ${.CURDIR}/../mount
UMNTALL= ${.CURDIR}/../../usr.sbin/rpc.umntall
CFLAGS+= -DNFS -I${MOUNT} -I${UMNTALL}
WARNS?= 3
LINKS= ${BINDIR}/mount_nfs ${BINDIR}/mount_nfs4
.PATH: ${MOUNT} ${UMNTALL}
.include <bsd.prog.mk>

View File

@ -36,7 +36,7 @@
.Nd mount NFS file systems
.Sh SYNOPSIS
.Nm
.Op Fl 234bcdiLlNPsTU
.Op Fl 23bcdiLlNPsTU
.Op Fl a Ar maxreadahead
.Op Fl D Ar deadthresh
.Op Fl g Ar maxgroups
@ -157,8 +157,6 @@ then version 2).
Note that NFS version 2 has a file size limit of 2 gigabytes.
.It Cm nfsv3
Use the NFS Version 3 protocol.
.It Cm nfsv4
Use the NFS Version 4 protocol.
.It Cm noconn
For UDP mount points, do not do a
.Xr connect 2 .
@ -303,9 +301,6 @@ Same as
.It Fl 3
Same as
.Fl o Cm nfsv3
.It Fl 4
Same as
.Fl o Cm nfsv4
.It Fl D
Same as
.Fl o Cm deadthresh

View File

@ -1,27 +1,3 @@
/*
* copyright (c) 2003
* the regents of the university of michigan
* all rights reserved
*
* permission is granted to use, copy, create derivative works and redistribute
* this software and such derivative works for any purpose, so long as the name
* of the university of michigan is not used in any advertising or publicity
* pertaining to the use or distribution of this software without specific,
* written prior authorization. if the above copyright notice or any other
* identification of the university of michigan is included in any copy of any
* portion of this software, then the disclaimer below must also be included.
*
* this software is provided as is, without representation from the university
* of michigan as to its fitness for any purpose, and without warranty by the
* university of michigan of any kind, either express or implied, including
* without limitation the implied warranties of merchantability and fitness for
* a particular purpose. the regents of the university of michigan shall not be
* liable for any damages, including special, indirect, incidental, or
* consequential damages, with respect to any claim arising out of or in
* connection with the use of the software, even if it has been or is hereafter
* advised of the possibility of such damages.
*/
/*
* Copyright (c) 1992, 1993, 1994
* The Regents of the University of California. All rights reserved.
@ -140,7 +116,6 @@ enum mountmode {
ANY,
V2,
V3,
V4
} mountmode = ANY;
/* Return codes for nfs_tryproto. */
@ -155,7 +130,6 @@ int fallback_mount(struct iovec *iov, int iovlen, int mntflags);
int sec_name_to_num(char *sec);
char *sec_num_to_name(int num);
int getnfsargs(char *, struct iovec **iov, int *iovlen);
int getnfs4args(char *, struct iovec **iov, int *iovlen);
/* void set_rpc_maxgrouplist(int); */
struct netconfig *getnetconf_cached(const char *netid);
const char *netidbytype(int af, int sotype);
@ -164,8 +138,6 @@ int xdr_dir(XDR *, char *);
int xdr_fh(XDR *, struct nfhret *);
enum tryret nfs_tryproto(struct addrinfo *ai, char *hostp, char *spec,
char **errstr, struct iovec **iov, int *iovlen);
enum tryret nfs4_tryproto(struct addrinfo *ai, char *hostp, char *spec,
char **errstr);
enum tryret returncode(enum clnt_stat stat, struct rpc_err *rpcerr);
extern int getosreldate(void);
@ -190,15 +162,8 @@ main(int argc, char *argv[])
++fstype;
if (strcmp(fstype, "nfs4") == 0) {
nfsproto = IPPROTO_TCP;
portspec = "2049";
build_iovec(&iov, &iovlen, "tcp", NULL, 0);
mountmode = V4;
}
while ((c = getopt(argc, argv,
"234a:bcdD:g:I:iLlNo:PR:r:sTt:w:x:U")) != -1)
"23a:bcdD:g:I:iLlNo:PR:r:sTt:w:x:U")) != -1)
switch (c) {
case '2':
mountmode = V2;
@ -206,10 +171,6 @@ main(int argc, char *argv[])
case '3':
mountmode = V3;
break;
case '4':
mountmode = V4;
fstype = "nfs4";
break;
case 'a':
printf("-a deprecated, use -o readhead=<value>\n");
build_iovec(&iov, &iovlen, "readahead", optarg, (size_t)-1);
@ -301,10 +262,6 @@ main(int argc, char *argv[])
mountmode = V2;
} else if (strcmp(opt, "nfsv3") == 0) {
mountmode = V3;
} else if (strcmp(opt, "nfsv4") == 0) {
pass_flag_to_nmount=0;
mountmode = V4;
fstype = "nfs4";
} else if (strcmp(opt, "port") == 0) {
pass_flag_to_nmount=0;
asprintf(&portspec, "%d",
@ -406,13 +363,8 @@ main(int argc, char *argv[])
/* The default is to keep retrying forever. */
retrycnt = 0;
if (mountmode == V4) {
if (!getnfs4args(spec, &iov, &iovlen))
exit(1);
} else {
if (!getnfsargs(spec, &iov, &iovlen))
exit(1);
}
if (!getnfsargs(spec, &iov, &iovlen))
exit(1);
/* resolve the mountpoint with realpath(3) */
(void)checkpath(name, mntpath);
@ -814,129 +766,6 @@ getnfsargs(char *spec, struct iovec **iov, int *iovlen)
return (1);
}
int
getnfs4args(char *spec, struct iovec **iov, int *iovlen)
{
struct addrinfo hints, *ai_nfs, *ai;
enum tryret ret;
int ecode, speclen, remoteerr, sotype;
char *hostp, *delimp, *errstr;
size_t len;
static char nam[MNAMELEN + 1];
if (nfsproto == IPPROTO_TCP)
sotype = SOCK_STREAM;
else if (nfsproto == IPPROTO_UDP)
sotype = SOCK_DGRAM;
if ((delimp = strrchr(spec, ':')) != NULL) {
hostp = spec;
spec = delimp + 1;
} else if ((delimp = strrchr(spec, '@')) != NULL) {
warnx("path@server syntax is deprecated, use server:path");
hostp = delimp + 1;
} else {
warnx("no <host>:<dirpath> nfs-name");
return (0);
}
*delimp = '\0';
/*
* If there has been a trailing slash at mounttime it seems
* that some mountd implementations fail to remove the mount
* entries from their mountlist while unmounting.
*/
for (speclen = strlen(spec);
speclen > 1 && spec[speclen - 1] == '/';
speclen--)
spec[speclen - 1] = '\0';
if (strlen(hostp) + strlen(spec) + 1 > MNAMELEN) {
warnx("%s:%s: %s", hostp, spec, strerror(ENAMETOOLONG));
return (0);
}
/* Make both '@' and ':' notations equal */
if (*hostp != '\0') {
len = strlen(hostp);
memmove(nam, hostp, len);
nam[len] = ':';
memmove(nam + len + 1, spec, speclen);
nam[len + speclen + 1] = '\0';
}
/*
* Handle an internet host address.
*/
memset(&hints, 0, sizeof hints);
hints.ai_flags = AI_NUMERICHOST;
hints.ai_socktype = sotype;
if (getaddrinfo(hostp, portspec, &hints, &ai_nfs) != 0) {
hints.ai_flags = 0;
if ((ecode = getaddrinfo(hostp, portspec, &hints, &ai_nfs))
!= 0) {
if (portspec == NULL)
errx(1, "%s: %s", hostp, gai_strerror(ecode));
else
errx(1, "%s:%s: %s", hostp, portspec,
gai_strerror(ecode));
return (0);
}
}
ret = TRYRET_LOCALERR;
for (;;) {
/*
* Try each entry returned by getaddrinfo(). Note the
* occurence of remote errors by setting `remoteerr'.
*/
remoteerr = 0;
for (ai = ai_nfs; ai != NULL; ai = ai->ai_next) {
if ((ai->ai_family == AF_INET6) &&
(opflags & OF_NOINET6))
continue;
if ((ai->ai_family == AF_INET) &&
(opflags & OF_NOINET4))
continue;
ret = nfs4_tryproto(ai, hostp, spec, &errstr);
if (ret == TRYRET_SUCCESS)
break;
if (ret != TRYRET_LOCALERR)
remoteerr = 1;
if ((opflags & ISBGRND) == 0)
fprintf(stderr, "%s\n", errstr);
}
if (ret == TRYRET_SUCCESS)
break;
/* Exit if all errors were local. */
if (!remoteerr)
exit(1);
/*
* If retrycnt == 0, we are to keep retrying forever.
* Otherwise decrement it, and exit if it hits zero.
*/
if (retrycnt != 0 && --retrycnt == 0)
exit(1);
if ((opflags & (BGRND | ISBGRND)) == BGRND) {
warnx("Cannot immediately mount %s:%s, backgrounding",
hostp, spec);
opflags |= ISBGRND;
if (daemon(0, 0) != 0)
err(1, "daemon");
}
sleep(60);
}
freeaddrinfo(ai_nfs);
build_iovec(iov, iovlen, "hostname", nam, (size_t)-1);
/* Add mounted file system to PATH_MOUNTTAB */
if (!add_mtab(hostp, spec))
warnx("can't update %s for %s:%s", PATH_MOUNTTAB, hostp, spec);
return (1);
}
/*
* Try to set up the NFS arguments according to the address
* family, protocol (and possibly port) specified in `ai'.
@ -1142,82 +971,6 @@ nfs_tryproto(struct addrinfo *ai, char *hostp, char *spec, char **errstr,
return (TRYRET_SUCCESS);
}
/*
* Try to set up the NFS arguments according to the address
* family, protocol (and possibly port) specified in `ai'.
*
* Returns TRYRET_SUCCESS if successful, or:
* TRYRET_TIMEOUT The server did not respond.
* TRYRET_REMOTEERR The server reported an error.
* TRYRET_LOCALERR Local failure.
*
* In all error cases, *errstr will be set to a statically-allocated string
* describing the error.
*/
enum tryret
nfs4_tryproto(struct addrinfo *ai, char *hostp, char *spec, char **errstr)
{
static char errbuf[256];
struct sockaddr_storage nfs_ss;
struct netbuf nfs_nb;
struct netconfig *nconf;
const char *netid;
int nfsvers, sotype;
errbuf[0] = '\0';
*errstr = errbuf;
if (nfsproto == IPPROTO_TCP)
sotype = SOCK_STREAM;
else if (nfsproto == IPPROTO_UDP)
sotype = SOCK_DGRAM;
if ((netid = netidbytype(ai->ai_family, sotype)) == NULL) {
snprintf(errbuf, sizeof errbuf,
"af %d sotype %d not supported", ai->ai_family, sotype);
return (TRYRET_LOCALERR);
}
if ((nconf = getnetconf_cached(netid)) == NULL) {
snprintf(errbuf, sizeof errbuf, "%s: %s", netid, nc_sperror());
return (TRYRET_LOCALERR);
}
nfsvers = 4;
if (portspec != NULL && atoi(portspec) != 0) {
/* `ai' contains the complete nfsd sockaddr. */
nfs_nb.buf = ai->ai_addr;
nfs_nb.len = nfs_nb.maxlen = ai->ai_addrlen;
} else {
/* Ask the remote rpcbind. */
nfs_nb.buf = &nfs_ss;
nfs_nb.len = nfs_nb.maxlen = sizeof nfs_ss;
if (!rpcb_getaddr(RPCPROG_NFS, nfsvers, nconf, &nfs_nb,
hostp)) {
snprintf(errbuf, sizeof errbuf, "[%s] %s:%s: %s",
netid, hostp, spec,
clnt_spcreateerror("RPCPROG_NFS"));
return (returncode(rpc_createerr.cf_stat,
&rpc_createerr.cf_error));
}
}
/*
* Store the filehandle and server address in nfsargsp, making
* sure to copy any locally allocated structures.
*/
addrlen = nfs_nb.len;
addr = malloc(addrlen);
if (addr == NULL)
err(1, "malloc");
bcopy(nfs_nb.buf, addr, addrlen);
return (TRYRET_SUCCESS);
}
/*
* Catagorise a RPC return status and error into an `enum tryret'
* return code.
@ -1361,7 +1114,7 @@ void
usage()
{
(void)fprintf(stderr, "%s\n%s\n%s\n%s\n",
"usage: mount_nfs [-234bcdiLlNPsTU] [-a maxreadahead] [-D deadthresh]",
"usage: mount_nfs [-23bcdiLlNPsTU] [-a maxreadahead] [-D deadthresh]",
" [-g maxgroups] [-I readdirsize] [-o options] [-R retrycnt]",
" [-r readsize] [-t timeout] [-w writesize] [-x retrans]",
" rhost:path node");

View File

@ -11,7 +11,7 @@ SUBDIR= boot
CSCOPEDIRS= boot bsm cam cddl compat conf contrib crypto ddb dev fs gdb \
geom gnu isa kern libkern modules net net80211 netatalk \
netgraph netinet netinet6 netipsec netipx netnatm netncp \
netsmb nfs nfs4client nfsclient nfsserver nlm opencrypto \
netsmb nfs nfsclient nfsserver nlm opencrypto \
pci rpc security sys ufs vm xdr ${CSCOPE_ARCHDIR}
.if defined(ALL_ARCH)
CSCOPE_ARCHDIR ?= amd64 arm i386 ia64 mips pc98 powerpc sparc64 sun4v

View File

@ -2450,14 +2450,6 @@ netsmb/smb_subr.c optional netsmb
netsmb/smb_trantcp.c optional netsmb
netsmb/smb_usr.c optional netsmb
nfs/nfs_common.c optional nfsclient | nfsserver
nfs4client/nfs4_dev.c optional nfsclient
nfs4client/nfs4_idmap.c optional nfsclient
nfs4client/nfs4_socket.c optional nfsclient
nfs4client/nfs4_subs.c optional nfsclient
nfs4client/nfs4_vfs_subs.c optional nfsclient
nfs4client/nfs4_vfsops.c optional nfsclient
nfs4client/nfs4_vn_subs.c optional nfsclient
nfs4client/nfs4_vnops.c optional nfsclient
nfsclient/bootp_subr.c optional bootp nfsclient
nfsclient/krpc_subr.c optional bootp nfsclient
nfsclient/nfs_bio.c optional nfsclient
@ -2519,7 +2511,6 @@ rpc/rpc_generic.c optional krpc | nfslockd | nfsclient | nfsserver
rpc/rpc_prot.c optional krpc | nfslockd | nfsclient | nfsserver
rpc/rpcb_clnt.c optional krpc | nfslockd | nfsclient | nfsserver
rpc/rpcb_prot.c optional krpc | nfslockd | nfsclient | nfsserver
rpc/rpcclnt.c optional nfsclient
rpc/svc.c optional krpc | nfslockd | nfsserver
rpc/svc_auth.c optional krpc | nfslockd | nfsserver
rpc/svc_auth_unix.c optional krpc | nfslockd | nfsserver

View File

@ -226,7 +226,6 @@ KGSSAPI_DEBUG opt_kgssapi.h
# filesystems will be enabled - but look below.
NFSCLIENT opt_nfs.h
NFSSERVER opt_nfs.h
NFS4CLIENT opt_nfs.h
# Use this option to compile both NFS client and server using the
# legacy RPC implementation instead of the newer KRPC system (which

View File

@ -59,7 +59,6 @@ __FBSDID("$FreeBSD$");
#include <sys/vnode.h>
#include <rpc/rpc.h>
#include <rpc/rpcclnt.h>
#include <kgssapi/krb5/kcrypto.h>

View File

@ -98,7 +98,6 @@
#include <crypto/des/des.h>
#include <sys/md5.h>
#include <rpc/rpc.h>
#include <rpc/rpcclnt.h>
#include <rpc/rpcsec_gss.h>
/*

View File

@ -1,36 +0,0 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../../nfsclient ${.CURDIR}/../../nfs4client \
${.CURDIR}/../../nfs ${.CURDIR}/../../rpc
KMOD= nfs4client
SRCS= vnode_if.h \
nfs_bio.c nfs_lock.c nfs_node.c nfs_nfsiod.c \
nfs_common.c \
opt_inet.h opt_nfs.h opt_bootp.h opt_nfsroot.h \
nfs4_dev.c nfs4_idmap.c nfs4_socket.c nfs4_subs.c \
nfs4_vfs_subs.c nfs4_vfsops.c nfs4_vn_subs.c nfs4_vnops.c
SRCS+= opt_inet6.h
# USE THE RPCCLNT:
CFLAGS+= -DRPCCLNT_DEBUG
SRCS+= rpcclnt.c
# USE THE NEW IDMAPPER
CFLAGS+= -DUSE_NEW_IDMAPPER
.if !defined(KERNBUILDDIR)
NFS_INET?= 1 # 0/1 - requires INET to be configured in kernel
NFS_INET6?= 1 # 0/1 - requires INET6 to be configured in kernel
.if ${NFS_INET} > 0
opt_inet.h:
echo "#define INET 1" > ${.TARGET}
.endif
.if ${NFS_INET6} > 0
opt_inet6.h:
echo "#define INET6 1" > ${.TARGET}
.endif
.endif
.include <bsd.kmod.mk>

View File

@ -1,24 +1,14 @@
# $FreeBSD$
.PATH: ${.CURDIR}/../../nfsclient ${.CURDIR}/../../nfs4client \
${.CURDIR}/../../nfs ${.CURDIR}/../../rpc
.PATH: ${.CURDIR}/../../nfsclient ${.CURDIR}/../../nfs ${.CURDIR}/../../rpc
KMOD= nfsclient
SRCS= vnode_if.h \
nfs_bio.c nfs_lock.c nfs_node.c nfs_socket.c nfs_subs.c nfs_nfsiod.c \
nfs_vfsops.c nfs_vnops.c nfs_common.c nfs_krpc.c \
opt_inet.h opt_nfs.h opt_bootp.h opt_nfsroot.h
SRCS+= nfs4_dev.c nfs4_idmap.c nfs4_socket.c nfs4_subs.c \
nfs4_vfs_subs.c nfs4_vfsops.c nfs4_vn_subs.c nfs4_vnops.c
SRCS+= opt_inet6.h opt_kdtrace.h opt_kgssapi.h opt_route.h
# USE THE RPCCLNT:
CFLAGS+= -DRPCCLNT_DEBUG
SRCS+= rpcclnt.c
# USE THE NEW IDMAPPER
CFLAGS+= -DUSE_NEW_IDMAPPER
.if !defined(KERNBUILDDIR)
NFS_INET?= 1 # 0/1 - requires INET to be configured in kernel
NFS_INET6?= 1 # 0/1 - requires INET6 to be configured in kernel

View File

@ -1,260 +0,0 @@
/* $FreeBSD$ */
/* $Id: nfs4.h,v 1.25 2003/11/05 14:58:58 rees Exp $ */
/*-
* copyright (c) 2003
* the regents of the university of michigan
* all rights reserved
*
* permission is granted to use, copy, create derivative works and redistribute
* this software and such derivative works for any purpose, so long as the name
* of the university of michigan is not used in any advertising or publicity
* pertaining to the use or distribution of this software without specific,
* written prior authorization. if the above copyright notice or any other
* identification of the university of michigan is included in any copy of any
* portion of this software, then the disclaimer below must also be included.
*
* this software is provided as is, without representation from the university
* of michigan as to its fitness for any purpose, and without warranty by the
* university of michigan of any kind, either express or implied, including
* without limitation the implied warranties of merchantability and fitness for
* a particular purpose. the regents of the university of michigan shall not be
* liable for any damages, including special, indirect, incidental, or
* consequential damages, with respect to any claim arising out of or in
* connection with the use of the software, even if it has been or is hereafter
* advised of the possibility of such damages.
*/
#ifndef _NFS4CLIENT_NFS4_H
#define _NFS4CLIENT_NFS4_H
#define NFS4_USE_RPCCLNT
#define NFS4_MINOR_VERSION 0
#define NFS_PORT 2049
#define NFS4_DEF_FILE_IO_BUFFER_SIZE 4096
#define NFS4_MAX_FILE_IO_BUFFER_SIZE 32768
#define NFS4_DEF_MAXFILESIZE 0xffffffff
#define NFS4_SUPER_MAGIC 0xF00BA4
#define NFS4FS_SILLY_RENAME 1
#define NFS4FS_STRICT_LOCKING 1
#define NFS4FS_RETRY_OLD_STATEID 1
#define NFS4FS_MIN_LEASE (1 * hz)
#define NFS4FS_DEFAULT_LEASE (30 * hz)
#define NFS4FS_MAX_LEASE (120 * hz)
#define NFS4FS_RETRY_MIN_DELAY (hz >> 4)
#define NFS4FS_RETRY_MAX_DELAY (hz << 3)
#define NFS4FS_SEMAPHORE_DELAY (hz >> 4)
#define NFS4FS_GRACE_DELAY (hz * 5)
#define NFS4FS_OLD_STATEID_DELAY (hz >> 3)
#define NFS4FS_OP_MAX 10
#define NFS4_BUFSIZE 8192
#define NFS4FS_MAX_IOV 10
#define NFS4_SETCLIENTID_MAXTRIES 5
#define NFS4_READDIR_MAXTRIES 5
#define NFS4_MAXIO 4
#define NFS4_MAX_REQUEST_SOFT 192
#define NFS4_MAX_REQUEST_HARD 256
#define NFS4_MAXCOMMIT 64
#define NFS4_READ_DELAY (2 * HZ)
#define NFS4_WRITEBACK_DELAY (5 * HZ)
#define NFS4_WRITEBACK_LOCKDELAY (60 * HZ)
#define NFS4_COMMIT_DELAY (5 * HZ)
#define RPC_SLACK_SPACE 512
struct nfs4_compound {
char *tag;
int req_nops;
uint32_t *req_nopsp;
uint32_t *req_seqidp;
uint32_t *req_stateidp[NFS4_MAXIO];
uint32_t req_nstateid;
u_int seqidused;
int rep_status;
int rep_nops;
struct nfs4_fctx *fcp;
struct vnode *curvp;
struct vnode *savevp;
struct nfsmount *nmp;
};
struct nfs4_fdata {
struct nfsnode *fd_n;
pid_t fd_pid;
};
struct nfs4_oparg_putfh {
/* filled in by caller */
/* struct dentry *dentry;*/
/* filled in by setup routine */
/* nfs_opnum4 op;*/
uint32_t fh_len;
nfsfh_t fh_val;
int nlookups;
};
struct nfs4_oparg_getattr {
struct vnode *vp;
nfsv4bitmap *bm;
struct nfsv4_fattr fa;
};
struct nfs4_oparg_getfh {
uint32_t fh_len;
nfsfh_t fh_val;
struct vnode *vp;
};
struct nfs4_oparg_lookup {
const char *name;
uint32_t namelen;
struct vnode *vp;
};
struct nfs4_oparg_setclientid {
struct nfsmount *np;
uint32_t namelen;
char *name;
char *cb_netid;
uint32_t cb_netidlen;
char *cb_univaddr;
uint32_t cb_univaddrlen;
uint32_t cb_prog;
uint64_t clientid;
u_char verf[NFSX_V4VERF];
};
struct nfs4_oparg_access {
uint32_t mode;
uint32_t rmode;
uint32_t supported;
};
struct nfs4_oparg_open {
uint32_t flags;
uint32_t rflags;
nfsv4cltype ctype;
struct vattr *vap;
struct componentname *cnp;
struct nfs4_fctx *fcp;
char stateid[NFSX_V4STATEID];
};
struct nfs4_oparg_read {
uint64_t off;
uint32_t maxcnt;
uint32_t eof;
uint32_t retlen;
struct uio *uiop;
struct nfs4_fctx *fcp;
};
struct nfs4_oparg_write {
uint64_t off;
uint32_t stable;
uint32_t cnt;
uint32_t retlen;
uint32_t committed;
struct uio *uiop;
u_char wverf[NFSX_V4VERF];
struct nfs4_fctx *fcp;
};
struct nfs4_oparg_commit {
uint32_t len;
off_t start;
u_char verf[NFSX_V4VERF];
};
struct nfs4_oparg_readdir {
uint32_t cnt;
nfsv4bitmap *bm;
uint64_t cookie;
u_char verf[NFSX_V4VERF];
};
struct nfs4_oparg_create {
nfstype type;
char *linktext;
char *name;
uint32_t namelen;
struct vattr *vap;
};
struct nfs4_oparg_rename {
const char *fname;
uint32_t fnamelen;
const char *tname;
uint32_t tnamelen;
};
struct nfs4_oparg_link {
const char *name;
uint32_t namelen;
};
/*
* Lockowner
*/
struct nfs4_lowner {
uint32_t lo_cnt;
uint32_t lo_seqid;
uint32_t lo_id;
};
#define NFS4_SEQIDMUTATINGERROR(err) \
(((err) != NFSERR_STALE_CLIENTID) && \
((err) != NFSERR_BAD_SEQID) && \
((err) != NFSERR_STALE_STATEID) && \
((err) != NFSERR_BAD_STATEID))
/* Standard bitmasks */
extern nfsv4bitmap nfsv4_fsinfobm;
extern nfsv4bitmap nfsv4_fsattrbm;
extern nfsv4bitmap nfsv4_getattrbm;
extern nfsv4bitmap nfsv4_readdirbm;
vfs_init_t nfs4_init;
vfs_uninit_t nfs4_uninit;
uint32_t nfs_v4fileid4_to_fileid(uint64_t);
int nfs4_readrpc(struct vnode *, struct uio *, struct ucred *);
int nfs4_writerpc(struct vnode *, struct uio *, struct ucred *, int *,
int *);
int nfs4_commit(struct vnode *vp, u_quad_t offset, int cnt,
struct ucred *cred, struct thread *td);
int nfs4_readdirrpc(struct vnode *, struct uio *, struct ucred *);
int nfs4_readlinkrpc(struct vnode *, struct uio *, struct ucred *);
int nfs4_sigintr(struct nfsmount *, struct nfsreq *, struct thread *);
int nfs4_writebp(struct buf *, int, struct thread *);
int nfs4_request(struct vnode *, struct mbuf *, int, struct thread *,
struct ucred *, struct mbuf **, struct mbuf **, caddr_t *);
int nfs4_request_mnt(struct nfsmount *, struct mbuf *, int, struct thread *,
struct ucred *, struct mbuf **, struct mbuf **, caddr_t *);
int nfs4_connect(struct nfsmount *);
void nfs4_disconnect(struct nfsmount *);
void nfs4_safedisconnect(struct nfsmount *);
int nfs4_nmcancelreqs(struct nfsmount *);
void nfs_v4initcompound(struct nfs4_compound *);
int nfs_v4postop(struct nfs4_compound *, int);
int nfs_v4handlestatus(int, struct nfs4_compound *);
#endif /* _NFS4CLIENT_NFS4_H */

View File

@ -1,456 +0,0 @@
/* $FreeBSD$ */
/* $Id: nfs4_dev.c,v 1.10 2003/11/05 14:58:59 rees Exp $ */
/*-
* copyright (c) 2003
* the regents of the university of michigan
* all rights reserved
*
* permission is granted to use, copy, create derivative works and redistribute
* this software and such derivative works for any purpose, so long as the name
* of the university of michigan is not used in any advertising or publicity
* pertaining to the use or distribution of this software without specific,
* written prior authorization. if the above copyright notice or any other
* identification of the university of michigan is included in any copy of any
* portion of this software, then the disclaimer below must also be included.
*
* this software is provided as is, without representation from the university
* of michigan as to its fitness for any purpose, and without warranty by the
* university of michigan of any kind, either express or implied, including
* without limitation the implied warranties of merchantability and fitness for
* a particular purpose. the regents of the university of michigan shall not be
* liable for any damages, including special, indirect, incidental, or
* consequential damages, with respect to any claim arising out of or in
* connection with the use of the software, even if it has been or is hereafter
* advised of the possibility of such damages.
*/
#include <sys/param.h>
#include <sys/conf.h>
#include <sys/queue.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/poll.h>
#include <sys/mutex.h>
#include <sys/stat.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/wait.h>
#include <sys/signalvar.h>
#include <nfs4client/nfs4_dev.h>
#ifdef NFS4DEVVERBOSE
#define NFS4DEV_DEBUG(X...) printf(X)
#else
#define NFS4DEV_DEBUG(X...)
#endif
#define NFS4DEV_NAME "nfs4"
#define CDEV_MINOR 1
MALLOC_DEFINE(M_NFS4DEV, "nfs4_dev", "NFS4 device");
struct nfs4dev_upcall {
/* request msg */
struct nfs4dev_msg up_reqmsg;
size_t up_reqmsglen;
/* reply (payload only) */
caddr_t up_rep;
size_t * up_replen;
int up_copied; /* non-zero when reply has been copied to
'*up_rep' */
int up_error; /* non-zero if an error occured */
TAILQ_ENTRY(nfs4dev_upcall) up_entry;
};
#define nfs4dev_upcall_get(MP) (MP) = malloc(sizeof(struct nfs4dev_upcall), M_NFS4DEV, M_WAITOK | M_ZERO)
#define nfs4dev_upcall_put(MP) free((MP), M_NFS4DEV)
static int nfs4dev_nopen = 0;
static struct thread * nfs4dev_reader = NULL;
static struct cdev *nfs4device = 0;
static struct mtx nfs4dev_daemon_mtx;
static int nfs4dev_xid = 0;
/* queue of pending upcalls */
TAILQ_HEAD(, nfs4dev_upcall) nfs4dev_newq;
static struct mtx nfs4dev_newq_mtx;
/* queue of upcalls waiting for replys */
TAILQ_HEAD(, nfs4dev_upcall) nfs4dev_waitq;
static struct mtx nfs4dev_waitq_mtx;
/* dev hooks */
static d_open_t nfs4dev_open;
static d_close_t nfs4dev_close;
static d_ioctl_t nfs4dev_ioctl;
static d_poll_t nfs4dev_poll;
static struct cdevsw nfs4dev_cdevsw = {
#if (__FreeBSD_version > 502102)
.d_version = D_VERSION,
.d_flags = D_NEEDGIANT,
#endif
.d_open = nfs4dev_open,
.d_close = nfs4dev_close,
.d_ioctl = nfs4dev_ioctl,
.d_poll = nfs4dev_poll,
.d_name = NFS4DEV_NAME,
};
static int nfs4dev_reply(caddr_t);
static int nfs4dev_request(caddr_t);
/* Userland requests a new operation to service */
static int
nfs4dev_request(caddr_t addr)
{
struct nfs4dev_upcall * u;
struct nfs4dev_msg * m = (struct nfs4dev_msg *) addr;
mtx_lock(&nfs4dev_newq_mtx);
if (TAILQ_EMPTY(&nfs4dev_newq)) {
mtx_unlock(&nfs4dev_newq_mtx);
return EAGAIN;
}
u = TAILQ_FIRST(&nfs4dev_newq);
TAILQ_REMOVE(&nfs4dev_newq, u, up_entry);
mtx_unlock(&nfs4dev_newq_mtx);
bcopy(&u->up_reqmsg, m, sizeof(struct nfs4dev_msg));
mtx_lock(&nfs4dev_waitq_mtx);
TAILQ_INSERT_TAIL(&nfs4dev_waitq, u, up_entry);
mtx_unlock(&nfs4dev_waitq_mtx);
return 0;
}
static int
nfs4dev_reply(caddr_t addr)
{
struct nfs4dev_upcall * u;
struct nfs4dev_msg * m = (struct nfs4dev_msg *) addr;
int error;
if (m->msg_vers != NFS4DEV_VERSION) {
printf("nfs4dev version mismatch\n");
return EINVAL;
}
if (m->msg_type > NFS4DEV_MAX_TYPE) {
NFS4DEV_DEBUG("nfs4dev: unsupported message type\n");
return EINVAL;
}
if (m->msg_len < sizeof(*m) - NFS4DEV_MSG_MAX_DATALEN ||
m->msg_len > NFS4DEV_MSG_MAX_DATALEN) {
NFS4DEV_DEBUG("bad message length\n");
return EINVAL;
}
/* match the reply with a request */
mtx_lock(&nfs4dev_waitq_mtx);
TAILQ_FOREACH(u, &nfs4dev_waitq, up_entry) {
if (m->msg_xid == u->up_reqmsg.msg_xid) {
if (m->msg_type == u->up_reqmsg.msg_type)
goto found;
NFS4DEV_DEBUG("nfs4dev: op type mismatch!\n");
break;
}
}
mtx_unlock(&nfs4dev_waitq_mtx);
NFS4DEV_DEBUG("nfs4dev msg op: %d xid: %x not found.\n",
m->msg_type, m->msg_xid);
error = EIO;
goto bad;
found:
TAILQ_REMOVE(&nfs4dev_waitq, u, up_entry);
mtx_unlock(&nfs4dev_waitq_mtx);
if (m->msg_error) {
error = m->msg_error;
goto bad;
}
if (m->msg_len > *u->up_replen) {
error = EFAULT;
goto bad;
}
bcopy(m->msg_data, u->up_rep, m->msg_len);
*u->up_replen = m->msg_len;
u->up_copied = m->msg_len;
wakeup(u);
return 0;
bad:
if (u) {
u->up_error = error;
wakeup(u);
}
return error;
}
void
nfs4dev_init(void)
{
nfs4dev_xid = arc4random();
TAILQ_INIT(&nfs4dev_newq);
TAILQ_INIT(&nfs4dev_waitq);
mtx_init(&nfs4dev_newq_mtx, "nfs4dev newq", NULL, MTX_DEF);
mtx_init(&nfs4dev_waitq_mtx, "nfs4dev waitq", NULL, MTX_DEF);
mtx_init(&nfs4dev_daemon_mtx, "nfs4dev state", NULL, MTX_DEF);
nfs4device = make_dev(&nfs4dev_cdevsw, CDEV_MINOR, (uid_t)0, (gid_t)0,
S_IRUSR | S_IWUSR, "nfs4");
}
void
nfs4dev_uninit(void)
{
struct proc * dead = NULL;
mtx_lock(&nfs4dev_daemon_mtx);
if (nfs4dev_nopen) {
if (nfs4dev_reader == NULL) {
NFS4DEV_DEBUG("nfs4dev uninit(): unregistered reader\n");
} else {
dead = nfs4dev_reader->td_proc;
}
}
mtx_unlock(&nfs4dev_daemon_mtx);
if (dead != NULL) {
NFS4DEV_DEBUG("nfs4dev_uninit(): you forgot to kill attached daemon (pid: %u)\n",
dead->p_pid);
PROC_LOCK(dead);
psignal(dead, SIGTERM);
PROC_UNLOCK(dead);
}
/* XXX moot? */
nfs4dev_purge();
mtx_destroy(&nfs4dev_newq_mtx);
mtx_destroy(&nfs4dev_waitq_mtx);
mtx_destroy(&nfs4dev_daemon_mtx);
destroy_dev(nfs4device);
}
/* device interface functions */
static int
nfs4dev_open(struct cdev *dev, int flags, int fmt, struct thread *td)
{
if (dev != nfs4device)
return ENODEV;
mtx_lock(&nfs4dev_daemon_mtx);
if (nfs4dev_nopen) {
mtx_unlock(&nfs4dev_daemon_mtx);
return EBUSY;
}
nfs4dev_nopen++;
nfs4dev_reader = curthread;
mtx_unlock(&nfs4dev_daemon_mtx);
return (0);
}
static int
nfs4dev_close(struct cdev *dev, int flags, int fmt, struct thread *td)
{
struct nfs4dev_upcall * u;
if (dev != nfs4device)
return ENODEV;
mtx_lock(&nfs4dev_daemon_mtx);
if (!nfs4dev_nopen) {
mtx_unlock(&nfs4dev_daemon_mtx);
return ENOENT;
}
nfs4dev_nopen--;
nfs4dev_reader = NULL;
mtx_unlock(&nfs4dev_daemon_mtx);
mtx_lock(&nfs4dev_waitq_mtx);
while (!TAILQ_EMPTY(&nfs4dev_waitq)) {
u = TAILQ_FIRST(&nfs4dev_waitq);
TAILQ_REMOVE(&nfs4dev_waitq, u, up_entry);
u->up_error = EINTR;
wakeup(u);
}
mtx_unlock(&nfs4dev_waitq_mtx);
return 0;
}
static int
nfs4dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td)
{
int error;
if (dev != nfs4device)
return ENODEV;
if (data == NULL)
return EFAULT;
if (nfs4dev_reader != curthread)
nfs4dev_reader = curthread;
switch (cmd) {
case NFS4DEVIOCGET:
error = nfs4dev_request(data);
break;
case NFS4DEVIOCPUT:
error = nfs4dev_reply(data);
break;
default:
NFS4DEV_DEBUG("nfs4dev_ioctl: unkown ioctl cmd %d\n", (int)cmd);
error = EOPNOTSUPP;
break;
}
return error;
}
static int
nfs4dev_poll(struct cdev *dev, int events, struct thread *td)
{
int revents;
if (dev != nfs4device)
return EINVAL;
mtx_lock(&nfs4dev_daemon_mtx);
if (nfs4dev_nopen == 0) {
mtx_unlock(&nfs4dev_daemon_mtx);
return 0;
}
mtx_unlock(&nfs4dev_daemon_mtx);
revents = 0;
/* check readable data */
mtx_lock(&nfs4dev_newq_mtx);
if (!TAILQ_EMPTY(&nfs4dev_newq))
revents |= POLLIN;
mtx_unlock(&nfs4dev_newq_mtx);
mtx_lock(&nfs4dev_waitq_mtx);
if (!TAILQ_EMPTY(&nfs4dev_waitq))
revents |= POLLOUT;
mtx_unlock(&nfs4dev_waitq_mtx);
return revents;
}
int
nfs4dev_call(uint32_t type, caddr_t req_data, size_t req_len, caddr_t rep_data, size_t * rep_lenp)
{
struct nfs4dev_upcall * u;
int error = 0;
unsigned int xtmp;
mtx_lock(&nfs4dev_daemon_mtx);
if (nfs4dev_nopen == 0) {
mtx_unlock(&nfs4dev_daemon_mtx);
return EINVAL;
}
mtx_unlock(&nfs4dev_daemon_mtx);
if (type > NFS4DEV_MAX_TYPE)
return EOPNOTSUPP;
NFS4DEV_DEBUG("upcall %d/%d:%d\n", type, req_len, *rep_lenp);
nfs4dev_upcall_get(u);
u->up_error = 0;
u->up_rep = rep_data;
u->up_replen = rep_lenp;
u->up_copied = 0;
u->up_reqmsg.msg_vers = NFS4DEV_VERSION;
/* XXX efficient copying */
bcopy(req_data, u->up_reqmsg.msg_data, req_len);
u->up_reqmsg.msg_len = req_len;
mtx_lock(&nfs4dev_newq_mtx);
/* get new XID */
while ((xtmp = arc4random() % 256) == 0);
nfs4dev_xid += xtmp;
u->up_reqmsg.msg_xid = nfs4dev_xid;
TAILQ_INSERT_TAIL(&nfs4dev_newq, u, up_entry);
mtx_unlock(&nfs4dev_newq_mtx);
NFS4DEV_DEBUG("nfs4dev op: %d xid: %x sleeping\n", u->up_reqmsg.msg_type, u->up_reqmsg.msg_xid);
do {
tsleep(u, PLOCK, "nfs4dev", 0);
} while (u->up_copied == 0 && u->up_error == 0);
/* upcall now removed from the queue */
NFS4DEV_DEBUG("nfs4dev prog: %d xid: %x continues...\n",
u->up_reqmsg.msg_type, u->up_reqmsg.msg_xid);
if (u->up_error) {
error = u->up_error;
NFS4DEV_DEBUG("nfs4dev prog: %d xid: %x error: %d\n",
u->up_reqmsg.msg_type, u->up_reqmsg.msg_xid, u->up_error);
goto out;
}
out:
nfs4dev_upcall_put(u);
return error;
}
void
nfs4dev_purge(void)
{
struct nfs4dev_upcall * u;
mtx_lock(&nfs4dev_newq_mtx);
while (!TAILQ_EMPTY(&nfs4dev_newq)) {
u = TAILQ_FIRST(&nfs4dev_newq);
TAILQ_REMOVE(&nfs4dev_newq, u, up_entry);
u->up_error = EINTR;
wakeup(u);
}
mtx_unlock(&nfs4dev_newq_mtx);
mtx_lock(&nfs4dev_waitq_mtx);
while (!TAILQ_EMPTY(&nfs4dev_waitq)) {
u = TAILQ_FIRST(&nfs4dev_waitq);
TAILQ_REMOVE(&nfs4dev_waitq, u, up_entry);
u->up_error = EINTR;
wakeup(u);
}
mtx_unlock(&nfs4dev_waitq_mtx);
}

View File

@ -1,65 +0,0 @@
/* $FreeBSD$ */
/* $Id: nfs4_dev.h,v 1.3 2003/11/05 14:58:59 rees Exp $ */
/*-
* copyright (c) 2003
* the regents of the university of michigan
* all rights reserved
*
* permission is granted to use, copy, create derivative works and redistribute
* this software and such derivative works for any purpose, so long as the name
* of the university of michigan is not used in any advertising or publicity
* pertaining to the use or distribution of this software without specific,
* written prior authorization. if the above copyright notice or any other
* identification of the university of michigan is included in any copy of any
* portion of this software, then the disclaimer below must also be included.
*
* this software is provided as is, without representation from the university
* of michigan as to its fitness for any purpose, and without warranty by the
* university of michigan of any kind, either express or implied, including
* without limitation the implied warranties of merchantability and fitness for
* a particular purpose. the regents of the university of michigan shall not be
* liable for any damages, including special, indirect, incidental, or
* consequential damages, with respect to any claim arising out of or in
* connection with the use of the software, even if it has been or is hereafter
* advised of the possibility of such damages.
*/
#ifndef _NFS3_DEV_H_
#define _NFS4_DEV_H_
#include <sys/ioccom.h>
/* type of upcall */
#define NFS4DEV_TYPE_IDMAP 0
#define NFS4DEV_TYPE_GSS 1
#define NFS4DEV_MAX_TYPE 1
struct nfs4dev_msg {
unsigned int msg_vers;
unsigned int msg_type;
unsigned int msg_xid;
unsigned int msg_error;
#define NFS4DEV_MSG_MAX_DATALEN 350
size_t msg_len;
uint8_t msg_data[NFS4DEV_MSG_MAX_DATALEN];
};
#define NFS4DEV_VERSION (0x3 << 16 | (int) sizeof(struct nfs4dev_msg))
/* ioctl commands */
#define NFS4DEVIOCGET _IOR('A', 0x200, struct nfs4dev_msg)
#define NFS4DEVIOCPUT _IOW('A', 0x201, struct nfs4dev_msg)
#ifdef _KERNEL
int nfs4dev_call(uint32_t type, caddr_t req_data, size_t req_len, caddr_t rep_datap, size_t * rep_lenp);
void nfs4dev_purge(void);
void nfs4dev_init(void);
void nfs4dev_uninit(void);
#endif
#endif /* _NFS4_DEV_H_ */

View File

@ -1,509 +0,0 @@
/* $FreeBSD$ */
/* $Id: nfs4_idmap.c,v 1.4 2003/11/05 14:58:59 rees Exp $ */
/*-
* copyright (c) 2003
* the regents of the university of michigan
* all rights reserved
*
* permission is granted to use, copy, create derivative works and redistribute
* this software and such derivative works for any purpose, so long as the name
* of the university of michigan is not used in any advertising or publicity
* pertaining to the use or distribution of this software without specific,
* written prior authorization. if the above copyright notice or any other
* identification of the university of michigan is included in any copy of any
* portion of this software, then the disclaimer below must also be included.
*
* this software is provided as is, without representation from the university
* of michigan as to its fitness for any purpose, and without warranty by the
* university of michigan of any kind, either express or implied, including
* without limitation the implied warranties of merchantability and fitness for
* a particular purpose. the regents of the university of michigan shall not be
* liable for any damages, including special, indirect, incidental, or
* consequential damages, with respect to any claim arising out of or in
* connection with the use of the software, even if it has been or is hereafter
* advised of the possibility of such damages.
*/
/* TODO:
* o validate ascii
* */
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/lock.h>
#include <sys/lockmgr.h>
#include <sys/fnv_hash.h>
#include <sys/proc.h>
#include <sys/syscall.h>
#include <sys/sysent.h>
#include <sys/libkern.h>
#include <rpc/rpcclnt.h>
#include <nfs4client/nfs4_dev.h>
#include <nfs4client/nfs4_idmap.h>
#ifdef IDMAPVERBOSE
#define IDMAP_DEBUG(...) printf(__VA_ARGS__);
#else
#define IDMAP_DEBUG(...)
#endif
#define IDMAP_HASH_SIZE 37
MALLOC_DEFINE(M_IDMAP, "idmap", "idmap");
#define idmap_entry_get(ID) (ID) = malloc(sizeof(struct idmap_entry), M_IDMAP, M_WAITOK | M_ZERO)
#define idmap_entry_put(ID) free((ID), M_IDMAP)
struct idmap_entry {
struct idmap_msg id_info;
TAILQ_ENTRY(idmap_entry) id_entry_id;
TAILQ_ENTRY(idmap_entry) id_entry_name;
};
struct idmap_hash {
TAILQ_HEAD(, idmap_entry) hash_name[IDMAP_HASH_SIZE];
TAILQ_HEAD(, idmap_entry) hash_id[IDMAP_HASH_SIZE];
struct lock hash_lock;
};
#define IDMAP_RLOCK(lock) lockmgr(lock, LK_SHARED, NULL)
#define IDMAP_WLOCK(lock) lockmgr(lock, LK_EXCLUSIVE, NULL)
#define IDMAP_UNLOCK(lock) lockmgr(lock, LK_RELEASE, NULL)
static struct idmap_hash idmap_uid_hash;
static struct idmap_hash idmap_gid_hash;
static struct idmap_entry * idmap_name_lookup(uint32_t, char *);
static struct idmap_entry * idmap_id_lookup(uint32_t, ident_t);
static int idmap_upcall_name(uint32_t, char *, struct idmap_entry **);
static int idmap_upcall_id(uint32_t , ident_t, struct idmap_entry ** );
static int idmap_add(struct idmap_entry *);
static int
idmap_upcall_name(uint32_t type, char * name, struct idmap_entry ** found)
{
int error;
struct idmap_entry * e;
size_t len, siz;
if (type > IDMAP_MAX_TYPE || type == 0) {
IDMAP_DEBUG("bad type %d\n", type);
return EINVAL; /* XXX */
}
if (name == NULL || (len = strlen(name)) == 0 || len > IDMAP_MAXNAMELEN) {
IDMAP_DEBUG("idmap_upcall_name: bad name\n");
return EFAULT; /* XXX */
}
e = malloc(sizeof(struct idmap_entry), M_IDMAP,
M_WAITOK | M_ZERO);
e->id_info.id_type = type;
bcopy(name, e->id_info.id_name, len);
e->id_info.id_namelen = len;
siz = sizeof(struct idmap_msg);
error = nfs4dev_call(NFS4DEV_TYPE_IDMAP, (caddr_t)&e->id_info, siz,
(caddr_t)&e->id_info, &siz);
if (error) {
IDMAP_DEBUG("error %d in nfs4dev_upcall()\n", error);
*found = NULL;
return error;
}
if (siz != sizeof(struct idmap_msg)) {
IDMAP_DEBUG("bad size of returned message\n");
*found = NULL;
return EFAULT;
}
*found = e;
return 0;
}
static int
idmap_upcall_id(uint32_t type, ident_t id, struct idmap_entry ** found)
{
int error;
struct idmap_entry * e;
size_t siz;
if (type > IDMAP_MAX_TYPE)
panic("bad type"); /* XXX */
e = malloc(sizeof(struct idmap_entry), M_IDMAP,
M_WAITOK | M_ZERO);
e->id_info.id_type = type;
e->id_info.id_namelen = 0; /* should already */
e->id_info.id_id = id;
siz = sizeof(struct idmap_msg);
error = nfs4dev_call(NFS4DEV_TYPE_IDMAP, (caddr_t)&e->id_info, siz,
(caddr_t)&e->id_info, &siz);
if (error) {
IDMAP_DEBUG("error %d in nfs4dev_upcall()\n", error);
*found = NULL;
return error;
}
if (siz != sizeof(struct idmap_msg)) {
IDMAP_DEBUG("bad size of returned message\n");
*found = NULL;
return EFAULT;
}
*found = e;
return 0;
}
static void
idmap_hashf(struct idmap_entry *e, uint32_t * hval_id, uint32_t * hval_name)
{
switch (e->id_info.id_type) {
case IDMAP_TYPE_UID:
*hval_id = e->id_info.id_id.uid % IDMAP_HASH_SIZE;
break;
case IDMAP_TYPE_GID:
*hval_id = e->id_info.id_id.gid % IDMAP_HASH_SIZE;
break;
default:
/* XXX yikes! */
panic("hashf: bad type!");
break;
}
if (e->id_info.id_namelen == 0)
/* XXX */ panic("hashf: bad name");
*hval_name = fnv_32_str(e->id_info.id_name, FNV1_32_INIT) % IDMAP_HASH_SIZE;
}
static int
idmap_add(struct idmap_entry * e)
{
struct idmap_hash * hash;
uint32_t hval_id, hval_name;
if (e->id_info.id_namelen == 0) {
printf("idmap_add: name of len 0\n");
return EINVAL;
}
switch (e->id_info.id_type) {
case IDMAP_TYPE_UID:
hash = &idmap_uid_hash;
break;
case IDMAP_TYPE_GID:
hash = &idmap_gid_hash;
break;
default:
/* XXX yikes */
panic("idmap add: bad type!");
break;
}
idmap_hashf(e, &hval_id, &hval_name);
IDMAP_WLOCK(&hash->hash_lock);
TAILQ_INSERT_TAIL(&hash->hash_id[hval_id], e, id_entry_id);
TAILQ_INSERT_TAIL(&hash->hash_name[hval_name], e, id_entry_name);
IDMAP_UNLOCK(&hash->hash_lock);
return 0;
}
static struct idmap_entry *
idmap_id_lookup(uint32_t type, ident_t id)
{
struct idmap_hash * hash;
uint32_t hval;
struct idmap_entry * e;
switch (type) {
case IDMAP_TYPE_UID:
hash = &idmap_uid_hash;
hval = id.uid % IDMAP_HASH_SIZE;
break;
case IDMAP_TYPE_GID:
hash = &idmap_gid_hash;
hval = id.gid % IDMAP_HASH_SIZE;
break;
default:
/* XXX yikes */
panic("lookup: bad type!");
break;
}
IDMAP_RLOCK(&hash->hash_lock);
TAILQ_FOREACH(e, &hash->hash_id[hval], id_entry_name) {
if ((type == IDMAP_TYPE_UID && e->id_info.id_id.uid == id.uid)||
(type == IDMAP_TYPE_GID && e->id_info.id_id.gid == id.gid)) {
IDMAP_UNLOCK(&hash->hash_lock);
return e;
}
}
IDMAP_UNLOCK(&hash->hash_lock);
return NULL;
}
static struct idmap_entry *
idmap_name_lookup(uint32_t type, char * name)
{
struct idmap_hash * hash;
uint32_t hval;
struct idmap_entry * e;
size_t len;
switch (type) {
case IDMAP_TYPE_UID:
hash = &idmap_uid_hash;
break;
case IDMAP_TYPE_GID:
hash = &idmap_gid_hash;
break;
default:
/* XXX yikes */
panic("lookup: bad type!");
break;
}
len = strlen(name);
if (len == 0 || len > IDMAP_MAXNAMELEN) {
IDMAP_DEBUG("bad name length %d\n", len);
return NULL;
}
hval = fnv_32_str(name, FNV1_32_INIT) % IDMAP_HASH_SIZE;
IDMAP_RLOCK(&hash->hash_lock);
TAILQ_FOREACH(e, &hash->hash_name[hval], id_entry_name) {
if ((strlen(e->id_info.id_name) == strlen(name)) && strncmp(e->id_info.id_name, name, strlen(name)) == 0) {
IDMAP_UNLOCK(&hash->hash_lock);
return e;
}
}
IDMAP_UNLOCK(&hash->hash_lock);
return NULL;
}
void
idmap_init(void)
{
unsigned int i;
for (i=0; i<IDMAP_HASH_SIZE; i++) {
TAILQ_INIT(&idmap_uid_hash.hash_name[i]);
TAILQ_INIT(&idmap_uid_hash.hash_id[i]);
TAILQ_INIT(&idmap_gid_hash.hash_name[i]);
TAILQ_INIT(&idmap_gid_hash.hash_id[i]);
}
lockinit(&idmap_uid_hash.hash_lock, PLOCK, "idmap uid hash table", 0,0);
lockinit(&idmap_gid_hash.hash_lock, PLOCK, "idmap gid hash table", 0,0);
}
void idmap_uninit(void)
{
struct idmap_entry * e;
int i;
lockdestroy(&idmap_uid_hash.hash_lock);
lockdestroy(&idmap_gid_hash.hash_lock);
for (i=0; i<IDMAP_HASH_SIZE; i++) {
while(!TAILQ_EMPTY(&idmap_uid_hash.hash_name[i])) {
e = TAILQ_FIRST(&idmap_uid_hash.hash_name[i]);
TAILQ_REMOVE(&idmap_uid_hash.hash_name[i], e, id_entry_name);
TAILQ_REMOVE(&idmap_uid_hash.hash_id[i], e, id_entry_id);
free(e, M_IDMAP);
}
while(!TAILQ_EMPTY(&idmap_gid_hash.hash_name[i])) {
e = TAILQ_FIRST(&idmap_gid_hash.hash_name[i]);
TAILQ_REMOVE(&idmap_gid_hash.hash_name[i], e, id_entry_name);
TAILQ_REMOVE(&idmap_gid_hash.hash_id[i], e, id_entry_id);
free(e, M_IDMAP);
}
}
}
int
idmap_uid_to_name(uid_t uid, char ** name, size_t * len)
{
struct idmap_entry * e;
int error = 0;
ident_t id;
id.uid = uid;
if ((e = idmap_id_lookup(IDMAP_TYPE_UID, id)) == NULL) {
if ((error = idmap_upcall_id(IDMAP_TYPE_UID, id, &e)) != 0) {
IDMAP_DEBUG("error in upcall\n");
return error;
}
if (e == NULL) {
IDMAP_DEBUG("no error from upcall, but no data returned\n");
return EFAULT;
}
if (idmap_add(e) != 0) {
IDMAP_DEBUG("idmap_add failed\n");
free(e, M_IDMAP);
return EFAULT;
}
}
*name = e->id_info.id_name;
*len = e->id_info.id_namelen;
return 0;
}
int
idmap_gid_to_name(gid_t gid, char ** name, size_t * len)
{
struct idmap_entry * e;
int error = 0;
ident_t id;
id.gid = gid;
if ((e = idmap_id_lookup(IDMAP_TYPE_GID, id)) == NULL) {
if ((error = idmap_upcall_id(IDMAP_TYPE_GID, id, &e))) {
IDMAP_DEBUG("error in upcall\n");
return error;
}
if (e == NULL) {
IDMAP_DEBUG("no error from upcall, but no data returned\n");
return EFAULT;
}
if (idmap_add(e) != 0) {
IDMAP_DEBUG("idmap_add failed\n");
free(e, M_IDMAP);
}
}
*name = e->id_info.id_name;
*len = e->id_info.id_namelen;
return 0;
}
int
idmap_name_to_uid(char * name, size_t len, uid_t * id)
{
struct idmap_entry * e;
int error = 0;
char * namestr;
if (name == NULL )
return EFAULT;
if (len == 0 || len > IDMAP_MAXNAMELEN) {
IDMAP_DEBUG("idmap_name_to_uid: bad len\n");
return EINVAL;
}
/* XXX hack */
namestr = malloc(len + 1, M_TEMP, M_WAITOK);
bcopy(name, namestr, len);
namestr[len] = '\0';
if ((e = idmap_name_lookup(IDMAP_TYPE_UID, namestr)) == NULL) {
if ((error = idmap_upcall_name(IDMAP_TYPE_UID, namestr, &e))) {
free(namestr, M_TEMP);
return error;
}
if (e == NULL) {
IDMAP_DEBUG("no error from upcall, but no data returned\n");
free(namestr, M_TEMP);
return EFAULT;
}
if (idmap_add(e) != 0) {
IDMAP_DEBUG("idmap_add failed\n");
free(e, M_IDMAP);
}
}
*id = e->id_info.id_id.uid;
free(namestr, M_TEMP);
return 0;
}
int
idmap_name_to_gid(char * name, size_t len, gid_t * id)
{
struct idmap_entry * e;
int error = 0;
char * namestr;
if (name == NULL )
return EFAULT;
if (len == 0 || len > IDMAP_MAXNAMELEN) {
IDMAP_DEBUG("idmap_name_to_uid: bad len\n");
return EINVAL;
}
/* XXX hack */
namestr = malloc(len + 1, M_TEMP, M_WAITOK);
bcopy(name, namestr, len);
namestr[len] = '\0';
if ((e = idmap_name_lookup(IDMAP_TYPE_GID, namestr)) == NULL) {
if ((error = idmap_upcall_name(IDMAP_TYPE_GID, namestr, &e)) != 0) {
IDMAP_DEBUG("error in upcall\n");
free(namestr, M_TEMP);
return error;
}
if (e == NULL) {
IDMAP_DEBUG("no error from upcall, but no data returned\n");
free(namestr, M_TEMP);
return EFAULT;
}
if (idmap_add(e) != 0) {
IDMAP_DEBUG("idmap_add failed\n");
free(e, M_IDMAP);
}
}
*id = e->id_info.id_id.gid;
free(namestr, M_TEMP);
return 0;
}

View File

@ -1,64 +0,0 @@
/* $FreeBSD$ */
/* $Id: nfs4_idmap.h,v 1.2 2003/11/05 14:58:59 rees Exp $ */
/*-
* copyright (c) 2003
* the regents of the university of michigan
* all rights reserved
*
* permission is granted to use, copy, create derivative works and redistribute
* this software and such derivative works for any purpose, so long as the name
* of the university of michigan is not used in any advertising or publicity
* pertaining to the use or distribution of this software without specific,
* written prior authorization. if the above copyright notice or any other
* identification of the university of michigan is included in any copy of any
* portion of this software, then the disclaimer below must also be included.
*
* this software is provided as is, without representation from the university
* of michigan as to its fitness for any purpose, and without warranty by the
* university of michigan of any kind, either express or implied, including
* without limitation the implied warranties of merchantability and fitness for
* a particular purpose. the regents of the university of michigan shall not be
* liable for any damages, including special, indirect, incidental, or
* consequential damages, with respect to any claim arising out of or in
* connection with the use of the software, even if it has been or is hereafter
* advised of the possibility of such damages.
*/
#ifndef __NFS4_IDMAP_H__
#define __NFS4_IDMAP_H__
#define IDMAP_TYPE_GID 1
#define IDMAP_TYPE_UID 2
#define IDMAP_MAX_TYPE 2
typedef union {
uid_t uid;
gid_t gid;
} ident_t;
#define IDMAP_MAXNAMELEN 249
struct idmap_msg {
uint32_t id_type;
ident_t id_id;
size_t id_namelen;
char id_name[IDMAP_MAXNAMELEN + 1];
};
#ifdef _KERNEL
MALLOC_DECLARE(M_IDMAP);
void idmap_init(void);
void idmap_uninit(void);
int idmap_gid_to_name(gid_t id, char ** name, size_t * len);
int idmap_uid_to_name(uid_t id, char ** name, size_t * len);
int idmap_name_to_gid(char *, size_t len, gid_t *);
int idmap_name_to_uid(char *, size_t len, uid_t *);
#endif /* _KERNEL */
#endif /* __NFS4_GSS_H__ */

View File

@ -1,348 +0,0 @@
/* $FreeBSD$ */
/* $Id: nfs_socket.c,v 1.12 2003/11/05 14:59:01 rees Exp $ */
/*-
* copyright (c) 2003
* the regents of the university of michigan
* all rights reserved
*
* permission is granted to use, copy, create derivative works and redistribute
* this software and such derivative works for any purpose, so long as the name
* of the university of michigan is not used in any advertising or publicity
* pertaining to the use or distribution of this software without specific,
* written prior authorization. if the above copyright notice or any other
* identification of the university of michigan is included in any copy of any
* portion of this software, then the disclaimer below must also be included.
*
* this software is provided as is, without representation from the university
* of michigan as to its fitness for any purpose, and without warranty by the
* university of michigan of any kind, either express or implied, including
* without limitation the implied warranties of merchantability and fitness for
* a particular purpose. the regents of the university of michigan shall not be
* liable for any damages, including special, indirect, incidental, or
* consequential damages, with respect to any claim arising out of or in
* connection with the use of the software, even if it has been or is hereafter
* advised of the possibility of such damages.
*/
/*-
* Copyright (c) 1989, 1991, 1993, 1995
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Rick Macklem at The University of Guelph.
*
* 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
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* @(#)nfs_socket.c 8.5 (Berkeley) 3/30/95
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
* Socket operations for use by nfs
*/
#include "opt_inet6.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/mount.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/protosw.h>
#include <sys/signalvar.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/syslog.h>
#include <sys/vnode.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <rpc/rpcclnt.h>
#include <nfs/rpcv2.h>
#include <nfs/nfsproto.h>
#include <nfsclient/nfs.h>
#include <nfs4client/nfs4.h>
#include <nfs/xdr_subs.h>
#include <nfsclient/nfsm_subs.h>
#include <nfsclient/nfsmount.h>
#ifdef NFS4_USE_RPCCLNT
#include <rpc/rpcclnt.h>
#include <rpc/rpcm_subs.h>
#endif
#ifdef NFS4_USE_RPCCLNT
static struct rpc_program nfs_program = {
NFS_PROG, NFS_VER4, "NFSv4"
};
#endif
static struct {
short nfserr;
short syserr;
} nfs_errtbl[] = {
{ NFS_OK, 0 },
{ NFSERR_PERM, EPERM },
{ NFSERR_NOENT, ENOENT },
{ NFSERR_IO, EIO },
{ NFSERR_NXIO, ENXIO },
{ NFSERR_ACCES, EACCES },
{ NFSERR_EXIST, EEXIST },
{ NFSERR_XDEV, EXDEV },
{ NFSERR_MLINK, EMLINK },
{ NFSERR_NODEV, ENODEV },
{ NFSERR_NOTDIR, ENOTDIR },
{ NFSERR_ISDIR, EISDIR },
{ NFSERR_INVAL, EINVAL },
{ NFSERR_FBIG, EFBIG },
{ NFSERR_NOSPC, ENOSPC },
{ NFSERR_ROFS, EROFS },
{ NFSERR_MLINK, EMLINK },
{ NFSERR_NAMETOL, ENAMETOOLONG },
{ NFSERR_NOTEMPTY, ENOTEMPTY },
{ NFSERR_NOTSUPP, EOPNOTSUPP },
#ifdef EDQUOT
{ NFSERR_DQUOT, EDQUOT },
#endif
{ NFSERR_STALE, ESTALE },
{ NFSERR_DENIED, EAGAIN },
{ NFSERR_SYMLINK, ELOOP },
{ NFSERR_BADXDR, EBADRPC },
{ NFSERR_WRONGSEC, EPERM },
{ -1, EIO }
};
static int
nfs4_nfserr_to_syserr(int nfserr)
{
int i, syserr;
/* XXX : not the optimal algorithm, but will do for now! */
for (i = 0; nfs_errtbl[i].nfserr != -1; i++) {
if (nfs_errtbl[i].nfserr == nfserr)
break;
}
#ifdef NFS4_MAP_UNKNOWN_ERR
syserr = nfs_errtbl[i].syserr;
#else
if (nfs_errtbl[i].nfserr != -1)
syserr = nfs_errtbl[i].syserr;
else
syserr = nfserr;
#endif
return syserr;
}
int
nfs4_connect(struct nfsmount *nmp)
{
struct rpcclnt * rpc = &nmp->nm_rpcclnt;
struct rpc_auth * auth;
int flag = 0;
int error;
/* XXX hack! */
#ifdef __OpenBSD__
struct proc * td = curproc;
#else
struct thread * td = curthread;
#endif
auth = malloc(sizeof(struct rpc_auth), M_TEMP, M_WAITOK);
auth->auth_type = RPCAUTH_UNIX;
/* translate nfs flags -> rpcclnt flags */
if (nmp->nm_flag & NFSMNT_SOFT)
flag |= RPCCLNT_SOFT;
if (nmp->nm_flag & NFSMNT_INT)
flag |= RPCCLNT_INT;
if (nmp->nm_flag & NFSMNT_NOCONN)
flag |= RPCCLNT_NOCONN;
if (nmp->nm_flag & NFSMNT_DUMBTIMR)
flag |= RPCCLNT_DUMBTIMR;
/* rpc->rc_servername = nmp->nm_mountp->mnt_stat.f_mntfromname; */
error = rpcclnt_setup(rpc, &nfs_program, nmp->nm_nam, nmp->nm_sotype,
nmp->nm_soproto, auth,
/* XXX: check nmp->nm_flag to make sure these are set */
(nmp->nm_rsize > nmp->nm_readdirsize) ? nmp->nm_rsize : nmp->nm_readdirsize,
nmp->nm_wsize, flag);
/* set deadthresh, timeo, retry */
rpc->rc_deadthresh = nmp->nm_deadthresh;
rpc->rc_timeo = nmp->nm_timeo;
rpc->rc_retry = nmp->nm_retry;
if (error)
return error;
return rpcclnt_connect(rpc, td);
}
/*
* NFS disconnect. Clean up and unlink.
*/
void
nfs4_disconnect(struct nfsmount *nmp)
{
rpcclnt_disconnect(&nmp->nm_rpcclnt);
}
void
nfs4_safedisconnect(struct nfsmount *nmp)
{
rpcclnt_safedisconnect(&nmp->nm_rpcclnt);
}
/*
* nfs_request - goes something like this
* - fill in request struct
* - links it into list
* - calls nfs_send() for first transmit
* - calls nfs_receive() to get reply
* - break down rpc header and return with nfs reply pointed to
* by mrep or error
* nb: always frees up mreq mbuf list
*/
/* XXX overloaded before */
#define NQ_TRYLATERDEL 15 /* Initial try later delay (sec) */
int
nfs4_request(struct vnode *vp, struct mbuf *mrest, int procnum,
struct thread *td, struct ucred *cred, struct mbuf **mrp,
struct mbuf **mdp, caddr_t *dposp)
{
int error;
error = nfs4_request_mnt(VFSTONFS(vp->v_mount), mrest, procnum,
td, cred, mrp, mdp, dposp);
/*
** If the File Handle was stale, invalidate the
** lookup cache, just in case.
**/
if (error == ESTALE)
nfs_purgecache(vp);
return (error);
}
int
nfs4_request_mnt(struct nfsmount *nmp, struct mbuf *mrest, int procnum,
struct thread *td, struct ucred *cred, struct mbuf **mrp,
struct mbuf **mdp, caddr_t *dposp)
{
int error;
u_int32_t *tl;
struct rpcclnt * clnt = &nmp->nm_rpcclnt;
struct mbuf *md, *mrep;
caddr_t dpos;
struct rpc_reply reply;
if ((error = rpcclnt_request(clnt, mrest, procnum, td, cred,
&reply)) != 0) {
goto out;
}
/* XXX: don't free mrest if an error occured, to allow caller to retry*/
m_freem(mrest);
mrep = reply.mrep;
md = reply.result_md;
dpos = reply.result_dpos;
tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED);
if (*tl != 0) {
error = fxdr_unsigned(int, *tl);
#if 0
if ((nmp->nm_flag & NFSMNT_NFSV3) &&
error == NFSERR_TRYLATER) {
m_freem(mrep);
error = 0;
waituntil = time_second + trylater_delay;
while (time_second < waituntil)
(void) tsleep(&fake_wchan, PSOCK, "nqnfstry", hz);
trylater_delay *= nfs_backoff[trylater_cnt];
if (trylater_cnt < NFS_NBACKOFF - 1)
trylater_cnt++;
goto tryagain;
}
#endif
goto out;
}
*mrp = mrep;
*mdp = md;
*dposp = dpos;
return (0);
nfsmout:
out:
m_freem(reply.mrep);
*mrp = NULL;
*mdp = NULL;
return (nfs4_nfserr_to_syserr(error));
}
/*
* Mark all of an nfs mount's outstanding requests with R_SOFTTERM and
* wait for all requests to complete. This is used by forced unmounts
* to terminate any outstanding RPCs.
*/
int
nfs4_nmcancelreqs(nmp)
struct nfsmount *nmp;
{
return rpcclnt_cancelreqs(&nmp->nm_rpcclnt);
}
/*
* Test for a termination condition pending on the process.
* This is used for NFSMNT_INT mounts.
*/
int
nfs4_sigintr(struct nfsmount *nmp, struct nfsreq *rep, struct thread *td)
{
if (rep != NULL) {
printf("nfs_sigintr: attempting to use nfsreq != NULL\n");
return EINTR;
}
return rpcclnt_sigintr(&nmp->nm_rpcclnt, NULL, td);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,34 +0,0 @@
/* $FreeBSD$ */
/* $Id: nfs4_vfs.h,v 1.4 2003/11/05 14:59:00 rees Exp $ */
/*-
* copyright (c) 2003
* the regents of the university of michigan
* all rights reserved
*
* permission is granted to use, copy, create derivative works and redistribute
* this software and such derivative works for any purpose, so long as the name
* of the university of michigan is not used in any advertising or publicity
* pertaining to the use or distribution of this software without specific,
* written prior authorization. if the above copyright notice or any other
* identification of the university of michigan is included in any copy of any
* portion of this software, then the disclaimer below must also be included.
*
* this software is provided as is, without representation from the university
* of michigan as to its fitness for any purpose, and without warranty by the
* university of michigan of any kind, either express or implied, including
* without limitation the implied warranties of merchantability and fitness for
* a particular purpose. the regents of the university of michigan shall not be
* liable for any damages, including special, indirect, incidental, or
* consequential damages, with respect to any claim arising out of or in
* connection with the use of the software, even if it has been or is hereafter
* advised of the possibility of such damages.
*/
#ifndef _NFS4CLIENT_NFS4_VFS_H
#define _NFS4CLIENT_NFS4_VFS_H
void nfs4_vfsop_fsinfo(struct nfsv4_fattr *, struct nfsmount *);
void nfs4_vfsop_statfs(struct nfsv4_fattr *, struct statfs *, struct mount *);
#endif /* _NFS4CLIENT_NFS4_VFS_H */

View File

@ -1,125 +0,0 @@
/* $FreeBSD$ */
/* $Id: nfs4_vfs_subs.c,v 1.5 2003/11/05 14:59:00 rees Exp $ */
/*-
* copyright (c) 2003
* the regents of the university of michigan
* all rights reserved
*
* permission is granted to use, copy, create derivative works and redistribute
* this software and such derivative works for any purpose, so long as the name
* of the university of michigan is not used in any advertising or publicity
* pertaining to the use or distribution of this software without specific,
* written prior authorization. if the above copyright notice or any other
* identification of the university of michigan is included in any copy of any
* portion of this software, then the disclaimer below must also be included.
*
* this software is provided as is, without representation from the university
* of michigan as to its fitness for any purpose, and without warranty by the
* university of michigan of any kind, either express or implied, including
* without limitation the implied warranties of merchantability and fitness for
* a particular purpose. the regents of the university of michigan shall not be
* liable for any damages, including special, indirect, incidental, or
* consequential damages, with respect to any claim arising out of or in
* connection with the use of the software, even if it has been or is hereafter
* advised of the possibility of such damages.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/limits.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/module.h>
#include <sys/mount.h>
#include <sys/proc.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/sockio.h>
#include <sys/vnode.h>
#include <vm/vm.h>
#include <vm/vm_extern.h>
#include <vm/uma.h>
#include <net/if.h>
#include <net/route.h>
#include <netinet/in.h>
#include <rpc/rpcclnt.h>
#include <nfs/rpcv2.h>
#include <nfs/nfsproto.h>
#include <nfsclient/nfs.h>
#include <nfsclient/nfsmount.h>
#include <nfs/xdr_subs.h>
#include <nfsclient/nfsm_subs.h>
#include <nfsclient/nfsdiskless.h>
/* NFSv4 */
#include <nfs4client/nfs4.h>
#include <nfs4client/nfs4m_subs.h>
#include <nfs4client/nfs4_vfs.h>
#include <nfsclient/nfsnode.h>
void
nfs4_vfsop_fsinfo(struct nfsv4_fattr *fap, struct nfsmount *nmp)
{
uint32_t max;
if (fap->fa4_valid & FA4V_FSID) {
nmp->nm_fsid.val[0] = fap->fa4_fsid_major;
nmp->nm_fsid.val[1] = fap->fa4_fsid_minor;
}
if (fap->fa4_valid & FA4V_MAXREAD) {
max = fap->fa4_maxread;
if (max < nmp->nm_rsize) {
nmp->nm_rsize = max & ~(NFS_FABLKSIZE - 1);
if (nmp->nm_rsize == 0)
nmp->nm_rsize = max;
}
if (max < nmp->nm_readdirsize) {
nmp->nm_readdirsize = max & ~(NFS_DIRBLKSIZ - 1);
if (nmp->nm_readdirsize == 0)
nmp->nm_readdirsize = max;
}
}
if (fap->fa4_valid & FA4V_MAXWRITE) {
max = fap->fa4_maxwrite;
if (max < nmp->nm_wsize) {
nmp->nm_wsize = max & ~(NFS_FABLKSIZE - 1);
if (nmp->nm_wsize == 0)
nmp->nm_wsize = max;
}
}
if (fap->fa4_valid & FA4V_LEASE_TIME)
nmp->nm_lease_time = fap->fa4_lease_time;
/* nmp->nm_flag |= NFSMNT_GOTFSINFO; */
}
void
nfs4_vfsop_statfs(struct nfsv4_fattr *fap, struct statfs *sbp, struct mount *mp)
{
struct nfsmount *nmp = VFSTONFS(mp);
sbp->f_iosize = nfs_iosize(nmp);
sbp->f_bsize = NFS_FABLKSIZE;
if (fap->fa4_valid & FA4V_FSID) {
sbp->f_fsid.val[0] = fap->fa4_fsid_major;
sbp->f_fsid.val[1] = fap->fa4_fsid_minor;
}
sbp->f_ffree = fap->fa4_valid & FA4V_FFREE ? fap->fa4_ffree : 0;
/* sbp->f_ftotal = fa->fa4_valid & FA4_FTOTAL ? fa->fa4_ftotal : 0; */
sbp->f_bavail = fap->fa4_valid & FA4V_SAVAIL ?
fap->fa4_savail / NFS_FABLKSIZE : 500000;
sbp->f_bfree = fap->fa4_valid & FA4V_SFREE ?
fap->fa4_sfree / NFS_FABLKSIZE : 500000;
sbp->f_blocks = fap->fa4_valid & FA4V_STOTAL ?
fap->fa4_stotal / NFS_FABLKSIZE : 1000000;
}

View File

@ -1,886 +0,0 @@
/* $Id: nfs_vfsops.c,v 1.38 2003/11/05 14:59:01 rees Exp $ */
/*-
* copyright (c) 2003
* the regents of the university of michigan
* all rights reserved
*
* permission is granted to use, copy, create derivative works and redistribute
* this software and such derivative works for any purpose, so long as the name
* of the university of michigan is not used in any advertising or publicity
* pertaining to the use or distribution of this software without specific,
* written prior authorization. if the above copyright notice or any other
* identification of the university of michigan is included in any copy of any
* portion of this software, then the disclaimer below must also be included.
*
* this software is provided as is, without representation from the university
* of michigan as to its fitness for any purpose, and without warranty by the
* university of michigan of any kind, either express or implied, including
* without limitation the implied warranties of merchantability and fitness for
* a particular purpose. the regents of the university of michigan shall not be
* liable for any damages, including special, indirect, incidental, or
* consequential damages, with respect to any claim arising out of or in
* connection with the use of the software, even if it has been or is hereafter
* advised of the possibility of such damages.
*/
/*-
* Copyright (c) 1989, 1993, 1995
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Rick Macklem at The University of Guelph.
*
* 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
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* @(#)nfs_vfsops.c 8.12 (Berkeley) 5/20/95
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include "opt_bootp.h"
#include "opt_nfsroot.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/kthread.h>
#include <sys/limits.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/module.h>
#include <sys/mount.h>
#include <sys/proc.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/sockio.h>
#include <sys/sysctl.h>
#include <sys/unistd.h>
#include <sys/vnode.h>
#include <sys/signalvar.h>
#include <vm/vm.h>
#include <vm/vm_extern.h>
#include <vm/uma.h>
#include <net/if.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_var.h>
#include <rpc/rpcclnt.h>
#include <nfs/rpcv2.h>
#include <nfs/nfsproto.h>
#include <nfsclient/nfs.h>
#include <nfs4client/nfs4.h>
#include <nfsclient/nfsnode.h>
#include <nfsclient/nfsmount.h>
#include <nfs/xdr_subs.h>
#include <nfsclient/nfsm_subs.h>
#include <nfsclient/nfsdiskless.h>
#include <nfs4client/nfs4m_subs.h>
#include <nfs4client/nfs4_vfs.h>
#include <nfs4client/nfs4_dev.h>
#include <nfs4client/nfs4_idmap.h>
SYSCTL_NODE(_vfs, OID_AUTO, nfs4, CTLFLAG_RW, 0, "NFS4 filesystem");
SYSCTL_STRUCT(_vfs_nfs4, NFS_NFSSTATS, nfsstats, CTLFLAG_RD,
&nfsstats, nfsstats, "S,nfsstats");
static void nfs4_decode_args(struct nfsmount *nmp, struct nfs_args *argp);
static void nfs4_daemon(void *arg);
static int mountnfs(struct nfs_args *, struct mount *,
struct sockaddr *, char *, struct vnode **,
struct ucred *cred);
static int nfs4_do_setclientid(struct nfsmount *nmp, struct ucred *cred);
static vfs_mount_t nfs4_mount;
static vfs_cmount_t nfs4_cmount;
static vfs_unmount_t nfs4_unmount;
static vfs_root_t nfs4_root;
static vfs_statfs_t nfs4_statfs;
static vfs_sync_t nfs4_sync;
static int fake_wchan;
/*
* nfs vfs operations.
*/
static struct vfsops nfs4_vfsops = {
.vfs_init = nfs4_init,
.vfs_mount = nfs4_mount,
.vfs_cmount = nfs4_cmount,
.vfs_root = nfs4_root,
.vfs_statfs = nfs4_statfs,
.vfs_sync = nfs4_sync,
.vfs_uninit = nfs4_uninit,
.vfs_unmount = nfs4_unmount,
};
VFS_SET(nfs4_vfsops, nfs4, VFCF_NETWORK);
static struct nfs_rpcops nfs4_rpcops = {
nfs4_readrpc,
nfs4_writerpc,
nfs4_writebp,
nfs4_readlinkrpc,
nfs4_invaldir,
nfs4_commit,
};
/* So that loader and kldload(2) can find us, wherever we are.. */
MODULE_VERSION(nfs4, 1);
void nfsargs_ntoh(struct nfs_args *);
int
nfs4_init(struct vfsconf *vfsp)
{
rpcclnt_init();
nfs4dev_init();
idmap_init();
nfsm_v4init();
return (0);
}
int
nfs4_uninit(struct vfsconf *vfsp)
{
rpcclnt_uninit();
nfs4dev_uninit();
idmap_uninit();
return (0);
}
/*
* nfs statfs call
*/
static int
nfs4_statfs(struct mount *mp, struct statfs *sbp)
{
struct vnode *vp;
struct thread *td;
struct nfs_statfs *sfp;
caddr_t bpos, dpos;
struct nfsmount *nmp = VFSTONFS(mp);
int error = 0;
struct mbuf *mreq, *mrep = NULL, *md, *mb;
struct nfsnode *np;
struct nfs4_compound cp;
struct nfs4_oparg_getattr ga;
struct nfsv4_fattr *fap = &ga.fa;
td = curthread;
#ifndef nolint
sfp = NULL;
#endif
error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE);
if (error)
return (error);
vp = NFSTOV(np);
nfsstats.rpccnt[NFSPROC_FSSTAT]++;
mreq = nfsm_reqhead(vp, NFSV4PROC_COMPOUND, NFSX_FH(1));
mb = mreq;
bpos = mtod(mb, caddr_t);
ga.bm = &nfsv4_fsattrbm;
nfs_v4initcompound(&cp);
nfsm_v4build_compound(&cp, "statfs()");
nfsm_v4build_putfh(&cp, vp);
nfsm_v4build_getattr(&cp, &ga);
nfsm_v4build_finalize(&cp);
nfsm_request(vp, NFSV4PROC_COMPOUND, td, td->td_ucred);
if (error != 0)
goto nfsmout;
nfsm_v4dissect_compound(&cp);
nfsm_v4dissect_putfh(&cp);
nfsm_v4dissect_getattr(&cp, &ga);
nfs4_vfsop_statfs(fap, sbp, mp);
nfsmout:
error = nfs_v4postop(&cp, error);
vput(vp);
if (mrep != NULL)
m_freem(mrep);
return (error);
}
static void
nfs4_decode_args(struct nfsmount *nmp, struct nfs_args *argp)
{
int s;
int adjsock;
int maxio;
s = splnet();
/*
* Silently clear NFSMNT_NOCONN if it's a TCP mount, it makes
* no sense in that context. Also, set appropriate retransmit
* and soft timeout behavior.
*/
if (argp->sotype == SOCK_STREAM) {
nmp->nm_flag &= ~NFSMNT_NOCONN;
nmp->nm_flag |= NFSMNT_DUMBTIMR;
nmp->nm_timeo = NFS_MAXTIMEO;
nmp->nm_retry = NFS_RETRANS_TCP;
}
nmp->nm_flag &= ~NFSMNT_RDIRPLUS;
/* Re-bind if rsrvd port requested and wasn't on one */
adjsock = !(nmp->nm_flag & NFSMNT_RESVPORT)
&& (argp->flags & NFSMNT_RESVPORT);
/* Also re-bind if we're switching to/from a connected UDP socket */
adjsock |= ((nmp->nm_flag & NFSMNT_NOCONN) !=
(argp->flags & NFSMNT_NOCONN));
/* Update flags atomically. Don't change the lock bits. */
nmp->nm_flag = argp->flags | nmp->nm_flag;
splx(s);
if ((argp->flags & NFSMNT_TIMEO) && argp->timeo > 0) {
nmp->nm_timeo = (argp->timeo * NFS_HZ + 5) / 10;
if (nmp->nm_timeo < NFS_MINTIMEO)
nmp->nm_timeo = NFS_MINTIMEO;
else if (nmp->nm_timeo > NFS_MAXTIMEO)
nmp->nm_timeo = NFS_MAXTIMEO;
}
if ((argp->flags & NFSMNT_RETRANS) && argp->retrans > 1) {
nmp->nm_retry = argp->retrans;
if (nmp->nm_retry > NFS_MAXREXMIT)
nmp->nm_retry = NFS_MAXREXMIT;
}
if (argp->flags & NFSMNT_NFSV3) {
if (argp->sotype == SOCK_DGRAM)
maxio = NFS_MAXDGRAMDATA;
else
maxio = NFS_MAXDATA;
} else
maxio = NFS_V2MAXDATA;
if ((argp->flags & NFSMNT_WSIZE) && argp->wsize > 0) {
nmp->nm_wsize = argp->wsize;
/* Round down to multiple of blocksize */
nmp->nm_wsize &= ~(NFS_FABLKSIZE - 1);
if (nmp->nm_wsize <= 0)
nmp->nm_wsize = NFS_FABLKSIZE;
}
if (nmp->nm_wsize > maxio)
nmp->nm_wsize = maxio;
if (nmp->nm_wsize > MAXBSIZE)
nmp->nm_wsize = MAXBSIZE;
if ((argp->flags & NFSMNT_RSIZE) && argp->rsize > 0) {
nmp->nm_rsize = argp->rsize;
/* Round down to multiple of blocksize */
nmp->nm_rsize &= ~(NFS_FABLKSIZE - 1);
if (nmp->nm_rsize <= 0)
nmp->nm_rsize = NFS_FABLKSIZE;
}
if (nmp->nm_rsize > maxio)
nmp->nm_rsize = maxio;
if (nmp->nm_rsize > MAXBSIZE)
nmp->nm_rsize = MAXBSIZE;
if ((argp->flags & NFSMNT_READDIRSIZE) && argp->readdirsize > 0) {
nmp->nm_readdirsize = argp->readdirsize;
}
if (nmp->nm_readdirsize > maxio)
nmp->nm_readdirsize = maxio;
if (nmp->nm_readdirsize > nmp->nm_rsize)
nmp->nm_readdirsize = nmp->nm_rsize;
if ((argp->flags & NFSMNT_ACREGMIN) && argp->acregmin >= 0)
nmp->nm_acregmin = argp->acregmin;
else
nmp->nm_acregmin = NFS_MINATTRTIMO;
if ((argp->flags & NFSMNT_ACREGMAX) && argp->acregmax >= 0)
nmp->nm_acregmax = argp->acregmax;
else
nmp->nm_acregmax = NFS_MAXATTRTIMO;
if ((argp->flags & NFSMNT_ACDIRMIN) && argp->acdirmin >= 0)
nmp->nm_acdirmin = argp->acdirmin;
else
nmp->nm_acdirmin = NFS_MINDIRATTRTIMO;
if ((argp->flags & NFSMNT_ACDIRMAX) && argp->acdirmax >= 0)
nmp->nm_acdirmax = argp->acdirmax;
else
nmp->nm_acdirmax = NFS_MAXDIRATTRTIMO;
if (nmp->nm_acdirmin > nmp->nm_acdirmax)
nmp->nm_acdirmin = nmp->nm_acdirmax;
if (nmp->nm_acregmin > nmp->nm_acregmax)
nmp->nm_acregmin = nmp->nm_acregmax;
if ((argp->flags & NFSMNT_MAXGRPS) && argp->maxgrouplist >= 0) {
if (argp->maxgrouplist <= NFS_MAXGRPS)
nmp->nm_numgrps = argp->maxgrouplist;
else
nmp->nm_numgrps = NFS_MAXGRPS;
}
if ((argp->flags & NFSMNT_READAHEAD) && argp->readahead >= 0) {
if (argp->readahead <= NFS_MAXRAHEAD)
nmp->nm_readahead = argp->readahead;
else
nmp->nm_readahead = NFS_MAXRAHEAD;
}
if ((argp->flags & NFSMNT_DEADTHRESH) && argp->deadthresh >= 0) {
if (argp->deadthresh <= NFS_MAXDEADTHRESH)
nmp->nm_deadthresh = argp->deadthresh;
else
nmp->nm_deadthresh = NFS_MAXDEADTHRESH;
}
adjsock |= ((nmp->nm_sotype != argp->sotype) ||
(nmp->nm_soproto != argp->proto));
nmp->nm_sotype = argp->sotype;
nmp->nm_soproto = argp->proto;
if (nmp->nm_rpcclnt.rc_so && adjsock) {
nfs_safedisconnect(nmp);
if (nmp->nm_sotype == SOCK_DGRAM) {
while (nfs4_connect(nmp)) {
printf("nfs4_decode_args: retrying connect\n");
(void)tsleep(&fake_wchan, PSOCK, "nfscon", hz);
}
}
}
}
/*
* VFS Operations.
*
* mount system call
* It seems a bit dumb to copyinstr() the host and path here and then
* bcopy() them in mountnfs(), but I wanted to detect errors before
* doing the sockargs() call because sockargs() allocates an mbuf and
* an error after that means that I have to release the mbuf.
*/
/* ARGSUSED */
static int
nfs4_cmount(struct mntarg *ma, void *data, int flags)
{
struct nfs_args args;
int error;
error = copyin(data, &args, sizeof(struct nfs_args));
if (error)
return (error);
ma = mount_arg(ma, "nfs_args", &args, sizeof args);
error = kernel_mount(ma, flags);
return (error);
}
static int
nfs4_mount(struct mount *mp)
{
int error;
struct nfs_args args;
struct sockaddr *nam;
struct vnode *vp;
char hst[MNAMELEN];
size_t len;
if (mp->mnt_flag & MNT_ROOTFS) {
printf("nfs4_mountroot not supported\n");
return (EINVAL);
}
error = vfs_copyopt(mp->mnt_optnew, "nfs_args", &args, sizeof args);
if (error)
return (error);
if (args.version != NFS_ARGSVERSION)
return (EPROGMISMATCH);
if (mp->mnt_flag & MNT_UPDATE) {
struct nfsmount *nmp = VFSTONFS(mp);
if (nmp == NULL)
return (EIO);
/*
* When doing an update, we can't change from or to
* v3, switch lockd strategies or change cookie translation
*/
args.flags = (args.flags &
~(NFSMNT_NFSV3 | NFSMNT_NFSV4 | NFSMNT_NOLOCKD)) |
(nmp->nm_flag &
(NFSMNT_NFSV3 | NFSMNT_NFSV4 | NFSMNT_NOLOCKD));
nfs4_decode_args(nmp, &args);
return (0);
}
error = copyinstr(args.hostname, hst, MNAMELEN-1, &len);
if (error)
return (error);
bzero(&hst[len], MNAMELEN - len);
/* sockargs() call must be after above copyin() calls */
error = getsockaddr(&nam, (caddr_t)args.addr, args.addrlen);
if (error)
return (error);
error = mountnfs(&args, mp, nam, hst, &vp, curthread->td_ucred);
return (error);
}
/*
* renew should be done async
* should re-scan mount queue each time
*/
struct proc *nfs4_daemonproc;
static int
nfs4_do_renew(struct nfsmount *nmp, struct ucred *cred)
{
struct nfs4_compound cp;
struct mbuf *mreq, *mrep = NULL, *md, *mb;
caddr_t bpos, dpos;
int error;
mreq = nfsm_reqhead(NULL, NFSV4PROC_COMPOUND, sizeof(uint64_t));
mb = mreq;
bpos = mtod(mb, caddr_t);
nfs_v4initcompound(&cp);
nfsm_v4build_compound(&cp, "nfs4_do_renew()");
nfsm_v4build_renew(&cp, nmp->nm_clientid);
nfsm_v4build_finalize(&cp);
nfsm_request_mnt(nmp, NFSV4PROC_COMPOUND, curthread, cred);
if (error != 0)
goto nfsmout;
nfsm_v4dissect_compound(&cp);
nfsm_v4dissect_renew(&cp);
nmp->nm_last_renewal = time_second;
return (0);
nfsmout:
error = nfs_v4postop(&cp, error);
/* XXX */
if (mrep != NULL)
m_freem(mrep);
return (error);
}
static void
nfs4_daemon(void *arg)
{
struct mount *mp;
struct nfsmount *nmp;
int nmounts;
while (1) {
nmounts = 0;
mtx_lock(&mountlist_mtx);
TAILQ_FOREACH(mp, &mountlist, mnt_list) {
if (strcmp(mp->mnt_vfc->vfc_name, "nfs4") != 0)
continue;
nmounts++;
nmp = VFSTONFS(mp);
if (time_second < nmp->nm_last_renewal + nmp->nm_lease_time - 4)
continue;
mtx_unlock(&mountlist_mtx);
mtx_lock(&Giant);
nfs4_do_renew(nmp, (struct ucred *) arg);
mtx_unlock(&Giant);
mtx_lock(&mountlist_mtx);
}
mtx_unlock(&mountlist_mtx);
/* Must kill the daemon here, or module unload will cause a panic */
if (nmounts == 0) {
mtx_lock(&Giant);
nfs4_daemonproc = NULL;
mtx_unlock(&Giant);
/*printf("nfsv4 renewd exiting\n");*/
kproc_exit(0);
}
tsleep(&nfs4_daemonproc, PVFS, "nfs4", 2 * hz);
}
}
/*
* Common code for mount and mountroot
*/
static int
mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
char *hst, struct vnode **vpp, struct ucred *cred)
{
struct nfsmount *nmp;
char *rpth, *cp1, *cp2;
int nlkup = 0, error;
struct nfs4_compound cp;
struct mbuf *mreq, *mrep = NULL, *md, *mb;
caddr_t bpos, dpos;
struct nfs4_oparg_lookup lkup;
struct nfs4_oparg_getfh gfh;
struct nfs4_oparg_getattr ga;
struct thread *td = curthread; /* XXX */
if (mp->mnt_flag & MNT_UPDATE) {
nmp = VFSTONFS(mp);
/* update paths, file handles, etc, here XXX */
free(nam, M_SONAME);
return (0);
} else {
nmp = uma_zalloc(nfsmount_zone, M_WAITOK);
bzero((caddr_t)nmp, sizeof (struct nfsmount));
TAILQ_INIT(&nmp->nm_bufq);
mp->mnt_data = nmp;
}
vfs_getnewfsid(mp);
nmp->nm_mountp = mp;
mtx_init(&nmp->nm_mtx, "NFS4mount lock", NULL, MTX_DEF);
nmp->nm_maxfilesize = 0xffffffffLL;
nmp->nm_timeo = NFS_TIMEO;
nmp->nm_retry = NFS_RETRANS;
nmp->nm_wsize = NFS_WSIZE;
nmp->nm_rsize = NFS_RSIZE;
nmp->nm_readdirsize = NFS_READDIRSIZE;
nmp->nm_numgrps = NFS_MAXGRPS;
nmp->nm_readahead = NFS_DEFRAHEAD;
nmp->nm_deadthresh = NFS_MAXDEADTHRESH;
vfs_mountedfrom(mp, hst);
nmp->nm_nam = nam;
/* Set up the sockets and per-host congestion */
nmp->nm_sotype = argp->sotype;
nmp->nm_soproto = argp->proto;
nmp->nm_rpcops = &nfs4_rpcops;
/* XXX */
mp->mnt_stat.f_iosize = PAGE_SIZE;
argp->flags |= (NFSMNT_NFSV3 | NFSMNT_NFSV4);
nfs4_decode_args(nmp, argp);
if ((error = nfs4_connect(nmp)))
goto bad;
mreq = nfsm_reqhead(NULL, NFSV4PROC_COMPOUND, NFSX_FH(1));
mb = mreq;
bpos = mtod(mb, caddr_t);
ga.bm = &nfsv4_fsinfobm;
nfs_v4initcompound(&cp);
/* Get remote path */
rpth = hst;
strsep(&rpth, ":");
nfsm_v4build_compound(&cp, "mountnfs()");
nfsm_v4build_putrootfh(&cp);
for (cp1 = rpth; cp1 && *cp1; cp1 = cp2) {
while (*cp1 == '/')
cp1++;
if (!*cp1)
break;
for (cp2 = cp1; *cp2 && *cp2 != '/'; cp2++)
;
lkup.name = cp1;
lkup.namelen = cp2 - cp1;
nfsm_v4build_lookup(&cp, &lkup);
nlkup++;
}
nfsm_v4build_getfh(&cp, &gfh);
nfsm_v4build_getattr(&cp, &ga);
nfsm_v4build_finalize(&cp);
nfsm_request_mnt(nmp, NFSV4PROC_COMPOUND, td, cred);
if (error != 0)
goto nfsmout;
nfsm_v4dissect_compound(&cp);
nfsm_v4dissect_putrootfh(&cp);
while (nlkup--)
nfsm_v4dissect_lookup(&cp);
nfsm_v4dissect_getfh(&cp, &gfh);
nfsm_v4dissect_getattr(&cp, &ga);
nfs4_vfsop_fsinfo(&ga.fa, nmp);
nmp->nm_state |= NFSSTA_GOTFSINFO;
/* Copy root fh into nfsmount. */
nmp->nm_fhsize = gfh.fh_len;
bcopy(&gfh.fh_val, nmp->nm_fh, nmp->nm_fhsize);
nmp->nm_last_renewal = time_second;
if ((error = nfs4_do_setclientid(nmp, cred)) != 0)
goto nfsmout;
/* Start renewd if it isn't already running */
if (nfs4_daemonproc == NULL)
kproc_create(nfs4_daemon, crdup(cred), &nfs4_daemonproc,
(RFPROC|RFMEM), 0, "nfs4rd");
return (0);
nfsmout:
error = nfs_v4postop(&cp, error);
/* XXX */
if (mrep != NULL)
m_freem(mrep);
bad:
mtx_destroy(&nmp->nm_mtx);
nfs4_disconnect(nmp);
uma_zfree(nfsmount_zone, nmp);
free(nam, M_SONAME);
return (error);
}
/*
* unmount system call
*/
static int
nfs4_unmount(struct mount *mp, int mntflags)
{
struct nfsmount *nmp;
int error, flags = 0;
if (mntflags & MNT_FORCE)
flags |= FORCECLOSE;
nmp = VFSTONFS(mp);
/*
* Goes something like this..
* - Call vflush to clear out vnodes for this filesystem
* - Close the socket
* - Free up the data structures
*/
/* In the forced case, cancel any outstanding requests. */
if (flags & FORCECLOSE) {
error = nfs_nmcancelreqs(nmp);
if (error)
return (error);
nfs4dev_purge();
}
error = vflush(mp, 0, flags, curthread);
if (error)
return (error);
/*
* We are now committed to the unmount.
*/
nfs4_disconnect(nmp);
free(nmp->nm_nam, M_SONAME);
/* XXX there's a race condition here for SMP */
wakeup(&nfs4_daemonproc);
mtx_destroy(&nmp->nm_mtx);
uma_zfree(nfsmount_zone, nmp);
return (0);
}
/*
* Return root of a filesystem
*/
static int
nfs4_root(struct mount *mp, int flags, struct vnode **vpp)
{
struct vnode *vp;
struct nfsmount *nmp;
struct nfsnode *np;
int error;
nmp = VFSTONFS(mp);
error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np,
LK_EXCLUSIVE);
if (error)
return (error);
vp = NFSTOV(np);
if (vp->v_type == VNON)
vp->v_type = VDIR;
vp->v_vflag |= VV_ROOT;
*vpp = vp;
return (0);
}
/*
* Flush out the buffer cache
*/
static int
nfs4_sync(struct mount *mp, int waitfor)
{
struct vnode *vp, *mvp;
struct thread *td;
int error, allerror = 0;
td = curthread;
/*
* Force stale buffer cache information to be flushed.
*/
MNT_ILOCK(mp);
loop:
MNT_VNODE_FOREACH(vp, mp, mvp) {
VI_LOCK(vp);
MNT_IUNLOCK(mp);
/* XXX racy bv_cnt check. */
if (VOP_ISLOCKED(vp) || vp->v_bufobj.bo_dirty.bv_cnt == 0 ||
waitfor == MNT_LAZY) {
VI_UNLOCK(vp);
MNT_ILOCK(mp);
continue;
}
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
MNT_ILOCK(mp);
MNT_VNODE_FOREACH_ABORT_ILOCKED(mp, mvp);
goto loop;
}
error = VOP_FSYNC(vp, waitfor, td);
if (error)
allerror = error;
VOP_UNLOCK(vp, 0);
vrele(vp);
MNT_ILOCK(mp);
}
MNT_IUNLOCK(mp);
return (allerror);
}
static int
nfs4_do_setclientid(struct nfsmount *nmp, struct ucred *cred)
{
struct nfs4_oparg_setclientid scid;
struct nfs4_compound cp;
struct mbuf *mreq, *mrep = NULL, *md, *mb;
caddr_t bpos, dpos;
struct route ro;
char *ipsrc = NULL, uaddr[24], name[24];
int try = 0;
static unsigned long seq;
int error;
#ifndef NFS4_USE_RPCCLNT
return (0);
#endif
if (nmp->nm_clientid) {
printf("nfs4_do_setclientid: already have clientid!\n");
error = 0;
goto nfsmout;
}
/* Try not to re-use clientids */
if (seq == 0)
seq = time_second;
#ifdef NFS4_USE_RPCCLNT
scid.cb_netid = (nmp->nm_rpcclnt.rc_sotype == SOCK_STREAM) ? "tcp" : "udp";
#endif
scid.cb_netid = "tcp";
scid.cb_netidlen = 3;
scid.cb_prog = 0x1234; /* XXX */
/* Do a route lookup to find our source address for talking to this server */
bzero(&ro, sizeof ro);
#ifdef NFS4_USE_RPCCLNT
ro.ro_dst = *nmp->nm_rpcclnt.rc_name;
#endif
/* XXX MRT NFS uses table 0 */
in_rtalloc(&ro, 0);
if (ro.ro_rt == NULL) {
error = EHOSTUNREACH;
goto nfsmout;
}
ipsrc = inet_ntoa(IA_SIN(ifatoia(ro.ro_rt->rt_ifa))->sin_addr);
sprintf(uaddr, "%s.12.48", ipsrc);
scid.cb_univaddr = uaddr;
scid.cb_univaddrlen = strlen(uaddr);
RTFREE(ro.ro_rt);
try_again:
sprintf(name, "%s-%d", ipsrc, (int) ((seq + try) % 1000000L));
scid.namelen = strlen(name);
scid.name = name;
nfs_v4initcompound(&cp);
mreq = nfsm_reqhead(NULL, NFSV4PROC_COMPOUND, NFSX_FH(1));
mb = mreq;
bpos = mtod(mb, caddr_t);
nfsm_v4build_compound(&cp, "nfs4_do_setclientid()");
nfsm_v4build_setclientid(&cp, &scid);
nfsm_v4build_finalize(&cp);
nfsm_request_mnt(nmp, NFSV4PROC_COMPOUND, curthread, cred);
if (error != 0)
goto nfsmout;
nfsm_v4dissect_compound(&cp);
nfsm_v4dissect_setclientid(&cp, &scid);
nmp->nm_clientid = scid.clientid;
error = nfs_v4postop(&cp, error);
/* Confirm */
m_freem(mrep);
mreq = nfsm_reqhead(NULL, NFSV4PROC_COMPOUND, NFSX_FH(1));
mb = mreq;
bpos = mtod(mb, caddr_t);
nfs_v4initcompound(&cp);
nfsm_v4build_compound(&cp, "nfs4_do_setclientid() (confirm)");
nfsm_v4build_setclientid_confirm(&cp, &scid);
nfsm_v4build_finalize(&cp);
nfsm_request_mnt(nmp, NFSV4PROC_COMPOUND, curthread, cred);
if (error != 0)
goto nfsmout;
nfsm_v4dissect_compound(&cp);
nfsm_v4dissect_setclientid_confirm(&cp);
nfsmout:
error = nfs_v4postop(&cp, error);
if (mrep)
m_freem(mrep);
if (error == NFSERR_CLID_INUSE && (++try < NFS4_SETCLIENTID_MAXTRIES))
goto try_again;
return (error);
}

View File

@ -1,33 +0,0 @@
/* $FreeBSD$ */
/* $Id: nfs4_vn.h,v 1.5 2003/11/05 14:59:00 rees Exp $ */
/*-
* copyright (c) 2003
* the regents of the university of michigan
* all rights reserved
*
* permission is granted to use, copy, create derivative works and redistribute
* this software and such derivative works for any purpose, so long as the name
* of the university of michigan is not used in any advertising or publicity
* pertaining to the use or distribution of this software without specific,
* written prior authorization. if the above copyright notice or any other
* identification of the university of michigan is included in any copy of any
* portion of this software, then the disclaimer below must also be included.
*
* this software is provided as is, without representation from the university
* of michigan as to its fitness for any purpose, and without warranty by the
* university of michigan of any kind, either express or implied, including
* without limitation the implied warranties of merchantability and fitness for
* a particular purpose. the regents of the university of michigan shall not be
* liable for any damages, including special, indirect, incidental, or
* consequential damages, with respect to any claim arising out of or in
* connection with the use of the software, even if it has been or is hereafter
* advised of the possibility of such damages.
*/
#ifndef _NFS4CLIENT_NFS4_VFS_H
#define _NFS4CLIENT_NFS4_VFS_H
void nfs4_vnop_loadattrcache(struct vnode *, struct nfsv4_fattr *, struct vattr *);
#endif /* _NFS4CLIENT_NFS4_VFS_H */

View File

@ -1,225 +0,0 @@
/* $FreeBSD$ */
/* $Id: nfs4_vn_subs.c,v 1.9 2003/11/05 14:59:00 rees Exp $ */
/*-
* copyright (c) 2003
* the regents of the university of michigan
* all rights reserved
*
* permission is granted to use, copy, create derivative works and redistribute
* this software and such derivative works for any purpose, so long as the name
* of the university of michigan is not used in any advertising or publicity
* pertaining to the use or distribution of this software without specific,
* written prior authorization. if the above copyright notice or any other
* identification of the university of michigan is included in any copy of any
* portion of this software, then the disclaimer below must also be included.
*
* this software is provided as is, without representation from the university
* of michigan as to its fitness for any purpose, and without warranty by the
* university of michigan of any kind, either express or implied, including
* without limitation the implied warranties of merchantability and fitness for
* a particular purpose. the regents of the university of michigan shall not be
* liable for any damages, including special, indirect, incidental, or
* consequential damages, with respect to any claim arising out of or in
* connection with the use of the software, even if it has been or is hereafter
* advised of the possibility of such damages.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/limits.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/module.h>
#include <sys/mount.h>
#include <sys/proc.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/sockio.h>
#include <sys/vnode.h>
#include <sys/types.h>
#include <vm/vm.h>
#include <vm/vm_extern.h>
#include <vm/uma.h>
#include <net/if.h>
#include <net/route.h>
#include <netinet/in.h>
#include <rpc/rpcclnt.h>
#include <nfs/rpcv2.h>
#include <nfs/nfsproto.h>
#include <nfsclient/nfs.h>
#include <nfsclient/nfsmount.h>
#include <nfs/xdr_subs.h>
#include <nfsclient/nfsm_subs.h>
#include <nfsclient/nfsdiskless.h>
/* NFSv4 */
#include <nfs4client/nfs4.h>
#include <nfs4client/nfs4m_subs.h>
#include <nfs4client/nfs4_vn.h>
#include <nfsclient/nfsnode.h>
void
nfs4_vnop_loadattrcache(struct vnode *vp, struct nfsv4_fattr *fap,
struct vattr *vaper)
{
struct vattr *vap;
struct nfsnode *np;
int32_t rdev;
enum vtype vtyp;
u_short vmode;
struct timespec mtime;
struct timeval tv;
microtime(&tv);
vtyp = nv3tov_type[fap->fa4_type & 0x7];
vmode = (fap->fa4_valid & FA4V_MODE) ? fap->fa4_mode : 0777;
rdev = (fap->fa4_valid & FA4V_RDEV) ?
makedev(fap->fa4_rdev_major, fap->fa4_rdev_minor) : 0;
if (fap->fa4_valid & FA4V_MTIME)
mtime = fap->fa4_mtime;
else
bzero(&mtime, sizeof mtime);
/*
* If v_type == VNON it is a new node, so fill in the v_type,
* n_mtime fields. Check to see if it represents a special
* device, and if so, check for a possible alias. Once the
* correct vnode has been obtained, fill in the rest of the
* information.
*/
np = VTONFS(vp);
vap = &np->n_vattr;
if (vp->v_type != vtyp || np->n_mtime.tv_sec == 0) {
bzero(vap, sizeof *vap);
vp->v_type = vtyp;
np->n_mtime.tv_sec = mtime.tv_sec;
}
vap->va_type = vtyp;
vap->va_mode = (vmode & 07777);
vap->va_rdev = rdev;
vap->va_mtime = mtime;
vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
if (fap->fa4_valid & FA4V_NLINK)
vap->va_nlink = fap->fa4_nlink;
if (fap->fa4_valid & FA4V_UID)
vap->va_uid = fap->fa4_uid;
if (fap->fa4_valid & FA4V_GID)
vap->va_gid = fap->fa4_gid;
vap->va_size = fap->fa4_size;
vap->va_blocksize = NFS_FABLKSIZE;
vap->va_bytes = fap->fa4_size;
if (fap->fa4_valid & FA4V_FILEID)
vap->va_fileid = nfs_v4fileid4_to_fileid(fap->fa4_fileid);
if (fap->fa4_valid & FA4V_ATIME)
vap->va_atime = fap->fa4_atime;
if (fap->fa4_valid & FA4V_BTIME)
vap->va_birthtime = fap->fa4_btime;
if (fap->fa4_valid & FA4V_CTIME)
vap->va_ctime = fap->fa4_ctime;
vap->va_flags = 0;
vap->va_filerev = 0;
/* XXX dontshrink flag? */
if (vap->va_size != np->n_size) {
if (vap->va_type == VREG) {
if (np->n_flag & NMODIFIED) {
if (vap->va_size < np->n_size)
vap->va_size = np->n_size;
else
np->n_size = vap->va_size;
} else
np->n_size = vap->va_size;
vnode_pager_setsize(vp, np->n_size);
} else
np->n_size = vap->va_size;
}
np->n_attrstamp = tv.tv_sec;
if (vaper != NULL) {
bcopy((caddr_t)vap, (caddr_t)vaper, sizeof(*vap));
if (np->n_flag & NCHG) {
if (np->n_flag & NACC)
vaper->va_atime = np->n_atim;
if (np->n_flag & NUPD)
vaper->va_mtime = np->n_mtim;
}
}
}
static uint64_t nfs_nullcookie = 0;
/*
* This function finds the directory cookie that corresponds to the
* logical byte offset given.
*/
uint64_t *
nfs4_getcookie(struct nfsnode *np, off_t off, int add)
{
struct nfsdmap *dp, *dp2;
int pos;
pos = (uoff_t)off / NFS_DIRBLKSIZ;
if (pos == 0 || off < 0) {
#ifdef DIAGNOSTIC
if (add)
panic("nfs getcookie add at <= 0");
#endif
return (&nfs_nullcookie);
}
pos--;
dp = LIST_FIRST(&np->n_cookies);
if (!dp) {
if (add) {
dp = malloc(sizeof (struct nfsdmap),
M_NFSDIROFF, M_WAITOK);
dp->ndm_eocookie = 0;
LIST_INSERT_HEAD(&np->n_cookies, dp, ndm_list);
} else
return (NULL);
}
while (pos >= NFSNUMCOOKIES) {
pos -= NFSNUMCOOKIES;
if (LIST_NEXT(dp, ndm_list)) {
if (!add && dp->ndm_eocookie < NFSNUMCOOKIES &&
pos >= dp->ndm_eocookie)
return (NULL);
dp = LIST_NEXT(dp, ndm_list);
} else if (add) {
dp2 = malloc(sizeof (struct nfsdmap),
M_NFSDIROFF, M_WAITOK);
dp2->ndm_eocookie = 0;
LIST_INSERT_AFTER(dp, dp2, ndm_list);
dp = dp2;
} else
return (NULL);
}
if (pos >= dp->ndm_eocookie) {
if (add)
dp->ndm_eocookie = pos + 1;
else
return (NULL);
}
return (&dp->ndm4_cookies[pos]);
}
/*
* Invalidate cached directory information, except for the actual directory
* blocks (which are invalidated separately).
* Done mainly to avoid the use of stale offset cookies.
*/
void
nfs4_invaldir(struct vnode *vp)
{
struct nfsnode *np = VTONFS(vp);
np->n_direofoffset = 0;
bzero(np->n4_cookieverf, NFSX_V4VERF);
if (LIST_FIRST(&np->n_cookies))
LIST_FIRST(&np->n_cookies)->ndm_eocookie = 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,498 +0,0 @@
/* $FreeBSD$ */
/* $Id: nfs4m_subs.h,v 1.36 2003/11/05 14:59:01 rees Exp $ */
/*-
* copyright (c) 2003
* the regents of the university of michigan
* all rights reserved
*
* permission is granted to use, copy, create derivative works and redistribute
* this software and such derivative works for any purpose, so long as the name
* of the university of michigan is not used in any advertising or publicity
* pertaining to the use or distribution of this software without specific,
* written prior authorization. if the above copyright notice or any other
* identification of the university of michigan is included in any copy of any
* portion of this software, then the disclaimer below must also be included.
*
* this software is provided as is, without representation from the university
* of michigan as to its fitness for any purpose, and without warranty by the
* university of michigan of any kind, either express or implied, including
* without limitation the implied warranties of merchantability and fitness for
* a particular purpose. the regents of the university of michigan shall not be
* liable for any damages, including special, indirect, incidental, or
* consequential damages, with respect to any claim arising out of or in
* connection with the use of the software, even if it has been or is hereafter
* advised of the possibility of such damages.
*/
#ifndef _NFS4CLIENT_NFSM4_SUBS_H
#define _NFS4CLIENT_NFSM4_SUBS_H
void nfsm_v4init(void);
void nfsm_buildf_xx(struct mbuf **mb, caddr_t *bpos, char *fmt, ...);
int nfsm_dissectf_xx(struct mbuf **md, caddr_t *dpos, char *fmt, ...);
int nfsm_v4build_compound_xx(struct nfs4_compound *, char *,
struct mbuf **, caddr_t *);
int nfsm_v4build_putfh_xx(struct nfs4_compound *, struct vnode *,
struct mbuf **, caddr_t *);
int nfsm_v4build_putfh_nv_xx(struct nfs4_compound *, struct nfs4_oparg_getfh *,
struct mbuf **, caddr_t *);
int nfsm_v4build_getattr_xx(struct nfs4_compound *, struct nfs4_oparg_getattr *,
struct mbuf **, caddr_t *);
int nfsm_v4build_finalize_xx(struct nfs4_compound *, struct mbuf **, caddr_t *);
int nfsm_v4build_getfh_xx(struct nfs4_compound *, struct nfs4_oparg_getfh *,
struct mbuf **, caddr_t *);
int nfsm_v4build_lookup_xx(struct nfs4_compound *, struct nfs4_oparg_lookup *,
struct mbuf **, caddr_t *);
int nfsm_v4build_setclientid_xx(struct nfs4_compound *,
struct nfs4_oparg_setclientid *, struct mbuf **, caddr_t *);
int nfsm_v4build_setclientid_confirm_xx(struct nfs4_compound *,
struct nfs4_oparg_setclientid *, struct mbuf **, caddr_t *);
int nfsm_v4build_close_xx(struct nfs4_compound *, struct nfs4_fctx *,
struct mbuf **, caddr_t *);
int nfsm_v4build_access_xx(struct nfs4_compound *, struct nfs4_oparg_access *,
struct mbuf **, caddr_t *);
int nfsm_v4build_open_xx(struct nfs4_compound *, struct nfs4_oparg_open *,
struct mbuf **, caddr_t *);
int nfsm_v4build_open_confirm_xx(struct nfs4_compound *, struct nfs4_oparg_open *,
struct mbuf **, caddr_t *);
int nfsm_v4build_read_xx(struct nfs4_compound *, struct nfs4_oparg_read *,
struct mbuf **, caddr_t *);
int nfsm_v4build_write_xx(struct nfs4_compound *, struct nfs4_oparg_write *,
struct mbuf **, caddr_t *);
int nfsm_v4build_commit_xx(struct nfs4_compound *, struct nfs4_oparg_commit *,
struct mbuf **, caddr_t *);
int nfsm_v4build_readdir_xx(struct nfs4_compound *, struct nfs4_oparg_readdir *,
struct mbuf **, caddr_t *);
int nfsm_v4build_renew_xx(struct nfs4_compound *, uint64_t,
struct mbuf **, caddr_t *);
int nfsm_v4build_setattr_xx(struct nfs4_compound *, struct vattr *,
struct nfs4_fctx *, struct mbuf **, caddr_t *);
int nfsm_v4build_create_xx(struct nfs4_compound *, struct nfs4_oparg_create *,
struct mbuf **, caddr_t *);
int nfsm_v4build_rename_xx(struct nfs4_compound *, struct nfs4_oparg_rename *,
struct mbuf **, caddr_t *);
int nfsm_v4build_link_xx(struct nfs4_compound *, struct nfs4_oparg_link *,
struct mbuf **, caddr_t *);
int nfsm_v4build_remove_xx(struct nfs4_compound *, const char *, u_int,
struct mbuf **, caddr_t *);
int nfsm_v4dissect_compound_xx(struct nfs4_compound *, struct mbuf **, caddr_t *);
int nfsm_v4dissect_getattr_xx(struct nfs4_compound *, struct nfs4_oparg_getattr *,
struct mbuf **, caddr_t *);
int nfsm_v4dissect_getfh_xx(struct nfs4_compound *, struct nfs4_oparg_getfh *,
struct mbuf **, caddr_t *);
int nfsm_v4dissect_setclientid_xx(struct nfs4_compound *,
struct nfs4_oparg_setclientid *, struct mbuf **, caddr_t *);
int nfsm_v4dissect_close_xx(struct nfs4_compound *, struct nfs4_fctx *,
struct mbuf **, caddr_t *);
int nfsm_v4dissect_access_xx(struct nfs4_compound *, struct nfs4_oparg_access *,
struct mbuf **, caddr_t *);
int nfsm_v4dissect_open_xx(struct nfs4_compound *, struct nfs4_oparg_open *,
struct mbuf **, caddr_t *);
int nfsm_v4dissect_open_confirm_xx(struct nfs4_compound *, struct nfs4_oparg_open *,
struct mbuf **, caddr_t *);
int nfsm_v4dissect_read_xx(struct nfs4_compound *, struct nfs4_oparg_read *,
struct mbuf **, caddr_t *);
int nfsm_v4dissect_write_xx(struct nfs4_compound *, struct nfs4_oparg_write *,
struct mbuf **, caddr_t *);
int nfsm_v4dissect_commit_xx(struct nfs4_compound *, struct nfs4_oparg_commit *,
struct mbuf **, caddr_t *);
int nfsm_v4dissect_setattr_xx(struct nfs4_compound *, struct mbuf **, caddr_t *);
int nfsm_v4dissect_create_xx(struct nfs4_compound *, struct nfs4_oparg_create *,
struct mbuf **, caddr_t *);
int nfsm_v4dissect_readlink_xx(struct nfs4_compound *, struct uio *,
struct mbuf **, caddr_t *);
int nfsm_v4dissect_attrs_xx(struct nfsv4_fattr *, struct mbuf **, caddr_t *);
int nfsm_v4build_simple_xx(struct nfs4_compound *, uint32_t,
struct mbuf **, caddr_t *);
int nfsm_v4dissect_simple_xx(struct nfs4_compound *, uint32_t,
uint32_t, struct mbuf **, caddr_t *);
#define nfsm_v4build_putrootfh_xx(cp, mb, bpos) \
nfsm_v4build_simple_xx((cp), NFSV4OP_PUTROOTFH, (mb), (bpos))
#define nfsm_v4build_lookupp_xx(cp, mb, bpos) \
nfsm_v4build_simple_xx((cp), NFSV4OP_LOOKUPP, (mb), (bpos))
#define nfsm_v4build_savefh_xx(cp, mb, bpos) \
nfsm_v4build_simple_xx((cp), NFSV4OP_SAVEFH, (mb), (bpos))
#define nfsm_v4build_readlink_xx(cp, mb, bpos) \
nfsm_v4build_simple_xx((cp), NFSV4OP_READLINK, (mb), (bpos))
#define nfsm_v4dissect_putrootfh_xx(cp, mb, bpos) \
nfsm_v4dissect_simple_xx((cp), NFSV4OP_PUTROOTFH, 0, (mb), (bpos))
#define nfsm_v4dissect_lookup_xx(cp, mb, bpos) \
nfsm_v4dissect_simple_xx((cp), NFSV4OP_LOOKUP, 0, (mb), (bpos))
#define nfsm_v4dissect_lookupp_xx(cp, mb, bpos) \
nfsm_v4dissect_simple_xx((cp), NFSV4OP_LOOKUPP, 0, (mb), (bpos))
#define nfsm_v4dissect_putfh_xx(cp, mb, bpos) \
nfsm_v4dissect_simple_xx((cp), NFSV4OP_PUTFH, 0, (mb), (bpos))
#define nfsm_v4dissect_renew_xx(cp, mb, bpos) \
nfsm_v4dissect_simple_xx((cp), NFSV4OP_RENEW, 0, (mb), (bpos))
#define nfsm_v4dissect_setclientid_confirm_xx(cp, mb, bpos) \
nfsm_v4dissect_simple_xx((cp), NFSV4OP_SETCLIENTID_CONFIRM, 0, (mb), (bpos))
#define nfsm_v4dissect_rename_xx(cp, mb, bpos) \
nfsm_v4dissect_simple_xx((cp), NFSV4OP_RENAME, 0, (mb), (bpos))
#define nfsm_v4dissect_link_xx(cp, mb, bpos) \
nfsm_v4dissect_simple_xx((cp), NFSV4OP_LINK, 0, (mb), (bpos))
#define nfsm_v4dissect_savefh_xx(cp, mb, bpos) \
nfsm_v4dissect_simple_xx((cp), NFSV4OP_SAVEFH, 0, (mb), (bpos))
#define nfsm_v4dissect_remove_xx(cp, mb, bpos) \
nfsm_v4dissect_simple_xx((cp), NFSV4OP_REMOVE, 0, (mb), (bpos))
#define nfsm_v4build_compound(cp, tag) do { \
int32_t t1; \
t1 = nfsm_v4build_compound_xx((cp), (tag), &mb, &bpos); \
nfsm_bcheck(t1, mreq); \
} while (0)
#define nfsm_v4build_finalize(cp) do { \
int32_t t1; \
t1 = nfsm_v4build_finalize_xx((cp), &mb, &bpos); \
nfsm_bcheck(t1, mreq); \
} while (0)
#define nfsm_v4build_putfh(cp, vp) do { \
int32_t t1; \
t1 = nfsm_v4build_putfh_xx((cp), (vp), &mb, &bpos); \
nfsm_bcheck(t1, mreq); \
} while (0)
#define nfsm_v4build_putfh_nv(cp, gfh) do { \
int32_t t1; \
t1 = nfsm_v4build_putfh_nv_xx((cp), (gfh), &mb, &bpos); \
nfsm_bcheck(t1, mreq); \
} while (0)
#define nfsm_v4build_putrootfh(cp) do { \
int32_t t1; \
t1 = nfsm_v4build_putrootfh_xx((cp), &mb, &bpos); \
nfsm_bcheck(t1, mreq); \
} while (0)
#define nfsm_v4build_getattr(cp, ga) do { \
int32_t t1; \
t1 = nfsm_v4build_getattr_xx((cp), (ga), &mb, &bpos); \
nfsm_bcheck(t1, mreq); \
} while (0)
#define nfsm_v4build_setattr(cp, vap, fcp) do { \
int32_t t1; \
t1 = nfsm_v4build_setattr_xx((cp), (vap), (fcp), &mb, &bpos); \
nfsm_bcheck(t1, mreq); \
} while (0)
#define nfsm_v4build_lookup(cp, l) do { \
int32_t t1; \
t1 = nfsm_v4build_lookup_xx((cp), (l), &mb, &bpos); \
nfsm_bcheck(t1, mreq); \
} while (0)
#define nfsm_v4build_lookupp(cp) do { \
int32_t t1; \
t1 = nfsm_v4build_lookupp_xx((cp), &mb, &bpos); \
nfsm_bcheck(t1, mreq); \
} while (0)
#define nfsm_v4build_getfh(cp, gfh) do { \
int32_t t1; \
t1 = nfsm_v4build_getfh_xx((cp), (gfh), &mb, &bpos); \
nfsm_bcheck(t1, mreq); \
} while (0)
#define nfsm_v4build_close(cp, fcp) do { \
int32_t t1; \
t1 = nfsm_v4build_close_xx((cp), (fcp), &mb, &bpos); \
nfsm_bcheck(t1, mreq); \
} while (0)
#define nfsm_v4build_access(cp, acc) do { \
int32_t t1; \
t1 = nfsm_v4build_access_xx((cp), (acc), &mb, &bpos); \
nfsm_bcheck(t1, mreq); \
} while (0)
#define nfsm_v4build_open(cp, o) do { \
int32_t t1; \
t1 = nfsm_v4build_open_xx((cp), (o), &mb, &bpos); \
nfsm_bcheck(t1, mreq); \
} while (0)
#define nfsm_v4build_open_confirm(cp, o) do { \
int32_t t1; \
t1 = nfsm_v4build_open_confirm_xx((cp), (o), &mb, &bpos); \
nfsm_bcheck(t1, mreq); \
} while (0)
#define nfsm_v4build_read(cp, r) do { \
int32_t t1; \
t1 = nfsm_v4build_read_xx((cp), (r), &mb, &bpos); \
nfsm_bcheck(t1, mreq); \
} while (0)
#define nfsm_v4build_write(cp, w) do { \
int32_t t1; \
t1 = nfsm_v4build_write_xx((cp), (w), &mb, &bpos); \
nfsm_bcheck(t1, mreq); \
} while (0)
#define nfsm_v4build_commit(cp, c) do { \
int32_t t1; \
t1 = nfsm_v4build_commit_xx((cp), (c), &mb, &bpos); \
nfsm_bcheck(t1, mreq); \
} while (0)
#define nfsm_v4build_readdir(cp, r) do { \
int32_t t1; \
t1 = nfsm_v4build_readdir_xx((cp), (r), &mb, &bpos); \
nfsm_bcheck(t1, mreq); \
} while (0)
#define nfsm_v4build_renew(cp, cid) do { \
int32_t t1; \
t1 = nfsm_v4build_renew_xx((cp), (cid), &mb, &bpos); \
nfsm_bcheck(t1, mreq); \
} while (0)
#define nfsm_v4build_setclientid(cp, cid) do { \
int32_t t1; \
t1 = nfsm_v4build_setclientid_xx((cp), (cid), &mb, &bpos); \
nfsm_bcheck(t1, mreq); \
} while (0)
#define nfsm_v4build_setclientid_confirm(cp, cid) do { \
int32_t t1; \
t1 = nfsm_v4build_setclientid_confirm_xx((cp), (cid), &mb, &bpos); \
nfsm_bcheck(t1, mreq); \
} while (0)
#define nfsm_v4build_create(cp, c) do { \
int32_t t1; \
t1 = nfsm_v4build_create_xx((cp), (c), &mb, &bpos); \
nfsm_bcheck(t1, mreq); \
} while (0)
#define nfsm_v4build_rename(cp, r) do { \
int32_t t1; \
t1 = nfsm_v4build_rename_xx((cp), (r), &mb, &bpos); \
nfsm_bcheck(t1, mreq); \
} while (0)
#define nfsm_v4build_link(cp, r) do { \
int32_t t1; \
t1 = nfsm_v4build_link_xx((cp), (r), &mb, &bpos); \
nfsm_bcheck(t1, mreq); \
} while (0)
#define nfsm_v4build_savefh(cp) do { \
int32_t t1; \
t1 = nfsm_v4build_savefh_xx((cp), &mb, &bpos); \
nfsm_bcheck(t1, mreq); \
} while (0)
#define nfsm_v4build_readlink(cp) do { \
int32_t t1; \
t1 = nfsm_v4build_readlink_xx((cp), &mb, &bpos); \
nfsm_bcheck(t1, mreq); \
} while (0)
#define nfsm_v4build_remove(cp, name, namelen) do { \
int32_t t1; \
t1 = nfsm_v4build_remove_xx((cp), (name), (namelen), &mb, &bpos); \
nfsm_bcheck(t1, mreq); \
} while (0)
/* --- */
#define nfsm_v4dissect_compound(cp) \
do { \
int32_t t1; \
t1 = nfsm_v4dissect_compound_xx((cp), &md, &dpos); \
nfsm_dcheck(t1, mrep); \
} while (0)
#define nfsm_v4dissect_putfh(cp) \
do { \
int32_t t1; \
t1 = nfsm_v4dissect_putfh_xx((cp), &md, &dpos); \
nfsm_dcheck(t1, mrep); \
} while (0)
#define nfsm_v4dissect_putrootfh(cp) \
do { \
int32_t t1; \
t1 = nfsm_v4dissect_putrootfh_xx((cp), &md, &dpos); \
nfsm_dcheck(t1, mrep); \
} while (0)
#define nfsm_v4dissect_getattr(cp, ga) \
do { \
int32_t t1; \
t1 = nfsm_v4dissect_getattr_xx((cp), (ga), &md, &dpos); \
nfsm_dcheck(t1, mrep); \
} while (0)
#define nfsm_v4dissect_setattr(cp) \
do { \
int32_t t1; \
t1 = nfsm_v4dissect_setattr_xx((cp), &md, &dpos); \
nfsm_dcheck(t1, mrep); \
} while (0)
#define nfsm_v4dissect_lookup(cp) \
do { \
int32_t t1; \
t1 = nfsm_v4dissect_lookup_xx((cp), &md, &dpos); \
nfsm_dcheck(t1, mrep); \
} while (0)
#define nfsm_v4dissect_lookupp(cp) \
do { \
int32_t t1; \
t1 = nfsm_v4dissect_lookupp_xx((cp), &md, &dpos); \
nfsm_dcheck(t1, mrep); \
} while (0)
#define nfsm_v4dissect_getfh(cp, gfh) \
do { \
int32_t t1; \
t1 = nfsm_v4dissect_getfh_xx((cp), (gfh), &md, &dpos); \
nfsm_dcheck(t1, mrep); \
} while (0)
#define nfsm_v4dissect_setclientid(cp, sci) \
do { \
int32_t t1; \
t1 = nfsm_v4dissect_setclientid_xx((cp), (sci), &md, &dpos); \
nfsm_dcheck(t1, mrep); \
} while (0)
#define nfsm_v4dissect_setclientid_confirm(cp) \
do { \
int32_t t1; \
t1 = nfsm_v4dissect_setclientid_confirm_xx((cp), &md, &dpos); \
nfsm_dcheck(t1, mrep); \
} while (0)
#define nfsm_v4dissect_close(cp, fcp) \
do { \
int32_t t1; \
t1 = nfsm_v4dissect_close_xx((cp), (fcp), &md, &dpos); \
nfsm_dcheck(t1, mrep); \
} while (0)
#define nfsm_v4dissect_access(cp, acc) \
do { \
int32_t t1; \
t1 = nfsm_v4dissect_access_xx((cp), (acc), &md, &dpos); \
nfsm_dcheck(t1, mrep); \
} while (0)
#define nfsm_v4dissect_open(cp, openp) \
do { \
int32_t t1; \
t1 = nfsm_v4dissect_open_xx((cp), (openp), &md, &dpos); \
nfsm_dcheck(t1, mrep); \
} while (0)
#define nfsm_v4dissect_open_confirm(cp, openp) \
do { \
int32_t t1; \
t1 = nfsm_v4dissect_open_confirm_xx((cp), (openp), &md, &dpos); \
nfsm_dcheck(t1, mrep); \
} while (0)
#define nfsm_v4dissect_read(cp, r) \
do { \
int32_t t1; \
t1 = nfsm_v4dissect_read_xx((cp), (r), &md, &dpos); \
nfsm_dcheck(t1, mrep); \
} while (0)
#define nfsm_v4dissect_write(cp, w) \
do { \
int32_t t1; \
t1 = nfsm_v4dissect_write_xx((cp), (w), &md, &dpos); \
nfsm_dcheck(t1, mrep); \
} while (0)
#define nfsm_v4dissect_commit(cp, c) \
do { \
int32_t t1; \
t1 = nfsm_v4dissect_commit_xx((cp), (c), &md, &dpos); \
nfsm_dcheck(t1, mrep); \
} while (0)
#define nfsm_v4dissect_attrs(fattr) \
do { \
int32_t t1; \
t1 = nfsm_v4dissect_attrs_xx((fattr), &md, &dpos); \
nfsm_dcheck(t1, mrep); \
} while (0)
#define nfsm_v4dissect_renew(cp) \
do { \
int32_t t1; \
t1 = nfsm_v4dissect_renew_xx((cp), &md, &dpos); \
nfsm_dcheck(t1, mrep); \
} while (0)
#define nfsm_v4dissect_create(cp, c) \
do { \
int32_t t1; \
t1 = nfsm_v4dissect_create_xx((cp), (c), &md, &dpos); \
nfsm_dcheck(t1, mrep); \
} while (0)
#define nfsm_v4dissect_rename(cp) \
do { \
int32_t t1; \
t1 = nfsm_v4dissect_rename_xx((cp), &md, &dpos); \
nfsm_dcheck(t1, mrep); \
} while (0)
#define nfsm_v4dissect_link(cp) \
do { \
int32_t t1; \
t1 = nfsm_v4dissect_link_xx((cp), &md, &dpos); \
nfsm_dcheck(t1, mrep); \
} while (0)
#define nfsm_v4dissect_savefh(cp) \
do { \
int32_t t1; \
t1 = nfsm_v4dissect_savefh_xx((cp), &md, &dpos); \
nfsm_dcheck(t1, mrep); \
} while (0)
#define nfsm_v4dissect_readlink(cp, uiop) \
do { \
int32_t t1; \
t1 = nfsm_v4dissect_readlink_xx((cp), (uiop), &md, &dpos); \
nfsm_dcheck(t1, mrep); \
} while (0)
#define nfsm_v4dissect_remove(cp) \
do { \
int32_t t1; \
t1 = nfsm_v4dissect_remove_xx((cp), &md, &dpos); \
nfsm_dcheck(t1, mrep); \
} while (0)
#endif /* _NFS4CLIENT_NFSM4_SUBS_H */

View File

@ -68,8 +68,6 @@ __FBSDID("$FreeBSD$");
#include <net/if_dl.h>
#include <net/vnet.h>
#include <rpc/rpcclnt.h>
#include <nfs/rpcv2.h>
#include <nfs/nfsproto.h>
#include <nfsclient/nfs.h>

View File

@ -57,8 +57,6 @@ __FBSDID("$FreeBSD$");
#include <net/if.h>
#include <netinet/in.h>
#include <rpc/rpcclnt.h>
#include <nfs/rpcv2.h>
#include <nfsclient/krpc.h>
#include <nfs/xdr_subs.h>

View File

@ -111,18 +111,6 @@
*/
#define NFS_NFSSTATS 1 /* struct: struct nfsstats */
/*
* File context information for nfsv4. Currently, there is only one
* lockowner for the whole machine "0."
*/
struct nfs4_fctx {
TAILQ_ENTRY(nfs4_fstate) next;
uint32_t refcnt;
struct nfs4_lowner *lop;
struct nfsnode *np;
char stateid[NFSX_V4STATEID];
};
#ifdef _KERNEL
#ifdef MALLOC_DECLARE

View File

@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
#include <sys/bio.h>
#include <sys/buf.h>
#include <sys/kernel.h>
#include <sys/mbuf.h>
#include <sys/mount.h>
#include <sys/proc.h>
#include <sys/resourcevar.h>
@ -56,8 +57,6 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_pager.h>
#include <vm/vnode_pager.h>
#include <rpc/rpcclnt.h>
#include <nfs/rpcv2.h>
#include <nfs/nfsproto.h>
#include <nfsclient/nfs.h>
@ -65,8 +64,6 @@ __FBSDID("$FreeBSD$");
#include <nfsclient/nfsnode.h>
#include <nfsclient/nfs_kdtrace.h>
#include <nfs4client/nfs4.h>
static struct buf *nfs_getcacheblk(struct vnode *vp, daddr_t bn, int size,
struct thread *td);
static int nfs_directio_write(struct vnode *vp, struct uio *uiop,
@ -1612,17 +1609,13 @@ nfs_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td)
case VDIR:
nfsstats.readdir_bios++;
uiop->uio_offset = ((u_quad_t)bp->b_lblkno) * NFS_DIRBLKSIZ;
if ((nmp->nm_flag & NFSMNT_NFSV4) != 0)
error = nfs4_readdirrpc(vp, uiop, cr);
else {
if ((nmp->nm_flag & NFSMNT_RDIRPLUS) != 0) {
error = nfs_readdirplusrpc(vp, uiop, cr);
if (error == NFSERR_NOTSUPP)
nmp->nm_flag &= ~NFSMNT_RDIRPLUS;
}
if ((nmp->nm_flag & NFSMNT_RDIRPLUS) == 0)
error = nfs_readdirrpc(vp, uiop, cr);
if ((nmp->nm_flag & NFSMNT_RDIRPLUS) != 0) {
error = nfs_readdirplusrpc(vp, uiop, cr);
if (error == NFSERR_NOTSUPP)
nmp->nm_flag &= ~NFSMNT_RDIRPLUS;
}
if ((nmp->nm_flag & NFSMNT_RDIRPLUS) == 0)
error = nfs_readdirrpc(vp, uiop, cr);
/*
* end-of-directory sets B_INVAL but does not generate an
* error.

View File

@ -55,7 +55,6 @@ __FBSDID("$FreeBSD$");
#include <net/vnet.h>
#include <netinet/in.h>
#include <rpc/rpcclnt.h>
#include <nfs/rpcv2.h>
#include <nfs/nfsproto.h>
#include <nfsclient/nfs.h>

View File

@ -60,7 +60,6 @@ __FBSDID("$FreeBSD$");
#include <sys/vnode.h>
#include <rpc/rpc.h>
#include <rpc/rpcclnt.h>
#include <nfs/rpcv2.h>
#include <nfs/nfsproto.h>
@ -70,8 +69,6 @@ __FBSDID("$FreeBSD$");
#include <nfsclient/nfsmount.h>
#include <nfsclient/nfsnode.h>
#include <nfs4client/nfs4.h>
#ifndef NFS_LEGACYRPC
#ifdef KDTRACE_HOOKS
@ -445,8 +442,6 @@ nfs_request(struct vnode *vp, struct mbuf *mreq, int procnum,
return (ESTALE);
}
nmp = VFSTONFS(vp->v_mount);
if ((nmp->nm_flag & NFSMNT_NFSV4) != 0)
return nfs4_request(vp, mreq, procnum, td, cred, mrp, mdp, dposp);
bzero(&nf, sizeof(struct nfs_feedback_arg));
nf.nf_mount = nmp;
nf.nf_td = td;
@ -740,8 +735,6 @@ nfs_sigintr(struct nfsmount *nmp, struct nfsreq *rep, struct thread *td)
struct proc *p;
sigset_t tmpset;
if ((nmp->nm_flag & NFSMNT_NFSV4) != 0)
return nfs4_sigintr(nmp, rep, td);
/* Terminate all requests while attempting a forced unmount. */
if (nmp->nm_mountp->mnt_kern_flag & MNTK_UNMOUNTF)
return (EIO);

View File

@ -53,8 +53,6 @@ __FBSDID("$FreeBSD$");
#include <net/if.h>
#include <rpc/rpcclnt.h>
#include <nfs/rpcv2.h>
#include <nfs/nfsproto.h>
#include <nfsclient/nfs.h>

View File

@ -63,8 +63,6 @@ __FBSDID("$FreeBSD$");
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <rpc/rpcclnt.h>
#include <nfs/xdr_subs.h>
#include <nfs/rpcv2.h>
#include <nfs/nfsproto.h>

View File

@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <sys/fnv_hash.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/mount.h>
#include <sys/namei.h>
#include <sys/proc.h>
@ -49,8 +50,6 @@ __FBSDID("$FreeBSD$");
#include <vm/uma.h>
#include <rpc/rpcclnt.h>
#include <nfs/rpcv2.h>
#include <nfs/nfsproto.h>
#include <nfsclient/nfs.h>
@ -133,19 +132,13 @@ nfs_nget(struct mount *mntp, nfsfh_t *fhp, int fhsize, struct nfsnode **npp, int
*/
np = uma_zalloc(nfsnode_zone, M_WAITOK | M_ZERO);
if (nmp->nm_flag & NFSMNT_NFSV4)
error = getnewvnode("nfs4", mntp, &nfs4_vnodeops, &nvp);
else
error = getnewvnode("nfs", mntp, &nfs_vnodeops, &nvp);
error = getnewvnode("nfs", mntp, &nfs_vnodeops, &nvp);
if (error) {
uma_zfree(nfsnode_zone, np);
return (error);
}
vp = nvp;
if (nmp->nm_flag & NFSMNT_NFSV4)
vp->v_bufobj.bo_ops = &buf_ops_nfs4;
else
vp->v_bufobj.bo_ops = &buf_ops_nfs;
vp->v_bufobj.bo_ops = &buf_ops_nfs;
vp->v_data = np;
np->n_vnode = vp;
/*

View File

@ -62,8 +62,6 @@ __FBSDID("$FreeBSD$");
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <rpc/rpcclnt.h>
#include <nfs/rpcv2.h>
#include <nfs/nfsproto.h>
#include <nfsclient/nfs.h>
@ -72,8 +70,6 @@ __FBSDID("$FreeBSD$");
#include <nfsclient/nfsmount.h>
#include <nfsclient/nfsnode.h>
#include <nfs4client/nfs4.h>
#ifdef NFS_LEGACYRPC
#define TRUE 1
@ -1145,8 +1141,6 @@ nfs_request(struct vnode *vp, struct mbuf *mrest, int procnum,
return (ESTALE);
}
nmp = VFSTONFS(vp->v_mount);
if ((nmp->nm_flag & NFSMNT_NFSV4) != 0)
return nfs4_request(vp, mrest, procnum, td, cred, mrp, mdp, dposp);
rep = malloc(sizeof(struct nfsreq), M_NFSREQ, M_WAITOK);
bzero(rep, sizeof(struct nfsreq));
rep->r_nmp = nmp;
@ -1747,8 +1741,6 @@ nfs_sigintr(struct nfsmount *nmp, struct nfsreq *rep, struct thread *td)
struct proc *p;
sigset_t tmpset;
if ((nmp->nm_flag & NFSMNT_NFSV4) != 0)
return nfs4_sigintr(nmp, rep, td);
if (rep) {
mtx_lock(&rep->r_mtx);
if (rep->r_flags & R_SOFTTERM) {

View File

@ -65,8 +65,6 @@ __FBSDID("$FreeBSD$");
#include <vm/vm_extern.h>
#include <vm/uma.h>
#include <rpc/rpcclnt.h>
#include <nfs/rpcv2.h>
#include <nfs/nfsproto.h>
#include <nfsclient/nfs.h>

View File

@ -66,7 +66,6 @@ __FBSDID("$FreeBSD$");
#include <net/route.h>
#include <netinet/in.h>
#include <rpc/rpcclnt.h>
#include <rpc/rpc.h>
#include <nfs/rpcv2.h>

View File

@ -70,8 +70,6 @@ __FBSDID("$FreeBSD$");
#include <fs/fifofs/fifo.h>
#include <rpc/rpcclnt.h>
#include <nfs/rpcv2.h>
#include <nfs/nfsproto.h>
#include <nfsclient/nfs.h>

View File

@ -147,17 +147,6 @@ do { \
} \
} while (0)
#define nfsm_request_mnt(n, t, p, c) \
do { \
error = nfs4_request_mnt((n), mreq, (t), (p), (c), &mrep, &md, &dpos); \
if (error != 0) { \
if (error & NFSERR_RETERR) \
error &= ~NFSERR_RETERR; \
else \
goto nfsmout; \
} \
} while (0)
/* *********************************** */
/* Reply interpretation phase macros */

View File

@ -79,7 +79,6 @@ struct nfsmount {
int nm_numgrps; /* Max. size of groupslist */
u_char nm_fh[NFSX_V4FH]; /* File handle of root dir */
int nm_fhsize; /* Size of root file handle */
struct rpcclnt nm_rpcclnt; /* rpc state */
#ifdef NFS_LEGACYRPC
struct socket *nm_so; /* Rpc socket */
#endif

View File

@ -135,8 +135,6 @@ struct nfsnode {
short n_fhsize; /* size in bytes, of fh */
short n_flag; /* Flag for locking.. */
nfsfh_t n_fh; /* Small File Handle */
struct nfs4_fctx n_rfc;
struct nfs4_fctx n_wfc;
u_char *n_name; /* leaf name, for v4 OPEN op */
uint32_t n_namelen;
int n_directio_opens;
@ -188,9 +186,7 @@ extern struct nfsmount *nfs_iodmount[NFS_MAXASYNCDAEMON];
extern struct vop_vector nfs_fifoops;
extern struct vop_vector nfs_vnodeops;
extern struct vop_vector nfs4_vnodeops;
extern struct buf_ops buf_ops_nfs;
extern struct buf_ops buf_ops_nfs4;
extern vop_advlock_t *nfs_advlock_p;
extern vop_reclaim_t *nfs_reclaim_p;
@ -206,12 +202,9 @@ int nfs_reclaim(struct vop_reclaim_args *);
/* other stuff */
int nfs_removeit(struct sillyrename *);
int nfs4_removeit(struct sillyrename *);
int nfs_nget(struct mount *, nfsfh_t *, int, struct nfsnode **, int flags);
nfsuint64 *nfs_getcookie(struct nfsnode *, off_t, int);
uint64_t *nfs4_getcookie(struct nfsnode *, off_t, int);
void nfs_invaldir(struct vnode *);
void nfs4_invaldir(struct vnode *);
int nfs_upgrade_vnlock(struct vnode *vp);
void nfs_downgrade_vnlock(struct vnode *vp, int old_lock);
void nfs_printf(const char *fmt, ...);

View File

@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/lockf.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/mount.h>
#include <sys/mutex.h>
#include <sys/proc.h>
@ -44,7 +45,6 @@ __FBSDID("$FreeBSD$");
#include <sys/vimage.h>
#include <sys/vnode.h>
#include <rpc/rpcclnt.h>
#include <nfs/nfsproto.h>
#include <nfsclient/nfs.h>
#include <nfsclient/nfsnode.h>

File diff suppressed because it is too large Load Diff

View File

@ -1,354 +0,0 @@
/* $FreeBSD$ */
/* $OpenBSD: nfsmount.h,v 1.11 2002/03/14 01:27:13 millert Exp $ */
/* $NetBSD: nfsmount.h,v 1.10 1996/02/18 11:54:03 fvdl Exp $ */
/*-
* copyright (c) 2003
* the regents of the university of michigan
* all rights reserved
*
* permission is granted to use, copy, create derivative works and redistribute
* this software and such derivative works for any purpose, so long as the name
* of the university of michigan is not used in any advertising or publicity
* pertaining to the use or distribution of this software without specific,
* written prior authorization. if the above copyright notice or any other
* identification of the university of michigan is included in any copy of any
* portion of this software, then the disclaimer below must also be included.
*
* this software is provided as is, without representation from the university
* of michigan as to its fitness for any purpose, and without warranty by the
* university of michigan of any kind, either express or implied, including
* without limitation the implied warranties of merchantability and fitness for
* a particular purpose. the regents of the university of michigan shall not be
* liable for any damages, including special, indirect, incidental, or
* consequential damages, with respect to any claim arising out of or in
* connection with the use of the software, even if it has been or is hereafter
* advised of the possibility of such damages.
*/
/*-
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Rick Macklem at The University of Guelph.
*
* 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
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
*
* @(#)nfsmount.h 8.3 (Berkeley) 3/30/95
*/
#ifndef _RPCCLNT_H_
#define _RPCCLNT_H_
#include <sys/types.h>
#include <sys/malloc.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#ifdef __OpenBSD__
#define RPC_EXEC_CTX struct proc *
#else
#define RPC_EXEC_CTX struct thread *
#endif
#ifdef RPCCLNT_DEBUG
#define RPCDEBUG(args...) do{ \
if(rpcdebugon != 0){ \
printf("%s(): ", __func__);\
printf(args); \
printf("\n"); \
}}while(0)
#else
#define RPCDEBUG(args...)
#endif
/* from nfs/nfs.h */
#define RPC_TICKINTVL 10
/* from nfs/nfsproto.h */
#define RPC_MAXDATA 32768
#define RPC_MAXPKTHDR 404
#define RPC_MAXPACKET (RPC_MAXPKTHDR + RPC_MAXDATA)
#define RPCX_UNSIGNED 4
/* defines for rpcclnt's rc_flags
XXX these flags came from the NFSMNT_* flags in OpenBSD's sys/mount.h */
#define RPCCLNT_SOFT 0x001 /* soft mount (hard is details) */
#define RPCCLNT_INT 0x002 /* allow interrupts on hard mounts */
#define RPCCLNT_NOCONN 0x004 /* dont connect the socket (udp) */
#define RPCCLNT_DUMBTIMR 0x010
#define RPCCLNT_SNDLOCK 0x100
#define RPCCLNT_WANTSND 0x200
#define RPCCLNT_RCVLOCK 0x400
#define RPCCLNT_WANTRCV 0x800
/* Flag values for r_flags */
#define R_TIMING 0x01 /* timing request (in mntp) */
#define R_SENT 0x02 /* request has been sent */
#define R_SOFTTERM 0x04 /* soft mnt, too many retries */
#define R_INTR 0x08 /* intr mnt, signal pending */
#define R_SOCKERR 0x10 /* Fatal error on socket */
#define R_TPRINTFMSG 0x20 /* Did a tprintf msg. */
#define R_MUSTRESEND 0x40 /* Must resend request */
#define R_GETONEREP 0x80 /* Probe for one reply only */
#define RPC_HZ (hz / rpcclnt_ticks) /* Ticks/sec */
#define RPC_TIMEO (1 * RPC_HZ) /* Default timeout = 1 second */
#define RPC_MAXREXMIT 100 /* Stop counting after this many */
#define RPCIGNORE_SOERROR(s, e) \
((e) != EINTR && (e) != ERESTART && (e) != EWOULDBLOCK && \
((s) & PR_CONNREQUIRED) == 0)
#define RPCINT_SIGMASK (sigmask(SIGINT)|sigmask(SIGTERM)|sigmask(SIGKILL)| \
sigmask(SIGHUP)|sigmask(SIGQUIT))
#define RPCMADV(m, s) (m)->m_data += (s)
#define RPCAUTH_ROOTCREDS NULL
#define RPCCLNTINT_SIGMASK(set) \
(SIGISMEMBER(set, SIGINT) || SIGISMEMBER(set, SIGTERM) || \
SIGISMEMBER(set, SIGHUP) || SIGISMEMBER(set, SIGKILL) || \
SIGISMEMBER(set, SIGQUIT))
#define fxdr_unsigned(t, v) ((t)ntohl((int32_t)(v)))
#define txdr_unsigned(v) (htonl((int32_t)(v)))
/* global rpcstats
* XXX should be per rpcclnt */
struct rpcstats {
int rpcretries;
int rpcrequests;
int rpctimeouts;
int rpcunexpected;
int rpcinvalid;
};
struct rpc_program {
u_int32_t prog_id;
u_int32_t prog_version;
char * prog_name;
};
struct rpc_auth {
unsigned int auth_type;
};
struct rpctask {
TAILQ_ENTRY(rpctask) r_chain;
struct mbuf *r_mreq;
struct mbuf *r_mrep;
struct mbuf *r_md;
caddr_t r_dpos;
struct rpcclnt *r_rpcclnt;
u_int32_t r_xid;
int r_flags; /* flags on request, see below */
int r_retry; /* max retransmission count */
int r_rexmit; /* current retrans count */
int r_timer; /* tick counter on reply */
int r_procnum; /* NFS procedure number */
int r_rtt; /* RTT for rpc */
RPC_EXEC_CTX r_td;
};
struct rpc_reply {
struct {
u_int32_t type;
u_int32_t status;
/* used only when reply == RPC_MSGDENIED and
* status == RPC_AUTHERR */
u_int32_t autherr;
/* rpc mismatch info if reply == RPC_MSGDENIED and
* status == RPC_MISMATCH */
struct {
u_int32_t low;
u_int32_t high;
} mismatch_info;
} stat;
/* head of the mbuf chain */
struct mbuf * mrep;
/* mbuf and position of the verification opaque data
* note that this is only valid when stat.reply == RPC_MSGACCEPTED */
u_int32_t verf_type;
u_int32_t verf_size;
struct mbuf * verf_md;
caddr_t verf_dpos;
/* mbuf and postion of the result of the rpc request */
struct mbuf * result_md;
caddr_t result_dpos;
};
/*
* RPC Client connection context.
* One allocated on every NFS mount.
* Holds RPC specific information for mount.
*/
/* XXX: please note that all pointer type variables are just set (not copied),
* so it is up to the user to free these values */
struct rpcclnt {
int rc_flag; /* For RPCCLNT_* flags */
int rc_wsize; /* Max size of the request data */
int rc_rsize; /* Max size of the response data */
struct sockaddr *rc_name;
struct socket *rc_so; /* Rpc socket */
int rc_sotype; /* Type of socket */
int rc_soproto; /* and protocol */
int rc_soflags; /* pr_flags for socket protocol */
int rc_timeo; /* Init timer for NFSMNT_DUMBTIMR */
int rc_retry; /* Max retries */
int rc_srtt[4]; /* Timers for rpcs */
int rc_sdrtt[4];
int rc_sent; /* Request send count */
int rc_cwnd; /* Request send window */
int rc_timeouts; /* Request timeouts */
/* XXX: this is not being set!!!! */
int rc_deadthresh; /* Threshold of timeouts-->dead server*/
/* authentication: */
/* currently can be RPCAUTH_NULL, RPCAUTH_KERBV4, RPCAUTH_UNIX */
/* should be kept in XDR form */
int rc_authtype; /* Authenticator type */
#if 0
/* RPCAUTH_KERB4 */
int rc_authlen; /* and length */
char *rc_authstr; /* Authenticator string */
int rc_verflen;
char *rc_verfstr; /* and the verifier */
#endif
/* RPCAUTH_UNIX*/
struct rpc_auth * rc_auth; /* authentication */
#if 0
/* stored in XDR form (network byte order) */
unsigned int rc_progid; /* program id */
unsigned int rc_progvers; /* program version */
/* name of server for log messages */
const char *rc_servername; /* for printing error messages */
#else
struct rpc_program * rc_prog;
#endif
/* XXX: this should be removed */
int rc_proctlen; /* if == 0 then rc_proct == NULL */
int * rc_proct;
};
#ifdef __OpenBSD__
extern struct pool rpcreply_pool;
extern struct pool rpcclnt_pool;
#else
/* MALLOC_DECLARE(M_RPC); */
#endif
extern int rpcdebugon;
#ifdef __OpenBSD__
#define rpcclnt_get(X) \
do { \
(X) = pool_get(&rpcclnt_pool, PR_WAITOK); \
bzero((X), sizeof(struct rpcclnt)); \
}while(0)
#define rpcclnt_put(X) \
do { \
if ((X) != NULL){ \
pool_put(&rpcclnt_pool, (X)); \
}}while(0)
#else /* !__OpenBSD__ */
/* usage count for module (un)loading */
extern unsigned int rpcclnt_usage;
extern struct mtx rpcclnt_usage_mutex;
void rpcclnt_create(struct rpcclnt ** rpc);
void rpcclnt_destroy(struct rpcclnt * rpc);
#define rpcclnt_get(X) rpcclnt_create(&(X))
#define rpcclnt_put(X) rpcclnt_destroy(X)
#ifdef RPCCLNT_TEST
struct rpcclnt_test_args {
int nothing;
};
int rpcclnt_test(struct thread *, struct rpcclnt_test_args *);
#define RPC_RETURN(X) do { RPCDEBUG("returning %d", X); return X; }while(0)
#endif /* RPCCLNT_TEST */
#endif /* !__OpenBSD__ */
void rpcclnt_init(void);
void rpcclnt_uninit(void);
#if 0
int rpcclnt_setup(struct rpcclnt *, int, struct sockaddr *, int, int, int, int, const char *, int, int);
#endif
int rpcclnt_setup(struct rpcclnt *, struct rpc_program *, struct sockaddr *, int, int, struct rpc_auth *, int, int, int);
int rpcclnt_connect(struct rpcclnt *, RPC_EXEC_CTX td);
int rpcclnt_reconnect(struct rpctask *, RPC_EXEC_CTX td);
void rpcclnt_disconnect(struct rpcclnt *);
void rpcclnt_safedisconnect(struct rpcclnt *);
void rpcclnt_setauth(struct rpcclnt *, u_int32_t, u_int32_t, char *, u_int32_t, char *, struct ucred *);
int rpcclnt_request(struct rpcclnt *, struct mbuf *, int, RPC_EXEC_CTX, struct ucred *, struct rpc_reply *);
int rpcclnt_err(struct rpc_reply *);
int rpcclnt_cancelreqs(struct rpcclnt *);
int rpcclnt_sigintr(struct rpcclnt *, struct rpctask *, RPC_EXEC_CTX);
#endif /* _RPCCLNT_H_ */