Merge tag 'nfs-for-5.1-3' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
[linux-2.6-block.git] / fs / cifs / smb2inode.c
1 /*
2  *   fs/cifs/smb2inode.c
3  *
4  *   Copyright (C) International Business Machines  Corp., 2002, 2011
5  *                 Etersoft, 2012
6  *   Author(s): Pavel Shilovsky (pshilovsky@samba.org),
7  *              Steve French (sfrench@us.ibm.com)
8  *
9  *   This library is free software; you can redistribute it and/or modify
10  *   it under the terms of the GNU Lesser General Public License as published
11  *   by the Free Software Foundation; either version 2.1 of the License, or
12  *   (at your option) any later version.
13  *
14  *   This library is distributed in the hope that it will be useful,
15  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
17  *   the GNU Lesser General Public License for more details.
18  *
19  *   You should have received a copy of the GNU Lesser General Public License
20  *   along with this library; if not, write to the Free Software
21  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22  */
23 #include <linux/fs.h>
24 #include <linux/stat.h>
25 #include <linux/slab.h>
26 #include <linux/pagemap.h>
27 #include <asm/div64.h>
28 #include "cifsfs.h"
29 #include "cifspdu.h"
30 #include "cifsglob.h"
31 #include "cifsproto.h"
32 #include "cifs_debug.h"
33 #include "cifs_fs_sb.h"
34 #include "cifs_unicode.h"
35 #include "fscache.h"
36 #include "smb2glob.h"
37 #include "smb2pdu.h"
38 #include "smb2proto.h"
39
40 static void
41 free_set_inf_compound(struct smb_rqst *rqst)
42 {
43         if (rqst[1].rq_iov)
44                 SMB2_set_info_free(&rqst[1]);
45         if (rqst[2].rq_iov)
46                 SMB2_close_free(&rqst[2]);
47 }
48
49
50 static int
51 smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon,
52                  struct cifs_sb_info *cifs_sb, const char *full_path,
53                  __u32 desired_access, __u32 create_disposition,
54                  __u32 create_options, void *ptr, int command)
55 {
56         int rc;
57         __le16 *utf16_path = NULL;
58         __u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
59         struct cifs_open_parms oparms;
60         struct cifs_fid fid;
61         struct cifs_ses *ses = tcon->ses;
62         int num_rqst = 0;
63         struct smb_rqst rqst[3];
64         int resp_buftype[3];
65         struct kvec rsp_iov[3];
66         struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
67         struct kvec qi_iov[1];
68         struct kvec si_iov[SMB2_SET_INFO_IOV_SIZE];
69         struct kvec close_iov[1];
70         struct smb2_query_info_rsp *qi_rsp = NULL;
71         int flags = 0;
72         __u8 delete_pending[8] = {1, 0, 0, 0, 0, 0, 0, 0};
73         unsigned int size[2];
74         void *data[2];
75         struct smb2_file_rename_info rename_info;
76         struct smb2_file_link_info link_info;
77         int len;
78
79         if (smb3_encryption_required(tcon))
80                 flags |= CIFS_TRANSFORM_REQ;
81
82         memset(rqst, 0, sizeof(rqst));
83         resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER;
84         memset(rsp_iov, 0, sizeof(rsp_iov));
85
86         /* Open */
87         utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
88         if (!utf16_path)
89                 return -ENOMEM;
90
91         oparms.tcon = tcon;
92         oparms.desired_access = desired_access;
93         oparms.disposition = create_disposition;
94         oparms.create_options = create_options;
95         if (backup_cred(cifs_sb))
96                 oparms.create_options |= CREATE_OPEN_BACKUP_INTENT;
97         oparms.fid = &fid;
98         oparms.reconnect = false;
99
100         memset(&open_iov, 0, sizeof(open_iov));
101         rqst[num_rqst].rq_iov = open_iov;
102         rqst[num_rqst].rq_nvec = SMB2_CREATE_IOV_SIZE;
103         rc = SMB2_open_init(tcon, &rqst[num_rqst], &oplock, &oparms,
104                             utf16_path);
105         kfree(utf16_path);
106         if (rc)
107                 goto finished;
108
109         smb2_set_next_command(tcon, &rqst[num_rqst++]);
110
111         /* Operation */
112         switch (command) {
113         case SMB2_OP_QUERY_INFO:
114                 memset(&qi_iov, 0, sizeof(qi_iov));
115                 rqst[num_rqst].rq_iov = qi_iov;
116                 rqst[num_rqst].rq_nvec = 1;
117
118                 rc = SMB2_query_info_init(tcon, &rqst[num_rqst], COMPOUND_FID,
119                                 COMPOUND_FID, FILE_ALL_INFORMATION,
120                                 SMB2_O_INFO_FILE, 0,
121                                 sizeof(struct smb2_file_all_info) +
122                                           PATH_MAX * 2, 0, NULL);
123                 smb2_set_next_command(tcon, &rqst[num_rqst]);
124                 smb2_set_related(&rqst[num_rqst++]);
125                 trace_smb3_query_info_compound_enter(xid, ses->Suid, tcon->tid,
126                                                      full_path);
127                 break;
128         case SMB2_OP_DELETE:
129                 trace_smb3_delete_enter(xid, ses->Suid, tcon->tid, full_path);
130                 break;
131         case SMB2_OP_MKDIR:
132                 /*
133                  * Directories are created through parameters in the
134                  * SMB2_open() call.
135                  */
136                 trace_smb3_mkdir_enter(xid, ses->Suid, tcon->tid, full_path);
137                 break;
138         case SMB2_OP_RMDIR:
139                 memset(&si_iov, 0, sizeof(si_iov));
140                 rqst[num_rqst].rq_iov = si_iov;
141                 rqst[num_rqst].rq_nvec = 1;
142
143                 size[0] = 1; /* sizeof __u8 See MS-FSCC section 2.4.11 */
144                 data[0] = &delete_pending[0];
145
146                 rc = SMB2_set_info_init(tcon, &rqst[num_rqst], COMPOUND_FID,
147                                         COMPOUND_FID, current->tgid,
148                                         FILE_DISPOSITION_INFORMATION,
149                                         SMB2_O_INFO_FILE, 0, data, size);
150                 smb2_set_next_command(tcon, &rqst[num_rqst]);
151                 smb2_set_related(&rqst[num_rqst++]);
152                 trace_smb3_rmdir_enter(xid, ses->Suid, tcon->tid, full_path);
153                 break;
154         case SMB2_OP_SET_EOF:
155                 memset(&si_iov, 0, sizeof(si_iov));
156                 rqst[num_rqst].rq_iov = si_iov;
157                 rqst[num_rqst].rq_nvec = 1;
158
159                 size[0] = 8; /* sizeof __le64 */
160                 data[0] = ptr;
161
162                 rc = SMB2_set_info_init(tcon, &rqst[num_rqst], COMPOUND_FID,
163                                         COMPOUND_FID, current->tgid,
164                                         FILE_END_OF_FILE_INFORMATION,
165                                         SMB2_O_INFO_FILE, 0, data, size);
166                 smb2_set_next_command(tcon, &rqst[num_rqst]);
167                 smb2_set_related(&rqst[num_rqst++]);
168                 trace_smb3_set_eof_enter(xid, ses->Suid, tcon->tid, full_path);
169                 break;
170         case SMB2_OP_SET_INFO:
171                 memset(&si_iov, 0, sizeof(si_iov));
172                 rqst[num_rqst].rq_iov = si_iov;
173                 rqst[num_rqst].rq_nvec = 1;
174
175
176                 size[0] = sizeof(FILE_BASIC_INFO);
177                 data[0] = ptr;
178
179                 rc = SMB2_set_info_init(tcon, &rqst[num_rqst], COMPOUND_FID,
180                                         COMPOUND_FID, current->tgid,
181                                         FILE_BASIC_INFORMATION,
182                                         SMB2_O_INFO_FILE, 0, data, size);
183                 smb2_set_next_command(tcon, &rqst[num_rqst]);
184                 smb2_set_related(&rqst[num_rqst++]);
185                 trace_smb3_set_info_compound_enter(xid, ses->Suid, tcon->tid,
186                                                    full_path);
187                 break;
188         case SMB2_OP_RENAME:
189                 memset(&si_iov, 0, sizeof(si_iov));
190                 rqst[num_rqst].rq_iov = si_iov;
191                 rqst[num_rqst].rq_nvec = 2;
192
193                 len = (2 * UniStrnlen((wchar_t *)ptr, PATH_MAX));
194
195                 rename_info.ReplaceIfExists = 1;
196                 rename_info.RootDirectory = 0;
197                 rename_info.FileNameLength = cpu_to_le32(len);
198
199                 size[0] = sizeof(struct smb2_file_rename_info);
200                 data[0] = &rename_info;
201
202                 size[1] = len + 2 /* null */;
203                 data[1] = (__le16 *)ptr;
204
205                 rc = SMB2_set_info_init(tcon, &rqst[num_rqst], COMPOUND_FID,
206                                         COMPOUND_FID, current->tgid,
207                                         FILE_RENAME_INFORMATION,
208                                         SMB2_O_INFO_FILE, 0, data, size);
209                 smb2_set_next_command(tcon, &rqst[num_rqst]);
210                 smb2_set_related(&rqst[num_rqst++]);
211                 trace_smb3_rename_enter(xid, ses->Suid, tcon->tid, full_path);
212                 break;
213         case SMB2_OP_HARDLINK:
214                 memset(&si_iov, 0, sizeof(si_iov));
215                 rqst[num_rqst].rq_iov = si_iov;
216                 rqst[num_rqst].rq_nvec = 2;
217
218                 len = (2 * UniStrnlen((wchar_t *)ptr, PATH_MAX));
219
220                 link_info.ReplaceIfExists = 0;
221                 link_info.RootDirectory = 0;
222                 link_info.FileNameLength = cpu_to_le32(len);
223
224                 size[0] = sizeof(struct smb2_file_link_info);
225                 data[0] = &link_info;
226
227                 size[1] = len + 2 /* null */;
228                 data[1] = (__le16 *)ptr;
229
230                 rc = SMB2_set_info_init(tcon, &rqst[num_rqst], COMPOUND_FID,
231                                         COMPOUND_FID, current->tgid,
232                                         FILE_LINK_INFORMATION,
233                                         SMB2_O_INFO_FILE, 0, data, size);
234                 smb2_set_next_command(tcon, &rqst[num_rqst]);
235                 smb2_set_related(&rqst[num_rqst++]);
236                 trace_smb3_hardlink_enter(xid, ses->Suid, tcon->tid, full_path);
237                 break;
238         default:
239                 cifs_dbg(VFS, "Invalid command\n");
240                 rc = -EINVAL;
241         }
242         if (rc)
243                 goto finished;
244
245         /* Close */
246         memset(&close_iov, 0, sizeof(close_iov));
247         rqst[num_rqst].rq_iov = close_iov;
248         rqst[num_rqst].rq_nvec = 1;
249         rc = SMB2_close_init(tcon, &rqst[num_rqst], COMPOUND_FID,
250                              COMPOUND_FID);
251         smb2_set_related(&rqst[num_rqst++]);
252         if (rc)
253                 goto finished;
254
255         rc = compound_send_recv(xid, ses, flags, num_rqst, rqst,
256                                 resp_buftype, rsp_iov);
257
258  finished:
259         SMB2_open_free(&rqst[0]);
260         switch (command) {
261         case SMB2_OP_QUERY_INFO:
262                 if (rc == 0) {
263                         qi_rsp = (struct smb2_query_info_rsp *)
264                                 rsp_iov[1].iov_base;
265                         rc = smb2_validate_and_copy_iov(
266                                 le16_to_cpu(qi_rsp->OutputBufferOffset),
267                                 le32_to_cpu(qi_rsp->OutputBufferLength),
268                                 &rsp_iov[1], sizeof(struct smb2_file_all_info),
269                                 ptr);
270                 }
271                 if (rqst[1].rq_iov)
272                         SMB2_query_info_free(&rqst[1]);
273                 if (rqst[2].rq_iov)
274                         SMB2_close_free(&rqst[2]);
275                 if (rc)
276                         trace_smb3_query_info_compound_err(xid,  ses->Suid,
277                                                 tcon->tid, rc);
278                 else
279                         trace_smb3_query_info_compound_done(xid, ses->Suid,
280                                                 tcon->tid);
281                 break;
282         case SMB2_OP_DELETE:
283                 if (rc)
284                         trace_smb3_delete_err(xid,  ses->Suid, tcon->tid, rc);
285                 else
286                         trace_smb3_delete_done(xid, ses->Suid, tcon->tid);
287                 if (rqst[1].rq_iov)
288                         SMB2_close_free(&rqst[1]);
289                 break;
290         case SMB2_OP_MKDIR:
291                 if (rc)
292                         trace_smb3_mkdir_err(xid,  ses->Suid, tcon->tid, rc);
293                 else
294                         trace_smb3_mkdir_done(xid, ses->Suid, tcon->tid);
295                 if (rqst[1].rq_iov)
296                         SMB2_close_free(&rqst[1]);
297                 break;
298         case SMB2_OP_HARDLINK:
299                 if (rc)
300                         trace_smb3_hardlink_err(xid,  ses->Suid, tcon->tid, rc);
301                 else
302                         trace_smb3_hardlink_done(xid, ses->Suid, tcon->tid);
303                 free_set_inf_compound(rqst);
304                 break;
305         case SMB2_OP_RENAME:
306                 if (rc)
307                         trace_smb3_rename_err(xid,  ses->Suid, tcon->tid, rc);
308                 else
309                         trace_smb3_rename_done(xid, ses->Suid, tcon->tid);
310                 free_set_inf_compound(rqst);
311                 break;
312         case SMB2_OP_RMDIR:
313                 if (rc)
314                         trace_smb3_rmdir_err(xid,  ses->Suid, tcon->tid, rc);
315                 else
316                         trace_smb3_rmdir_done(xid, ses->Suid, tcon->tid);
317                 free_set_inf_compound(rqst);
318                 break;
319         case SMB2_OP_SET_EOF:
320                 if (rc)
321                         trace_smb3_set_eof_err(xid,  ses->Suid, tcon->tid, rc);
322                 else
323                         trace_smb3_set_eof_done(xid, ses->Suid, tcon->tid);
324                 free_set_inf_compound(rqst);
325                 break;
326         case SMB2_OP_SET_INFO:
327                 if (rc)
328                         trace_smb3_set_info_compound_err(xid,  ses->Suid,
329                                                 tcon->tid, rc);
330                 else
331                         trace_smb3_set_info_compound_done(xid, ses->Suid,
332                                                 tcon->tid);
333                 free_set_inf_compound(rqst);
334                 break;
335         }
336         free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
337         free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
338         free_rsp_buf(resp_buftype[2], rsp_iov[2].iov_base);
339         return rc;
340 }
341
342 void
343 move_smb2_info_to_cifs(FILE_ALL_INFO *dst, struct smb2_file_all_info *src)
344 {
345         memcpy(dst, src, (size_t)(&src->CurrentByteOffset) - (size_t)src);
346         dst->CurrentByteOffset = src->CurrentByteOffset;
347         dst->Mode = src->Mode;
348         dst->AlignmentRequirement = src->AlignmentRequirement;
349         dst->IndexNumber1 = 0; /* we don't use it */
350 }
351
352 int
353 smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon,
354                      struct cifs_sb_info *cifs_sb, const char *full_path,
355                      FILE_ALL_INFO *data, bool *adjust_tz, bool *symlink)
356 {
357         int rc;
358         struct smb2_file_all_info *smb2_data;
359         __u32 create_options = 0;
360         struct cifs_fid fid;
361         bool no_cached_open = tcon->nohandlecache;
362
363         *adjust_tz = false;
364         *symlink = false;
365
366         smb2_data = kzalloc(sizeof(struct smb2_file_all_info) + PATH_MAX * 2,
367                             GFP_KERNEL);
368         if (smb2_data == NULL)
369                 return -ENOMEM;
370
371         /* If it is a root and its handle is cached then use it */
372         if (!strlen(full_path) && !no_cached_open) {
373                 rc = open_shroot(xid, tcon, &fid);
374                 if (rc)
375                         goto out;
376
377                 if (tcon->crfid.file_all_info_is_valid) {
378                         move_smb2_info_to_cifs(data,
379                                                &tcon->crfid.file_all_info);
380                 } else {
381                         rc = SMB2_query_info(xid, tcon, fid.persistent_fid,
382                                              fid.volatile_fid, smb2_data);
383                         if (!rc)
384                                 move_smb2_info_to_cifs(data, smb2_data);
385                 }
386                 close_shroot(&tcon->crfid);
387                 goto out;
388         }
389
390         if (backup_cred(cifs_sb))
391                 create_options |= CREATE_OPEN_BACKUP_INTENT;
392
393         rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
394                               FILE_READ_ATTRIBUTES, FILE_OPEN, create_options,
395                               smb2_data, SMB2_OP_QUERY_INFO);
396         if (rc == -EOPNOTSUPP) {
397                 *symlink = true;
398                 create_options |= OPEN_REPARSE_POINT;
399
400                 /* Failed on a symbolic link - query a reparse point info */
401                 rc = smb2_compound_op(xid, tcon, cifs_sb, full_path,
402                                       FILE_READ_ATTRIBUTES, FILE_OPEN,
403                                       create_options, smb2_data,
404                                       SMB2_OP_QUERY_INFO);
405         }
406         if (rc)
407                 goto out;
408
409         move_smb2_info_to_cifs(data, smb2_data);
410 out:
411         kfree(smb2_data);
412         return rc;
413 }
414
415 int
416 smb2_mkdir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
417            struct cifs_sb_info *cifs_sb)
418 {
419         return smb2_compound_op(xid, tcon, cifs_sb, name,
420                                 FILE_WRITE_ATTRIBUTES, FILE_CREATE,
421                                 CREATE_NOT_FILE, NULL, SMB2_OP_MKDIR);
422 }
423
424 void
425 smb2_mkdir_setinfo(struct inode *inode, const char *name,
426                    struct cifs_sb_info *cifs_sb, struct cifs_tcon *tcon,
427                    const unsigned int xid)
428 {
429         FILE_BASIC_INFO data;
430         struct cifsInodeInfo *cifs_i;
431         u32 dosattrs;
432         int tmprc;
433
434         memset(&data, 0, sizeof(data));
435         cifs_i = CIFS_I(inode);
436         dosattrs = cifs_i->cifsAttrs | ATTR_READONLY;
437         data.Attributes = cpu_to_le32(dosattrs);
438         tmprc = smb2_compound_op(xid, tcon, cifs_sb, name,
439                                  FILE_WRITE_ATTRIBUTES, FILE_CREATE,
440                                  CREATE_NOT_FILE, &data, SMB2_OP_SET_INFO);
441         if (tmprc == 0)
442                 cifs_i->cifsAttrs = dosattrs;
443 }
444
445 int
446 smb2_rmdir(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
447            struct cifs_sb_info *cifs_sb)
448 {
449         return smb2_compound_op(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN,
450                                 CREATE_NOT_FILE,
451                                 NULL, SMB2_OP_RMDIR);
452 }
453
454 int
455 smb2_unlink(const unsigned int xid, struct cifs_tcon *tcon, const char *name,
456             struct cifs_sb_info *cifs_sb)
457 {
458         return smb2_compound_op(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN,
459                                 CREATE_DELETE_ON_CLOSE | OPEN_REPARSE_POINT,
460                                 NULL, SMB2_OP_DELETE);
461 }
462
463 static int
464 smb2_set_path_attr(const unsigned int xid, struct cifs_tcon *tcon,
465                    const char *from_name, const char *to_name,
466                    struct cifs_sb_info *cifs_sb, __u32 access, int command)
467 {
468         __le16 *smb2_to_name = NULL;
469         int rc;
470
471         smb2_to_name = cifs_convert_path_to_utf16(to_name, cifs_sb);
472         if (smb2_to_name == NULL) {
473                 rc = -ENOMEM;
474                 goto smb2_rename_path;
475         }
476         rc = smb2_compound_op(xid, tcon, cifs_sb, from_name, access,
477                               FILE_OPEN, 0, smb2_to_name, command);
478 smb2_rename_path:
479         kfree(smb2_to_name);
480         return rc;
481 }
482
483 int
484 smb2_rename_path(const unsigned int xid, struct cifs_tcon *tcon,
485                  const char *from_name, const char *to_name,
486                  struct cifs_sb_info *cifs_sb)
487 {
488         return smb2_set_path_attr(xid, tcon, from_name, to_name, cifs_sb,
489                                   DELETE, SMB2_OP_RENAME);
490 }
491
492 int
493 smb2_create_hardlink(const unsigned int xid, struct cifs_tcon *tcon,
494                      const char *from_name, const char *to_name,
495                      struct cifs_sb_info *cifs_sb)
496 {
497         return smb2_set_path_attr(xid, tcon, from_name, to_name, cifs_sb,
498                                   FILE_READ_ATTRIBUTES, SMB2_OP_HARDLINK);
499 }
500
501 int
502 smb2_set_path_size(const unsigned int xid, struct cifs_tcon *tcon,
503                    const char *full_path, __u64 size,
504                    struct cifs_sb_info *cifs_sb, bool set_alloc)
505 {
506         __le64 eof = cpu_to_le64(size);
507
508         return smb2_compound_op(xid, tcon, cifs_sb, full_path,
509                                 FILE_WRITE_DATA, FILE_OPEN, 0, &eof,
510                                 SMB2_OP_SET_EOF);
511 }
512
513 int
514 smb2_set_file_info(struct inode *inode, const char *full_path,
515                    FILE_BASIC_INFO *buf, const unsigned int xid)
516 {
517         struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
518         struct tcon_link *tlink;
519         int rc;
520
521         if ((buf->CreationTime == 0) && (buf->LastAccessTime == 0) &&
522             (buf->LastWriteTime == 0) && (buf->ChangeTime == 0) &&
523             (buf->Attributes == 0))
524                 return 0; /* would be a no op, no sense sending this */
525
526         tlink = cifs_sb_tlink(cifs_sb);
527         if (IS_ERR(tlink))
528                 return PTR_ERR(tlink);
529
530         rc = smb2_compound_op(xid, tlink_tcon(tlink), cifs_sb, full_path,
531                               FILE_WRITE_ATTRIBUTES, FILE_OPEN, 0, buf,
532                               SMB2_OP_SET_INFO);
533         cifs_put_tlink(tlink);
534         return rc;
535 }