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