1 /* 2 * This file and its contents are supplied under the terms of the 3 * Common Development and Distribution License ("CDDL"), version 1.0. 4 * You may only use this file in accordance with the terms of version 5 * 1.0 of the CDDL. 6 * 7 * A full copy of the text of the CDDL should have accompanied this 8 * source. A copy of the CDDL is also available via the Internet at 9 * http://www.illumos.org/license/CDDL. 10 */ 11 12 /* 13 * Copyright 2017 Nexenta Systems, Inc. All rights reserved. 14 */ 15 16 #ifndef _SMBSRV_SMB_OPLOCK_H 17 #define _SMBSRV_SMB_OPLOCK_H 18 19 #include <smbsrv/ntifs.h> 20 21 #ifdef __cplusplus 22 extern "C" { 23 #endif 24 25 /* 26 * 2.1.1.10 Per Oplock 27 * 28 * 29 * ExclusiveOpen: The Open used to request the opportunistic lock. 30 * 31 * IIOplocks: A list of zero or more Opens used to request a LEVEL_TWO 32 * opportunistic lock, as specified in section 2.1.5.17.1. 33 * 34 * ROplocks: A list of zero or more Opens used to request a LEVEL_GRANULAR 35 * (RequestedOplockLevel: READ_CACHING) opportunistic lock, as specified in 36 * section 2.1.5.17.1. 37 * 38 * RHOplocks: A list of zero or more Opens used to request a LEVEL_GRANULAR 39 * (RequestedOplockLevel: (READ_CACHING|HANDLE_CACHING)) opportunistic lock, 40 * as specified in section 2.1.5.17.1. 41 * 42 * RHBreakQueue: A list of zero or more RHOpContext objects. This queue is 43 * used to track (READ_CACHING|HANDLE_CACHING) oplocks as they are breaking. 44 * 45 * WaitList: A list of zero or more Opens belonging to operations that are 46 * waiting for an oplock to break, as specified in section 2.1.4.12. 47 * 48 * State: The current state of the oplock, expressed as a combination of 49 * one or more flags. Valid flags are: 50 * [ As follows; Re-ordered a bit from the spec. ] 51 */ 52 53 /* 54 * READ_CACHING - Indicates that this Oplock represents an oplock 55 * that provides caching of reads; this provides the SMB 2.1 read 56 * caching lease, as described in [MS-SMB2] section 2.2.13.2.8. 57 */ 58 #define READ_CACHING OPLOCK_LEVEL_CACHE_READ /* 1 */ 59 60 /* 61 * HANDLE_CACHING - Indicates that this Oplock represents an oplock 62 * that provides caching of handles; this provides the SMB 2.1 handle 63 * caching lease, as described in [MS-SMB2] section 2.2.13.2.8. 64 */ 65 #define HANDLE_CACHING OPLOCK_LEVEL_CACHE_HANDLE /* 2 */ 66 67 /* 68 * WRITE_CACHING - Indicates that this Oplock represents an oplock 69 * that provides caching of writes; this provides the SMB 2.1 write 70 * caching lease, as described in [MS-SMB2] section 2.2.13.2.8. 71 */ 72 #define WRITE_CACHING OPLOCK_LEVEL_CACHE_WRITE /* 4 */ 73 74 /* 75 * EXCLUSIVE - Indicates that this Oplock represents an oplock that 76 * can be held by exactly one client at a time. This flag always appears 77 * in combination with other flags that indicate the actual oplock level. 78 * For example, (READ_CACHING|WRITE_CACHING|EXCLUSIVE) represents a 79 * read caching and write caching oplock, which can be held by only 80 * one client at a time. 81 */ 82 #define EXCLUSIVE 0x00000010 83 84 /* 85 * MIXED_R_AND_RH - Always appears together with READ_CACHING and 86 * HANDLE_CACHING. Indicates that this Oplock represents an oplock 87 * on which at least one client has been granted a read caching oplock, 88 * and at least one other client has been granted a read caching and 89 * handle caching oplock. 90 */ 91 #define MIXED_R_AND_RH 0x00000020 92 93 /* 94 * LEVEL_TWO_OPLOCK - Indicates that this Oplock represents a 95 * Level 2 (also called Shared) oplock. 96 * Corresponds to SMB2_OPLOCK_LEVEL_II 97 */ 98 #define LEVEL_TWO_OPLOCK OPLOCK_LEVEL_TWO /* 0x100 */ 99 100 /* 101 * LEVEL_ONE_OPLOCK - Indicates that this Oplock represents a 102 * Level 1 (also called Exclusive) oplock. 103 * Corresponds to SMB2_OPLOCK_LEVEL_EXCLUSIVE 104 */ 105 #define LEVEL_ONE_OPLOCK OPLOCK_LEVEL_ONE /* 0x200 */ 106 107 /* 108 * BATCH_OPLOCK - Indicates that this Oplock represents a Batch oplock. 109 * Corresponds to SMB2_OPLOCK_LEVEL_BATCH 110 */ 111 #define BATCH_OPLOCK OPLOCK_LEVEL_BATCH /* 0x400 */ 112 113 /* Note: ntifs.h OPLOCK_LEVEL_GRANULAR 0x800 */ 114 115 /* 116 * Note that the oplock leasing implementation uses this shift 117 * to convert (i.e.) CACHE_READ to BREAK_TO_READ_CACHING etc. 118 * This relationship is checked in smb_srv_oplock.c 119 */ 120 #define BREAK_SHIFT 16 121 122 /* 123 * BREAK_TO_READ_CACHING - Indicates that this Oplock represents an 124 * oplock that is currently breaking to an oplock that provides 125 * caching of reads; the oplock has broken but the break has not yet 126 * been acknowledged. 127 */ 128 #define BREAK_TO_READ_CACHING 0x00010000 129 130 /* 131 * BREAK_TO_HANDLE_CACHING - Indicates that this Oplock represents an 132 * oplock that is currently breaking to an oplock that provides 133 * caching of handles; the oplock has broken but the break has not yet 134 * been acknowledged. Note: == (CACHE_HANDLE << BREAK_SHIFT) 135 */ 136 #define BREAK_TO_HANDLE_CACHING 0x00020000 137 138 /* 139 * BREAK_TO_WRITE_CACHING - Indicates that this Oplock represents an 140 * oplock that is currently breaking to an oplock that provides 141 * caching of writes; the oplock has broken but the break has 142 * not yet been acknowledged. 143 */ 144 #define BREAK_TO_WRITE_CACHING 0x00040000 145 146 /* 147 * BREAK_TO_NO_CACHING - Indicates that this Oplock represents an 148 * oplock that is currently breaking to None (that is, no oplock); 149 * the oplock has broken but the break has not yet been acknowledged. 150 */ 151 #define BREAK_TO_NO_CACHING 0x00080000 152 153 /* 154 * BREAK_TO_TWO - Indicates that this Oplock represents an oplock 155 * that is currently breaking from either Level 1 or Batch to Level 2; 156 * the oplock has broken but the break has not yet been acknowledged. 157 */ 158 #define BREAK_TO_TWO 0x00100000 159 160 /* 161 * BREAK_TO_NONE - Indicates that this Oplock represents an oplock 162 * that is currently breaking from either Level 1 or Batch to None 163 * (that is, no oplock); the oplock has broken but the break has 164 * not yet been acknowledged. 165 */ 166 #define BREAK_TO_NONE 0x00200000 167 168 /* 169 * BREAK_TO_TWO_TO_NONE - Indicates that this Oplock represents an 170 * oplock that is currently breaking from either Level 1 or Batch to 171 * None (that is, no oplock), and was previously breaking from Level 1 172 * or Batch to Level 2; the oplock has broken but the break has 173 * not yet been acknowledged. 174 */ 175 #define BREAK_TO_TWO_TO_NONE 0x00400000 176 177 /* 178 * NO_OPLOCK - Indicates that this Oplock does not represent a 179 * currently granted or breaking oplock. This is semantically 180 * equivalent to the Oplock object being entirely absent from a 181 * Stream. This flag always appears alone. 182 * Note we also have OPLOCK_LEVEL_NONE == 0 from ntifs.h 183 */ 184 #define NO_OPLOCK 0x10000000 185 186 /* 187 * An internal flag, non-overlapping wth other oplock flags, 188 * used only in smb_cmn_oplock.c (and here only to make clear 189 * that it does not overlap with an other flags above). 190 */ 191 #define PARENT_OBJECT 0x40000000 192 193 /* 194 * Also not in the spec, but convenient 195 */ 196 #define BREAK_LEVEL_MASK (\ 197 BREAK_TO_READ_CACHING |\ 198 BREAK_TO_WRITE_CACHING |\ 199 BREAK_TO_HANDLE_CACHING |\ 200 BREAK_TO_NO_CACHING) 201 202 #define BREAK_ANY (\ 203 BREAK_LEVEL_MASK |\ 204 BREAK_TO_TWO |\ 205 BREAK_TO_NONE |\ 206 BREAK_TO_TWO_TO_NONE) 207 208 209 /* 210 * Convenience macro to walk ofiles on a give node. 211 * Used as follows: 212 * FOREACH_NODE_OFILE(node, o) { muck_with(o); } 213 */ 214 #define FOREACH_NODE_OFILE(node, o) for \ 215 (o = smb_llist_head(&node->n_ofile_list); \ 216 o != NULL; \ 217 o = smb_llist_next(&node->n_ofile_list, o)) 218 219 /* 220 * Some short-hand names used in the oplock code. 221 */ 222 223 #define STATUS_NEW_HANDLE NT_STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE 224 #define STATUS_CANT_GRANT NT_STATUS_CANNOT_GRANT_REQUESTED_OPLOCK 225 226 typedef enum oplock_type { 227 LEVEL_NONE = OPLOCK_LEVEL_NONE, 228 LEVEL_TWO = OPLOCK_LEVEL_TWO, 229 LEVEL_ONE = OPLOCK_LEVEL_ONE, 230 LEVEL_BATCH = OPLOCK_LEVEL_BATCH, 231 LEVEL_GRANULAR = OPLOCK_LEVEL_GRANULAR 232 } oplock_type_t; 233 234 typedef enum oplock_cache_level { 235 CACHE_R = READ_CACHING, 236 237 CACHE_RH = READ_CACHING | 238 HANDLE_CACHING, 239 240 CACHE_RW = READ_CACHING | 241 WRITE_CACHING, 242 243 CACHE_RWH = READ_CACHING | 244 WRITE_CACHING | 245 HANDLE_CACHING, 246 } oplock_cache_t; 247 248 #ifdef __cplusplus 249 } 250 #endif 251 252 #endif /* _SMBSRV_SMB_OPLOCK_H */ 253