Modify the NFS clients and the NLM so that the NLM can be used

by both clients. Since the NLM uses various fields of the
nfsmount structure, those fields were extracted and put in a
separate nfs_mountcommon structure stored in sys/nfs/nfs_mountcommon.h.
This structure also has a function pointer for a function that
extracts the required information from the mount point and nfs vnode
for that particular client, for information stored differently by the
clients.

Reviewed by:	jhb
MFC after:	2 weeks
This commit is contained in:
Rick Macklem 2010-10-19 00:20:00 +00:00
parent 4f2bbc00f2
commit ca27c028d8
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=214048
14 changed files with 168 additions and 45 deletions

View File

@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/fcntl.h>
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mount.h>
@ -53,12 +54,13 @@ __FBSDID("$FreeBSD$");
#include <fs/nfsclient/nfsmount.h>
#include <fs/nfsclient/nfs.h>
#include <nfs/nfs_lock.h>
extern struct vop_vector newnfs_vnodeops;
extern struct buf_ops buf_ops_newnfs;
MALLOC_DECLARE(M_NEWNFSREQ);
uma_zone_t newnfsnode_zone;
vop_reclaim_t *ncl_reclaim_p = NULL;
void
ncl_nhinit(void)
@ -238,8 +240,8 @@ ncl_reclaim(struct vop_reclaim_args *ap)
* If the NLM is running, give it a chance to abort pending
* locks.
*/
if (ncl_reclaim_p)
ncl_reclaim_p(ap);
if (nfs_reclaim_p != NULL)
nfs_reclaim_p(ap);
/*
* Destroy the vm object and flush associated pages.

View File

@ -96,10 +96,13 @@ SYSCTL_INT(_vfs_newnfs, NFS_TPRINTF_DELAY,
static void nfs_sec_name(char *, int *);
static void nfs_decode_args(struct mount *mp, struct nfsmount *nmp,
struct nfs_args *argp, struct ucred *, struct thread *);
struct nfs_args *argp, const char *, struct ucred *,
struct thread *);
static int mountnfs(struct nfs_args *, struct mount *,
struct sockaddr *, char *, u_char *, u_char *, u_char *,
struct vnode **, struct ucred *, struct thread *, int);
static void nfs_getnlminfo(struct vnode *, uint8_t *, int *,
struct sockaddr_storage *, int *, off_t *);
static vfs_mount_t nfs_mount;
static vfs_cmount_t nfs_cmount;
static vfs_unmount_t nfs_unmount;
@ -518,10 +521,11 @@ nfs_sec_name(char *sec, int *flagsp)
static void
nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp,
struct ucred *cred, struct thread *td)
const char *hostname, struct ucred *cred, struct thread *td)
{
int s;
int adjsock;
char *p;
s = splnet();
@ -659,6 +663,14 @@ nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp,
nmp->nm_sotype = argp->sotype;
nmp->nm_soproto = argp->proto;
}
if (hostname != NULL) {
strlcpy(nmp->nm_hostname, hostname,
sizeof(nmp->nm_hostname));
p = strchr(nmp->nm_hostname, ':');
if (p != NULL)
*p = '\0';
}
}
static const char *nfs_opts[] = { "from",
@ -933,7 +945,7 @@ nfs_mount(struct mount *mp)
NFSMNT_INTEGRITY |
NFSMNT_PRIVACY |
NFSMNT_NOLOCKD /*|NFSMNT_XLATECOOKIE*/));
nfs_decode_args(mp, nmp, &args, td->td_ucred, td);
nfs_decode_args(mp, nmp, &args, NULL, td->td_ucred, td);
goto out;
}
@ -1110,13 +1122,14 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
nmp->nm_sockreq.nr_cred = crhold(cred);
mtx_init(&nmp->nm_sockreq.nr_mtx, "nfssock", NULL, MTX_DEF);
mp->mnt_data = nmp;
nmp->nm_getinfo = nfs_getnlminfo;
}
vfs_getnewfsid(mp);
nmp->nm_mountp = mp;
mtx_init(&nmp->nm_mtx, "NFSmount lock", NULL, MTX_DEF | MTX_DUPOK);
nmp->nm_negnametimeo = negnametimeo;
nfs_decode_args(mp, nmp, argp, cred, td);
nfs_decode_args(mp, nmp, argp, hst, cred, td);
/*
* V2 can only handle 32 bit filesizes. A 4GB-1 limit may be too
@ -1447,3 +1460,26 @@ nfs_sysctl(struct mount *mp, fsctlop_t op, struct sysctl_req *req)
return (0);
}
/*
* Extract the information needed by the nlm from the nfs vnode.
*/
static void
nfs_getnlminfo(struct vnode *vp, uint8_t *fhp, int *fhlenp,
struct sockaddr_storage *sp, int *is_v3p, off_t *sizep)
{
struct nfsmount *nmp;
struct nfsnode *np = VTONFS(vp);
nmp = VFSTONFS(vp->v_mount);
if (fhlenp != NULL)
*fhlenp = np->n_fhp->nfh_len;
if (fhp != NULL)
bcopy(np->n_fhp->nfh_fh, fhp, np->n_fhp->nfh_len);
if (sp != NULL)
bcopy(nmp->nm_nam, sp, min(nmp->nm_nam->sa_len, sizeof(*sp)));
if (is_v3p != NULL)
*is_v3p = NFS_ISV3(vp);
if (sizep != NULL)
*sizep = np->n_size;
}

View File

@ -84,7 +84,6 @@ __FBSDID("$FreeBSD$");
extern struct nfsstats newnfsstats;
MALLOC_DECLARE(M_NEWNFSREQ);
vop_advlock_t *ncl_advlock_p = NULL;
/*
* Ifdef for FreeBSD-current merged buffer cache. It is unfortunate that these
@ -2937,8 +2936,8 @@ nfs_advlock(struct vop_advlock_args *ap)
VOP_UNLOCK(vp, 0);
error = lf_advlock(ap, &(vp->v_lockf), size);
} else {
if (ncl_advlock_p)
error = ncl_advlock_p(ap);
if (nfs_advlock_p != NULL)
error = nfs_advlock_p(ap);
else {
VOP_UNLOCK(vp, 0);
error = ENOLCK;

View File

@ -35,22 +35,19 @@
#ifndef _NFSCLIENT_NFSMOUNT_H_
#define _NFSCLIENT_NFSMOUNT_H_
#include <nfs/nfs_mountcommon.h>
/*
* Mount structure.
* One allocated on every NFS mount.
* Holds NFS specific information for mount.
*/
struct nfsmount {
struct mtx nm_mtx;
int nm_flag; /* Flags for soft/hard... */
int nm_state; /* Internal state flags */
struct mount *nm_mountp; /* Vfs structure for this filesystem */
struct nfsmount_common nm_com; /* Common fields for nlm */
int nm_numgrps; /* Max. size of groupslist */
u_char nm_fh[NFSX_FHMAX]; /* File handle of root dir */
int nm_fhsize; /* Size of root file handle */
struct nfssockreq nm_sockreq; /* Socket Info */
int nm_timeo; /* Init timer for NFSMNT_DUMBTIMR */
int nm_retry; /* Max retries */
int nm_timeouts; /* Request timeouts */
int nm_rsize; /* Max size of read rpc */
int nm_wsize; /* Max size of write rpc */
@ -89,6 +86,14 @@ struct nfsmount {
#define nm_soproto nm_sockreq.nr_soproto
#define nm_client nm_sockreq.nr_client
#define nm_krbname nm_name
#define nm_mtx nm_com.nmcom_mtx
#define nm_flag nm_com.nmcom_flag
#define nm_state nm_com.nmcom_state
#define nm_mountp nm_com.nmcom_mountp
#define nm_timeo nm_com.nmcom_timeo
#define nm_retry nm_com.nmcom_retry
#define nm_hostname nm_com.nmcom_hostname
#define nm_getinfo nm_com.nmcom_getinfo
#define NFSMNT_DIRPATH(m) (&((m)->nm_name[(m)->nm_krbnamelen + 1]))
#define NFSMNT_SRVKRBNAME(m) \

View File

@ -62,6 +62,9 @@ __FBSDID("$FreeBSD$");
extern void (*nlminfo_release_p)(struct proc *p);
vop_advlock_t *nfs_advlock_p = nfs_dolock;
vop_reclaim_t *nfs_reclaim_p = NULL;
MALLOC_DEFINE(M_NFSLOCK, "nfsclient_lock", "NFS lock request");
MALLOC_DEFINE(M_NLMINFO, "nfsclient_nlminfo", "NFS lock process structure");
@ -236,20 +239,19 @@ nfs_dolock(struct vop_advlock_args *ap)
int error;
struct flock *fl;
struct proc *p;
struct nfsmount *nmp;
td = curthread;
p = td->td_proc;
vp = ap->a_vp;
fl = ap->a_fl;
nmp = VFSTONFS(vp->v_mount);
ASSERT_VOP_LOCKED(vp, "nfs_dolock");
bcopy(VFSTONFS(vp->v_mount)->nm_nam, &msg.lm_addr,
min(sizeof msg.lm_addr, VFSTONFS(vp->v_mount)->nm_nam->sa_len));
msg.lm_fh_len = NFS_ISV3(vp) ? VTONFS(vp)->n_fhsize : NFSX_V2FH;
bcopy(VTONFS(vp)->n_fhp, msg.lm_fh, msg.lm_fh_len);
msg.lm_nfsv3 = NFS_ISV3(vp);
nmp->nm_getinfo(vp, msg.lm_fh, &msg.lm_fh_len, &msg.lm_addr,
&msg.lm_nfsv3, NULL);
VOP_UNLOCK(vp, 0);
/*

View File

@ -87,4 +87,6 @@ struct lockd_ans {
#ifdef _KERNEL
int nfs_dolock(struct vop_advlock_args *ap);
extern vop_advlock_t *nfs_advlock_p;
extern vop_reclaim_t *nfs_reclaim_p;
#endif

51
sys/nfs/nfs_mountcommon.h Normal file
View File

@ -0,0 +1,51 @@
/*-
* Copyright (c) 2009 Rick Macklem, University of Guelph
* All rights reserved.
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
*
* $FreeBSD$
*/
#ifndef _NFS_MOUNTCOMMON_H_
#define _NFS_MOUNTCOMMON_H_
/*
* The common fields of the nfsmount structure for the two clients
* used by the nlm. It includes a function pointer that provides
* a mechanism for getting the client specific info for an nfs vnode.
*/
typedef void nfs_getinfofromvp_ftype(struct vnode *, uint8_t *, int *,
struct sockaddr_storage *, int *, off_t *);
struct nfsmount_common {
struct mtx nmcom_mtx;
int nmcom_flag; /* Flags for soft/hard... */
int nmcom_state; /* Internal state flags */
struct mount *nmcom_mountp; /* Vfs structure for this filesystem */
int nmcom_timeo; /* Init timer for NFSMNT_DUMBTIMR */
int nmcom_retry; /* Max retries */
char nmcom_hostname[MNAMELEN]; /* server's name */
nfs_getinfofromvp_ftype *nmcom_getinfo; /* Get info from nfsnode */
};
#endif /* _NFS_MOUNTCOMMON_H_ */

View File

@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/fcntl.h>
#include <sys/fnv_hash.h>
#include <sys/lock.h>
#include <sys/malloc.h>
@ -51,6 +52,7 @@ __FBSDID("$FreeBSD$");
#include <vm/uma.h>
#include <nfs/nfsproto.h>
#include <nfs/nfs_lock.h>
#include <nfsclient/nfs.h>
#include <nfsclient/nfsnode.h>
#include <nfsclient/nfsmount.h>

View File

@ -115,6 +115,8 @@ static void nfs_decode_args(struct mount *mp, struct nfsmount *nmp,
static int mountnfs(struct nfs_args *, struct mount *,
struct sockaddr *, char *, struct vnode **,
struct ucred *cred, int);
static void nfs_getnlminfo(struct vnode *, uint8_t *, int *,
struct sockaddr_storage *, int *, off_t *);
static vfs_mount_t nfs_mount;
static vfs_cmount_t nfs_cmount;
static vfs_unmount_t nfs_unmount;
@ -1202,6 +1204,7 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
bzero((caddr_t)nmp, sizeof (struct nfsmount));
TAILQ_INIT(&nmp->nm_bufq);
mp->mnt_data = nmp;
nmp->nm_getinfo = nfs_getnlminfo;
}
vfs_getnewfsid(mp);
nmp->nm_mountp = mp;
@ -1490,3 +1493,27 @@ nfs_sysctl(struct mount *mp, fsctlop_t op, struct sysctl_req *req)
}
return (0);
}
/*
* Extract the information needed by the nlm from the nfs vnode.
*/
static void
nfs_getnlminfo(struct vnode *vp, uint8_t *fhp, int *fhlenp,
struct sockaddr_storage *sp, int *is_v3p, off_t *sizep)
{
struct nfsmount *nmp;
struct nfsnode *np = VTONFS(vp);
nmp = VFSTONFS(vp->v_mount);
if (fhlenp != NULL)
*fhlenp = np->n_fhsize;
if (fhp != NULL)
bcopy(np->n_fhp, fhp, np->n_fhsize);
if (sp != NULL)
bcopy(nmp->nm_nam, sp, min(nmp->nm_nam->sa_len, sizeof(*sp)));
if (is_v3p != NULL)
*is_v3p = NFS_ISV3(vp);
if (sizep != NULL)
*sizep = np->n_size;
}

View File

@ -215,8 +215,6 @@ struct mtx nfs_iod_mtx;
enum nfsiod_state nfs_iodwant[NFS_MAXASYNCDAEMON];
struct nfsmount *nfs_iodmount[NFS_MAXASYNCDAEMON];
int nfs_numasync = 0;
vop_advlock_t *nfs_advlock_p = nfs_dolock;
vop_reclaim_t *nfs_reclaim_p = NULL;
#define DIRHDSIZ (sizeof (struct dirent) - (MAXNAMLEN + 1))
SYSCTL_DECL(_vfs_nfs);

View File

@ -36,6 +36,10 @@
#ifndef _NFSCLIENT_NFSMOUNT_H_
#define _NFSCLIENT_NFSMOUNT_H_
#include <sys/socket.h>
#include <nfs/nfs_mountcommon.h>
#include <rpc/types.h>
#include <rpc/auth.h>
#include <rpc/clnt.h>
@ -47,10 +51,7 @@
* Holds NFS specific information for mount.
*/
struct nfsmount {
struct mtx nm_mtx;
int nm_flag; /* Flags for soft/hard... */
int nm_state; /* Internal state flags */
struct mount *nm_mountp; /* Vfs structure for this filesystem */
struct nfsmount_common nm_com; /* Common fields for nlm */
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 */
@ -58,8 +59,6 @@ struct nfsmount {
int nm_soproto; /* and protocol */
int nm_soflags; /* pr_flags for socket protocol */
struct sockaddr *nm_nam; /* Addr of server */
int nm_timeo; /* Init timer for NFSMNT_DUMBTIMR */
int nm_retry; /* Max retries */
int nm_deadthresh; /* Threshold of timeouts-->dead server*/
int nm_rsize; /* Max size of read rpc */
int nm_wsize; /* Max size of write rpc */
@ -79,7 +78,6 @@ struct nfsmount {
struct nfs_rpcops *nm_rpcops;
int nm_tprintf_initial_delay; /* initial delay */
int nm_tprintf_delay; /* interval for messages */
char nm_hostname[MNAMELEN]; /* server's name */
int nm_secflavor; /* auth flavor to use for rpc */
struct __rpc_client *nm_client;
struct rpc_timers nm_timers[NFS_MAX_TIMER]; /* RTT Timers for rpcs */
@ -94,6 +92,15 @@ struct nfsmount {
time_t nm_last_renewal;
};
#define nm_mtx nm_com.nmcom_mtx
#define nm_flag nm_com.nmcom_flag
#define nm_state nm_com.nmcom_state
#define nm_mountp nm_com.nmcom_mountp
#define nm_timeo nm_com.nmcom_timeo
#define nm_retry nm_com.nmcom_retry
#define nm_hostname nm_com.nmcom_hostname
#define nm_getinfo nm_com.nmcom_getinfo
#if defined(_KERNEL)
/*
* Convert mount ptr to nfsmount ptr.

View File

@ -187,9 +187,6 @@ extern struct vop_vector nfs_fifoops;
extern struct vop_vector nfs_vnodeops;
extern struct buf_ops buf_ops_nfs;
extern vop_advlock_t *nfs_advlock_p;
extern vop_reclaim_t *nfs_reclaim_p;
/*
* Prototypes for NFS vnode operations
*/

View File

@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <sys/mount.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/socket.h>
#include <sys/syslog.h>
#include <sys/systm.h>
#include <sys/unistd.h>
@ -47,7 +48,6 @@ __FBSDID("$FreeBSD$");
#include <nfs/nfsproto.h>
#include <nfsclient/nfs.h>
#include <nfsclient/nfsnode.h>
#include <nfsclient/nfsmount.h>
#include <nlm/nlm_prot.h>
@ -196,7 +196,6 @@ nlm_advlock_internal(struct vnode *vp, void *id, int op, struct flock *fl,
{
struct thread *td = curthread;
struct nfsmount *nmp;
struct nfsnode *np;
off_t size;
size_t fhlen;
union nfsfh fh;
@ -214,6 +213,7 @@ nlm_advlock_internal(struct vnode *vp, void *id, int op, struct flock *fl,
struct nlm_file_svid *ns;
int svid;
int error;
int is_v3;
ASSERT_VOP_LOCKED(vp, "nlm_advlock_1");
@ -225,18 +225,13 @@ nlm_advlock_internal(struct vnode *vp, void *id, int op, struct flock *fl,
if (op == F_SETLK || op == F_UNLCK)
nfs_vinvalbuf(vp, V_SAVE, td, 1);
np = VTONFS(vp);
nmp = VFSTONFS(vp->v_mount);
size = np->n_size;
sa = nmp->nm_nam;
memcpy(&ss, sa, sa->sa_len);
sa = (struct sockaddr *) &ss;
strcpy(servername, nmp->nm_hostname);
fhlen = np->n_fhsize;
memcpy(&fh.fh_bytes, np->n_fhp, fhlen);
nmp->nm_getinfo(vp, fh.fh_bytes, &fhlen, &ss, &is_v3, &size);
sa = (struct sockaddr *) &ss;
timo.tv_sec = nmp->nm_timeo / NFS_HZ;
timo.tv_usec = (nmp->nm_timeo % NFS_HZ) * (1000000 / NFS_HZ);
if (NFS_ISV3(vp))
if (is_v3 != 0)
vers = NLM_VERS4;
else
vers = NLM_VERS;

View File

@ -55,8 +55,7 @@ __FBSDID("$FreeBSD$");
#include <sys/vnode.h>
#include <nfs/nfsproto.h>
#include <nfsclient/nfs.h>
#include <nfsclient/nfsnode.h>
#include <nfs/nfs_lock.h>
#include <nlm/nlm_prot.h>
#include <nlm/sm_inter.h>
@ -2432,4 +2431,5 @@ DECLARE_MODULE(nfslockd, nfslockd_mod, SI_SUB_VFS, SI_ORDER_ANY);
/* So that loader and kldload(2) can find us, wherever we are.. */
MODULE_DEPEND(nfslockd, krpc, 1, 1, 1);
MODULE_DEPEND(nfslockd, nfs, 1, 1, 1);
MODULE_DEPEND(nfslockd, nfslock, 1, 1, 1);
MODULE_VERSION(nfslockd, 1);