Blame view
fs/cifs/smb2inode.c
20.5 KB
be4cb9e3d CIFS: Query SMB2 ... |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
/* * fs/cifs/smb2inode.c * * Copyright (C) International Business Machines Corp., 2002, 2011 * Etersoft, 2012 * Author(s): Pavel Shilovsky (pshilovsky@samba.org), * Steve French (sfrench@us.ibm.com) * * This library is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation; either version 2.1 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See * the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <linux/fs.h> #include <linux/stat.h> #include <linux/slab.h> #include <linux/pagemap.h> #include <asm/div64.h> #include "cifsfs.h" #include "cifspdu.h" #include "cifsglob.h" #include "cifsproto.h" #include "cifs_debug.h" #include "cifs_fs_sb.h" #include "cifs_unicode.h" #include "fscache.h" #include "smb2glob.h" #include "smb2pdu.h" #include "smb2proto.h" |
8191576a1 smb3: Add dynamic... |
39 40 41 42 43 44 45 46 |
static void free_set_inf_compound(struct smb_rqst *rqst) { if (rqst[1].rq_iov) SMB2_set_info_free(&rqst[1]); if (rqst[2].rq_iov) SMB2_close_free(&rqst[2]); } |
a7d5c2946 cifs: reduce stac... |
47 48 49 50 51 52 53 54 55 56 57 |
struct cop_vars { struct cifs_open_parms oparms; struct kvec rsp_iov[3]; struct smb_rqst rqst[3]; struct kvec open_iov[SMB2_CREATE_IOV_SIZE]; struct kvec qi_iov[1]; struct kvec si_iov[SMB2_SET_INFO_IOV_SIZE]; struct kvec close_iov[1]; struct smb2_file_rename_info rename_info; struct smb2_file_link_info link_info; }; |
be4cb9e3d CIFS: Query SMB2 ... |
58 |
static int |
c5a5f38f0 cifs: add a smb2_... |
59 60 61 |
smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_sb_info *cifs_sb, const char *full_path, __u32 desired_access, __u32 create_disposition, |
c3ca78e21 smb3: pass mode b... |
62 |
__u32 create_options, umode_t mode, void *ptr, int command, |
8de9e86c6 cifs: create a he... |
63 |
struct cifsFileInfo *cfile) |
c5a5f38f0 cifs: add a smb2_... |
64 |
{ |
a7d5c2946 cifs: reduce stac... |
65 66 67 |
struct cop_vars *vars = NULL; struct kvec *rsp_iov; struct smb_rqst *rqst; |
c5a5f38f0 cifs: add a smb2_... |
68 69 70 |
int rc; __le16 *utf16_path = NULL; __u8 oplock = SMB2_OPLOCK_LEVEL_NONE; |
c5a5f38f0 cifs: add a smb2_... |
71 72 |
struct cifs_fid fid; struct cifs_ses *ses = tcon->ses; |
352d96f3a cifs: multichanne... |
73 |
struct TCP_Server_Info *server; |
c5a5f38f0 cifs: add a smb2_... |
74 |
int num_rqst = 0; |
c5a5f38f0 cifs: add a smb2_... |
75 |
int resp_buftype[3]; |
c2e0fe3f5 cifs: make rmdir(... |
76 |
struct smb2_query_info_rsp *qi_rsp = NULL; |
c5a5f38f0 cifs: add a smb2_... |
77 |
int flags = 0; |
c2e0fe3f5 cifs: make rmdir(... |
78 |
__u8 delete_pending[8] = {1, 0, 0, 0, 0, 0, 0, 0}; |
bb435512c cifs: change SMB2... |
79 80 |
unsigned int size[2]; void *data[2]; |
bb435512c cifs: change SMB2... |
81 |
int len; |
c5a5f38f0 cifs: add a smb2_... |
82 |
|
a7d5c2946 cifs: reduce stac... |
83 84 85 86 87 |
vars = kzalloc(sizeof(*vars), GFP_ATOMIC); if (vars == NULL) return -ENOMEM; rqst = &vars->rqst[0]; rsp_iov = &vars->rsp_iov[0]; |
352d96f3a cifs: multichanne... |
88 |
server = cifs_pick_channel(ses); |
c5a5f38f0 cifs: add a smb2_... |
89 90 |
if (smb3_encryption_required(tcon)) flags |= CIFS_TRANSFORM_REQ; |
c5a5f38f0 cifs: add a smb2_... |
91 |
resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER; |
c5a5f38f0 cifs: add a smb2_... |
92 |
|
8de9e86c6 cifs: create a he... |
93 94 95 |
/* We already have a handle so we can skip the open */ if (cfile) goto after_open; |
c5a5f38f0 cifs: add a smb2_... |
96 97 |
/* Open */ utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb); |
8de9e86c6 cifs: create a he... |
98 99 100 101 |
if (!utf16_path) { rc = -ENOMEM; goto finished; } |
c5a5f38f0 cifs: add a smb2_... |
102 |
|
a7d5c2946 cifs: reduce stac... |
103 104 105 106 107 108 109 |
vars->oparms.tcon = tcon; vars->oparms.desired_access = desired_access; vars->oparms.disposition = create_disposition; vars->oparms.create_options = cifs_create_options(cifs_sb, create_options); vars->oparms.fid = &fid; vars->oparms.reconnect = false; vars->oparms.mode = mode; |
c8c412f97 SMB3: Fix mkdir w... |
110 |
vars->oparms.cifs_sb = cifs_sb; |
a7d5c2946 cifs: reduce stac... |
111 112 |
rqst[num_rqst].rq_iov = &vars->open_iov[0]; |
c5a5f38f0 cifs: add a smb2_... |
113 |
rqst[num_rqst].rq_nvec = SMB2_CREATE_IOV_SIZE; |
352d96f3a cifs: multichanne... |
114 115 |
rc = SMB2_open_init(tcon, server, &rqst[num_rqst], &oplock, &vars->oparms, |
c5a5f38f0 cifs: add a smb2_... |
116 117 118 119 |
utf16_path); kfree(utf16_path); if (rc) goto finished; |
8de9e86c6 cifs: create a he... |
120 121 122 123 |
smb2_set_next_command(tcon, &rqst[num_rqst]); after_open: num_rqst++; rc = 0; |
c5a5f38f0 cifs: add a smb2_... |
124 125 126 127 |
/* Operation */ switch (command) { case SMB2_OP_QUERY_INFO: |
a7d5c2946 cifs: reduce stac... |
128 |
rqst[num_rqst].rq_iov = &vars->qi_iov[0]; |
c5a5f38f0 cifs: add a smb2_... |
129 |
rqst[num_rqst].rq_nvec = 1; |
496902dc1 cifs: add a helpe... |
130 |
if (cfile) |
352d96f3a cifs: multichanne... |
131 132 |
rc = SMB2_query_info_init(tcon, server, &rqst[num_rqst], |
496902dc1 cifs: add a helpe... |
133 134 135 |
cfile->fid.persistent_fid, cfile->fid.volatile_fid, FILE_ALL_INFORMATION, |
c5a5f38f0 cifs: add a smb2_... |
136 137 |
SMB2_O_INFO_FILE, 0, sizeof(struct smb2_file_all_info) + |
f5b05d622 cifs: add IOCTL f... |
138 |
PATH_MAX * 2, 0, NULL); |
496902dc1 cifs: add a helpe... |
139 |
else { |
352d96f3a cifs: multichanne... |
140 141 |
rc = SMB2_query_info_init(tcon, server, &rqst[num_rqst], |
496902dc1 cifs: add a helpe... |
142 143 |
COMPOUND_FID, COMPOUND_FID, |
352d96f3a cifs: multichanne... |
144 |
FILE_ALL_INFORMATION, |
496902dc1 cifs: add a helpe... |
145 146 147 148 149 150 151 152 |
SMB2_O_INFO_FILE, 0, sizeof(struct smb2_file_all_info) + PATH_MAX * 2, 0, NULL); if (!rc) { smb2_set_next_command(tcon, &rqst[num_rqst]); smb2_set_related(&rqst[num_rqst]); } } |
88a92c913 cifs: fix crash i... |
153 154 |
if (rc) goto finished; |
496902dc1 cifs: add a helpe... |
155 |
num_rqst++; |
8191576a1 smb3: Add dynamic... |
156 157 |
trace_smb3_query_info_compound_enter(xid, ses->Suid, tcon->tid, full_path); |
c5a5f38f0 cifs: add a smb2_... |
158 |
break; |
6a5f6592a SMB311: Add suppo... |
159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 |
case SMB2_OP_POSIX_QUERY_INFO: rqst[num_rqst].rq_iov = &vars->qi_iov[0]; rqst[num_rqst].rq_nvec = 1; if (cfile) rc = SMB2_query_info_init(tcon, server, &rqst[num_rqst], cfile->fid.persistent_fid, cfile->fid.volatile_fid, SMB_FIND_FILE_POSIX_INFO, SMB2_O_INFO_FILE, 0, /* TBD: fix following to allow for longer SIDs */ sizeof(struct smb311_posix_qinfo *) + (PATH_MAX * 2) + (sizeof(struct cifs_sid) * 2), 0, NULL); else { rc = SMB2_query_info_init(tcon, server, &rqst[num_rqst], COMPOUND_FID, COMPOUND_FID, SMB_FIND_FILE_POSIX_INFO, SMB2_O_INFO_FILE, 0, sizeof(struct smb311_posix_qinfo *) + (PATH_MAX * 2) + (sizeof(struct cifs_sid) * 2), 0, NULL); if (!rc) { smb2_set_next_command(tcon, &rqst[num_rqst]); smb2_set_related(&rqst[num_rqst]); } } if (rc) goto finished; num_rqst++; |
e4bd7c4a8 smb311: Add trace... |
191 |
trace_smb3_posix_query_info_compound_enter(xid, ses->Suid, tcon->tid, full_path); |
6a5f6592a SMB311: Add suppo... |
192 |
break; |
47dd9597d cifs: change unli... |
193 |
case SMB2_OP_DELETE: |
8191576a1 smb3: Add dynamic... |
194 |
trace_smb3_delete_enter(xid, ses->Suid, tcon->tid, full_path); |
47dd9597d cifs: change unli... |
195 |
break; |
f733e3936 cifs: change mkdi... |
196 197 198 199 200 |
case SMB2_OP_MKDIR: /* * Directories are created through parameters in the * SMB2_open() call. */ |
8191576a1 smb3: Add dynamic... |
201 |
trace_smb3_mkdir_enter(xid, ses->Suid, tcon->tid, full_path); |
f733e3936 cifs: change mkdi... |
202 |
break; |
c2e0fe3f5 cifs: make rmdir(... |
203 |
case SMB2_OP_RMDIR: |
a7d5c2946 cifs: reduce stac... |
204 |
rqst[num_rqst].rq_iov = &vars->si_iov[0]; |
c2e0fe3f5 cifs: make rmdir(... |
205 |
rqst[num_rqst].rq_nvec = 1; |
271b9c0c8 smb3: Fix rmdir c... |
206 |
size[0] = 1; /* sizeof __u8 See MS-FSCC section 2.4.11 */ |
c2e0fe3f5 cifs: make rmdir(... |
207 |
data[0] = &delete_pending[0]; |
352d96f3a cifs: multichanne... |
208 209 |
rc = SMB2_set_info_init(tcon, server, &rqst[num_rqst], COMPOUND_FID, |
c2e0fe3f5 cifs: make rmdir(... |
210 211 212 |
COMPOUND_FID, current->tgid, FILE_DISPOSITION_INFORMATION, SMB2_O_INFO_FILE, 0, data, size); |
88a92c913 cifs: fix crash i... |
213 214 |
if (rc) goto finished; |
e77fe73c7 cifs: we can not ... |
215 |
smb2_set_next_command(tcon, &rqst[num_rqst]); |
c2e0fe3f5 cifs: make rmdir(... |
216 |
smb2_set_related(&rqst[num_rqst++]); |
8191576a1 smb3: Add dynamic... |
217 |
trace_smb3_rmdir_enter(xid, ses->Suid, tcon->tid, full_path); |
c2e0fe3f5 cifs: make rmdir(... |
218 |
break; |
f7bfe04bf cifs: change SMB2... |
219 |
case SMB2_OP_SET_EOF: |
a7d5c2946 cifs: reduce stac... |
220 |
rqst[num_rqst].rq_iov = &vars->si_iov[0]; |
f7bfe04bf cifs: change SMB2... |
221 222 223 224 |
rqst[num_rqst].rq_nvec = 1; size[0] = 8; /* sizeof __le64 */ data[0] = ptr; |
352d96f3a cifs: multichanne... |
225 226 |
rc = SMB2_set_info_init(tcon, server, &rqst[num_rqst], COMPOUND_FID, |
f7bfe04bf cifs: change SMB2... |
227 228 229 |
COMPOUND_FID, current->tgid, FILE_END_OF_FILE_INFORMATION, SMB2_O_INFO_FILE, 0, data, size); |
88a92c913 cifs: fix crash i... |
230 231 |
if (rc) goto finished; |
e77fe73c7 cifs: we can not ... |
232 |
smb2_set_next_command(tcon, &rqst[num_rqst]); |
f7bfe04bf cifs: change SMB2... |
233 |
smb2_set_related(&rqst[num_rqst++]); |
8191576a1 smb3: Add dynamic... |
234 |
trace_smb3_set_eof_enter(xid, ses->Suid, tcon->tid, full_path); |
f7bfe04bf cifs: change SMB2... |
235 |
break; |
dcbf91035 cifs: change SMB2... |
236 |
case SMB2_OP_SET_INFO: |
a7d5c2946 cifs: reduce stac... |
237 |
rqst[num_rqst].rq_iov = &vars->si_iov[0]; |
dcbf91035 cifs: change SMB2... |
238 |
rqst[num_rqst].rq_nvec = 1; |
bb435512c cifs: change SMB2... |
239 |
|
dcbf91035 cifs: change SMB2... |
240 241 |
size[0] = sizeof(FILE_BASIC_INFO); data[0] = ptr; |
dc9300a67 cifs: use existin... |
242 |
if (cfile) |
352d96f3a cifs: multichanne... |
243 244 |
rc = SMB2_set_info_init(tcon, server, &rqst[num_rqst], |
dc9300a67 cifs: use existin... |
245 246 247 248 249 |
cfile->fid.persistent_fid, cfile->fid.volatile_fid, current->tgid, FILE_BASIC_INFORMATION, SMB2_O_INFO_FILE, 0, data, size); else { |
352d96f3a cifs: multichanne... |
250 251 |
rc = SMB2_set_info_init(tcon, server, &rqst[num_rqst], |
dc9300a67 cifs: use existin... |
252 253 254 255 256 257 258 259 260 |
COMPOUND_FID, COMPOUND_FID, current->tgid, FILE_BASIC_INFORMATION, SMB2_O_INFO_FILE, 0, data, size); if (!rc) { smb2_set_next_command(tcon, &rqst[num_rqst]); smb2_set_related(&rqst[num_rqst]); } } |
88a92c913 cifs: fix crash i... |
261 262 |
if (rc) goto finished; |
dc9300a67 cifs: use existin... |
263 |
num_rqst++; |
8191576a1 smb3: Add dynamic... |
264 265 |
trace_smb3_set_info_compound_enter(xid, ses->Suid, tcon->tid, full_path); |
dcbf91035 cifs: change SMB2... |
266 |
break; |
bb435512c cifs: change SMB2... |
267 |
case SMB2_OP_RENAME: |
a7d5c2946 cifs: reduce stac... |
268 |
rqst[num_rqst].rq_iov = &vars->si_iov[0]; |
bb435512c cifs: change SMB2... |
269 270 271 |
rqst[num_rqst].rq_nvec = 2; len = (2 * UniStrnlen((wchar_t *)ptr, PATH_MAX)); |
a7d5c2946 cifs: reduce stac... |
272 273 274 |
vars->rename_info.ReplaceIfExists = 1; vars->rename_info.RootDirectory = 0; vars->rename_info.FileNameLength = cpu_to_le32(len); |
bb435512c cifs: change SMB2... |
275 276 |
size[0] = sizeof(struct smb2_file_rename_info); |
a7d5c2946 cifs: reduce stac... |
277 |
data[0] = &vars->rename_info; |
bb435512c cifs: change SMB2... |
278 279 280 |
size[1] = len + 2 /* null */; data[1] = (__le16 *)ptr; |
8de9e86c6 cifs: create a he... |
281 |
if (cfile) |
352d96f3a cifs: multichanne... |
282 283 |
rc = SMB2_set_info_init(tcon, server, &rqst[num_rqst], |
8de9e86c6 cifs: create a he... |
284 285 286 287 288 |
cfile->fid.persistent_fid, cfile->fid.volatile_fid, current->tgid, FILE_RENAME_INFORMATION, SMB2_O_INFO_FILE, 0, data, size); else { |
352d96f3a cifs: multichanne... |
289 290 |
rc = SMB2_set_info_init(tcon, server, &rqst[num_rqst], |
8de9e86c6 cifs: create a he... |
291 292 |
COMPOUND_FID, COMPOUND_FID, current->tgid, FILE_RENAME_INFORMATION, |
bb435512c cifs: change SMB2... |
293 |
SMB2_O_INFO_FILE, 0, data, size); |
dc9300a67 cifs: use existin... |
294 295 296 297 |
if (!rc) { smb2_set_next_command(tcon, &rqst[num_rqst]); smb2_set_related(&rqst[num_rqst]); } |
8de9e86c6 cifs: create a he... |
298 |
} |
88a92c913 cifs: fix crash i... |
299 300 |
if (rc) goto finished; |
8de9e86c6 cifs: create a he... |
301 |
num_rqst++; |
8191576a1 smb3: Add dynamic... |
302 |
trace_smb3_rename_enter(xid, ses->Suid, tcon->tid, full_path); |
bb435512c cifs: change SMB2... |
303 304 |
break; case SMB2_OP_HARDLINK: |
a7d5c2946 cifs: reduce stac... |
305 |
rqst[num_rqst].rq_iov = &vars->si_iov[0]; |
bb435512c cifs: change SMB2... |
306 307 308 |
rqst[num_rqst].rq_nvec = 2; len = (2 * UniStrnlen((wchar_t *)ptr, PATH_MAX)); |
a7d5c2946 cifs: reduce stac... |
309 310 311 |
vars->link_info.ReplaceIfExists = 0; vars->link_info.RootDirectory = 0; vars->link_info.FileNameLength = cpu_to_le32(len); |
bb435512c cifs: change SMB2... |
312 313 |
size[0] = sizeof(struct smb2_file_link_info); |
a7d5c2946 cifs: reduce stac... |
314 |
data[0] = &vars->link_info; |
bb435512c cifs: change SMB2... |
315 316 317 |
size[1] = len + 2 /* null */; data[1] = (__le16 *)ptr; |
352d96f3a cifs: multichanne... |
318 319 |
rc = SMB2_set_info_init(tcon, server, &rqst[num_rqst], COMPOUND_FID, |
bb435512c cifs: change SMB2... |
320 321 322 |
COMPOUND_FID, current->tgid, FILE_LINK_INFORMATION, SMB2_O_INFO_FILE, 0, data, size); |
88a92c913 cifs: fix crash i... |
323 324 |
if (rc) goto finished; |
e77fe73c7 cifs: we can not ... |
325 |
smb2_set_next_command(tcon, &rqst[num_rqst]); |
bb435512c cifs: change SMB2... |
326 |
smb2_set_related(&rqst[num_rqst++]); |
8191576a1 smb3: Add dynamic... |
327 |
trace_smb3_hardlink_enter(xid, ses->Suid, tcon->tid, full_path); |
bb435512c cifs: change SMB2... |
328 |
break; |
c5a5f38f0 cifs: add a smb2_... |
329 330 331 332 333 334 335 |
default: cifs_dbg(VFS, "Invalid command "); rc = -EINVAL; } if (rc) goto finished; |
8de9e86c6 cifs: create a he... |
336 337 338 |
/* We already have a handle so we can skip the close */ if (cfile) goto after_close; |
c5a5f38f0 cifs: add a smb2_... |
339 |
/* Close */ |
a7d5c2946 cifs: reduce stac... |
340 |
rqst[num_rqst].rq_iov = &vars->close_iov[0]; |
c5a5f38f0 cifs: add a smb2_... |
341 |
rqst[num_rqst].rq_nvec = 1; |
352d96f3a cifs: multichanne... |
342 343 |
rc = SMB2_close_init(tcon, server, &rqst[num_rqst], COMPOUND_FID, |
43f8a6a74 smb3: query attri... |
344 |
COMPOUND_FID, false); |
8de9e86c6 cifs: create a he... |
345 |
smb2_set_related(&rqst[num_rqst]); |
c5a5f38f0 cifs: add a smb2_... |
346 347 |
if (rc) goto finished; |
8de9e86c6 cifs: create a he... |
348 349 350 351 352 353 |
after_close: num_rqst++; if (cfile) { cifsFileInfo_put(cfile); cfile = NULL; |
352d96f3a cifs: multichanne... |
354 355 |
rc = compound_send_recv(xid, ses, server, flags, num_rqst - 2, |
8de9e86c6 cifs: create a he... |
356 357 358 |
&rqst[1], &resp_buftype[1], &rsp_iov[1]); } else |
352d96f3a cifs: multichanne... |
359 360 |
rc = compound_send_recv(xid, ses, server, flags, num_rqst, |
8de9e86c6 cifs: create a he... |
361 362 |
rqst, resp_buftype, rsp_iov); |
c5a5f38f0 cifs: add a smb2_... |
363 364 |
finished: |
8de9e86c6 cifs: create a he... |
365 366 |
if (cfile) cifsFileInfo_put(cfile); |
c5a5f38f0 cifs: add a smb2_... |
367 |
SMB2_open_free(&rqst[0]); |
7dcc82c2d smb3: improve han... |
368 |
if (rc == -EREMCHG) { |
a0a3036b8 cifs: Standardize... |
369 370 |
pr_warn_once("server share %s deleted ", tcon->treeName); |
7dcc82c2d smb3: improve han... |
371 372 |
tcon->need_reconnect = true; } |
c5a5f38f0 cifs: add a smb2_... |
373 374 375 |
switch (command) { case SMB2_OP_QUERY_INFO: if (rc == 0) { |
c2e0fe3f5 cifs: make rmdir(... |
376 377 |
qi_rsp = (struct smb2_query_info_rsp *) rsp_iov[1].iov_base; |
c5a5f38f0 cifs: add a smb2_... |
378 |
rc = smb2_validate_and_copy_iov( |
c2e0fe3f5 cifs: make rmdir(... |
379 380 |
le16_to_cpu(qi_rsp->OutputBufferOffset), le32_to_cpu(qi_rsp->OutputBufferLength), |
c5a5f38f0 cifs: add a smb2_... |
381 |
&rsp_iov[1], sizeof(struct smb2_file_all_info), |
c2e0fe3f5 cifs: make rmdir(... |
382 |
ptr); |
c5a5f38f0 cifs: add a smb2_... |
383 384 385 386 387 |
} if (rqst[1].rq_iov) SMB2_query_info_free(&rqst[1]); if (rqst[2].rq_iov) SMB2_close_free(&rqst[2]); |
8191576a1 smb3: Add dynamic... |
388 389 390 391 392 393 |
if (rc) trace_smb3_query_info_compound_err(xid, ses->Suid, tcon->tid, rc); else trace_smb3_query_info_compound_done(xid, ses->Suid, tcon->tid); |
c5a5f38f0 cifs: add a smb2_... |
394 |
break; |
6a5f6592a SMB311: Add suppo... |
395 396 397 398 399 400 401 402 403 404 405 406 407 408 |
case SMB2_OP_POSIX_QUERY_INFO: if (rc == 0) { qi_rsp = (struct smb2_query_info_rsp *) rsp_iov[1].iov_base; rc = smb2_validate_and_copy_iov( le16_to_cpu(qi_rsp->OutputBufferOffset), le32_to_cpu(qi_rsp->OutputBufferLength), &rsp_iov[1], sizeof(struct smb311_posix_qinfo) /* add SIDs */, ptr); } if (rqst[1].rq_iov) SMB2_query_info_free(&rqst[1]); if (rqst[2].rq_iov) SMB2_close_free(&rqst[2]); if (rc) |
e4bd7c4a8 smb311: Add trace... |
409 |
trace_smb3_posix_query_info_compound_err(xid, ses->Suid, tcon->tid, rc); |
6a5f6592a SMB311: Add suppo... |
410 |
else |
e4bd7c4a8 smb311: Add trace... |
411 |
trace_smb3_posix_query_info_compound_done(xid, ses->Suid, tcon->tid); |
6a5f6592a SMB311: Add suppo... |
412 |
break; |
47dd9597d cifs: change unli... |
413 |
case SMB2_OP_DELETE: |
8191576a1 smb3: Add dynamic... |
414 415 416 417 418 419 420 |
if (rc) trace_smb3_delete_err(xid, ses->Suid, tcon->tid, rc); else trace_smb3_delete_done(xid, ses->Suid, tcon->tid); if (rqst[1].rq_iov) SMB2_close_free(&rqst[1]); break; |
f733e3936 cifs: change mkdi... |
421 |
case SMB2_OP_MKDIR: |
8191576a1 smb3: Add dynamic... |
422 423 424 425 |
if (rc) trace_smb3_mkdir_err(xid, ses->Suid, tcon->tid, rc); else trace_smb3_mkdir_done(xid, ses->Suid, tcon->tid); |
f733e3936 cifs: change mkdi... |
426 427 428 |
if (rqst[1].rq_iov) SMB2_close_free(&rqst[1]); break; |
bb435512c cifs: change SMB2... |
429 |
case SMB2_OP_HARDLINK: |
8191576a1 smb3: Add dynamic... |
430 431 432 433 434 435 |
if (rc) trace_smb3_hardlink_err(xid, ses->Suid, tcon->tid, rc); else trace_smb3_hardlink_done(xid, ses->Suid, tcon->tid); free_set_inf_compound(rqst); break; |
bb435512c cifs: change SMB2... |
436 |
case SMB2_OP_RENAME: |
8191576a1 smb3: Add dynamic... |
437 438 439 440 441 442 |
if (rc) trace_smb3_rename_err(xid, ses->Suid, tcon->tid, rc); else trace_smb3_rename_done(xid, ses->Suid, tcon->tid); free_set_inf_compound(rqst); break; |
c2e0fe3f5 cifs: make rmdir(... |
443 |
case SMB2_OP_RMDIR: |
8191576a1 smb3: Add dynamic... |
444 445 446 447 448 449 |
if (rc) trace_smb3_rmdir_err(xid, ses->Suid, tcon->tid, rc); else trace_smb3_rmdir_done(xid, ses->Suid, tcon->tid); free_set_inf_compound(rqst); break; |
dcbf91035 cifs: change SMB2... |
450 |
case SMB2_OP_SET_EOF: |
8191576a1 smb3: Add dynamic... |
451 452 453 454 455 456 |
if (rc) trace_smb3_set_eof_err(xid, ses->Suid, tcon->tid, rc); else trace_smb3_set_eof_done(xid, ses->Suid, tcon->tid); free_set_inf_compound(rqst); break; |
dcbf91035 cifs: change SMB2... |
457 |
case SMB2_OP_SET_INFO: |
8191576a1 smb3: Add dynamic... |
458 459 460 461 462 463 464 |
if (rc) trace_smb3_set_info_compound_err(xid, ses->Suid, tcon->tid, rc); else trace_smb3_set_info_compound_done(xid, ses->Suid, tcon->tid); free_set_inf_compound(rqst); |
c2e0fe3f5 cifs: make rmdir(... |
465 |
break; |
c5a5f38f0 cifs: add a smb2_... |
466 467 468 469 |
} free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base); free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base); free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base); |
a7d5c2946 cifs: reduce stac... |
470 |
kfree(vars); |
c5a5f38f0 cifs: add a smb2_... |
471 472 |
return rc; } |
f0df737ee CIFS: Add open/cl... |
473 |
void |
be4cb9e3d CIFS: Query SMB2 ... |
474 475 476 477 478 479 480 481 482 483 484 485 |
move_smb2_info_to_cifs(FILE_ALL_INFO *dst, struct smb2_file_all_info *src) { memcpy(dst, src, (size_t)(&src->CurrentByteOffset) - (size_t)src); dst->CurrentByteOffset = src->CurrentByteOffset; dst->Mode = src->Mode; dst->AlignmentRequirement = src->AlignmentRequirement; dst->IndexNumber1 = 0; /* we don't use it */ } int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_sb_info *cifs_sb, const char *full_path, |
2e4564b31 smb3: add support... |
486 |
FILE_ALL_INFO *data, bool *adjust_tz, bool *reparse) |
be4cb9e3d CIFS: Query SMB2 ... |
487 488 489 |
{ int rc; struct smb2_file_all_info *smb2_data; |
61351d6d5 smb3: send backup... |
490 |
__u32 create_options = 0; |
6a9cbdd1c CIFS: Fix mounts ... |
491 |
bool no_cached_open = tcon->nohandlecache; |
496902dc1 cifs: add a helpe... |
492 |
struct cifsFileInfo *cfile; |
9e81e8ff7 cifs: return cach... |
493 |
struct cached_fid *cfid = NULL; |
be4cb9e3d CIFS: Query SMB2 ... |
494 495 |
*adjust_tz = false; |
2e4564b31 smb3: add support... |
496 |
*reparse = false; |
be4cb9e3d CIFS: Query SMB2 ... |
497 |
|
1bbe4997b CIFS: Fix wrong f... |
498 |
smb2_data = kzalloc(sizeof(struct smb2_file_all_info) + PATH_MAX * 2, |
be4cb9e3d CIFS: Query SMB2 ... |
499 500 501 |
GFP_KERNEL); if (smb2_data == NULL) return -ENOMEM; |
6a9cbdd1c CIFS: Fix mounts ... |
502 503 504 |
/* If it is a root and its handle is cached then use it */ if (!strlen(full_path) && !no_cached_open) { |
9e81e8ff7 cifs: return cach... |
505 |
rc = open_shroot(xid, tcon, cifs_sb, &cfid); |
6a9cbdd1c CIFS: Fix mounts ... |
506 507 |
if (rc) goto out; |
b0f6df737 cifs: cache FILE_... |
508 509 510 511 512 |
if (tcon->crfid.file_all_info_is_valid) { move_smb2_info_to_cifs(data, &tcon->crfid.file_all_info); } else { |
9e81e8ff7 cifs: return cach... |
513 514 515 |
rc = SMB2_query_info(xid, tcon, cfid->fid->persistent_fid, cfid->fid->volatile_fid, smb2_data); |
b0f6df737 cifs: cache FILE_... |
516 517 518 |
if (!rc) move_smb2_info_to_cifs(data, smb2_data); } |
9e81e8ff7 cifs: return cach... |
519 |
close_shroot(cfid); |
6a9cbdd1c CIFS: Fix mounts ... |
520 521 |
goto out; } |
496902dc1 cifs: add a helpe... |
522 |
cifs_get_readable_path(tcon, full_path, &cfile); |
c5a5f38f0 cifs: add a smb2_... |
523 |
rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, |
61351d6d5 smb3: send backup... |
524 |
FILE_READ_ATTRIBUTES, FILE_OPEN, create_options, |
c3ca78e21 smb3: pass mode b... |
525 |
ACL_NO_MODE, smb2_data, SMB2_OP_QUERY_INFO, cfile); |
eb85d94bd CIFS: Fix symboli... |
526 |
if (rc == -EOPNOTSUPP) { |
2e4564b31 smb3: add support... |
527 |
*reparse = true; |
61351d6d5 smb3: send backup... |
528 |
create_options |= OPEN_REPARSE_POINT; |
eb85d94bd CIFS: Fix symboli... |
529 |
/* Failed on a symbolic link - query a reparse point info */ |
c5a5f38f0 cifs: add a smb2_... |
530 531 |
rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES, FILE_OPEN, |
c3ca78e21 smb3: pass mode b... |
532 533 |
create_options, ACL_NO_MODE, smb2_data, SMB2_OP_QUERY_INFO, NULL); |
eb85d94bd CIFS: Fix symboli... |
534 |
} |
be4cb9e3d CIFS: Query SMB2 ... |
535 536 537 538 539 540 541 542 |
if (rc) goto out; move_smb2_info_to_cifs(data, smb2_data); out: kfree(smb2_data); return rc; } |
a0e731839 CIFS: Add SMB2 su... |
543 |
|
6a5f6592a SMB311: Add suppo... |
544 545 546 547 |
int smb311_posix_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, struct cifs_sb_info *cifs_sb, const char *full_path, |
2e4564b31 smb3: add support... |
548 |
struct smb311_posix_qinfo *data, bool *adjust_tz, bool *reparse) |
6a5f6592a SMB311: Add suppo... |
549 550 551 552 553 554 555 |
{ int rc; __u32 create_options = 0; struct cifsFileInfo *cfile; struct smb311_posix_qinfo *smb2_data; *adjust_tz = false; |
2e4564b31 smb3: add support... |
556 |
*reparse = false; |
6a5f6592a SMB311: Add suppo... |
557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 |
/* BB TODO: Make struct larger when add support for parsing owner SIDs */ smb2_data = kzalloc(sizeof(struct smb311_posix_qinfo), GFP_KERNEL); if (smb2_data == NULL) return -ENOMEM; /* * BB TODO: Add support for using the cached root handle. * Create SMB2_query_posix_info worker function to do non-compounded query * when we already have an open file handle for this. For now this is fast enough * (always using the compounded version). */ cifs_get_readable_path(tcon, full_path, &cfile); rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES, FILE_OPEN, create_options, ACL_NO_MODE, smb2_data, SMB2_OP_POSIX_QUERY_INFO, cfile); if (rc == -EOPNOTSUPP) { /* BB TODO: When support for special files added to Samba re-verify this path */ |
2e4564b31 smb3: add support... |
577 |
*reparse = true; |
6a5f6592a SMB311: Add suppo... |
578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 |
create_options |= OPEN_REPARSE_POINT; /* Failed on a symbolic link - query a reparse point info */ rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, FILE_READ_ATTRIBUTES, FILE_OPEN, create_options, ACL_NO_MODE, smb2_data, SMB2_OP_POSIX_QUERY_INFO, NULL); } if (rc) goto out; /* TODO: will need to allow for the 2 SIDs when add support for getting owner UID/GID */ memcpy(data, smb2_data, sizeof(struct smb311_posix_qinfo)); out: kfree(smb2_data); return rc; } |
a0e731839 CIFS: Add SMB2 su... |
596 |
int |
c3ca78e21 smb3: pass mode b... |
597 598 |
smb2_mkdir(const unsigned int xid, struct inode *parent_inode, umode_t mode, struct cifs_tcon *tcon, const char *name, |
a0e731839 CIFS: Add SMB2 su... |
599 600 |
struct cifs_sb_info *cifs_sb) { |
f733e3936 cifs: change mkdi... |
601 602 |
return smb2_compound_op(xid, tcon, cifs_sb, name, FILE_WRITE_ATTRIBUTES, FILE_CREATE, |
c3ca78e21 smb3: pass mode b... |
603 604 |
CREATE_NOT_FILE, mode, NULL, SMB2_OP_MKDIR, NULL); |
a0e731839 CIFS: Add SMB2 su... |
605 606 607 608 609 610 611 612 613 |
} void smb2_mkdir_setinfo(struct inode *inode, const char *name, struct cifs_sb_info *cifs_sb, struct cifs_tcon *tcon, const unsigned int xid) { FILE_BASIC_INFO data; struct cifsInodeInfo *cifs_i; |
dc9300a67 cifs: use existin... |
614 |
struct cifsFileInfo *cfile; |
a0e731839 CIFS: Add SMB2 su... |
615 616 617 618 619 620 621 |
u32 dosattrs; int tmprc; memset(&data, 0, sizeof(data)); cifs_i = CIFS_I(inode); dosattrs = cifs_i->cifsAttrs | ATTR_READONLY; data.Attributes = cpu_to_le32(dosattrs); |
86f740f2a cifs: fix rename(... |
622 |
cifs_get_writable_path(tcon, name, FIND_WR_ANY, &cfile); |
dcbf91035 cifs: change SMB2... |
623 624 |
tmprc = smb2_compound_op(xid, tcon, cifs_sb, name, FILE_WRITE_ATTRIBUTES, FILE_CREATE, |
c3ca78e21 smb3: pass mode b... |
625 626 |
CREATE_NOT_FILE, ACL_NO_MODE, &data, SMB2_OP_SET_INFO, cfile); |
a0e731839 CIFS: Add SMB2 su... |
627 628 629 |
if (tmprc == 0) cifs_i->cifsAttrs = dosattrs; } |
1a500f010 CIFS: Add SMB2 su... |
630 631 632 633 634 |
int smb2_rmdir(const unsigned int xid, struct cifs_tcon *tcon, const char *name, struct cifs_sb_info *cifs_sb) { |
c2e0fe3f5 cifs: make rmdir(... |
635 |
return smb2_compound_op(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN, |
c3ca78e21 smb3: pass mode b... |
636 |
CREATE_NOT_FILE, ACL_NO_MODE, |
8de9e86c6 cifs: create a he... |
637 |
NULL, SMB2_OP_RMDIR, NULL); |
1a500f010 CIFS: Add SMB2 su... |
638 |
} |
cbe6f439f CIFS: Add SMB2 su... |
639 640 641 642 643 |
int smb2_unlink(const unsigned int xid, struct cifs_tcon *tcon, const char *name, struct cifs_sb_info *cifs_sb) { |
47dd9597d cifs: change unli... |
644 645 |
return smb2_compound_op(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN, CREATE_DELETE_ON_CLOSE | OPEN_REPARSE_POINT, |
c3ca78e21 smb3: pass mode b... |
646 |
ACL_NO_MODE, NULL, SMB2_OP_DELETE, NULL); |
cbe6f439f CIFS: Add SMB2 su... |
647 |
} |
35143eb5c CIFS: Add SMB2 su... |
648 |
|
568798cc6 CIFS: Add SMB2 su... |
649 650 651 |
static int smb2_set_path_attr(const unsigned int xid, struct cifs_tcon *tcon, const char *from_name, const char *to_name, |
8de9e86c6 cifs: create a he... |
652 653 |
struct cifs_sb_info *cifs_sb, __u32 access, int command, struct cifsFileInfo *cfile) |
35143eb5c CIFS: Add SMB2 su... |
654 655 656 657 658 659 660 661 662 |
{ __le16 *smb2_to_name = NULL; int rc; smb2_to_name = cifs_convert_path_to_utf16(to_name, cifs_sb); if (smb2_to_name == NULL) { rc = -ENOMEM; goto smb2_rename_path; } |
bb435512c cifs: change SMB2... |
663 |
rc = smb2_compound_op(xid, tcon, cifs_sb, from_name, access, |
c3ca78e21 smb3: pass mode b... |
664 665 |
FILE_OPEN, 0, ACL_NO_MODE, smb2_to_name, command, cfile); |
35143eb5c CIFS: Add SMB2 su... |
666 667 668 669 |
smb2_rename_path: kfree(smb2_to_name); return rc; } |
568798cc6 CIFS: Add SMB2 su... |
670 671 672 673 674 675 |
int smb2_rename_path(const unsigned int xid, struct cifs_tcon *tcon, const char *from_name, const char *to_name, struct cifs_sb_info *cifs_sb) { |
8de9e86c6 cifs: create a he... |
676 |
struct cifsFileInfo *cfile; |
86f740f2a cifs: fix rename(... |
677 |
cifs_get_writable_path(tcon, from_name, FIND_WR_WITH_DELETE, &cfile); |
8de9e86c6 cifs: create a he... |
678 679 680 |
return smb2_set_path_attr(xid, tcon, from_name, to_name, cifs_sb, DELETE, SMB2_OP_RENAME, cfile); |
568798cc6 CIFS: Add SMB2 su... |
681 682 683 684 685 686 687 688 |
} int smb2_create_hardlink(const unsigned int xid, struct cifs_tcon *tcon, const char *from_name, const char *to_name, struct cifs_sb_info *cifs_sb) { return smb2_set_path_attr(xid, tcon, from_name, to_name, cifs_sb, |
8de9e86c6 cifs: create a he... |
689 690 |
FILE_READ_ATTRIBUTES, SMB2_OP_HARDLINK, NULL); |
568798cc6 CIFS: Add SMB2 su... |
691 |
} |
c839ff244 CIFS: Add SMB2 su... |
692 693 694 695 696 697 698 |
int smb2_set_path_size(const unsigned int xid, struct cifs_tcon *tcon, const char *full_path, __u64 size, struct cifs_sb_info *cifs_sb, bool set_alloc) { __le64 eof = cpu_to_le64(size); |
f7bfe04bf cifs: change SMB2... |
699 700 |
return smb2_compound_op(xid, tcon, cifs_sb, full_path, |
c3ca78e21 smb3: pass mode b... |
701 702 |
FILE_WRITE_DATA, FILE_OPEN, 0, ACL_NO_MODE, &eof, SMB2_OP_SET_EOF, NULL); |
c839ff244 CIFS: Add SMB2 su... |
703 |
} |
1feeaac75 CIFS: Add set_fil... |
704 705 706 707 708 709 710 711 |
int smb2_set_file_info(struct inode *inode, const char *full_path, FILE_BASIC_INFO *buf, const unsigned int xid) { struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct tcon_link *tlink; int rc; |
18dd8e1a6 Do not send SMB3 ... |
712 |
if ((buf->CreationTime == 0) && (buf->LastAccessTime == 0) && |
fd09b7d3b smb3: Do not send... |
713 |
(buf->LastWriteTime == 0) && (buf->ChangeTime == 0) && |
18dd8e1a6 Do not send SMB3 ... |
714 715 |
(buf->Attributes == 0)) return 0; /* would be a no op, no sense sending this */ |
1feeaac75 CIFS: Add set_fil... |
716 717 718 |
tlink = cifs_sb_tlink(cifs_sb); if (IS_ERR(tlink)) return PTR_ERR(tlink); |
18dd8e1a6 Do not send SMB3 ... |
719 |
|
dcbf91035 cifs: change SMB2... |
720 |
rc = smb2_compound_op(xid, tlink_tcon(tlink), cifs_sb, full_path, |
c3ca78e21 smb3: pass mode b... |
721 722 |
FILE_WRITE_ATTRIBUTES, FILE_OPEN, 0, ACL_NO_MODE, buf, SMB2_OP_SET_INFO, NULL); |
1feeaac75 CIFS: Add set_fil... |
723 724 725 |
cifs_put_tlink(tlink); return rc; } |