Blame view

fs/cifs/smb2inode.c 20.5 KB
be4cb9e3d   Pavel Shilovsky   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   Steve French   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   Ronnie Sahlberg   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   Pavel Shilovsky   CIFS: Query SMB2 ...
58
  static int
c5a5f38f0   Ronnie Sahlberg   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   Steve French   smb3: pass mode b...
62
  		 __u32 create_options, umode_t mode, void *ptr, int command,
8de9e86c6   Ronnie Sahlberg   cifs: create a he...
63
  		 struct cifsFileInfo *cfile)
c5a5f38f0   Ronnie Sahlberg   cifs: add a smb2_...
64
  {
a7d5c2946   Ronnie Sahlberg   cifs: reduce stac...
65
66
67
  	struct cop_vars *vars = NULL;
  	struct kvec *rsp_iov;
  	struct smb_rqst *rqst;
c5a5f38f0   Ronnie Sahlberg   cifs: add a smb2_...
68
69
70
  	int rc;
  	__le16 *utf16_path = NULL;
  	__u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
c5a5f38f0   Ronnie Sahlberg   cifs: add a smb2_...
71
72
  	struct cifs_fid fid;
  	struct cifs_ses *ses = tcon->ses;
352d96f3a   Aurelien Aptel   cifs: multichanne...
73
  	struct TCP_Server_Info *server;
c5a5f38f0   Ronnie Sahlberg   cifs: add a smb2_...
74
  	int num_rqst = 0;
c5a5f38f0   Ronnie Sahlberg   cifs: add a smb2_...
75
  	int resp_buftype[3];
c2e0fe3f5   Ronnie Sahlberg   cifs: make rmdir(...
76
  	struct smb2_query_info_rsp *qi_rsp = NULL;
c5a5f38f0   Ronnie Sahlberg   cifs: add a smb2_...
77
  	int flags = 0;
c2e0fe3f5   Ronnie Sahlberg   cifs: make rmdir(...
78
  	__u8 delete_pending[8] = {1, 0, 0, 0, 0, 0, 0, 0};
bb435512c   Ronnie Sahlberg   cifs: change SMB2...
79
80
  	unsigned int size[2];
  	void *data[2];
bb435512c   Ronnie Sahlberg   cifs: change SMB2...
81
  	int len;
c5a5f38f0   Ronnie Sahlberg   cifs: add a smb2_...
82

a7d5c2946   Ronnie Sahlberg   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   Aurelien Aptel   cifs: multichanne...
88
  	server = cifs_pick_channel(ses);
c5a5f38f0   Ronnie Sahlberg   cifs: add a smb2_...
89
90
  	if (smb3_encryption_required(tcon))
  		flags |= CIFS_TRANSFORM_REQ;
c5a5f38f0   Ronnie Sahlberg   cifs: add a smb2_...
91
  	resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
c5a5f38f0   Ronnie Sahlberg   cifs: add a smb2_...
92

8de9e86c6   Ronnie Sahlberg   cifs: create a he...
93
94
95
  	/* We already have a handle so we can skip the open */
  	if (cfile)
  		goto after_open;
c5a5f38f0   Ronnie Sahlberg   cifs: add a smb2_...
96
97
  	/* Open */
  	utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
8de9e86c6   Ronnie Sahlberg   cifs: create a he...
98
99
100
101
  	if (!utf16_path) {
  		rc = -ENOMEM;
  		goto finished;
  	}
c5a5f38f0   Ronnie Sahlberg   cifs: add a smb2_...
102

a7d5c2946   Ronnie Sahlberg   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   Steve French   SMB3: Fix mkdir w...
110
  	vars->oparms.cifs_sb = cifs_sb;
a7d5c2946   Ronnie Sahlberg   cifs: reduce stac...
111
112
  
  	rqst[num_rqst].rq_iov = &vars->open_iov[0];
c5a5f38f0   Ronnie Sahlberg   cifs: add a smb2_...
113
  	rqst[num_rqst].rq_nvec = SMB2_CREATE_IOV_SIZE;
352d96f3a   Aurelien Aptel   cifs: multichanne...
114
115
  	rc = SMB2_open_init(tcon, server,
  			    &rqst[num_rqst], &oplock, &vars->oparms,
c5a5f38f0   Ronnie Sahlberg   cifs: add a smb2_...
116
117
118
119
  			    utf16_path);
  	kfree(utf16_path);
  	if (rc)
  		goto finished;
8de9e86c6   Ronnie Sahlberg   cifs: create a he...
120
121
122
123
  	smb2_set_next_command(tcon, &rqst[num_rqst]);
   after_open:
  	num_rqst++;
  	rc = 0;
c5a5f38f0   Ronnie Sahlberg   cifs: add a smb2_...
124
125
126
127
  
  	/* Operation */
  	switch (command) {
  	case SMB2_OP_QUERY_INFO:
a7d5c2946   Ronnie Sahlberg   cifs: reduce stac...
128
  		rqst[num_rqst].rq_iov = &vars->qi_iov[0];
c5a5f38f0   Ronnie Sahlberg   cifs: add a smb2_...
129
  		rqst[num_rqst].rq_nvec = 1;
496902dc1   Ronnie Sahlberg   cifs: add a helpe...
130
  		if (cfile)
352d96f3a   Aurelien Aptel   cifs: multichanne...
131
132
  			rc = SMB2_query_info_init(tcon, server,
  				&rqst[num_rqst],
496902dc1   Ronnie Sahlberg   cifs: add a helpe...
133
134
135
  				cfile->fid.persistent_fid,
  				cfile->fid.volatile_fid,
  				FILE_ALL_INFORMATION,
c5a5f38f0   Ronnie Sahlberg   cifs: add a smb2_...
136
137
  				SMB2_O_INFO_FILE, 0,
  				sizeof(struct smb2_file_all_info) +
f5b05d622   Ronnie Sahlberg   cifs: add IOCTL f...
138
  					  PATH_MAX * 2, 0, NULL);
496902dc1   Ronnie Sahlberg   cifs: add a helpe...
139
  		else {
352d96f3a   Aurelien Aptel   cifs: multichanne...
140
141
  			rc = SMB2_query_info_init(tcon, server,
  				&rqst[num_rqst],
496902dc1   Ronnie Sahlberg   cifs: add a helpe...
142
143
  				COMPOUND_FID,
  				COMPOUND_FID,
352d96f3a   Aurelien Aptel   cifs: multichanne...
144
  				FILE_ALL_INFORMATION,
496902dc1   Ronnie Sahlberg   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   Ronnie Sahlberg   cifs: fix crash i...
153
154
  		if (rc)
  			goto finished;
496902dc1   Ronnie Sahlberg   cifs: add a helpe...
155
  		num_rqst++;
8191576a1   Steve French   smb3: Add dynamic...
156
157
  		trace_smb3_query_info_compound_enter(xid, ses->Suid, tcon->tid,
  						     full_path);
c5a5f38f0   Ronnie Sahlberg   cifs: add a smb2_...
158
  		break;
6a5f6592a   Steve French   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   Steve French   smb311: Add trace...
191
  		trace_smb3_posix_query_info_compound_enter(xid, ses->Suid, tcon->tid, full_path);
6a5f6592a   Steve French   SMB311: Add suppo...
192
  		break;
47dd9597d   Ronnie Sahlberg   cifs: change unli...
193
  	case SMB2_OP_DELETE:
8191576a1   Steve French   smb3: Add dynamic...
194
  		trace_smb3_delete_enter(xid, ses->Suid, tcon->tid, full_path);
47dd9597d   Ronnie Sahlberg   cifs: change unli...
195
  		break;
f733e3936   Ronnie Sahlberg   cifs: change mkdi...
196
197
198
199
200
  	case SMB2_OP_MKDIR:
  		/*
  		 * Directories are created through parameters in the
  		 * SMB2_open() call.
  		 */
8191576a1   Steve French   smb3: Add dynamic...
201
  		trace_smb3_mkdir_enter(xid, ses->Suid, tcon->tid, full_path);
f733e3936   Ronnie Sahlberg   cifs: change mkdi...
202
  		break;
c2e0fe3f5   Ronnie Sahlberg   cifs: make rmdir(...
203
  	case SMB2_OP_RMDIR:
a7d5c2946   Ronnie Sahlberg   cifs: reduce stac...
204
  		rqst[num_rqst].rq_iov = &vars->si_iov[0];
c2e0fe3f5   Ronnie Sahlberg   cifs: make rmdir(...
205
  		rqst[num_rqst].rq_nvec = 1;
271b9c0c8   Ronnie Sahlberg   smb3: Fix rmdir c...
206
  		size[0] = 1; /* sizeof __u8 See MS-FSCC section 2.4.11 */
c2e0fe3f5   Ronnie Sahlberg   cifs: make rmdir(...
207
  		data[0] = &delete_pending[0];
352d96f3a   Aurelien Aptel   cifs: multichanne...
208
209
  		rc = SMB2_set_info_init(tcon, server,
  					&rqst[num_rqst], COMPOUND_FID,
c2e0fe3f5   Ronnie Sahlberg   cifs: make rmdir(...
210
211
212
  					COMPOUND_FID, current->tgid,
  					FILE_DISPOSITION_INFORMATION,
  					SMB2_O_INFO_FILE, 0, data, size);
88a92c913   Ronnie Sahlberg   cifs: fix crash i...
213
214
  		if (rc)
  			goto finished;
e77fe73c7   Ronnie Sahlberg   cifs: we can not ...
215
  		smb2_set_next_command(tcon, &rqst[num_rqst]);
c2e0fe3f5   Ronnie Sahlberg   cifs: make rmdir(...
216
  		smb2_set_related(&rqst[num_rqst++]);
8191576a1   Steve French   smb3: Add dynamic...
217
  		trace_smb3_rmdir_enter(xid, ses->Suid, tcon->tid, full_path);
c2e0fe3f5   Ronnie Sahlberg   cifs: make rmdir(...
218
  		break;
f7bfe04bf   Ronnie Sahlberg   cifs: change SMB2...
219
  	case SMB2_OP_SET_EOF:
a7d5c2946   Ronnie Sahlberg   cifs: reduce stac...
220
  		rqst[num_rqst].rq_iov = &vars->si_iov[0];
f7bfe04bf   Ronnie Sahlberg   cifs: change SMB2...
221
222
223
224
  		rqst[num_rqst].rq_nvec = 1;
  
  		size[0] = 8; /* sizeof __le64 */
  		data[0] = ptr;
352d96f3a   Aurelien Aptel   cifs: multichanne...
225
226
  		rc = SMB2_set_info_init(tcon, server,
  					&rqst[num_rqst], COMPOUND_FID,
f7bfe04bf   Ronnie Sahlberg   cifs: change SMB2...
227
228
229
  					COMPOUND_FID, current->tgid,
  					FILE_END_OF_FILE_INFORMATION,
  					SMB2_O_INFO_FILE, 0, data, size);
88a92c913   Ronnie Sahlberg   cifs: fix crash i...
230
231
  		if (rc)
  			goto finished;
e77fe73c7   Ronnie Sahlberg   cifs: we can not ...
232
  		smb2_set_next_command(tcon, &rqst[num_rqst]);
f7bfe04bf   Ronnie Sahlberg   cifs: change SMB2...
233
  		smb2_set_related(&rqst[num_rqst++]);
8191576a1   Steve French   smb3: Add dynamic...
234
  		trace_smb3_set_eof_enter(xid, ses->Suid, tcon->tid, full_path);
f7bfe04bf   Ronnie Sahlberg   cifs: change SMB2...
235
  		break;
dcbf91035   Ronnie Sahlberg   cifs: change SMB2...
236
  	case SMB2_OP_SET_INFO:
a7d5c2946   Ronnie Sahlberg   cifs: reduce stac...
237
  		rqst[num_rqst].rq_iov = &vars->si_iov[0];
dcbf91035   Ronnie Sahlberg   cifs: change SMB2...
238
  		rqst[num_rqst].rq_nvec = 1;
bb435512c   Ronnie Sahlberg   cifs: change SMB2...
239

dcbf91035   Ronnie Sahlberg   cifs: change SMB2...
240
241
  		size[0] = sizeof(FILE_BASIC_INFO);
  		data[0] = ptr;
dc9300a67   Ronnie Sahlberg   cifs: use existin...
242
  		if (cfile)
352d96f3a   Aurelien Aptel   cifs: multichanne...
243
244
  			rc = SMB2_set_info_init(tcon, server,
  				&rqst[num_rqst],
dc9300a67   Ronnie Sahlberg   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   Aurelien Aptel   cifs: multichanne...
250
251
  			rc = SMB2_set_info_init(tcon, server,
  				&rqst[num_rqst],
dc9300a67   Ronnie Sahlberg   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   Ronnie Sahlberg   cifs: fix crash i...
261
262
  		if (rc)
  			goto finished;
dc9300a67   Ronnie Sahlberg   cifs: use existin...
263
  		num_rqst++;
8191576a1   Steve French   smb3: Add dynamic...
264
265
  		trace_smb3_set_info_compound_enter(xid, ses->Suid, tcon->tid,
  						   full_path);
dcbf91035   Ronnie Sahlberg   cifs: change SMB2...
266
  		break;
bb435512c   Ronnie Sahlberg   cifs: change SMB2...
267
  	case SMB2_OP_RENAME:
a7d5c2946   Ronnie Sahlberg   cifs: reduce stac...
268
  		rqst[num_rqst].rq_iov = &vars->si_iov[0];
bb435512c   Ronnie Sahlberg   cifs: change SMB2...
269
270
271
  		rqst[num_rqst].rq_nvec = 2;
  
  		len = (2 * UniStrnlen((wchar_t *)ptr, PATH_MAX));
a7d5c2946   Ronnie Sahlberg   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   Ronnie Sahlberg   cifs: change SMB2...
275
276
  
  		size[0] = sizeof(struct smb2_file_rename_info);
a7d5c2946   Ronnie Sahlberg   cifs: reduce stac...
277
  		data[0] = &vars->rename_info;
bb435512c   Ronnie Sahlberg   cifs: change SMB2...
278
279
280
  
  		size[1] = len + 2 /* null */;
  		data[1] = (__le16 *)ptr;
8de9e86c6   Ronnie Sahlberg   cifs: create a he...
281
  		if (cfile)
352d96f3a   Aurelien Aptel   cifs: multichanne...
282
283
  			rc = SMB2_set_info_init(tcon, server,
  						&rqst[num_rqst],
8de9e86c6   Ronnie Sahlberg   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   Aurelien Aptel   cifs: multichanne...
289
290
  			rc = SMB2_set_info_init(tcon, server,
  					&rqst[num_rqst],
8de9e86c6   Ronnie Sahlberg   cifs: create a he...
291
292
  					COMPOUND_FID, COMPOUND_FID,
  					current->tgid, FILE_RENAME_INFORMATION,
bb435512c   Ronnie Sahlberg   cifs: change SMB2...
293
  					SMB2_O_INFO_FILE, 0, data, size);
dc9300a67   Ronnie Sahlberg   cifs: use existin...
294
295
296
297
  			if (!rc) {
  				smb2_set_next_command(tcon, &rqst[num_rqst]);
  				smb2_set_related(&rqst[num_rqst]);
  			}
8de9e86c6   Ronnie Sahlberg   cifs: create a he...
298
  		}
88a92c913   Ronnie Sahlberg   cifs: fix crash i...
299
300
  		if (rc)
  			goto finished;
8de9e86c6   Ronnie Sahlberg   cifs: create a he...
301
  		num_rqst++;
8191576a1   Steve French   smb3: Add dynamic...
302
  		trace_smb3_rename_enter(xid, ses->Suid, tcon->tid, full_path);
bb435512c   Ronnie Sahlberg   cifs: change SMB2...
303
304
  		break;
  	case SMB2_OP_HARDLINK:
a7d5c2946   Ronnie Sahlberg   cifs: reduce stac...
305
  		rqst[num_rqst].rq_iov = &vars->si_iov[0];
bb435512c   Ronnie Sahlberg   cifs: change SMB2...
306
307
308
  		rqst[num_rqst].rq_nvec = 2;
  
  		len = (2 * UniStrnlen((wchar_t *)ptr, PATH_MAX));
a7d5c2946   Ronnie Sahlberg   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   Ronnie Sahlberg   cifs: change SMB2...
312
313
  
  		size[0] = sizeof(struct smb2_file_link_info);
a7d5c2946   Ronnie Sahlberg   cifs: reduce stac...
314
  		data[0] = &vars->link_info;
bb435512c   Ronnie Sahlberg   cifs: change SMB2...
315
316
317
  
  		size[1] = len + 2 /* null */;
  		data[1] = (__le16 *)ptr;
352d96f3a   Aurelien Aptel   cifs: multichanne...
318
319
  		rc = SMB2_set_info_init(tcon, server,
  					&rqst[num_rqst], COMPOUND_FID,
bb435512c   Ronnie Sahlberg   cifs: change SMB2...
320
321
322
  					COMPOUND_FID, current->tgid,
  					FILE_LINK_INFORMATION,
  					SMB2_O_INFO_FILE, 0, data, size);
88a92c913   Ronnie Sahlberg   cifs: fix crash i...
323
324
  		if (rc)
  			goto finished;
e77fe73c7   Ronnie Sahlberg   cifs: we can not ...
325
  		smb2_set_next_command(tcon, &rqst[num_rqst]);
bb435512c   Ronnie Sahlberg   cifs: change SMB2...
326
  		smb2_set_related(&rqst[num_rqst++]);
8191576a1   Steve French   smb3: Add dynamic...
327
  		trace_smb3_hardlink_enter(xid, ses->Suid, tcon->tid, full_path);
bb435512c   Ronnie Sahlberg   cifs: change SMB2...
328
  		break;
c5a5f38f0   Ronnie Sahlberg   cifs: add a smb2_...
329
330
331
332
333
334
335
  	default:
  		cifs_dbg(VFS, "Invalid command
  ");
  		rc = -EINVAL;
  	}
  	if (rc)
  		goto finished;
8de9e86c6   Ronnie Sahlberg   cifs: create a he...
336
337
338
  	/* We already have a handle so we can skip the close */
  	if (cfile)
  		goto after_close;
c5a5f38f0   Ronnie Sahlberg   cifs: add a smb2_...
339
  	/* Close */
a7d5c2946   Ronnie Sahlberg   cifs: reduce stac...
340
  	rqst[num_rqst].rq_iov = &vars->close_iov[0];
c5a5f38f0   Ronnie Sahlberg   cifs: add a smb2_...
341
  	rqst[num_rqst].rq_nvec = 1;
352d96f3a   Aurelien Aptel   cifs: multichanne...
342
343
  	rc = SMB2_close_init(tcon, server,
  			     &rqst[num_rqst], COMPOUND_FID,
43f8a6a74   Steve French   smb3: query attri...
344
  			     COMPOUND_FID, false);
8de9e86c6   Ronnie Sahlberg   cifs: create a he...
345
  	smb2_set_related(&rqst[num_rqst]);
c5a5f38f0   Ronnie Sahlberg   cifs: add a smb2_...
346
347
  	if (rc)
  		goto finished;
8de9e86c6   Ronnie Sahlberg   cifs: create a he...
348
349
350
351
352
353
   after_close:
  	num_rqst++;
  
  	if (cfile) {
  		cifsFileInfo_put(cfile);
  		cfile = NULL;
352d96f3a   Aurelien Aptel   cifs: multichanne...
354
355
  		rc = compound_send_recv(xid, ses, server,
  					flags, num_rqst - 2,
8de9e86c6   Ronnie Sahlberg   cifs: create a he...
356
357
358
  					&rqst[1], &resp_buftype[1],
  					&rsp_iov[1]);
  	} else
352d96f3a   Aurelien Aptel   cifs: multichanne...
359
360
  		rc = compound_send_recv(xid, ses, server,
  					flags, num_rqst,
8de9e86c6   Ronnie Sahlberg   cifs: create a he...
361
362
  					rqst, resp_buftype,
  					rsp_iov);
c5a5f38f0   Ronnie Sahlberg   cifs: add a smb2_...
363
364
  
   finished:
8de9e86c6   Ronnie Sahlberg   cifs: create a he...
365
366
  	if (cfile)
  		cifsFileInfo_put(cfile);
c5a5f38f0   Ronnie Sahlberg   cifs: add a smb2_...
367
  	SMB2_open_free(&rqst[0]);
7dcc82c2d   Steve French   smb3: improve han...
368
  	if (rc == -EREMCHG) {
a0a3036b8   Joe Perches   cifs: Standardize...
369
370
  		pr_warn_once("server share %s deleted
  ", tcon->treeName);
7dcc82c2d   Steve French   smb3: improve han...
371
372
  		tcon->need_reconnect = true;
  	}
c5a5f38f0   Ronnie Sahlberg   cifs: add a smb2_...
373
374
375
  	switch (command) {
  	case SMB2_OP_QUERY_INFO:
  		if (rc == 0) {
c2e0fe3f5   Ronnie Sahlberg   cifs: make rmdir(...
376
377
  			qi_rsp = (struct smb2_query_info_rsp *)
  				rsp_iov[1].iov_base;
c5a5f38f0   Ronnie Sahlberg   cifs: add a smb2_...
378
  			rc = smb2_validate_and_copy_iov(
c2e0fe3f5   Ronnie Sahlberg   cifs: make rmdir(...
379
380
  				le16_to_cpu(qi_rsp->OutputBufferOffset),
  				le32_to_cpu(qi_rsp->OutputBufferLength),
c5a5f38f0   Ronnie Sahlberg   cifs: add a smb2_...
381
  				&rsp_iov[1], sizeof(struct smb2_file_all_info),
c2e0fe3f5   Ronnie Sahlberg   cifs: make rmdir(...
382
  				ptr);
c5a5f38f0   Ronnie Sahlberg   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   Steve French   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   Ronnie Sahlberg   cifs: add a smb2_...
394
  		break;
6a5f6592a   Steve French   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   Steve French   smb311: Add trace...
409
  			trace_smb3_posix_query_info_compound_err(xid,  ses->Suid, tcon->tid, rc);
6a5f6592a   Steve French   SMB311: Add suppo...
410
  		else
e4bd7c4a8   Steve French   smb311: Add trace...
411
  			trace_smb3_posix_query_info_compound_done(xid, ses->Suid, tcon->tid);
6a5f6592a   Steve French   SMB311: Add suppo...
412
  		break;
47dd9597d   Ronnie Sahlberg   cifs: change unli...
413
  	case SMB2_OP_DELETE:
8191576a1   Steve French   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   Ronnie Sahlberg   cifs: change mkdi...
421
  	case SMB2_OP_MKDIR:
8191576a1   Steve French   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   Ronnie Sahlberg   cifs: change mkdi...
426
427
428
  		if (rqst[1].rq_iov)
  			SMB2_close_free(&rqst[1]);
  		break;
bb435512c   Ronnie Sahlberg   cifs: change SMB2...
429
  	case SMB2_OP_HARDLINK:
8191576a1   Steve French   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   Ronnie Sahlberg   cifs: change SMB2...
436
  	case SMB2_OP_RENAME:
8191576a1   Steve French   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   Ronnie Sahlberg   cifs: make rmdir(...
443
  	case SMB2_OP_RMDIR:
8191576a1   Steve French   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   Ronnie Sahlberg   cifs: change SMB2...
450
  	case SMB2_OP_SET_EOF:
8191576a1   Steve French   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   Ronnie Sahlberg   cifs: change SMB2...
457
  	case SMB2_OP_SET_INFO:
8191576a1   Steve French   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   Ronnie Sahlberg   cifs: make rmdir(...
465
  		break;
c5a5f38f0   Ronnie Sahlberg   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   Ronnie Sahlberg   cifs: reduce stac...
470
  	kfree(vars);
c5a5f38f0   Ronnie Sahlberg   cifs: add a smb2_...
471
472
  	return rc;
  }
f0df737ee   Pavel Shilovsky   CIFS: Add open/cl...
473
  void
be4cb9e3d   Pavel Shilovsky   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   Steve French   smb3: add support...
486
  		     FILE_ALL_INFO *data, bool *adjust_tz, bool *reparse)
be4cb9e3d   Pavel Shilovsky   CIFS: Query SMB2 ...
487
488
489
  {
  	int rc;
  	struct smb2_file_all_info *smb2_data;
61351d6d5   Steve French   smb3: send backup...
490
  	__u32 create_options = 0;
6a9cbdd1c   Pavel Shilovsky   CIFS: Fix mounts ...
491
  	bool no_cached_open = tcon->nohandlecache;
496902dc1   Ronnie Sahlberg   cifs: add a helpe...
492
  	struct cifsFileInfo *cfile;
9e81e8ff7   Ronnie Sahlberg   cifs: return cach...
493
  	struct cached_fid *cfid = NULL;
be4cb9e3d   Pavel Shilovsky   CIFS: Query SMB2 ...
494
495
  
  	*adjust_tz = false;
2e4564b31   Steve French   smb3: add support...
496
  	*reparse = false;
be4cb9e3d   Pavel Shilovsky   CIFS: Query SMB2 ...
497

1bbe4997b   Pavel Shilovsky   CIFS: Fix wrong f...
498
  	smb2_data = kzalloc(sizeof(struct smb2_file_all_info) + PATH_MAX * 2,
be4cb9e3d   Pavel Shilovsky   CIFS: Query SMB2 ...
499
500
501
  			    GFP_KERNEL);
  	if (smb2_data == NULL)
  		return -ENOMEM;
6a9cbdd1c   Pavel Shilovsky   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   Ronnie Sahlberg   cifs: return cach...
505
  		rc = open_shroot(xid, tcon, cifs_sb, &cfid);
6a9cbdd1c   Pavel Shilovsky   CIFS: Fix mounts ...
506
507
  		if (rc)
  			goto out;
b0f6df737   Ronnie Sahlberg   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   Ronnie Sahlberg   cifs: return cach...
513
514
515
  			rc = SMB2_query_info(xid, tcon,
  					     cfid->fid->persistent_fid,
  					     cfid->fid->volatile_fid, smb2_data);
b0f6df737   Ronnie Sahlberg   cifs: cache FILE_...
516
517
518
  			if (!rc)
  				move_smb2_info_to_cifs(data, smb2_data);
  		}
9e81e8ff7   Ronnie Sahlberg   cifs: return cach...
519
  		close_shroot(cfid);
6a9cbdd1c   Pavel Shilovsky   CIFS: Fix mounts ...
520
521
  		goto out;
  	}
496902dc1   Ronnie Sahlberg   cifs: add a helpe...
522
  	cifs_get_readable_path(tcon, full_path, &cfile);
c5a5f38f0   Ronnie Sahlberg   cifs: add a smb2_...
523
  	rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
61351d6d5   Steve French   smb3: send backup...
524
  			      FILE_READ_ATTRIBUTES, FILE_OPEN, create_options,
c3ca78e21   Steve French   smb3: pass mode b...
525
  			      ACL_NO_MODE, smb2_data, SMB2_OP_QUERY_INFO, cfile);
eb85d94bd   Pavel Shilovsky   CIFS: Fix symboli...
526
  	if (rc == -EOPNOTSUPP) {
2e4564b31   Steve French   smb3: add support...
527
  		*reparse = true;
61351d6d5   Steve French   smb3: send backup...
528
  		create_options |= OPEN_REPARSE_POINT;
eb85d94bd   Pavel Shilovsky   CIFS: Fix symboli...
529
  		/* Failed on a symbolic link - query a reparse point info */
c5a5f38f0   Ronnie Sahlberg   cifs: add a smb2_...
530
531
  		rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
  				      FILE_READ_ATTRIBUTES, FILE_OPEN,
c3ca78e21   Steve French   smb3: pass mode b...
532
533
  				      create_options, ACL_NO_MODE,
  				      smb2_data, SMB2_OP_QUERY_INFO, NULL);
eb85d94bd   Pavel Shilovsky   CIFS: Fix symboli...
534
  	}
be4cb9e3d   Pavel Shilovsky   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   Pavel Shilovsky   CIFS: Add SMB2 su...
543

6a5f6592a   Steve French   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   Steve French   smb3: add support...
548
  		     struct smb311_posix_qinfo *data, bool *adjust_tz, bool *reparse)
6a5f6592a   Steve French   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   Steve French   smb3: add support...
556
  	*reparse = false;
6a5f6592a   Steve French   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   Steve French   smb3: add support...
577
  		*reparse = true;
6a5f6592a   Steve French   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   Pavel Shilovsky   CIFS: Add SMB2 su...
596
  int
c3ca78e21   Steve French   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   Pavel Shilovsky   CIFS: Add SMB2 su...
599
600
  	   struct cifs_sb_info *cifs_sb)
  {
f733e3936   Ronnie Sahlberg   cifs: change mkdi...
601
602
  	return smb2_compound_op(xid, tcon, cifs_sb, name,
  				FILE_WRITE_ATTRIBUTES, FILE_CREATE,
c3ca78e21   Steve French   smb3: pass mode b...
603
604
  				CREATE_NOT_FILE, mode, NULL, SMB2_OP_MKDIR,
  				NULL);
a0e731839   Pavel Shilovsky   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   Ronnie Sahlberg   cifs: use existin...
614
  	struct cifsFileInfo *cfile;
a0e731839   Pavel Shilovsky   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   Aurelien Aptel   cifs: fix rename(...
622
  	cifs_get_writable_path(tcon, name, FIND_WR_ANY, &cfile);
dcbf91035   Ronnie Sahlberg   cifs: change SMB2...
623
624
  	tmprc = smb2_compound_op(xid, tcon, cifs_sb, name,
  				 FILE_WRITE_ATTRIBUTES, FILE_CREATE,
c3ca78e21   Steve French   smb3: pass mode b...
625
626
  				 CREATE_NOT_FILE, ACL_NO_MODE,
  				 &data, SMB2_OP_SET_INFO, cfile);
a0e731839   Pavel Shilovsky   CIFS: Add SMB2 su...
627
628
629
  	if (tmprc == 0)
  		cifs_i->cifsAttrs = dosattrs;
  }
1a500f010   Pavel Shilovsky   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   Ronnie Sahlberg   cifs: make rmdir(...
635
  	return smb2_compound_op(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN,
c3ca78e21   Steve French   smb3: pass mode b...
636
  				CREATE_NOT_FILE, ACL_NO_MODE,
8de9e86c6   Ronnie Sahlberg   cifs: create a he...
637
  				NULL, SMB2_OP_RMDIR, NULL);
1a500f010   Pavel Shilovsky   CIFS: Add SMB2 su...
638
  }
cbe6f439f   Pavel Shilovsky   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   Ronnie Sahlberg   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   Steve French   smb3: pass mode b...
646
  				ACL_NO_MODE, NULL, SMB2_OP_DELETE, NULL);
cbe6f439f   Pavel Shilovsky   CIFS: Add SMB2 su...
647
  }
35143eb5c   Pavel Shilovsky   CIFS: Add SMB2 su...
648

568798cc6   Pavel Shilovsky   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   Ronnie Sahlberg   cifs: create a he...
652
653
  		   struct cifs_sb_info *cifs_sb, __u32 access, int command,
  		   struct cifsFileInfo *cfile)
35143eb5c   Pavel Shilovsky   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   Ronnie Sahlberg   cifs: change SMB2...
663
  	rc = smb2_compound_op(xid, tcon, cifs_sb, from_name, access,
c3ca78e21   Steve French   smb3: pass mode b...
664
665
  			      FILE_OPEN, 0, ACL_NO_MODE, smb2_to_name,
  			      command, cfile);
35143eb5c   Pavel Shilovsky   CIFS: Add SMB2 su...
666
667
668
669
  smb2_rename_path:
  	kfree(smb2_to_name);
  	return rc;
  }
568798cc6   Pavel Shilovsky   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   Ronnie Sahlberg   cifs: create a he...
676
  	struct cifsFileInfo *cfile;
86f740f2a   Aurelien Aptel   cifs: fix rename(...
677
  	cifs_get_writable_path(tcon, from_name, FIND_WR_WITH_DELETE, &cfile);
8de9e86c6   Ronnie Sahlberg   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   Pavel Shilovsky   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   Ronnie Sahlberg   cifs: create a he...
689
690
  				  FILE_READ_ATTRIBUTES, SMB2_OP_HARDLINK,
  				  NULL);
568798cc6   Pavel Shilovsky   CIFS: Add SMB2 su...
691
  }
c839ff244   Pavel Shilovsky   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   Ronnie Sahlberg   cifs: change SMB2...
699
700
  
  	return smb2_compound_op(xid, tcon, cifs_sb, full_path,
c3ca78e21   Steve French   smb3: pass mode b...
701
702
  				FILE_WRITE_DATA, FILE_OPEN, 0, ACL_NO_MODE,
  				&eof, SMB2_OP_SET_EOF, NULL);
c839ff244   Pavel Shilovsky   CIFS: Add SMB2 su...
703
  }
1feeaac75   Pavel Shilovsky   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   Steve French   Do not send SMB3 ...
712
  	if ((buf->CreationTime == 0) && (buf->LastAccessTime == 0) &&
fd09b7d3b   Steve French   smb3: Do not send...
713
  	    (buf->LastWriteTime == 0) && (buf->ChangeTime == 0) &&
18dd8e1a6   Steve French   Do not send SMB3 ...
714
715
  	    (buf->Attributes == 0))
  		return 0; /* would be a no op, no sense sending this */
1feeaac75   Pavel Shilovsky   CIFS: Add set_fil...
716
717
718
  	tlink = cifs_sb_tlink(cifs_sb);
  	if (IS_ERR(tlink))
  		return PTR_ERR(tlink);
18dd8e1a6   Steve French   Do not send SMB3 ...
719

dcbf91035   Ronnie Sahlberg   cifs: change SMB2...
720
  	rc = smb2_compound_op(xid, tlink_tcon(tlink), cifs_sb, full_path,
c3ca78e21   Steve French   smb3: pass mode b...
721
722
  			      FILE_WRITE_ATTRIBUTES, FILE_OPEN,
  			      0, ACL_NO_MODE, buf, SMB2_OP_SET_INFO, NULL);
1feeaac75   Pavel Shilovsky   CIFS: Add set_fil...
723
724
725
  	cifs_put_tlink(tlink);
  	return rc;
  }