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
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.
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]
22 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
23 /* All Rights Reserved */
27 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
28 * Use is subject to license terms.
31 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
32 * Copyright 2015 Joyent, Inc.
38 #include <sys/types.h>
39 #include <sys/fcntl.h>
40 #include <sys/vnode.h>
41 #include <sys/t_lock.h> /* for <sys/callb.h> */
42 #include <sys/callb.h>
43 #include <sys/param.h>
54 * Private declarations and instrumentation for local locking.
58 * The flag passed to fs_frlock() may be ORed together with either
59 * `F_REMOTELOCK' or `F_PXFSLOCK'. Since this flag is initialized using the
60 * `f_flag' field in the `file' structure, and that field is an unsigned short,
61 * we do not use the first 2 bytes.
63 #define F_REMOTELOCK (0x01 << 16) /* Set if NLM lock */
64 #define F_PXFSLOCK (0x02 << 16) /* Clustering: set if PXFS lock */
67 * The command passed to reclock() is made by ORing together one or more of
68 * the following values.
71 #define INOFLCK 0x01 /* Vnode is locked when reclock() is called. */
72 #define SETFLCK 0x02 /* Set a file lock. */
73 #define SLPFLCK 0x04 /* Wait if blocked. */
74 #define RCMDLCK 0x08 /* F_REMOTELOCK specified */
75 #define PCMDLCK 0x10 /* Clustering: F_PXFSLOCK specified */
76 #define NBMLCK 0x20 /* non-blocking mandatory locking */
79 * Special pid value that can be passed to cleanlocks(). It means that
80 * cleanlocks() should flush all locks for the given sysid, not just the
81 * locks owned by a specific process.
86 /* file locking structure (connected to vnode) */
91 * The lock manager is allowed to use unsigned offsets and lengths, though
92 * regular Unix processes are still required to use signed offsets and
95 typedef ulong_t u_off_t
;
97 #define MAX_U_OFF_T ((u_off_t)~0)
98 #define MAX_U_OFFSET_T ((u_offset_t)~0)
101 * define MAXEND as the largest positive value the signed offset_t will hold.
103 #define MAXEND MAXOFFSET_T
106 * Definitions for accessing the l_pad area of struct flock. The
107 * descriminant of the pad_info_t union is the fcntl command used in
108 * conjunction with the flock struct.
112 int pi_pad
[4]; /* (original pad area) */
113 int pi_has_rmt
; /* F_HASREMOTELOCKS */
116 #define l_has_rmt(flockp) (((pad_info_t *)((flockp)->l_pad))->pi_has_rmt)
119 * Optional callbacks for blocking lock requests. Each function is called
121 * The first call is after the request is put in the "sleeping" list, but
122 * before waiting. At most one callback may return a callb_cpr_t object;
123 * the others must return NULL. If a callb_cpr_t is returned, the thread
124 * will be marked as safe to suspend while waiting for the lock.
125 * The second call is after the request wakes up. Note that the request
126 * might not have been granted at the second call (e.g., the request was
128 * New callbacks should be added to the head of the list. For the first
129 * call the list is walked in order. For the second call the list is
130 * walked backwards (in case the callbacks need to reacquire locks).
133 typedef enum {FLK_BEFORE_SLEEP
, FLK_AFTER_SLEEP
} flk_cb_when_t
;
135 struct flk_callback
{
136 struct flk_callback
*cb_next
; /* circular linked list */
137 struct flk_callback
*cb_prev
;
138 callb_cpr_t
*(*cb_callback
)(flk_cb_when_t
, void *); /* fcn ptr */
139 void *cb_data
; /* ptr to callback data */
142 typedef struct flk_callback flk_callback_t
;
145 * This structure members are not used any more inside the kernel.
146 * The structure is used for casting some pointer assignments only.
149 typedef struct filock
{
151 struct flock set
; /* contains type, start, and end */
153 int granted_flag
; /* granted flag */
154 struct filock
*blk
; /* for sleeping locks only */
155 struct attacher
*blocking_list
;
156 struct attacher
*my_attacher
;
162 #define FLP_DELAYED_FREE -1 /* special value for granted_flag */
164 /* structure that contains list of locks to be granted */
166 #define MAX_GRANT_LOCKS 52
168 typedef struct grant_lock
{
169 struct filock
*grant_lock_list
[MAX_GRANT_LOCKS
];
170 struct grant_lock
*next
;
174 * Provide a way to cleanly enable and disable Network Lock Manager locking
175 * requests (i.e., requests from remote clients):
176 * FLK_NLM_SHUTTING_DOWN: Forces all blocked NLM requests to bail out
178 * FLK_NLM_DOWN: Clears all granted NLM server locks. Both status
179 * codes cause new NLM lock requests to fail immediately with ENOLCK.
180 * FLK_NLM_UP: Changes the state of all locks to UP, after a server has
181 * shutdown and is restarting on the same node.
185 * Enumerated type of the four possible states an NLM server can be in.
189 FLK_NLM_SHUTTING_DOWN
,
195 * Provide a way to cleanly enable and disable lock manager locking
196 * requests (i.e., requests from remote clients). FLK_WAKEUP_SLEEPERS
197 * forces all blocked lock manager requests to bail out and return ENOLCK.
198 * FLK_LOCKMGR_DOWN clears all granted lock manager locks. Both status
199 * codes cause new lock manager requests to fail immediately with ENOLCK.
206 } flk_lockmgr_status_t
;
208 #if defined(_KERNEL) || defined(_FAKE_KERNEL)
211 * The following structure is used to hold a list of locks returned
212 * by the F_ACTIVELIST or F_SLEEPINGLIST commands to fs_frlock.
214 * N.B. The lists returned by these commands are dynamically
215 * allocated and must be freed by the caller. The vnodes returned
216 * in the lists are held and must be released when the caller is done.
219 typedef struct locklist
{
221 struct flock64 ll_flock
;
222 struct locklist
*ll_next
;
225 #define FLK_QUERY_ACTIVE 0x1
226 #define FLK_QUERY_SLEEPING 0x2
229 int ofdlock(file_t
*, int, struct flock64
*, int, u_offset_t
);
230 void ofdcleanlock(file_t
*);
232 int reclock(struct vnode
*, struct flock64
*, int, int, u_offset_t
,
234 int chklock(struct vnode
*, int, u_offset_t
, ssize_t
, int,
236 int convoff(struct vnode
*, struct flock64
*, int, offset_t
);
237 void cleanlocks(struct vnode
*, pid_t
, int);
238 locklist_t
*flk_get_sleeping_locks(int sysid
, pid_t pid
);
239 locklist_t
*flk_get_active_locks(int sysid
, pid_t pid
);
240 locklist_t
*flk_active_locks_for_vp(const struct vnode
*vp
);
241 locklist_t
*flk_active_nbmand_locks_for_vp(const struct vnode
*vp
);
242 locklist_t
*flk_active_nbmand_locks(pid_t pid
);
243 void flk_free_locklist(locklist_t
*);
244 int flk_convert_lock_data(struct vnode
*, struct flock64
*,
245 u_offset_t
*, u_offset_t
*, offset_t
);
246 int flk_check_lock_data(u_offset_t
, u_offset_t
, offset_t
);
247 int flk_has_remote_locks(struct vnode
*vp
);
248 void flk_set_lockmgr_status(flk_lockmgr_status_t status
);
249 int flk_sysid_has_locks(int sysid
, int chklck
);
250 int flk_has_remote_locks_for_sysid(vnode_t
*vp
, int);
251 void flk_init_callback(flk_callback_t
*,
252 callb_cpr_t
*(*)(flk_cb_when_t
, void *), void *);
253 void flk_add_callback(flk_callback_t
*,
254 callb_cpr_t
*(*)(flk_cb_when_t
, void *), void *,
256 void flk_del_callback(flk_callback_t
*);
257 callb_cpr_t
*flk_invoke_callbacks(flk_callback_t
*, flk_cb_when_t
);
260 extern zone_key_t flock_zone_key
;
262 void *flk_zone_init(zoneid_t
);
263 void flk_zone_fini(zoneid_t
, void *);
265 /* Clustering hooks */
266 void cl_flk_set_nlm_status(int nlmid
, flk_nlm_status_t nlm_state
);
267 void cl_flk_remove_locks_by_sysid(int sysid
);
268 int cl_flk_has_remote_locks_for_nlmid(struct vnode
*vp
, int nlmid
);
269 void cl_flk_change_nlm_state_to_unknown(int nlmid
);
270 void cl_flk_delete_pxfs_locks(struct vfs
*vfsp
, int pxfsid
);
277 #endif /* _SYS_FLOCK_H */