Remove the unmaintained University of Michigan NFSv4 client from 8.x
prior to 8.0-RELEASE. Rick Macklem's new and more feature-rich NFSv234 client and server are replacing it. Discussed with: rmacklem
This commit is contained in:
parent
9ce13065db
commit
86ce6a83d1
@ -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"
|
@ -36,7 +36,6 @@ SUBDIR= adjkerntz \
|
||||
ggate \
|
||||
growfs \
|
||||
gvinum \
|
||||
idmapd \
|
||||
ifconfig \
|
||||
init \
|
||||
${_ipf} \
|
||||
|
@ -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>
|
@ -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
|
@ -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);
|
||||
}
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -1,27 +1,3 @@
|
||||
/*
|
||||
* copyright (c) 2003
|
||||
* the regents of the university of michigan
|
||||
* all rights reserved
|
||||
*
|
||||
* permission is granted to use, copy, create derivative works and redistribute
|
||||
* this software and such derivative works for any purpose, so long as the name
|
||||
* of the university of michigan is not used in any advertising or publicity
|
||||
* pertaining to the use or distribution of this software without specific,
|
||||
* written prior authorization. if the above copyright notice or any other
|
||||
* identification of the university of michigan is included in any copy of any
|
||||
* portion of this software, then the disclaimer below must also be included.
|
||||
*
|
||||
* this software is provided as is, without representation from the university
|
||||
* of michigan as to its fitness for any purpose, and without warranty by the
|
||||
* university of michigan of any kind, either express or implied, including
|
||||
* without limitation the implied warranties of merchantability and fitness for
|
||||
* a particular purpose. the regents of the university of michigan shall not be
|
||||
* liable for any damages, including special, indirect, incidental, or
|
||||
* consequential damages, with respect to any claim arising out of or in
|
||||
* connection with the use of the software, even if it has been or is hereafter
|
||||
* advised of the possibility of such damages.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
@ -140,7 +116,6 @@ enum mountmode {
|
||||
ANY,
|
||||
V2,
|
||||
V3,
|
||||
V4
|
||||
} mountmode = ANY;
|
||||
|
||||
/* Return codes for nfs_tryproto. */
|
||||
@ -155,7 +130,6 @@ int fallback_mount(struct iovec *iov, int iovlen, int mntflags);
|
||||
int sec_name_to_num(char *sec);
|
||||
char *sec_num_to_name(int num);
|
||||
int getnfsargs(char *, struct iovec **iov, int *iovlen);
|
||||
int getnfs4args(char *, struct iovec **iov, int *iovlen);
|
||||
/* void set_rpc_maxgrouplist(int); */
|
||||
struct netconfig *getnetconf_cached(const char *netid);
|
||||
const char *netidbytype(int af, int sotype);
|
||||
@ -164,8 +138,6 @@ int xdr_dir(XDR *, char *);
|
||||
int xdr_fh(XDR *, struct nfhret *);
|
||||
enum tryret nfs_tryproto(struct addrinfo *ai, char *hostp, char *spec,
|
||||
char **errstr, struct iovec **iov, int *iovlen);
|
||||
enum tryret nfs4_tryproto(struct addrinfo *ai, char *hostp, char *spec,
|
||||
char **errstr);
|
||||
enum tryret returncode(enum clnt_stat stat, struct rpc_err *rpcerr);
|
||||
extern int getosreldate(void);
|
||||
|
||||
@ -190,15 +162,8 @@ main(int argc, char *argv[])
|
||||
|
||||
++fstype;
|
||||
|
||||
if (strcmp(fstype, "nfs4") == 0) {
|
||||
nfsproto = IPPROTO_TCP;
|
||||
portspec = "2049";
|
||||
build_iovec(&iov, &iovlen, "tcp", NULL, 0);
|
||||
mountmode = V4;
|
||||
}
|
||||
|
||||
while ((c = getopt(argc, argv,
|
||||
"234a:bcdD:g:I:iLlNo:PR:r:sTt:w:x:U")) != -1)
|
||||
"23a:bcdD:g:I:iLlNo:PR:r:sTt:w:x:U")) != -1)
|
||||
switch (c) {
|
||||
case '2':
|
||||
mountmode = V2;
|
||||
@ -206,10 +171,6 @@ main(int argc, char *argv[])
|
||||
case '3':
|
||||
mountmode = V3;
|
||||
break;
|
||||
case '4':
|
||||
mountmode = V4;
|
||||
fstype = "nfs4";
|
||||
break;
|
||||
case 'a':
|
||||
printf("-a deprecated, use -o readhead=<value>\n");
|
||||
build_iovec(&iov, &iovlen, "readahead", optarg, (size_t)-1);
|
||||
@ -301,10 +262,6 @@ main(int argc, char *argv[])
|
||||
mountmode = V2;
|
||||
} else if (strcmp(opt, "nfsv3") == 0) {
|
||||
mountmode = V3;
|
||||
} else if (strcmp(opt, "nfsv4") == 0) {
|
||||
pass_flag_to_nmount=0;
|
||||
mountmode = V4;
|
||||
fstype = "nfs4";
|
||||
} else if (strcmp(opt, "port") == 0) {
|
||||
pass_flag_to_nmount=0;
|
||||
asprintf(&portspec, "%d",
|
||||
@ -406,13 +363,8 @@ main(int argc, char *argv[])
|
||||
/* The default is to keep retrying forever. */
|
||||
retrycnt = 0;
|
||||
|
||||
if (mountmode == V4) {
|
||||
if (!getnfs4args(spec, &iov, &iovlen))
|
||||
exit(1);
|
||||
} else {
|
||||
if (!getnfsargs(spec, &iov, &iovlen))
|
||||
exit(1);
|
||||
}
|
||||
if (!getnfsargs(spec, &iov, &iovlen))
|
||||
exit(1);
|
||||
|
||||
/* resolve the mountpoint with realpath(3) */
|
||||
(void)checkpath(name, mntpath);
|
||||
@ -814,129 +766,6 @@ getnfsargs(char *spec, struct iovec **iov, int *iovlen)
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
getnfs4args(char *spec, struct iovec **iov, int *iovlen)
|
||||
{
|
||||
struct addrinfo hints, *ai_nfs, *ai;
|
||||
enum tryret ret;
|
||||
int ecode, speclen, remoteerr, sotype;
|
||||
char *hostp, *delimp, *errstr;
|
||||
size_t len;
|
||||
static char nam[MNAMELEN + 1];
|
||||
|
||||
if (nfsproto == IPPROTO_TCP)
|
||||
sotype = SOCK_STREAM;
|
||||
else if (nfsproto == IPPROTO_UDP)
|
||||
sotype = SOCK_DGRAM;
|
||||
|
||||
|
||||
if ((delimp = strrchr(spec, ':')) != NULL) {
|
||||
hostp = spec;
|
||||
spec = delimp + 1;
|
||||
} else if ((delimp = strrchr(spec, '@')) != NULL) {
|
||||
warnx("path@server syntax is deprecated, use server:path");
|
||||
hostp = delimp + 1;
|
||||
} else {
|
||||
warnx("no <host>:<dirpath> nfs-name");
|
||||
return (0);
|
||||
}
|
||||
*delimp = '\0';
|
||||
|
||||
/*
|
||||
* If there has been a trailing slash at mounttime it seems
|
||||
* that some mountd implementations fail to remove the mount
|
||||
* entries from their mountlist while unmounting.
|
||||
*/
|
||||
for (speclen = strlen(spec);
|
||||
speclen > 1 && spec[speclen - 1] == '/';
|
||||
speclen--)
|
||||
spec[speclen - 1] = '\0';
|
||||
if (strlen(hostp) + strlen(spec) + 1 > MNAMELEN) {
|
||||
warnx("%s:%s: %s", hostp, spec, strerror(ENAMETOOLONG));
|
||||
return (0);
|
||||
}
|
||||
/* Make both '@' and ':' notations equal */
|
||||
if (*hostp != '\0') {
|
||||
len = strlen(hostp);
|
||||
memmove(nam, hostp, len);
|
||||
nam[len] = ':';
|
||||
memmove(nam + len + 1, spec, speclen);
|
||||
nam[len + speclen + 1] = '\0';
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle an internet host address.
|
||||
*/
|
||||
memset(&hints, 0, sizeof hints);
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
hints.ai_socktype = sotype;
|
||||
if (getaddrinfo(hostp, portspec, &hints, &ai_nfs) != 0) {
|
||||
hints.ai_flags = 0;
|
||||
if ((ecode = getaddrinfo(hostp, portspec, &hints, &ai_nfs))
|
||||
!= 0) {
|
||||
if (portspec == NULL)
|
||||
errx(1, "%s: %s", hostp, gai_strerror(ecode));
|
||||
else
|
||||
errx(1, "%s:%s: %s", hostp, portspec,
|
||||
gai_strerror(ecode));
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
ret = TRYRET_LOCALERR;
|
||||
for (;;) {
|
||||
/*
|
||||
* Try each entry returned by getaddrinfo(). Note the
|
||||
* occurence of remote errors by setting `remoteerr'.
|
||||
*/
|
||||
remoteerr = 0;
|
||||
for (ai = ai_nfs; ai != NULL; ai = ai->ai_next) {
|
||||
if ((ai->ai_family == AF_INET6) &&
|
||||
(opflags & OF_NOINET6))
|
||||
continue;
|
||||
if ((ai->ai_family == AF_INET) &&
|
||||
(opflags & OF_NOINET4))
|
||||
continue;
|
||||
ret = nfs4_tryproto(ai, hostp, spec, &errstr);
|
||||
if (ret == TRYRET_SUCCESS)
|
||||
break;
|
||||
if (ret != TRYRET_LOCALERR)
|
||||
remoteerr = 1;
|
||||
if ((opflags & ISBGRND) == 0)
|
||||
fprintf(stderr, "%s\n", errstr);
|
||||
}
|
||||
if (ret == TRYRET_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Exit if all errors were local. */
|
||||
if (!remoteerr)
|
||||
exit(1);
|
||||
|
||||
/*
|
||||
* If retrycnt == 0, we are to keep retrying forever.
|
||||
* Otherwise decrement it, and exit if it hits zero.
|
||||
*/
|
||||
if (retrycnt != 0 && --retrycnt == 0)
|
||||
exit(1);
|
||||
|
||||
if ((opflags & (BGRND | ISBGRND)) == BGRND) {
|
||||
warnx("Cannot immediately mount %s:%s, backgrounding",
|
||||
hostp, spec);
|
||||
opflags |= ISBGRND;
|
||||
if (daemon(0, 0) != 0)
|
||||
err(1, "daemon");
|
||||
}
|
||||
sleep(60);
|
||||
}
|
||||
freeaddrinfo(ai_nfs);
|
||||
build_iovec(iov, iovlen, "hostname", nam, (size_t)-1);
|
||||
/* Add mounted file system to PATH_MOUNTTAB */
|
||||
if (!add_mtab(hostp, spec))
|
||||
warnx("can't update %s for %s:%s", PATH_MOUNTTAB, hostp, spec);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to set up the NFS arguments according to the address
|
||||
* family, protocol (and possibly port) specified in `ai'.
|
||||
@ -1142,82 +971,6 @@ nfs_tryproto(struct addrinfo *ai, char *hostp, char *spec, char **errstr,
|
||||
return (TRYRET_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Try to set up the NFS arguments according to the address
|
||||
* family, protocol (and possibly port) specified in `ai'.
|
||||
*
|
||||
* Returns TRYRET_SUCCESS if successful, or:
|
||||
* TRYRET_TIMEOUT The server did not respond.
|
||||
* TRYRET_REMOTEERR The server reported an error.
|
||||
* TRYRET_LOCALERR Local failure.
|
||||
*
|
||||
* In all error cases, *errstr will be set to a statically-allocated string
|
||||
* describing the error.
|
||||
*/
|
||||
enum tryret
|
||||
nfs4_tryproto(struct addrinfo *ai, char *hostp, char *spec, char **errstr)
|
||||
{
|
||||
static char errbuf[256];
|
||||
struct sockaddr_storage nfs_ss;
|
||||
struct netbuf nfs_nb;
|
||||
struct netconfig *nconf;
|
||||
const char *netid;
|
||||
int nfsvers, sotype;
|
||||
|
||||
errbuf[0] = '\0';
|
||||
*errstr = errbuf;
|
||||
|
||||
if (nfsproto == IPPROTO_TCP)
|
||||
sotype = SOCK_STREAM;
|
||||
else if (nfsproto == IPPROTO_UDP)
|
||||
sotype = SOCK_DGRAM;
|
||||
|
||||
if ((netid = netidbytype(ai->ai_family, sotype)) == NULL) {
|
||||
snprintf(errbuf, sizeof errbuf,
|
||||
"af %d sotype %d not supported", ai->ai_family, sotype);
|
||||
return (TRYRET_LOCALERR);
|
||||
}
|
||||
if ((nconf = getnetconf_cached(netid)) == NULL) {
|
||||
snprintf(errbuf, sizeof errbuf, "%s: %s", netid, nc_sperror());
|
||||
return (TRYRET_LOCALERR);
|
||||
}
|
||||
|
||||
nfsvers = 4;
|
||||
|
||||
if (portspec != NULL && atoi(portspec) != 0) {
|
||||
/* `ai' contains the complete nfsd sockaddr. */
|
||||
nfs_nb.buf = ai->ai_addr;
|
||||
nfs_nb.len = nfs_nb.maxlen = ai->ai_addrlen;
|
||||
} else {
|
||||
/* Ask the remote rpcbind. */
|
||||
nfs_nb.buf = &nfs_ss;
|
||||
nfs_nb.len = nfs_nb.maxlen = sizeof nfs_ss;
|
||||
|
||||
if (!rpcb_getaddr(RPCPROG_NFS, nfsvers, nconf, &nfs_nb,
|
||||
hostp)) {
|
||||
snprintf(errbuf, sizeof errbuf, "[%s] %s:%s: %s",
|
||||
netid, hostp, spec,
|
||||
clnt_spcreateerror("RPCPROG_NFS"));
|
||||
return (returncode(rpc_createerr.cf_stat,
|
||||
&rpc_createerr.cf_error));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Store the filehandle and server address in nfsargsp, making
|
||||
* sure to copy any locally allocated structures.
|
||||
*/
|
||||
addrlen = nfs_nb.len;
|
||||
addr = malloc(addrlen);
|
||||
|
||||
if (addr == NULL)
|
||||
err(1, "malloc");
|
||||
bcopy(nfs_nb.buf, addr, addrlen);
|
||||
|
||||
return (TRYRET_SUCCESS);
|
||||
}
|
||||
|
||||
/*
|
||||
* Catagorise a RPC return status and error into an `enum tryret'
|
||||
* return code.
|
||||
@ -1361,7 +1114,7 @@ void
|
||||
usage()
|
||||
{
|
||||
(void)fprintf(stderr, "%s\n%s\n%s\n%s\n",
|
||||
"usage: mount_nfs [-234bcdiLlNPsTU] [-a maxreadahead] [-D deadthresh]",
|
||||
"usage: mount_nfs [-23bcdiLlNPsTU] [-a maxreadahead] [-D deadthresh]",
|
||||
" [-g maxgroups] [-I readdirsize] [-o options] [-R retrycnt]",
|
||||
" [-r readsize] [-t timeout] [-w writesize] [-x retrans]",
|
||||
" rhost:path node");
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -59,7 +59,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <sys/vnode.h>
|
||||
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpc/rpcclnt.h>
|
||||
|
||||
#include <kgssapi/krb5/kcrypto.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>
|
||||
|
||||
/*
|
||||
|
@ -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>
|
@ -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
|
||||
|
@ -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 */
|
@ -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);
|
||||
}
|
@ -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_ */
|
@ -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;
|
||||
}
|
@ -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__ */
|
@ -1,348 +0,0 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $Id: nfs_socket.c,v 1.12 2003/11/05 14:59:01 rees Exp $ */
|
||||
|
||||
/*-
|
||||
* copyright (c) 2003
|
||||
* the regents of the university of michigan
|
||||
* all rights reserved
|
||||
*
|
||||
* permission is granted to use, copy, create derivative works and redistribute
|
||||
* this software and such derivative works for any purpose, so long as the name
|
||||
* of the university of michigan is not used in any advertising or publicity
|
||||
* pertaining to the use or distribution of this software without specific,
|
||||
* written prior authorization. if the above copyright notice or any other
|
||||
* identification of the university of michigan is included in any copy of any
|
||||
* portion of this software, then the disclaimer below must also be included.
|
||||
*
|
||||
* this software is provided as is, without representation from the university
|
||||
* of michigan as to its fitness for any purpose, and without warranty by the
|
||||
* university of michigan of any kind, either express or implied, including
|
||||
* without limitation the implied warranties of merchantability and fitness for
|
||||
* a particular purpose. the regents of the university of michigan shall not be
|
||||
* liable for any damages, including special, indirect, incidental, or
|
||||
* consequential damages, with respect to any claim arising out of or in
|
||||
* connection with the use of the software, even if it has been or is hereafter
|
||||
* advised of the possibility of such damages.
|
||||
*/
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1989, 1991, 1993, 1995
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Rick Macklem at The University of Guelph.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)nfs_socket.c 8.5 (Berkeley) 3/30/95
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
/*
|
||||
* Socket operations for use by nfs
|
||||
*/
|
||||
|
||||
#include "opt_inet6.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/signalvar.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/vnode.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
#include <rpc/rpcclnt.h>
|
||||
|
||||
#include <nfs/rpcv2.h>
|
||||
#include <nfs/nfsproto.h>
|
||||
#include <nfsclient/nfs.h>
|
||||
#include <nfs4client/nfs4.h>
|
||||
#include <nfs/xdr_subs.h>
|
||||
#include <nfsclient/nfsm_subs.h>
|
||||
#include <nfsclient/nfsmount.h>
|
||||
|
||||
#ifdef NFS4_USE_RPCCLNT
|
||||
#include <rpc/rpcclnt.h>
|
||||
#include <rpc/rpcm_subs.h>
|
||||
#endif
|
||||
|
||||
#ifdef NFS4_USE_RPCCLNT
|
||||
static struct rpc_program nfs_program = {
|
||||
NFS_PROG, NFS_VER4, "NFSv4"
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
static struct {
|
||||
short nfserr;
|
||||
short syserr;
|
||||
} nfs_errtbl[] = {
|
||||
{ NFS_OK, 0 },
|
||||
{ NFSERR_PERM, EPERM },
|
||||
{ NFSERR_NOENT, ENOENT },
|
||||
{ NFSERR_IO, EIO },
|
||||
{ NFSERR_NXIO, ENXIO },
|
||||
{ NFSERR_ACCES, EACCES },
|
||||
{ NFSERR_EXIST, EEXIST },
|
||||
{ NFSERR_XDEV, EXDEV },
|
||||
{ NFSERR_MLINK, EMLINK },
|
||||
{ NFSERR_NODEV, ENODEV },
|
||||
{ NFSERR_NOTDIR, ENOTDIR },
|
||||
{ NFSERR_ISDIR, EISDIR },
|
||||
{ NFSERR_INVAL, EINVAL },
|
||||
{ NFSERR_FBIG, EFBIG },
|
||||
{ NFSERR_NOSPC, ENOSPC },
|
||||
{ NFSERR_ROFS, EROFS },
|
||||
{ NFSERR_MLINK, EMLINK },
|
||||
{ NFSERR_NAMETOL, ENAMETOOLONG },
|
||||
{ NFSERR_NOTEMPTY, ENOTEMPTY },
|
||||
{ NFSERR_NOTSUPP, EOPNOTSUPP },
|
||||
#ifdef EDQUOT
|
||||
{ NFSERR_DQUOT, EDQUOT },
|
||||
#endif
|
||||
{ NFSERR_STALE, ESTALE },
|
||||
{ NFSERR_DENIED, EAGAIN },
|
||||
{ NFSERR_SYMLINK, ELOOP },
|
||||
{ NFSERR_BADXDR, EBADRPC },
|
||||
{ NFSERR_WRONGSEC, EPERM },
|
||||
{ -1, EIO }
|
||||
};
|
||||
|
||||
static int
|
||||
nfs4_nfserr_to_syserr(int nfserr)
|
||||
{
|
||||
int i, syserr;
|
||||
|
||||
/* XXX : not the optimal algorithm, but will do for now! */
|
||||
for (i = 0; nfs_errtbl[i].nfserr != -1; i++) {
|
||||
if (nfs_errtbl[i].nfserr == nfserr)
|
||||
break;
|
||||
}
|
||||
#ifdef NFS4_MAP_UNKNOWN_ERR
|
||||
syserr = nfs_errtbl[i].syserr;
|
||||
#else
|
||||
if (nfs_errtbl[i].nfserr != -1)
|
||||
syserr = nfs_errtbl[i].syserr;
|
||||
else
|
||||
syserr = nfserr;
|
||||
#endif
|
||||
return syserr;
|
||||
}
|
||||
|
||||
int
|
||||
nfs4_connect(struct nfsmount *nmp)
|
||||
{
|
||||
struct rpcclnt * rpc = &nmp->nm_rpcclnt;
|
||||
struct rpc_auth * auth;
|
||||
int flag = 0;
|
||||
int error;
|
||||
|
||||
/* XXX hack! */
|
||||
#ifdef __OpenBSD__
|
||||
struct proc * td = curproc;
|
||||
#else
|
||||
struct thread * td = curthread;
|
||||
#endif
|
||||
|
||||
auth = malloc(sizeof(struct rpc_auth), M_TEMP, M_WAITOK);
|
||||
auth->auth_type = RPCAUTH_UNIX;
|
||||
|
||||
/* translate nfs flags -> rpcclnt flags */
|
||||
if (nmp->nm_flag & NFSMNT_SOFT)
|
||||
flag |= RPCCLNT_SOFT;
|
||||
|
||||
if (nmp->nm_flag & NFSMNT_INT)
|
||||
flag |= RPCCLNT_INT;
|
||||
|
||||
if (nmp->nm_flag & NFSMNT_NOCONN)
|
||||
flag |= RPCCLNT_NOCONN;
|
||||
|
||||
if (nmp->nm_flag & NFSMNT_DUMBTIMR)
|
||||
flag |= RPCCLNT_DUMBTIMR;
|
||||
|
||||
/* rpc->rc_servername = nmp->nm_mountp->mnt_stat.f_mntfromname; */
|
||||
|
||||
error = rpcclnt_setup(rpc, &nfs_program, nmp->nm_nam, nmp->nm_sotype,
|
||||
nmp->nm_soproto, auth,
|
||||
/* XXX: check nmp->nm_flag to make sure these are set */
|
||||
(nmp->nm_rsize > nmp->nm_readdirsize) ? nmp->nm_rsize : nmp->nm_readdirsize,
|
||||
nmp->nm_wsize, flag);
|
||||
|
||||
/* set deadthresh, timeo, retry */
|
||||
rpc->rc_deadthresh = nmp->nm_deadthresh;
|
||||
rpc->rc_timeo = nmp->nm_timeo;
|
||||
rpc->rc_retry = nmp->nm_retry;
|
||||
|
||||
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
return rpcclnt_connect(rpc, td);
|
||||
}
|
||||
|
||||
/*
|
||||
* NFS disconnect. Clean up and unlink.
|
||||
*/
|
||||
void
|
||||
nfs4_disconnect(struct nfsmount *nmp)
|
||||
{
|
||||
rpcclnt_disconnect(&nmp->nm_rpcclnt);
|
||||
}
|
||||
|
||||
void
|
||||
nfs4_safedisconnect(struct nfsmount *nmp)
|
||||
{
|
||||
rpcclnt_safedisconnect(&nmp->nm_rpcclnt);
|
||||
}
|
||||
|
||||
/*
|
||||
* nfs_request - goes something like this
|
||||
* - fill in request struct
|
||||
* - links it into list
|
||||
* - calls nfs_send() for first transmit
|
||||
* - calls nfs_receive() to get reply
|
||||
* - break down rpc header and return with nfs reply pointed to
|
||||
* by mrep or error
|
||||
* nb: always frees up mreq mbuf list
|
||||
*/
|
||||
/* XXX overloaded before */
|
||||
#define NQ_TRYLATERDEL 15 /* Initial try later delay (sec) */
|
||||
|
||||
int
|
||||
nfs4_request(struct vnode *vp, struct mbuf *mrest, int procnum,
|
||||
struct thread *td, struct ucred *cred, struct mbuf **mrp,
|
||||
struct mbuf **mdp, caddr_t *dposp)
|
||||
{
|
||||
int error;
|
||||
|
||||
error = nfs4_request_mnt(VFSTONFS(vp->v_mount), mrest, procnum,
|
||||
td, cred, mrp, mdp, dposp);
|
||||
|
||||
/*
|
||||
** If the File Handle was stale, invalidate the
|
||||
** lookup cache, just in case.
|
||||
**/
|
||||
if (error == ESTALE)
|
||||
nfs_purgecache(vp);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
nfs4_request_mnt(struct nfsmount *nmp, struct mbuf *mrest, int procnum,
|
||||
struct thread *td, struct ucred *cred, struct mbuf **mrp,
|
||||
struct mbuf **mdp, caddr_t *dposp)
|
||||
{
|
||||
int error;
|
||||
u_int32_t *tl;
|
||||
struct rpcclnt * clnt = &nmp->nm_rpcclnt;
|
||||
struct mbuf *md, *mrep;
|
||||
caddr_t dpos;
|
||||
struct rpc_reply reply;
|
||||
|
||||
if ((error = rpcclnt_request(clnt, mrest, procnum, td, cred,
|
||||
&reply)) != 0) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* XXX: don't free mrest if an error occured, to allow caller to retry*/
|
||||
m_freem(mrest);
|
||||
mrep = reply.mrep;
|
||||
md = reply.result_md;
|
||||
dpos = reply.result_dpos;
|
||||
|
||||
tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED);
|
||||
if (*tl != 0) {
|
||||
error = fxdr_unsigned(int, *tl);
|
||||
#if 0
|
||||
if ((nmp->nm_flag & NFSMNT_NFSV3) &&
|
||||
error == NFSERR_TRYLATER) {
|
||||
m_freem(mrep);
|
||||
error = 0;
|
||||
waituntil = time_second + trylater_delay;
|
||||
while (time_second < waituntil)
|
||||
(void) tsleep(&fake_wchan, PSOCK, "nqnfstry", hz);
|
||||
trylater_delay *= nfs_backoff[trylater_cnt];
|
||||
if (trylater_cnt < NFS_NBACKOFF - 1)
|
||||
trylater_cnt++;
|
||||
goto tryagain;
|
||||
}
|
||||
#endif
|
||||
goto out;
|
||||
}
|
||||
|
||||
*mrp = mrep;
|
||||
*mdp = md;
|
||||
*dposp = dpos;
|
||||
return (0);
|
||||
nfsmout:
|
||||
out:
|
||||
m_freem(reply.mrep);
|
||||
*mrp = NULL;
|
||||
*mdp = NULL;
|
||||
return (nfs4_nfserr_to_syserr(error));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Mark all of an nfs mount's outstanding requests with R_SOFTTERM and
|
||||
* wait for all requests to complete. This is used by forced unmounts
|
||||
* to terminate any outstanding RPCs.
|
||||
*/
|
||||
int
|
||||
nfs4_nmcancelreqs(nmp)
|
||||
struct nfsmount *nmp;
|
||||
{
|
||||
return rpcclnt_cancelreqs(&nmp->nm_rpcclnt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test for a termination condition pending on the process.
|
||||
* This is used for NFSMNT_INT mounts.
|
||||
*/
|
||||
int
|
||||
nfs4_sigintr(struct nfsmount *nmp, struct nfsreq *rep, struct thread *td)
|
||||
{
|
||||
if (rep != NULL) {
|
||||
printf("nfs_sigintr: attempting to use nfsreq != NULL\n");
|
||||
return EINTR;
|
||||
}
|
||||
return rpcclnt_sigintr(&nmp->nm_rpcclnt, NULL, td);
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -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 */
|
@ -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;
|
||||
}
|
@ -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);
|
||||
}
|
@ -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 */
|
@ -1,225 +0,0 @@
|
||||
/* $FreeBSD$ */
|
||||
/* $Id: nfs4_vn_subs.c,v 1.9 2003/11/05 14:59:00 rees Exp $ */
|
||||
|
||||
/*-
|
||||
* copyright (c) 2003
|
||||
* the regents of the university of michigan
|
||||
* all rights reserved
|
||||
*
|
||||
* permission is granted to use, copy, create derivative works and redistribute
|
||||
* this software and such derivative works for any purpose, so long as the name
|
||||
* of the university of michigan is not used in any advertising or publicity
|
||||
* pertaining to the use or distribution of this software without specific,
|
||||
* written prior authorization. if the above copyright notice or any other
|
||||
* identification of the university of michigan is included in any copy of any
|
||||
* portion of this software, then the disclaimer below must also be included.
|
||||
*
|
||||
* this software is provided as is, without representation from the university
|
||||
* of michigan as to its fitness for any purpose, and without warranty by the
|
||||
* university of michigan of any kind, either express or implied, including
|
||||
* without limitation the implied warranties of merchantability and fitness for
|
||||
* a particular purpose. the regents of the university of michigan shall not be
|
||||
* liable for any damages, including special, indirect, incidental, or
|
||||
* consequential damages, with respect to any claim arising out of or in
|
||||
* connection with the use of the software, even if it has been or is hereafter
|
||||
* advised of the possibility of such damages.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/limits.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/module.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/sockio.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_extern.h>
|
||||
#include <vm/uma.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <rpc/rpcclnt.h>
|
||||
|
||||
#include <nfs/rpcv2.h>
|
||||
#include <nfs/nfsproto.h>
|
||||
#include <nfsclient/nfs.h>
|
||||
#include <nfsclient/nfsmount.h>
|
||||
#include <nfs/xdr_subs.h>
|
||||
#include <nfsclient/nfsm_subs.h>
|
||||
#include <nfsclient/nfsdiskless.h>
|
||||
|
||||
/* NFSv4 */
|
||||
#include <nfs4client/nfs4.h>
|
||||
#include <nfs4client/nfs4m_subs.h>
|
||||
#include <nfs4client/nfs4_vn.h>
|
||||
|
||||
#include <nfsclient/nfsnode.h>
|
||||
|
||||
void
|
||||
nfs4_vnop_loadattrcache(struct vnode *vp, struct nfsv4_fattr *fap,
|
||||
struct vattr *vaper)
|
||||
{
|
||||
struct vattr *vap;
|
||||
struct nfsnode *np;
|
||||
int32_t rdev;
|
||||
enum vtype vtyp;
|
||||
u_short vmode;
|
||||
struct timespec mtime;
|
||||
struct timeval tv;
|
||||
|
||||
microtime(&tv);
|
||||
|
||||
vtyp = nv3tov_type[fap->fa4_type & 0x7];
|
||||
vmode = (fap->fa4_valid & FA4V_MODE) ? fap->fa4_mode : 0777;
|
||||
rdev = (fap->fa4_valid & FA4V_RDEV) ?
|
||||
makedev(fap->fa4_rdev_major, fap->fa4_rdev_minor) : 0;
|
||||
if (fap->fa4_valid & FA4V_MTIME)
|
||||
mtime = fap->fa4_mtime;
|
||||
else
|
||||
bzero(&mtime, sizeof mtime);
|
||||
|
||||
/*
|
||||
* If v_type == VNON it is a new node, so fill in the v_type,
|
||||
* n_mtime fields. Check to see if it represents a special
|
||||
* device, and if so, check for a possible alias. Once the
|
||||
* correct vnode has been obtained, fill in the rest of the
|
||||
* information.
|
||||
*/
|
||||
np = VTONFS(vp);
|
||||
vap = &np->n_vattr;
|
||||
if (vp->v_type != vtyp || np->n_mtime.tv_sec == 0) {
|
||||
bzero(vap, sizeof *vap);
|
||||
vp->v_type = vtyp;
|
||||
np->n_mtime.tv_sec = mtime.tv_sec;
|
||||
}
|
||||
vap->va_type = vtyp;
|
||||
vap->va_mode = (vmode & 07777);
|
||||
vap->va_rdev = rdev;
|
||||
vap->va_mtime = mtime;
|
||||
vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
|
||||
if (fap->fa4_valid & FA4V_NLINK)
|
||||
vap->va_nlink = fap->fa4_nlink;
|
||||
if (fap->fa4_valid & FA4V_UID)
|
||||
vap->va_uid = fap->fa4_uid;
|
||||
if (fap->fa4_valid & FA4V_GID)
|
||||
vap->va_gid = fap->fa4_gid;
|
||||
vap->va_size = fap->fa4_size;
|
||||
vap->va_blocksize = NFS_FABLKSIZE;
|
||||
vap->va_bytes = fap->fa4_size;
|
||||
if (fap->fa4_valid & FA4V_FILEID)
|
||||
vap->va_fileid = nfs_v4fileid4_to_fileid(fap->fa4_fileid);
|
||||
if (fap->fa4_valid & FA4V_ATIME)
|
||||
vap->va_atime = fap->fa4_atime;
|
||||
if (fap->fa4_valid & FA4V_BTIME)
|
||||
vap->va_birthtime = fap->fa4_btime;
|
||||
if (fap->fa4_valid & FA4V_CTIME)
|
||||
vap->va_ctime = fap->fa4_ctime;
|
||||
vap->va_flags = 0;
|
||||
vap->va_filerev = 0;
|
||||
/* XXX dontshrink flag? */
|
||||
if (vap->va_size != np->n_size) {
|
||||
if (vap->va_type == VREG) {
|
||||
if (np->n_flag & NMODIFIED) {
|
||||
if (vap->va_size < np->n_size)
|
||||
vap->va_size = np->n_size;
|
||||
else
|
||||
np->n_size = vap->va_size;
|
||||
} else
|
||||
np->n_size = vap->va_size;
|
||||
vnode_pager_setsize(vp, np->n_size);
|
||||
} else
|
||||
np->n_size = vap->va_size;
|
||||
}
|
||||
np->n_attrstamp = tv.tv_sec;
|
||||
if (vaper != NULL) {
|
||||
bcopy((caddr_t)vap, (caddr_t)vaper, sizeof(*vap));
|
||||
if (np->n_flag & NCHG) {
|
||||
if (np->n_flag & NACC)
|
||||
vaper->va_atime = np->n_atim;
|
||||
if (np->n_flag & NUPD)
|
||||
vaper->va_mtime = np->n_mtim;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint64_t nfs_nullcookie = 0;
|
||||
/*
|
||||
* This function finds the directory cookie that corresponds to the
|
||||
* logical byte offset given.
|
||||
*/
|
||||
uint64_t *
|
||||
nfs4_getcookie(struct nfsnode *np, off_t off, int add)
|
||||
{
|
||||
struct nfsdmap *dp, *dp2;
|
||||
int pos;
|
||||
|
||||
pos = (uoff_t)off / NFS_DIRBLKSIZ;
|
||||
if (pos == 0 || off < 0) {
|
||||
#ifdef DIAGNOSTIC
|
||||
if (add)
|
||||
panic("nfs getcookie add at <= 0");
|
||||
#endif
|
||||
return (&nfs_nullcookie);
|
||||
}
|
||||
pos--;
|
||||
dp = LIST_FIRST(&np->n_cookies);
|
||||
if (!dp) {
|
||||
if (add) {
|
||||
dp = malloc(sizeof (struct nfsdmap),
|
||||
M_NFSDIROFF, M_WAITOK);
|
||||
dp->ndm_eocookie = 0;
|
||||
LIST_INSERT_HEAD(&np->n_cookies, dp, ndm_list);
|
||||
} else
|
||||
return (NULL);
|
||||
}
|
||||
while (pos >= NFSNUMCOOKIES) {
|
||||
pos -= NFSNUMCOOKIES;
|
||||
if (LIST_NEXT(dp, ndm_list)) {
|
||||
if (!add && dp->ndm_eocookie < NFSNUMCOOKIES &&
|
||||
pos >= dp->ndm_eocookie)
|
||||
return (NULL);
|
||||
dp = LIST_NEXT(dp, ndm_list);
|
||||
} else if (add) {
|
||||
dp2 = malloc(sizeof (struct nfsdmap),
|
||||
M_NFSDIROFF, M_WAITOK);
|
||||
dp2->ndm_eocookie = 0;
|
||||
LIST_INSERT_AFTER(dp, dp2, ndm_list);
|
||||
dp = dp2;
|
||||
} else
|
||||
return (NULL);
|
||||
}
|
||||
if (pos >= dp->ndm_eocookie) {
|
||||
if (add)
|
||||
dp->ndm_eocookie = pos + 1;
|
||||
else
|
||||
return (NULL);
|
||||
}
|
||||
return (&dp->ndm4_cookies[pos]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Invalidate cached directory information, except for the actual directory
|
||||
* blocks (which are invalidated separately).
|
||||
* Done mainly to avoid the use of stale offset cookies.
|
||||
*/
|
||||
void
|
||||
nfs4_invaldir(struct vnode *vp)
|
||||
{
|
||||
struct nfsnode *np = VTONFS(vp);
|
||||
|
||||
np->n_direofoffset = 0;
|
||||
bzero(np->n4_cookieverf, NFSX_V4VERF);
|
||||
if (LIST_FIRST(&np->n_cookies))
|
||||
LIST_FIRST(&np->n_cookies)->ndm_eocookie = 0;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -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 */
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
/*
|
||||
|
@ -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) {
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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
|
||||
|
@ -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, ...);
|
||||
|
@ -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>
|
||||
|
2114
sys/rpc/rpcclnt.c
2114
sys/rpc/rpcclnt.c
File diff suppressed because it is too large
Load Diff
@ -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_ */
|
Loading…
Reference in New Issue
Block a user