Print this page
NEX-5665 SMB2 oplock leases
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-5665 SMB2 oplock leases
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-1643 dtrace provider for smbsrv
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
NEX-6041 Should pass the smbtorture lock tests
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
NEX-1192 add context options to xpg4 grep (nits)
NEX-1192 add context options to xpg4 grep
SUP-867 panic in smb_com_locking_andx
SMB-11 SMB2 message parse & dispatch
SMB-12 SMB2 Negotiate Protocol
SMB-13 SMB2 Session Setup
SMB-14 SMB2 Logoff
SMB-15 SMB2 Tree Connect
SMB-16 SMB2 Tree Disconnect
SMB-17 SMB2 Create
SMB-18 SMB2 Close
SMB-19 SMB2 Flush
SMB-20 SMB2 Read
SMB-21 SMB2 Write
SMB-22 SMB2 Lock/Unlock
SMB-23 SMB2 Ioctl
SMB-24 SMB2 Cancel
SMB-25 SMB2 Echo
SMB-26 SMB2 Query Dir
SMB-27 SMB2 Change Notify
SMB-28 SMB2 Query Info
SMB-29 SMB2 Set Info
SMB-30 SMB2 Oplocks
SMB-53 SMB2 Create Context options
(SMB2 code review cleanup 1, 2, 3)
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/fs/smbsrv/smb_locking_andx.c
+++ new/usr/src/uts/common/fs/smbsrv/smb_locking_andx.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
|
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
24 - * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
24 + * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
25 25 */
26 26
27 27 /*
28 28 * SMB: locking_andx
29 29 *
30 30 * SMB_COM_LOCKING_ANDX allows both locking and/or unlocking of file range(s).
31 31 *
32 32 * Client Request Description
33 33 * ================================== =================================
34 34 *
35 35 * UCHAR WordCount; Count of parameter words = 8
36 36 * UCHAR AndXCommand; Secondary (X) command; 0xFF = none
37 37 * UCHAR AndXReserved; Reserved (must be 0)
38 38 * USHORT AndXOffset; Offset to next command WordCount
39 39 * USHORT Fid; File handle
40 40 * UCHAR LockType; See LockType table below
41 41 * UCHAR OplockLevel; The new oplock level
42 42 * ULONG Timeout; Milliseconds to wait for unlock
43 43 * USHORT NumberOfUnlocks; Num. unlock range structs following
44 44 * USHORT NumberOfLocks; Num. lock range structs following
45 45 * USHORT ByteCount; Count of data bytes
46 46 * LOCKING_ANDX_RANGE Unlocks[]; Unlock ranges
47 47 * LOCKING_ANDX_RANGE Locks[]; Lock ranges
48 48 *
49 49 * LockType Flag Name Value Description
50 50 * ============================ ===== ================================
51 51 *
52 52 * LOCKING_ANDX_SHARED_LOCK 0x01 Read-only lock
53 53 * LOCKING_ANDX_OPLOCK_RELEASE 0x02 Oplock break notification
54 54 * LOCKING_ANDX_CHANGE_LOCKTYPE 0x04 Change lock type
55 55 * LOCKING_ANDX_CANCEL_LOCK 0x08 Cancel outstanding request
56 56 * LOCKING_ANDX_LARGE_FILES 0x10 Large file locking format
57 57 *
58 58 * LOCKING_ANDX_RANGE Format
59 59 * =====================================================================
60 60 *
61 61 * USHORT Pid; PID of process "owning" lock
62 62 * ULONG Offset; Offset to bytes to [un]lock
63 63 * ULONG Length; Number of bytes to [un]lock
64 64 *
65 65 * Large File LOCKING_ANDX_RANGE Format
66 66 * =====================================================================
67 67 *
68 68 * USHORT Pid; PID of process "owning" lock
69 69 * USHORT Pad; Pad to DWORD align (mbz)
70 70 * ULONG OffsetHigh; Offset to bytes to [un]lock
71 71 * (high)
72 72 * ULONG OffsetLow; Offset to bytes to [un]lock (low)
73 73 * ULONG LengthHigh; Number of bytes to [un]lock
74 74 * (high)
75 75 * ULONG LengthLow; Number of bytes to [un]lock (low)
76 76 *
77 77 * Server Response Description
78 78 * ================================== =================================
79 79 *
80 80 * UCHAR WordCount; Count of parameter words = 2
81 81 * UCHAR AndXCommand; Secondary (X) command; 0xFF =
82 82 * none
83 83 * UCHAR AndXReserved; Reserved (must be 0)
84 84 * USHORT AndXOffset; Offset to next command WordCount
85 85 * USHORT ByteCount; Count of data bytes = 0
86 86 *
87 87 * Locking is a simple mechanism for excluding other processes read/write
88 88 * access to regions of a file. The locked regions can be anywhere in the
89 89 * logical file. Locking beyond end-of-file is permitted. Any process
90 90 * using the Fid specified in this request's Fid has access to the locked
91 91 * bytes, other processes will be denied the locking of the same bytes.
92 92 *
93 93 * The proper method for using locks is not to rely on being denied read or
94 94 * write access on any of the read/write protocols but rather to attempt
95 95 * the locking protocol and proceed with the read/write only if the locks
96 96 * succeeded.
97 97 *
98 98 * Locking a range of bytes will fail if any subranges or overlapping
99 99 * ranges are locked. In other words, if any of the specified bytes are
100 100 * already locked, the lock will fail.
101 101 *
102 102 * If NumberOfUnlocks is non-zero, the Unlocks vector contains
103 103 * NumberOfUnlocks elements. Each element requests that a lock at Offset
104 104 * of Length be released. If NumberOfLocks is nonzero, the Locks vector
105 105 * contains NumberOfLocks elements. Each element requests the acquisition
106 106 * of a lock at Offset of Length.
107 107 *
108 108 * Timeout is the maximum amount of time to wait for the byte range(s)
109 109 * specified to become unlocked. A timeout value of 0 indicates that the
110 110 * server should fail immediately if any lock range specified is locked. A
111 111 *
112 112 * timeout value of -1 indicates that the server should wait as long as it
113 113 * takes for each byte range specified to become unlocked so that it may be
114 114 * again locked by this protocol. Any other value of smb_timeout specifies
115 115 * the maximum number of milliseconds to wait for all lock range(s)
116 116 * specified to become available.
117 117 *
118 118 * If any of the lock ranges timeout because of the area to be locked is
119 119 * already locked (or the lock fails), the other ranges in the protocol
120 120 * request which were successfully locked as a result of this protocol will
121 121 * be unlocked (either all requested ranges will be locked when this
122 122 * protocol returns to the client or none).
123 123 *
124 124 * If LockType has the LOCKING_ANDX_SHARED_LOCK flag set, the lock is
125 125 * specified as a shared lock. Locks for both read and write (where
126 126 * LOCKING_ANDX_SHARED_LOCK is clear) should be prohibited, but other
127 127 * shared locks should be permitted. If shared locks can not be supported
128 128 * by a server, the server should map the lock to a lock for both read and
129 129 * write. Closing a file with locks still in force causes the locks to be
130 130 * released in no defined order.
131 131 *
132 132 * If LockType has the LOCKING_ANDX_LARGE_FILES flag set and if the
133 133 * negotiated protocol is NT LM 0.12 or later, then the Locks and Unlocks
134 134 * vectors are in the Large File LOCKING_ANDX_RANGE format. This allows
135 135 * specification of 64 bit offsets for very large files.
136 136 *
137 137 * If the one and only member of the Locks vector has the
138 138 * LOCKING_ANDX_CANCEL_LOCK flag set in the LockType field, the client is
139 139 * requesting the server to cancel a previously requested, but not yet
140 140 * responded to, lock.
141 141 *
142 142 * If LockType has the LOCKING_ANDX_CHANGE_LOCKTYPE flag set, the client is
143 143 * requesting that the server atomically change the lock type from a shared
144 144 * lock to an exclusive lock or vice versa. If the server can not do this
145 145 * in an atomic fashion, the server must reject this request. NT and W95
146 146 * servers do not support this capability.
147 147 *
148 148 * Oplocks are described in the "Opportunistic Locks" section elsewhere in
149 149 * this document. A client requests an oplock by setting the appropriate
150 150 * bit in the SMB_COM_OPEN_ANDX request when the file is being opened in a
151 151 * mode which is not exclusive. The server responds by setting the
152 152 * appropriate bit in the response SMB indicating whether or not the oplock
153 153 * was granted. By granting the oplock, the server tells the client the
154 154 * file is currently only being used by this one client process at the
155 155 * current time. The client can therefore safely do read ahead and write
156 156 * behind as well as local caching of file locks knowing that the file will
157 157 * not be accessed/changed in any way by another process while the oplock
158 158 * is in effect. The client will be notified when any other process
159 159 * attempts to open or modify the oplocked file.
160 160 *
161 161 * When another user attempts to open or otherwise modify the file which a
162 162 * client has oplocked, the server delays the second attempt and notifies
163 163 * the client via an SMB_LOCKING_ANDX SMB asynchronously sent from the
164 164 * server to the client. This message has the LOCKING_ANDX_OPLOCK_RELEASE
165 165 * flag set indicating to the client that the oplock is being broken.
166 166 *
167 167 * OplockLevel indicates the type of oplock the client now owns. If
168 168 * OplockLevel is 0, the client possesses no oplocks on the file at all, if
169 169 * OplockLevel is 1 the client possesses a Level II oplock. The client is
170 170 * expected to flush any dirty buffers to the server, submit any file locks
171 171 * and respond to the server with either an SMB_LOCKING_ANDX SMB having the
172 172 * LOCKING_ANDX_OPLOCK_RELEASE flag set, or with a file close if the file
173 173 * is no longer in use by the client. If the client sends an
174 174 * SMB_LOCKING_ANDX SMB with the LOCKING_ANDX_OPLOCK_RELEASE flag set and
175 175 * NumberOfLocks is zero, the server does not send a response. Since a
176 176 * close being sent to the server and break oplock notification from the
177 177 * server could cross on the wire, if the client gets an oplock
178 178 * notification on a file which it does not have open, that notification
179 179 * should be ignored.
180 180 *
181 181 * Due to timing, the client could get an "oplock broken" notification in a
182 182 * user's data buffer as a result of this notification crossing on the wire
183 183 * with a SMB_COM_READ_RAW request. The client must detect this (use
184 184 * length of msg, "FFSMB", MID of -1 and Command of SMB_COM_LOCKING_ANDX)
185 185 * and honor the "oplock broken" notification as usual. The server must
186 186 * also note on receipt of an SMB_COM_READ_RAW request that there is an
187 187 * outstanding (unanswered) "oplock broken" notification to the client and
188 188 * return a zero length response denoting failure of the read raw request.
189 189 * The client should (after responding to the "oplock broken"
190 190 * notification), use a standard read protocol to redo the read request.
191 191 * This allows a file to actually contain data matching an "oplock broken"
192 192 * notification and still be read correctly.
193 193 *
194 194 * The entire message sent and received including the optional second
195 195 * protocol must fit in the negotiated maximum transfer size. The
196 196 * following are the only valid SMB commands for AndXCommand for
197 197 * SMB_COM_LOCKING_ANDX:
198 198 *
199 199 * SMB_COM_READ SMB_COM_READ_ANDX
200 200 * SMB_COM_WRITE SMB_COM_WRITE_ANDX
201 201 * SMB_COM_FLUSH
202 202 *
203 203 * 4.2.6.1 Errors
204 204 *
|
↓ open down ↓ |
170 lines elided |
↑ open up ↑ |
205 205 * ERRDOS/ERRbadfile
206 206 * ERRDOS/ERRbadfid
207 207 * ERRDOS/ERRlock
208 208 * ERRDOS/ERRinvdevice
209 209 * ERRSRV/ERRinvid
210 210 * ERRSRV/ERRbaduid
211 211 */
212 212
213 213 #include <smbsrv/smb_kproto.h>
214 214
215 +/*
216 + * This is a somewhat arbitrary sanity limit on the length of the
217 + * SMB2_LOCK_ELEMENT array. It usually has length one or two.
218 + */
219 +int smb_lock_max_elem = 1024;
220 +
215 221 smb_sdrc_t
216 222 smb_pre_locking_andx(smb_request_t *sr)
217 223 {
218 - DTRACE_SMB_1(op__LockingX__start, smb_request_t *, sr);
224 + DTRACE_SMB_START(op__LockingX, smb_request_t *, sr);
219 225 return (SDRC_SUCCESS);
220 226 }
221 227
222 228 void
223 229 smb_post_locking_andx(smb_request_t *sr)
224 230 {
225 - DTRACE_SMB_1(op__LockingX__done, smb_request_t *, sr);
231 + DTRACE_SMB_DONE(op__LockingX, smb_request_t *, sr);
226 232 }
227 233
234 +struct lreq {
235 + uint64_t off;
236 + uint64_t len;
237 + uint32_t pid;
238 + uint32_t _x;
239 +};
240 +
228 241 smb_sdrc_t
229 242 smb_com_locking_andx(smb_request_t *sr)
230 243 {
231 244 unsigned short i;
232 245 unsigned char lock_type; /* See lock_type table above */
233 246 unsigned char oplock_level; /* The new oplock level */
234 247 uint32_t timeout; /* Milliseconds to wait for lock */
235 248 unsigned short unlock_num; /* # unlock range structs */
236 249 unsigned short lock_num; /* # lock range structs */
237 - uint32_t save_pid; /* Process Id of owner */
238 - uint32_t offset32, length32;
239 - uint64_t offset64;
240 - uint64_t length64;
241 250 DWORD result;
242 251 int rc;
243 252 uint32_t ltype;
253 + uint32_t status;
244 254 smb_ofile_t *ofile;
245 255 uint16_t tmp_pid; /* locking uses 16-bit pids */
246 - uint8_t brk;
256 + uint32_t lrv_tot;
257 + struct lreq *lrv_ul;
258 + struct lreq *lrv_lk;
259 + struct lreq *lr;
247 260
248 261 rc = smbsr_decode_vwv(sr, "4.wbblww", &sr->smb_fid, &lock_type,
249 262 &oplock_level, &timeout, &unlock_num, &lock_num);
250 263 if (rc != 0)
251 264 return (SDRC_ERROR);
252 265
253 266 smbsr_lookup_file(sr);
254 267 if (sr->fid_ofile == NULL) {
255 268 smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
256 269 return (SDRC_ERROR);
257 270 }
258 271 ofile = sr->fid_ofile;
259 272 if (ofile->f_node == NULL) {
260 273 smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
261 274 ERRDOS, ERROR_INVALID_PARAMETER);
262 275 return (SDRC_ERROR);
263 276 }
264 277
278 + if (unlock_num > smb_lock_max_elem ||
279 + lock_num > smb_lock_max_elem) {
280 + smbsr_error(sr, NT_STATUS_INSUFFICIENT_RESOURCES,
281 + ERRDOS, ERROR_NO_SYSTEM_RESOURCES);
282 + return (SDRC_ERROR);
283 + }
284 +
265 285 if (lock_type & LOCKING_ANDX_SHARED_LOCK)
266 286 ltype = SMB_LOCK_TYPE_READONLY;
267 287 else
268 288 ltype = SMB_LOCK_TYPE_READWRITE;
269 289
270 - save_pid = sr->smb_pid; /* Save the original pid */
271 -
272 290 if (lock_type & LOCKING_ANDX_OPLOCK_RELEASE) {
291 + uint32_t NewLevel;
273 292 if (oplock_level == 0)
274 - brk = SMB_OPLOCK_BREAK_TO_NONE;
293 + NewLevel = OPLOCK_LEVEL_NONE;
275 294 else
276 - brk = SMB_OPLOCK_BREAK_TO_LEVEL_II;
277 - smb_oplock_ack(ofile->f_node, ofile, brk);
295 + NewLevel = OPLOCK_LEVEL_TWO;
296 + status = smb_oplock_ack_break(sr, ofile, &NewLevel);
297 + if (status == NT_STATUS_OPLOCK_BREAK_IN_PROGRESS) {
298 + (void) smb_oplock_wait_break(ofile->f_node, 0);
299 + status = 0;
300 + }
278 301 if (unlock_num == 0 && lock_num == 0)
279 302 return (SDRC_NO_REPLY);
280 303 }
281 304
282 305 /*
283 306 * No support for changing locktype (although we could probably
284 307 * implement this)
285 308 */
286 309 if (lock_type & LOCKING_ANDX_CHANGE_LOCK_TYPE) {
287 310 smbsr_error(sr, 0, ERRDOS,
288 311 ERROR_ATOMIC_LOCKS_NOT_SUPPORTED);
289 312 return (SDRC_ERROR);
290 313 }
291 314
292 - /*
293 - * No support for cancel lock (smbtorture expects this)
294 - */
295 - if (lock_type & LOCKING_ANDX_CANCEL_LOCK) {
296 - smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
297 - ERRDOS, ERROR_INVALID_PARAMETER);
298 - return (SDRC_ERROR);
299 - }
300 -
301 315 if (lock_type & LOCKING_ANDX_LARGE_FILES) {
302 316 /*
303 317 * negotiated protocol should be NT LM 0.12 or later
304 318 */
305 319 if (sr->session->dialect < NT_LM_0_12) {
306 320 smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
307 321 ERRDOS, ERROR_INVALID_PARAMETER);
308 322 return (SDRC_ERROR);
309 323 }
324 + }
310 325
311 - for (i = 0; i < unlock_num; i++) {
312 - rc = smb_mbc_decodef(&sr->smb_data, "w2.QQ",
313 - &tmp_pid, &offset64, &length64);
314 - if (rc) {
315 - /*
316 - * This is the error returned by Windows 2000
317 - * even when STATUS32 has been negotiated.
318 - */
319 - smbsr_error(sr, 0, ERRSRV, ERRerror);
320 - return (SDRC_ERROR);
321 - }
322 - sr->smb_pid = tmp_pid; /* NB: 16-bit */
326 + /*
327 + * Parse the unlock, lock vectors. Will parse all the
328 + * unlock + lock records into one array, and then use
329 + * pointers to the unlock and lock parts.
330 + */
331 + lrv_tot = unlock_num + lock_num;
332 + lrv_ul = smb_srm_zalloc(sr, lrv_tot * sizeof (*lrv_ul));
333 + lrv_lk = &lrv_ul[unlock_num];
323 334
324 - result = smb_unlock_range(sr, sr->fid_ofile->f_node,
325 - offset64, length64);
326 - if (result != NT_STATUS_SUCCESS) {
327 - smbsr_error(sr, NT_STATUS_RANGE_NOT_LOCKED,
328 - ERRDOS, ERROR_NOT_LOCKED);
329 - return (SDRC_ERROR);
330 - }
335 + for (i = 0; i < lrv_tot; i++) {
336 + lr = &lrv_ul[i];
337 + if (lock_type & LOCKING_ANDX_LARGE_FILES) {
338 + rc = smb_mbc_decodef(&sr->smb_data, "w2.QQ",
339 + &tmp_pid, &lr->off, &lr->len);
340 + } else {
341 + uint32_t offset32, length32;
342 + rc = smb_mbc_decodef(&sr->smb_data, "wll",
343 + &tmp_pid, &offset32, &length32);
344 + lr->off = offset32;
345 + lr->len = length32;
331 346 }
347 + lr->pid = tmp_pid; /* 16-bit PID */
348 + if (rc) {
349 + /*
350 + * This is the error returned by Windows 2000
351 + * even when STATUS32 has been negotiated.
352 + */
353 + smbsr_error(sr, 0, ERRSRV, ERRerror);
354 + return (SDRC_ERROR);
355 + }
356 + }
332 357
333 - for (i = 0; i < lock_num; i++) {
334 - rc = smb_mbc_decodef(&sr->smb_data, "w2.QQ",
335 - &tmp_pid, &offset64, &length64);
336 - if (rc) {
337 - smbsr_error(sr, 0, ERRSRV, ERRerror);
338 - return (SDRC_ERROR);
339 - }
340 - sr->smb_pid = tmp_pid; /* NB: 16-bit */
358 + /*
359 + * Cancel waiting locks. MS-CIFS says one place that
360 + * this cancels all waiting locks for this FID+PID,
361 + * but smbtorture insists this cancels just one.
362 + * Tests with Windows 7 confirms that.
363 + */
364 + if ((lock_type & LOCKING_ANDX_CANCEL_LOCK) != 0) {
365 + lr = lrv_lk;
341 366
342 - result = smb_lock_range(sr, offset64, length64, timeout,
343 - ltype);
344 - if (result != NT_STATUS_SUCCESS) {
345 - smb_lock_range_error(sr, result);
346 - return (SDRC_ERROR);
347 - }
367 + result = smb_lock_range_cancel(sr, lr->off, lr->len, lr->pid);
368 +
369 + if (result != NT_STATUS_SUCCESS) {
370 + smbsr_error(sr, 0, ERRDOS,
371 + ERROR_CANCEL_VIOLATION);
372 + return (SDRC_ERROR);
348 373 }
349 - } else {
350 - for (i = 0; i < unlock_num; i++) {
351 - rc = smb_mbc_decodef(&sr->smb_data, "wll", &tmp_pid,
352 - &offset32, &length32);
353 - if (rc) {
354 - smbsr_error(sr, 0, ERRSRV, ERRerror);
355 - return (SDRC_ERROR);
356 - }
357 - sr->smb_pid = tmp_pid; /* NB: 16-bit */
374 + goto out;
375 + }
358 376
359 - result = smb_unlock_range(sr, sr->fid_ofile->f_node,
360 - (uint64_t)offset32, (uint64_t)length32);
361 - if (result != NT_STATUS_SUCCESS) {
362 - smbsr_error(sr, NT_STATUS_RANGE_NOT_LOCKED,
363 - ERRDOS, ERROR_NOT_LOCKED);
364 - return (SDRC_ERROR);
365 - }
377 + /*
378 + * Normal unlock and lock list
379 + */
380 + for (i = 0; i < unlock_num; i++) {
381 + lr = &lrv_ul[i];
382 +
383 + result = smb_unlock_range(sr, lr->off, lr->len, lr->pid);
384 + if (result != NT_STATUS_SUCCESS) {
385 + smbsr_error(sr, NT_STATUS_RANGE_NOT_LOCKED,
386 + ERRDOS, ERROR_NOT_LOCKED);
387 + return (SDRC_ERROR);
366 388 }
389 + }
390 + for (i = 0; i < lock_num; i++) {
391 + lr = &lrv_lk[i];
367 392
368 - for (i = 0; i < lock_num; i++) {
369 - rc = smb_mbc_decodef(&sr->smb_data, "wll", &tmp_pid,
370 - &offset32, &length32);
371 - if (rc) {
372 - smbsr_error(sr, 0, ERRSRV, ERRerror);
373 - return (SDRC_ERROR);
393 + result = smb_lock_range(sr, lr->off, lr->len, lr->pid,
394 + ltype, timeout);
395 + if (result != NT_STATUS_SUCCESS) {
396 + /*
397 + * Oh... we have to rollback.
398 + */
399 + while (i > 0) {
400 + --i;
401 + lr = &lrv_lk[i];
402 + (void) smb_unlock_range(sr,
403 + lr->off, lr->len, lr->pid);
374 404 }
375 - sr->smb_pid = tmp_pid; /* NB: 16-bit */
376 -
377 - result = smb_lock_range(sr, (uint64_t)offset32,
378 - (uint64_t)length32, timeout, ltype);
379 - if (result != NT_STATUS_SUCCESS) {
380 - smb_lock_range_error(sr, result);
381 - return (SDRC_ERROR);
382 - }
405 + smb_lock_range_error(sr, result);
406 + return (SDRC_ERROR);
383 407 }
384 408 }
385 409
386 - sr->smb_pid = save_pid;
387 - if (smbsr_encode_result(sr, 2, 0, "bb.ww", 2, sr->andx_com, 7, 0))
410 +out:
411 + if (smbsr_encode_result(sr, 2, 0, "bb.ww",
412 + 2, sr->andx_com, 0x27, 0) != 0)
388 413 return (SDRC_ERROR);
389 414 return (SDRC_SUCCESS);
390 415 }
391 416
392 417 /*
393 418 * Compose an SMB1 Oplock Break Notification packet, including
394 419 * the SMB1 header and everything, in sr->reply.
395 420 * The caller will send it and free the request.
396 421 */
397 422 void
398 -smb1_oplock_break_notification(smb_request_t *sr, uint8_t brk)
423 +smb1_oplock_break_notification(smb_request_t *sr, uint32_t NewLevel)
399 424 {
400 425 smb_ofile_t *ofile = sr->fid_ofile;
401 426 uint16_t fid;
402 427 uint8_t lock_type;
403 428 uint8_t oplock_level;
404 429
405 - switch (brk) {
430 + /*
431 + * Convert internal level to SMB1
432 + */
433 + switch (NewLevel) {
406 434 default:
407 435 ASSERT(0);
408 436 /* FALLTHROUGH */
409 - case SMB_OPLOCK_BREAK_TO_NONE:
437 + case OPLOCK_LEVEL_NONE:
410 438 oplock_level = 0;
411 439 break;
412 - case SMB_OPLOCK_BREAK_TO_LEVEL_II:
440 +
441 + case OPLOCK_LEVEL_TWO:
413 442 oplock_level = 1;
414 443 break;
415 444 }
416 445
417 446 sr->smb_com = SMB_COM_LOCKING_ANDX;
418 447 sr->smb_tid = ofile->f_tree->t_tid;
419 448 sr->smb_pid = 0xFFFF;
420 449 sr->smb_uid = 0;
421 450 sr->smb_mid = 0xFFFF;
422 451 fid = ofile->f_fid;
423 452 lock_type = LOCKING_ANDX_OPLOCK_RELEASE;
424 453
425 454 (void) smb_mbc_encodef(
426 455 &sr->reply, "Mb19.wwwwbb3.wbb10.",
427 456 /* "\xffSMB" M */
428 457 sr->smb_com, /* b */
429 458 /* status, flags, signature 19. */
430 459 sr->smb_tid, /* w */
431 460 sr->smb_pid, /* w */
432 461 sr->smb_uid, /* w */
433 462 sr->smb_mid, /* w */
434 463 8, /* word count b */
435 464 0xFF, /* AndX cmd b */
436 465 /* AndX reserved, offset 3. */
437 466 fid,
438 467 lock_type,
439 468 oplock_level);
440 469 }
|
↓ open down ↓ |
18 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX