Print this page
NEX-3758 Support for remote stale lock detection
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
SMB-50 User-mode SMB server
Includes work by these authors:
Thomas Keiser <thomas.keiser@nexenta.com>
Albert Lee <trisk@nexenta.com>
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/sys/flock.h
+++ new/usr/src/uts/common/sys/flock.h
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License, Version 1.0 only
6 6 * (the "License"). You may not use this file except in compliance
7 7 * with the License.
8 8 *
9 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 10 * or http://www.opensolaris.org/os/licensing.
11 11 * See the License for the specific language governing permissions
|
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
12 12 * and limitations under the License.
13 13 *
14 14 * When distributing Covered Code, include this CDDL HEADER in each
15 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 16 * If applicable, add the following below this CDDL HEADER, with the
17 17 * fields enclosed by brackets "[]" replaced with your own identifying
18 18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 19 *
20 20 * CDDL HEADER END
21 21 */
22 +
23 +/*
24 + * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
25 + */
26 +
22 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
23 28 /* All Rights Reserved */
24 29
25 30
26 31 /*
27 32 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
28 33 * Use is subject to license terms.
29 34 */
30 35 /*
31 36 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
32 37 * Copyright 2015 Joyent, Inc.
33 38 */
34 39
35 40 #ifndef _SYS_FLOCK_H
36 41 #define _SYS_FLOCK_H
37 42
38 43 #include <sys/types.h>
39 44 #include <sys/fcntl.h>
40 45 #include <sys/vnode.h>
41 46 #include <sys/t_lock.h> /* for <sys/callb.h> */
42 47 #include <sys/callb.h>
43 48 #include <sys/param.h>
44 49 #include <sys/zone.h>
45 50 #if defined(_KERNEL)
46 51 #include <sys/file.h>
47 52 #endif
48 53
49 54 #ifdef __cplusplus
50 55 extern "C" {
51 56 #endif
52 57
53 58 /*
54 59 * Private declarations and instrumentation for local locking.
55 60 */
56 61
57 62 /*
58 63 * The flag passed to fs_frlock() may be ORed together with either
59 64 * `F_REMOTELOCK' or `F_PXFSLOCK'. Since this flag is initialized using the
60 65 * `f_flag' field in the `file' structure, and that field is an unsigned short,
61 66 * we do not use the first 2 bytes.
62 67 */
63 68 #define F_REMOTELOCK (0x01 << 16) /* Set if NLM lock */
64 69 #define F_PXFSLOCK (0x02 << 16) /* Clustering: set if PXFS lock */
65 70
66 71 /*
67 72 * The command passed to reclock() is made by ORing together one or more of
68 73 * the following values.
69 74 */
70 75
71 76 #define INOFLCK 0x01 /* Vnode is locked when reclock() is called. */
72 77 #define SETFLCK 0x02 /* Set a file lock. */
73 78 #define SLPFLCK 0x04 /* Wait if blocked. */
74 79 #define RCMDLCK 0x08 /* F_REMOTELOCK specified */
75 80 #define PCMDLCK 0x10 /* Clustering: F_PXFSLOCK specified */
76 81 #define NBMLCK 0x20 /* non-blocking mandatory locking */
77 82
78 83 /*
79 84 * Special pid value that can be passed to cleanlocks(). It means that
80 85 * cleanlocks() should flush all locks for the given sysid, not just the
81 86 * locks owned by a specific process.
82 87 */
83 88
84 89 #define IGN_PID (-1)
85 90
86 91 /* file locking structure (connected to vnode) */
87 92
88 93 #define l_end l_len
89 94
90 95 /*
91 96 * The lock manager is allowed to use unsigned offsets and lengths, though
92 97 * regular Unix processes are still required to use signed offsets and
93 98 * lengths.
94 99 */
95 100 typedef ulong_t u_off_t;
96 101
97 102 #define MAX_U_OFF_T ((u_off_t)~0)
98 103 #define MAX_U_OFFSET_T ((u_offset_t)~0)
99 104
100 105 /*
101 106 * define MAXEND as the largest positive value the signed offset_t will hold.
102 107 */
103 108 #define MAXEND MAXOFFSET_T
104 109
105 110 /*
106 111 * Definitions for accessing the l_pad area of struct flock. The
107 112 * descriminant of the pad_info_t union is the fcntl command used in
108 113 * conjunction with the flock struct.
109 114 */
110 115
111 116 typedef union {
112 117 int pi_pad[4]; /* (original pad area) */
113 118 int pi_has_rmt; /* F_HASREMOTELOCKS */
114 119 } pad_info_t;
115 120
116 121 #define l_has_rmt(flockp) (((pad_info_t *)((flockp)->l_pad))->pi_has_rmt)
117 122
118 123 /*
119 124 * Optional callbacks for blocking lock requests. Each function is called
120 125 * twice.
121 126 * The first call is after the request is put in the "sleeping" list, but
122 127 * before waiting. At most one callback may return a callb_cpr_t object;
123 128 * the others must return NULL. If a callb_cpr_t is returned, the thread
124 129 * will be marked as safe to suspend while waiting for the lock.
125 130 * The second call is after the request wakes up. Note that the request
126 131 * might not have been granted at the second call (e.g., the request was
127 132 * signalled).
128 133 * New callbacks should be added to the head of the list. For the first
129 134 * call the list is walked in order. For the second call the list is
130 135 * walked backwards (in case the callbacks need to reacquire locks).
131 136 */
132 137
133 138 typedef enum {FLK_BEFORE_SLEEP, FLK_AFTER_SLEEP} flk_cb_when_t;
134 139
135 140 struct flk_callback {
136 141 struct flk_callback *cb_next; /* circular linked list */
137 142 struct flk_callback *cb_prev;
138 143 callb_cpr_t *(*cb_callback)(flk_cb_when_t, void *); /* fcn ptr */
139 144 void *cb_data; /* ptr to callback data */
140 145 };
141 146
142 147 typedef struct flk_callback flk_callback_t;
143 148
144 149 /*
145 150 * This structure members are not used any more inside the kernel.
146 151 * The structure is used for casting some pointer assignments only.
147 152 */
148 153
149 154 typedef struct filock {
150 155 kcondvar_t cv;
151 156 struct flock set; /* contains type, start, and end */
152 157 struct {
153 158 int granted_flag; /* granted flag */
154 159 struct filock *blk; /* for sleeping locks only */
155 160 struct attacher *blocking_list;
156 161 struct attacher *my_attacher;
157 162 } stat;
158 163 struct filock *prev;
159 164 struct filock *next;
160 165 } filock_t;
161 166
162 167 #define FLP_DELAYED_FREE -1 /* special value for granted_flag */
163 168
164 169 /* structure that contains list of locks to be granted */
165 170
166 171 #define MAX_GRANT_LOCKS 52
167 172
168 173 typedef struct grant_lock {
169 174 struct filock *grant_lock_list[MAX_GRANT_LOCKS];
170 175 struct grant_lock *next;
171 176 } grant_lock_t;
172 177
173 178 /*
174 179 * Provide a way to cleanly enable and disable Network Lock Manager locking
175 180 * requests (i.e., requests from remote clients):
176 181 * FLK_NLM_SHUTTING_DOWN: Forces all blocked NLM requests to bail out
177 182 * and return ENOLCK.
178 183 * FLK_NLM_DOWN: Clears all granted NLM server locks. Both status
179 184 * codes cause new NLM lock requests to fail immediately with ENOLCK.
180 185 * FLK_NLM_UP: Changes the state of all locks to UP, after a server has
181 186 * shutdown and is restarting on the same node.
182 187 */
183 188
184 189 /*
185 190 * Enumerated type of the four possible states an NLM server can be in.
186 191 */
187 192 typedef enum {
188 193 FLK_NLM_UP,
189 194 FLK_NLM_SHUTTING_DOWN,
190 195 FLK_NLM_DOWN,
191 196 FLK_NLM_UNKNOWN
192 197 } flk_nlm_status_t;
193 198
194 199 /*
195 200 * Provide a way to cleanly enable and disable lock manager locking
196 201 * requests (i.e., requests from remote clients). FLK_WAKEUP_SLEEPERS
197 202 * forces all blocked lock manager requests to bail out and return ENOLCK.
198 203 * FLK_LOCKMGR_DOWN clears all granted lock manager locks. Both status
199 204 * codes cause new lock manager requests to fail immediately with ENOLCK.
200 205 */
201 206
202 207 typedef enum {
203 208 FLK_LOCKMGR_UP,
204 209 FLK_WAKEUP_SLEEPERS,
205 210 FLK_LOCKMGR_DOWN
206 211 } flk_lockmgr_status_t;
207 212
208 213 #if defined(_KERNEL) || defined(_FAKE_KERNEL)
209 214
210 215 /*
211 216 * The following structure is used to hold a list of locks returned
212 217 * by the F_ACTIVELIST or F_SLEEPINGLIST commands to fs_frlock.
213 218 *
214 219 * N.B. The lists returned by these commands are dynamically
215 220 * allocated and must be freed by the caller. The vnodes returned
216 221 * in the lists are held and must be released when the caller is done.
217 222 */
218 223
219 224 typedef struct locklist {
220 225 struct vnode *ll_vp;
221 226 struct flock64 ll_flock;
222 227 struct locklist *ll_next;
223 228 } locklist_t;
224 229
225 230 #define FLK_QUERY_ACTIVE 0x1
226 231 #define FLK_QUERY_SLEEPING 0x2
227 232
228 233 #if defined(_KERNEL)
229 234 int ofdlock(file_t *, int, struct flock64 *, int, u_offset_t);
230 235 void ofdcleanlock(file_t *);
231 236 #endif
232 237 int reclock(struct vnode *, struct flock64 *, int, int, u_offset_t,
233 238 flk_callback_t *);
234 239 int chklock(struct vnode *, int, u_offset_t, ssize_t, int,
235 240 caller_context_t *);
236 241 int convoff(struct vnode *, struct flock64 *, int, offset_t);
237 242 void cleanlocks(struct vnode *, pid_t, int);
238 243 locklist_t *flk_get_sleeping_locks(int sysid, pid_t pid);
239 244 locklist_t *flk_get_active_locks(int sysid, pid_t pid);
240 245 locklist_t *flk_active_locks_for_vp(const struct vnode *vp);
241 246 locklist_t *flk_active_nbmand_locks_for_vp(const struct vnode *vp);
242 247 locklist_t *flk_active_nbmand_locks(pid_t pid);
243 248 void flk_free_locklist(locklist_t *);
244 249 int flk_convert_lock_data(struct vnode *, struct flock64 *,
245 250 u_offset_t *, u_offset_t *, offset_t);
246 251 int flk_check_lock_data(u_offset_t, u_offset_t, offset_t);
247 252 int flk_has_remote_locks(struct vnode *vp);
248 253 void flk_set_lockmgr_status(flk_lockmgr_status_t status);
249 254 int flk_sysid_has_locks(int sysid, int chklck);
250 255 int flk_has_remote_locks_for_sysid(vnode_t *vp, int);
251 256 void flk_init_callback(flk_callback_t *,
252 257 callb_cpr_t *(*)(flk_cb_when_t, void *), void *);
253 258 void flk_add_callback(flk_callback_t *,
254 259 callb_cpr_t *(*)(flk_cb_when_t, void *), void *,
255 260 flk_callback_t *);
256 261 void flk_del_callback(flk_callback_t *);
257 262 callb_cpr_t *flk_invoke_callbacks(flk_callback_t *, flk_cb_when_t);
258 263
259 264 /* Zones hooks */
260 265 extern zone_key_t flock_zone_key;
|
↓ open down ↓ |
229 lines elided |
↑ open up ↑ |
261 266
262 267 void *flk_zone_init(zoneid_t);
263 268 void flk_zone_fini(zoneid_t, void *);
264 269
265 270 /* Clustering hooks */
266 271 void cl_flk_set_nlm_status(int nlmid, flk_nlm_status_t nlm_state);
267 272 void cl_flk_remove_locks_by_sysid(int sysid);
268 273 int cl_flk_has_remote_locks_for_nlmid(struct vnode *vp, int nlmid);
269 274 void cl_flk_change_nlm_state_to_unknown(int nlmid);
270 275 void cl_flk_delete_pxfs_locks(struct vfs *vfsp, int pxfsid);
276 +
277 +/* Support for the remote stale lock detection */
278 +struct sockaddr;
279 +
280 +typedef int (*sysid_to_host_translator_t)(zoneid_t, sysid_t, struct sockaddr *,
281 + const char **);
282 +
283 +void flk_add_sysid_to_host_translator(sysid_to_host_translator_t);
271 284 #endif /* _KERNEL */
272 285
273 286 #ifdef __cplusplus
274 287 }
275 288 #endif
276 289
277 290 #endif /* _SYS_FLOCK_H */
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX