Commit 1093a60e authored by Chuck Lever's avatar Chuck Lever Committed by Trond Myklebust

NLM/NFS: Use cached nlm_host when calling nlmclnt_proc()

Now that each NFS mount point caches its own nlm_host structure, it can be
passed to nlmclnt_proc() for each lock request.  By pinning an nlm_host for
each mount point, we trade the overhead of looking up or creating a fresh
nlm_host struct during every NLM procedure call for a little extra memory.

We also restrict the nlmclnt_proc symbol to limit the use of this call to
in-tree modules.

Note that nlm_lookup_host() (just removed from the client's per-request
NLM processing) could also trigger an nlm_host garbage collection.  Now
client-side nlm_host garbage collection occurs only during NFS mount
processing.  Since the NFS client now holds a reference on these nlm_host
structures, they wouldn't have been affected by garbage collection
anyway.

Given that nlm_lookup_host() reorders the global nlm_host chain after
every successful lookup, and that a garbage collection could be triggered
during the call, we've removed a significant amount of per-NLM-request
CPU processing overhead.

Sidebar: there are only a few remaining references to the internals of
NFS inodes in the client-side NLM code.  The only references I found are
related to extracting or comparing the inode's file handle via NFS_FH().
One is in nlmclnt_grant(); the other is in nlmclnt_setlockargs().
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 9289e7f9
...@@ -145,34 +145,21 @@ static void nlmclnt_release_lockargs(struct nlm_rqst *req) ...@@ -145,34 +145,21 @@ static void nlmclnt_release_lockargs(struct nlm_rqst *req)
BUG_ON(req->a_args.lock.fl.fl_ops != NULL); BUG_ON(req->a_args.lock.fl.fl_ops != NULL);
} }
/* /**
* This is the main entry point for the NLM client. * nlmclnt_proc - Perform a single client-side lock request
* @host: address of a valid nlm_host context representing the NLM server
* @cmd: fcntl-style file lock operation to perform
* @fl: address of arguments for the lock operation
*
*/ */
int int nlmclnt_proc(struct nlm_host *host, int cmd, struct file_lock *fl)
nlmclnt_proc(struct inode *inode, int cmd, struct file_lock *fl)
{ {
struct rpc_clnt *client = NFS_CLIENT(inode);
struct sockaddr_in addr;
struct nfs_server *nfssrv = NFS_SERVER(inode);
struct nlm_host *host;
struct nlm_rqst *call; struct nlm_rqst *call;
sigset_t oldset; sigset_t oldset;
unsigned long flags; unsigned long flags;
int status, vers; int status;
vers = (NFS_PROTO(inode)->version == 3) ? 4 : 1;
if (NFS_PROTO(inode)->version > 3) {
printk(KERN_NOTICE "NFSv4 file locking not implemented!\n");
return -ENOLCK;
}
rpc_peeraddr(client, (struct sockaddr *) &addr, sizeof(addr));
host = nlmclnt_lookup_host(&addr, client->cl_xprt->prot, vers,
nfssrv->nfs_client->cl_hostname,
strlen(nfssrv->nfs_client->cl_hostname));
if (host == NULL)
return -ENOLCK;
nlm_get_host(host);
call = nlm_alloc_call(host); call = nlm_alloc_call(host);
if (call == NULL) if (call == NULL)
return -ENOMEM; return -ENOMEM;
...@@ -219,7 +206,7 @@ nlmclnt_proc(struct inode *inode, int cmd, struct file_lock *fl) ...@@ -219,7 +206,7 @@ nlmclnt_proc(struct inode *inode, int cmd, struct file_lock *fl)
dprintk("lockd: clnt proc returns %d\n", status); dprintk("lockd: clnt proc returns %d\n", status);
return status; return status;
} }
EXPORT_SYMBOL(nlmclnt_proc); EXPORT_SYMBOL_GPL(nlmclnt_proc);
/* /*
* Allocate an NLM RPC call struct * Allocate an NLM RPC call struct
......
...@@ -767,7 +767,9 @@ static void nfs3_proc_commit_setup(struct nfs_write_data *data, struct rpc_messa ...@@ -767,7 +767,9 @@ static void nfs3_proc_commit_setup(struct nfs_write_data *data, struct rpc_messa
static int static int
nfs3_proc_lock(struct file *filp, int cmd, struct file_lock *fl) nfs3_proc_lock(struct file *filp, int cmd, struct file_lock *fl)
{ {
return nlmclnt_proc(filp->f_path.dentry->d_inode, cmd, fl); struct inode *inode = filp->f_path.dentry->d_inode;
return nlmclnt_proc(NFS_SERVER(inode)->nlm_host, cmd, fl);
} }
const struct nfs_rpc_ops nfs_v3_clientops = { const struct nfs_rpc_ops nfs_v3_clientops = {
......
...@@ -593,7 +593,9 @@ nfs_proc_commit_setup(struct nfs_write_data *data, struct rpc_message *msg) ...@@ -593,7 +593,9 @@ nfs_proc_commit_setup(struct nfs_write_data *data, struct rpc_message *msg)
static int static int
nfs_proc_lock(struct file *filp, int cmd, struct file_lock *fl) nfs_proc_lock(struct file *filp, int cmd, struct file_lock *fl)
{ {
return nlmclnt_proc(filp->f_path.dentry->d_inode, cmd, fl); struct inode *inode = filp->f_path.dentry->d_inode;
return nlmclnt_proc(NFS_SERVER(inode)->nlm_host, cmd, fl);
} }
......
...@@ -42,7 +42,8 @@ extern struct nlm_host *nlmclnt_init(const char *server_name, ...@@ -42,7 +42,8 @@ extern struct nlm_host *nlmclnt_init(const char *server_name,
u32 nfs_version); u32 nfs_version);
extern void nlmclnt_done(struct nlm_host *host); extern void nlmclnt_done(struct nlm_host *host);
extern int nlmclnt_proc(struct inode *, int, struct file_lock *); extern int nlmclnt_proc(struct nlm_host *host, int cmd,
struct file_lock *fl);
extern int lockd_up(int proto); extern int lockd_up(int proto);
extern void lockd_down(void); extern void lockd_down(void);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment