Deleted Added
full compact
nlm_prot_impl.c (197730) nlm_prot_impl.c (197840)
1/*-
2 * Copyright (c) 2008 Isilon Inc http://www.isilon.com/
3 * Authors: Doug Rabson <dfr@rabson.org>
4 * Developed with Red Inc: Alfred Perlstein <alfred@freebsd.org>
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 14 unchanged lines hidden (view full) ---

23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include "opt_inet6.h"
29
30#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 2008 Isilon Inc http://www.isilon.com/
3 * Authors: Doug Rabson <dfr@rabson.org>
4 * Developed with Red Inc: Alfred Perlstein <alfred@freebsd.org>
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 14 unchanged lines hidden (view full) ---

23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#include "opt_inet6.h"
29
30#include <sys/cdefs.h>
31__FBSDID("$FreeBSD: head/sys/nlm/nlm_prot_impl.c 197730 2009-10-03 12:22:12Z nyan $");
31__FBSDID("$FreeBSD: head/sys/nlm/nlm_prot_impl.c 197840 2009-10-07 19:50:14Z zml $");
32
33#include <sys/param.h>
32
33#include <sys/param.h>
34#include <sys/fail.h>
34#include <sys/fcntl.h>
35#include <sys/kernel.h>
36#include <sys/kthread.h>
37#include <sys/lockf.h>
38#include <sys/malloc.h>
39#include <sys/mount.h>
40#if __FreeBSD_version >= 700000
41#include <sys/priv.h>

--- 30 unchanged lines hidden (view full) ---

72#define NLM_IDLE_TIMEOUT 30
73
74/*
75 * We check the host list for idle every few seconds.
76 */
77#define NLM_IDLE_PERIOD 5
78
79/*
35#include <sys/fcntl.h>
36#include <sys/kernel.h>
37#include <sys/kthread.h>
38#include <sys/lockf.h>
39#include <sys/malloc.h>
40#include <sys/mount.h>
41#if __FreeBSD_version >= 700000
42#include <sys/priv.h>

--- 30 unchanged lines hidden (view full) ---

73#define NLM_IDLE_TIMEOUT 30
74
75/*
76 * We check the host list for idle every few seconds.
77 */
78#define NLM_IDLE_PERIOD 5
79
80/*
81 * We only look for GRANTED_RES messages for a little while.
82 */
83#define NLM_EXPIRE_TIMEOUT 10
84
85/*
80 * Support for sysctl vfs.nlm.sysid
81 */
82SYSCTL_NODE(_vfs, OID_AUTO, nlm, CTLFLAG_RW, NULL, "Network Lock Manager");
83SYSCTL_NODE(_vfs_nlm, OID_AUTO, sysid, CTLFLAG_RW, NULL, "");
84
85/*
86 * Syscall hooks
87 */

--- 111 unchanged lines hidden (view full) ---

199 TAILQ_ENTRY(nlm_async_lock) af_link; /* (l) host's list of locks */
200 struct task af_task; /* (c) async callback details */
201 void *af_cookie; /* (l) lock manager cancel token */
202 struct vnode *af_vp; /* (l) vnode to lock */
203 struct flock af_fl; /* (c) lock details */
204 struct nlm_host *af_host; /* (c) host which is locking */
205 CLIENT *af_rpc; /* (c) rpc client to send message */
206 nlm4_testargs af_granted; /* (c) notification details */
86 * Support for sysctl vfs.nlm.sysid
87 */
88SYSCTL_NODE(_vfs, OID_AUTO, nlm, CTLFLAG_RW, NULL, "Network Lock Manager");
89SYSCTL_NODE(_vfs_nlm, OID_AUTO, sysid, CTLFLAG_RW, NULL, "");
90
91/*
92 * Syscall hooks
93 */

--- 111 unchanged lines hidden (view full) ---

205 TAILQ_ENTRY(nlm_async_lock) af_link; /* (l) host's list of locks */
206 struct task af_task; /* (c) async callback details */
207 void *af_cookie; /* (l) lock manager cancel token */
208 struct vnode *af_vp; /* (l) vnode to lock */
209 struct flock af_fl; /* (c) lock details */
210 struct nlm_host *af_host; /* (c) host which is locking */
211 CLIENT *af_rpc; /* (c) rpc client to send message */
212 nlm4_testargs af_granted; /* (c) notification details */
213 time_t af_expiretime; /* (c) notification time */
207};
208TAILQ_HEAD(nlm_async_lock_list, nlm_async_lock);
209
210/*
211 * NLM host.
212 */
213enum nlm_host_state {
214 NLM_UNMONITORED,

--- 17 unchanged lines hidden (view full) ---

232 struct sockaddr_storage nh_addr; /* (s) remote address of host */
233 struct nlm_rpc nh_srvrpc; /* (l) RPC for server replies */
234 struct nlm_rpc nh_clntrpc; /* (l) RPC for client requests */
235 rpcvers_t nh_vers; /* (s) NLM version of host */
236 int nh_state; /* (s) last seen NSM state of host */
237 enum nlm_host_state nh_monstate; /* (l) local NSM monitoring state */
238 time_t nh_idle_timeout; /* (s) Time at which host is idle */
239 struct sysctl_ctx_list nh_sysctl; /* (c) vfs.nlm.sysid nodes */
214};
215TAILQ_HEAD(nlm_async_lock_list, nlm_async_lock);
216
217/*
218 * NLM host.
219 */
220enum nlm_host_state {
221 NLM_UNMONITORED,

--- 17 unchanged lines hidden (view full) ---

239 struct sockaddr_storage nh_addr; /* (s) remote address of host */
240 struct nlm_rpc nh_srvrpc; /* (l) RPC for server replies */
241 struct nlm_rpc nh_clntrpc; /* (l) RPC for client requests */
242 rpcvers_t nh_vers; /* (s) NLM version of host */
243 int nh_state; /* (s) last seen NSM state of host */
244 enum nlm_host_state nh_monstate; /* (l) local NSM monitoring state */
245 time_t nh_idle_timeout; /* (s) Time at which host is idle */
246 struct sysctl_ctx_list nh_sysctl; /* (c) vfs.nlm.sysid nodes */
247 uint32_t nh_grantcookie; /* (l) grant cookie counter */
240 struct nlm_async_lock_list nh_pending; /* (l) pending async locks */
248 struct nlm_async_lock_list nh_pending; /* (l) pending async locks */
249 struct nlm_async_lock_list nh_granted; /* (l) granted locks */
241 struct nlm_async_lock_list nh_finished; /* (l) finished async locks */
242};
243TAILQ_HEAD(nlm_host_list, nlm_host);
244
245static struct nlm_host_list nlm_hosts; /* (g) */
246static uint32_t nlm_next_sysid = 1; /* (g) */
247
248static void nlm_host_unmonitor(struct nlm_host *);
249
250 struct nlm_async_lock_list nh_finished; /* (l) finished async locks */
251};
252TAILQ_HEAD(nlm_host_list, nlm_host);
253
254static struct nlm_host_list nlm_hosts; /* (g) */
255static uint32_t nlm_next_sysid = 1; /* (g) */
256
257static void nlm_host_unmonitor(struct nlm_host *);
258
259struct nlm_grantcookie {
260 uint32_t ng_sysid;
261 uint32_t ng_cookie;
262};
263
264static inline uint32_t
265ng_sysid(struct netobj *src)
266{
267
268 return ((struct nlm_grantcookie *)src->n_bytes)->ng_sysid;
269}
270
271static inline uint32_t
272ng_cookie(struct netobj *src)
273{
274
275 return ((struct nlm_grantcookie *)src->n_bytes)->ng_cookie;
276}
277
250/**********************************************************************/
251
252/*
253 * Initialise NLM globals.
254 */
255static void
256nlm_init(void *dummy)
257{

--- 18 unchanged lines hidden (view full) ---

276
277 if (nlm_syscall_registered)
278 syscall_deregister(&nlm_syscall_offset,
279 &nlm_syscall_prev_sysent);
280}
281SYSUNINIT(nlm_uninit, SI_SUB_LOCK, SI_ORDER_FIRST, nlm_uninit, NULL);
282
283/*
278/**********************************************************************/
279
280/*
281 * Initialise NLM globals.
282 */
283static void
284nlm_init(void *dummy)
285{

--- 18 unchanged lines hidden (view full) ---

304
305 if (nlm_syscall_registered)
306 syscall_deregister(&nlm_syscall_offset,
307 &nlm_syscall_prev_sysent);
308}
309SYSUNINIT(nlm_uninit, SI_SUB_LOCK, SI_ORDER_FIRST, nlm_uninit, NULL);
310
311/*
312 * Create a netobj from an arbitrary source.
313 */
314void
315nlm_make_netobj(struct netobj *dst, caddr_t src, size_t srcsize,
316 struct malloc_type *type)
317{
318
319 dst->n_len = srcsize;
320 dst->n_bytes = malloc(srcsize, type, M_WAITOK);
321 memcpy(dst->n_bytes, src, srcsize);
322}
323
324/*
284 * Copy a struct netobj.
285 */
286void
287nlm_copy_netobj(struct netobj *dst, struct netobj *src,
288 struct malloc_type *type)
289{
290
325 * Copy a struct netobj.
326 */
327void
328nlm_copy_netobj(struct netobj *dst, struct netobj *src,
329 struct malloc_type *type)
330{
331
291 dst->n_len = src->n_len;
292 dst->n_bytes = malloc(src->n_len, type, M_WAITOK);
293 memcpy(dst->n_bytes, src->n_bytes, src->n_len);
332 nlm_make_netobj(dst, src->n_bytes, src->n_len, type);
294}
295
333}
334
335
296/*
297 * Create an RPC client handle for the given (address,prog,vers)
298 * triple using UDP.
299 */
300static CLIENT *
301nlm_get_rpc(struct sockaddr *sa, rpcprog_t prog, rpcvers_t vers)
302{
303 char *wchan = "nlmrcv";

--- 209 unchanged lines hidden (view full) ---

513 * granted. We notify the host which initiated the request.
514 */
515static void
516nlm_lock_callback(void *arg, int pending)
517{
518 struct nlm_async_lock *af = (struct nlm_async_lock *) arg;
519 struct rpc_callextra ext;
520
336/*
337 * Create an RPC client handle for the given (address,prog,vers)
338 * triple using UDP.
339 */
340static CLIENT *
341nlm_get_rpc(struct sockaddr *sa, rpcprog_t prog, rpcvers_t vers)
342{
343 char *wchan = "nlmrcv";

--- 209 unchanged lines hidden (view full) ---

553 * granted. We notify the host which initiated the request.
554 */
555static void
556nlm_lock_callback(void *arg, int pending)
557{
558 struct nlm_async_lock *af = (struct nlm_async_lock *) arg;
559 struct rpc_callextra ext;
560
521 NLM_DEBUG(2, "NLM: async lock %p for %s (sysid %d) granted\n",
522 af, af->af_host->nh_caller_name, af->af_host->nh_sysid);
561 NLM_DEBUG(2, "NLM: async lock %p for %s (sysid %d) granted,"
562 " cookie %d:%d\n", af, af->af_host->nh_caller_name,
563 af->af_host->nh_sysid, ng_sysid(&af->af_granted.cookie),
564 ng_cookie(&af->af_granted.cookie));
523
524 /*
525 * Send the results back to the host.
526 *
527 * Note: there is a possible race here with nlm_host_notify
528 * destroying the RPC client. To avoid problems, the first
529 * thing nlm_host_notify does is to cancel pending async lock
530 * requests.

--- 20 unchanged lines hidden (view full) ---

551 granted.alock.l_len =
552 af->af_granted.alock.l_len;
553
554 nlm_granted_msg_1(&granted,
555 NULL, af->af_rpc, &ext, nlm_zero_tv);
556 }
557
558 /*
565
566 /*
567 * Send the results back to the host.
568 *
569 * Note: there is a possible race here with nlm_host_notify
570 * destroying the RPC client. To avoid problems, the first
571 * thing nlm_host_notify does is to cancel pending async lock
572 * requests.

--- 20 unchanged lines hidden (view full) ---

593 granted.alock.l_len =
594 af->af_granted.alock.l_len;
595
596 nlm_granted_msg_1(&granted,
597 NULL, af->af_rpc, &ext, nlm_zero_tv);
598 }
599
600 /*
559 * Move this entry to the nh_finished list. Someone else will
560 * free it later - its too hard to do it here safely without
561 * racing with cancel.
562 *
563 * XXX possibly we should have a third "granted sent but not
564 * ack'ed" list so that we can re-send the granted message.
601 * Move this entry to the nh_granted list.
565 */
602 */
603 af->af_expiretime = time_uptime + NLM_EXPIRE_TIMEOUT;
566 mtx_lock(&af->af_host->nh_lock);
567 TAILQ_REMOVE(&af->af_host->nh_pending, af, af_link);
604 mtx_lock(&af->af_host->nh_lock);
605 TAILQ_REMOVE(&af->af_host->nh_pending, af, af_link);
568 TAILQ_INSERT_TAIL(&af->af_host->nh_finished, af, af_link);
606 TAILQ_INSERT_TAIL(&af->af_host->nh_granted, af, af_link);
569 mtx_unlock(&af->af_host->nh_lock);
570}
571
572/*
573 * Free an async lock request. The request must have been removed from
574 * any list.
575 */
576static void

--- 53 unchanged lines hidden (view full) ---

630 nlm_free_async_lock(af);
631 mtx_lock(&host->nh_lock);
632 }
633
634 return (error);
635}
636
637static void
607 mtx_unlock(&af->af_host->nh_lock);
608}
609
610/*
611 * Free an async lock request. The request must have been removed from
612 * any list.
613 */
614static void

--- 53 unchanged lines hidden (view full) ---

668 nlm_free_async_lock(af);
669 mtx_lock(&host->nh_lock);
670 }
671
672 return (error);
673}
674
675static void
638nlm_free_finished_locks(struct nlm_host *host)
676nlm_check_expired_locks(struct nlm_host *host)
639{
640 struct nlm_async_lock *af;
677{
678 struct nlm_async_lock *af;
679 time_t uptime = time_uptime;
641
642 mtx_lock(&host->nh_lock);
680
681 mtx_lock(&host->nh_lock);
682 while ((af = TAILQ_FIRST(&host->nh_granted)) != NULL
683 && uptime >= af->af_expiretime) {
684 NLM_DEBUG(2, "NLM: async lock %p for %s (sysid %d) expired,"
685 " cookie %d:%d\n", af, af->af_host->nh_caller_name,
686 af->af_host->nh_sysid, ng_sysid(&af->af_granted.cookie),
687 ng_cookie(&af->af_granted.cookie));
688 TAILQ_REMOVE(&host->nh_granted, af, af_link);
689 mtx_unlock(&host->nh_lock);
690 nlm_free_async_lock(af);
691 mtx_lock(&host->nh_lock);
692 }
643 while ((af = TAILQ_FIRST(&host->nh_finished)) != NULL) {
644 TAILQ_REMOVE(&host->nh_finished, af, af_link);
645 mtx_unlock(&host->nh_lock);
646 nlm_free_async_lock(af);
647 mtx_lock(&host->nh_lock);
648 }
649 mtx_unlock(&host->nh_lock);
650}

--- 66 unchanged lines hidden (view full) ---

717 while ((af = TAILQ_FIRST(&host->nh_pending)) != NULL) {
718 /*
719 * nlm_cancel_async_lock will remove the entry from
720 * nh_pending and free it.
721 */
722 nlm_cancel_async_lock(af);
723 }
724 mtx_unlock(&host->nh_lock);
693 while ((af = TAILQ_FIRST(&host->nh_finished)) != NULL) {
694 TAILQ_REMOVE(&host->nh_finished, af, af_link);
695 mtx_unlock(&host->nh_lock);
696 nlm_free_async_lock(af);
697 mtx_lock(&host->nh_lock);
698 }
699 mtx_unlock(&host->nh_lock);
700}

--- 66 unchanged lines hidden (view full) ---

767 while ((af = TAILQ_FIRST(&host->nh_pending)) != NULL) {
768 /*
769 * nlm_cancel_async_lock will remove the entry from
770 * nh_pending and free it.
771 */
772 nlm_cancel_async_lock(af);
773 }
774 mtx_unlock(&host->nh_lock);
725 nlm_free_finished_locks(host);
775 nlm_check_expired_locks(host);
726
727 /*
728 * The host just rebooted - trash its locks.
729 */
730 lf_clearremotesys(host->nh_sysid);
731 host->nh_state = newstate;
732
733 /*

--- 60 unchanged lines hidden (view full) ---

794 host->nh_refs = 1;
795 strlcpy(host->nh_caller_name, caller_name, MAXNAMELEN);
796 host->nh_sysid = nlm_next_sysid++;
797 snprintf(host->nh_sysid_string, sizeof(host->nh_sysid_string),
798 "%d", host->nh_sysid);
799 host->nh_vers = 0;
800 host->nh_state = 0;
801 host->nh_monstate = NLM_UNMONITORED;
776
777 /*
778 * The host just rebooted - trash its locks.
779 */
780 lf_clearremotesys(host->nh_sysid);
781 host->nh_state = newstate;
782
783 /*

--- 60 unchanged lines hidden (view full) ---

844 host->nh_refs = 1;
845 strlcpy(host->nh_caller_name, caller_name, MAXNAMELEN);
846 host->nh_sysid = nlm_next_sysid++;
847 snprintf(host->nh_sysid_string, sizeof(host->nh_sysid_string),
848 "%d", host->nh_sysid);
849 host->nh_vers = 0;
850 host->nh_state = 0;
851 host->nh_monstate = NLM_UNMONITORED;
852 host->nh_grantcookie = 1;
802 TAILQ_INIT(&host->nh_pending);
853 TAILQ_INIT(&host->nh_pending);
854 TAILQ_INIT(&host->nh_granted);
803 TAILQ_INIT(&host->nh_finished);
804 TAILQ_INSERT_TAIL(&nlm_hosts, host, nh_link);
805
806 mtx_unlock(&nlm_global_lock);
807
808 sysctl_ctx_init(&host->nh_sysctl);
809 oid = SYSCTL_ADD_NODE(&host->nh_sysctl,
810 SYSCTL_STATIC_CHILDREN(_vfs_nlm_sysid),

--- 1018 unchanged lines hidden (view full) ---

1829 if (!host) {
1830 result->stat.stat = nlm4_denied_nolocks;
1831 return (ENOMEM);
1832 }
1833
1834 NLM_DEBUG(3, "nlm_do_test(): caller_name = %s (sysid = %d)\n",
1835 host->nh_caller_name, host->nh_sysid);
1836
855 TAILQ_INIT(&host->nh_finished);
856 TAILQ_INSERT_TAIL(&nlm_hosts, host, nh_link);
857
858 mtx_unlock(&nlm_global_lock);
859
860 sysctl_ctx_init(&host->nh_sysctl);
861 oid = SYSCTL_ADD_NODE(&host->nh_sysctl,
862 SYSCTL_STATIC_CHILDREN(_vfs_nlm_sysid),

--- 1018 unchanged lines hidden (view full) ---

1881 if (!host) {
1882 result->stat.stat = nlm4_denied_nolocks;
1883 return (ENOMEM);
1884 }
1885
1886 NLM_DEBUG(3, "nlm_do_test(): caller_name = %s (sysid = %d)\n",
1887 host->nh_caller_name, host->nh_sysid);
1888
1837 nlm_free_finished_locks(host);
1889 nlm_check_expired_locks(host);
1838 sysid = host->nh_sysid;
1839
1840 nlm_convert_to_fhandle_t(&fh, &argp->alock.fh);
1841 nlm_copy_netobj(&result->cookie, &argp->cookie, M_RPC);
1842
1843 if (time_uptime < nlm_grace_threshold) {
1844 result->stat.stat = nlm4_denied_grace_period;
1845 goto out;

--- 88 unchanged lines hidden (view full) ---

1934 && host->nh_state != argp->state) {
1935 /*
1936 * The host rebooted without telling us. Trash its
1937 * locks.
1938 */
1939 nlm_host_notify(host, argp->state);
1940 }
1941
1890 sysid = host->nh_sysid;
1891
1892 nlm_convert_to_fhandle_t(&fh, &argp->alock.fh);
1893 nlm_copy_netobj(&result->cookie, &argp->cookie, M_RPC);
1894
1895 if (time_uptime < nlm_grace_threshold) {
1896 result->stat.stat = nlm4_denied_grace_period;
1897 goto out;

--- 88 unchanged lines hidden (view full) ---

1986 && host->nh_state != argp->state) {
1987 /*
1988 * The host rebooted without telling us. Trash its
1989 * locks.
1990 */
1991 nlm_host_notify(host, argp->state);
1992 }
1993
1942 nlm_free_finished_locks(host);
1994 nlm_check_expired_locks(host);
1943 sysid = host->nh_sysid;
1944
1945 nlm_convert_to_fhandle_t(&fh, &argp->alock.fh);
1946 nlm_copy_netobj(&result->cookie, &argp->cookie, M_RPC);
1947
1948 if (time_uptime < nlm_grace_threshold && !argp->reclaim) {
1949 result->stat.stat = nlm4_denied_grace_period;
1950 goto out;

--- 12 unchanged lines hidden (view full) ---

1963 fl.l_whence = SEEK_SET;
1964 if (argp->exclusive)
1965 fl.l_type = F_WRLCK;
1966 else
1967 fl.l_type = F_RDLCK;
1968 if (argp->block) {
1969 struct nlm_async_lock *af;
1970 CLIENT *client;
1995 sysid = host->nh_sysid;
1996
1997 nlm_convert_to_fhandle_t(&fh, &argp->alock.fh);
1998 nlm_copy_netobj(&result->cookie, &argp->cookie, M_RPC);
1999
2000 if (time_uptime < nlm_grace_threshold && !argp->reclaim) {
2001 result->stat.stat = nlm4_denied_grace_period;
2002 goto out;

--- 12 unchanged lines hidden (view full) ---

2015 fl.l_whence = SEEK_SET;
2016 if (argp->exclusive)
2017 fl.l_type = F_WRLCK;
2018 else
2019 fl.l_type = F_RDLCK;
2020 if (argp->block) {
2021 struct nlm_async_lock *af;
2022 CLIENT *client;
2023 struct nlm_grantcookie cookie;
1971
1972 /*
1973 * First, make sure we can contact the host's NLM.
1974 */
1975 client = nlm_host_get_rpc(host, TRUE);
1976 if (!client) {
1977 result->stat.stat = nlm4_failed;
1978 goto out;

--- 9 unchanged lines hidden (view full) ---

1988 TAILQ_FOREACH(af, &host->nh_pending, af_link) {
1989 if (af->af_fl.l_start == fl.l_start
1990 && af->af_fl.l_len == fl.l_len
1991 && af->af_fl.l_pid == fl.l_pid
1992 && af->af_fl.l_type == fl.l_type) {
1993 break;
1994 }
1995 }
2024
2025 /*
2026 * First, make sure we can contact the host's NLM.
2027 */
2028 client = nlm_host_get_rpc(host, TRUE);
2029 if (!client) {
2030 result->stat.stat = nlm4_failed;
2031 goto out;

--- 9 unchanged lines hidden (view full) ---

2041 TAILQ_FOREACH(af, &host->nh_pending, af_link) {
2042 if (af->af_fl.l_start == fl.l_start
2043 && af->af_fl.l_len == fl.l_len
2044 && af->af_fl.l_pid == fl.l_pid
2045 && af->af_fl.l_type == fl.l_type) {
2046 break;
2047 }
2048 }
2049 if (!af) {
2050 cookie.ng_sysid = host->nh_sysid;
2051 cookie.ng_cookie = host->nh_grantcookie++;
2052 }
1996 mtx_unlock(&host->nh_lock);
1997 if (af) {
1998 CLNT_RELEASE(client);
1999 result->stat.stat = nlm4_blocked;
2000 goto out;
2001 }
2002
2003 af = malloc(sizeof(struct nlm_async_lock), M_NLM,
2004 M_WAITOK|M_ZERO);
2005 TASK_INIT(&af->af_task, 0, nlm_lock_callback, af);
2006 af->af_vp = vs.vs_vp;
2007 af->af_fl = fl;
2008 af->af_host = host;
2009 af->af_rpc = client;
2010 /*
2011 * We use M_RPC here so that we can xdr_free the thing
2012 * later.
2013 */
2053 mtx_unlock(&host->nh_lock);
2054 if (af) {
2055 CLNT_RELEASE(client);
2056 result->stat.stat = nlm4_blocked;
2057 goto out;
2058 }
2059
2060 af = malloc(sizeof(struct nlm_async_lock), M_NLM,
2061 M_WAITOK|M_ZERO);
2062 TASK_INIT(&af->af_task, 0, nlm_lock_callback, af);
2063 af->af_vp = vs.vs_vp;
2064 af->af_fl = fl;
2065 af->af_host = host;
2066 af->af_rpc = client;
2067 /*
2068 * We use M_RPC here so that we can xdr_free the thing
2069 * later.
2070 */
2071 nlm_make_netobj(&af->af_granted.cookie,
2072 (caddr_t)&cookie, sizeof(cookie), M_RPC);
2014 af->af_granted.exclusive = argp->exclusive;
2015 af->af_granted.alock.caller_name =
2016 strdup(argp->alock.caller_name, M_RPC);
2017 nlm_copy_netobj(&af->af_granted.alock.fh,
2018 &argp->alock.fh, M_RPC);
2019 nlm_copy_netobj(&af->af_granted.alock.oh,
2020 &argp->alock.oh, M_RPC);
2021 af->af_granted.alock.svid = argp->alock.svid;

--- 84 unchanged lines hidden (view full) ---

2106 if (!host) {
2107 result->stat.stat = nlm4_denied_nolocks;
2108 return (ENOMEM);
2109 }
2110
2111 NLM_DEBUG(3, "nlm_do_cancel(): caller_name = %s (sysid = %d)\n",
2112 host->nh_caller_name, host->nh_sysid);
2113
2073 af->af_granted.exclusive = argp->exclusive;
2074 af->af_granted.alock.caller_name =
2075 strdup(argp->alock.caller_name, M_RPC);
2076 nlm_copy_netobj(&af->af_granted.alock.fh,
2077 &argp->alock.fh, M_RPC);
2078 nlm_copy_netobj(&af->af_granted.alock.oh,
2079 &argp->alock.oh, M_RPC);
2080 af->af_granted.alock.svid = argp->alock.svid;

--- 84 unchanged lines hidden (view full) ---

2165 if (!host) {
2166 result->stat.stat = nlm4_denied_nolocks;
2167 return (ENOMEM);
2168 }
2169
2170 NLM_DEBUG(3, "nlm_do_cancel(): caller_name = %s (sysid = %d)\n",
2171 host->nh_caller_name, host->nh_sysid);
2172
2114 nlm_free_finished_locks(host);
2173 nlm_check_expired_locks(host);
2115 sysid = host->nh_sysid;
2116
2117 nlm_convert_to_fhandle_t(&fh, &argp->alock.fh);
2118 nlm_copy_netobj(&result->cookie, &argp->cookie, M_RPC);
2119
2120 if (time_uptime < nlm_grace_threshold) {
2121 result->stat.stat = nlm4_denied_grace_period;
2122 goto out;

--- 72 unchanged lines hidden (view full) ---

2195 if (!host) {
2196 result->stat.stat = nlm4_denied_nolocks;
2197 return (ENOMEM);
2198 }
2199
2200 NLM_DEBUG(3, "nlm_do_unlock(): caller_name = %s (sysid = %d)\n",
2201 host->nh_caller_name, host->nh_sysid);
2202
2174 sysid = host->nh_sysid;
2175
2176 nlm_convert_to_fhandle_t(&fh, &argp->alock.fh);
2177 nlm_copy_netobj(&result->cookie, &argp->cookie, M_RPC);
2178
2179 if (time_uptime < nlm_grace_threshold) {
2180 result->stat.stat = nlm4_denied_grace_period;
2181 goto out;

--- 72 unchanged lines hidden (view full) ---

2254 if (!host) {
2255 result->stat.stat = nlm4_denied_nolocks;
2256 return (ENOMEM);
2257 }
2258
2259 NLM_DEBUG(3, "nlm_do_unlock(): caller_name = %s (sysid = %d)\n",
2260 host->nh_caller_name, host->nh_sysid);
2261
2203 nlm_free_finished_locks(host);
2262 nlm_check_expired_locks(host);
2204 sysid = host->nh_sysid;
2205
2206 nlm_convert_to_fhandle_t(&fh, &argp->alock.fh);
2207 nlm_copy_netobj(&result->cookie, &argp->cookie, M_RPC);
2208
2209 if (time_uptime < nlm_grace_threshold) {
2210 result->stat.stat = nlm4_denied_grace_period;
2211 goto out;

--- 40 unchanged lines hidden (view full) ---

2252 host = nlm_find_host_by_addr(svc_getrpccaller(rqstp), rqstp->rq_vers);
2253 if (!host) {
2254 result->stat.stat = nlm4_denied_nolocks;
2255 return (ENOMEM);
2256 }
2257
2258 nlm_copy_netobj(&result->cookie, &argp->cookie, M_RPC);
2259 result->stat.stat = nlm4_denied;
2263 sysid = host->nh_sysid;
2264
2265 nlm_convert_to_fhandle_t(&fh, &argp->alock.fh);
2266 nlm_copy_netobj(&result->cookie, &argp->cookie, M_RPC);
2267
2268 if (time_uptime < nlm_grace_threshold) {
2269 result->stat.stat = nlm4_denied_grace_period;
2270 goto out;

--- 40 unchanged lines hidden (view full) ---

2311 host = nlm_find_host_by_addr(svc_getrpccaller(rqstp), rqstp->rq_vers);
2312 if (!host) {
2313 result->stat.stat = nlm4_denied_nolocks;
2314 return (ENOMEM);
2315 }
2316
2317 nlm_copy_netobj(&result->cookie, &argp->cookie, M_RPC);
2318 result->stat.stat = nlm4_denied;
2319 KFAIL_POINT_CODE(DEBUG_FP, nlm_deny_grant, goto out);
2260
2261 mtx_lock(&nlm_global_lock);
2262 TAILQ_FOREACH(nw, &nlm_waiting_locks, nw_link) {
2263 if (!nw->nw_waiting)
2264 continue;
2265 if (argp->alock.svid == nw->nw_lock.svid
2266 && argp->alock.l_offset == nw->nw_lock.l_offset
2267 && argp->alock.l_len == nw->nw_lock.l_len
2268 && argp->alock.fh.n_len == nw->nw_lock.fh.n_len
2269 && !memcmp(argp->alock.fh.n_bytes, nw->nw_lock.fh.n_bytes,
2270 nw->nw_lock.fh.n_len)) {
2271 nw->nw_waiting = FALSE;
2272 wakeup(nw);
2273 result->stat.stat = nlm4_granted;
2274 break;
2275 }
2276 }
2277 mtx_unlock(&nlm_global_lock);
2320
2321 mtx_lock(&nlm_global_lock);
2322 TAILQ_FOREACH(nw, &nlm_waiting_locks, nw_link) {
2323 if (!nw->nw_waiting)
2324 continue;
2325 if (argp->alock.svid == nw->nw_lock.svid
2326 && argp->alock.l_offset == nw->nw_lock.l_offset
2327 && argp->alock.l_len == nw->nw_lock.l_len
2328 && argp->alock.fh.n_len == nw->nw_lock.fh.n_len
2329 && !memcmp(argp->alock.fh.n_bytes, nw->nw_lock.fh.n_bytes,
2330 nw->nw_lock.fh.n_len)) {
2331 nw->nw_waiting = FALSE;
2332 wakeup(nw);
2333 result->stat.stat = nlm4_granted;
2334 break;
2335 }
2336 }
2337 mtx_unlock(&nlm_global_lock);
2338
2339out:
2278 if (rpcp)
2279 *rpcp = nlm_host_get_rpc(host, TRUE);
2280 nlm_host_release(host);
2281 return (0);
2282}
2283
2284void
2340 if (rpcp)
2341 *rpcp = nlm_host_get_rpc(host, TRUE);
2342 nlm_host_release(host);
2343 return (0);
2344}
2345
2346void
2347nlm_do_granted_res(nlm4_res *argp, struct svc_req *rqstp)
2348{
2349 struct nlm_host *host = NULL;
2350 struct nlm_async_lock *af = NULL;
2351 int error;
2352
2353 if (argp->cookie.n_len != sizeof(struct nlm_grantcookie)) {
2354 NLM_DEBUG(1, "NLM: bogus grant cookie");
2355 goto out;
2356 }
2357
2358 host = nlm_find_host_by_sysid(ng_sysid(&argp->cookie));
2359 if (!host) {
2360 NLM_DEBUG(1, "NLM: Unknown host rejected our grant");
2361 goto out;
2362 }
2363
2364 mtx_lock(&host->nh_lock);
2365 TAILQ_FOREACH(af, &host->nh_granted, af_link)
2366 if (ng_cookie(&argp->cookie) ==
2367 ng_cookie(&af->af_granted.cookie))
2368 break;
2369 if (af)
2370 TAILQ_REMOVE(&host->nh_granted, af, af_link);
2371 mtx_unlock(&host->nh_lock);
2372
2373 if (!af) {
2374 NLM_DEBUG(1, "NLM: host %s (sysid %d) replied to our grant "
2375 "with unrecognized cookie %d:%d", host->nh_caller_name,
2376 host->nh_sysid, ng_sysid(&argp->cookie),
2377 ng_cookie(&argp->cookie));
2378 goto out;
2379 }
2380
2381 if (argp->stat.stat != nlm4_granted) {
2382 af->af_fl.l_type = F_UNLCK;
2383 error = VOP_ADVLOCK(af->af_vp, NULL, F_UNLCK, &af->af_fl, F_REMOTE);
2384 if (error) {
2385 NLM_DEBUG(1, "NLM: host %s (sysid %d) rejected our grant "
2386 "and we failed to unlock (%d)", host->nh_caller_name,
2387 host->nh_sysid, error);
2388 goto out;
2389 }
2390
2391 NLM_DEBUG(5, "NLM: async lock %p rejected by host %s (sysid %d)",
2392 af, host->nh_caller_name, host->nh_sysid);
2393 } else {
2394 NLM_DEBUG(5, "NLM: async lock %p accepted by host %s (sysid %d)",
2395 af, host->nh_caller_name, host->nh_sysid);
2396 }
2397
2398 out:
2399 if (af)
2400 nlm_free_async_lock(af);
2401 if (host)
2402 nlm_host_release(host);
2403}
2404
2405void
2285nlm_do_free_all(nlm4_notify *argp)
2286{
2287 struct nlm_host *host, *thost;
2288
2289 TAILQ_FOREACH_SAFE(host, &nlm_hosts, nh_link, thost) {
2290 if (!strcmp(host->nh_caller_name, argp->name))
2291 nlm_host_notify(host, argp->state);
2292 }

--- 22 unchanged lines hidden ---
2406nlm_do_free_all(nlm4_notify *argp)
2407{
2408 struct nlm_host *host, *thost;
2409
2410 TAILQ_FOREACH_SAFE(host, &nlm_hosts, nh_link, thost) {
2411 if (!strcmp(host->nh_caller_name, argp->name))
2412 nlm_host_notify(host, argp->state);
2413 }

--- 22 unchanged lines hidden ---