aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2008-01-11 17:09:59 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2008-01-30 02:06:07 -0500
commit1093a60ef34bb12010fe7ea4b780bee1c57cfbbe (patch)
treebc558d58ae38aab7e615883eceef1ec253c2d646
parent9289e7f91add1c09c3ec8571a2080f7507730b8d (diff)
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: Chuck Lever <chuck.lever@oracle.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r--fs/lockd/clntproc.c33
-rw-r--r--fs/nfs/nfs3proc.c4
-rw-r--r--fs/nfs/proc.c4
-rw-r--r--include/linux/lockd/bind.h3
4 files changed, 18 insertions, 26 deletions
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
index a10343bed160..b1a4dba443bc 100644
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -145,34 +145,21 @@ static void nlmclnt_release_lockargs(struct nlm_rqst *req)
145 BUG_ON(req->a_args.lock.fl.fl_ops != NULL); 145 BUG_ON(req->a_args.lock.fl.fl_ops != NULL);
146} 146}
147 147
148/* 148/**
149 * This is the main entry point for the NLM client. 149 * nlmclnt_proc - Perform a single client-side lock request
150 * @host: address of a valid nlm_host context representing the NLM server
151 * @cmd: fcntl-style file lock operation to perform
152 * @fl: address of arguments for the lock operation
153 *
150 */ 154 */
151int 155int nlmclnt_proc(struct nlm_host *host, int cmd, struct file_lock *fl)
152nlmclnt_proc(struct inode *inode, int cmd, struct file_lock *fl)
153{ 156{
154 struct rpc_clnt *client = NFS_CLIENT(inode);
155 struct sockaddr_in addr;
156 struct nfs_server *nfssrv = NFS_SERVER(inode);
157 struct nlm_host *host;
158 struct nlm_rqst *call; 157 struct nlm_rqst *call;
159 sigset_t oldset; 158 sigset_t oldset;
160 unsigned long flags; 159 unsigned long flags;
161 int status, vers; 160 int status;
162
163 vers = (NFS_PROTO(inode)->version == 3) ? 4 : 1;
164 if (NFS_PROTO(inode)->version > 3) {
165 printk(KERN_NOTICE "NFSv4 file locking not implemented!\n");
166 return -ENOLCK;
167 }
168
169 rpc_peeraddr(client, (struct sockaddr *) &addr, sizeof(addr));
170 host = nlmclnt_lookup_host(&addr, client->cl_xprt->prot, vers,
171 nfssrv->nfs_client->cl_hostname,
172 strlen(nfssrv->nfs_client->cl_hostname));
173 if (host == NULL)
174 return -ENOLCK;
175 161
162 nlm_get_host(host);
176 call = nlm_alloc_call(host); 163 call = nlm_alloc_call(host);
177 if (call == NULL) 164 if (call == NULL)
178 return -ENOMEM; 165 return -ENOMEM;
@@ -219,7 +206,7 @@ nlmclnt_proc(struct inode *inode, int cmd, struct file_lock *fl)
219 dprintk("lockd: clnt proc returns %d\n", status); 206 dprintk("lockd: clnt proc returns %d\n", status);
220 return status; 207 return status;
221} 208}
222EXPORT_SYMBOL(nlmclnt_proc); 209EXPORT_SYMBOL_GPL(nlmclnt_proc);
223 210
224/* 211/*
225 * Allocate an NLM RPC call struct 212 * Allocate an NLM RPC call struct
diff --git a/fs/nfs/nfs3proc.c b/fs/nfs/nfs3proc.c
index e68580ebaa47..b353c1a05bfd 100644
--- a/fs/nfs/nfs3proc.c
+++ b/fs/nfs/nfs3proc.c
@@ -767,7 +767,9 @@ static void nfs3_proc_commit_setup(struct nfs_write_data *data, struct rpc_messa
767static int 767static int
768nfs3_proc_lock(struct file *filp, int cmd, struct file_lock *fl) 768nfs3_proc_lock(struct file *filp, int cmd, struct file_lock *fl)
769{ 769{
770 return nlmclnt_proc(filp->f_path.dentry->d_inode, cmd, fl); 770 struct inode *inode = filp->f_path.dentry->d_inode;
771
772 return nlmclnt_proc(NFS_SERVER(inode)->nlm_host, cmd, fl);
771} 773}
772 774
773const struct nfs_rpc_ops nfs_v3_clientops = { 775const struct nfs_rpc_ops nfs_v3_clientops = {
diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c
index c9f46a24e75c..5ccf7faee19c 100644
--- a/fs/nfs/proc.c
+++ b/fs/nfs/proc.c
@@ -593,7 +593,9 @@ nfs_proc_commit_setup(struct nfs_write_data *data, struct rpc_message *msg)
593static int 593static int
594nfs_proc_lock(struct file *filp, int cmd, struct file_lock *fl) 594nfs_proc_lock(struct file *filp, int cmd, struct file_lock *fl)
595{ 595{
596 return nlmclnt_proc(filp->f_path.dentry->d_inode, cmd, fl); 596 struct inode *inode = filp->f_path.dentry->d_inode;
597
598 return nlmclnt_proc(NFS_SERVER(inode)->nlm_host, cmd, fl);
597} 599}
598 600
599 601
diff --git a/include/linux/lockd/bind.h b/include/linux/lockd/bind.h
index ad5402f5456b..73368075af03 100644
--- a/include/linux/lockd/bind.h
+++ b/include/linux/lockd/bind.h
@@ -42,7 +42,8 @@ extern struct nlm_host *nlmclnt_init(const char *server_name,
42 u32 nfs_version); 42 u32 nfs_version);
43extern void nlmclnt_done(struct nlm_host *host); 43extern void nlmclnt_done(struct nlm_host *host);
44 44
45extern int nlmclnt_proc(struct inode *, int, struct file_lock *); 45extern int nlmclnt_proc(struct nlm_host *host, int cmd,
46 struct file_lock *fl);
46extern int lockd_up(int proto); 47extern int lockd_up(int proto);
47extern void lockd_down(void); 48extern void lockd_down(void);
48 49