2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22 /*
23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 * Copyright 2015 Joyent, Inc.
26 */
27
28 #ifndef _SYS_FLOCK_IMPL_H
29 #define _SYS_FLOCK_IMPL_H
30
31 #include <sys/types.h>
32 #include <sys/fcntl.h> /* flock definition */
33 #include <sys/file.h> /* FREAD etc */
34 #include <sys/flock.h> /* RCMD etc */
35 #include <sys/kmem.h>
36 #include <sys/user.h>
37 #include <sys/thread.h>
38 #include <sys/proc.h>
39 #include <sys/cred.h>
40 #include <sys/debug.h>
41 #include <sys/cmn_err.h>
42 #include <sys/errno.h>
43 #include <sys/systm.h>
44 #include <sys/vnode.h>
45 #include <sys/share.h> /* just to get GETSYSID def */
46
47 #ifdef __cplusplus
48 extern "C" {
49 #endif
50
51 struct edge {
52 struct edge *edge_adj_next; /* adjacency list next */
53 struct edge *edge_adj_prev; /* adjacency list prev */
54 struct edge *edge_in_next; /* incoming edges list next */
55 struct edge *edge_in_prev; /* incoming edges list prev */
56 struct lock_descriptor *from_vertex; /* edge emanating from lock */
57 struct lock_descriptor *to_vertex; /* edge pointing to lock */
58 };
59
60 typedef struct edge edge_t;
61
62 struct lock_descriptor {
63 struct lock_descriptor *l_next; /* next active/sleep lock */
64 struct lock_descriptor *l_prev; /* previous active/sleep lock */
65 struct edge l_edge; /* edge for adj and in lists */
66 struct lock_descriptor *l_stack; /* for stack operations */
67 struct lock_descriptor *l_stack1; /* for stack operations */
68 struct lock_descriptor *l_dstack; /* stack for debug functions */
69 struct edge *l_sedge; /* start edge for graph alg. */
70 int l_index; /* used for barrier count */
71 struct graph *l_graph; /* graph this belongs to */
72 vnode_t *l_vnode; /* vnode being locked */
73 int l_type; /* type of lock */
74 int l_state; /* state described below */
75 u_offset_t l_start; /* start offset */
76 u_offset_t l_end; /* end offset */
77 flock64_t l_flock; /* original flock request */
78 int l_color; /* color used for graph alg */
79 kcondvar_t l_cv; /* wait condition for lock */
80 int pvertex; /* index to proc vertex */
81 int l_status; /* status described below */
82 flk_nlm_status_t l_nlm_state; /* state of NLM server */
83 flk_callback_t *l_callbacks; /* callbacks, or NULL */
84 zoneid_t l_zoneid; /* zone of request */
85 file_t *l_ofd; /* OFD-style reference */
86 };
87
88 typedef struct lock_descriptor lock_descriptor_t;
89
90 /*
91 * Each graph holds locking information for some number of vnodes. The
92 * active and sleeping lists are circular, with a dummy head element.
93 */
94
95 struct graph {
96 kmutex_t gp_mutex; /* mutex for this graph */
97 struct lock_descriptor active_locks;
98 struct lock_descriptor sleeping_locks;
99 int index; /* index of this graph into the hash table */
100 int mark; /* used for coloring the graph */
101 };
102
103 typedef struct graph graph_t;
104
381 #define HEAD(lock) (&(lock)->l_edge)
382 #define NEXT_ADJ(ep) ((ep)->edge_adj_next)
383 #define NEXT_IN(ep) ((ep)->edge_in_next)
384 #define IN_ADJ_INIT(lock) \
385 { \
386 (lock)->l_edge.edge_adj_next = (lock)->l_edge.edge_adj_prev = &(lock)->l_edge; \
387 (lock)->l_edge.edge_in_next = (lock)->l_edge.edge_in_prev = &(lock)->l_edge; \
388 }
389
390 #define COPY(lock1, lock2) \
391 { \
392 (lock1)->l_graph = (lock2)->l_graph; \
393 (lock1)->l_vnode = (lock2)->l_vnode; \
394 (lock1)->l_type = (lock2)->l_type; \
395 (lock1)->l_state = (lock2)->l_state; \
396 (lock1)->l_start = (lock2)->l_start; \
397 (lock1)->l_end = (lock2)->l_end; \
398 (lock1)->l_flock = (lock2)->l_flock; \
399 (lock1)->l_zoneid = (lock2)->l_zoneid; \
400 (lock1)->pvertex = (lock2)->pvertex; \
401 }
402
403 /*
404 * Clustering
405 */
406 /* Routines to set and get the NLM state in a lock request */
407 #define SET_NLM_STATE(lock, nlm_state) ((lock)->l_nlm_state = nlm_state)
408 #define GET_NLM_STATE(lock) ((lock)->l_nlm_state)
409 /*
410 * NLM registry abstraction:
411 * Abstraction overview:
412 * This registry keeps track of the NLM servers via their nlmids
413 * that have requested locks at the LLM this registry is associated
414 * with.
415 */
416 /* Routines to manipulate the NLM registry object state */
417 #define FLK_REGISTRY_IS_NLM_UNKNOWN(nlmreg, nlmid) \
418 ((nlmreg)[nlmid] == FLK_NLM_UNKNOWN)
419 #define FLK_REGISTRY_IS_NLM_UP(nlmreg, nlmid) \
420 ((nlmreg)[nlmid] == FLK_NLM_UP)
|
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
7 * with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22
23 /*
24 * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
25 */
26
27 /*
28 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
29 * Use is subject to license terms.
30 * Copyright 2015 Joyent, Inc.
31 */
32
33 #ifndef _SYS_FLOCK_IMPL_H
34 #define _SYS_FLOCK_IMPL_H
35
36 #include <sys/types.h>
37 #include <sys/fcntl.h> /* flock definition */
38 #include <sys/file.h> /* FREAD etc */
39 #include <sys/flock.h> /* RCMD etc */
40 #include <sys/kmem.h>
41 #include <sys/user.h>
42 #include <sys/thread.h>
43 #include <sys/proc.h>
44 #include <sys/cred.h>
45 #include <sys/debug.h>
46 #include <sys/cmn_err.h>
47 #include <sys/errno.h>
48 #include <sys/systm.h>
49 #include <sys/vnode.h>
50 #include <sys/share.h> /* just to get GETSYSID def */
51 #include <sys/time.h>
52
53 #ifdef __cplusplus
54 extern "C" {
55 #endif
56
57 struct edge {
58 struct edge *edge_adj_next; /* adjacency list next */
59 struct edge *edge_adj_prev; /* adjacency list prev */
60 struct edge *edge_in_next; /* incoming edges list next */
61 struct edge *edge_in_prev; /* incoming edges list prev */
62 struct lock_descriptor *from_vertex; /* edge emanating from lock */
63 struct lock_descriptor *to_vertex; /* edge pointing to lock */
64 };
65
66 typedef struct edge edge_t;
67
68 struct lock_descriptor {
69 struct lock_descriptor *l_next; /* next active/sleep lock */
70 struct lock_descriptor *l_prev; /* previous active/sleep lock */
71 struct edge l_edge; /* edge for adj and in lists */
72 struct lock_descriptor *l_stack; /* for stack operations */
73 struct lock_descriptor *l_stack1; /* for stack operations */
74 struct lock_descriptor *l_dstack; /* stack for debug functions */
75 struct edge *l_sedge; /* start edge for graph alg. */
76 int l_index; /* used for barrier count */
77 struct graph *l_graph; /* graph this belongs to */
78 vnode_t *l_vnode; /* vnode being locked */
79 int l_type; /* type of lock */
80 int l_state; /* state described below */
81 u_offset_t l_start; /* start offset */
82 u_offset_t l_end; /* end offset */
83 flock64_t l_flock; /* original flock request */
84 int l_color; /* color used for graph alg */
85 kcondvar_t l_cv; /* wait condition for lock */
86 int pvertex; /* index to proc vertex */
87 int l_status; /* status described below */
88 flk_nlm_status_t l_nlm_state; /* state of NLM server */
89 flk_callback_t *l_callbacks; /* callbacks, or NULL */
90 zoneid_t l_zoneid; /* zone of request */
91 hrtime_t l_blocker; /* time when this lock */
92 /* started to prevent other */
93 /* locks from being set */
94 file_t *l_ofd; /* OFD-style reference */
95 };
96
97 typedef struct lock_descriptor lock_descriptor_t;
98
99 /*
100 * Each graph holds locking information for some number of vnodes. The
101 * active and sleeping lists are circular, with a dummy head element.
102 */
103
104 struct graph {
105 kmutex_t gp_mutex; /* mutex for this graph */
106 struct lock_descriptor active_locks;
107 struct lock_descriptor sleeping_locks;
108 int index; /* index of this graph into the hash table */
109 int mark; /* used for coloring the graph */
110 };
111
112 typedef struct graph graph_t;
113
390 #define HEAD(lock) (&(lock)->l_edge)
391 #define NEXT_ADJ(ep) ((ep)->edge_adj_next)
392 #define NEXT_IN(ep) ((ep)->edge_in_next)
393 #define IN_ADJ_INIT(lock) \
394 { \
395 (lock)->l_edge.edge_adj_next = (lock)->l_edge.edge_adj_prev = &(lock)->l_edge; \
396 (lock)->l_edge.edge_in_next = (lock)->l_edge.edge_in_prev = &(lock)->l_edge; \
397 }
398
399 #define COPY(lock1, lock2) \
400 { \
401 (lock1)->l_graph = (lock2)->l_graph; \
402 (lock1)->l_vnode = (lock2)->l_vnode; \
403 (lock1)->l_type = (lock2)->l_type; \
404 (lock1)->l_state = (lock2)->l_state; \
405 (lock1)->l_start = (lock2)->l_start; \
406 (lock1)->l_end = (lock2)->l_end; \
407 (lock1)->l_flock = (lock2)->l_flock; \
408 (lock1)->l_zoneid = (lock2)->l_zoneid; \
409 (lock1)->pvertex = (lock2)->pvertex; \
410 (lock1)->l_blocker = (lock2)->l_blocker; \
411 }
412
413 /*
414 * Clustering
415 */
416 /* Routines to set and get the NLM state in a lock request */
417 #define SET_NLM_STATE(lock, nlm_state) ((lock)->l_nlm_state = nlm_state)
418 #define GET_NLM_STATE(lock) ((lock)->l_nlm_state)
419 /*
420 * NLM registry abstraction:
421 * Abstraction overview:
422 * This registry keeps track of the NLM servers via their nlmids
423 * that have requested locks at the LLM this registry is associated
424 * with.
425 */
426 /* Routines to manipulate the NLM registry object state */
427 #define FLK_REGISTRY_IS_NLM_UNKNOWN(nlmreg, nlmid) \
428 ((nlmreg)[nlmid] == FLK_NLM_UNKNOWN)
429 #define FLK_REGISTRY_IS_NLM_UP(nlmreg, nlmid) \
430 ((nlmreg)[nlmid] == FLK_NLM_UP)
|