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)
 
 |