Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 :
4 : test suite for SMB2 leases
5 :
6 : Copyright (C) Zachary Loafman 2009
7 :
8 : This program is free software; you can redistribute it and/or modify
9 : it under the terms of the GNU General Public License as published by
10 : the Free Software Foundation; either version 3 of the License, or
11 : (at your option) any later version.
12 :
13 : This program is distributed in the hope that it will be useful,
14 : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : GNU General Public License for more details.
17 :
18 : You should have received a copy of the GNU General Public License
19 : along with this program. If not, see <http://www.gnu.org/licenses/>.
20 : */
21 :
22 : #include "torture/util.h"
23 :
24 : struct lease_break_info {
25 : struct torture_context *tctx;
26 :
27 : struct smb2_lease_break lease_break;
28 : struct smb2_transport *lease_transport;
29 : bool lease_skip_ack;
30 : struct smb2_lease_break_ack lease_break_ack;
31 : int count;
32 : int failures;
33 :
34 : struct smb2_handle oplock_handle;
35 : uint8_t held_oplock_level;
36 : uint8_t oplock_level;
37 : int oplock_count;
38 : int oplock_failures;
39 : };
40 :
41 : #define CHECK_LEASE_BREAK(__lb, __oldstate, __state, __key) \
42 : do { \
43 : uint16_t __new = smb2_util_lease_state(__state); \
44 : uint16_t __old = smb2_util_lease_state(__oldstate); \
45 : CHECK_VAL((__lb)->new_lease_state, __new); \
46 : CHECK_VAL((__lb)->current_lease.lease_state, __old); \
47 : CHECK_VAL((__lb)->current_lease.lease_key.data[0], (__key)); \
48 : CHECK_VAL((__lb)->current_lease.lease_key.data[1], ~(__key)); \
49 : if (__old & (SMB2_LEASE_WRITE | SMB2_LEASE_HANDLE)) { \
50 : CHECK_VAL((__lb)->break_flags, \
51 : SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED); \
52 : } else { \
53 : CHECK_VAL((__lb)->break_flags, 0); \
54 : } \
55 : } while(0)
56 :
57 : #define CHECK_LEASE_BREAK_ACK(__lba, __state, __key) \
58 : do { \
59 : CHECK_VAL((__lba)->out.reserved, 0); \
60 : CHECK_VAL((__lba)->out.lease.lease_key.data[0], (__key)); \
61 : CHECK_VAL((__lba)->out.lease.lease_key.data[1], ~(__key)); \
62 : CHECK_VAL((__lba)->out.lease.lease_state, smb2_util_lease_state(__state)); \
63 : CHECK_VAL((__lba)->out.lease.lease_flags, 0); \
64 : CHECK_VAL((__lba)->out.lease.lease_duration, 0); \
65 : } while(0)
66 :
67 : #define CHECK_NO_BREAK(tctx) \
68 : do { \
69 : torture_wait_for_lease_break(tctx); \
70 : CHECK_VAL(lease_break_info.failures, 0); \
71 : CHECK_VAL(lease_break_info.count, 0); \
72 : CHECK_VAL(lease_break_info.oplock_failures, 0); \
73 : CHECK_VAL(lease_break_info.oplock_count, 0); \
74 : } while(0)
75 :
76 : #define CHECK_OPLOCK_BREAK(__brokento) \
77 : do { \
78 : torture_wait_for_lease_break(tctx); \
79 : CHECK_VAL(lease_break_info.oplock_count, 1); \
80 : CHECK_VAL(lease_break_info.oplock_failures, 0); \
81 : CHECK_VAL(lease_break_info.oplock_level, \
82 : smb2_util_oplock_level(__brokento)); \
83 : lease_break_info.held_oplock_level = lease_break_info.oplock_level; \
84 : } while(0)
85 :
86 : #define _CHECK_BREAK_INFO(__oldstate, __state, __key) \
87 : do { \
88 : torture_wait_for_lease_break(tctx); \
89 : CHECK_VAL(lease_break_info.failures, 0); \
90 : CHECK_VAL(lease_break_info.count, 1); \
91 : CHECK_LEASE_BREAK(&lease_break_info.lease_break, (__oldstate), \
92 : (__state), (__key)); \
93 : if (!lease_break_info.lease_skip_ack && \
94 : (lease_break_info.lease_break.break_flags & \
95 : SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED)) \
96 : { \
97 : torture_wait_for_lease_break(tctx); \
98 : CHECK_LEASE_BREAK_ACK(&lease_break_info.lease_break_ack, \
99 : (__state), (__key)); \
100 : } \
101 : } while(0)
102 :
103 : #define CHECK_BREAK_INFO(__oldstate, __state, __key) \
104 : do { \
105 : _CHECK_BREAK_INFO(__oldstate, __state, __key); \
106 : CHECK_VAL(lease_break_info.lease_break.new_epoch, 0); \
107 : } while(0)
108 :
109 : #define CHECK_BREAK_INFO_V2(__transport, __oldstate, __state, __key, __epoch) \
110 : do { \
111 : _CHECK_BREAK_INFO(__oldstate, __state, __key); \
112 : CHECK_VAL(lease_break_info.lease_break.new_epoch, __epoch); \
113 : if (!TARGET_IS_SAMBA3(tctx)) { \
114 : CHECK_VAL((uintptr_t)lease_break_info.lease_transport, \
115 : (uintptr_t)__transport); \
116 : } \
117 : } while(0)
118 :
119 : extern struct lease_break_info lease_break_info;
120 :
121 : bool torture_lease_handler(struct smb2_transport *transport,
122 : const struct smb2_lease_break *lb,
123 : void *private_data);
124 : bool torture_lease_ignore_handler(struct smb2_transport *transport,
125 : const struct smb2_lease_break *lb,
126 : void *private_data);
127 : void torture_wait_for_lease_break(struct torture_context *tctx);
128 :
129 550 : static inline void torture_reset_lease_break_info(struct torture_context *tctx,
130 : struct lease_break_info *r)
131 : {
132 550 : ZERO_STRUCTP(r);
133 550 : r->tctx = tctx;
134 550 : }
|