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