mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-15 10:17:20 +00:00
Use function pointers to remove the depenancy cross dependancy on nfs4
and the nfs3 client. Also fix some bugs that happen to be causing crashes in both v3 and v4 introduced by the v4 import. Submitted by: Jim Rees <rees@umich.edu> Approved by: re
This commit is contained in:
parent
1647bdb853
commit
90abe7f294
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=122953
@ -144,89 +144,20 @@ static struct vfsops nfs_vfsops = {
|
||||
};
|
||||
VFS_SET(nfs_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 *);
|
||||
|
||||
#ifdef NFS4DISKLESS
|
||||
/*
|
||||
* This structure must be filled in by a primary bootstrap or bootstrap
|
||||
* server for a diskless/dataless machine. It is initialized below just
|
||||
* to ensure that it is allocated to initialized data (.data not .bss).
|
||||
*/
|
||||
struct nfs_diskless nfs_diskless = { { { 0 } } };
|
||||
struct nfsv3_diskless nfsv3_diskless = { { { 0 } } };
|
||||
int nfs_diskless_valid = 0;
|
||||
|
||||
SYSCTL_INT(_vfs_nfs4, OID_AUTO, diskless_valid, CTLFLAG_RD,
|
||||
&nfs_diskless_valid, 0, "");
|
||||
|
||||
SYSCTL_STRING(_vfs_nfs4, OID_AUTO, diskless_rootpath, CTLFLAG_RD,
|
||||
nfsv3_diskless.root_hostnam, 0, "");
|
||||
|
||||
SYSCTL_OPAQUE(_vfs_nfs4, OID_AUTO, diskless_rootaddr, CTLFLAG_RD,
|
||||
&nfsv3_diskless.root_saddr, sizeof nfsv3_diskless.root_saddr,
|
||||
"%Ssockaddr_in", "");
|
||||
|
||||
SYSCTL_STRING(_vfs_nfs4, OID_AUTO, diskless_swappath, CTLFLAG_RD,
|
||||
nfsv3_diskless.swap_hostnam, 0, "");
|
||||
|
||||
SYSCTL_OPAQUE(_vfs_nfs4, OID_AUTO, diskless_swapaddr, CTLFLAG_RD,
|
||||
&nfsv3_diskless.swap_saddr, sizeof nfsv3_diskless.swap_saddr,
|
||||
"%Ssockaddr_in","");
|
||||
|
||||
static int nfs_mountdiskless(char *, char *, int,
|
||||
struct sockaddr_in *, struct nfs_args *,
|
||||
struct thread *, struct vnode **, struct mount **);
|
||||
static void nfs_convert_diskless(void);
|
||||
static void nfs_convert_oargs(struct nfs_args *args,
|
||||
struct onfs_args *oargs);
|
||||
|
||||
static void
|
||||
nfs_convert_oargs(struct nfs_args *args, struct onfs_args *oargs)
|
||||
{
|
||||
|
||||
args->version = NFS_ARGSVERSION;
|
||||
args->addr = oargs->addr;
|
||||
args->addrlen = oargs->addrlen;
|
||||
args->sotype = oargs->sotype;
|
||||
args->proto = oargs->proto;
|
||||
args->fh = oargs->fh;
|
||||
args->fhsize = oargs->fhsize;
|
||||
args->flags = oargs->flags;
|
||||
args->wsize = oargs->wsize;
|
||||
args->rsize = oargs->rsize;
|
||||
args->readdirsize = oargs->readdirsize;
|
||||
args->timeo = oargs->timeo;
|
||||
args->retrans = oargs->retrans;
|
||||
args->maxgrouplist = oargs->maxgrouplist;
|
||||
args->readahead = oargs->readahead;
|
||||
args->deadthresh = oargs->deadthresh;
|
||||
args->hostname = oargs->hostname;
|
||||
}
|
||||
|
||||
static void
|
||||
nfs_convert_diskless(void)
|
||||
{
|
||||
|
||||
bcopy(&nfs_diskless.myif, &nfsv3_diskless.myif,
|
||||
sizeof(struct ifaliasreq));
|
||||
bcopy(&nfs_diskless.mygateway, &nfsv3_diskless.mygateway,
|
||||
sizeof(struct sockaddr_in));
|
||||
nfs_convert_oargs(&nfsv3_diskless.root_args,&nfs_diskless.root_args);
|
||||
nfsv3_diskless.root_fhsize = NFSX_V2FH;
|
||||
bcopy(nfs_diskless.root_fh, nfsv3_diskless.root_fh, NFSX_V2FH);
|
||||
bcopy(&nfs_diskless.root_saddr,&nfsv3_diskless.root_saddr,
|
||||
sizeof(struct sockaddr_in));
|
||||
bcopy(nfs_diskless.root_hostnam, nfsv3_diskless.root_hostnam, MNAMELEN);
|
||||
nfsv3_diskless.root_time = nfs_diskless.root_time;
|
||||
bcopy(nfs_diskless.my_hostnam, nfsv3_diskless.my_hostnam,
|
||||
MAXHOSTNAMELEN);
|
||||
nfs_diskless_valid = 3;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
nfs4_init(struct vfsconf *vfsp)
|
||||
{
|
||||
@ -632,10 +563,10 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *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;
|
||||
|
||||
/* XXX - this is to make some other code work. Sort of ugly. */
|
||||
argp->flags |= (NFSMNT_NFSV3 | NFSMNT_NFSV4);
|
||||
|
||||
nfs_decode_args(nmp, argp);
|
||||
|
@ -214,6 +214,20 @@ extern TAILQ_HEAD(nfs_reqq, nfsreq) nfs_reqq;
|
||||
#define R_MUSTRESEND 0x40 /* Must resend request */
|
||||
#define R_GETONEREP 0x80 /* Probe for one reply only */
|
||||
|
||||
/*
|
||||
* Pointers to ops that differ from v3 to v4
|
||||
*/
|
||||
struct nfs_rpcops {
|
||||
int (*nr_readrpc)(struct vnode *vp, struct uio *uiop, struct ucred *cred);
|
||||
int (*nr_writerpc)(struct vnode *vp, struct uio *uiop, struct ucred *cred,
|
||||
int *iomode, int *must_commit);
|
||||
int (*nr_writebp)(struct buf *bp, int force, struct thread *td);
|
||||
int (*nr_readlinkrpc)(struct vnode *vp, struct uio *uiop, struct ucred *cred);
|
||||
void (*nr_invaldir)(struct vnode *vp);
|
||||
int (*nr_commit)(struct vnode *vp, u_quad_t offset, int cnt,
|
||||
struct ucred *cred, struct thread *td);
|
||||
};
|
||||
|
||||
/*
|
||||
* Defines for WebNFS
|
||||
*/
|
||||
|
@ -187,10 +187,7 @@ nfs_getpages(struct vop_getpages_args *ap)
|
||||
uio.uio_rw = UIO_READ;
|
||||
uio.uio_td = td;
|
||||
|
||||
if ((nmp->nm_flag & NFSMNT_NFSV4) != 0)
|
||||
error = nfs4_readrpc(vp, &uio, cred);
|
||||
else
|
||||
error = nfs_readrpc(vp, &uio, cred);
|
||||
error = (nmp->nm_rpcops->nr_readrpc)(vp, &uio, cred);
|
||||
pmap_qremove(kva, npages);
|
||||
|
||||
relpbuf(bp, &nfs_pbuf_freecnt);
|
||||
@ -352,10 +349,7 @@ nfs_putpages(struct vop_putpages_args *ap)
|
||||
else
|
||||
iomode = NFSV3WRITE_FILESYNC;
|
||||
|
||||
if ((nmp->nm_flag & NFSMNT_NFSV4) != 0)
|
||||
error = nfs4_writerpc(vp, &uio, cred, &iomode, &must_commit);
|
||||
else
|
||||
error = nfs_writerpc(vp, &uio, cred, &iomode, &must_commit);
|
||||
error = (nmp->nm_rpcops->nr_writerpc)(vp, &uio, cred, &iomode, &must_commit);
|
||||
|
||||
pmap_qremove(kva, npages);
|
||||
relpbuf(bp, &nfs_pbuf_freecnt);
|
||||
@ -428,7 +422,7 @@ nfs_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
|
||||
if (vp->v_type != VREG) {
|
||||
if (vp->v_type != VDIR)
|
||||
panic("nfs: bioread, not dir");
|
||||
nfs_invaldir(vp);
|
||||
(nmp->nm_rpcops->nr_invaldir)(vp);
|
||||
error = nfs_vinvalbuf(vp, V_SAVE, cred, td, 1);
|
||||
if (error)
|
||||
return (error);
|
||||
@ -444,7 +438,7 @@ nfs_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
|
||||
return (error);
|
||||
if (np->n_mtime != vattr.va_mtime.tv_sec) {
|
||||
if (vp->v_type == VDIR)
|
||||
nfs_invaldir(vp);
|
||||
(nmp->nm_rpcops->nr_invaldir)(vp);
|
||||
error = nfs_vinvalbuf(vp, V_SAVE, cred, td, 1);
|
||||
if (error)
|
||||
return (error);
|
||||
@ -592,7 +586,7 @@ nfs_bioread(struct vnode *vp, struct uio *uio, int ioflag, struct ucred *cred)
|
||||
}
|
||||
while (error == NFSERR_BAD_COOKIE) {
|
||||
printf("got bad cookie vp %p bp %p\n", vp, bp);
|
||||
nfs_invaldir(vp);
|
||||
(nmp->nm_rpcops->nr_invaldir)(vp);
|
||||
error = nfs_vinvalbuf(vp, 0, cred, td, 1);
|
||||
/*
|
||||
* Yuck! The directory has been modified on the
|
||||
@ -1022,10 +1016,7 @@ nfs_write(struct vop_write_args *ap)
|
||||
break;
|
||||
} else if ((n + on) == biosize) {
|
||||
bp->b_flags |= B_ASYNC;
|
||||
if ((nmp->nm_flag & NFSMNT_NFSV4) != 0)
|
||||
(void)nfs4_writebp(bp, 0, 0);
|
||||
else
|
||||
(void)nfs_writebp(bp, 0, 0);
|
||||
(void) (nmp->nm_rpcops->nr_writebp)(bp, 0, 0);
|
||||
} else {
|
||||
bdwrite(bp);
|
||||
}
|
||||
@ -1330,7 +1321,7 @@ nfs_doio(struct buf *bp, struct ucred *cr, struct thread *td)
|
||||
case VREG:
|
||||
uiop->uio_offset = ((off_t)bp->b_blkno) * DEV_BSIZE;
|
||||
nfsstats.read_bios++;
|
||||
error = nfs_readrpc(vp, uiop, cr);
|
||||
error = (nmp->nm_rpcops->nr_readrpc)(vp, uiop, cr);
|
||||
|
||||
if (!error) {
|
||||
if (uiop->uio_resid) {
|
||||
@ -1363,7 +1354,7 @@ nfs_doio(struct buf *bp, struct ucred *cr, struct thread *td)
|
||||
case VLNK:
|
||||
uiop->uio_offset = (off_t)0;
|
||||
nfsstats.readlink_bios++;
|
||||
error = nfs_readlinkrpc(vp, uiop, cr);
|
||||
error = (nmp->nm_rpcops->nr_readlinkrpc)(vp, uiop, cr);
|
||||
break;
|
||||
case VDIR:
|
||||
nfsstats.readdir_bios++;
|
||||
@ -1404,7 +1395,7 @@ nfs_doio(struct buf *bp, struct ucred *cr, struct thread *td)
|
||||
|
||||
off = ((u_quad_t)bp->b_blkno) * DEV_BSIZE + bp->b_dirtyoff;
|
||||
bp->b_flags |= B_WRITEINPROG;
|
||||
retv = nfs_commit(
|
||||
retv = (nmp->nm_rpcops->nr_commit)(
|
||||
bp->b_vp, off, bp->b_dirtyend-bp->b_dirtyoff,
|
||||
bp->b_wcred, td);
|
||||
bp->b_flags &= ~B_WRITEINPROG;
|
||||
@ -1442,7 +1433,7 @@ nfs_doio(struct buf *bp, struct ucred *cr, struct thread *td)
|
||||
iomode = NFSV3WRITE_FILESYNC;
|
||||
|
||||
bp->b_flags |= B_WRITEINPROG;
|
||||
error = nfs_writerpc(vp, uiop, cr, &iomode, &must_commit);
|
||||
error = (nmp->nm_rpcops->nr_writerpc)(vp, uiop, cr, &iomode, &must_commit);
|
||||
|
||||
/*
|
||||
* When setting B_NEEDCOMMIT also set B_CLUSTEROK to try
|
||||
|
@ -763,10 +763,6 @@ nfs_invaldir(struct vnode *vp)
|
||||
if (vp->v_type != VDIR)
|
||||
panic("nfs: invaldir not dir");
|
||||
#endif
|
||||
if ((VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NFSV4) != 0) {
|
||||
nfs4_invaldir(vp);
|
||||
return;
|
||||
}
|
||||
np->n_direofoffset = 0;
|
||||
np->n_cookieverf.nfsuquad[0] = 0;
|
||||
np->n_cookieverf.nfsuquad[1] = 0;
|
||||
|
@ -124,6 +124,15 @@ VFS_SET(nfs_vfsops, nfs, VFCF_NETWORK);
|
||||
/* So that loader and kldload(2) can find us, wherever we are.. */
|
||||
MODULE_VERSION(nfs, 1);
|
||||
|
||||
static struct nfs_rpcops nfs_rpcops = {
|
||||
nfs_readrpc,
|
||||
nfs_writerpc,
|
||||
nfs_writebp,
|
||||
nfs_readlinkrpc,
|
||||
nfs_invaldir,
|
||||
nfs_commit,
|
||||
};
|
||||
|
||||
/*
|
||||
* This structure must be filled in by a primary bootstrap or bootstrap
|
||||
* server for a diskless/dataless machine. It is initialized below just
|
||||
@ -790,6 +799,7 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
|
||||
/* Set up the sockets and per-host congestion */
|
||||
nmp->nm_sotype = argp->sotype;
|
||||
nmp->nm_soproto = argp->proto;
|
||||
nmp->nm_rpcops = &nfs_rpcops;
|
||||
|
||||
nfs_decode_args(nmp, argp);
|
||||
|
||||
|
@ -80,6 +80,7 @@ struct nfsmount {
|
||||
short nm_bufqwant; /* process wants to add to the queue */
|
||||
int nm_bufqiods; /* number of iods processing queue */
|
||||
u_int64_t nm_maxfilesize; /* maximum file size */
|
||||
struct nfs_rpcops *nm_rpcops;
|
||||
|
||||
/* NFSv4 */
|
||||
uint64_t nm_clientid;
|
||||
|
@ -128,11 +128,7 @@ struct nfsnode {
|
||||
struct lock n_rslock;
|
||||
struct nfs4_fctx n_rfc;
|
||||
struct nfs4_fctx n_wfc;
|
||||
/*
|
||||
* The last component name is needed for the NFSv4 OPEN
|
||||
* operation.
|
||||
*/
|
||||
u_char *n_name;
|
||||
u_char *n_name; /* leaf name, for v4 OPEN op */
|
||||
uint32_t n_namelen;
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user