static_assert(offsetof(struct nlm_cancargs_wrapper, xdrgen) == 0);
+struct nlm_unlockargs_wrapper {
+ struct nlm_unlockargs xdrgen;
+ struct lockd_lock lock;
+};
+
+static_assert(offsetof(struct nlm_unlockargs_wrapper, xdrgen) == 0);
+
static __be32
nlm_netobj_to_cookie(struct lockd_cookie *cookie, netobj *object)
{
return rpc_success;
}
+/**
+ * nlmsvc_proc_unlock - UNLOCK: Remove a lock
+ * @rqstp: RPC transaction context
+ *
+ * Returns:
+ * %rpc_success: RPC executed successfully.
+ * %rpc_drop_reply: Do not send an RPC reply.
+ *
+ * RPC synopsis:
+ * nlm_res NLM_UNLOCK(nlm_unlockargs) = 4;
+ *
+ * Permissible procedure status codes:
+ * %LCK_GRANTED: The requested lock was released.
+ * %LCK_DENIED_GRACE_PERIOD: The server has recently restarted and is
+ * re-establishing existing locks, and is not
+ * yet ready to accept normal service requests.
+ *
+ * The Linux NLM server implementation also returns:
+ * %LCK_DENIED_NOLOCKS: A needed resource could not be allocated.
+ */
static __be32
nlmsvc_proc_unlock(struct svc_rqst *rqstp)
{
- return __nlmsvc_proc_unlock(rqstp, rqstp->rq_resp);
+ struct nlm_unlockargs_wrapper *argp = rqstp->rq_argp;
+ struct nlm_res_wrapper *resp = rqstp->rq_resp;
+ struct net *net = SVC_NET(rqstp);
+ struct nlm_host *host = NULL;
+ struct nlm_file *file = NULL;
+
+ resp->xdrgen.cookie = argp->xdrgen.cookie;
+
+ resp->xdrgen.stat.stat = nlm_lck_denied_grace_period;
+ if (locks_in_grace(net))
+ goto out;
+
+ resp->xdrgen.stat.stat = nlm_lck_denied_nolocks;
+ host = nlm3svc_lookup_host(rqstp, argp->xdrgen.alock.caller_name, false);
+ if (!host)
+ goto out;
+
+ resp->xdrgen.stat.stat = nlm3svc_lookup_file(rqstp, host, &argp->lock,
+ &file, &argp->xdrgen.alock,
+ F_UNLCK);
+ if (resp->xdrgen.stat.stat)
+ goto out;
+
+ resp->xdrgen.stat.stat = nlmsvc_unlock(net, file, &argp->lock);
+ nlmsvc_release_lockowner(&argp->lock);
+
+out:
+ if (file)
+ nlm_release_file(file);
+ nlmsvc_release_host(host);
+ return resp->xdrgen.stat.stat == nlm__int__drop_reply ?
+ rpc_drop_reply : rpc_success;
}
/*
.pc_xdrressize = NLM3_nlm_res_sz,
.pc_name = "CANCEL",
},
- [NLMPROC_UNLOCK] = {
- .pc_func = nlmsvc_proc_unlock,
- .pc_decode = nlmsvc_decode_unlockargs,
- .pc_encode = nlmsvc_encode_res,
- .pc_argsize = sizeof(struct lockd_args),
- .pc_argzero = sizeof(struct lockd_args),
- .pc_ressize = sizeof(struct lockd_res),
- .pc_xdrressize = Ck+St,
- .pc_name = "UNLOCK",
+ [NLM_UNLOCK] = {
+ .pc_func = nlmsvc_proc_unlock,
+ .pc_decode = nlm_svc_decode_nlm_unlockargs,
+ .pc_encode = nlm_svc_encode_nlm_res,
+ .pc_argsize = sizeof(struct nlm_unlockargs_wrapper),
+ .pc_argzero = 0,
+ .pc_ressize = sizeof(struct nlm_res_wrapper),
+ .pc_xdrressize = NLM3_nlm_res_sz,
+ .pc_name = "UNLOCK",
},
[NLMPROC_GRANTED] = {
.pc_func = nlmsvc_proc_granted,
struct nlm_testargs_wrapper testargs;
struct nlm_lockargs_wrapper lockargs;
struct nlm_cancargs_wrapper cancargs;
+ struct nlm_unlockargs_wrapper unlockargs;
struct nlm_testres_wrapper testres;
struct nlm_res_wrapper res;
struct lockd_args args;