aboutsummaryrefslogtreecommitdiffstats
path: root/fs/lockd/clntproc.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/lockd/clntproc.c')
-rw-r--r--fs/lockd/clntproc.c26
1 files changed, 25 insertions, 1 deletions
diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
index 112952037933..066ac313ae5c 100644
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -150,17 +150,22 @@ static void nlmclnt_release_lockargs(struct nlm_rqst *req)
150 * @host: address of a valid nlm_host context representing the NLM server 150 * @host: address of a valid nlm_host context representing the NLM server
151 * @cmd: fcntl-style file lock operation to perform 151 * @cmd: fcntl-style file lock operation to perform
152 * @fl: address of arguments for the lock operation 152 * @fl: address of arguments for the lock operation
153 * @data: address of data to be sent to callback operations
153 * 154 *
154 */ 155 */
155int nlmclnt_proc(struct nlm_host *host, int cmd, struct file_lock *fl) 156int nlmclnt_proc(struct nlm_host *host, int cmd, struct file_lock *fl, void *data)
156{ 157{
157 struct nlm_rqst *call; 158 struct nlm_rqst *call;
158 int status; 159 int status;
160 const struct nlmclnt_operations *nlmclnt_ops = host->h_nlmclnt_ops;
159 161
160 call = nlm_alloc_call(host); 162 call = nlm_alloc_call(host);
161 if (call == NULL) 163 if (call == NULL)
162 return -ENOMEM; 164 return -ENOMEM;
163 165
166 if (nlmclnt_ops && nlmclnt_ops->nlmclnt_alloc_call)
167 nlmclnt_ops->nlmclnt_alloc_call(data);
168
164 nlmclnt_locks_init_private(fl, host); 169 nlmclnt_locks_init_private(fl, host);
165 if (!fl->fl_u.nfs_fl.owner) { 170 if (!fl->fl_u.nfs_fl.owner) {
166 /* lockowner allocation has failed */ 171 /* lockowner allocation has failed */
@@ -169,6 +174,7 @@ int nlmclnt_proc(struct nlm_host *host, int cmd, struct file_lock *fl)
169 } 174 }
170 /* Set up the argument struct */ 175 /* Set up the argument struct */
171 nlmclnt_setlockargs(call, fl); 176 nlmclnt_setlockargs(call, fl);
177 call->a_callback_data = data;
172 178
173 if (IS_SETLK(cmd) || IS_SETLKW(cmd)) { 179 if (IS_SETLK(cmd) || IS_SETLKW(cmd)) {
174 if (fl->fl_type != F_UNLCK) { 180 if (fl->fl_type != F_UNLCK) {
@@ -214,8 +220,12 @@ struct nlm_rqst *nlm_alloc_call(struct nlm_host *host)
214 220
215void nlmclnt_release_call(struct nlm_rqst *call) 221void nlmclnt_release_call(struct nlm_rqst *call)
216{ 222{
223 const struct nlmclnt_operations *nlmclnt_ops = call->a_host->h_nlmclnt_ops;
224
217 if (!atomic_dec_and_test(&call->a_count)) 225 if (!atomic_dec_and_test(&call->a_count))
218 return; 226 return;
227 if (nlmclnt_ops && nlmclnt_ops->nlmclnt_release_call)
228 nlmclnt_ops->nlmclnt_release_call(call->a_callback_data);
219 nlmclnt_release_host(call->a_host); 229 nlmclnt_release_host(call->a_host);
220 nlmclnt_release_lockargs(call); 230 nlmclnt_release_lockargs(call);
221 kfree(call); 231 kfree(call);
@@ -687,6 +697,19 @@ out:
687 return status; 697 return status;
688} 698}
689 699
700static void nlmclnt_unlock_prepare(struct rpc_task *task, void *data)
701{
702 struct nlm_rqst *req = data;
703 const struct nlmclnt_operations *nlmclnt_ops = req->a_host->h_nlmclnt_ops;
704 bool defer_call = false;
705
706 if (nlmclnt_ops && nlmclnt_ops->nlmclnt_unlock_prepare)
707 defer_call = nlmclnt_ops->nlmclnt_unlock_prepare(task, req->a_callback_data);
708
709 if (!defer_call)
710 rpc_call_start(task);
711}
712
690static void nlmclnt_unlock_callback(struct rpc_task *task, void *data) 713static void nlmclnt_unlock_callback(struct rpc_task *task, void *data)
691{ 714{
692 struct nlm_rqst *req = data; 715 struct nlm_rqst *req = data;
@@ -720,6 +743,7 @@ die:
720} 743}
721 744
722static const struct rpc_call_ops nlmclnt_unlock_ops = { 745static const struct rpc_call_ops nlmclnt_unlock_ops = {
746 .rpc_call_prepare = nlmclnt_unlock_prepare,
723 .rpc_call_done = nlmclnt_unlock_callback, 747 .rpc_call_done = nlmclnt_unlock_callback,
724 .rpc_release = nlmclnt_rpc_release, 748 .rpc_release = nlmclnt_rpc_release,
725}; 749};