nfsd: deal with variable-sized filehandles.

This commit is contained in:
yamt 2006-09-02 12:40:36 +00:00
parent d70ea60617
commit d7d8adb6ea
8 changed files with 277 additions and 248 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs.h,v 1.58 2006/07/13 12:00:26 martin Exp $ */
/* $NetBSD: nfs.h,v 1.59 2006/09/02 12:40:36 yamt Exp $ */
/*
* Copyright (c) 1989, 1993, 1995
* The Regents of the University of California. All rights reserved.
@ -358,8 +358,6 @@ extern TAILQ_HEAD(nfsreqhead, nfsreq) nfs_reqq;
#ifndef NFS_WDELAYHASHSIZ
#define NFS_WDELAYHASHSIZ 16 /* and with this */
#endif
#define NWDELAYHASH(sock, f) \
(&(sock)->ns_wdelayhashtbl[(*((u_int32_t *)(f))) % NFS_WDELAYHASHSIZ])
#ifndef NFS_MUIDHASHSIZ
#define NFS_MUIDHASHSIZ 63 /* Tune the size of nfsmount with this */
#endif
@ -486,6 +484,18 @@ struct nfsd {
#define NFSD_NEEDAUTH 0x04
#define NFSD_AUTHFAIL 0x08
#define NFSD_MAXFHSIZE 64
typedef struct nfsrvfh {
size_t nsfh_size;
union {
fhandle_t u_fh;
uint8_t u_opaque[NFSD_MAXFHSIZE];
} nsfh_u;
} nfsrvfh_t;
#define NFSRVFH_SIZE(nsfh) ((nsfh)->nsfh_size)
#define NFSRVFH_DATA(nsfh) ((void *)(nsfh)->nsfh_u.u_opaque)
#define NFSRVFH_FHANDLE(nsfh) (&(nsfh)->nsfh_u.u_fh)
/*
* This structure is used by the server for describing each request.
* Some fields are used only when write request gathering is performed.
@ -512,7 +522,7 @@ struct nfsrv_descript {
u_int32_t nd_retxid; /* Reply xid */
u_int32_t nd_duration; /* Lease duration */
struct timeval nd_starttime; /* Time RPC initiated */
nfsfh_t nd_fh; /* File handle */
nfsrvfh_t nd_fh; /* File handle */
kauth_cred_t nd_cr; /* Credentials */
};

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs_nqlease.c,v 1.68 2006/09/02 12:39:59 yamt Exp $ */
/* $NetBSD: nfs_nqlease.c,v 1.69 2006/09/02 12:40:36 yamt Exp $ */
/*
* Copyright (c) 1992, 1993
@ -49,7 +49,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: nfs_nqlease.c,v 1.68 2006/09/02 12:39:59 yamt Exp $");
__KERNEL_RCSID(0, "$NetBSD: nfs_nqlease.c,v 1.69 2006/09/02 12:40:36 yamt Exp $");
#include "fs_nfs.h"
#include "opt_nfs.h"
@ -186,11 +186,7 @@ nqsrv_getlease(vp, duration, flags, slp, lwp, nam, cachablep, frev, cred)
struct nqlease *tlp;
struct nqm **lphp;
struct vattr vattr;
union {
fhandle_t fh;
char space[LC_MAXFIDSIZ + offsetof(fhandle_t, fh_fid)];
} fh;
size_t fh_size;
nfsrvfh_t nsfh;
int i, ok, error, s;
if (vp->v_type != VREG && vp->v_type != VDIR && vp->v_type != VLNK)
@ -212,18 +208,14 @@ nqsrv_getlease(vp, duration, flags, slp, lwp, nam, cachablep, frev, cred)
/*
* Find the lease by searching the hash list.
*/
fh_size = sizeof(fh);
error = vfs_composefh(vp, &fh.fh, &fh_size);
error = nfsrv_composefh(vp, &nsfh, TRUE);
if (error) {
splx(s);
return (error);
}
lpp = NQFHHASH(fh.fh.fh_fid.fid_data);
lpp = NQFHHASH(NFSRVFH_FHANDLE(&nsfh)->fh_fid.fid_data);
LIST_FOREACH (lp, lpp, lc_hash) {
if (fh.fh.fh_fsid.__fsid_val[0] == lp->lc_fsid.__fsid_val[0] &&
fh.fh.fh_fsid.__fsid_val[1] == lp->lc_fsid.__fsid_val[1] &&
!memcmp(fh.fh.fh_fid.fid_data, lp->lc_fiddata,
fh.fh.fh_fid.fid_len - sizeof (int32_t))) {
if (!nfsrv_comparefh(&lp->lc_fh, &nsfh)) {
/* Found it */
lp->lc_vp = vp;
vp->v_lease = lp;
@ -321,9 +313,7 @@ doreply:
lp->lc_flag |= (LC_WRITE | LC_WRITTEN);
nqsrv_addhost(&lp->lc_host, slp, nam);
lp->lc_vp = vp;
lp->lc_fsid = fh.fh.fh_fsid;
memcpy(lp->lc_fiddata, fh.fh.fh_fid.fid_data,
fh.fh.fh_fid.fid_len - sizeof (int32_t));
nfsrv_copyfh(&lp->lc_fh, &nsfh);
if(!lpp)
panic("nfs_nqlease.c: Phoney lpp");
LIST_INSERT_HEAD(lpp, lp, lc_hash);
@ -477,9 +467,7 @@ nqsrv_send_eviction(vp, lp, slp, nam, cred, l)
struct mbuf *mreq, *mb, *nam2, *mheadend;
struct socket *so;
struct sockaddr_in *saddr;
nfsfh_t nfh;
fhandle_t *fhp;
size_t fh_size;
nfsrvfh_t nsfh;
caddr_t bpos, cp;
u_int32_t xid, *tl;
int len = 1, ok = 1, i = 0;
@ -489,6 +477,8 @@ nqsrv_send_eviction(vp, lp, slp, nam, cred, l)
if (nqsrv_cmpnam(slp, nam, lph))
lph->lph_flag |= LC_VACATED;
else if ((lph->lph_flag & (LC_LOCAL | LC_VACATED)) == 0) {
int error;
if (lph->lph_flag & LC_UDP) {
nam2 = m_get(M_WAIT, MT_SONAME);
MCLAIM(nam2, &nfs_mowner);
@ -523,11 +513,9 @@ nqsrv_send_eviction(vp, lp, slp, nam, cred, l)
solockp = (int *)0;
nfsm_reqhead((struct nfsnode *)0, NQNFSPROC_EVICTED,
NFSX_V3FH + NFSX_UNSIGNED);
memset(&nfh, 0, sizeof(nfh));
fhp = &nfh.fh_generic;
fh_size = NFS_SMALLFH;
vfs_composefh(vp, fhp, &fh_size);
nfsm_srvfhtom(fhp, 1);
error = nfsrv_composefh(vp, &nsfh, 1);
KASSERT(error == 0); /* XXX */
nfsm_srvfhtom(&nsfh, 1);
m = mreq;
siz = 0;
while (m) {
@ -727,8 +715,7 @@ nqnfsrv_getlease(nfsd, slp, lwp, mrq)
struct nfs_fattr *fp;
struct vattr va;
struct vnode *vp;
nfsfh_t nfh;
fhandle_t *fhp;
nfsrvfh_t nsfh;
u_int32_t *tl;
int32_t t1;
u_quad_t frev;
@ -738,12 +725,11 @@ nqnfsrv_getlease(nfsd, slp, lwp, mrq)
struct mbuf *mb, *mreq;
int flags, rdonly, cache = 0;
fhp = &nfh.fh_generic;
nfsm_srvmtofh(fhp);
nfsm_srvmtofh(&nsfh);
nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
flags = fxdr_unsigned(int, *tl++);
nfsd->nd_duration = fxdr_unsigned(int, *tl);
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly,
error = nfsrv_fhtovp(&nsfh, 1, &vp, cred, slp, nam, &rdonly,
(nfsd->nd_flag & ND_KERBAUTH), FALSE);
if (error) {
nfsm_reply(0);
@ -786,7 +772,7 @@ nqnfsrv_vacated(nfsd, slp, lwp, mrq)
struct nqlease *lp;
struct nqhost *lph;
struct nqlease *tlp = (struct nqlease *)0;
nfsfh_t nfh;
nfsrvfh_t nsfh;
fhandle_t *fhp;
u_int32_t *tl;
int32_t t1;
@ -796,17 +782,14 @@ nqnfsrv_vacated(nfsd, slp, lwp, mrq)
char *cp2, *bpos;
u_quad_t frev;
fhp = &nfh.fh_generic;
nfsm_srvmtofh(fhp);
nfsm_srvmtofh(&nsfh);
m_freem(mrep);
fhp = &nsfh.nsfh_u.u_fh;
/*
* Find the lease by searching the hash list.
*/
LIST_FOREACH(lp, NQFHHASH(fhp->fh_fid.fid_data), lc_hash) {
if (fhp->fh_fsid.__fsid_val[0] == lp->lc_fsid.__fsid_val[0] &&
fhp->fh_fsid.__fsid_val[1] == lp->lc_fsid.__fsid_val[1] &&
!memcmp(fhp->fh_fid.fid_data, lp->lc_fiddata,
LC_MAXFIDSIZ)) {
if (!nfsrv_comparefh(&lp->lc_fh, &nsfh)) {
/* Found it */
tlp = lp;
break;
@ -954,7 +937,7 @@ nqnfs_callback1(struct nfsmount *nmp, struct mbuf *mrep, struct mbuf *md,
struct vnode *vp;
u_int32_t *tl;
int32_t t1;
nfsfh_t nfh;
nfsrvfh_t nsfh;
fhandle_t *fhp;
struct nfsnode *np;
struct nfsd tnfsd;
@ -979,9 +962,9 @@ nqnfs_callback1(struct nfsmount *nmp, struct mbuf *mrep, struct mbuf *md,
m_freem(mrep);
return (EPERM);
}
fhp = &nfh.fh_generic;
nfsm_srvmtofh(fhp);
nfsm_srvmtofh(&nsfh);
m_freem(mrep);
fhp = &nsfh.nsfh_u.u_fh;
error = nfs_nget(nmp->nm_mountp, (nfsfh_t *)fhp, NFSX_V3FH, &np);
if (error)
return (error);

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs_serv.c,v 1.116 2006/09/02 07:26:47 christos Exp $ */
/* $NetBSD: nfs_serv.c,v 1.117 2006/09/02 12:40:36 yamt Exp $ */
/*
* Copyright (c) 1989, 1993
@ -55,7 +55,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: nfs_serv.c,v 1.116 2006/09/02 07:26:47 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: nfs_serv.c,v 1.117 2006/09/02 12:40:36 yamt Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -70,6 +70,7 @@ __KERNEL_RCSID(0, "$NetBSD: nfs_serv.c,v 1.116 2006/09/02 07:26:47 christos Exp
#include <sys/dirent.h>
#include <sys/stat.h>
#include <sys/kernel.h>
#include <sys/hash.h>
#include <sys/kauth.h>
#include <uvm/uvm.h>
@ -107,8 +108,7 @@ nfsrv3_access(nfsd, slp, lwp, mrq)
caddr_t dpos = nfsd->nd_dpos;
kauth_cred_t cred = nfsd->nd_cr;
struct vnode *vp;
nfsfh_t nfh;
fhandle_t *fhp;
nfsrvfh_t nsfh;
u_int32_t *tl;
int32_t t1;
caddr_t bpos;
@ -119,10 +119,9 @@ nfsrv3_access(nfsd, slp, lwp, mrq)
u_long inmode, testmode, outmode;
u_quad_t frev;
fhp = &nfh.fh_generic;
nfsm_srvmtofh(fhp);
nfsm_srvmtofh(&nsfh);
nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED);
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly,
error = nfsrv_fhtovp(&nsfh, 1, &vp, cred, slp, nam, &rdonly,
(nfsd->nd_flag & ND_KERBAUTH), FALSE);
if (error) {
nfsm_reply(NFSX_UNSIGNED);
@ -178,8 +177,7 @@ nfsrv_getattr(nfsd, slp, lwp, mrq)
struct nfs_fattr *fp;
struct vattr va;
struct vnode *vp;
nfsfh_t nfh;
fhandle_t *fhp;
nfsrvfh_t nsfh;
u_int32_t *tl;
int32_t t1;
caddr_t bpos;
@ -188,9 +186,8 @@ nfsrv_getattr(nfsd, slp, lwp, mrq)
struct mbuf *mb, *mreq;
u_quad_t frev;
fhp = &nfh.fh_generic;
nfsm_srvmtofh(fhp);
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly,
nfsm_srvmtofh(&nsfh);
error = nfsrv_fhtovp(&nsfh, 1, &vp, cred, slp, nam, &rdonly,
(nfsd->nd_flag & ND_KERBAUTH), FALSE);
if (error) {
nfsm_reply(0);
@ -225,8 +222,7 @@ nfsrv_setattr(nfsd, slp, lwp, mrq)
struct nfsv2_sattr *sp;
struct nfs_fattr *fp;
struct vnode *vp;
nfsfh_t nfh;
fhandle_t *fhp;
nfsrvfh_t nsfh;
u_int32_t *tl;
int32_t t1;
caddr_t bpos;
@ -240,9 +236,8 @@ nfsrv_setattr(nfsd, slp, lwp, mrq)
memset(&guard, 0, sizeof guard); /* XXX gcc */
fhp = &nfh.fh_generic;
nfsm_srvmtofh(fhp);
if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL)
nfsm_srvmtofh(&nsfh);
if ((mp = vfs_getvfs(&NFSRVFH_FHANDLE(&nsfh)->fh_fsid)) == NULL)
return (ESTALE);
vn_start_write(NULL, &mp, V_WAIT);
VATTR_NULL(&va);
@ -288,7 +283,7 @@ nfsrv_setattr(nfsd, slp, lwp, mrq)
/*
* Now that we have all the fields, lets do it.
*/
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly,
error = nfsrv_fhtovp(&nsfh, 1, &vp, cred, slp, nam, &rdonly,
(nfsd->nd_flag & ND_KERBAUTH), FALSE);
if (error) {
nfsm_reply(2 * NFSX_UNSIGNED);
@ -364,8 +359,7 @@ nfsrv_lookup(nfsd, slp, lwp, mrq)
struct nfs_fattr *fp;
struct nameidata nd, ind, *ndp = &nd;
struct vnode *vp, *dirp;
nfsfh_t nfh;
fhandle_t *fhp;
nfsrvfh_t nsfh;
caddr_t cp;
u_int32_t *tl;
int32_t t1;
@ -377,19 +371,16 @@ nfsrv_lookup(nfsd, slp, lwp, mrq)
struct mbuf *mb, *mreq;
struct vattr va, dirattr;
u_quad_t frev;
size_t fh_size;
fhp = &nfh.fh_generic;
fh_size = NFS_SMALLFH;
nfsm_srvmtofh(fhp);
nfsm_srvmtofh(&nsfh);
nfsm_srvnamesiz(len);
pubflag = nfs_ispublicfh(fhp);
pubflag = nfs_ispublicfh(&nsfh);
nd.ni_cnd.cn_cred = cred;
nd.ni_cnd.cn_nameiop = LOOKUP;
nd.ni_cnd.cn_flags = LOCKLEAF | SAVESTART;
error = nfs_namei(&nd, fhp, len, slp, nam, &md, &dpos,
error = nfs_namei(&nd, &nsfh, len, slp, nam, &md, &dpos,
&dirp, lwp, (nfsd->nd_flag & ND_KERBAUTH), pubflag);
if (!error && pubflag) {
@ -448,16 +439,17 @@ nfsrv_lookup(nfsd, slp, lwp, mrq)
vrele(ndp->ni_startdir);
PNBUF_PUT(nd.ni_cnd.cn_pnbuf);
vp = ndp->ni_vp;
error = vfs_composefh(vp, fhp, &fh_size);
error = nfsrv_composefh(vp, &nsfh, v3);
if (!error)
error = VOP_GETATTR(vp, &va, cred, lwp);
vput(vp);
nfsm_reply(NFSX_SRVFH(v3) + NFSX_POSTOPORFATTR(v3) + NFSX_POSTOPATTR(v3));
nfsm_reply(NFSX_SRVFH(&nsfh, v3) + NFSX_POSTOPORFATTR(v3) +
NFSX_POSTOPATTR(v3));
if (error) {
nfsm_srvpostop_attr(dirattr_ret, &dirattr);
return (0);
}
nfsm_srvfhtom(fhp, v3);
nfsm_srvfhtom(&nsfh, v3);
if (v3) {
nfsm_srvpostop_attr(0, &va);
nfsm_srvpostop_attr(dirattr_ret, &dirattr);
@ -495,13 +487,11 @@ nfsrv_readlink(nfsd, slp, lwp, mrq)
struct mbuf *mb, *mp2 = NULL, *mp3 = NULL, *mreq;
struct vnode *vp;
struct vattr attr;
nfsfh_t nfh;
fhandle_t *fhp;
nfsrvfh_t nsfh;
struct uio io, *uiop = &io;
u_quad_t frev;
fhp = &nfh.fh_generic;
nfsm_srvmtofh(fhp);
nfsm_srvmtofh(&nsfh);
len = 0;
i = 0;
while (len < NFS_MAXPATHLEN) {
@ -531,7 +521,7 @@ nfsrv_readlink(nfsd, slp, lwp, mrq)
uiop->uio_resid = len;
uiop->uio_rw = UIO_READ;
UIO_SETUP_SYSSPACE(uiop);
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
error = nfsrv_fhtovp(&nsfh, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), FALSE);
if (error) {
m_freem(mp3);
@ -596,15 +586,13 @@ nfsrv_read(nfsd, slp, lwp, mrq)
char *cp2;
struct mbuf *mb, *mreq;
struct vnode *vp;
nfsfh_t nfh;
fhandle_t *fhp;
nfsrvfh_t nsfh;
struct uio io, *uiop = &io;
struct vattr va;
off_t off;
u_quad_t frev;
fhp = &nfh.fh_generic;
nfsm_srvmtofh(fhp);
nfsm_srvmtofh(&nsfh);
if (v3) {
nfsm_dissect(tl, u_int32_t *, 2 * NFSX_UNSIGNED);
off = fxdr_hyper(tl);
@ -615,7 +603,7 @@ nfsrv_read(nfsd, slp, lwp, mrq)
nfsm_dissect(tl, uint32_t *, NFSX_UNSIGNED);
reqlen = fxdr_unsigned(uint32_t, *tl);
reqlen = MIN(reqlen, NFS_SRVMAXDATA(nfsd));
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
error = nfsrv_fhtovp(&nsfh, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), FALSE);
if (error) {
nfsm_reply(2 * NFSX_UNSIGNED);
@ -828,8 +816,7 @@ nfsrv_write(nfsd, slp, lwp, mrq)
char *cp2;
struct mbuf *mb, *mreq;
struct vnode *vp;
nfsfh_t nfh;
fhandle_t *fhp;
nfsrvfh_t nsfh;
struct uio io, *uiop = &io;
off_t off;
u_quad_t frev;
@ -839,9 +826,8 @@ nfsrv_write(nfsd, slp, lwp, mrq)
*mrq = NULL;
return (0);
}
fhp = &nfh.fh_generic;
nfsm_srvmtofh(fhp);
if ((mntp = vfs_getvfs(&fhp->fh_fsid)) == NULL)
nfsm_srvmtofh(&nsfh);
if ((mntp = vfs_getvfs(&NFSRVFH_FHANDLE(&nsfh)->fh_fsid)) == NULL)
return (ESTALE);
vn_start_write(NULL, &mntp, V_WAIT);
if (v3) {
@ -894,7 +880,7 @@ nfsrv_write(nfsd, slp, lwp, mrq)
vn_finished_write(mntp, 0);
return (0);
}
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
error = nfsrv_fhtovp(&nsfh, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), FALSE);
if (error) {
nfsm_reply(2 * NFSX_UNSIGNED);
@ -1011,6 +997,16 @@ nfsrv_samecred(kauth_cred_t cred1, kauth_cred_t cred2)
return (1);
}
static struct nfsrvw_delayhash *
nfsrv_nwdelayhash(struct nfssvc_sock *slp, const nfsrvfh_t *nsfh)
{
uint32_t hash;
hash = hash32_buf(NFSRVFH_DATA(nsfh), NFSRVFH_SIZE(nsfh),
HASH32_BUF_INIT);
return &slp->ns_wdelayhashtbl[hash % NFS_WDELAYHASHSIZ];
}
/*
* NFS write service with write gathering support. Called when
* nfsrvw_procrastinate > 0.
@ -1135,16 +1131,15 @@ nfsmout:
LIST_INSERT_HEAD(&slp->ns_tq, nfsd, nd_tq);
}
if (nfsd->nd_mrep) {
wpp = NWDELAYHASH(slp, nfsd->nd_fh.fh_generic.fh_fid.fid_data);
wpp = nfsrv_nwdelayhash(slp, &nfsd->nd_fh);
owp = NULL;
wp = LIST_FIRST(wpp);
while (wp &&
memcmp(&nfsd->nd_fh, &wp->nd_fh, NFSX_V3FH)) {
while (wp && nfsrv_comparefh(&nfsd->nd_fh, &wp->nd_fh)) {
owp = wp;
wp = LIST_NEXT(wp, nd_hash);
}
while (wp && wp->nd_off < nfsd->nd_off &&
!memcmp(&nfsd->nd_fh, &wp->nd_fh, NFSX_V3FH)) {
!nfsrv_comparefh(&nfsd->nd_fh, &wp->nd_fh)) {
owp = wp;
wp = LIST_NEXT(wp, nd_hash);
}
@ -1189,7 +1184,7 @@ loop1:
cred = nfsd->nd_cr;
v3 = (nfsd->nd_flag & ND_NFSV3);
forat_ret = aftat_ret = 1;
error = nfsrv_fhtovp(&nfsd->nd_fh.fh_generic, 1, &vp, cred, slp,
error = nfsrv_fhtovp(&nfsd->nd_fh, 1, &vp, cred, slp,
nfsd->nd_nam, &rdonly, (nfsd->nd_flag & ND_KERBAUTH),
FALSE);
if (!error) {
@ -1411,25 +1406,21 @@ nfsrv_create(nfsd, slp, lwp, mrq)
char *cp2;
struct mbuf *mb, *mreq;
struct vnode *vp = NULL, *dirp = NULL;
nfsfh_t nfh;
fhandle_t *fhp;
size_t fh_size;
nfsrvfh_t nsfh;
u_quad_t frev, tempsize;
u_char cverf[NFSX_V3CREATEVERF];
struct mount *mp = NULL;
nd.ni_cnd.cn_nameiop = 0;
fhp = &nfh.fh_generic;
fh_size = NFS_SMALLFH;
nfsm_srvmtofh(fhp);
if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL)
nfsm_srvmtofh(&nsfh);
if ((mp = vfs_getvfs(&NFSRVFH_FHANDLE(&nsfh)->fh_fsid)) == NULL)
return (ESTALE);
vn_start_write(NULL, &mp, V_WAIT);
nfsm_srvnamesiz(len);
nd.ni_cnd.cn_cred = cred;
nd.ni_cnd.cn_nameiop = CREATE;
nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF;
error = nfs_namei(&nd, fhp, len, slp, nam, &md, &dpos,
error = nfs_namei(&nd, &nsfh, len, slp, nam, &md, &dpos,
&dirp, lwp, (nfsd->nd_flag & ND_KERBAUTH), FALSE);
if (dirp) {
if (v3)
@ -1568,7 +1559,7 @@ nfsrv_create(nfsd, slp, lwp, mrq)
vput(vp);
}
if (!error) {
error = vfs_composefh(vp, fhp, &fh_size);
error = nfsrv_composefh(vp, &nsfh, v3);
if (!error)
error = VOP_GETATTR(vp, &va, cred, lwp);
vput(vp);
@ -1589,15 +1580,15 @@ nfsrv_create(nfsd, slp, lwp, mrq)
vrele(dirp);
}
}
nfsm_reply(NFSX_SRVFH(v3) + NFSX_FATTR(v3) + NFSX_WCCDATA(v3));
nfsm_reply(NFSX_SRVFH(&nsfh, v3) + NFSX_FATTR(v3) + NFSX_WCCDATA(v3));
if (v3) {
if (!error) {
nfsm_srvpostop_fh(fhp);
nfsm_srvpostop_fh(&nsfh);
nfsm_srvpostop_attr(0, &va);
}
nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
} else {
nfsm_srvfhtom(fhp, v3);
nfsm_srvfhtom(&nsfh, v3);
nfsm_build(fp, struct nfs_fattr *, NFSX_V2FATTR);
nfsm_srvfillattr(&va, fp);
}
@ -1642,24 +1633,20 @@ nfsrv_mknod(nfsd, slp, lwp, mrq)
char *cp2;
struct mbuf *mb, *mreq;
struct vnode *vp, *dirp = (struct vnode *)0;
nfsfh_t nfh;
fhandle_t *fhp;
size_t fh_size;
nfsrvfh_t nsfh;
u_quad_t frev;
struct mount *mp = NULL;
nd.ni_cnd.cn_nameiop = 0;
fhp = &nfh.fh_generic;
fh_size = NFS_SMALLFH;
nfsm_srvmtofh(fhp);
if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL)
nfsm_srvmtofh(&nsfh);
if ((mp = vfs_getvfs(&NFSRVFH_FHANDLE(&nsfh)->fh_fsid)) == NULL)
return (ESTALE);
vn_start_write(NULL, &mp, V_WAIT);
nfsm_srvnamesiz(len);
nd.ni_cnd.cn_cred = cred;
nd.ni_cnd.cn_nameiop = CREATE;
nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF;
error = nfs_namei(&nd, fhp, len, slp, nam, &md, &dpos,
error = nfs_namei(&nd, &nsfh, len, slp, nam, &md, &dpos,
&dirp, lwp, (nfsd->nd_flag & ND_KERBAUTH), FALSE);
if (dirp)
dirfor_ret = VOP_GETATTR(dirp, &dirfor, cred, lwp);
@ -1734,7 +1721,7 @@ abort:
out:
vp = nd.ni_vp;
if (!error) {
error = vfs_composefh(vp, fhp, &fh_size);
error = nfsrv_composefh(vp, &nsfh, TRUE);
if (!error)
error = VOP_GETATTR(vp, &va, cred, lwp);
vput(vp);
@ -1743,9 +1730,10 @@ out:
diraft_ret = VOP_GETATTR(dirp, &diraft, cred, lwp);
vrele(dirp);
}
nfsm_reply(NFSX_SRVFH(1) + NFSX_POSTOPATTR(1) + NFSX_WCCDATA(1));
nfsm_reply(NFSX_SRVFH(&nsfh, TRUE) + NFSX_POSTOPATTR(1) +
NFSX_WCCDATA(1));
if (!error) {
nfsm_srvpostop_fh(fhp);
nfsm_srvpostop_fh(&nsfh);
nfsm_srvpostop_attr(0, &va);
}
nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
@ -1789,24 +1777,22 @@ nfsrv_remove(nfsd, slp, lwp, mrq)
struct mbuf *mb, *mreq;
struct vnode *vp, *dirp;
struct vattr dirfor, diraft;
nfsfh_t nfh;
fhandle_t *fhp;
nfsrvfh_t nsfh;
u_quad_t frev;
struct mount *mp = NULL;
#ifndef nolint
vp = (struct vnode *)0;
#endif
fhp = &nfh.fh_generic;
nfsm_srvmtofh(fhp);
if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL)
nfsm_srvmtofh(&nsfh);
if ((mp = vfs_getvfs(&NFSRVFH_FHANDLE(&nsfh)->fh_fsid)) == NULL)
return (ESTALE);
vn_start_write(NULL, &mp, V_WAIT);
nfsm_srvnamesiz(len);
nd.ni_cnd.cn_cred = cred;
nd.ni_cnd.cn_nameiop = DELETE;
nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF;
error = nfs_namei(&nd, fhp, len, slp, nam, &md, &dpos,
error = nfs_namei(&nd, &nsfh, len, slp, nam, &md, &dpos,
&dirp, lwp, (nfsd->nd_flag & ND_KERBAUTH), FALSE);
if (dirp) {
if (v3)
@ -1882,8 +1868,7 @@ nfsrv_rename(nfsd, slp, lwp, mrq)
struct vnode *fvp, *tvp, *tdvp, *fdirp = (struct vnode *)0;
struct vnode *tdirp = (struct vnode *)0;
struct vattr fdirfor, fdiraft, tdirfor, tdiraft;
nfsfh_t fnfh, tnfh;
fhandle_t *ffhp, *tfhp;
nfsrvfh_t fnsfh, tnsfh;
u_quad_t frev;
uid_t saved_uid;
struct mount *mp = NULL;
@ -1891,12 +1876,10 @@ nfsrv_rename(nfsd, slp, lwp, mrq)
#ifndef nolint
fvp = (struct vnode *)0;
#endif
ffhp = &fnfh.fh_generic;
tfhp = &tnfh.fh_generic;
fromnd.ni_cnd.cn_nameiop = 0;
tond.ni_cnd.cn_nameiop = 0;
nfsm_srvmtofh(ffhp);
if ((mp = vfs_getvfs(&ffhp->fh_fsid)) == NULL)
nfsm_srvmtofh(&fnsfh);
if ((mp = vfs_getvfs(&NFSRVFH_FHANDLE(&fnsfh)->fh_fsid)) == NULL)
return (ESTALE);
vn_start_write(NULL, &mp, V_WAIT);
nfsm_srvnamesiz(len);
@ -1908,7 +1891,7 @@ nfsrv_rename(nfsd, slp, lwp, mrq)
fromnd.ni_cnd.cn_cred = cred;
fromnd.ni_cnd.cn_nameiop = DELETE;
fromnd.ni_cnd.cn_flags = WANTPARENT | SAVESTART;
error = nfs_namei(&fromnd, ffhp, len, slp, nam, &md,
error = nfs_namei(&fromnd, &fnsfh, len, slp, nam, &md,
&dpos, &fdirp, lwp, (nfsd->nd_flag & ND_KERBAUTH), FALSE);
if (fdirp) {
if (v3)
@ -1928,7 +1911,7 @@ nfsrv_rename(nfsd, slp, lwp, mrq)
return (0);
}
fvp = fromnd.ni_vp;
nfsm_srvmtofh(tfhp);
nfsm_srvmtofh(&tnsfh);
if (v3) {
nfsm_dissect(tl, uint32_t *, NFSX_UNSIGNED);
len2 = fxdr_unsigned(uint32_t, *tl);
@ -1942,7 +1925,7 @@ nfsrv_rename(nfsd, slp, lwp, mrq)
tond.ni_cnd.cn_cred = cred;
tond.ni_cnd.cn_nameiop = RENAME;
tond.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART;
error = nfs_namei(&tond, tfhp, len2, slp, nam, &md,
error = nfs_namei(&tond, &tnsfh, len2, slp, nam, &md,
&dpos, &tdirp, lwp, (nfsd->nd_flag & ND_KERBAUTH), FALSE);
if (tdirp) {
if (v3)
@ -2101,20 +2084,17 @@ nfsrv_link(nfsd, slp, lwp, mrq)
struct mbuf *mb, *mreq;
struct vnode *vp, *xp, *dirp = (struct vnode *)0;
struct vattr dirfor, diraft, at;
nfsfh_t nfh, dnfh;
fhandle_t *fhp, *dfhp;
nfsrvfh_t nsfh, dnsfh;
u_quad_t frev;
struct mount *mp = NULL;
fhp = &nfh.fh_generic;
dfhp = &dnfh.fh_generic;
nfsm_srvmtofh(fhp);
if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL)
nfsm_srvmtofh(&nsfh);
if ((mp = vfs_getvfs(&NFSRVFH_FHANDLE(&nsfh)->fh_fsid)) == NULL)
return (ESTALE);
vn_start_write(NULL, &mp, V_WAIT);
nfsm_srvmtofh(dfhp);
nfsm_srvmtofh(&dnsfh);
nfsm_srvnamesiz(len);
error = nfsrv_fhtovp(fhp, FALSE, &vp, cred, slp, nam,
error = nfsrv_fhtovp(&nsfh, FALSE, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), FALSE);
if (error) {
nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3));
@ -2129,7 +2109,7 @@ nfsrv_link(nfsd, slp, lwp, mrq)
nd.ni_cnd.cn_cred = cred;
nd.ni_cnd.cn_nameiop = CREATE;
nd.ni_cnd.cn_flags = LOCKPARENT;
error = nfs_namei(&nd, dfhp, len, slp, nam, &md, &dpos,
error = nfs_namei(&nd, &dnsfh, len, slp, nam, &md, &dpos,
&dirp, lwp, (nfsd->nd_flag & ND_KERBAUTH), FALSE);
if (dirp) {
if (v3)
@ -2209,24 +2189,20 @@ nfsrv_symlink(nfsd, slp, lwp, mrq)
int v3 = (nfsd->nd_flag & ND_NFSV3);
struct mbuf *mb, *mreq;
struct vnode *dirp = (struct vnode *)0;
nfsfh_t nfh;
fhandle_t *fhp;
size_t fh_size;
nfsrvfh_t nsfh;
u_quad_t frev;
struct mount *mp = NULL;
nd.ni_cnd.cn_nameiop = 0;
fhp = &nfh.fh_generic;
fh_size = NFS_SMALLFH;
nfsm_srvmtofh(fhp);
if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL)
nfsm_srvmtofh(&nsfh);
if ((mp = vfs_getvfs(&NFSRVFH_FHANDLE(&nsfh)->fh_fsid)) == NULL)
return (ESTALE);
vn_start_write(NULL, &mp, V_WAIT);
nfsm_srvnamesiz(len);
nd.ni_cnd.cn_cred = cred;
nd.ni_cnd.cn_nameiop = CREATE;
nd.ni_cnd.cn_flags = LOCKPARENT;
error = nfs_namei(&nd, fhp, len, slp, nam, &md, &dpos,
error = nfs_namei(&nd, &nsfh, len, slp, nam, &md, &dpos,
&dirp, lwp, (nfsd->nd_flag & ND_KERBAUTH), FALSE);
if (dirp) {
if (v3)
@ -2286,7 +2262,7 @@ abortop:
error = VOP_SYMLINK(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &va, pathcp);
if (!error) {
if (v3) {
error = vfs_composefh(nd.ni_vp, fhp, &fh_size);
error = nfsrv_composefh(nd.ni_vp, &nsfh, v3);
if (!error)
error = VOP_GETATTR(nd.ni_vp, &va, cred, lwp);
vput(nd.ni_vp);
@ -2301,10 +2277,11 @@ out:
diraft_ret = VOP_GETATTR(dirp, &diraft, cred, lwp);
vrele(dirp);
}
nfsm_reply(NFSX_SRVFH(v3) + NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3));
nfsm_reply(NFSX_SRVFH(&nsfh, v3) + NFSX_POSTOPATTR(v3) +
NFSX_WCCDATA(v3));
if (v3) {
if (!error) {
nfsm_srvpostop_fh(fhp);
nfsm_srvpostop_fh(&nsfh);
nfsm_srvpostop_attr(0, &va);
}
nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
@ -2353,23 +2330,19 @@ nfsrv_mkdir(nfsd, slp, lwp, mrq)
char *cp2;
struct mbuf *mb, *mreq;
struct vnode *vp, *dirp = (struct vnode *)0;
nfsfh_t nfh;
fhandle_t *fhp;
size_t fh_size;
nfsrvfh_t nsfh;
u_quad_t frev;
struct mount *mp = NULL;
fhp = &nfh.fh_generic;
fh_size = NFS_SMALLFH;
nfsm_srvmtofh(fhp);
if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL)
nfsm_srvmtofh(&nsfh);
if ((mp = vfs_getvfs(&NFSRVFH_FHANDLE(&nsfh)->fh_fsid)) == NULL)
return (ESTALE);
vn_start_write(NULL, &mp, V_WAIT);
nfsm_srvnamesiz(len);
nd.ni_cnd.cn_cred = cred;
nd.ni_cnd.cn_nameiop = CREATE;
nd.ni_cnd.cn_flags = LOCKPARENT;
error = nfs_namei(&nd, fhp, len, slp, nam, &md, &dpos,
error = nfs_namei(&nd, &nsfh, len, slp, nam, &md, &dpos,
&dirp, lwp, (nfsd->nd_flag & ND_KERBAUTH), FALSE);
if (dirp) {
if (v3)
@ -2411,7 +2384,7 @@ nfsrv_mkdir(nfsd, slp, lwp, mrq)
error = VOP_MKDIR(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &va);
if (!error) {
vp = nd.ni_vp;
error = vfs_composefh(vp, fhp, &fh_size);
error = nfsrv_composefh(vp, &nsfh, v3);
if (!error)
error = VOP_GETATTR(vp, &va, cred, lwp);
vput(vp);
@ -2421,15 +2394,16 @@ out:
diraft_ret = VOP_GETATTR(dirp, &diraft, cred, lwp);
vrele(dirp);
}
nfsm_reply(NFSX_SRVFH(v3) + NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3));
nfsm_reply(NFSX_SRVFH(&nsfh, v3) + NFSX_POSTOPATTR(v3) +
NFSX_WCCDATA(v3));
if (v3) {
if (!error) {
nfsm_srvpostop_fh(fhp);
nfsm_srvpostop_fh(&nsfh);
nfsm_srvpostop_attr(0, &va);
}
nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
} else {
nfsm_srvfhtom(fhp, v3);
nfsm_srvfhtom(&nsfh, v3);
nfsm_build(fp, struct nfs_fattr *, NFSX_V2FATTR);
nfsm_srvfillattr(&va, fp);
}
@ -2472,22 +2446,20 @@ nfsrv_rmdir(nfsd, slp, lwp, mrq)
struct mbuf *mb, *mreq;
struct vnode *vp, *dirp = (struct vnode *)0;
struct vattr dirfor, diraft;
nfsfh_t nfh;
fhandle_t *fhp;
nfsrvfh_t nsfh;
struct nameidata nd;
u_quad_t frev;
struct mount *mp = NULL;
fhp = &nfh.fh_generic;
nfsm_srvmtofh(fhp);
if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL)
nfsm_srvmtofh(&nsfh);
if ((mp = vfs_getvfs(&NFSRVFH_FHANDLE(&nsfh)->fh_fsid)) == NULL)
return (ESTALE);
vn_start_write(NULL, &mp, V_WAIT);
nfsm_srvnamesiz(len);
nd.ni_cnd.cn_cred = cred;
nd.ni_cnd.cn_nameiop = DELETE;
nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF;
error = nfs_namei(&nd, fhp, len, slp, nam, &md, &dpos,
error = nfs_namei(&nd, &nsfh, len, slp, nam, &md, &dpos,
&dirp, lwp, (nfsd->nd_flag & ND_KERBAUTH), FALSE);
if (dirp) {
if (v3)
@ -2589,7 +2561,6 @@ struct flrep {
u_int32_t fl_fattr[NFSX_V3FATTR / sizeof (u_int32_t)];
u_int32_t fl_fhok;
u_int32_t fl_fhsize;
u_int32_t fl_nfh[NFSX_V3FH / sizeof (u_int32_t)];
};
int
@ -2614,8 +2585,7 @@ nfsrv_readdir(nfsd, slp, lwp, mrq)
char *cpos, *cend, *cp2, *rbuf;
struct vnode *vp;
struct vattr at;
nfsfh_t nfh;
fhandle_t *fhp;
nfsrvfh_t nsfh;
struct uio io;
struct iovec iv;
int len, nlen, rem, xfer, tsiz, i, error = 0, getret = 1;
@ -2625,8 +2595,7 @@ nfsrv_readdir(nfsd, slp, lwp, mrq)
off_t *cookies = NULL, *cookiep;
nfsuint64 jar;
fhp = &nfh.fh_generic;
nfsm_srvmtofh(fhp);
nfsm_srvmtofh(&nsfh);
if (v3) {
nfsm_dissect(tl, u_int32_t *, 5 * NFSX_UNSIGNED);
toff = fxdr_hyper(tl);
@ -2644,7 +2613,7 @@ nfsrv_readdir(nfsd, slp, lwp, mrq)
if (siz > xfer)
siz = xfer;
fullsiz = siz;
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
error = nfsrv_fhtovp(&nsfh, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), FALSE);
if (!error && vp->v_type != VDIR) {
error = ENOTDIR;
@ -2877,9 +2846,7 @@ nfsrv_readdirplus(nfsd, slp, lwp, mrq)
char *cpos, *cend, *cp2, *rbuf;
struct vnode *vp, *nvp;
struct flrep fl;
nfsfh_t nfh;
fhandle_t *fhp, *nfhp = (fhandle_t *)fl.fl_nfh;
size_t fh_size = sizeof(fl.fl_nfh);
nfsrvfh_t nsfh;
struct uio io;
struct iovec iv;
struct vattr va, at, *vap = &va;
@ -2889,8 +2856,7 @@ nfsrv_readdirplus(nfsd, slp, lwp, mrq)
u_quad_t frev, off, toff, verf;
off_t *cookies = NULL, *cookiep;
fhp = &nfh.fh_generic;
nfsm_srvmtofh(fhp);
nfsm_srvmtofh(&nsfh);
nfsm_dissect(tl, u_int32_t *, 6 * NFSX_UNSIGNED);
toff = fxdr_hyper(tl);
tl += 2;
@ -2904,7 +2870,7 @@ nfsrv_readdirplus(nfsd, slp, lwp, mrq)
if (siz > xfer)
siz = xfer;
fullsiz = siz;
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
error = nfsrv_fhtovp(&nsfh, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), FALSE);
if (!error && vp->v_type != VDIR) {
error = ENOTDIR;
@ -3042,6 +3008,8 @@ again:
/* Loop through the records and build reply */
while (cpos < cend && ncookies > 0) {
if (dp->d_fileno != 0 && dp->d_type != DT_WHT) {
nfsrvfh_t nnsfh;
nlen = dp->d_namlen;
rem = nfsm_rndup(nlen)-nlen;
@ -3051,7 +3019,7 @@ again:
*/
if (VFS_VGET(vp->v_mount, dp->d_fileno, &nvp))
goto invalid;
if (vfs_composefh(nvp, nfhp, &fh_size)) {
if (nfsrv_composefh(nvp, &nnsfh, TRUE)) {
vput(nvp);
goto invalid;
}
@ -3121,7 +3089,7 @@ again:
/*
* Now copy the flrep structure out.
*/
xfer = sizeof (struct flrep);
xfer = sizeof(struct flrep);
cp = (caddr_t)&fl;
while (xfer > 0) {
nfsm_clget;
@ -3135,6 +3103,24 @@ again:
if (xfer > 0)
cp += tsiz;
}
/*
* ... and filehandle.
*/
xfer = NFSRVFH_SIZE(&nnsfh);
cp = NFSRVFH_DATA(&nnsfh);
while (xfer > 0) {
nfsm_clget;
if ((bp + xfer) > be)
tsiz = be - bp;
else
tsiz = xfer;
memcpy(bp, cp, tsiz);
bp += tsiz;
xfer -= tsiz;
if (xfer > 0)
cp += tsiz;
}
}
invalid:
cpos += dp->d_reclen;
@ -3178,8 +3164,7 @@ nfsrv_commit(nfsd, slp, lwp, mrq)
kauth_cred_t cred = nfsd->nd_cr;
struct vattr bfor, aft;
struct vnode *vp;
nfsfh_t nfh;
fhandle_t *fhp;
nfsrvfh_t nsfh;
u_int32_t *tl;
int32_t t1;
caddr_t bpos;
@ -3190,9 +3175,8 @@ nfsrv_commit(nfsd, slp, lwp, mrq)
u_quad_t frev, off, end;
struct mount *mp = NULL;
fhp = &nfh.fh_generic;
nfsm_srvmtofh(fhp);
if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL)
nfsm_srvmtofh(&nsfh);
if ((mp = vfs_getvfs(&NFSRVFH_FHANDLE(&nsfh)->fh_fsid)) == NULL)
return (ESTALE);
vn_start_write(NULL, &mp, V_WAIT);
nfsm_dissect(tl, u_int32_t *, 3 * NFSX_UNSIGNED);
@ -3200,7 +3184,7 @@ nfsrv_commit(nfsd, slp, lwp, mrq)
off = fxdr_hyper(tl);
tl += 2;
cnt = fxdr_unsigned(uint32_t, *tl);
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
error = nfsrv_fhtovp(&nsfh, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), FALSE);
if (error) {
nfsm_reply(2 * NFSX_UNSIGNED);
@ -3256,13 +3240,11 @@ nfsrv_statfs(nfsd, slp, lwp, mrq)
struct mbuf *mb, *mreq;
struct vnode *vp;
struct vattr at;
nfsfh_t nfh;
fhandle_t *fhp;
nfsrvfh_t nsfh;
u_quad_t frev, tval;
fhp = &nfh.fh_generic;
nfsm_srvmtofh(fhp);
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
nfsm_srvmtofh(&nsfh);
error = nfsrv_fhtovp(&nsfh, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), FALSE);
if (error) {
nfsm_reply(NFSX_UNSIGNED);
@ -3331,14 +3313,12 @@ nfsrv_fsinfo(nfsd, slp, lwp, mrq)
struct mbuf *mb, *mreq;
struct vnode *vp;
struct vattr at;
nfsfh_t nfh;
fhandle_t *fhp;
nfsrvfh_t nsfh;
u_quad_t frev, maxfsize;
struct statvfs *sb;
fhp = &nfh.fh_generic;
nfsm_srvmtofh(fhp);
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
nfsm_srvmtofh(&nsfh);
error = nfsrv_fhtovp(&nsfh, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), FALSE);
if (error) {
nfsm_reply(NFSX_UNSIGNED);
@ -3407,13 +3387,11 @@ nfsrv_pathconf(nfsd, slp, lwp, mrq)
struct mbuf *mb, *mreq;
struct vnode *vp;
struct vattr at;
nfsfh_t nfh;
fhandle_t *fhp;
nfsrvfh_t nsfh;
u_quad_t frev;
fhp = &nfh.fh_generic;
nfsm_srvmtofh(fhp);
error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam,
nfsm_srvmtofh(&nsfh);
error = nfsrv_fhtovp(&nsfh, 1, &vp, cred, slp, nam,
&rdonly, (nfsd->nd_flag & ND_KERBAUTH), FALSE);
if (error) {
nfsm_reply(NFSX_UNSIGNED);

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs_subs.c,v 1.167 2006/09/02 07:26:47 christos Exp $ */
/* $NetBSD: nfs_subs.c,v 1.168 2006/09/02 12:40:36 yamt Exp $ */
/*
* Copyright (c) 1989, 1993
@ -70,7 +70,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: nfs_subs.c,v 1.167 2006/09/02 07:26:47 christos Exp $");
__KERNEL_RCSID(0, "$NetBSD: nfs_subs.c,v 1.168 2006/09/02 12:40:36 yamt Exp $");
#include "fs_nfs.h"
#include "opt_nfs.h"
@ -2086,9 +2086,9 @@ nfs_cookieheuristic(vp, flagp, l, cred)
* it is not.
*/
int
nfs_namei(ndp, fhp, len, slp, nam, mdp, dposp, retdirp, l, kerbflag, pubflag)
nfs_namei(ndp, nsfh, len, slp, nam, mdp, dposp, retdirp, l, kerbflag, pubflag)
struct nameidata *ndp;
fhandle_t *fhp;
nfsrvfh_t *nsfh;
uint32_t len;
struct nfssvc_sock *slp;
struct mbuf *nam;
@ -2154,7 +2154,7 @@ nfs_namei(ndp, fhp, len, slp, nam, mdp, dposp, retdirp, l, kerbflag, pubflag)
/*
* Extract and set starting directory.
*/
error = nfsrv_fhtovp(fhp, FALSE, &dp, ndp->ni_cnd.cn_cred, slp,
error = nfsrv_fhtovp(nsfh, FALSE, &dp, ndp->ni_cnd.cn_cred, slp,
nam, &rdonly, kerbflag, pubflag);
if (error)
goto out;
@ -2523,8 +2523,8 @@ nfsm_srvfattr(nfsd, vap, fp)
* - if not lockflag unlock it with VOP_UNLOCK()
*/
int
nfsrv_fhtovp(fhp, lockflag, vpp, cred, slp, nam, rdonlyp, kerbflag, pubflag)
fhandle_t *fhp;
nfsrv_fhtovp(nsfh, lockflag, vpp, cred, slp, nam, rdonlyp, kerbflag, pubflag)
nfsrvfh_t *nsfh;
int lockflag;
struct vnode **vpp;
kauth_cred_t cred;
@ -2538,10 +2538,12 @@ nfsrv_fhtovp(fhp, lockflag, vpp, cred, slp, nam, rdonlyp, kerbflag, pubflag)
kauth_cred_t credanon;
int error, exflags;
struct sockaddr_in *saddr;
fhandle_t *fhp;
fhp = NFSRVFH_FHANDLE(nsfh);
*vpp = (struct vnode *)0;
if (nfs_ispublicfh(fhp)) {
if (nfs_ispublicfh(nsfh)) {
if (!pubflag || !nfs_pub.np_valid)
return (ESTALE);
fhp = nfs_pub.np_handle;
@ -2597,20 +2599,24 @@ nfsrv_fhtovp(fhp, lockflag, vpp, cred, slp, nam, rdonlyp, kerbflag, pubflag)
/*
* WebNFS: check if a filehandle is a public filehandle. For v3, this
* means a length of 0, for v2 it means all zeroes. nfsm_srvmtofh has
* transformed this to all zeroes in both cases, so check for it.
* means a length of 0, for v2 it means all zeroes.
*/
int
nfs_ispublicfh(fhp)
fhandle_t *fhp;
nfs_ispublicfh(const nfsrvfh_t *nsfh)
{
char *cp = (char *)fhp;
const char *cp = (char *)(NFSRVFH_DATA(nsfh));
int i;
for (i = 0; i < NFSX_V3FH; i++)
if (NFSRVFH_SIZE(nsfh) == 0) {
return TRUE;
}
if (NFSRVFH_SIZE(nsfh) != NFSX_V2FH) {
return FALSE;
}
for (i = 0; i < NFSX_V2FH; i++)
if (*cp++ != 0)
return (FALSE);
return (TRUE);
return FALSE;
return TRUE;
}
#endif /* NFSSERVER */
@ -2977,3 +2983,50 @@ nfs_renewxid(struct nfsreq *req)
m_copyback(req->r_mreq, off, sizeof(xid), (void *)&xid);
req->r_xid = xid;
}
#if defined(NFSSERVER)
int
nfsrv_composefh(struct vnode *vp, nfsrvfh_t *nsfh, boolean_t v3)
{
int error;
size_t fhsize;
fhsize = NFSD_MAXFHSIZE;
error = vfs_composefh(vp, NFSRVFH_DATA(nsfh), &fhsize);
if (NFSX_FHTOOBIG_P(fhsize, v3)) {
error = EOPNOTSUPP;
}
if (error != 0) {
return error;
}
if (!v3 && fhsize < NFSX_V2FH) {
memset((char *)NFSRVFH_DATA(nsfh) + fhsize, 0,
NFSX_V2FH - fhsize);
fhsize = NFSX_V2FH;
}
if ((fhsize % NFSX_UNSIGNED) != 0) {
return EOPNOTSUPP;
}
nsfh->nsfh_size = fhsize;
return 0;
}
int
nfsrv_comparefh(const nfsrvfh_t *fh1, const nfsrvfh_t *fh2)
{
if (NFSRVFH_SIZE(fh1) != NFSRVFH_SIZE(fh2)) {
return NFSRVFH_SIZE(fh2) - NFSRVFH_SIZE(fh1);
}
return memcmp(NFSRVFH_DATA(fh1), NFSRVFH_DATA(fh2), NFSRVFH_SIZE(fh1));
}
void
nfsrv_copyfh(nfsrvfh_t *fh1, const nfsrvfh_t *fh2)
{
size_t size;
fh1->nsfh_size = size = NFSRVFH_SIZE(fh2);
memcpy(NFSRVFH_DATA(fh1), NFSRVFH_DATA(fh2), size);
}
#endif /* defined(NFSSERVER) */

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfs_var.h,v 1.62 2006/07/01 11:29:42 yamt Exp $ */
/* $NetBSD: nfs_var.h,v 1.63 2006/09/02 12:40:36 yamt Exp $ */
/*-
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@ -271,7 +271,7 @@ int nfs_getattrcache(struct vnode *, struct vattr *);
void nfs_delayedtruncate(struct vnode *);
int nfs_check_wccdata(struct nfsnode *, const struct timespec *,
struct timespec *, boolean_t);
int nfs_namei(struct nameidata *, fhandle_t *, uint32_t, struct nfssvc_sock *,
int nfs_namei(struct nameidata *, nfsrvfh_t *, uint32_t, struct nfssvc_sock *,
struct mbuf *, struct mbuf **, caddr_t *, struct vnode **, struct lwp *,
int, int);
void nfs_zeropad(struct mbuf *, int, int);
@ -280,9 +280,9 @@ void nfsm_srvwcc(struct nfsrv_descript *, int, struct vattr *, int,
void nfsm_srvpostopattr(struct nfsrv_descript *, int, struct vattr *,
struct mbuf **, char **);
void nfsm_srvfattr(struct nfsrv_descript *, struct vattr *, struct nfs_fattr *);
int nfsrv_fhtovp(fhandle_t *, int, struct vnode **, kauth_cred_t,
int nfsrv_fhtovp(nfsrvfh_t *, int, struct vnode **, kauth_cred_t,
struct nfssvc_sock *, struct mbuf *, int *, int, int);
int nfs_ispublicfh __P((fhandle_t *));
int nfs_ispublicfh __P((const nfsrvfh_t *));
int netaddr_match(int, union nethostaddr *, struct mbuf *);
/* flags for nfs_loadattrcache and friends */
@ -303,6 +303,10 @@ void nfs_cookieheuristic(struct vnode *, int *, struct lwp *, kauth_cred_t);
u_int32_t nfs_getxid(void);
void nfs_renewxid(struct nfsreq *);
int nfsrv_composefh(struct vnode *, nfsrvfh_t *, boolean_t);
int nfsrv_comparefh(const nfsrvfh_t *, const nfsrvfh_t *);
void nfsrv_copyfh(nfsrvfh_t *, const nfsrvfh_t *);
/* nfs_syscalls.c */
int sys_getfh(struct lwp *, void *, register_t *);
int sys_nfssvc(struct lwp *, void *, register_t *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfsm_subs.h,v 1.46 2006/08/08 13:07:32 yamt Exp $ */
/* $NetBSD: nfsm_subs.h,v 1.47 2006/09/02 12:40:36 yamt Exp $ */
/*
* Copyright (c) 1989, 1993
@ -121,20 +121,22 @@
#define nfsm_srvfhtom(f, v3) \
{ if (v3) { \
nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED + NFSX_V3FH); \
*tl++ = txdr_unsigned(NFSX_V3FH); \
memcpy((caddr_t)tl, (caddr_t)(f), NFSX_V3FH); \
nfsm_build(tl, u_int32_t *, NFSX_UNSIGNED + \
NFSRVFH_SIZE(f)); \
*tl++ = txdr_unsigned(NFSRVFH_SIZE(f)); \
memcpy(tl, NFSRVFH_DATA(f), NFSRVFH_SIZE(f)); \
} else { \
KASSERT(NFSRVFH_SIZE(f) == NFSX_V2FH); \
nfsm_build(cp, caddr_t, NFSX_V2FH); \
memcpy(cp, (caddr_t)(f), NFSX_V3FH); \
memset(cp + NFSX_V3FH, 0, NFSX_V2FH - NFSX_V3FH); \
memcpy(cp, NFSRVFH_DATA(f), NFSX_V2FH); \
} }
#define nfsm_srvpostop_fh(f) \
{ nfsm_build(tl, u_int32_t *, 2 * NFSX_UNSIGNED + NFSX_V3FH); \
{ nfsm_build(tl, u_int32_t *, \
2 * NFSX_UNSIGNED + NFSRVFH_SIZE(f)); \
*tl++ = nfs_true; \
*tl++ = txdr_unsigned(NFSX_V3FH); \
memcpy((caddr_t)tl, (caddr_t)(f), NFSX_V3FH); \
*tl++ = txdr_unsigned(NFSRVFH_SIZE(f)); \
memcpy(tl, NFSRVFH_DATA(f), NFSRVFH_SIZE(f)); \
}
/*
@ -469,23 +471,23 @@
goto nfsmout; \
} }
#define nfsm_srvmtofh(f) \
#define nfsm_srvmtofh(nsfh) \
{ int fhlen = NFSX_V3FH; \
if (nfsd->nd_flag & ND_NFSV3) { \
nfsm_dissect(tl, u_int32_t *, NFSX_UNSIGNED); \
fhlen = fxdr_unsigned(int, *tl); \
if (fhlen == 0) { \
memset((caddr_t)(f), 0, NFSX_V3FH); \
} else if (fhlen != NFSX_V3FH) { \
if (fhlen > NFSX_V3FHMAX || \
(fhlen < FHANDLE_SIZE_MIN && fhlen > 0)) { \
error = EBADRPC; \
nfsm_reply(0); \
} \
} else { \
fhlen = NFSX_V2FH; \
} \
(nsfh)->nsfh_size = fhlen; \
if (fhlen != 0) { \
nfsm_dissect(tl, u_int32_t *, NFSX_V3FH); \
memcpy( (caddr_t)(f), (caddr_t)tl, NFSX_V3FH); \
if ((nfsd->nd_flag & ND_NFSV3) == 0) \
nfsm_adv(NFSX_V2FH - NFSX_V3FH); \
nfsm_dissect(tl, u_int32_t *, fhlen); \
memcpy(NFSRVFH_DATA(nsfh), tl, fhlen); \
} \
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: nfsproto.h,v 1.15 2006/07/31 16:34:44 martin Exp $ */
/* $NetBSD: nfsproto.h,v 1.16 2006/09/02 12:40:36 yamt Exp $ */
/*
* Copyright (c) 1989, 1993
@ -130,7 +130,7 @@
/* variants for both versions */
#define NFSX_FH(v3) ((v3) ? (NFSX_V3FHMAX + NFSX_UNSIGNED) : \
NFSX_V2FH)
#define NFSX_SRVFH(v3) ((v3) ? NFSX_V3FH : NFSX_V2FH)
#define NFSX_SRVFH(nsfh, v3) (((v3) ? NFSX_UNSIGNED : 0) + NFSRVFH_SIZE(nsfh))
#define NFSX_FATTR(v3) ((v3) ? NFSX_V3FATTR : NFSX_V2FATTR)
#define NFSX_PREOPATTR(v3) ((v3) ? (7 * NFSX_UNSIGNED) : 0)
#define NFSX_POSTOPATTR(v3) ((v3) ? (NFSX_V3FATTR + NFSX_UNSIGNED) : 0)
@ -144,6 +144,7 @@
#define NFSX_READDIR(v3) ((v3) ? (5 * NFSX_UNSIGNED) : \
(2 * NFSX_UNSIGNED))
#define NFSX_STATFS(v3) ((v3) ? NFSX_V3STATFS : NFSX_V2STATFS)
#define NFSX_FHTOOBIG_P(sz, v3) ((sz) > ((v3) ? NFSX_V3FHMAX : NFSX_V2FH))
/* nfs rpc procedure numbers (before version mapping) */
#define NFSPROC_NULL 0

View File

@ -1,4 +1,4 @@
/* $NetBSD: nqnfs.h,v 1.20 2006/07/13 12:00:26 martin Exp $ */
/* $NetBSD: nqnfs.h,v 1.21 2006/09/02 12:40:36 yamt Exp $ */
/*
* Copyright (c) 1992, 1993
@ -81,7 +81,6 @@
* hashed on lc_fh.
*/
#define LC_MOREHOSTSIZ 10
#define LC_MAXFIDSIZ 64
struct nqhost {
union {
@ -116,8 +115,7 @@ struct nqlease {
time_t lc_expiry; /* Expiry time (sec) */
struct nqhost lc_host; /* Host that got lease */
struct nqm *lc_morehosts; /* Other hosts that share read lease */
fsid_t lc_fsid; /* Fhandle */
char lc_fiddata[LC_MAXFIDSIZ];
nfsrvfh_t lc_fh;
struct vnode *lc_vp; /* Soft reference to associated vnode */
};
#define lc_flag lc_host.lph_un.un_udp.udp_flag