diff options
Diffstat (limited to 'fs/lockd/clntproc.c')
| -rw-r--r-- | fs/lockd/clntproc.c | 26 | 
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)   * @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 + * @data: address of data to be sent to callback operations   *   */ -int nlmclnt_proc(struct nlm_host *host, int cmd, struct file_lock *fl) +int nlmclnt_proc(struct nlm_host *host, int cmd, struct file_lock *fl, void *data)  {  	struct nlm_rqst		*call;  	int			status; +	const struct nlmclnt_operations *nlmclnt_ops = host->h_nlmclnt_ops;  	call = nlm_alloc_call(host);  	if (call == NULL)  		return -ENOMEM; +	if (nlmclnt_ops && nlmclnt_ops->nlmclnt_alloc_call) +		nlmclnt_ops->nlmclnt_alloc_call(data); +  	nlmclnt_locks_init_private(fl, host);  	if (!fl->fl_u.nfs_fl.owner) {  		/* lockowner allocation has failed */ @@ -169,6 +174,7 @@ int nlmclnt_proc(struct nlm_host *host, int cmd, struct file_lock *fl)  	}  	/* Set up the argument struct */  	nlmclnt_setlockargs(call, fl); +	call->a_callback_data = data;  	if (IS_SETLK(cmd) || IS_SETLKW(cmd)) {  		if (fl->fl_type != F_UNLCK) { @@ -214,8 +220,12 @@ struct nlm_rqst *nlm_alloc_call(struct nlm_host *host)  void nlmclnt_release_call(struct nlm_rqst *call)  { +	const struct nlmclnt_operations *nlmclnt_ops = call->a_host->h_nlmclnt_ops; +  	if (!atomic_dec_and_test(&call->a_count))  		return; +	if (nlmclnt_ops && nlmclnt_ops->nlmclnt_release_call) +		nlmclnt_ops->nlmclnt_release_call(call->a_callback_data);  	nlmclnt_release_host(call->a_host);  	nlmclnt_release_lockargs(call);  	kfree(call); @@ -687,6 +697,19 @@ out:  	return status;  } +static void nlmclnt_unlock_prepare(struct rpc_task *task, void *data) +{ +	struct nlm_rqst	*req = data; +	const struct nlmclnt_operations *nlmclnt_ops = req->a_host->h_nlmclnt_ops; +	bool defer_call = false; + +	if (nlmclnt_ops && nlmclnt_ops->nlmclnt_unlock_prepare) +		defer_call = nlmclnt_ops->nlmclnt_unlock_prepare(task, req->a_callback_data); + +	if (!defer_call) +		rpc_call_start(task); +} +  static void nlmclnt_unlock_callback(struct rpc_task *task, void *data)  {  	struct nlm_rqst	*req = data; @@ -720,6 +743,7 @@ die:  }  static const struct rpc_call_ops nlmclnt_unlock_ops = { +	.rpc_call_prepare = nlmclnt_unlock_prepare,  	.rpc_call_done = nlmclnt_unlock_callback,  	.rpc_release = nlmclnt_rpc_release,  };  |