summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2009-05-22 12:35:12 +0000
committerrwatson <rwatson@FreeBSD.org>2009-05-22 12:35:12 +0000
commitccb17e335aed123268303ae81de1b71c1340a1e7 (patch)
treed3806d83b9761a1610e63824e4451e9628878f16
parenta75d175b4f1d7335efc89a91eac2db17f903ec5e (diff)
downloadFreeBSD-src-ccb17e335aed123268303ae81de1b71c1340a1e7.zip
FreeBSD-src-ccb17e335aed123268303ae81de1b71c1340a1e7.tar.gz
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
-rwxr-xr-xetc/rc.d/idmapd18
-rw-r--r--sbin/Makefile1
-rw-r--r--sbin/idmapd/Makefile11
-rw-r--r--sbin/idmapd/idmapd.863
-rw-r--r--sbin/idmapd/idmapd.c418
-rw-r--r--sbin/mount_nfs/Makefile4
-rw-r--r--sbin/mount_nfs/mount_nfs.87
-rw-r--r--sbin/mount_nfs/mount_nfs.c255
-rw-r--r--sys/Makefile2
-rw-r--r--sys/conf/files9
-rw-r--r--sys/conf/options1
-rw-r--r--sys/fs/nfs/nfs_commonkrpc.c1
-rw-r--r--sys/fs/nfs/nfsport.h1
-rw-r--r--sys/modules/nfs4client/Makefile36
-rw-r--r--sys/modules/nfsclient/Makefile12
-rw-r--r--sys/nfs4client/nfs4.h260
-rw-r--r--sys/nfs4client/nfs4_dev.c456
-rw-r--r--sys/nfs4client/nfs4_dev.h65
-rw-r--r--sys/nfs4client/nfs4_idmap.c509
-rw-r--r--sys/nfs4client/nfs4_idmap.h64
-rw-r--r--sys/nfs4client/nfs4_socket.c348
-rw-r--r--sys/nfs4client/nfs4_subs.c1367
-rw-r--r--sys/nfs4client/nfs4_vfs.h34
-rw-r--r--sys/nfs4client/nfs4_vfs_subs.c125
-rw-r--r--sys/nfs4client/nfs4_vfsops.c886
-rw-r--r--sys/nfs4client/nfs4_vn.h33
-rw-r--r--sys/nfs4client/nfs4_vn_subs.c225
-rw-r--r--sys/nfs4client/nfs4_vnops.c2931
-rw-r--r--sys/nfs4client/nfs4m_subs.h498
-rw-r--r--sys/nfsclient/bootp_subr.c2
-rw-r--r--sys/nfsclient/krpc_subr.c2
-rw-r--r--sys/nfsclient/nfs.h12
-rw-r--r--sys/nfsclient/nfs_bio.c21
-rw-r--r--sys/nfsclient/nfs_diskless.c1
-rw-r--r--sys/nfsclient/nfs_krpc.c7
-rw-r--r--sys/nfsclient/nfs_lock.c2
-rw-r--r--sys/nfsclient/nfs_nfsiod.c2
-rw-r--r--sys/nfsclient/nfs_node.c13
-rw-r--r--sys/nfsclient/nfs_socket.c8
-rw-r--r--sys/nfsclient/nfs_subs.c2
-rw-r--r--sys/nfsclient/nfs_vfsops.c1
-rw-r--r--sys/nfsclient/nfs_vnops.c2
-rw-r--r--sys/nfsclient/nfsm_subs.h11
-rw-r--r--sys/nfsclient/nfsmount.h1
-rw-r--r--sys/nfsclient/nfsnode.h7
-rw-r--r--sys/nlm/nlm_advlock.c2
-rw-r--r--sys/rpc/rpcclnt.c2114
-rw-r--r--sys/rpc/rpcclnt.h354
48 files changed, 19 insertions, 11185 deletions
diff --git a/etc/rc.d/idmapd b/etc/rc.d/idmapd
deleted file mode 100755
index 4c90fd4..0000000
--- a/etc/rc.d/idmapd
+++ /dev/null
@@ -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"
diff --git a/sbin/Makefile b/sbin/Makefile
index 649f4a2..8ece390 100644
--- a/sbin/Makefile
+++ b/sbin/Makefile
@@ -36,7 +36,6 @@ SUBDIR= adjkerntz \
ggate \
growfs \
gvinum \
- idmapd \
ifconfig \
init \
${_ipf} \
diff --git a/sbin/idmapd/Makefile b/sbin/idmapd/Makefile
deleted file mode 100644
index 8206e0d..0000000
--- a/sbin/idmapd/Makefile
+++ /dev/null
@@ -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>
diff --git a/sbin/idmapd/idmapd.8 b/sbin/idmapd/idmapd.8
deleted file mode 100644
index 1fb6216..0000000
--- a/sbin/idmapd/idmapd.8
+++ /dev/null
@@ -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
diff --git a/sbin/idmapd/idmapd.c b/sbin/idmapd/idmapd.c
deleted file mode 100644
index fa3a082..0000000
--- a/sbin/idmapd/idmapd.c
+++ /dev/null
@@ -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);
-}
diff --git a/sbin/mount_nfs/Makefile b/sbin/mount_nfs/Makefile
index 4f7efea..960f97c 100644
--- a/sbin/mount_nfs/Makefile
+++ b/sbin/mount_nfs/Makefile
@@ -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>
diff --git a/sbin/mount_nfs/mount_nfs.8 b/sbin/mount_nfs/mount_nfs.8
index c75a30d..78a3b19 100644
--- a/sbin/mount_nfs/mount_nfs.8
+++ b/sbin/mount_nfs/mount_nfs.8
@@ -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
diff --git a/sbin/mount_nfs/mount_nfs.c b/sbin/mount_nfs/mount_nfs.c
index a2f5e89..102c51d 100644
--- a/sbin/mount_nfs/mount_nfs.c
+++ b/sbin/mount_nfs/mount_nfs.c
@@ -1,28 +1,4 @@
/*
- * 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 @@ tryagain:
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");
diff --git a/sys/Makefile b/sys/Makefile
index f41da81..cb5fd13 100644
--- a/sys/Makefile
+++ b/sys/Makefile
@@ -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
diff --git a/sys/conf/files b/sys/conf/files
index 33b4c6f..a3bd42f 100644
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -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
diff --git a/sys/conf/options b/sys/conf/options
index 758190f..cc06bd7 100644
--- a/sys/conf/options
+++ b/sys/conf/options
@@ -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
diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c
index 6e27e4d..4b37802 100644
--- a/sys/fs/nfs/nfs_commonkrpc.c
+++ b/sys/fs/nfs/nfs_commonkrpc.c
@@ -59,7 +59,6 @@ __FBSDID("$FreeBSD$");
#include <sys/vnode.h>
#include <rpc/rpc.h>
-#include <rpc/rpcclnt.h>
#include <kgssapi/krb5/kcrypto.h>
diff --git a/sys/fs/nfs/nfsport.h b/sys/fs/nfs/nfsport.h
index 5be6587..d452927 100644
--- a/sys/fs/nfs/nfsport.h
+++ b/sys/fs/nfs/nfsport.h
@@ -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>
/*
diff --git a/sys/modules/nfs4client/Makefile b/sys/modules/nfs4client/Makefile
deleted file mode 100644
index bdc272f..0000000
--- a/sys/modules/nfs4client/Makefile
+++ /dev/null
@@ -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>
diff --git a/sys/modules/nfsclient/Makefile b/sys/modules/nfsclient/Makefile
index a420502..af02f6a 100644
--- a/sys/modules/nfsclient/Makefile
+++ b/sys/modules/nfsclient/Makefile
@@ -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
diff --git a/sys/nfs4client/nfs4.h b/sys/nfs4client/nfs4.h
deleted file mode 100644
index 4bcc6a7..0000000
--- a/sys/nfs4client/nfs4.h
+++ /dev/null
@@ -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 */
diff --git a/sys/nfs4client/nfs4_dev.c b/sys/nfs4client/nfs4_dev.c
deleted file mode 100644
index fc1e487..0000000
--- a/sys/nfs4client/nfs4_dev.c
+++ /dev/null
@@ -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);
-}
diff --git a/sys/nfs4client/nfs4_dev.h b/sys/nfs4client/nfs4_dev.h
deleted file mode 100644
index be14ce2..0000000
--- a/sys/nfs4client/nfs4_dev.h
+++ /dev/null
@@ -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_ */
diff --git a/sys/nfs4client/nfs4_idmap.c b/sys/nfs4client/nfs4_idmap.c
deleted file mode 100644
index 5a02b47..0000000
--- a/sys/nfs4client/nfs4_idmap.c
+++ /dev/null
@@ -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;
-}
diff --git a/sys/nfs4client/nfs4_idmap.h b/sys/nfs4client/nfs4_idmap.h
deleted file mode 100644
index 0b09cf4..0000000
--- a/sys/nfs4client/nfs4_idmap.h
+++ /dev/null
@@ -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__ */
diff --git a/sys/nfs4client/nfs4_socket.c b/sys/nfs4client/nfs4_socket.c
deleted file mode 100644
index c1fe154..0000000
--- a/sys/nfs4client/nfs4_socket.c
+++ /dev/null
@@ -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);
-}
diff --git a/sys/nfs4client/nfs4_subs.c b/sys/nfs4client/nfs4_subs.c
deleted file mode 100644
index 21c89c9..0000000
--- a/sys/nfs4client/nfs4_subs.c
+++ /dev/null
@@ -1,1367 +0,0 @@
-/* $FreeBSD$ */
-/* $Id: nfs4_subs.c,v 1.52 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/cdefs.h>
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/bio.h>
-#include <sys/buf.h>
-#include <sys/proc.h>
-#include <sys/mount.h>
-#include <sys/vnode.h>
-#include <sys/namei.h>
-#include <sys/mbuf.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/malloc.h>
-#include <sys/sysent.h>
-#include <sys/syscall.h>
-#include <sys/sysproto.h>
-#include <sys/fcntl.h>
-
-#include <machine/stdarg.h>
-
-#include <vm/vm.h>
-#include <vm/vm_object.h>
-#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>
-#include <nfs4client/nfs4.h>
-#include <nfsclient/nfsnode.h>
-#include <nfsclient/nfsmount.h>
-#include <nfs/xdr_subs.h>
-#include <nfsclient/nfsm_subs.h>
-
-#include <nfs4client/nfs4_dev.h>
-#include <nfs4client/nfs4_idmap.h>
-#include <nfs4client/nfs4m_subs.h>
-
-#include <netinet/in.h>
-
-#define NFSM_DISSECT(s) do { \
- tl = nfsm_dissect_xx((s), md, dpos); \
- if (tl == NULL) { \
- printf("NFSM_DISSECT error; allocation (%s/%d) (%s:%d)\n", #s, s, __FILE__, __LINE__); \
- return (EBADRPC); \
- } \
-} while (0)
-
-#define NFSM_ADV(s) do { \
- t1 = nfsm_adv_xx((s), md, dpos); \
- if (t1 != 0) { \
- printf("NFSM_ADV error; allocation (%s/%d) (%s:%d)\n", #s, s, __FILE__, __LINE__); \
- return (EBADRPC); \
- } \
-} while (0)
-
-#define NFSM_MTOTIME(t) do { \
- NFSM_DISSECT(3 * NFSX_UNSIGNED); \
- (t).tv_sec = fxdr_hyper(tl); \
- tl += 2; \
- (t).tv_nsec = fxdr_unsigned(long, *tl++); \
-} while (0)
-
-static uint32_t __fsinfo_bm[2], __fsattr_bm[2], __getattr_bm[2], __readdir_bm[2];
-
-nfsv4bitmap nfsv4_fsinfobm = { 2, __fsinfo_bm };
-nfsv4bitmap nfsv4_fsattrbm = { 2, __fsattr_bm };
-nfsv4bitmap nfsv4_getattrbm = { 2, __getattr_bm };
-nfsv4bitmap nfsv4_readdirbm = { 2, __readdir_bm };
-
-/* Helper routines */
-int nfsm_v4build_attrs_xx(struct vattr *, struct mbuf **, caddr_t *);
-int nfsm_v4dissect_changeinfo_xx(nfsv4changeinfo *, struct mbuf **, caddr_t *);
-
-void
-nfsm_v4init(void)
-{
-
- /* Set up bitmasks */
- FA4_SET(FA4_FSID, __fsinfo_bm);
- FA4_SET(FA4_MAXREAD, __fsinfo_bm);
- FA4_SET(FA4_MAXWRITE, __fsinfo_bm);
- FA4_SET(FA4_LEASE_TIME, __fsinfo_bm);
-
- FA4_SET(FA4_FSID, __fsattr_bm);
- FA4_SET(FA4_FILES_FREE, __fsattr_bm);
- FA4_SET(FA4_FILES_TOTAL, __fsattr_bm);
- FA4_SET(FA4_SPACE_AVAIL, __fsattr_bm);
- FA4_SET(FA4_SPACE_FREE, __fsattr_bm);
- FA4_SET(FA4_SPACE_TOTAL, __fsattr_bm);
-
- FA4_SET(FA4_TYPE, __getattr_bm);
- FA4_SET(FA4_FSID, __getattr_bm);
- FA4_SET(FA4_SIZE, __getattr_bm);
- FA4_SET(FA4_MODE, __getattr_bm);
- FA4_SET(FA4_RAWDEV, __getattr_bm);
- FA4_SET(FA4_NUMLINKS, __getattr_bm);
- FA4_SET(FA4_OWNER, __getattr_bm);
- FA4_SET(FA4_OWNER_GROUP, __getattr_bm);
- FA4_SET(FA4_FILEID, __getattr_bm);
- FA4_SET(FA4_TIME_ACCESS, __getattr_bm);
- FA4_SET(FA4_TIME_CREATE, __getattr_bm);
- FA4_SET(FA4_TIME_METADATA, __getattr_bm);
- FA4_SET(FA4_TIME_MODIFY, __getattr_bm);
-
- FA4_SET(FA4_TYPE, __readdir_bm);
- FA4_SET(FA4_FSID, __readdir_bm);
- FA4_SET(FA4_FILEID, __readdir_bm);
- FA4_SET(FA4_RDATTR_ERROR, __readdir_bm);
-}
-
-/*
- * Util
- */
-
-uint32_t
-nfs_v4fileid4_to_fileid(uint64_t fid)
-{
- return ((uint32_t)((fid >> 32) | fid));
-}
-
-void
-nfs_v4initcompound(struct nfs4_compound *cp)
-{
- bzero(cp, sizeof(*cp));
-}
-
-/*
- * Build/dissect XDR buffer with a format string.
- *
- * u - unsigned
- * h - hyper
- * s - stringlength, string
- * k - skip length (bytes)
- * a - arraylength, componentlenght, array
- * o - opaque fix length
- * O - opaque var length in bytes
- */
-
-void
-nfsm_buildf_xx(struct mbuf **mb, caddr_t *bpos, char *fmt, ...)
-{
- uint32_t *tl, t1, len, uval;
- uint64_t hval;
- va_list args;
- char *p, *which;
-
- va_start(args, fmt);
- for (which = fmt; *which != '\0'; which++)
- switch (*which) {
- case 'u': /* Unsigned */
- tl = nfsm_build_xx(NFSX_UNSIGNED, mb, bpos);
- uval = va_arg(args, uint32_t);
- *tl++ = txdr_unsigned(uval);
- break;
- case 'h': /* Hyper */
- tl = nfsm_build_xx(2 * NFSX_UNSIGNED, mb, bpos);
- hval = va_arg(args, uint64_t);
- txdr_hyper(hval, tl);
- break;
- case 'o': /* Fixed-length opaque */
- len = va_arg(args, uint32_t);
- p = va_arg(args, char *);
- tl = nfsm_build_xx(nfsm_rndup(len), mb, bpos);
- bcopy(p, tl, len);
- break;
- case 'O': /* Variable-length opaque */
- case 's': /* String */
- len = va_arg(args, uint32_t);
- p = va_arg(args, char *);
- t1 = nfsm_strtom_xx(p, len, len, mb, bpos);
- break;
- case 'k': /* Skip */
- len = va_arg(args, uint32_t);
- nfsm_build_xx(nfsm_rndup(len), mb, bpos);
- break;
- default:
- panic("Invalid buildf string %s[%c]", fmt, *which);
- break;
- }
- va_end(args);
-}
-
-int
-nfsm_dissectf_xx(struct mbuf **md, caddr_t *dpos, char *fmt, ...)
-{
- uint32_t *tl, t1, len, *uval;
- uint64_t *hval;
- va_list args;
- char *p, *which;
-
- va_start(args, fmt);
- for (which = fmt; *which != '\0'; which++)
- switch (*which) {
- case 'u': /* Unsigned */
- tl = nfsm_dissect_xx(NFSX_UNSIGNED, md, dpos);
- if (tl == NULL)
- return (EBADRPC);
- uval = va_arg(args, uint32_t *);
- *uval = fxdr_unsigned(uint32_t, *tl++);
- break;
- case 'h': /* Hyper */
- tl = nfsm_dissect_xx(2 * NFSX_UNSIGNED, md, dpos);
- if (tl == NULL)
- return (EBADRPC);
- hval = va_arg(args, uint64_t *);
- *hval = fxdr_hyper(tl);
- break;
- case 'o': /* Fixed-length opaque */
- len = va_arg(args, uint32_t);
- p = va_arg(args, void *);
- tl = nfsm_dissect_xx(nfsm_rndup(len), md, dpos);
- if (tl == NULL)
- return (EBADRPC);
- bcopy(tl, p, len);
- break;
- case 'O': /* Variable-length opaque */
- case 's': /* String */
- len = va_arg(args, uint32_t);
- p = va_arg(args, char *);
- tl = nfsm_dissect_xx(nfsm_rndup(len), md, dpos);
- if (tl == NULL)
- return (EBADRPC);
- bcopy(tl, p, len);
- break;
- case 'k': /* Skip bytes */
- len = va_arg(args, uint32_t);
- t1 = nfsm_adv_xx(nfsm_rndup(len), md, dpos);
- break;
- default:
- panic("Invalid dissectf string %s[%c]", fmt, *which);
- break;
- }
- va_end(args);
-
- return (0);
-}
-
-/*
- * XXX - There are a few problems with the way the postops are places
- * in the code. Ideally, they should be taken care of immediately, as
- * to avoid uneceesary waits for mutexes, but then we would be
- * introducing even more complexity by having to handle two separate
- * cases. Also, since they are placed at the end of the vnops', there
- * may be operations which sleep in between, further extending this
- * wait. It is conceivable that there is a deadlock condition there,
- * too.
- *
- * Also, for vnops that do multiple operations, it's inconvenient
- * since on error, individual decoding will got nfsmout.
- */
-
-int
-nfs_v4postop(struct nfs4_compound *cp, int status)
-{
- struct nfs4_fctx *fcp = cp->fcp;
-
- /*
- * XXX does the previous result need to be stores with the
- * lockowner? ack, spec is unclear ..
- */
-
- if (fcp != NULL)
- if (cp->seqidused < cp->rep_nops ||
- (cp->seqidused + 1 == cp->rep_nops &&
- NFS4_SEQIDMUTATINGERROR(status)))
- fcp->lop->lo_seqid++;
-
- return (status);
-}
-
-int
-nfs_v4handlestatus(int status, struct nfs4_compound *cp)
-{
- return (status);
-}
-
-/*
- * Initial setup of compound.
- */
-
-int
-nfsm_v4build_compound_xx(struct nfs4_compound *cp, char *tag,
- struct mbuf **mb, caddr_t *bpos)
-{
- uint32_t t1, *tl, siz;
-
- /* Tag */
- siz = strlen(tag);
- t1 = nfsm_rndup(siz) + NFSX_UNSIGNED;
- if (t1 <= M_TRAILINGSPACE(*mb)) {
- tl = nfsm_build_xx(t1, mb, bpos);
- *tl++ = txdr_unsigned(siz);
- *(tl + ((t1 >> 2) - 2)) = 0;
- bcopy(tag, tl, siz);
- } else {
- t1 = nfsm_strtmbuf(mb, bpos, (const char *)tag, siz);
- if (t1 != 0)
- return (t1);
- }
-
- /* Minor version and argarray*/
- tl = nfsm_build_xx(2 * NFSX_UNSIGNED, mb, bpos);
- *tl++ = txdr_unsigned(NFS4_MINOR_VERSION);
- /* Save for backfill */
- cp->req_nopsp = tl;
- *tl = txdr_unsigned(0);
-
- cp->curvp = NULL;
- cp->savevp = NULL;
-
- return (0);
-}
-
-/*
- * XXX
- * - backfill for stateid, and such
- */
-int
-nfsm_v4build_finalize_xx(struct nfs4_compound *cp, struct mbuf **mb, caddr_t *bpos)
-{
- *cp->req_nopsp = txdr_unsigned(cp->req_nops);
-
- return (0);
-}
-
-int
-nfsm_v4build_putfh_xx(struct nfs4_compound *cp, struct vnode *vp,
- struct mbuf **mb, caddr_t *bpos)
-{
- uint32_t t1;
-
- /* Op */
- nfsm_buildf_xx(mb, bpos, "u", NFSV4OP_PUTFH);
-
- /* FH */
- t1 = nfsm_fhtom_xx(vp, 1, mb, bpos);
- if (t1 != 0)
- return (t1);
-
- cp->req_nops++;
- cp->curvp = vp;
-
- return (0);
-}
-
-int
-nfsm_v4build_putfh_nv_xx(struct nfs4_compound *cp, struct nfs4_oparg_getfh *gfh,
- struct mbuf **mb, caddr_t *bpos)
-{
- nfsm_buildf_xx(mb, bpos, "uuo",
- NFSV4OP_PUTFH,
- gfh->fh_len,
- gfh->fh_len,
- &gfh->fh_val);
-
- cp->req_nops++;
-
- return (0);
-}
-
-int
-nfsm_v4build_simple_xx(struct nfs4_compound *cp, uint32_t op,
- struct mbuf **mb, caddr_t *bpos)
-{
- nfsm_buildf_xx(mb, bpos, "u", op);
-
- cp->req_nops++;
-
- return (0);
-}
-
-int
-nfsm_v4build_getattr_xx(struct nfs4_compound *cp, struct nfs4_oparg_getattr *ga,
- struct mbuf **mb, caddr_t *bpos)
-{
- int i;
-
- /* Op + bitmap length + bitmap */
- nfsm_buildf_xx(mb, bpos, "uu", NFSV4OP_GETATTR, ga->bm->bmlen);
- for (i = 0; i < ga->bm->bmlen; i++)
- nfsm_buildf_xx(mb, bpos, "u", ga->bm->bmval[i]);
-
- ga->vp = cp->curvp;
- cp->req_nops++;
-
- return (0);
-}
-
-int
-nfsm_v4build_setattr_xx(struct nfs4_compound *cp, struct vattr *vap,
- struct nfs4_fctx *fcp, struct mbuf **mb, caddr_t *bpos)
-{
- int error;
- static char zero_stateid[NFSX_V4STATEID];
-
- nfsm_buildf_xx(mb, bpos, "uo",
- NFSV4OP_SETATTR,
- NFSX_V4STATEID, fcp ? fcp->stateid : zero_stateid);
- error = nfsm_v4build_attrs_xx(vap, mb, bpos);
- if (error == 0)
- cp->req_nops++;
-
- return (error);
-}
-
-int
-nfsm_v4build_getfh_xx(struct nfs4_compound *cp, struct nfs4_oparg_getfh *gfh,
- struct mbuf **mb, caddr_t *bpos)
-{
- nfsm_buildf_xx(mb, bpos, "u", NFSV4OP_GETFH);
-
- gfh->vp = cp->curvp;
- cp->req_nops++;
-
- return (0);
-}
-
-int
-nfsm_v4build_lookup_xx(struct nfs4_compound *cp, struct nfs4_oparg_lookup *l,
- struct mbuf **mb, caddr_t *bpos)
-{
- nfsm_buildf_xx(mb, bpos, "us", NFSV4OP_LOOKUP, l->namelen, l->name);
-
- cp->curvp = l->vp;
- cp->req_nops++;
-
- return (0);
-}
-
-int
-nfsm_v4build_setclientid_xx(struct nfs4_compound *cp,
- struct nfs4_oparg_setclientid *sci, struct mbuf **mb, caddr_t *bpos)
-{
- struct timeval tv;
-
- microtime(&tv);
-
- nfsm_buildf_xx(mb, bpos, "uuusussu",
- NFSV4OP_SETCLIENTID,
- tv.tv_sec, tv.tv_usec,
- sci->namelen, sci->name,
- sci->cb_prog,
- sci->cb_netidlen, sci->cb_netid,
- sci->cb_univaddrlen, sci->cb_univaddr,
- 0xCA11BACC);
-
- cp->req_nops++;
-
- return (0);
-}
-
-int
-nfsm_v4build_setclientid_confirm_xx(struct nfs4_compound *cp,
- struct nfs4_oparg_setclientid *sci, struct mbuf **mb, caddr_t *bpos)
-{
- nfsm_buildf_xx(mb, bpos, "uho",
- NFSV4OP_SETCLIENTID_CONFIRM,
- sci->clientid,
- sizeof(sci->verf), sci->verf);
-
- cp->req_nops++;
-
- return (0);
-}
-
-int
-nfsm_v4build_open_xx(struct nfs4_compound *cp, struct nfs4_oparg_open *op,
- struct mbuf **mb, caddr_t *bpos)
-{
- int error = 0;
- struct nfs4_lowner *lop = op->fcp->lop;
-
- nfsm_buildf_xx(mb, bpos, "uuuuhuu",
- NFSV4OP_OPEN,
- lop->lo_seqid,
- op->flags & O_ACCMODE,
- NFSV4OPENSHARE_DENY_NONE,
- cp->nmp->nm_clientid,
- 4, lop->lo_id);
-
- if (op->flags & O_CREAT) {
- nfsm_buildf_xx(mb, bpos, "u", OTCREATE);
- /* openflag4: mode */
- nfsm_buildf_xx(mb, bpos, "u", CMUNCHECKED);
- /* openflag4: createattrs... */
- if (op->vap != NULL) {
- if (op->flags & O_TRUNC)
- op->vap->va_size = 0;
- error = nfsm_v4build_attrs_xx(op->vap, mb, bpos);
- if (error != 0)
- return (error);
- } else
- nfsm_buildf_xx(mb, bpos, "uu", 0, 0);
- } else
- nfsm_buildf_xx(mb, bpos, "u", OTNOCREATE);
-
- nfsm_buildf_xx(mb, bpos, "us", op->ctype,
- op->cnp->cn_namelen, op->cnp->cn_nameptr);
-
- cp->seqidused = cp->req_nops++;
- cp->fcp = op->fcp;
-
- return (error);
-}
-
-/*
- * XXX
- * - Wait on recovery
- */
-int
-nfsm_v4build_open_confirm_xx(struct nfs4_compound *cp, struct nfs4_oparg_open *op,
- struct mbuf **mb, caddr_t *bpos)
-{
- nfsm_buildf_xx(mb, bpos, "uou",
- NFSV4OP_OPEN_CONFIRM,
- NFSX_V4STATEID, op->fcp->stateid,
- op->fcp->lop->lo_seqid);
-
- cp->seqidused = cp->req_nops++;
- cp->fcp = op->fcp;
-
- return (0);
-}
-
-/*
- * XXX
- * - Wait on recovery
- */
-int
-nfsm_v4build_close_xx(struct nfs4_compound *cp, struct nfs4_fctx *fcp,
- struct mbuf **mb, caddr_t *bpos)
-{
- struct nfs4_lowner *lop = fcp->lop;
-
- nfsm_buildf_xx(mb, bpos, "uuo",
- NFSV4OP_CLOSE,
- lop->lo_seqid,
- NFSX_V4STATEID, fcp->stateid);
-
- cp->seqidused = cp->req_nops++;
- cp->fcp = fcp;
-
- return (0);
-}
-
-int
-nfsm_v4build_access_xx(struct nfs4_compound *cp, struct nfs4_oparg_access *acc,
- struct mbuf **mb, caddr_t *bpos)
-{
- nfsm_buildf_xx(mb, bpos, "uu", NFSV4OP_ACCESS, acc->mode);
- cp->req_nops++;
-
- return (0);
-}
-
-int
-nfsm_v4build_read_xx(struct nfs4_compound *cp, struct nfs4_oparg_read *r,
- struct mbuf **mb, caddr_t *bpos)
-{
- nfsm_buildf_xx(mb, bpos, "uohu",
- NFSV4OP_READ,
- NFSX_V4STATEID, r->fcp->stateid,
- r->off,
- r->maxcnt);
- cp->req_nops++;
-
- return (0);
-}
-
-int
-nfsm_v4build_write_xx(struct nfs4_compound *cp, struct nfs4_oparg_write *w,
- struct mbuf **mb, caddr_t *bpos)
-{
- nfsm_buildf_xx(mb, bpos, "uohuu",
- NFSV4OP_WRITE,
- NFSX_V4STATEID, w->fcp->stateid,
- w->off,
- w->stable,
- w->cnt);
- cp->req_nops++;
- return (nfsm_uiotombuf(w->uiop, mb, w->cnt, bpos));
-}
-
-int
-nfsm_v4build_commit_xx(struct nfs4_compound *cp, struct nfs4_oparg_commit *c,
- struct mbuf **mb, caddr_t *bpos)
-{
- nfsm_buildf_xx(mb, bpos, "uhu", NFSV4OP_COMMIT, c->start, c->len);
- cp->req_nops++;
-
- return (0);
-}
-
-int
-nfsm_v4build_readdir_xx(struct nfs4_compound *cp, struct nfs4_oparg_readdir *r,
- struct mbuf **mb, caddr_t *bpos)
-{
- int i;
-
- nfsm_buildf_xx(mb, bpos, "uhouuu",
- NFSV4OP_READDIR,
- r->cookie,
- sizeof(r->verf), r->verf,
- r->cnt >> 4, /* meaningless "dircount" field */
- r->cnt,
- r->bm->bmlen);
-
- for (i = 0; i < r->bm->bmlen; i++)
- nfsm_buildf_xx(mb, bpos, "u", r->bm->bmval[i]);
-
- cp->req_nops++;
-
- return (0);
-}
-
-int
-nfsm_v4build_renew_xx(struct nfs4_compound *cp, uint64_t cid,
- struct mbuf **mb, caddr_t *bpos)
-{
- nfsm_buildf_xx(mb, bpos, "uh", NFSV4OP_RENEW, cid);
- cp->req_nops++;
-
- return (0);
-}
-
-int
-nfsm_v4build_create_xx(struct nfs4_compound *cp, struct nfs4_oparg_create *c,
- struct mbuf **mb, caddr_t *bpos)
-{
- uint32_t t1;
-
- nfsm_buildf_xx(mb, bpos, "uu", NFSV4OP_CREATE, c->type);
-
- if (c->type == NFLNK)
- /* XXX strlen */
- nfsm_buildf_xx(mb, bpos, "s", strlen(c->linktext), c->linktext);
- else if (c->type == NFCHR || c->type == NFBLK)
- nfsm_buildf_xx(mb, bpos, "uu",
- major(c->vap->va_rdev), minor(c->vap->va_rdev));
-
- /* Name */
- nfsm_buildf_xx(mb, bpos, "s", c->namelen, c->name);
-
- /* Attributes */
- t1 = nfsm_v4build_attrs_xx(c->vap, mb, bpos);
- if (t1 != 0)
- return (t1);
-
- cp->req_nops++;
-
- return (0);
-}
-
-int
-nfsm_v4build_rename_xx(struct nfs4_compound *cp, struct nfs4_oparg_rename *r,
- struct mbuf **mb, caddr_t *bpos)
-{
- nfsm_buildf_xx(mb, bpos, "uss", NFSV4OP_RENAME, r->fnamelen, r->fname,
- r->tnamelen, r->tname);
-
- cp->req_nops++;
-
- return (0);
-}
-
-int
-nfsm_v4build_link_xx(struct nfs4_compound *cp, struct nfs4_oparg_link *l,
- struct mbuf **mb, caddr_t *bpos)
-{
- nfsm_buildf_xx(mb, bpos, "us", NFSV4OP_LINK, l->namelen, l->name);
-
- cp->req_nops++;
-
- return (0);
-}
-
-int
-nfsm_v4build_remove_xx(struct nfs4_compound *cp, const char *name, u_int namelen,
- struct mbuf **mb, caddr_t *bpos)
-{
- nfsm_buildf_xx(mb, bpos, "us", NFSV4OP_REMOVE, namelen, name);
-
- cp->req_nops++;
-
- return (0);
-}
-
-int
-nfsm_v4build_attrs_xx(struct vattr *vap, struct mbuf **mb, caddr_t *bpos)
-{
- uint32_t *tl, *attrlenp, *bmvalp, len;
- size_t siz;
-
- tl = nfsm_build_xx(4 * NFSX_UNSIGNED, mb, bpos);
-
- *tl++ = txdr_unsigned(2); /* bitmap length */
- bmvalp = tl;
- bzero(bmvalp, 8);
- tl += 2;
- attrlenp = tl;
-
- len = 0;
- if (vap->va_size != VNOVAL) {
- tl = nfsm_build_xx(2 * NFSX_UNSIGNED, mb, bpos);
- FA4_SET(FA4_SIZE, bmvalp);
- txdr_hyper(vap->va_size, tl); tl += 2;
- len += 2 * NFSX_UNSIGNED;
- }
- if (vap->va_mode != (u_short)VNOVAL) {
- tl = nfsm_build_xx(NFSX_UNSIGNED, mb, bpos);
- FA4_SET(FA4_MODE, bmvalp);
- *tl++ = txdr_unsigned(vap->va_mode);
- len += NFSX_UNSIGNED;
- }
- if (vap->va_uid != VNOVAL) {
- int error;
- char *name;
- error = idmap_uid_to_name(vap->va_uid, &name, &siz);
- if (error || name == NULL || siz == 0) {
- /* XXX */
- siz = sizeof("nobody") - 1;
- tl = nfsm_build_xx(NFSX_UNSIGNED + nfsm_rndup(siz), mb,
- bpos);
- *tl++ = txdr_unsigned(siz);
- bcopy("nobody", tl, siz);
- len += NFSX_UNSIGNED + nfsm_rndup(siz);
- } else {
- tl = nfsm_build_xx(NFSX_UNSIGNED + nfsm_rndup(siz), mb,
- bpos);
- *tl++ = txdr_unsigned(siz);
- bcopy(name, tl, siz);
- len += NFSX_UNSIGNED + nfsm_rndup(siz);
- }
- FA4_SET(FA4_OWNER, bmvalp);
- }
- if (vap->va_gid != VNOVAL) {
- int error;
- char *name;
- error = idmap_gid_to_name(vap->va_gid, &name, &siz);
- if (error || name == NULL || siz == 0) {
- /* XXX */
- siz = sizeof("nogroup") - 1;
- tl = nfsm_build_xx(NFSX_UNSIGNED + nfsm_rndup(siz), mb,
- bpos);
- *tl++ = txdr_unsigned(siz);
- bcopy("nogroup", tl, siz);
- len += NFSX_UNSIGNED + nfsm_rndup(siz);
- } else {
- tl = nfsm_build_xx(NFSX_UNSIGNED + nfsm_rndup(siz), mb,
- bpos);
- *tl++ = txdr_unsigned(siz);
- bcopy(name, tl, siz);
- len += NFSX_UNSIGNED + nfsm_rndup(siz);
- }
- FA4_SET(FA4_OWNER_GROUP, bmvalp);
- }
- if (vap->va_atime.tv_sec != VNOVAL) {
- uint64_t val = vap->va_atime.tv_sec;
- tl = nfsm_build_xx(4 * NFSX_UNSIGNED, mb, bpos);
- FA4_SET(FA4_TIME_ACCESS_SET, bmvalp);
- *tl++ = txdr_unsigned(THCLIENTTIME);
- txdr_hyper(val, tl); tl += 2;
- *tl++ = txdr_unsigned(vap->va_atime.tv_nsec);
- len += 4 * NFSX_UNSIGNED;
- }
- if (vap->va_mtime.tv_sec != VNOVAL) {
- uint64_t val = vap->va_mtime.tv_sec;
- tl = nfsm_build_xx(4 * NFSX_UNSIGNED, mb, bpos);
- FA4_SET(FA4_TIME_MODIFY_SET, bmvalp);
- *tl++ = txdr_unsigned(THCLIENTTIME);
- txdr_hyper(val, tl); tl += 2;
- *tl++ = txdr_unsigned(vap->va_mtime.tv_nsec);
- len += 4 * NFSX_UNSIGNED;
- }
-
- bmvalp[0] = txdr_unsigned(bmvalp[0]);
- bmvalp[1] = txdr_unsigned(bmvalp[1]);
-
- *attrlenp = txdr_unsigned(len);
-
- return (0);
-}
-
-int
-nfsm_v4dissect_compound_xx(struct nfs4_compound *cp, struct mbuf **md, caddr_t *dpos)
-{
- uint32_t taglen, t1, *tl;
-
- tl = nfsm_dissect_xx(NFSX_UNSIGNED, md, dpos);
- if (tl == NULL)
- return (EBADRPC);
-
- /* Reply status is handled by the RPC code */
-
- taglen = fxdr_unsigned(uint32_t, *tl++);
- t1 = nfsm_adv_xx(nfsm_rndup(taglen), md, dpos);
- if (t1 != 0)
- return (EBADRPC);
-
- tl = nfsm_dissect_xx(NFSX_UNSIGNED, md, dpos);
- if (tl == NULL)
- return (EBADRPC);
-
- cp->rep_nops = fxdr_unsigned(uint32_t, *tl++);
-
- return (0);
-}
-
-int
-nfsm_v4dissect_simple_xx(struct nfs4_compound *cp, uint32_t op,
- uint32_t skipbytes, struct mbuf **md, caddr_t *dpos)
-{
- uint32_t t1, dop, status;
-
- t1 = nfsm_dissectf_xx(md, dpos, "uu", &dop, &status);
- if (t1 != 0)
- return (t1);
-
- if (dop != op || status != 0)
- return (EBADRPC);
-
- if (skipbytes > 0)
- NFSM_ADV(nfsm_rndup(skipbytes));
-
- return (0);
-}
-
-int
-nfsm_v4dissect_getattr_xx(struct nfs4_compound *cp, struct nfs4_oparg_getattr *ga,
- struct mbuf **md, caddr_t *dpos)
-{
- uint32_t *tl;
-
- tl = nfsm_dissect_xx(2 * NFSX_UNSIGNED, md, dpos);
- if (tl == NULL || fxdr_unsigned(uint32_t, *tl++) != NFSV4OP_GETATTR ||
- *tl++ != 0)
- return (EBADRPC);
-
- return (nfsm_v4dissect_attrs_xx(&ga->fa, md, dpos));
-}
-
-int
-nfsm_v4dissect_setattr_xx(struct nfs4_compound *cp, struct mbuf **md, caddr_t *dpos)
-{
- uint32_t t1, op, bmlen, status;
-
- t1 = nfsm_dissectf_xx(md, dpos, "uu", &op, &status);
- if (t1 != 0)
- return (t1);
-
- if (op != NFSV4OP_SETATTR || status != 0)
- return (EBADRPC);
-
- t1 = nfsm_dissectf_xx(md, dpos, "u", &bmlen);
- if (t1 != 0)
- return (t1);
-
- return (nfsm_dissectf_xx(md, dpos, "k", bmlen << 2));
-}
-
-int
-nfsm_v4dissect_getfh_xx(struct nfs4_compound *cp, struct nfs4_oparg_getfh *gfh,
- struct mbuf **md, caddr_t *dpos)
-{
- uint32_t *tl, len, xdrlen;
-
- tl = nfsm_dissect_xx(2 * NFSX_UNSIGNED, md, dpos);
- if (tl == NULL || fxdr_unsigned(uint32_t, *tl++) != NFSV4OP_GETFH)
- return (EBADRPC);
-
- if (*tl++ != 0)
- return (EBADRPC);
-
- NFSM_DISSECT(NFSX_UNSIGNED);
- len = fxdr_unsigned(uint32_t, *tl++);
- if (len > NFSX_V4FH)
- return (EBADRPC);
-
- /* XXX integrate this into nfs_mtofh()? */
-
- gfh->fh_len = len;
- xdrlen = nfsm_rndup(len);
-
- NFSM_DISSECT(xdrlen);
- bcopy(tl, &gfh->fh_val, xdrlen);
-
- return (0);
-}
-
-int
-nfsm_v4dissect_setclientid_xx(struct nfs4_compound *cp,
- struct nfs4_oparg_setclientid *sci, struct mbuf **md, caddr_t *dpos)
-{
- uint32_t *tl;
-
- tl = nfsm_dissect_xx(2 * NFSX_UNSIGNED, md, dpos);
- if (tl == NULL || fxdr_unsigned(uint32_t, *tl++) != NFSV4OP_SETCLIENTID)
- return (EBADRPC);
-
- /* Handle NFS4ERR_CLID_INUSE specially */
- if (*tl++ != 0)
- return (EBADRPC);
-
- NFSM_DISSECT(2 * NFSX_UNSIGNED);
- sci->clientid = fxdr_hyper(tl);
-
- NFSM_DISSECT(nfsm_rndup(NFSX_V4VERF));
- bcopy(tl, sci->verf, NFSX_V4VERF);
-
- return (0);
-}
-
-int
-nfsm_v4dissect_close_xx(struct nfs4_compound *cp, struct nfs4_fctx *fcp,
- struct mbuf **md, caddr_t *dpos)
-{
- uint32_t *tl, t1;
-
- tl = nfsm_dissect_xx(2 * NFSX_UNSIGNED, md, dpos);
- if (tl == NULL || fxdr_unsigned(uint32_t, *tl++) != NFSV4OP_CLOSE ||
- *tl++ != 0)
- return (EBADRPC);
-
- /* Copy stateid */
- t1 = nfsm_dissectf_xx(md, dpos, "o", NFSX_V4STATEID, fcp->stateid);
- if (t1 != 0)
- return (t1);
-
- return (0);
-}
-
-int
-nfsm_v4dissect_access_xx(struct nfs4_compound *cp, struct nfs4_oparg_access *acc,
- struct mbuf **md, caddr_t *dpos)
-{
- uint32_t *tl;
-
- tl = nfsm_dissect_xx(4 * NFSX_UNSIGNED, md, dpos);
- if (tl == NULL || fxdr_unsigned(uint32_t, *tl++) != NFSV4OP_ACCESS ||
- *tl++ != 0)
- return (EBADRPC);
-
- acc->supported = fxdr_unsigned(uint32_t, *tl++);
- acc->rmode = fxdr_unsigned(uint32_t, *tl++);
-
- return (0);
-}
-
-int
-nfsm_v4dissect_open_xx(struct nfs4_compound *cp, struct nfs4_oparg_open *op,
- struct mbuf **md, caddr_t *dpos)
-{
- uint32_t *tl, t1, bmlen, delegtype = ODNONE;
- int error = 0;
- nfsv4changeinfo cinfo;
- struct nfs4_fctx *fcp = op->fcp;
-
- tl = nfsm_dissect_xx(2 * NFSX_UNSIGNED, md, dpos);
- if (tl == NULL || fxdr_unsigned(uint32_t, *tl++) != NFSV4OP_OPEN ||
- *tl++ != 0)
- return (EBADRPC);
-
- t1 = nfsm_dissectf_xx(md, dpos, "o", NFSX_V4STATEID, fcp->stateid);
- if (t1 != 0)
- return (t1);
-
- error = nfsm_v4dissect_changeinfo_xx(&cinfo, md, dpos);
- if (error != 0)
- goto nfsmout;
-
- NFSM_DISSECT(2 * NFSX_UNSIGNED);
-
- op->rflags = fxdr_unsigned(uint32_t, *tl++);
- bmlen = fxdr_unsigned(uint32_t, *tl++);
- if (bmlen > 2) {
- error = EBADRPC;
- goto nfsmout;
- }
-
- /* Skip */
- NFSM_ADV(nfsm_rndup(bmlen << 2));
-
- NFSM_DISSECT(NFSX_UNSIGNED);
- delegtype = fxdr_unsigned(uint32_t, *tl++);
- switch (delegtype) {
- case ODREAD:
- case ODWRITE:
- printf("nfs4: client delegation not yet supported\n");
- error = EOPNOTSUPP;
- goto nfsmout;
- break;
- case ODNONE:
- default:
- break;
- }
-
- nfsmout:
- return (error);
-}
-
-int
-nfsm_v4dissect_open_confirm_xx(struct nfs4_compound *cp, struct nfs4_oparg_open *op,
- struct mbuf **md, caddr_t *dpos)
-{
- uint32_t *tl;
-
- tl = nfsm_dissect_xx(2 * NFSX_UNSIGNED, md, dpos);
- if (tl == NULL || fxdr_unsigned(uint32_t, *tl++) != NFSV4OP_OPEN_CONFIRM ||
- *tl++ != 0)
- return (EBADRPC);
-
- return nfsm_dissectf_xx(md, dpos, "o", NFSX_V4STATEID, op->fcp->stateid);
-}
-
-int
-nfsm_v4dissect_read_xx(struct nfs4_compound *cp, struct nfs4_oparg_read *r,
- struct mbuf **md, caddr_t *dpos)
-{
- uint32_t op, status, t1;
-
- t1 = nfsm_dissectf_xx(md, dpos, "uu", &op, &status);
- if (t1 != 0)
- return (t1);
-
- if (op != NFSV4OP_READ || status != 0)
- return (EBADRPC);
-
- t1 = nfsm_dissectf_xx(md, dpos, "uu", &r->eof, &r->retlen);
- if (t1 != 0)
- return (t1);
-
- return (nfsm_mbuftouio(md, r->uiop, r->retlen, dpos));
-}
-
-int
-nfsm_v4dissect_write_xx(struct nfs4_compound *cp, struct nfs4_oparg_write *w,
- struct mbuf **md, caddr_t *dpos)
-{
- uint32_t op, status, t1;
-
- t1 = nfsm_dissectf_xx(md, dpos, "uu", &op, &status);
- if (t1 != 0)
- return (t1);
-
- if (op != NFSV4OP_WRITE || status != 0)
- return (EBADRPC);
-
- return (nfsm_dissectf_xx(md, dpos, "uuo", &w->retlen, &w->committed,
- NFSX_V4VERF, w->wverf));
-}
-
-int
-nfsm_v4dissect_commit_xx(struct nfs4_compound *cp, struct nfs4_oparg_commit *c,
- struct mbuf **md, caddr_t *dpos)
-{
- uint32_t t1, op, status;
-
- t1 = nfsm_dissectf_xx(md, dpos, "uu", &op, &status);
- if (t1 != 0)
- return (t1);
-
- if (op != NFSV4OP_COMMIT || status != 0)
- return (EBADRPC);
-
- return (nfsm_dissectf_xx(md, dpos, "o", NFSX_V4VERF, c->verf));
-}
-
-int
-nfsm_v4dissect_create_xx(struct nfs4_compound *cp, struct nfs4_oparg_create *c,
- struct mbuf **md, caddr_t *dpos)
-{
- uint32_t t1, *tl, op, status, bmlen;
- nfsv4changeinfo ci;
-
- t1 = nfsm_dissectf_xx(md, dpos, "uu", &op, &status);
- if (t1 != 0)
- return (t1);
-
- if (op != NFSV4OP_CREATE || status != 0)
- return (EBADRPC);
-
- /* Just throw this away for now */
- t1 = nfsm_v4dissect_changeinfo_xx(&ci, md, dpos);
- if (t1 != 0)
- return (t1);
-
- /* Throw this away too */
- NFSM_DISSECT(NFSX_UNSIGNED);
- bmlen = fxdr_unsigned(uint32_t, *tl++);
- NFSM_DISSECT(bmlen * NFSX_UNSIGNED);
- tl += bmlen;
-
- return 0;
-}
-
-int
-nfsm_v4dissect_readlink_xx(struct nfs4_compound *cp, struct uio *uiop,
- struct mbuf **md, caddr_t *dpos)
-{
- uint32_t t1, *tl, op, status, linklen;
-
- t1 = nfsm_dissectf_xx(md, dpos, "uu", &op, &status);
- if (t1 != 0)
- return (t1);
-
- if (op != NFSV4OP_READLINK || status != 0)
- return (EBADRPC);
-
- /* Do this one manually for careful checking of sizes. */
- NFSM_DISSECT(NFSX_UNSIGNED);
- linklen = fxdr_unsigned(uint32_t, *tl++);
- if (linklen <= 0)
- return (EBADRPC);
-
- return (nfsm_mbuftouio(md, uiop, MIN(linklen, uiop->uio_resid), dpos));
-}
-
-int
-nfsm_v4dissect_changeinfo_xx(nfsv4changeinfo *ci,
- struct mbuf **md, caddr_t *dpos)
-{
- uint32_t *tl;
-
- NFSM_DISSECT(5 * NFSX_UNSIGNED);
-
- ci->ciatomic = fxdr_unsigned(uint32_t, *tl++);
- ci->cibefore = fxdr_hyper(tl); tl += 2;
- ci->ciafter = fxdr_hyper(tl); tl += 2;
-
- return (0);
-}
-
-int
-nfsm_v4dissect_attrs_xx(struct nfsv4_fattr *fa, struct mbuf **md, caddr_t *dpos)
-{
- uint32_t t1, *tl, bmlen, bmval[2], attrlen, len = 0;
-
- /* Bitmap length + value */
- NFSM_DISSECT(NFSX_UNSIGNED);
-
- bmlen = fxdr_unsigned(uint32_t, *tl++);
- if (bmlen > 2)
- return (EBADRPC);
-
- if (bmlen == 0)
- return (0);
-
- NFSM_DISSECT(nfsm_rndup(bmlen << 2) + NFSX_UNSIGNED);
-
- bmval[0] = bmlen > 0 ? fxdr_unsigned(uint32_t, *tl++) : 0;
- bmval[1] = bmlen > 1 ? fxdr_unsigned(uint32_t, *tl++) : 0;
-
- /* Attribute length */
- attrlen = fxdr_unsigned(uint32_t, *tl++);
-
- /*
- * XXX check for correct (<=) attributes mask return from
- * server. need to pass this in.
- */
-
- if (FA4_ISSET(FA4_TYPE, bmval)) {
- /* overflow check */
- NFSM_DISSECT(NFSX_UNSIGNED);
- fa->fa4_type = fxdr_unsigned(uint32_t, *tl++);
- fa->fa4_valid |= FA4V_TYPE;
- len += NFSX_UNSIGNED;
- }
- if (FA4_ISSET(FA4_CHANGE, bmval)) {
- NFSM_DISSECT(2 * NFSX_UNSIGNED);
- fa->fa4_changeid = fxdr_hyper(tl);
- fa->fa4_valid |= FA4V_CHANGEID;
- len += 2 * NFSX_UNSIGNED;
- }
- if (FA4_ISSET(FA4_SIZE, bmval)) {
- NFSM_DISSECT(2 * NFSX_UNSIGNED);
- fa->fa4_size = fxdr_hyper(tl);
- fa->fa4_valid |= FA4V_SIZE;
- len += 2 * NFSX_UNSIGNED;
- }
- if (FA4_ISSET(FA4_FSID, bmval)) {
- NFSM_DISSECT(4 * NFSX_UNSIGNED);
- fa->fa4_fsid_major = fxdr_hyper(tl); tl += 2;
- fa->fa4_fsid_minor = fxdr_hyper(tl);
- fa->fa4_valid |= FA4V_SIZE;
- len += 4 * NFSX_UNSIGNED;
- }
- if (FA4_ISSET(FA4_LEASE_TIME, bmval)) {
- NFSM_DISSECT(NFSX_UNSIGNED);
- fa->fa4_lease_time = fxdr_unsigned(uint32_t, *tl++);
- fa->fa4_valid |= FA4V_LEASE_TIME;
- len += NFSX_UNSIGNED;
- }
- if (FA4_ISSET(FA4_RDATTR_ERROR, bmval)) {
- /* ignore for now; we only ask for it so the compound won't fail */
- NFSM_DISSECT(NFSX_UNSIGNED);
- tl++;
- len += NFSX_UNSIGNED;
- }
- if (FA4_ISSET(FA4_FILEID, bmval)) {
- NFSM_DISSECT(2 * NFSX_UNSIGNED);
- fa->fa4_fileid = fxdr_hyper(tl);
- fa->fa4_valid |= FA4V_FILEID;
- len += 2 * NFSX_UNSIGNED;
- }
- if (FA4_ISSET(FA4_FILES_FREE, bmval)) {
- NFSM_DISSECT(2 * NFSX_UNSIGNED);
- fa->fa4_ffree = fxdr_hyper(tl);
- fa->fa4_valid |= FA4V_FFREE;
- len += 2 * NFSX_UNSIGNED;
- }
- if (FA4_ISSET(FA4_FILES_TOTAL, bmval)) {
- NFSM_DISSECT(2 * NFSX_UNSIGNED);
- fa->fa4_ftotal = fxdr_hyper(tl);
- fa->fa4_valid |= FA4V_FTOTAL;
- len += 2 * NFSX_UNSIGNED;
- }
- if (FA4_ISSET(FA4_MAXFILESIZE, bmval)) {
- NFSM_DISSECT(2 * NFSX_UNSIGNED);
- fa->fa4_maxfilesize = fxdr_hyper(tl);
- fa->fa4_valid |= FA4V_MAXFILESIZE;
- len += 2 * NFSX_UNSIGNED;
- }
- if (FA4_ISSET(FA4_MAXNAME, bmval)) {
- NFSM_DISSECT(NFSX_UNSIGNED);
- fa->fa4_maxname = fxdr_unsigned(uint32_t, *tl++);
- fa->fa4_valid |= FA4V_MAXNAME;
- len += NFSX_UNSIGNED;
- }
- if (FA4_ISSET(FA4_MAXREAD, bmval)) {
- NFSM_DISSECT(2 * NFSX_UNSIGNED);
- fa->fa4_maxread = fxdr_hyper(tl);
- fa->fa4_valid |= FA4V_MAXREAD;
- len += 2 * NFSX_UNSIGNED;
- }
- if (FA4_ISSET(FA4_MAXWRITE, bmval)) {
- NFSM_DISSECT(2 * NFSX_UNSIGNED);
- fa->fa4_maxwrite = fxdr_hyper(tl);
- fa->fa4_valid |= FA4V_MAXWRITE;
- len += 2 * NFSX_UNSIGNED;
- }
-
- if (FA4_ISSET(FA4_MODE, bmval)) {
- NFSM_DISSECT(NFSX_UNSIGNED);
- fa->fa4_mode = fxdr_unsigned(mode_t, *tl++);
- fa->fa4_valid |= FA4V_MODE;
- len += NFSX_UNSIGNED;
- }
- if (FA4_ISSET(FA4_NUMLINKS, bmval)) {
- NFSM_DISSECT(NFSX_UNSIGNED);
- fa->fa4_nlink = fxdr_unsigned(nlink_t, *tl++);
- fa->fa4_valid |= FA4V_NLINK;
- len += NFSX_UNSIGNED;
- }
- if (FA4_ISSET(FA4_OWNER, bmval)) {
- uint32_t ownerlen;
- int error;
-
- NFSM_DISSECT(NFSX_UNSIGNED);
-
- ownerlen = fxdr_unsigned(uint32_t, *tl++);
- NFSM_DISSECT(nfsm_rndup(ownerlen));
- error = idmap_name_to_uid((char *)tl, ownerlen, &fa->fa4_uid);
- if (error)
- fa->fa4_uid = -2;
- fa->fa4_valid |= FA4V_UID;
- len += NFSX_UNSIGNED + nfsm_rndup(ownerlen);
- }
- if (FA4_ISSET(FA4_OWNER_GROUP, bmval)) {
- uint32_t ownergrouplen;
- int error;
-
- NFSM_DISSECT(NFSX_UNSIGNED);
- ownergrouplen = fxdr_unsigned(uint32_t, *tl++);
- NFSM_DISSECT(nfsm_rndup(ownergrouplen));
- error = idmap_name_to_gid((char *)tl, ownergrouplen, &fa->fa4_gid);
- if (error)
- fa->fa4_gid = -2;
- fa->fa4_valid |= FA4V_GID;
- len += NFSX_UNSIGNED + nfsm_rndup(ownergrouplen);
- }
- if (FA4_ISSET(FA4_RAWDEV, bmval)) {
- NFSM_DISSECT(2 * NFSX_UNSIGNED);
- fa->fa4_rdev_major = fxdr_unsigned(uint32_t, *tl++);
- fa->fa4_rdev_minor = fxdr_unsigned(uint32_t, *tl++);
- fa->fa4_valid |= FA4V_RDEV;
- len += 2 * NFSX_UNSIGNED;
- }
- if (FA4_ISSET(FA4_SPACE_AVAIL, bmval)) {
- NFSM_DISSECT(2 * NFSX_UNSIGNED);
- fa->fa4_savail = fxdr_hyper(tl);
- fa->fa4_valid |= FA4V_SAVAIL;
- len += 2 * NFSX_UNSIGNED;
- }
- if (FA4_ISSET(FA4_SPACE_FREE, bmval)) {
- NFSM_DISSECT(2 * NFSX_UNSIGNED);
- fa->fa4_sfree = fxdr_hyper(tl);
- fa->fa4_valid |= FA4V_SFREE;
- len += 2 * NFSX_UNSIGNED;
- }
- if (FA4_ISSET(FA4_SPACE_TOTAL, bmval)) {
- NFSM_DISSECT(2 * NFSX_UNSIGNED);
- fa->fa4_stotal = fxdr_hyper(tl);
- fa->fa4_valid |= FA4V_STOTAL;
- len += 2 * NFSX_UNSIGNED;
- }
- if (FA4_ISSET(FA4_SPACE_USED, bmval)) {
- NFSM_ADV(2 * NFSX_UNSIGNED);
- len += 2 * NFSX_UNSIGNED;
- }
- if (FA4_ISSET(FA4_TIME_ACCESS, bmval)) {
- NFSM_MTOTIME(fa->fa4_atime);
- fa->fa4_valid |= FA4V_ATIME;
- len += 3 * NFSX_UNSIGNED;
- }
- if (FA4_ISSET(FA4_TIME_CREATE, bmval)) {
- NFSM_MTOTIME(fa->fa4_btime);
- fa->fa4_valid |= FA4V_BTIME;
- len += 3 * NFSX_UNSIGNED;
- }
- if (FA4_ISSET(FA4_TIME_METADATA, bmval)) {
- NFSM_MTOTIME(fa->fa4_ctime);
- fa->fa4_valid |= FA4V_CTIME;
- len += 3 * NFSX_UNSIGNED;
- }
- if (FA4_ISSET(FA4_TIME_MODIFY, bmval)) {
- NFSM_MTOTIME(fa->fa4_mtime);
- fa->fa4_valid |= FA4V_MTIME;
- len += 3 * NFSX_UNSIGNED;
- }
-
- if (len != attrlen)
- return (EBADRPC);
-
- return (0);
-}
diff --git a/sys/nfs4client/nfs4_vfs.h b/sys/nfs4client/nfs4_vfs.h
deleted file mode 100644
index 61999ac..0000000
--- a/sys/nfs4client/nfs4_vfs.h
+++ /dev/null
@@ -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 */
diff --git a/sys/nfs4client/nfs4_vfs_subs.c b/sys/nfs4client/nfs4_vfs_subs.c
deleted file mode 100644
index 6d667af..0000000
--- a/sys/nfs4client/nfs4_vfs_subs.c
+++ /dev/null
@@ -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;
-}
diff --git a/sys/nfs4client/nfs4_vfsops.c b/sys/nfs4client/nfs4_vfsops.c
deleted file mode 100644
index 808b63d..0000000
--- a/sys/nfs4client/nfs4_vfsops.c
+++ /dev/null
@@ -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);
-}
diff --git a/sys/nfs4client/nfs4_vn.h b/sys/nfs4client/nfs4_vn.h
deleted file mode 100644
index 2f5f730..0000000
--- a/sys/nfs4client/nfs4_vn.h
+++ /dev/null
@@ -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 */
diff --git a/sys/nfs4client/nfs4_vn_subs.c b/sys/nfs4client/nfs4_vn_subs.c
deleted file mode 100644
index 12095d0..0000000
--- a/sys/nfs4client/nfs4_vn_subs.c
+++ /dev/null
@@ -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;
-}
diff --git a/sys/nfs4client/nfs4_vnops.c b/sys/nfs4client/nfs4_vnops.c
deleted file mode 100644
index af85494..0000000
--- a/sys/nfs4client/nfs4_vnops.c
+++ /dev/null
@@ -1,2931 +0,0 @@
-/* $Id: nfs_vnops.c,v 1.45 2003/11/05 14:59:02 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
- * 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_vnops.c 8.16 (Berkeley) 5/27/95
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD$");
-
-/*
- * vnode op calls for Sun NFS version 2 and 3
- */
-
-#include "opt_inet.h"
-
-#include <sys/param.h>
-#include <sys/kernel.h>
-#include <sys/systm.h>
-#include <sys/resourcevar.h>
-#include <sys/proc.h>
-#include <sys/mount.h>
-#include <sys/bio.h>
-#include <sys/buf.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/namei.h>
-#include <sys/socket.h>
-#include <sys/vnode.h>
-#include <sys/dirent.h>
-#include <sys/fcntl.h>
-#include <sys/lockf.h>
-#include <sys/stat.h>
-#include <sys/sysctl.h>
-#include <sys/lockmgr.h>
-#include <sys/signalvar.h>
-
-#include <vm/vm.h>
-#include <vm/vm_extern.h>
-
-#include <fs/fifofs/fifo.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 <nfsclient/nfs_lock.h>
-#include <nfs/xdr_subs.h>
-#include <nfsclient/nfsm_subs.h>
-
-#include <net/if.h>
-#include <netinet/in.h>
-#include <netinet/in_var.h>
-
-/* NFSv4 */
-#include <nfs4client/nfs4m_subs.h>
-#include <nfs4client/nfs4_vn.h>
-
-/* Defs */
-#define TRUE 1
-#define FALSE 0
-
-/*
- * Ifdef for FreeBSD-current merged buffer cache. It is unfortunate that these
- * calls are not in getblk() and brelse() so that they would not be necessary
- * here.
- */
-#ifndef B_VMIO
-#define vfs_busy_pages(bp, f)
-#endif
-
-static int nfs4_flush(struct vnode *, int, struct thread *,
- int);
-static int nfs4_setattrrpc(struct vnode *, struct vattr *, struct ucred *);
-static int nfs4_closerpc(struct vnode *, struct ucred *, int);
-
-static vop_lookup_t nfs4_lookup;
-static vop_create_t nfs4_create;
-static vop_mknod_t nfs4_mknod;
-static vop_open_t nfs4_open;
-static vop_close_t nfs4_close;
-static vop_access_t nfs4_access;
-static vop_getattr_t nfs4_getattr;
-static vop_setattr_t nfs4_setattr;
-static vop_read_t nfs4_read;
-static vop_fsync_t nfs4_fsync;
-static vop_remove_t nfs4_remove;
-static vop_link_t nfs4_link;
-static vop_rename_t nfs4_rename;
-static vop_mkdir_t nfs4_mkdir;
-static vop_rmdir_t nfs4_rmdir;
-static vop_symlink_t nfs4_symlink;
-static vop_readdir_t nfs4_readdir;
-static vop_strategy_t nfs4_strategy;
-static int nfs4_lookitup(struct vnode *, const char *, int,
- struct ucred *, struct thread *, struct nfsnode **);
-static int nfs4_sillyrename(struct vnode *, struct vnode *,
- struct componentname *);
-static vop_readlink_t nfs4_readlink;
-static vop_print_t nfs4_print;
-static vop_advlock_t nfs4_advlock;
-static vop_advlockasync_t nfs4_advlockasync;
-
-/*
- * Global vfs data structures for nfs
- */
-struct vop_vector nfs4_vnodeops = {
- .vop_default = &default_vnodeops,
- .vop_access = nfs4_access,
- .vop_advlock = nfs4_advlock,
- .vop_advlockasync = nfs4_advlockasync,
- .vop_close = nfs4_close,
- .vop_create = nfs4_create,
- .vop_fsync = nfs4_fsync,
- .vop_getattr = nfs4_getattr,
- .vop_getpages = nfs_getpages,
- .vop_putpages = nfs_putpages,
- .vop_inactive = nfs_inactive,
- .vop_link = nfs4_link,
- .vop_lookup = nfs4_lookup,
- .vop_mkdir = nfs4_mkdir,
- .vop_mknod = nfs4_mknod,
- .vop_open = nfs4_open,
- .vop_print = nfs4_print,
- .vop_read = nfs4_read,
- .vop_readdir = nfs4_readdir,
- .vop_readlink = nfs4_readlink,
- .vop_reclaim = nfs_reclaim,
- .vop_remove = nfs4_remove,
- .vop_rename = nfs4_rename,
- .vop_rmdir = nfs4_rmdir,
- .vop_setattr = nfs4_setattr,
- .vop_strategy = nfs4_strategy,
- .vop_symlink = nfs4_symlink,
- .vop_write = nfs_write,
-};
-
-static int nfs4_removerpc(struct vnode *dvp, const char *name, int namelen,
- struct ucred *cred, struct thread *td);
-static int nfs4_renamerpc(struct vnode *fdvp, const char *fnameptr,
- int fnamelen, struct vnode *tdvp,
- const char *tnameptr, int tnamelen,
- struct ucred *cred, struct thread *td);
-static int nfs4_renameit(struct vnode *sdvp, struct componentname *scnp,
- struct sillyrename *sp);
-static int nfs4_openrpc(struct vnode *, struct vnode **,
- struct componentname *, int, struct vattr *);
-static int nfs4_open_confirm(struct vnode *vp, struct nfs4_compound *cpp,
- struct nfs4_oparg_open *openap,
- struct nfs4_oparg_getfh *gfh,
- struct ucred *cred, struct thread *td);
-static int nfs4_createrpc(struct vnode *, struct vnode **,
- struct componentname *, nfstype,
- struct vattr *, char *);
-
-/*
- * Global variables
- */
-struct nfs4_lowner nfs4_masterlowner;
-
-#define DIRHDSIZ (sizeof (struct dirent) - (MAXNAMLEN + 1))
-
-SYSCTL_DECL(_vfs_nfs4);
-
-static int nfs4_access_cache_timeout = NFS_MAXATTRTIMO;
-SYSCTL_INT(_vfs_nfs4, OID_AUTO, access_cache_timeout, CTLFLAG_RW,
- &nfs4_access_cache_timeout, 0, "NFS ACCESS cache timeout");
-
-#if 0
-static int nfsv3_commit_on_close = 0;
-SYSCTL_INT(_vfs_nfs4, OID_AUTO, nfsv3_commit_on_close, CTLFLAG_RW,
- &nfsv3_commit_on_close, 0, "write+commit on close, else only write");
-
-SYSCTL_INT(_vfs_nfs4, OID_AUTO, access_cache_hits, CTLFLAG_RD,
- &nfsstats.accesscache_hits, 0, "NFS ACCESS cache hit count");
-
-SYSCTL_INT(_vfs_nfs4, OID_AUTO, access_cache_misses, CTLFLAG_RD,
- &nfsstats.accesscache_misses, 0, "NFS ACCESS cache miss count");
-#endif
-
-#define NFSV3ACCESS_ALL (NFSV3ACCESS_READ | NFSV3ACCESS_MODIFY \
- | NFSV3ACCESS_EXTEND | NFSV3ACCESS_EXECUTE \
- | NFSV3ACCESS_DELETE | NFSV3ACCESS_LOOKUP)
-static int
-nfs4_v3_access_otw(struct vnode *vp, int wmode, struct thread *td,
- struct ucred *cred, uint32_t *retmode)
-{
- const int v3 = 1;
- u_int32_t *tl;
- int error = 0, attrflag, i, lrupos;
-
- return (0);
-
- struct mbuf *mreq, *mrep = NULL, *md, *mb;
- caddr_t bpos, dpos;
- u_int32_t rmode;
- struct nfsnode *np = VTONFS(vp);
-
- nfsstats.rpccnt[NFSPROC_ACCESS]++;
- mreq = nfsm_reqhead(vp, NFSPROC_ACCESS, NFSX_FH(v3) + NFSX_UNSIGNED);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
- nfsm_fhtom(vp, v3);
- tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED);
- *tl = txdr_unsigned(wmode);
- nfsm_request(vp, NFSPROC_ACCESS, td, cred);
- nfsm_postop_attr(vp, attrflag);
- if (!error) {
- lrupos = 0;
- tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED);
- rmode = fxdr_unsigned(u_int32_t, *tl);
- for (i = 0; i < NFS_ACCESSCACHESIZE; i++) {
- if (np->n_accesscache[i].uid == cred->cr_uid) {
- np->n_accesscache[i].mode = rmode;
- np->n_accesscache[i].stamp = time_second;
- break;
- }
- if (i > 0 && np->n_accesscache[i].stamp <
- np->n_accesscache[lrupos].stamp)
- lrupos = i;
- }
- if (i == NFS_ACCESSCACHESIZE) {
- np->n_accesscache[lrupos].uid = cred->cr_uid;
- np->n_accesscache[lrupos].mode = rmode;
- np->n_accesscache[lrupos].stamp = time_second;
- }
- if (retmode != NULL)
- *retmode = rmode;
- }
- m_freem(mrep);
-nfsmout:
- return error;
-}
-
-/*
- * nfs access vnode op.
- * For nfs version 2, just return ok. File accesses may fail later.
- * For nfs version 3, use the access rpc to check accessibility. If file modes
- * are changed on the server, accesses might still fail later.
- */
-static int
-nfs4_access(struct vop_access_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- int error = 0, i, gotahit;
- u_int32_t mode, rmode, wmode;
- int v3 = NFS_ISV3(vp); /* v3 \in v4 */
- struct nfsnode *np = VTONFS(vp);
- caddr_t bpos, dpos;
- struct mbuf *mreq, *mrep = NULL, *md, *mb;
- struct nfs4_compound cp;
- struct nfs4_oparg_access acc;
- struct thread *td = ap->a_td;
- struct ucred *cred = ap->a_cred;
-
- /*
- * Disallow write attempts on filesystems mounted read-only;
- * unless the file is a socket, fifo, or a block or character
- * device resident on the filesystem.
- */
- if ((ap->a_accmode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) {
- switch (vp->v_type) {
- case VREG:
- case VDIR:
- case VLNK:
- return (EROFS);
- default:
- break;
- }
- }
- /*
- * For nfs v3, check to see if we have done this recently, and if
- * so return our cached result instead of making an ACCESS call.
- * If not, do an access rpc, otherwise you are stuck emulating
- * ufs_access() locally using the vattr. This may not be correct,
- * since the server may apply other access criteria such as
- * client uid-->server uid mapping that we do not know about.
- */
- /* XXX Disable this for now; needs fixing of _access_otw() */
- if (0 && v3) {
- if (ap->a_accmode & VREAD)
- mode = NFSV3ACCESS_READ;
- else
- mode = 0;
- if (vp->v_type != VDIR) {
- if (ap->a_accmode & VWRITE)
- mode |= (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND);
- if (ap->a_accmode & VEXEC)
- mode |= NFSV3ACCESS_EXECUTE;
- } else {
- if (ap->a_accmode & VWRITE)
- mode |= (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND |
- NFSV3ACCESS_DELETE);
- if (ap->a_accmode & VEXEC)
- mode |= NFSV3ACCESS_LOOKUP;
- }
- /* XXX safety belt, only make blanket request if caching */
- if (nfs4_access_cache_timeout > 0) {
- wmode = NFSV3ACCESS_READ | NFSV3ACCESS_MODIFY |
- NFSV3ACCESS_EXTEND | NFSV3ACCESS_EXECUTE |
- NFSV3ACCESS_DELETE | NFSV3ACCESS_LOOKUP;
- } else {
- wmode = mode;
- }
-
- /*
- * Does our cached result allow us to give a definite yes to
- * this request?
- */
- gotahit = 0;
- for (i = 0; i < NFS_ACCESSCACHESIZE; i++) {
- if (ap->a_cred->cr_uid == np->n_accesscache[i].uid) {
- if (time_second < (np->n_accesscache[i].stamp +
- nfs4_access_cache_timeout) &&
- (np->n_accesscache[i].mode & mode) == mode) {
- nfsstats.accesscache_hits++;
- gotahit = 1;
- }
- break;
- }
- }
- if (gotahit == 0) {
- /*
- * Either a no, or a don't know. Go to the wire.
- */
- nfsstats.accesscache_misses++;
- error = nfs4_v3_access_otw(vp, wmode, ap->a_td,
- ap->a_cred, &rmode);
- if (error == 0) {
- if ((rmode & mode) != mode)
- error = EACCES;
- }
- }
- return (error);
- }
-
- /* XXX use generic access code here? */
- mode = ap->a_accmode & VREAD ? NFSV4ACCESS_READ : 0;
- if (vp->v_type == VDIR) {
- if (ap->a_accmode & VWRITE)
- mode |= NFSV4ACCESS_MODIFY | NFSV4ACCESS_EXTEND | NFSV4ACCESS_DELETE;
- if (ap->a_accmode & VEXEC)
- mode |= NFSV4ACCESS_LOOKUP;
- } else {
- if (ap->a_accmode & VWRITE)
- mode |= NFSV4ACCESS_MODIFY | NFSV4ACCESS_EXTEND;
- if (ap->a_accmode & VEXEC)
- mode |= NFSV4ACCESS_EXECUTE;
- }
-
- nfs_v4initcompound(&cp);
- acc.mode = mode;
-
- mreq = nfsm_reqhead(vp, NFSV4PROC_COMPOUND, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
-
- nfsm_v4build_compound(&cp, "nfs4_access()");
- nfsm_v4build_putfh(&cp, vp);
- nfsm_v4build_access(&cp, &acc);
- nfsm_v4build_finalize(&cp);
-
- nfsm_request(vp, NFSV4PROC_COMPOUND, td, cred);
- if (error != 0)
- goto nfsmout;
-
- nfsm_v4dissect_compound(&cp);
- nfsm_v4dissect_putfh(&cp);
- nfsm_v4dissect_access(&cp, &acc);
-
- if ((acc.rmode & mode) != mode)
- error = EACCES;
-
- nfsmout:
- error = nfs_v4postop(&cp, error);
-
- if (mrep != NULL)
- m_freem(mrep);
-
- return (error);
-}
-
-static int
-nfs4_openrpc(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp,
- int flags, struct vattr *vap)
-{
- struct vnode *vp = *vpp;
- struct nfs4_oparg_getattr getattr;
- struct nfs4_oparg_getfh getfh;
- struct nfs4_oparg_open opena;
- struct nfs4_compound cp;
- caddr_t bpos, dpos;
- int error = 0;
- struct mbuf *mreq, *mrep = NULL, *md, *mb;
- struct ucred *cred = cnp->cn_cred;
- struct thread *td = cnp->cn_thread;
- struct nfs4_fctx xfc, *fcp;
- struct nfsnode *np;
-
- if (vp == NULL) {
- /* Create a new file */
- np = NULL;
- fcp = &xfc;
- bzero(fcp, sizeof(*fcp));
- } else {
- np = VTONFS(vp);
- fcp = flags & FWRITE ? &np->n_wfc : &np->n_rfc;
- }
-
- /*
- * Since we are currently only one lockowner; we only open the
- * file once each for reading and writing.
- */
- if (fcp->refcnt++ != 0) {
- *vpp = vp;
- /*printf("not opening %s\n", np->n_name != NULL ? np->n_name : "");*/
- return (0);
- }
-
- fcp->lop = &nfs4_masterlowner;
- fcp->np = np;
-
- nfs_v4initcompound(&cp);
- cp.nmp = VFSTONFS(dvp->v_mount);
-
- opena.ctype = NCLNULL;
- opena.flags = flags;
- opena.vap = vap;
- opena.fcp = fcp; /* For lockowner */
- opena.cnp = cnp;
-
- getattr.bm = &nfsv4_getattrbm;
-
- mreq = nfsm_reqhead(vp, NFSV4PROC_COMPOUND, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
-
- nfsm_v4build_compound(&cp, "nfs4_openrpc()");
- nfsm_v4build_putfh(&cp, dvp);
- nfsm_v4build_open(&cp, &opena);
- nfsm_v4build_getattr(&cp, &getattr);
- nfsm_v4build_getfh(&cp, &getfh);
- nfsm_v4build_finalize(&cp);
-
- nfsm_request(vp != NULL ? vp : dvp, NFSV4PROC_COMPOUND, td, cred);
- if (error != 0)
- goto nfsmout;
-
- nfsm_v4dissect_compound(&cp);
- nfsm_v4dissect_putfh(&cp);
- nfsm_v4dissect_open(&cp, &opena);
- nfsm_v4dissect_getattr(&cp, &getattr);
- nfsm_v4dissect_getfh(&cp, &getfh);
-
- error = nfs_v4postop(&cp, error);
-
- if (opena.rflags & NFSV4OPENRES_CONFIRM) {
- error = nfs4_open_confirm(vp ? vp : dvp, &cp, &opena, &getfh, cred, td);
- if (error != 0)
- goto nfsmout;
- }
-
- if (vp == NULL) {
- /* New file */
- error = nfs_nget(dvp->v_mount, &getfh.fh_val,
- getfh.fh_len, &np, LK_EXCLUSIVE);
- if (error != 0)
- goto nfsmout;
-
- vp = NFSTOV(np);
- np->n_dvp = dvp;
- np->n_namelen = cnp->cn_namelen; /* XXX memory leaks on these; track! */
- if (np->n_name != NULL)
- free(np->n_name, M_NFSREQ);
- np->n_name = malloc(np->n_namelen + 1, M_NFSREQ, M_WAITOK);
- bcopy(cnp->cn_nameptr, np->n_name, np->n_namelen);
- np->n_name[np->n_namelen] = '\0';
- if (flags & FWRITE)
- np->n_wfc = *fcp;
- else
- np->n_rfc = *fcp;
-
- /*printf("opened new file %s\n", np->n_name);*/
-
- nfs4_vnop_loadattrcache(vp, &getattr.fa, NULL);
- *vpp = vp;
- } else {
- /*printf("openend \"old\" %s\n", np->n_name != NULL ? np->n_name : "");*/
-
- if (flags & O_TRUNC && np->n_size != 0) {
- struct vattr va;
-
- VATTR_NULL(&va);
- va.va_size = 0;
- error = nfs4_setattrrpc(vp, &va, cnp->cn_cred);
- }
- np->n_attrstamp = 0;
- }
-
- nfsmout:
- if (mrep != NULL)
- m_freem(mrep);
-
- return (error);
-}
-
-static int
-nfs4_open_confirm(struct vnode *vp, struct nfs4_compound *cpp,
- struct nfs4_oparg_open *openap, struct nfs4_oparg_getfh *gfh,
- struct ucred *cred, struct thread *td)
-{
- caddr_t bpos, dpos;
- int error = 0;
- struct mbuf *mreq, *mrep = NULL, *md, *mb;
-
- nfs_v4initcompound(cpp);
- cpp->nmp = VFSTONFS(vp->v_mount);
-
- mreq = nfsm_reqhead(vp, NFSV4PROC_COMPOUND, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
-
- nfsm_v4build_compound(cpp, "nfs4_open_confirm()");
- nfsm_v4build_putfh_nv(cpp, gfh);
- nfsm_v4build_open_confirm(cpp, openap);
- nfsm_v4build_finalize(cpp);
-
- nfsm_request(vp, NFSV4PROC_COMPOUND, td, cred);
- if (error != 0)
- goto nfsmout;
-
- nfsm_v4dissect_compound(cpp);
- nfsm_v4dissect_putfh(cpp);
- nfsm_v4dissect_open_confirm(cpp, openap);
-
- nfsmout:
- error = nfs_v4postop(cpp, error);
-
- if (mrep != NULL)
- m_freem(mrep);
-
- return (error);
-}
-
-
-/*
- * nfs open vnode op
- * Check to see if the type is ok
- * and that deletion is not in progress.
- * For paged in text files, you will need to flush the page cache
- * if consistency is lost.
- */
-/* ARGSUSED */
-static int
-nfs4_open(struct vop_open_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct nfsnode *np = VTONFS(vp);
- enum vtype vtype = vp->v_type;
- int mode = ap->a_mode;
- struct componentname cn;
-
- if (vtype != VREG) {
- if (vtype != VDIR && vtype != VLNK) {
-#ifdef DIAGNOSTIC
- printf("open eacces vtyp=%d\n", vp->v_type);
-#endif
- return (EACCES);
- } else
- return (0);
- }
-
- if (np->n_flag & NCREATED) {
- np->n_flag &= ~NCREATED;
- return (0);
- }
-
- cn.cn_nameptr = np->n_name;
- cn.cn_namelen = np->n_namelen;
- cn.cn_cred = ap->a_cred;
- cn.cn_thread = ap->a_td;
-
- return (nfs4_openrpc(np->n_dvp, &vp, &cn, mode, NULL));
-}
-
-static int
-nfs4_closerpc(struct vnode *vp, struct ucred *cred, int flags)
-{
- caddr_t bpos, dpos;
- int error = 0;
- struct mbuf *mreq, *mrep = NULL, *md, *mb;
- struct thread *td;
- struct nfs4_fctx *fcp;
- struct nfs4_compound cp;
- struct nfsnode *np = VTONFS(vp);
-
- td = curthread;
- fcp = flags & FWRITE ? &np->n_wfc : &np->n_rfc;
-
- nfs_v4initcompound(&cp);
-
- if (--fcp->refcnt != 0)
- return (0);
-
- /*printf("closing %s\n", np->n_name != NULL ? np->n_name : "");*/
-
- cp.fcp = fcp;
-
- mreq = nfsm_reqhead(vp, NFSV4PROC_COMPOUND, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
-
- nfsm_v4build_compound(&cp, "nfs4_closerpc()");
- nfsm_v4build_putfh(&cp, vp);
- nfsm_v4build_close(&cp, fcp);
- nfsm_v4build_finalize(&cp);
-
- nfsm_request(vp, NFSV4PROC_COMPOUND, td, cred);
- if (error != 0)
- goto nfsmout;
-
- nfsm_v4dissect_compound(&cp);
- nfsm_v4dissect_putfh(&cp);
- nfsm_v4dissect_close(&cp, fcp);
-
- nfsmout:
- error = nfs_v4postop(&cp, error);
-
- if (mrep != NULL)
- m_freem(mrep);
-
- return (error);
-}
-
-/*
- * nfs close vnode op
- * play it safe for now (see comments in v2/v3 nfs_close regarding dirty buffers)
- */
-/* ARGSUSED */
-static int
-nfs4_close(struct vop_close_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct nfsnode *np = VTONFS(vp);
- int error = 0;
-
- if (vp->v_type != VREG)
- return (0);
-
- if (np->n_flag & NMODIFIED) {
- error = nfs_vinvalbuf(vp, V_SAVE, ap->a_td, 1);
- np->n_attrstamp = 0;
- }
-
- error = nfs4_closerpc(vp, ap->a_cred, ap->a_fflag);
-
- if (!error && np->n_flag & NWRITEERR) {
- np->n_flag &= ~NWRITEERR;
- error = np->n_error;
- }
- return (error);
-}
-
-/*
- * nfs getattr call from vfs.
- */
-static int
-nfs4_getattr(struct vop_getattr_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct nfsnode *np = VTONFS(vp);
- caddr_t bpos, dpos;
- int error = 0;
- struct mbuf *mreq, *mrep = NULL, *md, *mb;
- struct nfs4_oparg_getattr ga;
- struct nfs4_compound cp;
-
- /*
- * Update local times for special files.
- */
- if (np->n_flag & (NACC | NUPD))
- np->n_flag |= NCHG;
- /*
- * First look in the cache.
- */
- if (nfs_getattrcache(vp, ap->a_vap) == 0)
- return (0);
-
- nfsstats.rpccnt[NFSPROC_GETATTR]++;
-
- mreq = nfsm_reqhead(vp, NFSV4PROC_COMPOUND, NFSX_FH(1));
- mb = mreq;
- bpos = mtod(mb, caddr_t);
-
- ga.bm = &nfsv4_getattrbm;
- nfs_v4initcompound(&cp);
-
- nfsm_v4build_compound(&cp, "nfs4_getattr()");
- nfsm_v4build_putfh(&cp, vp);
- nfsm_v4build_getattr(&cp, &ga);
- nfsm_v4build_finalize(&cp);
-
- nfsm_request(vp, NFSV4PROC_COMPOUND, curthread, ap->a_cred);
- if (error != 0)
- goto nfsmout;
-
- nfsm_v4dissect_compound(&cp);
- nfsm_v4dissect_putfh(&cp);
- nfsm_v4dissect_getattr(&cp, &ga);
-
- nfs4_vnop_loadattrcache(vp, &ga.fa, ap->a_vap);
-
-nfsmout:
- error = nfs_v4postop(&cp, error);
-
- if (mrep != NULL)
- m_freem(mrep);
- return (error);
-}
-
-/*
- * nfs setattr call.
- */
-static int
-nfs4_setattr(struct vop_setattr_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct nfsnode *np = VTONFS(vp);
- struct vattr *vap = ap->a_vap;
- struct thread *td = curthread;
- int error = 0;
- u_quad_t tsize;
-
-#ifndef nolint
- tsize = (u_quad_t)0;
-#endif
-
- /*
- * Setting of flags is not supported.
- */
- if (vap->va_flags != VNOVAL)
- return (EOPNOTSUPP);
-
- /*
- * Disallow write attempts if the filesystem is mounted read-only.
- */
- if ((vap->va_flags != VNOVAL || vap->va_uid != (uid_t)VNOVAL ||
- vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL ||
- vap->va_mtime.tv_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL) &&
- (vp->v_mount->mnt_flag & MNT_RDONLY))
- return (EROFS);
- if (vap->va_size != VNOVAL) {
- switch (vp->v_type) {
- case VDIR:
- return (EISDIR);
- case VCHR:
- case VBLK:
- case VSOCK:
- case VFIFO:
- if (vap->va_mtime.tv_sec == VNOVAL &&
- vap->va_atime.tv_sec == VNOVAL &&
- vap->va_mode == (mode_t)VNOVAL &&
- vap->va_uid == (uid_t)VNOVAL &&
- vap->va_gid == (gid_t)VNOVAL)
- return (0);
- vap->va_size = VNOVAL;
- break;
- default:
- /*
- * Disallow write attempts if the filesystem is
- * mounted read-only.
- */
- if (vp->v_mount->mnt_flag & MNT_RDONLY)
- return (EROFS);
-
- /*
- * We run vnode_pager_setsize() early (why?),
- * we must set np->n_size now to avoid vinvalbuf
- * V_SAVE races that might setsize a lower
- * value.
- */
-
- tsize = np->n_size;
- error = nfs_meta_setsize(vp, ap->a_cred, td,
- vap->va_size);
-
- if (np->n_flag & NMODIFIED) {
- if (vap->va_size == 0)
- error = nfs_vinvalbuf(vp, 0, td, 1);
- else
- error = nfs_vinvalbuf(vp, V_SAVE, td, 1);
- if (error) {
- vnode_pager_setsize(vp, np->n_size);
- return (error);
- }
- }
- /*
- * np->n_size has already been set to vap->va_size
- * in nfs_meta_setsize(). We must set it again since
- * nfs_loadattrcache() could be called through
- * nfs_meta_setsize() and could modify np->n_size.
- */
- np->n_vattr.va_size = np->n_size = vap->va_size;
- };
- } else if ((vap->va_mtime.tv_sec != VNOVAL ||
- vap->va_atime.tv_sec != VNOVAL) && (np->n_flag & NMODIFIED) &&
- vp->v_type == VREG &&
- (error = nfs_vinvalbuf(vp, V_SAVE, td, 1)) == EINTR)
- return (error);
-
- if (vap->va_size != VNOVAL && np->n_wfc.refcnt == 0) {
- /* Have to open the file before we can truncate it */
- struct componentname cn;
-
- cn.cn_nameptr = np->n_name;
- cn.cn_namelen = np->n_namelen;
- cn.cn_cred = ap->a_cred;
- cn.cn_thread = td;
- error = nfs4_openrpc(np->n_dvp, &vp, &cn, FWRITE, NULL);
- if (error)
- return error;
- np->n_flag |= NTRUNCATE;
- }
-
- error = nfs4_setattrrpc(vp, vap, ap->a_cred);
- if (error && vap->va_size != VNOVAL) {
- np->n_size = np->n_vattr.va_size = tsize;
- vnode_pager_setsize(vp, np->n_size);
- }
- return (error);
-}
-
-/*
- * Do an nfs setattr rpc.
- */
-static int
-nfs4_setattrrpc(struct vnode *vp, struct vattr *vap, struct ucred *cred)
-{
- caddr_t bpos, dpos;
- int error = 0;
- struct mbuf *mreq, *mrep = NULL, *md, *mb;
- struct thread *td;
- struct nfs4_compound cp;
- struct nfs4_oparg_getattr ga;
- struct nfsnode *np = VTONFS(vp);
- struct nfs4_fctx *fcp;
-
- td = curthread;
- nfsstats.rpccnt[NFSPROC_SETATTR]++;
- mreq = nfsm_reqhead(vp, NFSV4PROC_COMPOUND, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
-
- ga.bm = &nfsv4_getattrbm;
- fcp = (vap->va_size != VNOVAL) ? &np->n_wfc : NULL;
- nfs_v4initcompound(&cp);
-
- nfsm_v4build_compound(&cp, "nfs4_setattrrpc");
- nfsm_v4build_putfh(&cp, vp);
- nfsm_v4build_setattr(&cp, vap, fcp);
- nfsm_v4build_getattr(&cp, &ga);
- nfsm_v4build_finalize(&cp);
-
- nfsm_request(vp, NFSV4PROC_COMPOUND, td, cred);
- if (error != 0)
- goto nfsmout;
-
- nfsm_v4dissect_compound(&cp);
- nfsm_v4dissect_putfh(&cp);
- nfsm_v4dissect_setattr(&cp);
- nfsm_v4dissect_getattr(&cp, &ga);
-
- nfs4_vnop_loadattrcache(vp, &ga.fa, NULL);
-
- /* TODO: do the settatr and close in a single compound rpc */
- if (np->n_flag & NTRUNCATE) {
- error = nfs4_closerpc(vp, cred, FWRITE);
- np->n_flag &= ~NTRUNCATE;
- }
-
-nfsmout:
- error = nfs_v4postop(&cp, error);
-
- if (mrep != NULL)
- m_freem(mrep);
-
- return (error);
-}
-
-/*
- * nfs lookup call, one step at a time...
- * First look in cache
- * If not found, unlock the directory nfsnode and do the rpc
- */
-static int
-nfs4_lookup(struct vop_lookup_args *ap)
-{
- struct componentname *cnp = ap->a_cnp;
- struct vnode *dvp = ap->a_dvp;
- struct vnode **vpp = ap->a_vpp;
- int isdot, flags = cnp->cn_flags;
- struct vnode *newvp;
- struct nfsmount *nmp;
- caddr_t bpos, dpos;
- struct mbuf *mreq, *mrep = NULL, *md, *mb;
- long len;
- nfsfh_t *fhp;
- struct nfsnode *np;
- int error = 0, fhsize;
- struct thread *td = cnp->cn_thread;
- struct nfs4_compound cp;
- struct nfs4_oparg_getattr ga, dga;
- struct nfs4_oparg_lookup l;
- struct nfs4_oparg_getfh gfh;
-
- *vpp = NULLVP;
- if ((flags & ISLASTCN) && (dvp->v_mount->mnt_flag & MNT_RDONLY) &&
- (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
- return (EROFS);
- if (dvp->v_type != VDIR)
- return (ENOTDIR);
- nmp = VFSTONFS(dvp->v_mount);
- np = VTONFS(dvp);
-
- isdot = cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.';
-
- if ((error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred, td)) != 0) {
- *vpp = NULLVP;
- return (error);
- }
- if ((error = cache_lookup(dvp, vpp, cnp)) && error != ENOENT) {
- struct vattr vattr;
-
- newvp = *vpp;
- if (!VOP_GETATTR(newvp, &vattr, cnp->cn_cred)
- && vattr.va_ctime.tv_sec == VTONFS(newvp)->n_ctime) {
- nfsstats.lookupcache_hits++;
- if (cnp->cn_nameiop != LOOKUP &&
- (flags & ISLASTCN))
- cnp->cn_flags |= SAVENAME;
- return (0);
- }
- cache_purge(newvp);
- if (newvp != dvp)
- vput(newvp);
- else
- vrele(newvp);
- }
-
- error = 0;
- newvp = NULLVP;
- nfsstats.lookupcache_misses++;
- nfsstats.rpccnt[NFSPROC_LOOKUP]++;
-
- len = cnp->cn_namelen;
- mreq = nfsm_reqhead(NULL, NFSV4PROC_COMPOUND, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
-
- ga.bm = &nfsv4_getattrbm;
- dga.bm = &nfsv4_getattrbm;
- nfs_v4initcompound(&cp);
-
- nfsm_v4build_compound(&cp, "nfs4_lookup()");
- nfsm_v4build_putfh(&cp, dvp);
- nfsm_v4build_getattr(&cp, &dga);
- if (flags & ISDOTDOT)
- nfsm_v4build_lookupp(&cp);
- else if (!isdot) {
- l.name = cnp->cn_nameptr;
- l.namelen = len;
- nfsm_v4build_lookup(&cp, &l);
- }
- nfsm_v4build_getattr(&cp, &ga);
- nfsm_v4build_getfh(&cp, &gfh);
- nfsm_v4build_finalize(&cp);
-
- nfsm_request(dvp, NFSV4PROC_COMPOUND, cnp->cn_thread, cnp->cn_cred);
- if (error != 0)
- goto nfsmout;
-
- nfsm_v4dissect_compound(&cp);
- nfsm_v4dissect_putfh(&cp);
- nfsm_v4dissect_getattr(&cp, &dga);
- if (flags & ISDOTDOT)
- nfsm_v4dissect_lookupp(&cp);
- else if (!isdot)
- nfsm_v4dissect_lookup(&cp);
- nfsm_v4dissect_getattr(&cp, &ga);
- nfsm_v4dissect_getfh(&cp, &gfh);
-
- nfs4_vnop_loadattrcache(dvp, &dga.fa, NULL);
- fhp = &gfh.fh_val;
- fhsize = gfh.fh_len;
-
- /*
- * Handle RENAME case...
- */
- if (cnp->cn_nameiop == RENAME && (flags & ISLASTCN)) {
- if (NFS_CMPFH(np, fhp, fhsize))
- return (EISDIR);
-
- error = nfs_nget(dvp->v_mount, fhp, fhsize, &np, LK_EXCLUSIVE);
- if (error)
- return (error);
-
- newvp = NFSTOV(np);
-
- nfs4_vnop_loadattrcache(newvp, &ga.fa, NULL);
-
- *vpp = newvp;
- cnp->cn_flags |= SAVENAME;
- return (0);
- }
-
- if (flags & ISDOTDOT) {
- VOP_UNLOCK(dvp, 0);
-
- error = nfs_nget(dvp->v_mount, fhp, fhsize, &np, LK_EXCLUSIVE);
- vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY);
- if (error)
- return (error);
- newvp = NFSTOV(np);
-
- nfs4_vnop_loadattrcache(newvp, &ga.fa, NULL);
- } else if (NFS_CMPFH(np, fhp, fhsize)) {
- VREF(dvp);
- newvp = dvp;
- } else {
- error = nfs_nget(dvp->v_mount, fhp, fhsize, &np, LK_EXCLUSIVE);
- if (error)
- return (error);
- newvp = NFSTOV(np);
-
- /* Fill in np used by open. */
- np->n_dvp = dvp;
- np->n_namelen = cnp->cn_namelen;
- if (np->n_name != NULL)
- free(np->n_name, M_NFSREQ);
- np->n_name = malloc(np->n_namelen + 1, M_NFSREQ, M_WAITOK);
- bcopy(cnp->cn_nameptr, np->n_name, np->n_namelen);
- np->n_name[np->n_namelen] = '\0';
-
- nfs4_vnop_loadattrcache(newvp, &ga.fa, NULL);
- }
-
- if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))
- cnp->cn_flags |= SAVENAME;
- if ((cnp->cn_flags & MAKEENTRY) &&
- (cnp->cn_nameiop != DELETE || !(flags & ISLASTCN))) {
- np->n_ctime = np->n_vattr.va_ctime.tv_sec;
- cache_enter(dvp, newvp, cnp);
- }
- *vpp = newvp;
- m_freem(mrep);
-nfsmout:
- error = nfs_v4postop(&cp, error);
-
- if (error) {
- if (newvp != NULLVP) {
- vrele(newvp);
- *vpp = NULLVP;
- }
- if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME) &&
- (flags & ISLASTCN) && error == ENOENT) {
- if (dvp->v_mount->mnt_flag & MNT_RDONLY)
- error = EROFS;
- else
- error = EJUSTRETURN;
- }
- if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))
- cnp->cn_flags |= SAVENAME;
- }
-
- return (error);
-}
-
-/*
- * nfs read call.
- * Just call nfs_bioread() to do the work.
- */
-static int
-nfs4_read(struct vop_read_args *ap)
-{
- struct vnode *vp = ap->a_vp;
-
- switch (vp->v_type) {
- case VREG:
- return (nfs_bioread(vp, ap->a_uio, ap->a_ioflag, ap->a_cred));
- case VDIR:
- return (EISDIR);
- default:
- return (EOPNOTSUPP);
- }
-}
-
-/*
- * nfs readlink call
- */
-static int
-nfs4_readlink(struct vop_readlink_args *ap)
-{
- struct vnode *vp = ap->a_vp;
-
- if (vp->v_type != VLNK)
- return (EINVAL);
- return (nfs_bioread(vp, ap->a_uio, 0, ap->a_cred));
-}
-
-/*
- * Do a readlink rpc.
- * Called by nfs_doio() from below the buffer cache.
- */
-int
-nfs4_readlinkrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred)
-{
- caddr_t bpos, dpos;
- int error = 0;
- struct mbuf *mreq, *mrep = NULL, *md, *mb;
- struct nfs4_compound cp;
-
- nfsstats.rpccnt[NFSPROC_READLINK]++;
-
- mreq = nfsm_reqhead(vp, NFSV4PROC_COMPOUND, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
-
- nfs_v4initcompound(&cp);
-
- nfsm_v4build_compound(&cp, "nfs4_readlinkrpc()");
- nfsm_v4build_putfh(&cp, vp);
- nfsm_v4build_readlink(&cp);
- nfsm_v4build_finalize(&cp);
-
- nfsm_request(vp, NFSV4PROC_COMPOUND, uiop->uio_td, cred);
- if (error != 0)
- goto nfsmout;
-
- nfsm_v4dissect_compound(&cp);
- nfsm_v4dissect_putfh(&cp);
- nfsm_v4dissect_readlink(&cp, uiop);
-
-nfsmout:
- error = nfs_v4postop(&cp, error);
-
- if (mrep != NULL)
- m_freem(mrep);
- return (error);
-}
-
-/*
- * nfs read rpc call
- * Ditto above
- */
-int
-nfs4_readrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred)
-{
- caddr_t bpos, dpos;
- struct mbuf *mreq, *mrep = NULL, *md, *mb;
- struct nfsmount *nmp;
- int error = 0, len, tsiz;
- struct nfs4_compound cp;
- struct nfs4_oparg_read read;
- struct nfsnode *np = VTONFS(vp);
-
- nmp = VFSTONFS(vp->v_mount);
- tsiz = uiop->uio_resid;
- if (uiop->uio_offset + tsiz > nmp->nm_maxfilesize)
- return (EFBIG);
-
- if (tsiz == 0)
- return (0);
-
- read.uiop = uiop;
- read.fcp = np->n_rfc.refcnt > 0 ? &np->n_rfc : &np->n_wfc;
-
- while (tsiz > 0) {
- nfsstats.rpccnt[NFSPROC_READ]++;
- len = (tsiz > nmp->nm_rsize) ? nmp->nm_rsize : tsiz;
-
- read.off = uiop->uio_offset;
- read.maxcnt = len;
- nfs_v4initcompound(&cp);
-
- mreq = nfsm_reqhead(vp, NFSV4PROC_COMPOUND, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
-
- nfsm_v4build_compound(&cp, "nfs4_readrpc()");
- nfsm_v4build_putfh(&cp, vp);
- nfsm_v4build_read(&cp, &read);
- nfsm_v4build_finalize(&cp);
-
- nfsm_request(vp, NFSV4PROC_COMPOUND, uiop->uio_td, cred);
- if (error != 0) {
- error = nfs_v4postop(&cp, error);
- goto nfsmout;
- }
-
- nfsm_v4dissect_compound(&cp);
- nfsm_v4dissect_putfh(&cp);
- nfsm_v4dissect_read(&cp, &read);
-
- if (read.eof || read.retlen == 0)
- tsiz = 0;
- else
- tsiz -= read.retlen;
-
- error = nfs_v4postop(&cp, error);
-
- m_freem(mrep);
- mrep = NULL;
- }
-nfsmout:
- if (mrep != NULL)
- m_freem(mrep);
-
- return (error);
-}
-
-/*
- * nfs write call
- */
-int
-nfs4_writerpc(struct vnode *vp, struct uio *uiop, struct ucred *cred,
- int *iomode, int *must_commit)
-{
- int32_t backup;
- caddr_t bpos, dpos;
- struct mbuf *mreq, *mrep = NULL, *md, *mb;
- struct nfsmount *nmp = VFSTONFS(vp->v_mount);
- int error = 0, len, tsiz, wccflag = 1, rlen;
- struct nfs4_compound cp;
- struct nfs4_oparg_write write;
- nfsv4stablehow commit, committed = NSHFILESYNC;
- caddr_t verf;
- struct nfsnode *np = VTONFS(vp);
-
-#ifndef DIAGNOSTIC
- if (uiop->uio_iovcnt != 1)
- panic("nfs: writerpc iovcnt > 1");
-#endif
- *must_commit = 0;
- tsiz = uiop->uio_resid;
- if (uiop->uio_offset + tsiz > nmp->nm_maxfilesize)
- return (EFBIG);
-
- if (tsiz == 0)
- return (0);
-
- write.stable = (nfsv4stablehow)*iomode;
- write.uiop = uiop;
- write.fcp = &np->n_wfc;
-
- while (tsiz > 0) {
- nfsstats.rpccnt[NFSPROC_WRITE]++;
- len = (tsiz > nmp->nm_wsize) ? nmp->nm_wsize : tsiz;
-
- write.off = uiop->uio_offset;
- write.cnt = len;
- nfs_v4initcompound(&cp);
-
- mreq = nfsm_reqhead(vp, NFSV4PROC_COMPOUND, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
-
- nfsm_v4build_compound(&cp, "nfs4_writerpc()");
- nfsm_v4build_putfh(&cp, vp);
- nfsm_v4build_write(&cp, &write);
- nfsm_v4build_finalize(&cp);
-
- nfsm_request(vp, NFSV4PROC_COMPOUND, uiop->uio_td, cred);
- if (error != 0) {
- error = nfs_v4postop(&cp, error);
- goto nfsmout;
- }
-
- nfsm_v4dissect_compound(&cp);
- nfsm_v4dissect_putfh(&cp);
- nfsm_v4dissect_write(&cp, &write);
-
- rlen = write.retlen;
- if (rlen == 0) {
- error = NFSERR_IO;
- break;
- } else if (rlen < len) {
- backup = len - rlen;
- uiop->uio_iov->iov_base =
- (char *)uiop->uio_iov->iov_base - backup;
- uiop->uio_iov->iov_len += backup;
- uiop->uio_offset -= backup;
- uiop->uio_resid += backup;
- len = rlen;
- }
-
- commit = write.committed;
-
- if (committed == NSHFILESYNC ||
- (committed = NSHDATASYNC && commit == NSHUNSTABLE))
- committed = commit;
-
- verf = (caddr_t)write.wverf;
-
- if ((nmp->nm_flag & NFSSTA_HASWRITEVERF) == 0) {
- bcopy(verf, nmp->nm_verf, NFSX_V4VERF);
- nmp->nm_flag |= NFSMNT_HASWRITEVERF;
- } else if (bcmp(verf, nmp->nm_verf, NFSX_V4VERF)) {
- *must_commit = 1;
- bcopy(verf, nmp->nm_verf, NFSX_V4VERF);
- }
-
- /* XXX wccflag */
- if (wccflag)
- VTONFS(vp)->n_mtime = VTONFS(vp)->n_vattr.va_mtime;
-
- error = nfs_v4postop(&cp, error);
-
- m_freem(mrep);
- mrep = NULL;
- if (error)
- break;
- tsiz -= len;
- }
-nfsmout:
- if (mrep != NULL)
- m_freem(mrep);
- *iomode = committed;
- if (error)
- uiop->uio_resid = tsiz;
- return (error);
-}
-
-/* ARGSUSED */
-static int
-nfs4_mknod(struct vop_mknod_args *ap)
-{
- struct vattr *vap = ap->a_vap;
- struct vnode *newvp = NULL;
- int error;
-
- error = nfs4_createrpc(ap->a_dvp, &newvp,
- ap->a_cnp, (nfstype)vap->va_type, vap, NULL);
-
- /* XXX - is this actually referenced here? */
- if (error == 0) {
- *ap->a_vpp = newvp;
- vrele(newvp);
- }
-
- return (error);
-}
-
-static int
-nfs4_createrpc(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp,
- nfstype ftype, struct vattr *vap, char *linktarget)
-{
- struct nfsnode *dnp = VTONFS(dvp);
- struct nfsnode *np = NULL;
- struct vnode *newvp = NULL;
- struct nfs4_compound cp;
- struct nfs4_oparg_create c;
- struct nfs4_oparg_getattr ga;
- struct nfs4_oparg_getfh gfh;
- caddr_t bpos, dpos;
- struct mbuf *mreq, *mrep = NULL, *md, *mb;
- int error = 0;
-
- nfsstats.rpccnt[NFSPROC_CREATE]++;
-
- mreq = nfsm_reqhead(dvp, NFSV4PROC_COMPOUND, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
-
- bzero(&c, sizeof(c));
- bzero(&ga, sizeof(ga));
-
- c.type = ftype;
- c.vap = vap;
- c.linktext = linktarget;
- c.name = cnp->cn_nameptr;
- c.namelen = cnp->cn_namelen;
-
- ga.bm = &nfsv4_getattrbm;
- nfs_v4initcompound(&cp);
-
- nfsm_v4build_compound(&cp, "nfs4_createrpc()");
- nfsm_v4build_putfh(&cp, dvp);
- nfsm_v4build_create(&cp, &c);
- nfsm_v4build_getattr(&cp, &ga);
- nfsm_v4build_getfh(&cp, &gfh);
- nfsm_v4build_finalize(&cp);
-
- nfsm_request(dvp, NFSV4PROC_COMPOUND, cnp->cn_thread, cnp->cn_cred);
- if (error != 0)
- goto nfsmout;
-
- nfsm_v4dissect_compound(&cp);
- nfsm_v4dissect_putfh(&cp);
- nfsm_v4dissect_create(&cp, &c);
- nfsm_v4dissect_getattr(&cp, &ga);
- nfsm_v4dissect_getfh(&cp, &gfh);
-
- error = nfs_nget(dvp->v_mount, &gfh.fh_val, gfh.fh_len, &np, LK_EXCLUSIVE);
- if (error != 0)
- goto nfsmout;
-
- newvp = NFSTOV(np);
- nfs4_vnop_loadattrcache(newvp, &ga.fa, NULL);
-
- if (cnp->cn_flags & MAKEENTRY)
- cache_enter(dvp, newvp, cnp);
-
- dnp->n_flag |= NMODIFIED;
- dnp->n_attrstamp = 0;
-
- nfsmout:
- error = nfs_v4postop(&cp, error);
-
- if (mrep != NULL)
- m_freem(mrep);
-
- /* XXX */
- /*free(cnp->cn_pnbuf, M_NAMEI);*/
- if (error != 0 && newvp != NULL)
- vput(newvp);
- else if (error == 0)
- *vpp = newvp;
-
- return (error);
-}
-
-static int
-nfs4_renamerpc(struct vnode *fdvp, const char *fnameptr, int fnamelen,
- struct vnode *tdvp, const char *tnameptr, int tnamelen,
- struct ucred *cred, struct thread *td)
-{
-
- struct nfsnode *fnp = VTONFS(fdvp), *tnp = VTONFS(tdvp);
- caddr_t bpos, dpos;
- struct mbuf *mreq, *mrep = NULL, *md, *mb;
- struct nfs4_compound cp;
- struct nfs4_oparg_rename r;
- int error = 0;
-
- nfsstats.rpccnt[NFSPROC_RENAME]++;
-
- r.fname = fnameptr;
- r.fnamelen = fnamelen;
- r.tname = tnameptr;
- r.tnamelen = tnamelen;
- nfs_v4initcompound(&cp);
-
- mreq = nfsm_reqhead(fdvp, NFSV4PROC_COMPOUND, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
-
- nfsm_v4build_compound(&cp, "nfs4_renamerpc()");
- nfsm_v4build_putfh(&cp, fdvp);
- nfsm_v4build_savefh(&cp);
- nfsm_v4build_putfh(&cp, tdvp);
- nfsm_v4build_rename(&cp, &r);
- nfsm_v4build_finalize(&cp);
-
- nfsm_request(fdvp, NFSV4PROC_COMPOUND, td, cred);
- if (error != 0)
- goto nfsmout;
-
- nfsm_v4dissect_compound(&cp);
- nfsm_v4dissect_putfh(&cp);
- nfsm_v4dissect_savefh(&cp);
- nfsm_v4dissect_putfh(&cp);
- nfsm_v4dissect_rename(&cp);
-
- /* XXX should this always be performed? */
- fnp->n_flag |= NMODIFIED;
- tnp->n_flag |= NMODIFIED;
- fnp->n_attrstamp = tnp->n_attrstamp = 0;
-
- nfsmout:
- error = nfs_v4postop(&cp, error);
-
- if (mrep != NULL)
- m_freem(mrep);
-
- return (error);
-}
-
-/*
- * nfs file create call
- */
-static int
-nfs4_create(struct vop_create_args *ap)
-{
- struct vnode *dvp = ap->a_dvp;
- struct vattr *vap = ap->a_vap;
- struct nfsnode *dnp = VTONFS(dvp);
- struct componentname *cnp = ap->a_cnp;
- struct vnode *newvp = NULL;
- int error = 0, fmode = (O_CREAT | FREAD | FWRITE);
- struct vattr vattr;
-
- if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_cred)) != 0)
- return (error);
-
- if (vap->va_vaflags & VA_EXCLUSIVE)
- fmode |= O_EXCL;
-
- error = nfs4_openrpc(dvp, &newvp, cnp, fmode, vap);
- if (error != 0)
- goto out;
-
- VTONFS(newvp)->n_flag |= NCREATED;
-
- if (cnp->cn_flags & MAKEENTRY)
- cache_enter(dvp, newvp, cnp);
-
- *ap->a_vpp = newvp;
-
- dnp->n_flag |= NMODIFIED;
- dnp->n_attrstamp = 0; /* XXX; wccflag */
-
- out:
- return (error);
-}
-
-/*
- * nfs file remove call
- * To try and make nfs semantics closer to ufs semantics, a file that has
- * other processes using the vnode is renamed instead of removed and then
- * removed later on the last close.
- * - If v_usecount > 1
- * If a rename is not already in the works
- * call nfs4_sillyrename() to set it up
- * else
- * do the remove rpc
- */
-static int
-nfs4_remove(struct vop_remove_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct vnode *dvp = ap->a_dvp;
- struct componentname *cnp = ap->a_cnp;
- struct nfsnode *np = VTONFS(vp);
- int error = 0;
- struct vattr vattr;
-
-#ifndef DIAGNOSTIC
- if ((cnp->cn_flags & HASBUF) == 0)
- panic("nfs4_remove: no name");
- if (vrefcnt(vp) < 1)
- panic("nfs4_remove: bad v_usecount");
-#endif
- if (vp->v_type == VDIR)
- error = EPERM;
- else if (vrefcnt(vp) == 1 || (np->n_sillyrename &&
- !VOP_GETATTR(vp, &vattr, cnp->cn_cred) && vattr.va_nlink > 1)) {
- /*
- * Purge the name cache so that the chance of a lookup for
- * the name succeeding while the remove is in progress is
- * minimized. Without node locking it can still happen, such
- * that an I/O op returns ESTALE, but since you get this if
- * another host removes the file..
- */
- cache_purge(vp);
- /*
- * throw away biocache buffers, mainly to avoid
- * unnecessary delayed writes later.
- */
- error = nfs_vinvalbuf(vp, 0, cnp->cn_thread, 1);
- /* Do the rpc */
- if (error != EINTR)
- error = nfs4_removerpc(dvp, cnp->cn_nameptr,
- cnp->cn_namelen, cnp->cn_cred, cnp->cn_thread);
- /*
- * Kludge City: If the first reply to the remove rpc is lost..
- * the reply to the retransmitted request will be ENOENT
- * since the file was in fact removed
- * Therefore, we cheat and return success.
- */
- if (error == ENOENT)
- error = 0;
- } else if (!np->n_sillyrename)
- error = nfs4_sillyrename(dvp, vp, cnp);
- np->n_attrstamp = 0;
- return (error);
-}
-
-/*
- * nfs file remove rpc called from nfs_inactive
- */
-int
-nfs4_removeit(struct sillyrename *sp)
-{
- /*
- * Make sure that the directory vnode is still valid.
- * XXX we should lock sp->s_dvp here.
- */
- if (sp->s_dvp->v_type == VBAD)
- return (0);
- return (nfs4_removerpc(sp->s_dvp, sp->s_name, sp->s_namlen, sp->s_cred,
- NULL));
-}
-
-/*
- * Nfs remove rpc, called from nfs4_remove() and nfs4_removeit().
- */
-static int
-nfs4_removerpc(struct vnode *dvp, const char *name, int namelen,
- struct ucred *cred, struct thread *td)
-{
- caddr_t bpos, dpos;
- int error = 0;
- struct mbuf *mreq, *mrep = NULL, *md, *mb;
- struct nfs4_compound cp;
-
- nfsstats.rpccnt[NFSPROC_REMOVE]++;
-
- mreq = nfsm_reqhead(dvp, NFSV4PROC_COMPOUND, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
-
- nfs_v4initcompound(&cp);
-
- nfsm_v4build_compound(&cp, "nfs4_removerpc()");
- nfsm_v4build_putfh(&cp, dvp);
- nfsm_v4build_remove(&cp, name, namelen);
- nfsm_v4build_finalize(&cp);
-
- nfsm_request(dvp, NFSV4PROC_COMPOUND, td, cred);
- if (error != 0)
- goto nfsmout;
-
- nfsm_v4dissect_compound(&cp);
- nfsm_v4dissect_putfh(&cp);
- nfsm_v4dissect_remove(&cp);
-
- nfsmout:
- error = nfs_v4postop(&cp, error);
-
- if (mrep != NULL)
- m_freem(mrep);
-
- VTONFS(dvp)->n_flag |= NMODIFIED;
- VTONFS(dvp)->n_attrstamp = 0; /* XXX wccflag */
-
- return (error);
-}
-
-/*
- * nfs file rename call
- */
-static int
-nfs4_rename(struct vop_rename_args *ap)
-{
- struct vnode *fvp = ap->a_fvp;
- struct vnode *tvp = ap->a_tvp;
- struct vnode *fdvp = ap->a_fdvp;
- struct vnode *tdvp = ap->a_tdvp;
- struct componentname *tcnp = ap->a_tcnp;
- struct componentname *fcnp = ap->a_fcnp;
- int error;
-
- #ifndef DIAGNOSTIC
- if ((tcnp->cn_flags & HASBUF) == 0 ||
- (fcnp->cn_flags & HASBUF) == 0)
- panic("nfs4_rename: no name");
-#endif
- /* Check for cross-device rename */
- if ((fvp->v_mount != tdvp->v_mount) ||
- (tvp && (fvp->v_mount != tvp->v_mount))) {
- error = EXDEV;
- goto out;
- }
-
- if (fvp == tvp) {
- printf("nfs4_rename: fvp == tvp (can't happen)\n");
- error = 0;
- goto out;
- }
- if ((error = vn_lock(fvp, LK_EXCLUSIVE)) != 0)
- goto out;
-
- /*
- * We have to flush B_DELWRI data prior to renaming
- * the file. If we don't, the delayed-write buffers
- * can be flushed out later after the file has gone stale
- * under NFSV3. NFSV2 does not have this problem because
- * ( as far as I can tell ) it flushes dirty buffers more
- * often.
- */
- VOP_FSYNC(fvp, MNT_WAIT, fcnp->cn_thread);
- VOP_UNLOCK(fvp, 0);
- if (tvp)
- VOP_FSYNC(tvp, MNT_WAIT, tcnp->cn_thread);
-
- /*
- * If the tvp exists and is in use, sillyrename it before doing the
- * rename of the new file over it.
- * XXX Can't sillyrename a directory.
- */
- if (tvp && vrefcnt(tvp) > 1 && !VTONFS(tvp)->n_sillyrename &&
- tvp->v_type != VDIR && !nfs4_sillyrename(tdvp, tvp, tcnp)) {
- vput(tvp);
- tvp = NULL;
- }
-
- error = nfs4_renamerpc(fdvp, fcnp->cn_nameptr, fcnp->cn_namelen,
- tdvp, tcnp->cn_nameptr, tcnp->cn_namelen, tcnp->cn_cred,
- tcnp->cn_thread);
-
- if (fvp->v_type == VDIR) {
- if (tvp != NULL && tvp->v_type == VDIR)
- cache_purge(tdvp);
- cache_purge(fdvp);
- }
-
-out:
- if (tdvp == tvp)
- vrele(tdvp);
- else
- vput(tdvp);
- if (tvp)
- vput(tvp);
- vrele(fdvp);
- vrele(fvp);
- /*
- * Kludge: Map ENOENT => 0 assuming that it is a reply to a retry.
- */
- if (error == ENOENT)
- error = 0;
- return (error);
-}
-
-/*
- * nfs file rename rpc called from nfs4_remove() above
- */
-static int
-nfs4_renameit(struct vnode *sdvp, struct componentname *scnp,
- struct sillyrename *sp)
-{
- return (nfs4_renamerpc(sdvp, scnp->cn_nameptr, scnp->cn_namelen, sdvp,
- sp->s_name, sp->s_namlen, scnp->cn_cred, scnp->cn_thread));
-}
-
-/*
- * nfs hard link create call
- */
-static int
-nfs4_link(struct vop_link_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct vnode *tdvp = ap->a_tdvp;
- struct componentname *cnp = ap->a_cnp;
- caddr_t bpos, dpos;
- int error = 0;
- struct mbuf *mreq, *mrep = NULL, *md, *mb;
- struct nfs4_compound cp;
- struct nfs4_oparg_link l;
-
- if (vp->v_mount != tdvp->v_mount) {
- return (EXDEV);
- }
-
- /*
- * Push all writes to the server, so that the attribute cache
- * doesn't get "out of sync" with the server.
- * XXX There should be a better way!
- */
- VOP_FSYNC(vp, MNT_WAIT, cnp->cn_thread);
-
- nfsstats.rpccnt[NFSPROC_LINK]++;
-
- l.name = cnp->cn_nameptr;
- l.namelen = cnp->cn_namelen;
- nfs_v4initcompound(&cp);
-
- mreq = nfsm_reqhead(vp, NFSV4PROC_COMPOUND, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
-
- nfsm_v4build_compound(&cp, "nfs4_link()");
- nfsm_v4build_putfh(&cp, vp);
- nfsm_v4build_savefh(&cp);
- nfsm_v4build_putfh(&cp, tdvp);
- nfsm_v4build_link(&cp, &l);
- nfsm_v4build_finalize(&cp);
-
- nfsm_request(vp, NFSV4PROC_COMPOUND, cnp->cn_thread, cnp->cn_cred);
- if (error != 0)
- goto nfsmout;
-
- nfsm_v4dissect_compound(&cp);
- nfsm_v4dissect_putfh(&cp);
- nfsm_v4dissect_savefh(&cp);
- nfsm_v4dissect_putfh(&cp);
- nfsm_v4dissect_link(&cp);
-
- VTONFS(tdvp)->n_flag |= NMODIFIED;
- VTONFS(vp)->n_attrstamp = 0;
- VTONFS(tdvp)->n_attrstamp = 0;
-
-nfsmout:
- error = nfs_v4postop(&cp, error);
-
- if (mrep != NULL)
- m_freem(mrep);
-
- return (error);
-}
-
-/*
- * nfs symbolic link create call
- */
-static int
-nfs4_symlink(struct vop_symlink_args *ap)
-{
- struct vnode *dvp = ap->a_dvp;
- int error = 0;
- struct vnode *newvp = NULL;
-
- nfsstats.rpccnt[NFSPROC_SYMLINK]++;
-
- error = nfs4_createrpc(ap->a_dvp, &newvp, ap->a_cnp, NFLNK,
- ap->a_vap, ap->a_target);
-
- if (error != 0 && newvp != NULL)
- vput(newvp);
- else if (error == 0)
- *ap->a_vpp = newvp;
-
- VTONFS(dvp)->n_flag |= NMODIFIED;
- VTONFS(dvp)->n_attrstamp = 0; /* XXX wccflags */
-
- return (error);
-}
-
-/*
- * nfs make dir call
- */
-static int
-nfs4_mkdir(struct vop_mkdir_args *ap)
-{
- return (nfs4_createrpc(ap->a_dvp, ap->a_vpp, ap->a_cnp, NFDIR,
- ap->a_vap, NULL));
-}
-
-/*
- * nfs remove directory call
- */
-static int
-nfs4_rmdir(struct vop_rmdir_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct vnode *dvp = ap->a_dvp;
- struct nfsnode *dnp = VTONFS(dvp);
- struct componentname *cnp = ap->a_cnp;
- int error = 0;
-
- if (dvp == vp)
- return (EINVAL);
-
- error = (nfs4_removerpc(dvp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_cred,
- NULL));
- if (error)
- return (error);
-
- dnp->n_flag |= NMODIFIED;
- dnp->n_attrstamp = 0;
- cache_purge(dvp);
- cache_purge(vp);
-
- return (error);
-}
-
-/*
- * nfs readdir call
- */
-static int
-nfs4_readdir(struct vop_readdir_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct nfsnode *np = VTONFS(vp);
- struct uio *uio = ap->a_uio;
- int tresid, error;
- struct vattr vattr;
-
- if (vp->v_type != VDIR)
- return (EPERM);
- /*
- * First, check for hit on the EOF offset cache
- */
- if (np->n_direofoffset > 0 && uio->uio_offset >= np->n_direofoffset &&
- (np->n_flag & NMODIFIED) == 0) {
- if (!VOP_GETATTR(vp, &vattr, ap->a_cred) &&
- !NFS_TIMESPEC_COMPARE(&np->n_mtime, &vattr.va_mtime)) {
- nfsstats.direofcache_hits++;
- return (0);
- }
- }
-
- /*
- * Call nfs_bioread() to do the real work.
- */
- tresid = uio->uio_resid;
- error = nfs_bioread(vp, uio, 0, ap->a_cred);
-
- if (!error && uio->uio_resid == tresid)
- nfsstats.direofcache_misses++;
- return (error);
-}
-
-static u_char fty_to_dty[] = {
- DT_UNKNOWN, /* NFNON */
- DT_REG, /* NFREG */
- DT_DIR, /* NFDIR */
- DT_BLK, /* NFBLK */
- DT_CHR, /* NFCHR */
- DT_LNK, /* NFLNK */
- DT_SOCK, /* NFSOCK */
- DT_FIFO, /* NFFIFO */
- DT_UNKNOWN, /* NFATTRDIT */
- DT_UNKNOWN, /* NFNAMEDATTR */
- DT_UNKNOWN, /* NFBAD */
-};
-
-/*
- * Readdir rpc call.
- * Called from below the buffer cache by nfs_doio().
- */
-int
-nfs4_readdirrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred)
-{
- int len, left;
- struct dirent *dp = NULL;
- u_int32_t *tl;
- caddr_t p;
- uint64_t *cookiep;
- caddr_t bpos, dpos;
- struct mbuf *mreq, *mrep = NULL, *md, *mb;
- uint64_t cookie;
- struct nfsmount *nmp = VFSTONFS(vp->v_mount);
- struct nfsnode *dnp = VTONFS(vp);
- int error = 0, tlen, more_dirs = 1, blksiz = 0, bigenough = 1;
- struct nfs4_compound cp;
- struct nfs4_oparg_readdir readdir;
- struct nfsv4_fattr fattr;
- u_int fty;
-
-#ifndef DIAGNOSTIC
- if (uiop->uio_iovcnt != 1 || (uiop->uio_offset & (DIRBLKSIZ - 1)) ||
- (uiop->uio_resid & (DIRBLKSIZ - 1)))
- panic("nfs readdirrpc bad uio");
-#endif
-
- /*
- * If there is no cookie, assume directory was stale.
- */
- cookiep = nfs4_getcookie(dnp, uiop->uio_offset, 0);
- if (cookiep)
- cookie = *cookiep;
- else
- return (NFSERR_BAD_COOKIE);
-
- /* Generate fake entries for "." and ".." */
- while (cookie < 2 && bigenough) {
- cookie++;
- len = 4 + DIRHDSIZ;
-
- if (len > uiop->uio_resid) {
- bigenough = 0;
- break;
- }
- dp = (struct dirent *)uiop->uio_iov->iov_base;
-
- dp->d_namlen = cookie;
- dp->d_reclen = len;
- dp->d_type = DT_DIR;
- if (cookie == 1)
- dp->d_fileno = dnp->n_vattr.va_fileid; /* XXX has problems with pynfs virtualhandles */
- else
- dp->d_fileno = dnp->n_dvp != NULL ?
- VTONFS(dnp->n_dvp)->n_vattr.va_fileid : cookie;
-
- p = dp->d_name;
- *p++ = '.';
- if (cookie == 2)
- *p++ = '.';
- *p = '\0';
-
- blksiz += len;
- if (blksiz == DIRBLKSIZ)
- blksiz = 0;
- uiop->uio_offset += len;
- uiop->uio_resid -= len;
- uiop->uio_iov->iov_base = (char *)uiop->uio_iov->iov_base + len;
- uiop->uio_iov->iov_len -= len;
- }
-
- if (cookie == 2)
- cookie = 0;
-
- /* This is sort of ugly, to prevent v4postop() from acting weird */
- bzero(&cp, sizeof(cp));
-
- /*
- * Loop around doing readdir rpc's of size nm_readdirsize
- * truncated to a multiple of DIRBLKSIZ.
- * The stopping criteria is EOF or buffer full.
- */
- /*
- * XXX this is sort of ugly for nfsv4; we don't maintain the
- * strict abstraction, but do the decoding inline. that's ok.
- */
- while (more_dirs && bigenough) {
- nfsstats.rpccnt[NFSPROC_READDIR]++;
-
- mreq = nfsm_reqhead(vp, NFSV4PROC_COMPOUND, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
-
- readdir.cnt = nmp->nm_readdirsize;
- readdir.cookie = cookie;
- readdir.bm = &nfsv4_readdirbm;
- if (cookie == 0)
- bzero(&readdir.verf, sizeof(readdir.verf));
- else
- bcopy(&dnp->n_cookieverf, &readdir.verf,
- sizeof(readdir.verf));
-
- nfs_v4initcompound(&cp);
-
- nfsm_v4build_compound(&cp, "nfs4_readdirrpc()");
- nfsm_v4build_putfh(&cp, vp);
- nfsm_v4build_readdir(&cp, &readdir);
- nfsm_v4build_finalize(&cp);
-
- nfsm_request(vp, NFSV4PROC_COMPOUND, uiop->uio_td, cred);
- if (error != 0)
- goto nfsmout;
-
- nfsm_v4dissect_compound(&cp);
- nfsm_v4dissect_putfh(&cp);
-
- /*
- * XXX - Readdir gets handled inline like in
- * NFSv{2,3}. This is a nasty inconsistency and
- * should be fixed.
- */
-
- tl = nfsm_dissect(uint32_t *, 5 * NFSX_UNSIGNED);
- if (fxdr_unsigned(uint32_t, *tl++) != NFSV4OP_READDIR) {
- error = EBADRPC;
- goto nfsmout;
- }
- if (fxdr_unsigned(uint32_t, *tl++) != 0) {
- error = EBADRPC;
- goto nfsmout;
- }
-
- bcopy(tl, &dnp->n_cookieverf, NFSX_V4VERF);
- tl += 2;
- more_dirs = fxdr_unsigned(int, *tl++);
-
- /* loop thru the dir entries, doctoring them to 4bsd form */
- while (more_dirs && bigenough) {
- tl = nfsm_dissect(uint32_t *, 3 * NFSX_UNSIGNED);
- cookie = fxdr_hyper(tl);
- tl += 2;
- /* XXX cookie sanity check */
- len = fxdr_unsigned(int, *tl++);
- if (len <= 0 || len > NFS_MAXNAMLEN) {
- error = EBADRPC;
- goto nfsmout;
- }
- tlen = nfsm_rndup(len);
- if (tlen == len)
- tlen += 4; /* To ensure null termination */
- left = DIRBLKSIZ - blksiz;
- if ((tlen + DIRHDSIZ) > left) {
- dp->d_reclen += left;
- uiop->uio_iov->iov_base =
- (char *)uiop->uio_iov->iov_base + left;
- uiop->uio_iov->iov_len -= left;
- uiop->uio_offset += left;
- uiop->uio_resid -= left;
- blksiz = 0;
- }
- if ((tlen + DIRHDSIZ) > uiop->uio_resid)
- bigenough = 0;
- if (bigenough) {
- dp = (struct dirent *)uiop->uio_iov->iov_base;
-
- dp->d_namlen = len;
- dp->d_reclen = tlen + DIRHDSIZ;
-
- blksiz += dp->d_reclen;
- if (blksiz == DIRBLKSIZ)
- blksiz = 0;
- uiop->uio_offset += DIRHDSIZ;
- uiop->uio_resid -= DIRHDSIZ;
- uiop->uio_iov->iov_base =
- (char *)uiop->uio_iov->iov_base + DIRHDSIZ;
- uiop->uio_iov->iov_len -= DIRHDSIZ;
-
- /* Copy name */
- nfsm_mtouio(uiop, len);
- p = uiop->uio_iov->iov_base;
- tlen -= len;
- *p = '\0'; /* null terminate */
- /* printf("nfs4_readdirrpc: name: \"%s\" cookie %d\n",
- p - len, (int) cookie);*/
- uiop->uio_iov->iov_base =
- (char *)uiop->uio_iov->iov_base + tlen;
- uiop->uio_iov->iov_len -= tlen;
- uiop->uio_offset += tlen;
- uiop->uio_resid -= tlen;
-
- /* Copy attributes */
- nfsm_v4dissect_attrs(&fattr);
-
- dp->d_fileno = nfs_v4fileid4_to_fileid(
- fattr.fa4_valid & FA4V_FILEID &&
- fattr.fa4_fileid ?
- fattr.fa4_fileid : cookie);
-
- fty = (u_int)fattr.fa4_type;
- dp->d_type = fattr.fa4_valid & FA4V_TYPE &&
- (fty < sizeof(fty_to_dty)) ?
- fty_to_dty[fty] : DT_UNKNOWN;
- } else
- nfsm_adv(nfsm_rndup(len));
-
- tl = nfsm_dissect(uint32_t *, NFSX_UNSIGNED);
- more_dirs = fxdr_unsigned(int, *tl++);
- }
- /*
- * If at end of rpc data, get the eof boolean
- */
- if (!more_dirs) {
- tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED);
- more_dirs = (fxdr_unsigned(int, *tl) == 0);
- }
-
- error = nfs_v4postop(&cp, error);
-
- m_freem(mrep);
- mrep = NULL;
- }
- /*
- * Fill last record, iff any, out to a multiple of DIRBLKSIZ
- * by increasing d_reclen for the last record.
- */
- if (blksiz > 0) {
- left = DIRBLKSIZ - blksiz;
- dp->d_reclen += left;
- uiop->uio_iov->iov_base =
- (char *)uiop->uio_iov->iov_base + left;
- uiop->uio_iov->iov_len -= left;
- uiop->uio_offset += left;
- uiop->uio_resid -= left;
- }
-
- /*
- * We are now either at the end of the directory or have filled the
- * block.
- */
- if (bigenough)
- dnp->n_direofoffset = uiop->uio_offset;
- else {
- if (uiop->uio_resid > 0)
- printf("EEK! readdirrpc resid > 0\n");
- cookiep = nfs4_getcookie(dnp, uiop->uio_offset, 1);
- *cookiep = cookie;
- }
-nfsmout:
- if (mrep != NULL)
- m_freem(mrep);
- return (error);
-}
-
-/*
- * Silly rename. To make the NFS filesystem that is stateless look a little
- * more like the "ufs" a remove of an active vnode is translated to a rename
- * to a funny looking filename that is removed by nfs_inactive on the
- * nfsnode. There is the potential for another process on a different client
- * to create the same funny name between the nfs_lookitup() fails and the
- * nfs_rename() completes, but...
- */
-static int
-nfs4_sillyrename(struct vnode *dvp, struct vnode *vp, struct componentname *cnp)
-{
- struct sillyrename *sp;
- struct nfsnode *np;
- int error;
- short pid;
-
- cache_purge(dvp);
- np = VTONFS(vp);
-#ifndef DIAGNOSTIC
- if (vp->v_type == VDIR)
- panic("nfs: sillyrename dir");
-#endif
- sp = malloc(sizeof (struct sillyrename), M_NFSREQ, M_WAITOK);
- sp->s_cred = crhold(cnp->cn_cred);
- sp->s_dvp = dvp;
- sp->s_removeit = nfs4_removeit;
- VREF(dvp);
-
- /* Fudge together a funny name */
- pid = cnp->cn_thread->td_proc->p_pid;
- sp->s_namlen = sprintf(sp->s_name, ".nfsA%04x4.4", pid);
-
- /* Try lookitups until we get one that isn't there */
- while (nfs4_lookitup(dvp, sp->s_name, sp->s_namlen, sp->s_cred,
- cnp->cn_thread, NULL) == 0) {
- sp->s_name[4]++;
- if (sp->s_name[4] > 'z') {
- error = EINVAL;
- goto bad;
- }
- }
- error = nfs4_renameit(dvp, cnp, sp);
- if (error)
- goto bad;
- error = nfs4_lookitup(dvp, sp->s_name, sp->s_namlen, sp->s_cred,
- cnp->cn_thread, &np);
- np->n_sillyrename = sp;
- return (0);
-bad:
- vrele(sp->s_dvp);
- crfree(sp->s_cred);
- free((caddr_t)sp, M_NFSREQ);
- return (error);
-}
-
-/*
- * Look up a file name and optionally either update the file handle or
- * allocate an nfsnode, depending on the value of npp.
- * npp == NULL --> just do the lookup
- * *npp == NULL --> allocate a new nfsnode and make sure attributes are
- * handled too
- * *npp != NULL --> update the file handle in the vnode
- */
-static int
-nfs4_lookitup(struct vnode *dvp, const char *name, int len, struct ucred *cred,
- struct thread *td, struct nfsnode **npp)
-{
- struct vnode *newvp = NULL;
- struct nfsnode *np, *dnp = VTONFS(dvp);
- caddr_t bpos, dpos;
- int error = 0, fhlen;
- struct mbuf *mreq, *mrep = NULL, *md, *mb;
- nfsfh_t *nfhp;
- struct nfs4_compound cp;
- struct nfs4_oparg_lookup l;
- struct nfs4_oparg_getfh gfh;
- struct nfs4_oparg_getattr ga;
-
- nfsstats.rpccnt[NFSPROC_RENAME]++;
-
- mreq = nfsm_reqhead(dvp, NFSV4PROC_COMPOUND, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
-
- l.name = name;
- l.namelen = len;
-
- nfs_v4initcompound(&cp);
-
- ga.bm = &nfsv4_getattrbm;
-
- nfsm_v4build_compound(&cp, "nfs4_renamerpc()");
- nfsm_v4build_putfh(&cp, dvp);
- nfsm_v4build_lookup(&cp, &l);
- nfsm_v4build_getfh(&cp, &gfh);
- nfsm_v4build_getattr(&cp, &ga);
-
- nfsm_request(dvp, NFSV4PROC_COMPOUND, td, cred);
- if (error != 0)
- goto nfsmout;
-
- nfsm_v4dissect_compound(&cp);
- nfsm_v4dissect_putfh(&cp);
- nfsm_v4dissect_lookup(&cp);
- nfsm_v4dissect_getfh(&cp, &gfh);
- nfsm_v4dissect_getattr(&cp, &ga);
-
- if (npp != NULL && error == 0) {
- nfhp = &gfh.fh_val;
- fhlen = gfh.fh_len;
-
- if (*npp != NULL) {
- np = *npp;
- if (np->n_fhsize > NFS_SMALLFH && fhlen <= NFS_SMALLFH) {
- free((caddr_t)np->n_fhp, M_NFSBIGFH);
- np->n_fhp = &np->n_fh;
- } else if (np->n_fhsize <= NFS_SMALLFH && fhlen>NFS_SMALLFH)
- np->n_fhp =(nfsfh_t *)malloc(fhlen, M_NFSBIGFH, M_WAITOK);
- bcopy((caddr_t)nfhp, (caddr_t)np->n_fhp, fhlen);
- np->n_fhsize = fhlen;
- newvp = NFSTOV(np);
- } else if (NFS_CMPFH(dnp, nfhp, fhlen)) {
- VREF(dvp);
- newvp = dvp;
- } else {
- error = nfs_nget(dvp->v_mount, nfhp, fhlen, &np, LK_EXCLUSIVE);
- if (error) {
- m_freem(mrep);
- return (error);
- }
- newvp = NFSTOV(np);
- }
-
- if (newvp != dvp) {
- np->n_dvp = dvp;
- np->n_namelen = len;
- if (np->n_name != NULL)
- free(np->n_name, M_NFSREQ);
- np->n_name = malloc(np->n_namelen + 1, M_NFSREQ, M_WAITOK);
- memcpy(np->n_name, name, len);
- np->n_name[len] = '\0';
- }
- nfs4_vnop_loadattrcache(newvp, &ga.fa, NULL);
- }
-
-nfsmout:
- error = nfs_v4postop(&cp, error);
-
- if (mrep != NULL)
- m_freem(mrep);
- if (npp && *npp == NULL) {
- if (error) {
- if (newvp) {
- if (newvp == dvp)
- vrele(newvp);
- else
- vput(newvp);
- }
- } else
- *npp = np;
- }
-
-
- return (error);
-}
-
-/*
- * Nfs Version 3 commit rpc
- */
-int
-nfs4_commit(struct vnode *vp, u_quad_t offset, int cnt, struct ucred *cred,
- struct thread *td)
-{
- struct nfsmount *nmp = VFSTONFS(vp->v_mount);
- caddr_t bpos, dpos;
- int error = 0;
- struct mbuf *mreq, *mrep = NULL, *md, *mb;
- struct nfs4_compound cp;
- struct nfs4_oparg_commit commit;
-
- if ((nmp->nm_state & NFSSTA_HASWRITEVERF) == 0)
- return (0);
- nfsstats.rpccnt[NFSPROC_COMMIT]++;
-
- mreq = nfsm_reqhead(vp, NFSV4PROC_COMPOUND, 0);
- mb = mreq;
- bpos = mtod(mb, caddr_t);
-
- commit.start = offset;
- commit.len = cnt;
-
- nfs_v4initcompound(&cp);
-
- nfsm_v4build_compound(&cp, "nfs4_commit()");
- nfsm_v4build_putfh(&cp, vp);
- nfsm_v4build_commit(&cp, &commit);
- nfsm_v4build_finalize(&cp);
-
- nfsm_request(vp, NFSV4PROC_COMPOUND, td, cred);
- if (error != 0)
- goto nfsmout;
-
- nfsm_v4dissect_compound(&cp);
- nfsm_v4dissect_putfh(&cp);
- nfsm_v4dissect_commit(&cp, &commit);
-
- /* XXX */
- /* nfsm_wcc_data(vp, wccflag);*/
- if (bcmp(nmp->nm_verf, commit.verf, NFSX_V4VERF)) {
- bcopy(commit.verf, nmp->nm_verf, NFSX_V4VERF);
- error = NFSERR_STALEWRITEVERF;
- }
-
-nfsmout:
- error = nfs_v4postop(&cp, error);
-
- if (mrep == NULL)
- m_freem(mrep);
- return (error);
-}
-
-/*
- * Strategy routine.
- * For async requests when nfsiod(s) are running, queue the request by
- * calling nfs_asyncio(), otherwise just all nfs_doio() to do the
- * request.
- */
-static int
-nfs4_strategy(struct vop_strategy_args *ap)
-{
- struct buf *bp = ap->a_bp;
- struct ucred *cr;
- int error = 0;
-
- KASSERT(!(bp->b_flags & B_DONE),
- ("nfs4_strategy: buffer %p unexpectedly marked B_DONE", bp));
- BUF_ASSERT_HELD(bp);
-
- if (bp->b_iocmd == BIO_READ)
- cr = bp->b_rcred;
- else
- cr = bp->b_wcred;
-
- /*
- * If the op is asynchronous and an i/o daemon is waiting
- * queue the request, wake it up and wait for completion
- * otherwise just do it ourselves.
- */
- if ((bp->b_flags & B_ASYNC) == 0 ||
- nfs_asyncio(VFSTONFS(ap->a_vp->v_mount), bp, NOCRED, curthread))
- error = nfs_doio(ap->a_vp, bp, cr, curthread);
- return (error);
-}
-
-/*
- * fsync vnode op. Just call nfs4_flush() with commit == 1.
- */
-/* ARGSUSED */
-static int
-nfs4_fsync(struct vop_fsync_args *ap)
-{
- return (nfs4_flush(ap->a_vp, ap->a_waitfor, ap->a_td, 1));
-}
-
-/*
- * Flush all the blocks associated with a vnode.
- * Walk through the buffer pool and push any dirty pages
- * associated with the vnode.
- */
-static int
-nfs4_flush(struct vnode *vp, int waitfor, struct thread *td,
- int commit)
-{
- struct nfsnode *np = VTONFS(vp);
- struct bufobj *bo;
- struct buf *bp;
- int i;
- struct buf *nbp;
- struct nfsmount *nmp = VFSTONFS(vp->v_mount);
- int error = 0, slptimeo = 0, slpflag = 0, retv, bvecpos;
- int passone = 1;
- u_quad_t off, endoff, toff;
- struct ucred* wcred = NULL;
- struct buf **bvec = NULL;
-#ifndef NFS_COMMITBVECSIZ
-#define NFS_COMMITBVECSIZ 20
-#endif
- struct buf *bvec_on_stack[NFS_COMMITBVECSIZ];
- int bvecsize = 0, bveccount;
- bo = &vp->v_bufobj;
-
- if (nmp->nm_flag & NFSMNT_INT)
- slpflag = PCATCH;
- if (!commit)
- passone = 0;
- /*
- * A b_flags == (B_DELWRI | B_NEEDCOMMIT) block has been written to the
- * server, but nas not been committed to stable storage on the server
- * yet. On the first pass, the byte range is worked out and the commit
- * rpc is done. On the second pass, nfs_writebp() is called to do the
- * job.
- */
-again:
- off = (u_quad_t)-1;
- endoff = 0;
- bvecpos = 0;
- if (NFS_ISV3(vp) && commit) {
- if (bvec != NULL && bvec != bvec_on_stack)
- free(bvec, M_TEMP);
- /*
- * Count up how many buffers waiting for a commit.
- */
- bveccount = 0;
- BO_LOCK(bo);
- TAILQ_FOREACH_SAFE(bp, &bo->bo_dirty.bv_hd, b_bobufs, nbp) {
- if (!BUF_ISLOCKED(bp) &&
- (bp->b_flags & (B_DELWRI | B_NEEDCOMMIT))
- == (B_DELWRI | B_NEEDCOMMIT))
- bveccount++;
- }
- /*
- * Allocate space to remember the list of bufs to commit. It is
- * important to use M_NOWAIT here to avoid a race with nfs4_write.
- * If we can't get memory (for whatever reason), we will end up
- * committing the buffers one-by-one in the loop below.
- */
- if (bveccount > NFS_COMMITBVECSIZ) {
- /*
- * Release the vnode interlock to avoid a lock
- * order reversal.
- */
- BO_UNLOCK(bo);
- bvec = (struct buf **)
- malloc(bveccount * sizeof(struct buf *),
- M_TEMP, M_NOWAIT);
- BO_LOCK(bo);
- if (bvec == NULL) {
- bvec = bvec_on_stack;
- bvecsize = NFS_COMMITBVECSIZ;
- } else
- bvecsize = bveccount;
- } else {
- bvec = bvec_on_stack;
- bvecsize = NFS_COMMITBVECSIZ;
- }
- TAILQ_FOREACH_SAFE(bp, &bo->bo_dirty.bv_hd, b_bobufs, nbp) {
- if (bvecpos >= bvecsize)
- break;
- if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL)) {
- nbp = TAILQ_NEXT(bp, b_bobufs);
- continue;
- }
- if ((bp->b_flags & (B_DELWRI | B_NEEDCOMMIT)) !=
- (B_DELWRI | B_NEEDCOMMIT)) {
- BUF_UNLOCK(bp);
- nbp = TAILQ_NEXT(bp, b_bobufs);
- continue;
- }
- BO_UNLOCK(bo);
- bremfree(bp);
- /*
- * Work out if all buffers are using the same cred
- * so we can deal with them all with one commit.
- *
- * NOTE: we are not clearing B_DONE here, so we have
- * to do it later on in this routine if we intend to
- * initiate I/O on the bp.
- *
- * Note: to avoid loopback deadlocks, we do not
- * assign b_runningbufspace.
- */
- if (wcred == NULL)
- wcred = bp->b_wcred;
- else if (wcred != bp->b_wcred)
- wcred = NOCRED;
- vfs_busy_pages(bp, 1);
-
- BO_LOCK(bo);
- /*
- * bp is protected by being locked, but nbp is not
- * and vfs_busy_pages() may sleep. We have to
- * recalculate nbp.
- */
- nbp = TAILQ_NEXT(bp, b_bobufs);
-
- /*
- * A list of these buffers is kept so that the
- * second loop knows which buffers have actually
- * been committed. This is necessary, since there
- * may be a race between the commit rpc and new
- * uncommitted writes on the file.
- */
- bvec[bvecpos++] = bp;
- toff = ((u_quad_t)bp->b_blkno) * DEV_BSIZE +
- bp->b_dirtyoff;
- if (toff < off)
- off = toff;
- toff += (u_quad_t)(bp->b_dirtyend - bp->b_dirtyoff);
- if (toff > endoff)
- endoff = toff;
- }
- BO_UNLOCK(bo);
- }
- if (bvecpos > 0) {
- /*
- * Commit data on the server, as required.
- * If all bufs are using the same wcred, then use that with
- * one call for all of them, otherwise commit each one
- * separately.
- */
- if (wcred != NOCRED)
- retv = nfs4_commit(vp, off, (int)(endoff - off),
- wcred, td);
- else {
- retv = 0;
- for (i = 0; i < bvecpos; i++) {
- off_t off, size;
- bp = bvec[i];
- off = ((u_quad_t)bp->b_blkno) * DEV_BSIZE +
- bp->b_dirtyoff;
- size = (u_quad_t)(bp->b_dirtyend
- - bp->b_dirtyoff);
- retv = nfs4_commit(vp, off, (int)size,
- bp->b_wcred, td);
- if (retv) break;
- }
- }
-
- if (retv == NFSERR_STALEWRITEVERF)
- nfs_clearcommit(vp->v_mount);
-
- /*
- * Now, either mark the blocks I/O done or mark the
- * blocks dirty, depending on whether the commit
- * succeeded.
- */
- for (i = 0; i < bvecpos; i++) {
- bp = bvec[i];
- bp->b_flags &= ~(B_NEEDCOMMIT | B_CLUSTEROK);
- if (retv) {
- /*
- * Error, leave B_DELWRI intact
- */
- vfs_unbusy_pages(bp);
- brelse(bp);
- } else {
- /*
- * Success, remove B_DELWRI ( bundirty() ).
- *
- * b_dirtyoff/b_dirtyend seem to be NFS
- * specific. We should probably move that
- * into bundirty(). XXX
- */
- bufobj_wref(bo);
- bp->b_flags |= B_ASYNC;
- bundirty(bp);
- bp->b_flags &= ~B_DONE;
- bp->b_ioflags &= ~BIO_ERROR;
- bp->b_dirtyoff = bp->b_dirtyend = 0;
- bufdone(bp);
- }
- }
- }
-
- /*
- * Start/do any write(s) that are required.
- */
-loop:
- BO_LOCK(bo);
- TAILQ_FOREACH_SAFE(bp, &bo->bo_dirty.bv_hd, b_bobufs, nbp) {
- if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL)) {
- if (waitfor != MNT_WAIT || passone)
- continue;
-
- error = BUF_TIMELOCK(bp,
- LK_EXCLUSIVE | LK_SLEEPFAIL | LK_INTERLOCK,
- BO_MTX(bo), "nfsfsync", slpflag, slptimeo);
- if (error == 0)
- panic("nfs4_fsync: inconsistent lock");
- if (error == ENOLCK) {
- error = 0;
- goto loop;
- }
- if (nfs4_sigintr(nmp, NULL, td)) {
- error = EINTR;
- goto done;
- }
- if (slpflag == PCATCH) {
- slpflag = 0;
- slptimeo = 2 * hz;
- }
- goto loop;
- }
- if ((bp->b_flags & B_DELWRI) == 0)
- panic("nfs4_fsync: not dirty");
- if ((passone || !commit) && (bp->b_flags & B_NEEDCOMMIT)) {
- BUF_UNLOCK(bp);
- continue;
- }
- BO_LOCK(bo);
- bremfree(bp);
- if (passone || !commit)
- bp->b_flags |= B_ASYNC;
- else
- bp->b_flags |= B_ASYNC;
- bwrite(bp);
- goto loop;
- }
- if (passone) {
- passone = 0;
- BO_UNLOCK(bo);
- goto again;
- }
- if (waitfor == MNT_WAIT) {
- while (bo->bo_numoutput) {
- error = bufobj_wwait(bo, slpflag, slptimeo);
- if (error) {
- BO_UNLOCK(bo);
- if (nfs4_sigintr(nmp, NULL, td)) {
- error = EINTR;
- goto done;
- }
- if (slpflag == PCATCH) {
- slpflag = 0;
- slptimeo = 2 * hz;
- }
- BO_LOCK(bo);
- }
- }
- if (vp->v_bufobj.bo_dirty.bv_cnt > 0 && commit) {
- BO_UNLOCK(bo);
- goto loop;
- }
- }
- BO_UNLOCK(bo);
- if (np->n_flag & NWRITEERR) {
- error = np->n_error;
- np->n_flag &= ~NWRITEERR;
- }
-done:
- if (bvec != NULL && bvec != bvec_on_stack)
- free(bvec, M_TEMP);
- return (error);
-}
-
-/*
- * NFS advisory byte-level locks.
- */
-static int
-nfs4_advlock(struct vop_advlock_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- u_quad_t size;
- int error;
-
- return (EPERM);
-
- error = vn_lock(vp, LK_SHARED);
- if (error)
- return (error);
- if ((VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NOLOCKD) != 0) {
- size = VTONFS(vp)->n_size;
- VOP_UNLOCK(vp, 0);
- error = lf_advlock(ap, &(vp->v_lockf), size);
- } else
- error = nfs_dolock(ap);
- return (error);
-}
-
-/*
- * NFS advisory byte-level locks.
- */
-static int
-nfs4_advlockasync(struct vop_advlockasync_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- u_quad_t size;
- int error;
-
- return (EPERM);
-
- error = vn_lock(vp, LK_SHARED);
- if (error)
- return (error);
- if ((VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NOLOCKD) != 0) {
- size = VTONFS(vp)->n_size;
- VOP_UNLOCK(vp, 0);
- error = lf_advlockasync(ap, &(vp->v_lockf), size);
- } else {
- VOP_UNLOCK(vp, 0);
- error = EOPNOTSUPP;
- }
- return (error);
-}
-
-/*
- * Print out the contents of an nfsnode.
- */
-static int
-nfs4_print(struct vop_print_args *ap)
-{
- struct vnode *vp = ap->a_vp;
- struct nfsnode *np = VTONFS(vp);
-
- printf("\tfileid %ld fsid 0x%x",
- np->n_vattr.va_fileid, np->n_vattr.va_fsid);
- if (vp->v_type == VFIFO)
- fifo_printinfo(vp);
- printf("\n");
- return (0);
-}
-
-/*
- * This is the "real" nfs::bwrite(struct buf*).
- * We set B_CACHE if this is a VMIO buffer.
- */
-int
-nfs4_writebp(struct buf *bp, int force __unused, struct thread *td)
-{
- int s;
- int oldflags = bp->b_flags;
-#if 0
- int retv = 1;
- off_t off;
-#endif
-
- BUF_ASSERT_HELD(bp);
-
- if (bp->b_flags & B_INVAL) {
- brelse(bp);
- return(0);
- }
-
- bp->b_flags |= B_CACHE;
-
- /*
- * Undirty the bp. We will redirty it later if the I/O fails.
- */
-
- s = splbio();
- bundirty(bp);
- bp->b_flags &= ~B_DONE;
- bp->b_ioflags &= ~BIO_ERROR;
- bp->b_iocmd = BIO_WRITE;
-
- bufobj_wref(bp->b_bufobj);
- curthread->td_ru.ru_oublock++;
- splx(s);
-
- /*
- * Note: to avoid loopback deadlocks, we do not
- * assign b_runningbufspace.
- */
- vfs_busy_pages(bp, 1);
-
- BUF_KERNPROC(bp);
- bp->b_iooffset = dbtob(bp->b_blkno);
- bstrategy(bp);
-
- if( (oldflags & B_ASYNC) == 0) {
- int rtval = bufwait(bp);
-
- if (oldflags & B_DELWRI) {
- s = splbio();
- reassignbuf(bp);
- splx(s);
- }
-
- brelse(bp);
- return (rtval);
- }
-
- return (0);
-}
-
-/*
- * Just call nfs_writebp() with the force argument set to 1.
- *
- * NOTE: B_DONE may or may not be set in a_bp on call.
- */
-static int
-nfs4_bwrite(struct buf *bp)
-{
-
- return (nfs4_writebp(bp, 1, curthread));
-}
-
-struct buf_ops buf_ops_nfs4 = {
- .bop_name = "buf_ops_nfs4",
- .bop_write = nfs4_bwrite,
- .bop_strategy = bufstrategy,
- .bop_sync = bufsync,
- .bop_bdflush = bufbdflush,
-};
diff --git a/sys/nfs4client/nfs4m_subs.h b/sys/nfs4client/nfs4m_subs.h
deleted file mode 100644
index 60d0758..0000000
--- a/sys/nfs4client/nfs4m_subs.h
+++ /dev/null
@@ -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 */
diff --git a/sys/nfsclient/bootp_subr.c b/sys/nfsclient/bootp_subr.c
index f9bc5bf..05702f6 100644
--- a/sys/nfsclient/bootp_subr.c
+++ b/sys/nfsclient/bootp_subr.c
@@ -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>
diff --git a/sys/nfsclient/krpc_subr.c b/sys/nfsclient/krpc_subr.c
index 5682083..2023904 100644
--- a/sys/nfsclient/krpc_subr.c
+++ b/sys/nfsclient/krpc_subr.c
@@ -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>
diff --git a/sys/nfsclient/nfs.h b/sys/nfsclient/nfs.h
index 7f3a0f3..845f826 100644
--- a/sys/nfsclient/nfs.h
+++ b/sys/nfsclient/nfs.h
@@ -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
diff --git a/sys/nfsclient/nfs_bio.c b/sys/nfsclient/nfs_bio.c
index 6c468fb..92be17c 100644
--- a/sys/nfsclient/nfs_bio.c
+++ b/sys/nfsclient/nfs_bio.c
@@ -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.
diff --git a/sys/nfsclient/nfs_diskless.c b/sys/nfsclient/nfs_diskless.c
index d6d6b21..26a27b9 100644
--- a/sys/nfsclient/nfs_diskless.c
+++ b/sys/nfsclient/nfs_diskless.c
@@ -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>
diff --git a/sys/nfsclient/nfs_krpc.c b/sys/nfsclient/nfs_krpc.c
index 7f5c624..1aa398e 100644
--- a/sys/nfsclient/nfs_krpc.c
+++ b/sys/nfsclient/nfs_krpc.c
@@ -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);
diff --git a/sys/nfsclient/nfs_lock.c b/sys/nfsclient/nfs_lock.c
index 19ad066..ea6649e 100644
--- a/sys/nfsclient/nfs_lock.c
+++ b/sys/nfsclient/nfs_lock.c
@@ -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>
diff --git a/sys/nfsclient/nfs_nfsiod.c b/sys/nfsclient/nfs_nfsiod.c
index 9e0e272..7dc3f19 100644
--- a/sys/nfsclient/nfs_nfsiod.c
+++ b/sys/nfsclient/nfs_nfsiod.c
@@ -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>
diff --git a/sys/nfsclient/nfs_node.c b/sys/nfsclient/nfs_node.c
index 517c3a9..a7f00ca 100644
--- a/sys/nfsclient/nfs_node.c
+++ b/sys/nfsclient/nfs_node.c
@@ -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;
/*
diff --git a/sys/nfsclient/nfs_socket.c b/sys/nfsclient/nfs_socket.c
index 42ef655..64951fa 100644
--- a/sys/nfsclient/nfs_socket.c
+++ b/sys/nfsclient/nfs_socket.c
@@ -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) {
diff --git a/sys/nfsclient/nfs_subs.c b/sys/nfsclient/nfs_subs.c
index 1453dbf..71d4fb1 100644
--- a/sys/nfsclient/nfs_subs.c
+++ b/sys/nfsclient/nfs_subs.c
@@ -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>
diff --git a/sys/nfsclient/nfs_vfsops.c b/sys/nfsclient/nfs_vfsops.c
index d8ce36c..7d48023 100644
--- a/sys/nfsclient/nfs_vfsops.c
+++ b/sys/nfsclient/nfs_vfsops.c
@@ -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>
diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c
index 27d2c59..9f0d67a 100644
--- a/sys/nfsclient/nfs_vnops.c
+++ b/sys/nfsclient/nfs_vnops.c
@@ -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>
diff --git a/sys/nfsclient/nfsm_subs.h b/sys/nfsclient/nfsm_subs.h
index 3dd817f..51d2611 100644
--- a/sys/nfsclient/nfsm_subs.h
+++ b/sys/nfsclient/nfsm_subs.h
@@ -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 */
diff --git a/sys/nfsclient/nfsmount.h b/sys/nfsclient/nfsmount.h
index 75360fe..85f8501 100644
--- a/sys/nfsclient/nfsmount.h
+++ b/sys/nfsclient/nfsmount.h
@@ -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
diff --git a/sys/nfsclient/nfsnode.h b/sys/nfsclient/nfsnode.h
index 6f10d79..29198d8 100644
--- a/sys/nfsclient/nfsnode.h
+++ b/sys/nfsclient/nfsnode.h
@@ -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, ...);
diff --git a/sys/nlm/nlm_advlock.c b/sys/nlm/nlm_advlock.c
index a2c62f0..761ed73 100644
--- a/sys/nlm/nlm_advlock.c
+++ b/sys/nlm/nlm_advlock.c
@@ -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>
diff --git a/sys/rpc/rpcclnt.c b/sys/rpc/rpcclnt.c
deleted file mode 100644
index 1c90ff6..0000000
--- a/sys/rpc/rpcclnt.c
+++ /dev/null
@@ -1,2114 +0,0 @@
-/* $FreeBSD$ */
-/* $Id: rpcclnt.c,v 1.9 2003/11/05 14:59:03 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. 3. All advertising
- * materials mentioning features or use of this software must display the
- * following acknowledgement: This product includes software developed by the
- * University of California, Berkeley and its contributors. 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
- */
-
-/* XXX: kill ugly debug strings */
-/* XXX: get rid of proct, as it is not even being used... (or keep it so v{2,3}
- * can run, but clean it up! */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/mount.h>
-#include <sys/kernel.h>
-#include <sys/mbuf.h>
-#include <sys/syslog.h>
-#include <sys/malloc.h>
-#include <sys/uio.h>
-#include <sys/lock.h>
-#include <sys/signalvar.h>
-#include <sys/sysent.h>
-#include <sys/syscall.h>
-#include <sys/sysctl.h>
-
-#include <sys/domain.h>
-#include <sys/protosw.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/mutex.h>
-
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-
-#include <nfs/rpcv2.h>
-
-#include <rpc/rpcm_subs.h>
-#include <rpc/rpcclnt.h>
-
-/* memory management */
-#ifdef __OpenBSD__
-struct pool rpctask_pool;
-struct pool rpcclnt_pool;
-#define RPCTASKPOOL_LWM 10
-#define RPCTASKPOOL_HWM 40
-#else
-static MALLOC_DEFINE(M_RPCCLNT, "rpcclnt", "rpc state");
-#endif
-
-#define RPC_RETURN(X) do { RPCDEBUG("returning %d", X); return X; }while(0)
-
-/*
- * Estimate rto for an nfs rpc sent via. an unreliable datagram. Use the mean
- * and mean deviation of rtt for the appropriate type of rpc for the frequent
- * rpcs and a default for the others. The justification for doing "other"
- * this way is that these rpcs happen so infrequently that timer est. would
- * probably be stale. Also, since many of these rpcs are non-idempotent, a
- * conservative timeout is desired. getattr, lookup - A+2D read, write -
- * A+4D other - nm_timeo
- */
-#define RPC_RTO(n, t) \
- ((t) == 0 ? (n)->rc_timeo : \
- ((t) < 3 ? \
- (((((n)->rc_srtt[t-1] + 3) >> 2) + (n)->rc_sdrtt[t-1] + 1) >> 1) : \
- ((((n)->rc_srtt[t-1] + 7) >> 3) + (n)->rc_sdrtt[t-1] + 1)))
-
-#define RPC_SRTT(s,r) (r)->r_rpcclnt->rc_srtt[rpcclnt_proct((s),\
- (r)->r_procnum) - 1]
-
-#define RPC_SDRTT(s,r) (r)->r_rpcclnt->rc_sdrtt[rpcclnt_proct((s),\
- (r)->r_procnum) - 1]
-
-
-/*
- * There is a congestion window for outstanding rpcs maintained per mount
- * point. The cwnd size is adjusted in roughly the way that: Van Jacobson,
- * Congestion avoidance and Control, In "Proceedings of SIGCOMM '88". ACM,
- * August 1988. describes for TCP. The cwnd size is chopped in half on a
- * retransmit timeout and incremented by 1/cwnd when each rpc reply is
- * received and a full cwnd of rpcs is in progress. (The sent count and cwnd
- * are scaled for integer arith.) Variants of "slow start" were tried and
- * were found to be too much of a performance hit (ave. rtt 3 times larger),
- * I suspect due to the large rtt that nfs rpcs have.
- */
-#define RPC_CWNDSCALE 256
-#define RPC_MAXCWND (RPC_CWNDSCALE * 32)
-static const int rpcclnt_backoff[8] = {2, 4, 8, 16, 32, 64, 128, 256,};
-
-/* XXX ugly debug strings */
-#define RPC_ERRSTR_ACCEPTED_SIZE 6
-char *rpc_errstr_accepted[RPC_ERRSTR_ACCEPTED_SIZE] = {
- "", /* no good message... */
- "remote server hasn't exported program.",
- "remote server can't support version number.",
- "program can't support procedure.",
- "procedure can't decode params.",
- "remote error. remote side memory allocation failure?"
-};
-
-char *rpc_errstr_denied[2] = {
- "remote server doesnt support rpc version 2!",
- "remote server authentication error."
-};
-
-#define RPC_ERRSTR_AUTH_SIZE 6
-char *rpc_errstr_auth[RPC_ERRSTR_AUTH_SIZE] = {
- "",
- "auth error: bad credential (seal broken).",
- "auth error: client must begin new session.",
- "auth error: bad verifier (seal broken).",
- "auth error: verifier expired or replayed.",
- "auth error: rejected for security reasons.",
-};
-
-/*
- * Static data, mostly RPC constants in XDR form
- */
-static u_int32_t rpc_reply, rpc_call, rpc_vers;
-
-/*
- * rpc_msgdenied, rpc_mismatch, rpc_auth_unix, rpc_msgaccepted,
- * rpc_autherr, rpc_auth_kerb;
- */
-
-static u_int32_t rpcclnt_xid = 0;
-static u_int32_t rpcclnt_xid_touched = 0;
-struct rpcstats rpcstats;
-int rpcclnt_ticks;
-static int fake_wchan;
-
-SYSCTL_NODE(_kern, OID_AUTO, rpc, CTLFLAG_RD, 0, "RPC Subsystem");
-
-SYSCTL_UINT(_kern_rpc, OID_AUTO, retries, CTLFLAG_RD, &rpcstats.rpcretries, 0, "retries");
-SYSCTL_UINT(_kern_rpc, OID_AUTO, request, CTLFLAG_RD, &rpcstats.rpcrequests, 0, "request");
-SYSCTL_UINT(_kern_rpc, OID_AUTO, timeouts, CTLFLAG_RD, &rpcstats.rpctimeouts, 0, "timeouts");
-SYSCTL_UINT(_kern_rpc, OID_AUTO, unexpected, CTLFLAG_RD, &rpcstats.rpcunexpected, 0, "unexpected");
-SYSCTL_UINT(_kern_rpc, OID_AUTO, invalid, CTLFLAG_RD, &rpcstats.rpcinvalid, 0, "invalid");
-
-
-#ifdef RPCCLNT_DEBUG
-int rpcdebugon = 0;
-SYSCTL_UINT(_kern_rpc, OID_AUTO, debug_on, CTLFLAG_RW, &rpcdebugon, 0, "RPC Debug messages");
-#endif
-
-/*
- * Queue head for rpctask's
- */
-static
-TAILQ_HEAD(, rpctask) rpctask_q;
-struct callout rpcclnt_callout;
-
-#ifdef __OpenBSD__
-static int rpcclnt_send(struct socket *, struct mbuf *, struct mbuf *, struct rpctask *);
-static int rpcclnt_receive(struct rpctask *, struct mbuf **, struct mbuf **, RPC_EXEC_CTX);
-#else
-static int rpcclnt_send(struct socket *, struct sockaddr *, struct mbuf *, struct rpctask *);
-static int rpcclnt_receive(struct rpctask *, struct sockaddr **, struct mbuf **, RPC_EXEC_CTX);
-#endif
-
-static int rpcclnt_msg(RPC_EXEC_CTX, const char *, char *);
-
-static int rpcclnt_reply(struct rpctask *, RPC_EXEC_CTX);
-static void rpcclnt_timer(void *);
-static int rpcclnt_sndlock(int *, struct rpctask *);
-static void rpcclnt_sndunlock(int *);
-static int rpcclnt_rcvlock(struct rpctask *);
-static void rpcclnt_rcvunlock(int *);
-#if 0
-void rpcclnt_realign(struct mbuf *, int);
-#else
-static void rpcclnt_realign(struct mbuf **, int);
-#endif
-
-static struct mbuf *rpcclnt_buildheader(struct rpcclnt *, int, struct mbuf *, u_int32_t, int *, struct mbuf **, struct ucred *);
-static int rpcm_disct(struct mbuf **, caddr_t *, int, int, caddr_t *);
-static u_int32_t rpcclnt_proct(struct rpcclnt *, u_int32_t);
-static int rpc_adv(struct mbuf **, caddr_t *, int, int);
-static void rpcclnt_softterm(struct rpctask * task);
-
-static int rpcauth_buildheader(struct rpc_auth * auth, struct ucred *, struct mbuf **, caddr_t *);
-
-void
-rpcclnt_init(void)
-{
-#ifdef __OpenBSD__
- static struct timeout rpcclnt_timer_to;
-#endif
-
- rpcclnt_ticks = (hz * RPC_TICKINTVL + 500) / 1000;
- if (rpcclnt_ticks < 1)
- rpcclnt_ticks = 1;
- rpcstats.rpcretries = 0;
- rpcstats.rpcrequests = 0;
- rpcstats.rpctimeouts = 0;
- rpcstats.rpcunexpected = 0;
- rpcstats.rpcinvalid = 0;
-
- /*
- * rpc constants how about actually using more than one of these!
- */
-
- rpc_reply = txdr_unsigned(RPC_REPLY);
- rpc_vers = txdr_unsigned(RPC_VER2);
- rpc_call = txdr_unsigned(RPC_CALL);
-#if 0
- rpc_msgdenied = txdr_unsigned(RPC_MSGDENIED);
- rpc_msgaccepted = txdr_unsigned(RPC_MSGACCEPTED);
- rpc_mismatch = txdr_unsigned(RPC_MISMATCH);
- rpc_autherr = txdr_unsigned(RPC_AUTHERR);
- rpc_auth_unix = txdr_unsigned(RPCAUTH_UNIX);
- rpc_auth_kerb = txdr_unsigned(RPCAUTH_KERB4);
-#endif
-
- /* initialize rpctask queue */
- TAILQ_INIT(&rpctask_q);
-
-#ifdef __OpenBSD__
- /* initialize pools */
- pool_init(&rpctask_pool, sizeof(struct rpctask), 0, 0, RPCTASKPOOL_LWM,
- "rpctask_p", NULL);
- pool_setlowat(&rpctask_pool, RPCTASKPOOL_LWM);
- pool_sethiwat(&rpctask_pool, RPCTASKPOOL_HWM);
-
- pool_init(&rpcclnt_pool, sizeof(struct rpcclnt), 0, 0, 1, "rpcclnt_p", NULL);
-
- /* initialize timers */
- timeout_set(&rpcclnt_timer_to, rpcclnt_timer, &rpcclnt_timer_to);
- rpcclnt_timer(&rpcclnt_timer_to);
-#else /* !__OpenBSD__ */
- callout_init(&rpcclnt_callout, 0);
-#endif /* !__OpenBSD__ */
-
- RPCDEBUG("rpc initialed");
-
- return;
-}
-
-void
-rpcclnt_uninit(void)
-{
- RPCDEBUG("uninit");
- /* XXX delete sysctl variables? */
- callout_stop(&rpcclnt_callout);
-}
-
-int
-rpcclnt_setup(clnt, program, addr, sotype, soproto, auth, max_read_size, max_write_size, flags)
- struct rpcclnt * clnt;
- struct rpc_program * program;
- struct sockaddr * addr;
- int sotype;
- int soproto;
- struct rpc_auth * auth;
- int max_read_size;
- int max_write_size;
- int flags;
-{
- if (clnt == NULL || program == NULL || addr == NULL || auth == NULL)
- RPC_RETURN (EFAULT);
-
- if (program->prog_name == NULL)
- RPC_RETURN (EFAULT);
- clnt->rc_prog = program;
-
- clnt->rc_name = addr;
- clnt->rc_sotype = sotype;
- clnt->rc_soproto = soproto;
- clnt->rc_auth = auth;
- clnt->rc_rsize = max_read_size;
- clnt->rc_wsize = max_write_size;
- clnt->rc_flag = flags;
-
- clnt->rc_proctlen = 0;
- clnt->rc_proct = NULL;
-
- RPC_RETURN (0);
-}
-
-/*
- * Initialize sockets and congestion for a new RPC connection. We do not free
- * the sockaddr if error.
- */
-int
-rpcclnt_connect(rpc, td)
- struct rpcclnt *rpc;
- RPC_EXEC_CTX td;
-{
- struct socket *so;
- int s, error, rcvreserve, sndreserve;
- struct sockaddr *saddr;
-
-#ifdef __OpenBSD__
- struct sockaddr_in *sin;
- struct mbuf *m;
-#else
- struct sockaddr_in sin;
-
- int soarg;
- struct sockopt opt;
-#endif
-
- if (rpc == NULL) {
- RPCDEBUG("no rpcclnt struct!\n");
- RPC_RETURN(EFAULT);
- }
-
- /* create the socket */
- rpc->rc_so = NULL;
-
- saddr = rpc->rc_name;
-
- error = socreate(saddr->sa_family, &rpc->rc_so, rpc->rc_sotype,
- rpc->rc_soproto, td->td_ucred, td);
- if (error) {
- RPCDEBUG("error %d in socreate()", error);
- RPC_RETURN(error);
- }
- so = rpc->rc_so;
- rpc->rc_soflags = so->so_proto->pr_flags;
-
- /*
- * Some servers require that the client port be a reserved port
- * number. We always allocate a reserved port, as this prevents
- * filehandle disclosure through UDP port capture.
- */
- if (saddr->sa_family == AF_INET) {
-#ifdef __OpenBSD__
- struct mbuf *mopt;
- int *ip;
-#endif
-
-#ifdef __OpenBSD__
- MGET(mopt, M_TRYWAIT, MT_SOOPTS);
- mopt->m_len = sizeof(int);
- ip = mtod(mopt, int *);
- *ip = IP_PORTRANGE_LOW;
-
- error = sosetopt(so, IPPROTO_IP, IP_PORTRANGE, mopt);
-#else
- soarg = IP_PORTRANGE_LOW;
- bzero(&opt, sizeof(struct sockopt));
- opt.sopt_dir = SOPT_SET;
- opt.sopt_level = IPPROTO_IP;
- opt.sopt_name = IP_PORTRANGE;
- opt.sopt_val = &soarg;
- opt.sopt_valsize = sizeof(soarg);
-
- error = sosetopt(so, &opt);
-#endif
- if (error)
- goto bad;
-
-#ifdef __OpenBSD__
- MGET(m, M_TRYWAIT, MT_SONAME);
- sin = mtod(m, struct sockaddr_in *);
- sin->sin_len = m->m_len = sizeof(struct sockaddr_in);
- sin->sin_family = AF_INET;
- sin->sin_addr.s_addr = INADDR_ANY;
- sin->sin_port = htons(0);
- error = sobind(so, m);
- m_freem(m);
-#else
- sin.sin_len = sizeof(struct sockaddr_in);
- sin.sin_family = AF_INET;
- sin.sin_addr.s_addr = INADDR_ANY;
- sin.sin_port = htons(0);
- /*
- * &thread0 gives us root credentials to ensure sobind
- * will give us a reserved ephemeral port.
- */
- error = sobind(so, (struct sockaddr *) & sin, &thread0);
-#endif
- if (error)
- goto bad;
-
-#ifdef __OpenBSD__
- MGET(mopt, M_TRYWAIT, MT_SOOPTS);
- mopt->m_len = sizeof(int);
- ip = mtod(mopt, int *);
- *ip = IP_PORTRANGE_DEFAULT;
- error = sosetopt(so, IPPROTO_IP, IP_PORTRANGE, mopt);
-#else
- soarg = IP_PORTRANGE_DEFAULT;
- bzero(&opt, sizeof(struct sockopt));
- opt.sopt_dir = SOPT_SET;
- opt.sopt_level = IPPROTO_IP;
- opt.sopt_name = IP_PORTRANGE;
- opt.sopt_val = &soarg;
- opt.sopt_valsize = sizeof(soarg);
- error = sosetopt(so, &opt);
-#endif
- if (error)
- goto bad;
- }
- /*
- * Protocols that do not require connections may be optionally left
- * unconnected for servers that reply from a port other than
- * NFS_PORT.
- */
- if (rpc->rc_flag & RPCCLNT_NOCONN) {
- if (rpc->rc_soflags & PR_CONNREQUIRED) {
- error = ENOTCONN;
- goto bad;
- }
- } else {
- error = soconnect(so, saddr, td);
- if (error)
- goto bad;
-
- /*
- * Wait for the connection to complete. Cribbed from the
- * connect system call but with the wait timing out so that
- * interruptible mounts don't hang here for a long time.
- */
-#ifdef __OpenBSD__
- s = splsoftnet();
-#else
- s = splnet();
-#endif
- while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) {
- (void)tsleep((caddr_t) & so->so_timeo, PSOCK,
- "rpc", 2 * hz);
-
- /*
- * XXX needs to catch interrupt signals. something
- * like this: if ((so->so_state & SS_ISCONNECTING) &&
- * so->so_error == 0 && rep && (error =
- * nfs_sigintr(nmp, rep, rep->r_td)) != 0) {
- * so->so_state &= ~SS_ISCONNECTING; splx(s); goto
- * bad; }
- */
- }
- if (so->so_error) {
- error = so->so_error;
- so->so_error = 0;
- splx(s);
- goto bad;
- }
- splx(s);
- }
- if (rpc->rc_flag & (RPCCLNT_SOFT | RPCCLNT_INT)) {
- so->so_rcv.sb_timeo = (5 * hz);
- so->so_snd.sb_timeo = (5 * hz);
- } else {
- so->so_rcv.sb_timeo = 0;
- so->so_snd.sb_timeo = 0;
- }
-
-
- if (rpc->rc_sotype == SOCK_DGRAM) {
- sndreserve = rpc->rc_wsize + RPC_MAXPKTHDR;
- rcvreserve = rpc->rc_rsize + RPC_MAXPKTHDR;
- } else if (rpc->rc_sotype == SOCK_SEQPACKET) {
- sndreserve = (rpc->rc_wsize + RPC_MAXPKTHDR) * 2;
- rcvreserve = (rpc->rc_rsize + RPC_MAXPKTHDR) * 2;
- } else {
- if (rpc->rc_sotype != SOCK_STREAM)
- panic("rpcclnt_connect() bad sotype");
- if (so->so_proto->pr_flags & PR_CONNREQUIRED) {
-#ifdef __OpenBSD__
- MGET(m, M_TRYWAIT, MT_SOOPTS);
- *mtod(m, int32_t *) = 1;
- m->m_len = sizeof(int32_t);
- sosetopt(so, SOL_SOCKET, SO_KEEPALIVE, m);
-#else
- soarg = 1;
-
- bzero(&opt, sizeof(struct sockopt));
- opt.sopt_dir = SOPT_SET;
- opt.sopt_level = SOL_SOCKET;
- opt.sopt_name = SO_KEEPALIVE;
- opt.sopt_val = &soarg;
- opt.sopt_valsize = sizeof(soarg);
- sosetopt(so, &opt);
-#endif
- }
- if (so->so_proto->pr_protocol == IPPROTO_TCP) {
-#ifdef __OpenBSD__
- MGET(m, M_TRYWAIT, MT_SOOPTS);
- *mtod(m, int32_t *) = 1;
- m->m_len = sizeof(int32_t);
- sosetopt(so, IPPROTO_TCP, TCP_NODELAY, m);
-#else
- soarg = 1;
-
- bzero(&opt, sizeof(struct sockopt));
- opt.sopt_dir = SOPT_SET;
- opt.sopt_level = IPPROTO_TCP;
- opt.sopt_name = TCP_NODELAY;
- opt.sopt_val = &soarg;
- opt.sopt_valsize = sizeof(soarg);
- sosetopt(so, &opt);
-#endif
- }
- sndreserve = (rpc->rc_wsize + RPC_MAXPKTHDR +
- sizeof(u_int32_t)) * 2;
- rcvreserve = (rpc->rc_rsize + RPC_MAXPKTHDR +
- sizeof(u_int32_t)) * 2;
- }
- error = soreserve(so, sndreserve, rcvreserve);
- if (error)
- goto bad;
- so->so_rcv.sb_flags |= SB_NOINTR;
- so->so_snd.sb_flags |= SB_NOINTR;
-
- /* Initialize other non-zero congestion variables */
- rpc->rc_srtt[0] = rpc->rc_srtt[1] = rpc->rc_srtt[2] =
- rpc->rc_srtt[3] = (RPC_TIMEO << 3);
- rpc->rc_sdrtt[0] = rpc->rc_sdrtt[1] = rpc->rc_sdrtt[2] =
- rpc->rc_sdrtt[3] = 0;
- rpc->rc_cwnd = RPC_MAXCWND / 2; /* Initial send window */
- rpc->rc_sent = 0;
- rpc->rc_timeouts = 0;
- RPC_RETURN(0);
-
-bad:
- rpcclnt_disconnect(rpc);
- RPC_RETURN(error);
-}
-
-
-/*
- * Reconnect routine:
- * Called when a connection is broken on a reliable protocol.
- * - clean up the old socket
- * - rpcclnt_connect() again
- * - set R_MUSTRESEND for all outstanding requests on mount point
- * If this fails the mount point is DEAD!
- * nb: Must be called with the rpcclnt_sndlock() set on the mount point.
- */
-int
-rpcclnt_reconnect(rep, td)
- struct rpctask *rep;
- RPC_EXEC_CTX td;
-{
- struct rpctask *rp;
- struct rpcclnt *rpc = rep->r_rpcclnt;
- int error;
-
- rpcclnt_disconnect(rpc);
- while ((error = rpcclnt_connect(rpc, td)) != 0) {
- if (error == EINTR || error == ERESTART)
- RPC_RETURN(EINTR);
- tsleep(&fake_wchan, PSOCK, "rpccon", hz);
- }
-
- /*
- * Loop through outstanding request list and fix up all requests on
- * old socket.
- */
- for (rp = TAILQ_FIRST(&rpctask_q); rp != NULL;
- rp = TAILQ_NEXT(rp, r_chain)) {
- if (rp->r_rpcclnt == rpc)
- rp->r_flags |= R_MUSTRESEND;
- }
- RPC_RETURN(0);
-}
-
-/*
- * RPC transport disconnect. Clean up and unlink.
- */
-void
-rpcclnt_disconnect(rpc)
- struct rpcclnt *rpc;
-{
- struct socket *so;
-
- if (rpc->rc_so) {
- so = rpc->rc_so;
- rpc->rc_so = NULL;
- soshutdown(so, 2);
- soclose(so);
- }
-}
-
-void
-rpcclnt_safedisconnect(struct rpcclnt * rpc)
-{
- struct rpctask dummytask;
-
- bzero(&dummytask, sizeof(dummytask));
- dummytask.r_rpcclnt = rpc;
- rpcclnt_rcvlock(&dummytask);
- rpcclnt_disconnect(rpc);
- rpcclnt_rcvunlock(&rpc->rc_flag);
-}
-
-/*
- * This is the rpc send routine. For connection based socket types, it
- * must be called with an rpcclnt_sndlock() on the socket.
- * "rep == NULL" indicates that it has been called from a server.
- * For the client side:
- * - return EINTR if the RPC is terminated, 0 otherwise
- * - set R_MUSTRESEND if the send fails for any reason
- * - do any cleanup required by recoverable socket errors (?)
- * For the server side:
- * - return EINTR or ERESTART if interrupted by a signal
- * - return EPIPE if a connection is lost for connection based sockets (TCP...)
- * - do any cleanup required by recoverable socket errors (?)
- */
-static int
-rpcclnt_send(so, nam, top, rep)
- struct socket *so;
-#ifdef __OpenBSD__
- struct mbuf *nam;
-#else
- struct sockaddr *nam;
-#endif
- struct mbuf *top;
- struct rpctask *rep;
-{
-#ifdef __OpenBSD__
- struct mbuf *sendnam;
-#else
- struct sockaddr *sendnam;
- struct thread *td = curthread;
-#endif
- int error, soflags, flags;
-
- if (rep) {
- if (rep->r_flags & R_SOFTTERM) {
- m_freem(top);
- RPC_RETURN(EINTR);
- }
- if ((so = rep->r_rpcclnt->rc_so) == NULL) {
- rep->r_flags |= R_MUSTRESEND;
- m_freem(top);
- RPC_RETURN(0);
- }
- rep->r_flags &= ~R_MUSTRESEND;
- soflags = rep->r_rpcclnt->rc_soflags;
- } else
- soflags = so->so_proto->pr_flags;
-
- if ((soflags & PR_CONNREQUIRED) || (so->so_state & SS_ISCONNECTED))
- sendnam = NULL;
- else
- sendnam = nam;
-
- if (so->so_type == SOCK_SEQPACKET)
- flags = MSG_EOR;
- else
- flags = 0;
-
- /*
- * XXXRW: If/when this code becomes MPSAFE itself, Giant might have
- * to be conditionally acquired earlier for the stack so has to avoid
- * lock order reversals with any locks held over rpcclnt_send().
- */
- error = sosend(so, sendnam, NULL, top, NULL, flags, td);
- if (error) {
- if (rep) {
- log(LOG_INFO, "rpc send error %d for service %s\n", error,
- rep->r_rpcclnt->rc_prog->prog_name);
- /*
- * Deal with errors for the client side.
- */
- if (rep->r_flags & R_SOFTTERM)
- error = EINTR;
- else
- rep->r_flags |= R_MUSTRESEND;
- } else
- log(LOG_INFO, "rpc service send error %d\n", error);
-
- /*
- * Handle any recoverable (soft) socket errors here.
- */
- if (error != EINTR && error != ERESTART &&
- error != EWOULDBLOCK && error != EPIPE)
- error = 0;
- }
- RPC_RETURN(error);
-}
-
-/*
- * Receive a Sun RPC Request/Reply. For SOCK_DGRAM, the work is all done by
- * soreceive(), but for SOCK_STREAM we must deal with the Record Mark and
- * consolidate the data into a new mbuf list. nb: Sometimes TCP passes the
- * data up to soreceive() in long lists of small mbufs. For SOCK_STREAM we
- * must be very careful to read an entire record once we have read any of it,
- * even if the system call has been interrupted.
- */
-static int
-rpcclnt_receive(rep, aname, mp, td)
- struct rpctask *rep;
-#ifdef __OpenBSD__
- struct mbuf **aname;
-#else
- struct sockaddr **aname;
-#endif
- struct mbuf **mp;
- RPC_EXEC_CTX td;
-{
- struct socket *so;
- struct uio auio;
- struct iovec aio;
- struct mbuf *m;
- struct mbuf *control;
- u_int32_t len;
-#ifdef __OpenBSD__
- struct mbuf **getnam;
-#else
- struct sockaddr **getnam;
-#endif
- int error, sotype, rcvflg;
-
- /*
- * Set up arguments for soreceive()
- */
- *mp = NULL;
- *aname = NULL;
- sotype = rep->r_rpcclnt->rc_sotype;
-
- /*
- * For reliable protocols, lock against other senders/receivers in
- * case a reconnect is necessary. For SOCK_STREAM, first get the
- * Record Mark to find out how much more there is to get. We must
- * lock the socket against other receivers until we have an entire
- * rpc request/reply.
- */
- if (sotype != SOCK_DGRAM) {
- error = rpcclnt_sndlock(&rep->r_rpcclnt->rc_flag, rep);
- if (error)
- RPC_RETURN(error);
-tryagain:
- /*
- * Check for fatal errors and resending request.
- */
- /*
- * Ugh: If a reconnect attempt just happened, rc_so would
- * have changed. NULL indicates a failed attempt that has
- * essentially shut down this mount point.
- */
- if (rep->r_mrep || (rep->r_flags & R_SOFTTERM)) {
- rpcclnt_sndunlock(&rep->r_rpcclnt->rc_flag);
- RPC_RETURN(EINTR);
- }
- so = rep->r_rpcclnt->rc_so;
- if (!so) {
- error = rpcclnt_reconnect(rep, td);
- if (error) {
- rpcclnt_sndunlock(&rep->r_rpcclnt->rc_flag);
- RPC_RETURN(error);
- }
- goto tryagain;
- }
- while (rep->r_flags & R_MUSTRESEND) {
- m = m_copym(rep->r_mreq, 0, M_COPYALL, M_WAIT);
- rpcstats.rpcretries++;
- error = rpcclnt_send(so, rep->r_rpcclnt->rc_name, m, rep);
- if (error) {
- if (error == EINTR || error == ERESTART ||
- (error = rpcclnt_reconnect(rep, td)) != 0) {
- rpcclnt_sndunlock(&rep->r_rpcclnt->rc_flag);
- RPC_RETURN(error);
- }
- goto tryagain;
- }
- }
- rpcclnt_sndunlock(&rep->r_rpcclnt->rc_flag);
- if (sotype == SOCK_STREAM) {
- aio.iov_base = (caddr_t) & len;
- aio.iov_len = sizeof(u_int32_t);
- auio.uio_iov = &aio;
- auio.uio_iovcnt = 1;
- auio.uio_segflg = UIO_SYSSPACE;
- auio.uio_rw = UIO_READ;
- auio.uio_offset = 0;
- auio.uio_resid = sizeof(u_int32_t);
-#ifdef __OpenBSD__
- auio.uio_procp = td;
-#else
- auio.uio_td = td;
-#endif
- do {
- rcvflg = MSG_WAITALL;
- error = soreceive(so, NULL, &auio, NULL, NULL, &rcvflg);
- if (error == EWOULDBLOCK && rep) {
- if (rep->r_flags & R_SOFTTERM)
- RPC_RETURN(EINTR);
- }
- } while (error == EWOULDBLOCK);
- if (!error && auio.uio_resid > 0) {
- log(LOG_INFO,
- "short receive (%zu/%zu) from rpc server %s\n",
- sizeof(u_int32_t) - auio.uio_resid,
- sizeof(u_int32_t),
- rep->r_rpcclnt->rc_prog->prog_name);
- error = EPIPE;
- }
- if (error)
- goto errout;
- len = ntohl(len) & ~0x80000000;
- /*
- * This is SERIOUS! We are out of sync with the
- * sender and forcing a disconnect/reconnect is all I
- * can do.
- */
- if (len > RPC_MAXPACKET) {
- log(LOG_ERR, "%s (%d) from rpc server %s\n",
- "impossible packet length",
- len,
- rep->r_rpcclnt->rc_prog->prog_name);
- error = EFBIG;
- goto errout;
- }
- auio.uio_resid = len;
- do {
- rcvflg = MSG_WAITALL;
- error = soreceive(so, NULL, &auio, mp, NULL, &rcvflg);
- } while (error == EWOULDBLOCK || error == EINTR ||
- error == ERESTART);
- if (!error && auio.uio_resid > 0) {
- log(LOG_INFO,
- "short receive (%d/%d) from rpc server %s\n",
- len - auio.uio_resid, len,
- rep->r_rpcclnt->rc_prog->prog_name);
- error = EPIPE;
- }
- } else {
- /*
- * NB: Since uio_resid is big, MSG_WAITALL is ignored
- * and soreceive() will return when it has either a
- * control msg or a data msg. We have no use for
- * control msg., but must grab them and then throw
- * them away so we know what is going on.
- */
- auio.uio_resid = len = 100000000; /* Anything Big */
-#ifdef __OpenBSD__
- auio.uio_procp = td;
-#else
- auio.uio_td = td;
-#endif
- do {
- rcvflg = 0;
- error = soreceive(so, NULL, &auio, mp, &control, &rcvflg);
- if (control)
- m_freem(control);
- if (error == EWOULDBLOCK && rep) {
- if (rep->r_flags & R_SOFTTERM)
- RPC_RETURN(EINTR);
- }
- } while (error == EWOULDBLOCK ||
- (!error && *mp == NULL && control));
- if ((rcvflg & MSG_EOR) == 0)
- printf("Egad!!\n");
- if (!error && *mp == NULL)
- error = EPIPE;
- len -= auio.uio_resid;
- }
-errout:
- if (error && error != EINTR && error != ERESTART) {
- m_freem(*mp);
- *mp = (struct mbuf *) 0;
- if (error != EPIPE)
- log(LOG_INFO,
- "receive error %d from rpc server %s\n",
- error,
- rep->r_rpcclnt->rc_prog->prog_name);
- error = rpcclnt_sndlock(&rep->r_rpcclnt->rc_flag, rep);
- if (!error)
- error = rpcclnt_reconnect(rep, td);
- if (!error)
- goto tryagain;
- }
- } else {
- if ((so = rep->r_rpcclnt->rc_so) == NULL)
- RPC_RETURN(EACCES);
- if (so->so_state & SS_ISCONNECTED)
- getnam = NULL;
- else
- getnam = aname;
- auio.uio_resid = len = 1000000;
-#ifdef __OpenBSD__
- auio.uio_procp = td;
-#else
- auio.uio_td = td;
-#endif
-
- do {
- rcvflg = 0;
- error = soreceive(so, getnam, &auio, mp, NULL, &rcvflg);
- RPCDEBUG("soreceive returns %d", error);
- if (error == EWOULDBLOCK && (rep->r_flags & R_SOFTTERM)) {
- RPCDEBUG("wouldblock && softerm -> EINTR");
- RPC_RETURN(EINTR);
- }
- } while (error == EWOULDBLOCK);
- len -= auio.uio_resid;
- }
- if (error) {
- m_freem(*mp);
- *mp = NULL;
- } else {
- /*
- * Search for any mbufs that are not a multiple of 4 bytes
- * long or with m_data not longword aligned. These could
- * cause pointer alignment problems, so copy them to well
- * aligned mbufs.
- */
- rpcclnt_realign(mp, 5 * RPCX_UNSIGNED);
- }
- RPC_RETURN(error);
-}
-
-
-/*
- * Implement receipt of reply on a socket. We must search through the list of
- * received datagrams matching them with outstanding requests using the xid,
- * until ours is found.
- */
-/* ARGSUSED */
-static int
-rpcclnt_reply(myrep, td)
- struct rpctask *myrep;
- RPC_EXEC_CTX td;
-{
- struct rpctask *rep;
- struct rpcclnt *rpc = myrep->r_rpcclnt;
- int32_t t1;
- struct mbuf *mrep, *md;
-#ifdef __OpenBSD__
- struct mbuf *nam;
-#else
- struct sockaddr *nam;
-#endif
- u_int32_t rxid, *tl;
- caddr_t dpos, cp2;
- int error;
-
- /*
- * Loop around until we get our own reply
- */
- for (;;) {
- /*
- * Lock against other receivers so that I don't get stuck in
- * sbwait() after someone else has received my reply for me.
- * Also necessary for connection based protocols to avoid
- * race conditions during a reconnect.
- */
- error = rpcclnt_rcvlock(myrep);
- if (error)
- RPC_RETURN(error);
- /* Already received, bye bye */
- if (myrep->r_mrep != NULL) {
- rpcclnt_rcvunlock(&rpc->rc_flag);
- RPC_RETURN(0);
- }
- /*
- * Get the next Rpc reply off the socket
- */
- error = rpcclnt_receive(myrep, &nam, &mrep, td);
-
- rpcclnt_rcvunlock(&rpc->rc_flag);
-
- if (error) {
- /*
- * Ignore routing errors on connectionless
- * protocols??
- */
- if (RPCIGNORE_SOERROR(rpc->rc_soflags, error)) {
- rpc->rc_so->so_error = 0;
- if (myrep->r_flags & R_GETONEREP)
- RPC_RETURN(0);
- RPCDEBUG("ingoring routing error on connectionless protocol.");
- continue;
- }
- RPC_RETURN(error);
- }
-#ifdef __OpenBSD__
- if (nam)
- m_freem(nam);
-#else
- if (nam)
- free(nam, M_SONAME);
-#endif
-
- /*
- * Get the xid and check that it is an rpc reply
- */
- md = mrep;
- dpos = mtod(md, caddr_t);
- rpcm_dissect(tl, u_int32_t *, 2 * RPCX_UNSIGNED);
- rxid = *tl++;
- if (*tl != rpc_reply) {
- rpcstats.rpcinvalid++;
- m_freem(mrep);
-rpcmout:
- if (myrep->r_flags & R_GETONEREP)
- RPC_RETURN(0);
- continue;
- }
- /*
- * Loop through the request list to match up the reply Iff no
- * match, just drop the datagram
- */
- TAILQ_FOREACH(rep, &rpctask_q, r_chain) {
- if (rep->r_mrep == NULL && rxid == rep->r_xid) {
- /* Found it.. */
- rep->r_mrep = mrep;
- rep->r_md = md;
- rep->r_dpos = dpos;
-
- /*
- * Update congestion window. Do the additive
- * increase of one rpc/rtt.
- */
- if (rpc->rc_cwnd <= rpc->rc_sent) {
- rpc->rc_cwnd +=
- (RPC_CWNDSCALE * RPC_CWNDSCALE +
- (rpc->rc_cwnd >> 1)) / rpc->rc_cwnd;
- if (rpc->rc_cwnd > RPC_MAXCWND)
- rpc->rc_cwnd = RPC_MAXCWND;
- }
- rep->r_flags &= ~R_SENT;
- rpc->rc_sent -= RPC_CWNDSCALE;
- /*
- * Update rtt using a gain of 0.125 on the
- * mean and a gain of 0.25 on the deviation.
- */
- if (rep->r_flags & R_TIMING) {
- /*
- * Since the timer resolution of
- * NFS_HZ is so course, it can often
- * result in r_rtt == 0. Since r_rtt
- * == N means that the actual rtt is
- * between N+dt and N+2-dt ticks, add
- * 1.
- */
- t1 = rep->r_rtt + 1;
- t1 -= (RPC_SRTT(rpc, rep) >> 3);
- RPC_SRTT(rpc, rep) += t1;
- if (t1 < 0)
- t1 = -t1;
- t1 -= (RPC_SDRTT(rpc, rep) >> 2);
- RPC_SDRTT(rpc, rep) += t1;
- }
- rpc->rc_timeouts = 0;
- break;
- }
- }
- /*
- * If not matched to a request, drop it. If it's mine, get
- * out.
- */
- if (rep == 0) {
- rpcstats.rpcunexpected++;
- RPCDEBUG("rpc reply not matched\n");
- m_freem(mrep);
- } else if (rep == myrep) {
- if (rep->r_mrep == NULL)
- panic("rpcreply nil");
- RPC_RETURN(0);
- }
- if (myrep->r_flags & R_GETONEREP)
- RPC_RETURN(0);
- }
-}
-
-/* XXX: ignores tryagain! */
-/*
- * code from nfs_request - goes something like this
- * - fill in task struct
- * - links task into list
- * - calls rpcclnt_send() for first transmit
- * - calls rpcclnt_reply() to get reply
- * - fills in reply (which should be initialized prior to
- * calling), which is valid when 0 is returned and is
- * NEVER freed in this function
- *
- * nb: always frees the request header, but NEVER frees 'mrest'
- *
- * rpcclnt_setauth() should be used before calling this. EAUTH is returned if
- * authentication fails.
- *
- * note that reply->result_* are invalid unless reply->type ==
- * RPC_MSGACCEPTED and reply->status == RPC_SUCCESS and that reply->verf_*
- * are invalid unless reply->type == RPC_MSGACCEPTED
- */
-int
-rpcclnt_request(rpc, mrest, procnum, td, cred, reply)
- struct rpcclnt *rpc;
- struct mbuf *mrest;
- int procnum;
- RPC_EXEC_CTX td;
- struct ucred *cred;
- struct rpc_reply *reply;
-{
- struct mbuf *m, *mrep;
- struct rpctask *task;
- u_int32_t *tl;
- struct mbuf *md, *mheadend;
- caddr_t dpos, cp2;
- int t1, s, error = 0, mrest_len;
- u_int32_t xid;
-
-#ifdef __OpenBSD__
- task = pool_get(&rpctask_pool, PR_WAITOK);
-#else
- task = malloc(sizeof(struct rpctask), M_RPCCLNT, (M_WAITOK | M_ZERO));
-#endif
-
- task->r_rpcclnt = rpc;
- task->r_procnum = procnum;
- task->r_td = td;
-
- mrest_len = m_length(mrest, NULL);
-
- m = rpcclnt_buildheader(rpc, procnum, mrest, mrest_len, &xid, &mheadend,
- cred);
- /*
- * This can happen if the auth_type is neither UNIX or NULL
- */
- if (m == NULL) {
-#ifdef __OpenBSD__
- pool_put(&rpctask_pool, task);
-#else
- free(task, M_RPCCLNT);
-#endif
- error = EPROTONOSUPPORT;
- goto rpcmout;
- }
-
- /*
- * For stream protocols, insert a Sun RPC Record Mark.
- */
- if (rpc->rc_sotype == SOCK_STREAM) {
- M_PREPEND(m, RPCX_UNSIGNED, M_WAIT);
- *mtod(m, u_int32_t *) = htonl(0x80000000 |
- (m->m_pkthdr.len - RPCX_UNSIGNED));
- }
- task->r_mreq = m;
- task->r_xid = xid;
-
- if (rpc->rc_flag & RPCCLNT_SOFT)
- task->r_retry = rpc->rc_retry;
- else
- task->r_retry = RPC_MAXREXMIT + 1; /* past clip limit */
- task->r_rtt = task->r_rexmit = 0;
-
- if (rpcclnt_proct(rpc, procnum) > 0)
- task->r_flags = R_TIMING;
- else
- task->r_flags = 0;
- task->r_mrep = NULL;
-
- /*
- * Do the client side RPC.
- */
- rpcstats.rpcrequests++;
-
- /*
- * Chain request into list of outstanding requests. Be sure to put it
- * LAST so timer finds oldest requests first.
- */
- s = splsoftclock();
- if (TAILQ_EMPTY(&rpctask_q))
- callout_reset(&rpcclnt_callout, rpcclnt_ticks, rpcclnt_timer,
- NULL);
- TAILQ_INSERT_TAIL(&rpctask_q, task, r_chain);
-
- /*
- * If backing off another request or avoiding congestion, don't send
- * this one now but let timer do it. If not timing a request, do it
- * now.
- */
- if (rpc->rc_so && (rpc->rc_sotype != SOCK_DGRAM ||
- (rpc->rc_flag & RPCCLNT_DUMBTIMR) ||
- rpc->rc_sent < rpc->rc_cwnd)) {
- splx(s);
-
- if (rpc->rc_soflags & PR_CONNREQUIRED)
- error = rpcclnt_sndlock(&rpc->rc_flag, task);
- if (!error) {
- error = rpcclnt_send(rpc->rc_so, rpc->rc_name,
- m_copym(m, 0, M_COPYALL, M_WAIT),
- task);
- if (rpc->rc_soflags & PR_CONNREQUIRED)
- rpcclnt_sndunlock(&rpc->rc_flag);
- }
- if (!error && (task->r_flags & R_MUSTRESEND) == 0) {
- rpc->rc_sent += RPC_CWNDSCALE;
- task->r_flags |= R_SENT;
- }
- } else {
- splx(s);
- task->r_rtt = -1;
- }
-
- /*
- * Wait for the reply from our send or the timer's.
- */
- if (!error || error == EPIPE)
- error = rpcclnt_reply(task, td);
-
- /*
- * RPC done, unlink the request.
- */
- s = splsoftclock();
- TAILQ_REMOVE(&rpctask_q, task, r_chain);
- if (TAILQ_EMPTY(&rpctask_q))
- callout_stop(&rpcclnt_callout);
- splx(s);
-
- /*
- * Decrement the outstanding request count.
- */
- if (task->r_flags & R_SENT) {
- task->r_flags &= ~R_SENT; /* paranoia */
- rpc->rc_sent -= RPC_CWNDSCALE;
- }
- /*
- * If there was a successful reply and a tprintf msg. tprintf a
- * response.
- */
- if (!error && (task->r_flags & R_TPRINTFMSG)) {
- mtx_lock(&Giant);
- rpcclnt_msg(task->r_td, rpc->rc_prog->prog_name,
- "is alive again");
- mtx_unlock(&Giant);
- }
-
- /* free request header (leaving mrest) */
- mheadend->m_next = NULL;
- m_freem(task->r_mreq);
-
- /* initialize reply */
- reply->mrep = task->r_mrep;
- reply->verf_md = NULL;
- reply->result_md = NULL;
-
- mrep = task->r_mrep;
- md = task->r_md;
- dpos = task->r_dpos;
-
- /* task structure is no longer needed */
-#ifdef __OpenBSD__
- pool_put(&rpctask_pool, task);
-#else
- free(task, M_RPCCLNT);
-#endif
-
- if (error)
- goto rpcmout;
-
- /*
- * break down the rpc header and check if ok
- */
-
- rpcm_dissect(tl, u_int32_t *, RPCX_UNSIGNED);
- reply->stat.type = fxdr_unsigned(u_int32_t, *tl);
-
- if (reply->stat.type == RPC_MSGDENIED) {
- rpcm_dissect(tl, u_int32_t *, RPCX_UNSIGNED);
- reply->stat.status = fxdr_unsigned(u_int32_t, *tl);
-
- switch (reply->stat.status) {
- case RPC_MISMATCH:
- rpcm_dissect(tl, u_int32_t *, 2 * RPCX_UNSIGNED);
- reply->stat.mismatch_info.low = fxdr_unsigned(u_int32_t, *tl++);
- reply->stat.mismatch_info.high = fxdr_unsigned(u_int32_t, *tl);
- error = EOPNOTSUPP;
- break;
- case RPC_AUTHERR:
- rpcm_dissect(tl, u_int32_t *, RPCX_UNSIGNED);
- reply->stat.autherr = fxdr_unsigned(u_int32_t, *tl);
- error = EACCES;
- break;
- default:
- error = EBADRPC;
- break;
- }
- goto rpcmout;
- } else if (reply->stat.type != RPC_MSGACCEPTED) {
- error = EBADRPC;
- goto rpcmout;
- }
-
- rpcm_dissect(tl, u_int32_t *, 2 * RPCX_UNSIGNED);
-
- reply->verf_md = md;
- reply->verf_dpos = dpos;
-
- reply->verf_type = fxdr_unsigned(u_int32_t, *tl++);
- reply->verf_size = fxdr_unsigned(u_int32_t, *tl);
-
- if (reply->verf_size != 0)
- rpcm_adv(rpcm_rndup(reply->verf_size));
-
- rpcm_dissect(tl, u_int32_t *, RPCX_UNSIGNED);
- reply->stat.status = fxdr_unsigned(u_int32_t, *tl);
-
- if (reply->stat.status == RPC_SUCCESS) {
- if ((uint32_t)(dpos - mtod(md, caddr_t)) >= md->m_len) {
- RPCDEBUG("where is the next mbuf?");
- RPCDEBUG("%d -> %d",
- (int)(dpos - mtod(md, caddr_t)), md->m_len);
- if (md->m_next == NULL) {
- error = EBADRPC;
- goto rpcmout;
- } else {
- reply->result_md = md->m_next;
- reply->result_dpos = mtod(reply->result_md,
- caddr_t);
- }
- } else {
- reply->result_md = md;
- reply->result_dpos = dpos;
- }
- } else if (reply->stat.status == RPC_PROGMISMATCH) {
- rpcm_dissect(tl, u_int32_t *, 2 * RPCX_UNSIGNED);
- reply->stat.mismatch_info.low = fxdr_unsigned(u_int32_t, *tl++);
- reply->stat.mismatch_info.high = fxdr_unsigned(u_int32_t, *tl);
- error = EOPNOTSUPP;
- goto rpcmout;
- } else {
- error = EPROTONOSUPPORT;
- goto rpcmout;
- }
- error = 0;
-
-rpcmout:
- RPC_RETURN(error);
-}
-
-
-/*
- * RPC timer routine
- * Scan the rpctask list and retranmit any requests that have timed out.
- * To avoid retransmission attempts on STREAM sockets (in the future) make
- * sure to set the r_retry field to 0 (implies nm_retry == 0).
- */
-void
-rpcclnt_timer(arg)
- void *arg;
-{
-#ifdef __OpenBSD__
- struct timeout *to = (struct timeout *) arg;
-#endif
- struct rpctask *rep;
- struct mbuf *m;
- struct socket *so;
- struct rpcclnt *rpc;
- int timeo;
- int s, error;
-
-#ifndef __OpenBSD__
- struct thread *td = curthread;
-#endif
-
-#ifdef __OpenBSD__
- s = splsoftnet();
-#else
- s = splnet();
-#endif
- mtx_lock(&Giant); /* rpc_msg -> tprintf */
- TAILQ_FOREACH(rep, &rpctask_q, r_chain) {
- rpc = rep->r_rpcclnt;
- if (rep->r_mrep || (rep->r_flags & R_SOFTTERM))
- continue;
- if (rpcclnt_sigintr(rpc, rep, rep->r_td)) {
- rep->r_flags |= R_SOFTTERM;
- continue;
- }
- if (rep->r_rtt >= 0) {
- rep->r_rtt++;
- if (rpc->rc_flag & RPCCLNT_DUMBTIMR)
- timeo = rpc->rc_timeo;
- else
- timeo = RPC_RTO(rpc, rpcclnt_proct(rep->r_rpcclnt,
- rep->r_procnum));
- if (rpc->rc_timeouts > 0)
- timeo *= rpcclnt_backoff[rpc->rc_timeouts - 1];
- if (rep->r_rtt <= timeo)
- continue;
- if (rpc->rc_timeouts < 8)
- rpc->rc_timeouts++;
- }
- /*
- * Check for server not responding
- */
- if ((rep->r_flags & R_TPRINTFMSG) == 0 &&
- rep->r_rexmit > rpc->rc_deadthresh) {
- rpcclnt_msg(rep->r_td, rpc->rc_prog->prog_name,
- "not responding");
- rep->r_flags |= R_TPRINTFMSG;
- }
- if (rep->r_rexmit >= rep->r_retry) { /* too many */
- rpcstats.rpctimeouts++;
- rep->r_flags |= R_SOFTTERM;
- continue;
- }
- if (rpc->rc_sotype != SOCK_DGRAM) {
- if (++rep->r_rexmit > RPC_MAXREXMIT)
- rep->r_rexmit = RPC_MAXREXMIT;
- continue;
- }
- if ((so = rpc->rc_so) == NULL)
- continue;
-
- /*
- * If there is enough space and the window allows.. Resend it
- * Set r_rtt to -1 in case we fail to send it now.
- */
- rep->r_rtt = -1;
- if (sbspace(&so->so_snd) >= rep->r_mreq->m_pkthdr.len &&
- ((rpc->rc_flag & RPCCLNT_DUMBTIMR) ||
- (rep->r_flags & R_SENT) ||
- rpc->rc_sent < rpc->rc_cwnd) &&
- (m = m_copym(rep->r_mreq, 0, M_COPYALL, M_DONTWAIT))) {
- if ((rpc->rc_flag & RPCCLNT_NOCONN) == 0)
- error = (*so->so_proto->pr_usrreqs->pru_send) (so, 0, m,
- NULL, NULL, td);
- else
- error = (*so->so_proto->pr_usrreqs->pru_send)(so, 0, m, rpc->rc_name, NULL, td);
- if (error) {
- if (RPCIGNORE_SOERROR(rpc->rc_soflags, error))
- so->so_error = 0;
- } else {
- /*
- * Iff first send, start timing else turn
- * timing off, backoff timer and divide
- * congestion window by 2.
- */
- if (rep->r_flags & R_SENT) {
- rep->r_flags &= ~R_TIMING;
- if (++rep->r_rexmit > RPC_MAXREXMIT)
- rep->r_rexmit = RPC_MAXREXMIT;
- rpc->rc_cwnd >>= 1;
- if (rpc->rc_cwnd < RPC_CWNDSCALE)
- rpc->rc_cwnd = RPC_CWNDSCALE;
- rpcstats.rpcretries++;
- } else {
- rep->r_flags |= R_SENT;
- rpc->rc_sent += RPC_CWNDSCALE;
- }
- rep->r_rtt = 0;
- }
- }
- }
- mtx_unlock(&Giant); /* rpc_msg -> tprintf */
- splx(s);
-
-#ifdef __OpenBSD__
- timeout_add(rpcclnt_timer, to, rpcclnt_ticks);
-#else
- callout_reset(&rpcclnt_callout, rpcclnt_ticks, rpcclnt_timer, NULL);
-#endif
-}
-
-/*
- * Test for a termination condition pending on the process. This is used for
- * RPCCLNT_INT mounts.
- */
-int
-rpcclnt_sigintr(rpc, task, pr)
- struct rpcclnt *rpc;
- struct rpctask *task;
- RPC_EXEC_CTX pr;
-{
- struct proc *p;
-
- sigset_t tmpset;
-
- if (rpc == NULL)
- return EFAULT;
-
- /* XXX deal with forced unmounts */
-
- if (task && (task->r_flags & R_SOFTTERM))
- RPC_RETURN(EINTR);
-
- if (!(rpc->rc_flag & RPCCLNT_INT))
- RPC_RETURN(0);
-
- if (pr == NULL)
- return (0);
-
-#ifdef __OpenBSD__
- p = pr;
- if (p && p->p_siglist &&
- (((p->p_siglist & ~p->p_sigmask) & ~p->p_sigignore) &
- RPCINT_SIGMASK))
- RPC_RETURN(EINTR);
-#else
- p = pr->td_proc;
- PROC_LOCK(p);
- tmpset = p->p_siglist;
- SIGSETNAND(tmpset, pr->td_sigmask);
- mtx_lock(&p->p_sigacts->ps_mtx);
- SIGSETNAND(tmpset, p->p_sigacts->ps_sigignore);
- mtx_unlock(&p->p_sigacts->ps_mtx);
- if (SIGNOTEMPTY(p->p_siglist) && RPCCLNTINT_SIGMASK(tmpset)) {
- PROC_UNLOCK(p);
- RPC_RETURN(EINTR);
- }
- PROC_UNLOCK(p);
-#endif
- RPC_RETURN(0);
-}
-
-/*
- * Lock a socket against others. Necessary for STREAM sockets to ensure you
- * get an entire rpc request/reply and also to avoid race conditions between
- * the processes with nfs requests in progress when a reconnect is necessary.
- */
-static int
-rpcclnt_sndlock(flagp, task)
- int *flagp;
- struct rpctask *task;
-{
- RPC_EXEC_CTX p;
- int slpflag = 0, slptimeo = 0;
-
- p = task->r_td;
- if (task->r_rpcclnt->rc_flag & RPCCLNT_INT)
- slpflag = PCATCH;
- while (*flagp & RPCCLNT_SNDLOCK) {
- if (rpcclnt_sigintr(task->r_rpcclnt, task, p))
- RPC_RETURN(EINTR);
- *flagp |= RPCCLNT_WANTSND;
- (void)tsleep((caddr_t) flagp, slpflag | (PZERO - 1), "rpcsndlck",
- slptimeo);
- if (slpflag == PCATCH) {
- slpflag = 0;
- slptimeo = 2 * hz;
- }
- }
- *flagp |= RPCCLNT_SNDLOCK;
- RPC_RETURN(0);
-}
-
-/*
- * Unlock the stream socket for others.
- */
-static void
-rpcclnt_sndunlock(flagp)
- int *flagp;
-{
-
- if ((*flagp & RPCCLNT_SNDLOCK) == 0)
- panic("rpc sndunlock");
- *flagp &= ~RPCCLNT_SNDLOCK;
- if (*flagp & RPCCLNT_WANTSND) {
- *flagp &= ~RPCCLNT_WANTSND;
- wakeup((caddr_t) flagp);
- }
-}
-
-static int
-rpcclnt_rcvlock(task)
- struct rpctask *task;
-{
- int *flagp = &task->r_rpcclnt->rc_flag;
- int slpflag, slptimeo = 0;
-
- if (*flagp & RPCCLNT_INT)
- slpflag = PCATCH;
- else
- slpflag = 0;
- while (*flagp & RPCCLNT_RCVLOCK) {
- if (rpcclnt_sigintr(task->r_rpcclnt, task, task->r_td))
- RPC_RETURN(EINTR);
- *flagp |= RPCCLNT_WANTRCV;
- (void)tsleep((caddr_t) flagp, slpflag | (PZERO - 1), "rpcrcvlk",
- slptimeo);
- if (slpflag == PCATCH) {
- slpflag = 0;
- slptimeo = 2 * hz;
- }
- }
- *flagp |= RPCCLNT_RCVLOCK;
- RPC_RETURN(0);
-}
-
-/*
- * Unlock the stream socket for others.
- */
-static void
-rpcclnt_rcvunlock(flagp)
- int *flagp;
-{
-
- if ((*flagp & RPCCLNT_RCVLOCK) == 0)
- panic("nfs rcvunlock");
- *flagp &= ~RPCCLNT_RCVLOCK;
- if (*flagp & RPCCLNT_WANTRCV) {
- *flagp &= ~RPCCLNT_WANTRCV;
- wakeup((caddr_t) flagp);
- }
-}
-
-#if 0
-/*
- * Check for badly aligned mbuf data areas and realign data in an mbuf list
- * by copying the data areas up, as required.
- */
-void
-rpcclnt_realign(m, hsiz)
- struct mbuf *m;
- int hsiz;
-{
- struct mbuf *m2;
- int siz, mlen, olen;
- caddr_t tcp, fcp;
- struct mbuf *mnew;
-
- while (m) {
- /*
- * This never happens for UDP, rarely happens for TCP but
- * frequently happens for iso transport.
- */
- if ((m->m_len & 0x3) || (mtod(m, long)&0x3)) {
- olen = m->m_len;
- fcp = mtod(m, caddr_t);
- if ((long)fcp & 0x3) {
- if (m->m_flags & M_PKTHDR)
- m_tag_delete_chain(m, NULL);
- m->m_flags &= ~M_PKTHDR;
- if (m->m_flags & M_EXT)
- m->m_data = m->m_ext.ext_buf +
- ((m->m_ext.ext_size - olen) & ~0x3);
- else
- m->m_data = m->m_dat;
- }
- m->m_len = 0;
- tcp = mtod(m, caddr_t);
- mnew = m;
- m2 = m->m_next;
-
- /*
- * If possible, only put the first invariant part of
- * the RPC header in the first mbuf.
- */
- mlen = M_TRAILINGSPACE(m);
- if (olen <= hsiz && mlen > hsiz)
- mlen = hsiz;
-
- /* Loop through the mbuf list consolidating data. */
- while (m) {
- while (olen > 0) {
- if (mlen == 0) {
- if (m2->m_flags & M_PKTHDR)
- m_tag_delete_chain(m2, NULL);
- m2->m_flags &= ~M_PKTHDR;
- if (m2->m_flags & M_EXT)
- m2->m_data = m2->m_ext.ext_buf;
- else
- m2->m_data = m2->m_dat;
- m2->m_len = 0;
- mlen = M_TRAILINGSPACE(m2);
- tcp = mtod(m2, caddr_t);
- mnew = m2;
- m2 = m2->m_next;
- }
- siz = min(mlen, olen);
- if (tcp != fcp)
- bcopy(fcp, tcp, siz);
- mnew->m_len += siz;
- mlen -= siz;
- olen -= siz;
- tcp += siz;
- fcp += siz;
- }
- m = m->m_next;
- if (m) {
- olen = m->m_len;
- fcp = mtod(m, caddr_t);
- }
- }
-
- /*
- * Finally, set m_len == 0 for any trailing mbufs
- * that have been copied out of.
- */
- while (m2) {
- m2->m_len = 0;
- m2 = m2->m_next;
- }
- return;
- }
- m = m->m_next;
- }
-}
-#else
-static void
-rpcclnt_realign(struct mbuf **pm, int hsiz)
-{
- struct mbuf *m;
- struct mbuf *n = NULL;
- int off = 0;
-
- RPCDEBUG("in rpcclnt_realign()");
-
- while ((m = *pm) != NULL) {
- if ((m->m_len & 0x3) || (mtod(m, intptr_t) & 0x3)) {
- MGET(n, M_WAIT, MT_DATA);
- if (m->m_len >= MINCLSIZE) {
- MCLGET(n, M_WAIT);
- }
- n->m_len = 0;
- break;
- }
- pm = &m->m_next;
- }
-
- /*
- * If n is non-NULL, loop on m copying data, then replace the
- * portion of the chain that had to be realigned.
- */
- if (n != NULL) {
- while (m) {
- m_copyback(n, off, m->m_len, mtod(m, caddr_t));
- off += m->m_len;
- m = m->m_next;
- }
- m_freem(*pm);
- *pm = n;
- }
-
- RPCDEBUG("leave rpcclnt_realign()");
-}
-#endif
-
-static int
-rpcclnt_msg(p, server, msg)
- RPC_EXEC_CTX p;
- const char *server;
- char *msg;
-{
-#ifdef __OpenBSD__
- tpr_t tpr;
- struct proc *pr = p;
-
- if (p)
- tpr = tprintf_open(p);
- else
- tpr = NULL;
- tprintf(tpr, "rpc server %s: %s\n", server, msg);
- tprintf_close(tpr);
- RPC_RETURN(0);
-#else
- GIANT_REQUIRED;
-
- tprintf(p ? p->td_proc : NULL, LOG_INFO,
- "nfs server %s: %s\n", server, msg);
- RPC_RETURN(0);
-#endif
-}
-
-/*
- * Build the RPC header and fill in the authorization info. The authorization
- * string argument is only used when the credentials come from outside of the
- * kernel (AUTH_KERB). (likewise, the ucred is only used when inside the
- * kernel) Returns the head of the mbuf list.
- */
-static struct mbuf *
-rpcclnt_buildheader(rc, procid, mrest, mrest_len, xidp, mheadend, cred)
- struct rpcclnt *rc;
- int procid;
- struct mbuf *mrest;
- u_int32_t mrest_len;
- int *xidp;
- struct mbuf **mheadend;
- struct ucred * cred;
-{
- /* register */ struct mbuf *mb;
- register u_int32_t *tl;
- /* register */ caddr_t bpos;
- struct mbuf *mreq, *mb2;
- int error;
-
- MGETHDR(mb, M_WAIT, MT_DATA);
- if (6 * RPCX_UNSIGNED >= MINCLSIZE) {
- MCLGET(mb, M_WAIT);
- } else if (6 * RPCX_UNSIGNED < MHLEN) {
- MH_ALIGN(mb, 6 * RPCX_UNSIGNED);
- } else {
- RPCDEBUG("mbuf too small");
- panic("cheap bailout");
- }
- mb->m_len = 0;
- mreq = mb;
- bpos = mtod(mb, caddr_t);
-
- /*
- * First the RPC header.
- */
- rpcm_build(tl, u_int32_t *, 6 * RPCX_UNSIGNED);
-
- /* Get a new (non-zero) xid */
- if ((rpcclnt_xid == 0) && (rpcclnt_xid_touched == 0)) {
- rpcclnt_xid = arc4random();
- rpcclnt_xid_touched = 1;
- } else {
- while ((*xidp = arc4random() % 256) == 0);
- rpcclnt_xid += *xidp;
- }
-
- /* XXX: funky... */
- *tl++ = *xidp = txdr_unsigned(rpcclnt_xid);
-
- *tl++ = rpc_call;
- *tl++ = rpc_vers;
- *tl++ = txdr_unsigned(rc->rc_prog->prog_id);
- *tl++ = txdr_unsigned(rc->rc_prog->prog_version);
- *tl++ = txdr_unsigned(procid);
-
- if ((error = rpcauth_buildheader(rc->rc_auth, cred, &mb, &bpos))) {
- m_freem(mreq);
- RPCDEBUG("rpcauth_buildheader failed %d", error);
- return NULL;
- }
-
- mb->m_next = mrest;
- *mheadend = mb;
- mreq->m_pkthdr.len = m_length(mreq, NULL);
- mreq->m_pkthdr.rcvif = NULL;
- return (mreq);
-}
-
-/*
- * Help break down an mbuf chain by setting the first siz bytes contiguous
- * pointed to by returned val. This is used by the macros rpcm_dissect and
- * rpcm_dissecton for tough cases. (The macros use the vars. dpos and dpos2)
- */
-static int
-rpcm_disct(mdp, dposp, siz, left, cp2)
- struct mbuf **mdp;
- caddr_t *dposp;
- int siz;
- int left;
- caddr_t *cp2;
-{
- struct mbuf *mp, *mp2;
- int siz2, xfer;
- caddr_t p;
-
- mp = *mdp;
- while (left == 0) {
- *mdp = mp = mp->m_next;
- if (mp == NULL)
- RPC_RETURN(EBADRPC);
- left = mp->m_len;
- *dposp = mtod(mp, caddr_t);
- }
- if (left >= siz) {
- *cp2 = *dposp;
- *dposp += siz;
- } else if (mp->m_next == NULL) {
- RPC_RETURN(EBADRPC);
- } else if (siz > MHLEN) {
- panic("rpc S too big");
- } else {
- MGET(mp2, M_WAIT, MT_DATA);
- mp2->m_next = mp->m_next;
- mp->m_next = mp2;
- mp->m_len -= left;
- mp = mp2;
- *cp2 = p = mtod(mp, caddr_t);
- bcopy(*dposp, p, left); /* Copy what was left */
- siz2 = siz - left;
- p += left;
- mp2 = mp->m_next;
- /* Loop around copying up the siz2 bytes */
- while (siz2 > 0) {
- if (mp2 == NULL)
- RPC_RETURN(EBADRPC);
- xfer = (siz2 > mp2->m_len) ? mp2->m_len : siz2;
- if (xfer > 0) {
- bcopy(mtod(mp2, caddr_t), p, xfer);
- RPCMADV(mp2, xfer);
- mp2->m_len -= xfer;
- p += xfer;
- siz2 -= xfer;
- }
- if (siz2 > 0)
- mp2 = mp2->m_next;
- }
- mp->m_len = siz;
- *mdp = mp2;
- *dposp = mtod(mp2, caddr_t);
- }
- RPC_RETURN(0);
-}
-
-
-
-static u_int32_t
-rpcclnt_proct(rpc, procid)
- struct rpcclnt *rpc;
- u_int32_t procid;
-{
- if (rpc->rc_proctlen != 0 && rpc->rc_proct != NULL &&
- procid < rpc->rc_proctlen) {
- return rpc->rc_proct[procid];
- }
- return (0);
-}
-
-static int
-rpc_adv(mdp, dposp, offs, left)
- struct mbuf **mdp;
- caddr_t *dposp;
- int offs;
- int left;
-{
- struct mbuf *m;
- int s;
-
- m = *mdp;
- s = left;
- while (s < offs) {
- offs -= s;
- m = m->m_next;
- if (m == NULL)
- RPC_RETURN(EBADRPC);
- s = m->m_len;
- }
- *mdp = m;
- *dposp = mtod(m, caddr_t) + offs;
- RPC_RETURN(0);
-}
-
-int
-rpcclnt_cancelreqs(rpc)
- struct rpcclnt *rpc;
-{
- struct rpctask *task;
- int i, s;
-
- s = splnet();
- TAILQ_FOREACH(task, &rpctask_q, r_chain) {
- if (rpc != task->r_rpcclnt || task->r_mrep != NULL ||
- (task->r_flags & R_SOFTTERM))
- continue;
- rpcclnt_softterm(task);
- }
- splx(s);
-
- for (i = 0; i < 30; i++) {
- s = splnet();
- TAILQ_FOREACH(task, &rpctask_q, r_chain) {
- if (rpc == task->r_rpcclnt)
- break;
- }
- splx(s);
- if (task == NULL)
- return (0);
- tsleep(&fake_wchan, PSOCK, "nfscancel", hz);
- }
- return (EBUSY);
-}
-
-static void
-rpcclnt_softterm(struct rpctask * task)
-{
- task->r_flags |= R_SOFTTERM;
- if (task->r_flags & R_SENT) {
- task->r_rpcclnt->rc_sent -= RPC_CWNDSCALE;
- task->r_flags &= ~R_SENT;
- }
-}
-
-
-#ifndef __OpenBSD__
-/* called by rpcclnt_get() */
-void
-rpcclnt_create(struct rpcclnt ** rpc)
-{
- *rpc = malloc(sizeof(struct rpcclnt), M_RPCCLNT, M_WAITOK | M_ZERO);
-}
-
-/* called by rpcclnt_put() */
-void
-rpcclnt_destroy(struct rpcclnt * rpc)
-{
- if (rpc != NULL) {
- free(rpc, M_RPCCLNT);
- } else {
- RPCDEBUG("attempting to free a NULL rpcclnt (not dereferenced)");
- }
-}
-#endif /* !__OpenBSD__ */
-
-
-/* XXX: add a lock around the auth structure in struct rpcclnt and make this
- * call safe for calling durring a connection */
-static int
-rpcauth_buildheader(struct rpc_auth * auth, struct ucred * cred, struct mbuf ** mhdr, caddr_t * bp)
-{
- size_t authsiz, verfsiz;
- uint32_t mlen, grpsiz;
- register struct mbuf *mb, *mb2;
- caddr_t bpos;
- register u_int32_t *tl;
- register int i;
-
- if (auth == NULL || mhdr == NULL)
- return EFAULT;
-
- switch (auth->auth_type) {
- case RPCAUTH_NULL:
- authsiz = 0;
- verfsiz = 0;
- break;
- case RPCAUTH_UNIX:
- authsiz = (5 + cred->cr_ngroups) * RPCX_UNSIGNED;
- verfsiz = 0;
- break;
- default:
- return EPROTONOSUPPORT;
- break;
- };
-
- mlen = rpcm_rndup(authsiz) + rpcm_rndup(verfsiz) + 4 * RPCX_UNSIGNED;
-
- mb = *mhdr;
- bpos = *bp;
-
- rpcm_build(tl, u_int32_t *, mlen);
-
- *bp = bpos;
- *mhdr = mb;
-
- *tl++ = txdr_unsigned(auth->auth_type);
- *tl++ = txdr_unsigned(authsiz);
- switch (auth->auth_type) {
- case RPCAUTH_UNIX:
- *tl++ = 0;
- *tl++ = 0;
-
- *tl++ = txdr_unsigned(cred->cr_uid);
- *tl++ = txdr_unsigned(cred->cr_groups[0]);
- grpsiz = cred->cr_ngroups;
- *tl++ = txdr_unsigned(grpsiz);
- /* XXX: groups[0] is already sent... */
- for (i = 0 ; i < grpsiz ; i++) {
- *tl++ = txdr_unsigned(cred->cr_groups[i]);
- }
-
- /* null verification header */
- *tl++ = txdr_unsigned(RPCAUTH_NULL);
- *tl++ = 0;
- break;
- case RPCAUTH_NULL:
- /* just a null verf header */
- *tl++ = txdr_unsigned(RPCAUTH_NULL);
- *tl = 0;
- break;
- default:
- panic("inconsistent rpc auth type");
- break;
- }
-
- return 0;
-}
diff --git a/sys/rpc/rpcclnt.h b/sys/rpc/rpcclnt.h
deleted file mode 100644
index f57c4dc..0000000
--- a/sys/rpc/rpcclnt.h
+++ /dev/null
@@ -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_ */
OpenPOWER on IntegriCloud