Print this page
NEX-6276 SMB sparse file support
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-2604 Windows Explorer Stops Working / Crashes when Security Tab is accessed
NEX-2593 SMB2: unable to create folder with long filename on 4.0.3
NEX-2442 regression with smbtorture test raw.sfileinfo.rename
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/smb2_setinfo_file.c
+++ new/usr/src/uts/common/fs/smbsrv/smb2_setinfo_file.c
1 1 /*
2 2 * This file and its contents are supplied under the terms of the
|
↓ open down ↓ |
2 lines elided |
↑ open up ↑ |
3 3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 4 * You may only use this file in accordance with the terms of version
5 5 * 1.0 of the CDDL.
6 6 *
7 7 * A full copy of the text of the CDDL should have accompanied this
8 8 * source. A copy of the CDDL is also available via the Internet at
9 9 * http://www.illumos.org/license/CDDL.
10 10 */
11 11
12 12 /*
13 - * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
13 + * Copyright 2016 Nexenta Systems, Inc. All rights reserved.
14 14 */
15 15
16 16 /*
17 17 * Dispatch function for SMB2_SET_INFO
18 18 *
19 19 * [MS-FSCC 2.4] If a file system does not support ...
20 20 * an Information Classs, NT_STATUS_INVALID_PARAMETER...
21 21 */
22 22
23 23 #include <smbsrv/smb2_kproto.h>
24 24 #include <smbsrv/smb_fsops.h>
25 25 #include <smbsrv/ntifs.h>
26 26
27 27 static uint32_t smb2_setf_rename(smb_request_t *, smb_setinfo_t *);
28 28 static uint32_t smb2_setf_link(smb_request_t *, smb_setinfo_t *);
29 29
30 30 static uint32_t smb2_setf_seek(smb_request_t *, smb_setinfo_t *);
31 31 static uint32_t smb2_setf_full_ea(smb_request_t *, smb_setinfo_t *);
32 32 static uint32_t smb2_setf_mode(smb_request_t *, smb_setinfo_t *);
33 33
34 34 static uint32_t smb2_setf_pipe(smb_request_t *, smb_setinfo_t *);
35 35 static uint32_t smb2_setf_valid_len(smb_request_t *, smb_setinfo_t *);
36 36 static uint32_t smb2_setf_shortname(smb_request_t *, smb_setinfo_t *);
37 37
38 38
39 39 uint32_t
40 40 smb2_setinfo_file(smb_request_t *sr, smb_setinfo_t *si, int InfoClass)
41 41 {
42 42 smb_ofile_t *of = sr->fid_ofile;
43 43 uint32_t status;
44 44
45 45 si->si_node = of->f_node;
46 46
47 47 switch (InfoClass) {
48 48 case FileBasicInformation: /* 4 */
49 49 status = smb_set_basic_info(sr, si);
50 50 break;
51 51 case FileRenameInformation: /* 10 */
52 52 status = smb2_setf_rename(sr, si);
53 53 break;
54 54 case FileLinkInformation: /* 11 */
55 55 status = smb2_setf_link(sr, si);
56 56 break;
57 57 case FileDispositionInformation: /* 13 */
58 58 status = smb_set_disposition_info(sr, si);
59 59 break;
60 60 case FilePositionInformation: /* 14 */
61 61 status = smb2_setf_seek(sr, si);
62 62 break;
63 63 case FileFullEaInformation: /* 15 */
64 64 status = smb2_setf_full_ea(sr, si);
65 65 break;
66 66 case FileModeInformation: /* 16 */
67 67 status = smb2_setf_mode(sr, si);
68 68 break;
69 69 case FileAllocationInformation: /* 19 */
70 70 status = smb_set_alloc_info(sr, si);
71 71 break;
72 72 case FileEndOfFileInformation: /* 20 */
73 73 status = smb_set_eof_info(sr, si);
74 74 break;
75 75 case FilePipeInformation: /* 23 */
76 76 status = smb2_setf_pipe(sr, si);
77 77 break;
78 78 case FileValidDataLengthInformation: /* 39 */
79 79 status = smb2_setf_valid_len(sr, si);
80 80 break;
81 81 case FileShortNameInformation: /* 40 */
82 82 status = smb2_setf_shortname(sr, si);
83 83 break;
84 84 default:
85 85 status = NT_STATUS_INVALID_INFO_CLASS;
86 86 break;
87 87 }
88 88
89 89 return (status);
90 90 }
91 91
92 92
93 93 /*
94 94 * FileRenameInformation
95 95 * See also: smb_set_rename_info()
96 96 */
97 97 static uint32_t
98 98 smb2_setf_rename(smb_request_t *sr, smb_setinfo_t *si)
99 99 {
100 100 char *fname;
101 101 uint8_t flags;
102 102 uint64_t rootdir;
103 103 uint32_t namelen;
104 104 uint32_t status = 0;
105 105 int rc;
106 106
107 107 rc = smb_mbc_decodef(&si->si_data, "b7.ql",
108 108 &flags, &rootdir, &namelen);
109 109 if (rc == 0) {
110 110 rc = smb_mbc_decodef(&si->si_data, "%#U",
111 111 sr, namelen, &fname);
112 112 }
113 113 if (rc != 0)
114 114 return (NT_STATUS_INFO_LENGTH_MISMATCH);
115 115
116 116 if ((rootdir != 0) || (namelen == 0) || (namelen >= SMB_MAXPATHLEN)) {
117 117 return (NT_STATUS_INVALID_PARAMETER);
118 118 }
119 119
120 120 status = smb_setinfo_rename(sr, si->si_node, fname, flags);
121 121
122 122 return (status);
123 123 }
124 124
125 125 /*
126 126 * FileLinkInformation
127 127 */
128 128 static uint32_t
129 129 smb2_setf_link(smb_request_t *sr, smb_setinfo_t *si)
130 130 {
131 131 char *fname;
132 132 uint8_t flags;
133 133 uint64_t rootdir;
134 134 uint32_t namelen;
135 135 uint32_t status = 0;
136 136 int rc;
137 137
138 138 rc = smb_mbc_decodef(&si->si_data, "b7.ql",
139 139 &flags, &rootdir, &namelen);
140 140 if (rc == 0) {
141 141 rc = smb_mbc_decodef(&si->si_data, "%#U",
142 142 sr, namelen, &fname);
143 143 }
144 144 if (rc != 0)
145 145 return (NT_STATUS_INFO_LENGTH_MISMATCH);
146 146
147 147 if ((rootdir != 0) || (namelen == 0) || (namelen >= SMB_MAXPATHLEN)) {
148 148 return (NT_STATUS_INVALID_PARAMETER);
149 149 }
150 150
151 151 status = smb_setinfo_link(sr, si->si_node, fname, flags);
152 152
153 153 return (status);
154 154 }
155 155
156 156
157 157 /*
158 158 * FilePositionInformation
159 159 */
160 160 static uint32_t
161 161 smb2_setf_seek(smb_request_t *sr, smb_setinfo_t *si)
162 162 {
163 163 smb_ofile_t *of = sr->fid_ofile;
164 164 uint64_t newoff;
165 165
166 166 if (smb_mbc_decodef(&si->si_data, "q", &newoff) != 0)
167 167 return (NT_STATUS_INVALID_PARAMETER);
168 168
169 169 ASSERT(of->f_magic == SMB_OFILE_MAGIC);
170 170 mutex_enter(&of->f_mutex);
171 171 of->f_seek_pos = newoff;
172 172 mutex_exit(&of->f_mutex);
173 173
174 174 return (0);
175 175 }
176 176
177 177 /*
178 178 * FileFullEaInformation
179 179 * We could put EAs in a named stream...
180 180 */
181 181 /* ARGSUSED */
182 182 static uint32_t
183 183 smb2_setf_full_ea(smb_request_t *sr, smb_setinfo_t *si)
184 184 {
185 185 return (NT_STATUS_EAS_NOT_SUPPORTED);
186 186 }
187 187
188 188 /*
189 189 * FileModeInformation [MS-FSCC 2.4.24]
190 190 * FILE_WRITE_THROUGH
191 191 * FILE_SEQUENTIAL_ONLY
192 192 * FILE_NO_INTERMEDIATE_BUFFERING
193 193 * etc.
194 194 */
195 195 static uint32_t
196 196 smb2_setf_mode(smb_request_t *sr, smb_setinfo_t *si)
197 197 {
198 198 _NOTE(ARGUNUSED(sr))
199 199 uint32_t Mode;
200 200
201 201 if (smb_mbc_decodef(&si->si_data, "l", &Mode) != 0)
202 202 return (NT_STATUS_INVALID_PARAMETER);
203 203
204 204 #if 0 /* XXX - todo */
205 205 if (Mode & FILE_WRITE_THROUGH) {
206 206 /* store this in the ofile */
207 207 }
208 208 #endif
209 209
210 210 return (NT_STATUS_SUCCESS);
211 211 }
212 212
213 213
214 214
215 215 /*
216 216 * FilePipeInformation
217 217 */
218 218 static uint32_t
219 219 smb2_setf_pipe(smb_request_t *sr, smb_setinfo_t *si)
220 220 {
221 221 _NOTE(ARGUNUSED(si))
222 222 smb_ofile_t *of = sr->fid_ofile;
223 223 uint32_t ReadMode;
224 224 uint32_t CompletionMode;
225 225 uint32_t status;
226 226
227 227 if (smb_mbc_decodef(&si->si_data, "ll",
228 228 &ReadMode, &CompletionMode) != 0)
229 229 return (NT_STATUS_INFO_LENGTH_MISMATCH);
230 230
231 231 switch (of->f_ftype) {
232 232 case SMB_FTYPE_BYTE_PIPE:
233 233 case SMB_FTYPE_MESG_PIPE:
234 234 /*
235 235 * XXX: Do we need to actually do anything with
236 236 * ReadMode or CompletionMode? If so, (later)
237 237 * store these in the opipe object.
238 238 *
239 239 * See also: smb2_sif_pipe()
240 240 */
241 241 status = 0;
242 242 break;
243 243 case SMB_FTYPE_DISK:
244 244 case SMB_FTYPE_PRINTER:
245 245 default:
246 246 status = NT_STATUS_INVALID_PARAMETER;
247 247 }
248 248
249 249 return (status);
250 250 }
251 251
252 252 /*
253 253 * FileValidDataLengthInformation
254 254 */
255 255 /* ARGSUSED */
|
↓ open down ↓ |
232 lines elided |
↑ open up ↑ |
256 256 static uint32_t
257 257 smb2_setf_valid_len(smb_request_t *sr, smb_setinfo_t *si)
258 258 {
259 259 smb_ofile_t *of = sr->fid_ofile;
260 260 uint64_t eod;
261 261 int rc;
262 262
263 263 if (smb_mbc_decodef(&si->si_data, "q", &eod) != 0)
264 264 return (NT_STATUS_INFO_LENGTH_MISMATCH);
265 265
266 - rc = smb_fsop_set_data_length(sr, of->f_cr, of->f_node, eod);
266 + /*
267 + * Zero out data from EoD to end of file.
268 + * (Passing len=0 covers to end of file)
269 + */
270 + rc = smb_fsop_freesp(sr, of->f_cr, of, eod, 0);
267 271 if (rc != 0)
268 272 return (smb_errno2status(rc));
269 273
270 274 return (0);
271 275 }
272 276
273 277 /*
274 278 * FileShortNameInformation
275 279 * We can (optionally) support supply short names,
276 280 * but you can't change them.
277 281 */
278 282 static uint32_t
279 283 smb2_setf_shortname(smb_request_t *sr, smb_setinfo_t *si)
280 284 {
281 285 _NOTE(ARGUNUSED(si))
282 286 smb_ofile_t *of = sr->fid_ofile;
283 287
284 288 if (of->f_ftype != SMB_FTYPE_DISK)
285 289 return (NT_STATUS_INVALID_PARAMETER);
286 290 if ((of->f_tree->t_flags & SMB_TREE_SHORTNAMES) == 0)
287 291 return (NT_STATUS_SHORT_NAMES_NOT_ENABLED_ON_VOLUME);
288 292
289 293 return (NT_STATUS_ACCESS_DENIED);
290 294 }
|
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX