Linux 3.12.28
[linux/fpc-iii.git] / fs / cifs / smb2ops.c
blob4ac88f89a5e5f67291e9c9ef975d9487b848fdd9
1 /*
2 * SMB2 version specific operations
4 * Copyright (c) 2012, Jeff Layton <jlayton@redhat.com>
6 * This library is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License v2 as published
8 * by the Free Software Foundation.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include <linux/pagemap.h>
21 #include <linux/vfs.h>
22 #include "cifsglob.h"
23 #include "smb2pdu.h"
24 #include "smb2proto.h"
25 #include "cifsproto.h"
26 #include "cifs_debug.h"
27 #include "cifs_unicode.h"
28 #include "smb2status.h"
29 #include "smb2glob.h"
31 static int
32 change_conf(struct TCP_Server_Info *server)
34 server->credits += server->echo_credits + server->oplock_credits;
35 server->oplock_credits = server->echo_credits = 0;
36 switch (server->credits) {
37 case 0:
38 return -1;
39 case 1:
40 server->echoes = false;
41 server->oplocks = false;
42 cifs_dbg(VFS, "disabling echoes and oplocks\n");
43 break;
44 case 2:
45 server->echoes = true;
46 server->oplocks = false;
47 server->echo_credits = 1;
48 cifs_dbg(FYI, "disabling oplocks\n");
49 break;
50 default:
51 server->echoes = true;
52 server->oplocks = true;
53 server->echo_credits = 1;
54 server->oplock_credits = 1;
56 server->credits -= server->echo_credits + server->oplock_credits;
57 return 0;
60 static void
61 smb2_add_credits(struct TCP_Server_Info *server, const unsigned int add,
62 const int optype)
64 int *val, rc = 0;
65 spin_lock(&server->req_lock);
66 val = server->ops->get_credits_field(server, optype);
67 *val += add;
68 server->in_flight--;
69 if (server->in_flight == 0 && (optype & CIFS_OP_MASK) != CIFS_NEG_OP)
70 rc = change_conf(server);
72 * Sometimes server returns 0 credits on oplock break ack - we need to
73 * rebalance credits in this case.
75 else if (server->in_flight > 0 && server->oplock_credits == 0 &&
76 server->oplocks) {
77 if (server->credits > 1) {
78 server->credits--;
79 server->oplock_credits++;
82 spin_unlock(&server->req_lock);
83 wake_up(&server->request_q);
84 if (rc)
85 cifs_reconnect(server);
88 static void
89 smb2_set_credits(struct TCP_Server_Info *server, const int val)
91 spin_lock(&server->req_lock);
92 server->credits = val;
93 spin_unlock(&server->req_lock);
96 static int *
97 smb2_get_credits_field(struct TCP_Server_Info *server, const int optype)
99 switch (optype) {
100 case CIFS_ECHO_OP:
101 return &server->echo_credits;
102 case CIFS_OBREAK_OP:
103 return &server->oplock_credits;
104 default:
105 return &server->credits;
109 static unsigned int
110 smb2_get_credits(struct mid_q_entry *mid)
112 return le16_to_cpu(((struct smb2_hdr *)mid->resp_buf)->CreditRequest);
115 static __u64
116 smb2_get_next_mid(struct TCP_Server_Info *server)
118 __u64 mid;
119 /* for SMB2 we need the current value */
120 spin_lock(&GlobalMid_Lock);
121 mid = server->CurrentMid++;
122 spin_unlock(&GlobalMid_Lock);
123 return mid;
126 static struct mid_q_entry *
127 smb2_find_mid(struct TCP_Server_Info *server, char *buf)
129 struct mid_q_entry *mid;
130 struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
132 spin_lock(&GlobalMid_Lock);
133 list_for_each_entry(mid, &server->pending_mid_q, qhead) {
134 if ((mid->mid == hdr->MessageId) &&
135 (mid->mid_state == MID_REQUEST_SUBMITTED) &&
136 (mid->command == hdr->Command)) {
137 spin_unlock(&GlobalMid_Lock);
138 return mid;
141 spin_unlock(&GlobalMid_Lock);
142 return NULL;
145 static void
146 smb2_dump_detail(void *buf)
148 #ifdef CONFIG_CIFS_DEBUG2
149 struct smb2_hdr *smb = (struct smb2_hdr *)buf;
151 cifs_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Mid: %llu Pid: %d\n",
152 smb->Command, smb->Status, smb->Flags, smb->MessageId,
153 smb->ProcessId);
154 cifs_dbg(VFS, "smb buf %p len %u\n", smb, smb2_calc_size(smb));
155 #endif
158 static bool
159 smb2_need_neg(struct TCP_Server_Info *server)
161 return server->max_read == 0;
164 static int
165 smb2_negotiate(const unsigned int xid, struct cifs_ses *ses)
167 int rc;
168 ses->server->CurrentMid = 0;
169 rc = SMB2_negotiate(xid, ses);
170 /* BB we probably don't need to retry with modern servers */
171 if (rc == -EAGAIN)
172 rc = -EHOSTDOWN;
173 return rc;
176 static unsigned int
177 smb2_negotiate_wsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
179 struct TCP_Server_Info *server = tcon->ses->server;
180 unsigned int wsize;
182 /* start with specified wsize, or default */
183 wsize = volume_info->wsize ? volume_info->wsize : CIFS_DEFAULT_IOSIZE;
184 wsize = min_t(unsigned int, wsize, server->max_write);
185 /* set it to the maximum buffer size value we can send with 1 credit */
186 wsize = min_t(unsigned int, wsize, SMB2_MAX_BUFFER_SIZE);
188 return wsize;
191 static unsigned int
192 smb2_negotiate_rsize(struct cifs_tcon *tcon, struct smb_vol *volume_info)
194 struct TCP_Server_Info *server = tcon->ses->server;
195 unsigned int rsize;
197 /* start with specified rsize, or default */
198 rsize = volume_info->rsize ? volume_info->rsize : CIFS_DEFAULT_IOSIZE;
199 rsize = min_t(unsigned int, rsize, server->max_read);
200 /* set it to the maximum buffer size value we can send with 1 credit */
201 rsize = min_t(unsigned int, rsize, SMB2_MAX_BUFFER_SIZE);
203 return rsize;
206 static int
207 smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon,
208 struct cifs_sb_info *cifs_sb, const char *full_path)
210 int rc;
211 __le16 *utf16_path;
212 __u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
213 struct cifs_open_parms oparms;
214 struct cifs_fid fid;
216 utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
217 if (!utf16_path)
218 return -ENOMEM;
220 oparms.tcon = tcon;
221 oparms.desired_access = FILE_READ_ATTRIBUTES;
222 oparms.disposition = FILE_OPEN;
223 oparms.create_options = 0;
224 oparms.fid = &fid;
225 oparms.reconnect = false;
227 rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL);
228 if (rc) {
229 kfree(utf16_path);
230 return rc;
233 rc = SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
234 kfree(utf16_path);
235 return rc;
238 static int
239 smb2_get_srv_inum(const unsigned int xid, struct cifs_tcon *tcon,
240 struct cifs_sb_info *cifs_sb, const char *full_path,
241 u64 *uniqueid, FILE_ALL_INFO *data)
243 *uniqueid = le64_to_cpu(data->IndexNumber);
244 return 0;
247 static int
248 smb2_query_file_info(const unsigned int xid, struct cifs_tcon *tcon,
249 struct cifs_fid *fid, FILE_ALL_INFO *data)
251 int rc;
252 struct smb2_file_all_info *smb2_data;
254 smb2_data = kzalloc(sizeof(struct smb2_file_all_info) + MAX_NAME * 2,
255 GFP_KERNEL);
256 if (smb2_data == NULL)
257 return -ENOMEM;
259 rc = SMB2_query_info(xid, tcon, fid->persistent_fid, fid->volatile_fid,
260 smb2_data);
261 if (!rc)
262 move_smb2_info_to_cifs(data, smb2_data);
263 kfree(smb2_data);
264 return rc;
267 static bool
268 smb2_can_echo(struct TCP_Server_Info *server)
270 return server->echoes;
273 static void
274 smb2_clear_stats(struct cifs_tcon *tcon)
276 #ifdef CONFIG_CIFS_STATS
277 int i;
278 for (i = 0; i < NUMBER_OF_SMB2_COMMANDS; i++) {
279 atomic_set(&tcon->stats.smb2_stats.smb2_com_sent[i], 0);
280 atomic_set(&tcon->stats.smb2_stats.smb2_com_failed[i], 0);
282 #endif
285 static void
286 smb2_dump_share_caps(struct seq_file *m, struct cifs_tcon *tcon)
288 seq_puts(m, "\n\tShare Capabilities:");
289 if (tcon->capabilities & SMB2_SHARE_CAP_DFS)
290 seq_puts(m, " DFS,");
291 if (tcon->capabilities & SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY)
292 seq_puts(m, " CONTINUOUS AVAILABILITY,");
293 if (tcon->capabilities & SMB2_SHARE_CAP_SCALEOUT)
294 seq_puts(m, " SCALEOUT,");
295 if (tcon->capabilities & SMB2_SHARE_CAP_CLUSTER)
296 seq_puts(m, " CLUSTER,");
297 if (tcon->capabilities & SMB2_SHARE_CAP_ASYMMETRIC)
298 seq_puts(m, " ASYMMETRIC,");
299 if (tcon->capabilities == 0)
300 seq_puts(m, " None");
301 seq_printf(m, "\tShare Flags: 0x%x", tcon->share_flags);
304 static void
305 smb2_print_stats(struct seq_file *m, struct cifs_tcon *tcon)
307 #ifdef CONFIG_CIFS_STATS
308 atomic_t *sent = tcon->stats.smb2_stats.smb2_com_sent;
309 atomic_t *failed = tcon->stats.smb2_stats.smb2_com_failed;
310 seq_printf(m, "\nNegotiates: %d sent %d failed",
311 atomic_read(&sent[SMB2_NEGOTIATE_HE]),
312 atomic_read(&failed[SMB2_NEGOTIATE_HE]));
313 seq_printf(m, "\nSessionSetups: %d sent %d failed",
314 atomic_read(&sent[SMB2_SESSION_SETUP_HE]),
315 atomic_read(&failed[SMB2_SESSION_SETUP_HE]));
316 seq_printf(m, "\nLogoffs: %d sent %d failed",
317 atomic_read(&sent[SMB2_LOGOFF_HE]),
318 atomic_read(&failed[SMB2_LOGOFF_HE]));
319 seq_printf(m, "\nTreeConnects: %d sent %d failed",
320 atomic_read(&sent[SMB2_TREE_CONNECT_HE]),
321 atomic_read(&failed[SMB2_TREE_CONNECT_HE]));
322 seq_printf(m, "\nTreeDisconnects: %d sent %d failed",
323 atomic_read(&sent[SMB2_TREE_DISCONNECT_HE]),
324 atomic_read(&failed[SMB2_TREE_DISCONNECT_HE]));
325 seq_printf(m, "\nCreates: %d sent %d failed",
326 atomic_read(&sent[SMB2_CREATE_HE]),
327 atomic_read(&failed[SMB2_CREATE_HE]));
328 seq_printf(m, "\nCloses: %d sent %d failed",
329 atomic_read(&sent[SMB2_CLOSE_HE]),
330 atomic_read(&failed[SMB2_CLOSE_HE]));
331 seq_printf(m, "\nFlushes: %d sent %d failed",
332 atomic_read(&sent[SMB2_FLUSH_HE]),
333 atomic_read(&failed[SMB2_FLUSH_HE]));
334 seq_printf(m, "\nReads: %d sent %d failed",
335 atomic_read(&sent[SMB2_READ_HE]),
336 atomic_read(&failed[SMB2_READ_HE]));
337 seq_printf(m, "\nWrites: %d sent %d failed",
338 atomic_read(&sent[SMB2_WRITE_HE]),
339 atomic_read(&failed[SMB2_WRITE_HE]));
340 seq_printf(m, "\nLocks: %d sent %d failed",
341 atomic_read(&sent[SMB2_LOCK_HE]),
342 atomic_read(&failed[SMB2_LOCK_HE]));
343 seq_printf(m, "\nIOCTLs: %d sent %d failed",
344 atomic_read(&sent[SMB2_IOCTL_HE]),
345 atomic_read(&failed[SMB2_IOCTL_HE]));
346 seq_printf(m, "\nCancels: %d sent %d failed",
347 atomic_read(&sent[SMB2_CANCEL_HE]),
348 atomic_read(&failed[SMB2_CANCEL_HE]));
349 seq_printf(m, "\nEchos: %d sent %d failed",
350 atomic_read(&sent[SMB2_ECHO_HE]),
351 atomic_read(&failed[SMB2_ECHO_HE]));
352 seq_printf(m, "\nQueryDirectories: %d sent %d failed",
353 atomic_read(&sent[SMB2_QUERY_DIRECTORY_HE]),
354 atomic_read(&failed[SMB2_QUERY_DIRECTORY_HE]));
355 seq_printf(m, "\nChangeNotifies: %d sent %d failed",
356 atomic_read(&sent[SMB2_CHANGE_NOTIFY_HE]),
357 atomic_read(&failed[SMB2_CHANGE_NOTIFY_HE]));
358 seq_printf(m, "\nQueryInfos: %d sent %d failed",
359 atomic_read(&sent[SMB2_QUERY_INFO_HE]),
360 atomic_read(&failed[SMB2_QUERY_INFO_HE]));
361 seq_printf(m, "\nSetInfos: %d sent %d failed",
362 atomic_read(&sent[SMB2_SET_INFO_HE]),
363 atomic_read(&failed[SMB2_SET_INFO_HE]));
364 seq_printf(m, "\nOplockBreaks: %d sent %d failed",
365 atomic_read(&sent[SMB2_OPLOCK_BREAK_HE]),
366 atomic_read(&failed[SMB2_OPLOCK_BREAK_HE]));
367 #endif
370 static void
371 smb2_set_fid(struct cifsFileInfo *cfile, struct cifs_fid *fid, __u32 oplock)
373 struct cifsInodeInfo *cinode = CIFS_I(cfile->dentry->d_inode);
374 struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server;
376 cfile->fid.persistent_fid = fid->persistent_fid;
377 cfile->fid.volatile_fid = fid->volatile_fid;
378 server->ops->set_oplock_level(cinode, oplock, fid->epoch,
379 &fid->purge_cache);
380 cinode->can_cache_brlcks = CIFS_CACHE_WRITE(cinode);
383 static void
384 smb2_close_file(const unsigned int xid, struct cifs_tcon *tcon,
385 struct cifs_fid *fid)
387 SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid);
390 static int
391 smb2_flush_file(const unsigned int xid, struct cifs_tcon *tcon,
392 struct cifs_fid *fid)
394 return SMB2_flush(xid, tcon, fid->persistent_fid, fid->volatile_fid);
397 static unsigned int
398 smb2_read_data_offset(char *buf)
400 struct smb2_read_rsp *rsp = (struct smb2_read_rsp *)buf;
401 return rsp->DataOffset;
404 static unsigned int
405 smb2_read_data_length(char *buf)
407 struct smb2_read_rsp *rsp = (struct smb2_read_rsp *)buf;
408 return le32_to_cpu(rsp->DataLength);
412 static int
413 smb2_sync_read(const unsigned int xid, struct cifsFileInfo *cfile,
414 struct cifs_io_parms *parms, unsigned int *bytes_read,
415 char **buf, int *buf_type)
417 parms->persistent_fid = cfile->fid.persistent_fid;
418 parms->volatile_fid = cfile->fid.volatile_fid;
419 return SMB2_read(xid, parms, bytes_read, buf, buf_type);
422 static int
423 smb2_sync_write(const unsigned int xid, struct cifsFileInfo *cfile,
424 struct cifs_io_parms *parms, unsigned int *written,
425 struct kvec *iov, unsigned long nr_segs)
428 parms->persistent_fid = cfile->fid.persistent_fid;
429 parms->volatile_fid = cfile->fid.volatile_fid;
430 return SMB2_write(xid, parms, written, iov, nr_segs);
433 static int
434 smb2_set_file_size(const unsigned int xid, struct cifs_tcon *tcon,
435 struct cifsFileInfo *cfile, __u64 size, bool set_alloc)
437 __le64 eof = cpu_to_le64(size);
438 return SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid,
439 cfile->fid.volatile_fid, cfile->pid, &eof);
442 static int
443 smb2_query_dir_first(const unsigned int xid, struct cifs_tcon *tcon,
444 const char *path, struct cifs_sb_info *cifs_sb,
445 struct cifs_fid *fid, __u16 search_flags,
446 struct cifs_search_info *srch_inf)
448 __le16 *utf16_path;
449 int rc;
450 __u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
451 struct cifs_open_parms oparms;
453 utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
454 if (!utf16_path)
455 return -ENOMEM;
457 oparms.tcon = tcon;
458 oparms.desired_access = FILE_READ_ATTRIBUTES | FILE_READ_DATA;
459 oparms.disposition = FILE_OPEN;
460 oparms.create_options = 0;
461 oparms.fid = fid;
462 oparms.reconnect = false;
464 rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, NULL);
465 kfree(utf16_path);
466 if (rc) {
467 cifs_dbg(VFS, "open dir failed\n");
468 return rc;
471 srch_inf->entries_in_buffer = 0;
472 srch_inf->index_of_last_entry = 0;
474 rc = SMB2_query_directory(xid, tcon, fid->persistent_fid,
475 fid->volatile_fid, 0, srch_inf);
476 if (rc) {
477 cifs_dbg(VFS, "query directory failed\n");
478 SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid);
480 return rc;
483 static int
484 smb2_query_dir_next(const unsigned int xid, struct cifs_tcon *tcon,
485 struct cifs_fid *fid, __u16 search_flags,
486 struct cifs_search_info *srch_inf)
488 return SMB2_query_directory(xid, tcon, fid->persistent_fid,
489 fid->volatile_fid, 0, srch_inf);
492 static int
493 smb2_close_dir(const unsigned int xid, struct cifs_tcon *tcon,
494 struct cifs_fid *fid)
496 return SMB2_close(xid, tcon, fid->persistent_fid, fid->volatile_fid);
500 * If we negotiate SMB2 protocol and get STATUS_PENDING - update
501 * the number of credits and return true. Otherwise - return false.
503 static bool
504 smb2_is_status_pending(char *buf, struct TCP_Server_Info *server, int length)
506 struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
508 if (hdr->Status != STATUS_PENDING)
509 return false;
511 if (!length) {
512 spin_lock(&server->req_lock);
513 server->credits += le16_to_cpu(hdr->CreditRequest);
514 spin_unlock(&server->req_lock);
515 wake_up(&server->request_q);
518 return true;
521 static int
522 smb2_oplock_response(struct cifs_tcon *tcon, struct cifs_fid *fid,
523 struct cifsInodeInfo *cinode)
525 if (tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_LEASING)
526 return SMB2_lease_break(0, tcon, cinode->lease_key,
527 smb2_get_lease_state(cinode));
529 return SMB2_oplock_break(0, tcon, fid->persistent_fid,
530 fid->volatile_fid,
531 CIFS_CACHE_READ(cinode) ? 1 : 0);
534 static int
535 smb2_queryfs(const unsigned int xid, struct cifs_tcon *tcon,
536 struct kstatfs *buf)
538 int rc;
539 __le16 srch_path = 0; /* Null - open root of share */
540 u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
541 struct cifs_open_parms oparms;
542 struct cifs_fid fid;
544 oparms.tcon = tcon;
545 oparms.desired_access = FILE_READ_ATTRIBUTES;
546 oparms.disposition = FILE_OPEN;
547 oparms.create_options = 0;
548 oparms.fid = &fid;
549 oparms.reconnect = false;
551 rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL);
552 if (rc)
553 return rc;
554 buf->f_type = SMB2_MAGIC_NUMBER;
555 rc = SMB2_QFS_info(xid, tcon, fid.persistent_fid, fid.volatile_fid,
556 buf);
557 SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
558 return rc;
561 static bool
562 smb2_compare_fids(struct cifsFileInfo *ob1, struct cifsFileInfo *ob2)
564 return ob1->fid.persistent_fid == ob2->fid.persistent_fid &&
565 ob1->fid.volatile_fid == ob2->fid.volatile_fid;
568 static int
569 smb2_mand_lock(const unsigned int xid, struct cifsFileInfo *cfile, __u64 offset,
570 __u64 length, __u32 type, int lock, int unlock, bool wait)
572 if (unlock && !lock)
573 type = SMB2_LOCKFLAG_UNLOCK;
574 return SMB2_lock(xid, tlink_tcon(cfile->tlink),
575 cfile->fid.persistent_fid, cfile->fid.volatile_fid,
576 current->tgid, length, offset, type, wait);
579 static void
580 smb2_get_lease_key(struct inode *inode, struct cifs_fid *fid)
582 memcpy(fid->lease_key, CIFS_I(inode)->lease_key, SMB2_LEASE_KEY_SIZE);
585 static void
586 smb2_set_lease_key(struct inode *inode, struct cifs_fid *fid)
588 memcpy(CIFS_I(inode)->lease_key, fid->lease_key, SMB2_LEASE_KEY_SIZE);
591 static void
592 smb2_new_lease_key(struct cifs_fid *fid)
594 get_random_bytes(fid->lease_key, SMB2_LEASE_KEY_SIZE);
597 static int
598 smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
599 const char *full_path, char **target_path,
600 struct cifs_sb_info *cifs_sb)
602 int rc;
603 __le16 *utf16_path;
604 __u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
605 struct cifs_open_parms oparms;
606 struct cifs_fid fid;
607 struct smb2_err_rsp *err_buf = NULL;
608 struct smb2_symlink_err_rsp *symlink;
609 unsigned int sub_len, sub_offset;
611 cifs_dbg(FYI, "%s: path: %s\n", __func__, full_path);
613 utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
614 if (!utf16_path)
615 return -ENOMEM;
617 oparms.tcon = tcon;
618 oparms.desired_access = FILE_READ_ATTRIBUTES;
619 oparms.disposition = FILE_OPEN;
620 oparms.create_options = 0;
621 oparms.fid = &fid;
622 oparms.reconnect = false;
624 rc = SMB2_open(xid, &oparms, utf16_path, &oplock, NULL, &err_buf);
626 if (!rc || !err_buf) {
627 kfree(utf16_path);
628 return -ENOENT;
630 /* open must fail on symlink - reset rc */
631 rc = 0;
632 symlink = (struct smb2_symlink_err_rsp *)err_buf->ErrorData;
633 sub_len = le16_to_cpu(symlink->SubstituteNameLength);
634 sub_offset = le16_to_cpu(symlink->SubstituteNameOffset);
635 *target_path = cifs_strndup_from_utf16(
636 (char *)symlink->PathBuffer + sub_offset,
637 sub_len, true, cifs_sb->local_nls);
638 if (!(*target_path)) {
639 kfree(utf16_path);
640 return -ENOMEM;
642 convert_delimiter(*target_path, '/');
643 cifs_dbg(FYI, "%s: target path: %s\n", __func__, *target_path);
644 kfree(utf16_path);
645 return rc;
648 static void
649 smb2_downgrade_oplock(struct TCP_Server_Info *server,
650 struct cifsInodeInfo *cinode, bool set_level2)
652 if (set_level2)
653 server->ops->set_oplock_level(cinode, SMB2_OPLOCK_LEVEL_II,
654 0, NULL);
655 else
656 server->ops->set_oplock_level(cinode, 0, 0, NULL);
659 static void
660 smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
661 unsigned int epoch, bool *purge_cache)
663 oplock &= 0xFF;
664 if (oplock == SMB2_OPLOCK_LEVEL_NOCHANGE)
665 return;
666 if (oplock == SMB2_OPLOCK_LEVEL_BATCH) {
667 cinode->oplock = CIFS_CACHE_RHW_FLG;
668 cifs_dbg(FYI, "Batch Oplock granted on inode %p\n",
669 &cinode->vfs_inode);
670 } else if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE) {
671 cinode->oplock = CIFS_CACHE_RW_FLG;
672 cifs_dbg(FYI, "Exclusive Oplock granted on inode %p\n",
673 &cinode->vfs_inode);
674 } else if (oplock == SMB2_OPLOCK_LEVEL_II) {
675 cinode->oplock = CIFS_CACHE_READ_FLG;
676 cifs_dbg(FYI, "Level II Oplock granted on inode %p\n",
677 &cinode->vfs_inode);
678 } else
679 cinode->oplock = 0;
682 static void
683 smb21_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
684 unsigned int epoch, bool *purge_cache)
686 char message[5] = {0};
688 oplock &= 0xFF;
689 if (oplock == SMB2_OPLOCK_LEVEL_NOCHANGE)
690 return;
692 cinode->oplock = 0;
693 if (oplock & SMB2_LEASE_READ_CACHING_HE) {
694 cinode->oplock |= CIFS_CACHE_READ_FLG;
695 strcat(message, "R");
697 if (oplock & SMB2_LEASE_HANDLE_CACHING_HE) {
698 cinode->oplock |= CIFS_CACHE_HANDLE_FLG;
699 strcat(message, "H");
701 if (oplock & SMB2_LEASE_WRITE_CACHING_HE) {
702 cinode->oplock |= CIFS_CACHE_WRITE_FLG;
703 strcat(message, "W");
705 if (!cinode->oplock)
706 strcat(message, "None");
707 cifs_dbg(FYI, "%s Lease granted on inode %p\n", message,
708 &cinode->vfs_inode);
711 static void
712 smb3_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
713 unsigned int epoch, bool *purge_cache)
715 unsigned int old_oplock = cinode->oplock;
717 smb21_set_oplock_level(cinode, oplock, epoch, purge_cache);
719 if (purge_cache) {
720 *purge_cache = false;
721 if (old_oplock == CIFS_CACHE_READ_FLG) {
722 if (cinode->oplock == CIFS_CACHE_READ_FLG &&
723 (epoch - cinode->epoch > 0))
724 *purge_cache = true;
725 else if (cinode->oplock == CIFS_CACHE_RH_FLG &&
726 (epoch - cinode->epoch > 1))
727 *purge_cache = true;
728 else if (cinode->oplock == CIFS_CACHE_RHW_FLG &&
729 (epoch - cinode->epoch > 1))
730 *purge_cache = true;
731 else if (cinode->oplock == 0 &&
732 (epoch - cinode->epoch > 0))
733 *purge_cache = true;
734 } else if (old_oplock == CIFS_CACHE_RH_FLG) {
735 if (cinode->oplock == CIFS_CACHE_RH_FLG &&
736 (epoch - cinode->epoch > 0))
737 *purge_cache = true;
738 else if (cinode->oplock == CIFS_CACHE_RHW_FLG &&
739 (epoch - cinode->epoch > 1))
740 *purge_cache = true;
742 cinode->epoch = epoch;
746 static bool
747 smb2_is_read_op(__u32 oplock)
749 return oplock == SMB2_OPLOCK_LEVEL_II;
752 static bool
753 smb21_is_read_op(__u32 oplock)
755 return (oplock & SMB2_LEASE_READ_CACHING_HE) &&
756 !(oplock & SMB2_LEASE_WRITE_CACHING_HE);
759 static __le32
760 map_oplock_to_lease(u8 oplock)
762 if (oplock == SMB2_OPLOCK_LEVEL_EXCLUSIVE)
763 return SMB2_LEASE_WRITE_CACHING | SMB2_LEASE_READ_CACHING;
764 else if (oplock == SMB2_OPLOCK_LEVEL_II)
765 return SMB2_LEASE_READ_CACHING;
766 else if (oplock == SMB2_OPLOCK_LEVEL_BATCH)
767 return SMB2_LEASE_HANDLE_CACHING | SMB2_LEASE_READ_CACHING |
768 SMB2_LEASE_WRITE_CACHING;
769 return 0;
772 static char *
773 smb2_create_lease_buf(u8 *lease_key, u8 oplock)
775 struct create_lease *buf;
777 buf = kzalloc(sizeof(struct create_lease), GFP_KERNEL);
778 if (!buf)
779 return NULL;
781 buf->lcontext.LeaseKeyLow = cpu_to_le64(*((u64 *)lease_key));
782 buf->lcontext.LeaseKeyHigh = cpu_to_le64(*((u64 *)(lease_key + 8)));
783 buf->lcontext.LeaseState = map_oplock_to_lease(oplock);
785 buf->ccontext.DataOffset = cpu_to_le16(offsetof
786 (struct create_lease, lcontext));
787 buf->ccontext.DataLength = cpu_to_le32(sizeof(struct lease_context));
788 buf->ccontext.NameOffset = cpu_to_le16(offsetof
789 (struct create_lease, Name));
790 buf->ccontext.NameLength = cpu_to_le16(4);
791 buf->Name[0] = 'R';
792 buf->Name[1] = 'q';
793 buf->Name[2] = 'L';
794 buf->Name[3] = 's';
795 return (char *)buf;
798 static char *
799 smb3_create_lease_buf(u8 *lease_key, u8 oplock)
801 struct create_lease_v2 *buf;
803 buf = kzalloc(sizeof(struct create_lease_v2), GFP_KERNEL);
804 if (!buf)
805 return NULL;
807 buf->lcontext.LeaseKeyLow = cpu_to_le64(*((u64 *)lease_key));
808 buf->lcontext.LeaseKeyHigh = cpu_to_le64(*((u64 *)(lease_key + 8)));
809 buf->lcontext.LeaseState = map_oplock_to_lease(oplock);
811 buf->ccontext.DataOffset = cpu_to_le16(offsetof
812 (struct create_lease_v2, lcontext));
813 buf->ccontext.DataLength = cpu_to_le32(sizeof(struct lease_context_v2));
814 buf->ccontext.NameOffset = cpu_to_le16(offsetof
815 (struct create_lease_v2, Name));
816 buf->ccontext.NameLength = cpu_to_le16(4);
817 buf->Name[0] = 'R';
818 buf->Name[1] = 'q';
819 buf->Name[2] = 'L';
820 buf->Name[3] = 's';
821 return (char *)buf;
824 static __u8
825 smb2_parse_lease_buf(void *buf, unsigned int *epoch)
827 struct create_lease *lc = (struct create_lease *)buf;
829 *epoch = 0; /* not used */
830 if (lc->lcontext.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS)
831 return SMB2_OPLOCK_LEVEL_NOCHANGE;
832 return le32_to_cpu(lc->lcontext.LeaseState);
835 static __u8
836 smb3_parse_lease_buf(void *buf, unsigned int *epoch)
838 struct create_lease_v2 *lc = (struct create_lease_v2 *)buf;
840 *epoch = le16_to_cpu(lc->lcontext.Epoch);
841 if (lc->lcontext.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS)
842 return SMB2_OPLOCK_LEVEL_NOCHANGE;
843 return le32_to_cpu(lc->lcontext.LeaseState);
846 struct smb_version_operations smb20_operations = {
847 .compare_fids = smb2_compare_fids,
848 .setup_request = smb2_setup_request,
849 .setup_async_request = smb2_setup_async_request,
850 .check_receive = smb2_check_receive,
851 .add_credits = smb2_add_credits,
852 .set_credits = smb2_set_credits,
853 .get_credits_field = smb2_get_credits_field,
854 .get_credits = smb2_get_credits,
855 .get_next_mid = smb2_get_next_mid,
856 .read_data_offset = smb2_read_data_offset,
857 .read_data_length = smb2_read_data_length,
858 .map_error = map_smb2_to_linux_error,
859 .find_mid = smb2_find_mid,
860 .check_message = smb2_check_message,
861 .dump_detail = smb2_dump_detail,
862 .clear_stats = smb2_clear_stats,
863 .print_stats = smb2_print_stats,
864 .is_oplock_break = smb2_is_valid_oplock_break,
865 .downgrade_oplock = smb2_downgrade_oplock,
866 .need_neg = smb2_need_neg,
867 .negotiate = smb2_negotiate,
868 .negotiate_wsize = smb2_negotiate_wsize,
869 .negotiate_rsize = smb2_negotiate_rsize,
870 .sess_setup = SMB2_sess_setup,
871 .logoff = SMB2_logoff,
872 .tree_connect = SMB2_tcon,
873 .tree_disconnect = SMB2_tdis,
874 .is_path_accessible = smb2_is_path_accessible,
875 .can_echo = smb2_can_echo,
876 .echo = SMB2_echo,
877 .query_path_info = smb2_query_path_info,
878 .get_srv_inum = smb2_get_srv_inum,
879 .query_file_info = smb2_query_file_info,
880 .set_path_size = smb2_set_path_size,
881 .set_file_size = smb2_set_file_size,
882 .set_file_info = smb2_set_file_info,
883 .mkdir = smb2_mkdir,
884 .mkdir_setinfo = smb2_mkdir_setinfo,
885 .rmdir = smb2_rmdir,
886 .unlink = smb2_unlink,
887 .rename = smb2_rename_path,
888 .create_hardlink = smb2_create_hardlink,
889 .query_symlink = smb2_query_symlink,
890 .open = smb2_open_file,
891 .set_fid = smb2_set_fid,
892 .close = smb2_close_file,
893 .flush = smb2_flush_file,
894 .async_readv = smb2_async_readv,
895 .async_writev = smb2_async_writev,
896 .sync_read = smb2_sync_read,
897 .sync_write = smb2_sync_write,
898 .query_dir_first = smb2_query_dir_first,
899 .query_dir_next = smb2_query_dir_next,
900 .close_dir = smb2_close_dir,
901 .calc_smb_size = smb2_calc_size,
902 .is_status_pending = smb2_is_status_pending,
903 .oplock_response = smb2_oplock_response,
904 .queryfs = smb2_queryfs,
905 .mand_lock = smb2_mand_lock,
906 .mand_unlock_range = smb2_unlock_range,
907 .push_mand_locks = smb2_push_mandatory_locks,
908 .get_lease_key = smb2_get_lease_key,
909 .set_lease_key = smb2_set_lease_key,
910 .new_lease_key = smb2_new_lease_key,
911 .calc_signature = smb2_calc_signature,
912 .is_read_op = smb2_is_read_op,
913 .set_oplock_level = smb2_set_oplock_level,
914 .create_lease_buf = smb2_create_lease_buf,
915 .parse_lease_buf = smb2_parse_lease_buf,
918 struct smb_version_operations smb21_operations = {
919 .compare_fids = smb2_compare_fids,
920 .setup_request = smb2_setup_request,
921 .setup_async_request = smb2_setup_async_request,
922 .check_receive = smb2_check_receive,
923 .add_credits = smb2_add_credits,
924 .set_credits = smb2_set_credits,
925 .get_credits_field = smb2_get_credits_field,
926 .get_credits = smb2_get_credits,
927 .get_next_mid = smb2_get_next_mid,
928 .read_data_offset = smb2_read_data_offset,
929 .read_data_length = smb2_read_data_length,
930 .map_error = map_smb2_to_linux_error,
931 .find_mid = smb2_find_mid,
932 .check_message = smb2_check_message,
933 .dump_detail = smb2_dump_detail,
934 .clear_stats = smb2_clear_stats,
935 .print_stats = smb2_print_stats,
936 .is_oplock_break = smb2_is_valid_oplock_break,
937 .downgrade_oplock = smb2_downgrade_oplock,
938 .need_neg = smb2_need_neg,
939 .negotiate = smb2_negotiate,
940 .negotiate_wsize = smb2_negotiate_wsize,
941 .negotiate_rsize = smb2_negotiate_rsize,
942 .sess_setup = SMB2_sess_setup,
943 .logoff = SMB2_logoff,
944 .tree_connect = SMB2_tcon,
945 .tree_disconnect = SMB2_tdis,
946 .is_path_accessible = smb2_is_path_accessible,
947 .can_echo = smb2_can_echo,
948 .echo = SMB2_echo,
949 .query_path_info = smb2_query_path_info,
950 .get_srv_inum = smb2_get_srv_inum,
951 .query_file_info = smb2_query_file_info,
952 .set_path_size = smb2_set_path_size,
953 .set_file_size = smb2_set_file_size,
954 .set_file_info = smb2_set_file_info,
955 .mkdir = smb2_mkdir,
956 .mkdir_setinfo = smb2_mkdir_setinfo,
957 .rmdir = smb2_rmdir,
958 .unlink = smb2_unlink,
959 .rename = smb2_rename_path,
960 .create_hardlink = smb2_create_hardlink,
961 .query_symlink = smb2_query_symlink,
962 .open = smb2_open_file,
963 .set_fid = smb2_set_fid,
964 .close = smb2_close_file,
965 .flush = smb2_flush_file,
966 .async_readv = smb2_async_readv,
967 .async_writev = smb2_async_writev,
968 .sync_read = smb2_sync_read,
969 .sync_write = smb2_sync_write,
970 .query_dir_first = smb2_query_dir_first,
971 .query_dir_next = smb2_query_dir_next,
972 .close_dir = smb2_close_dir,
973 .calc_smb_size = smb2_calc_size,
974 .is_status_pending = smb2_is_status_pending,
975 .oplock_response = smb2_oplock_response,
976 .queryfs = smb2_queryfs,
977 .mand_lock = smb2_mand_lock,
978 .mand_unlock_range = smb2_unlock_range,
979 .push_mand_locks = smb2_push_mandatory_locks,
980 .get_lease_key = smb2_get_lease_key,
981 .set_lease_key = smb2_set_lease_key,
982 .new_lease_key = smb2_new_lease_key,
983 .calc_signature = smb2_calc_signature,
984 .is_read_op = smb21_is_read_op,
985 .set_oplock_level = smb21_set_oplock_level,
986 .create_lease_buf = smb2_create_lease_buf,
987 .parse_lease_buf = smb2_parse_lease_buf,
990 struct smb_version_operations smb30_operations = {
991 .compare_fids = smb2_compare_fids,
992 .setup_request = smb2_setup_request,
993 .setup_async_request = smb2_setup_async_request,
994 .check_receive = smb2_check_receive,
995 .add_credits = smb2_add_credits,
996 .set_credits = smb2_set_credits,
997 .get_credits_field = smb2_get_credits_field,
998 .get_credits = smb2_get_credits,
999 .get_next_mid = smb2_get_next_mid,
1000 .read_data_offset = smb2_read_data_offset,
1001 .read_data_length = smb2_read_data_length,
1002 .map_error = map_smb2_to_linux_error,
1003 .find_mid = smb2_find_mid,
1004 .check_message = smb2_check_message,
1005 .dump_detail = smb2_dump_detail,
1006 .clear_stats = smb2_clear_stats,
1007 .print_stats = smb2_print_stats,
1008 .dump_share_caps = smb2_dump_share_caps,
1009 .is_oplock_break = smb2_is_valid_oplock_break,
1010 .downgrade_oplock = smb2_downgrade_oplock,
1011 .need_neg = smb2_need_neg,
1012 .negotiate = smb2_negotiate,
1013 .negotiate_wsize = smb2_negotiate_wsize,
1014 .negotiate_rsize = smb2_negotiate_rsize,
1015 .sess_setup = SMB2_sess_setup,
1016 .logoff = SMB2_logoff,
1017 .tree_connect = SMB2_tcon,
1018 .tree_disconnect = SMB2_tdis,
1019 .is_path_accessible = smb2_is_path_accessible,
1020 .can_echo = smb2_can_echo,
1021 .echo = SMB2_echo,
1022 .query_path_info = smb2_query_path_info,
1023 .get_srv_inum = smb2_get_srv_inum,
1024 .query_file_info = smb2_query_file_info,
1025 .set_path_size = smb2_set_path_size,
1026 .set_file_size = smb2_set_file_size,
1027 .set_file_info = smb2_set_file_info,
1028 .mkdir = smb2_mkdir,
1029 .mkdir_setinfo = smb2_mkdir_setinfo,
1030 .rmdir = smb2_rmdir,
1031 .unlink = smb2_unlink,
1032 .rename = smb2_rename_path,
1033 .create_hardlink = smb2_create_hardlink,
1034 .query_symlink = smb2_query_symlink,
1035 .open = smb2_open_file,
1036 .set_fid = smb2_set_fid,
1037 .close = smb2_close_file,
1038 .flush = smb2_flush_file,
1039 .async_readv = smb2_async_readv,
1040 .async_writev = smb2_async_writev,
1041 .sync_read = smb2_sync_read,
1042 .sync_write = smb2_sync_write,
1043 .query_dir_first = smb2_query_dir_first,
1044 .query_dir_next = smb2_query_dir_next,
1045 .close_dir = smb2_close_dir,
1046 .calc_smb_size = smb2_calc_size,
1047 .is_status_pending = smb2_is_status_pending,
1048 .oplock_response = smb2_oplock_response,
1049 .queryfs = smb2_queryfs,
1050 .mand_lock = smb2_mand_lock,
1051 .mand_unlock_range = smb2_unlock_range,
1052 .push_mand_locks = smb2_push_mandatory_locks,
1053 .get_lease_key = smb2_get_lease_key,
1054 .set_lease_key = smb2_set_lease_key,
1055 .new_lease_key = smb2_new_lease_key,
1056 .generate_signingkey = generate_smb3signingkey,
1057 .calc_signature = smb3_calc_signature,
1058 .is_read_op = smb21_is_read_op,
1059 .set_oplock_level = smb3_set_oplock_level,
1060 .create_lease_buf = smb3_create_lease_buf,
1061 .parse_lease_buf = smb3_parse_lease_buf,
1062 .validate_negotiate = smb3_validate_negotiate,
1065 struct smb_version_values smb20_values = {
1066 .version_string = SMB20_VERSION_STRING,
1067 .protocol_id = SMB20_PROT_ID,
1068 .req_capabilities = 0, /* MBZ */
1069 .large_lock_type = 0,
1070 .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
1071 .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
1072 .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
1073 .header_size = sizeof(struct smb2_hdr),
1074 .max_header_size = MAX_SMB2_HDR_SIZE,
1075 .read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
1076 .lock_cmd = SMB2_LOCK,
1077 .cap_unix = 0,
1078 .cap_nt_find = SMB2_NT_FIND,
1079 .cap_large_files = SMB2_LARGE_FILES,
1080 .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
1081 .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
1082 .create_lease_size = sizeof(struct create_lease),
1085 struct smb_version_values smb21_values = {
1086 .version_string = SMB21_VERSION_STRING,
1087 .protocol_id = SMB21_PROT_ID,
1088 .req_capabilities = 0, /* MBZ on negotiate req until SMB3 dialect */
1089 .large_lock_type = 0,
1090 .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
1091 .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
1092 .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
1093 .header_size = sizeof(struct smb2_hdr),
1094 .max_header_size = MAX_SMB2_HDR_SIZE,
1095 .read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
1096 .lock_cmd = SMB2_LOCK,
1097 .cap_unix = 0,
1098 .cap_nt_find = SMB2_NT_FIND,
1099 .cap_large_files = SMB2_LARGE_FILES,
1100 .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
1101 .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
1102 .create_lease_size = sizeof(struct create_lease),
1105 struct smb_version_values smb30_values = {
1106 .version_string = SMB30_VERSION_STRING,
1107 .protocol_id = SMB30_PROT_ID,
1108 .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU,
1109 .large_lock_type = 0,
1110 .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
1111 .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
1112 .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
1113 .header_size = sizeof(struct smb2_hdr),
1114 .max_header_size = MAX_SMB2_HDR_SIZE,
1115 .read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
1116 .lock_cmd = SMB2_LOCK,
1117 .cap_unix = 0,
1118 .cap_nt_find = SMB2_NT_FIND,
1119 .cap_large_files = SMB2_LARGE_FILES,
1120 .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
1121 .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
1122 .create_lease_size = sizeof(struct create_lease_v2),
1125 struct smb_version_values smb302_values = {
1126 .version_string = SMB302_VERSION_STRING,
1127 .protocol_id = SMB302_PROT_ID,
1128 .req_capabilities = SMB2_GLOBAL_CAP_DFS | SMB2_GLOBAL_CAP_LEASING | SMB2_GLOBAL_CAP_LARGE_MTU,
1129 .large_lock_type = 0,
1130 .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
1131 .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
1132 .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
1133 .header_size = sizeof(struct smb2_hdr),
1134 .max_header_size = MAX_SMB2_HDR_SIZE,
1135 .read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
1136 .lock_cmd = SMB2_LOCK,
1137 .cap_unix = 0,
1138 .cap_nt_find = SMB2_NT_FIND,
1139 .cap_large_files = SMB2_LARGE_FILES,
1140 .signing_enabled = SMB2_NEGOTIATE_SIGNING_ENABLED | SMB2_NEGOTIATE_SIGNING_REQUIRED,
1141 .signing_required = SMB2_NEGOTIATE_SIGNING_REQUIRED,
1142 .create_lease_size = sizeof(struct create_lease_v2),