.. | .. |
---|
22 | 22 | #include <linux/in.h> |
---|
23 | 23 | #include <linux/in6.h> |
---|
24 | 24 | #include <linux/slab.h> |
---|
| 25 | +#include <linux/scatterlist.h> |
---|
| 26 | +#include <linux/mm.h> |
---|
25 | 27 | #include <linux/mempool.h> |
---|
26 | 28 | #include <linux/workqueue.h> |
---|
27 | 29 | #include "cifs_fs_sb.h" |
---|
.. | .. |
---|
30 | 32 | #include <linux/scatterlist.h> |
---|
31 | 33 | #include <uapi/linux/cifs/cifs_mount.h> |
---|
32 | 34 | #include "smb2pdu.h" |
---|
| 35 | +#include "smb2glob.h" |
---|
33 | 36 | |
---|
34 | 37 | #define CIFS_MAGIC_NUMBER 0xFF534D42 /* the first four bytes of SMB PDUs */ |
---|
35 | 38 | |
---|
| 39 | +#define SMB_PATH_MAX 260 |
---|
36 | 40 | #define CIFS_PORT 445 |
---|
37 | 41 | #define RFC1001_PORT 139 |
---|
38 | 42 | |
---|
.. | .. |
---|
57 | 61 | * max attribute cache timeout (jiffies) - 2^30 |
---|
58 | 62 | */ |
---|
59 | 63 | #define CIFS_MAX_ACTIMEO (1 << 30) |
---|
| 64 | + |
---|
| 65 | +/* |
---|
| 66 | + * Max persistent and resilient handle timeout (milliseconds). |
---|
| 67 | + * Windows durable max was 960000 (16 minutes) |
---|
| 68 | + */ |
---|
| 69 | +#define SMB3_MAX_HANDLE_TIMEOUT 960000 |
---|
60 | 70 | |
---|
61 | 71 | /* |
---|
62 | 72 | * MAX_REQ is the maximum number of requests that WE will send |
---|
.. | .. |
---|
188 | 198 | unsigned int rq_tailsz; /* length of last page */ |
---|
189 | 199 | }; |
---|
190 | 200 | |
---|
191 | | -enum smb_version { |
---|
192 | | - Smb_1 = 1, |
---|
193 | | - Smb_20, |
---|
194 | | - Smb_21, |
---|
195 | | - Smb_30, |
---|
196 | | - Smb_302, |
---|
197 | | - Smb_311, |
---|
198 | | - Smb_3any, |
---|
199 | | - Smb_default, |
---|
200 | | - Smb_version_err |
---|
201 | | -}; |
---|
202 | | - |
---|
203 | 201 | struct mid_q_entry; |
---|
204 | 202 | struct TCP_Server_Info; |
---|
205 | 203 | struct cifsFileInfo; |
---|
.. | .. |
---|
215 | 213 | struct cifs_search_info; |
---|
216 | 214 | struct cifsInodeInfo; |
---|
217 | 215 | struct cifs_open_parms; |
---|
| 216 | +struct cifs_credits; |
---|
218 | 217 | |
---|
219 | 218 | struct smb_version_operations { |
---|
220 | 219 | int (*send_cancel)(struct TCP_Server_Info *, struct smb_rqst *, |
---|
.. | .. |
---|
222 | 221 | bool (*compare_fids)(struct cifsFileInfo *, struct cifsFileInfo *); |
---|
223 | 222 | /* setup request: allocate mid, sign message */ |
---|
224 | 223 | struct mid_q_entry *(*setup_request)(struct cifs_ses *, |
---|
225 | | - struct smb_rqst *); |
---|
| 224 | + struct TCP_Server_Info *, |
---|
| 225 | + struct smb_rqst *); |
---|
226 | 226 | /* setup async request: allocate mid, sign message */ |
---|
227 | 227 | struct mid_q_entry *(*setup_async_request)(struct TCP_Server_Info *, |
---|
228 | 228 | struct smb_rqst *); |
---|
229 | 229 | /* check response: verify signature, map error */ |
---|
230 | 230 | int (*check_receive)(struct mid_q_entry *, struct TCP_Server_Info *, |
---|
231 | 231 | bool); |
---|
232 | | - void (*add_credits)(struct TCP_Server_Info *, const unsigned int, |
---|
233 | | - const int); |
---|
| 232 | + void (*add_credits)(struct TCP_Server_Info *server, |
---|
| 233 | + const struct cifs_credits *credits, |
---|
| 234 | + const int optype); |
---|
234 | 235 | void (*set_credits)(struct TCP_Server_Info *, const int); |
---|
235 | 236 | int * (*get_credits_field)(struct TCP_Server_Info *, const int); |
---|
236 | 237 | unsigned int (*get_credits)(struct mid_q_entry *); |
---|
.. | .. |
---|
258 | 259 | /* verify the message */ |
---|
259 | 260 | int (*check_message)(char *, unsigned int, struct TCP_Server_Info *); |
---|
260 | 261 | bool (*is_oplock_break)(char *, struct TCP_Server_Info *); |
---|
261 | | - int (*handle_cancelled_mid)(char *, struct TCP_Server_Info *); |
---|
| 262 | + int (*handle_cancelled_mid)(struct mid_q_entry *, struct TCP_Server_Info *); |
---|
262 | 263 | void (*downgrade_oplock)(struct TCP_Server_Info *server, |
---|
263 | 264 | struct cifsInodeInfo *cinode, __u32 oplock, |
---|
264 | 265 | unsigned int epoch, bool *purge_cache); |
---|
.. | .. |
---|
288 | 289 | const char *, struct dfs_info3_param **, |
---|
289 | 290 | unsigned int *, const struct nls_table *, int); |
---|
290 | 291 | /* informational QFS call */ |
---|
291 | | - void (*qfs_tcon)(const unsigned int, struct cifs_tcon *); |
---|
| 292 | + void (*qfs_tcon)(const unsigned int, struct cifs_tcon *, |
---|
| 293 | + struct cifs_sb_info *); |
---|
292 | 294 | /* check if a path is accessible or not */ |
---|
293 | 295 | int (*is_path_accessible)(const unsigned int, struct cifs_tcon *, |
---|
294 | 296 | struct cifs_sb_info *, const char *); |
---|
.. | .. |
---|
299 | 301 | /* query file data from the server */ |
---|
300 | 302 | int (*query_file_info)(const unsigned int, struct cifs_tcon *, |
---|
301 | 303 | struct cifs_fid *, FILE_ALL_INFO *); |
---|
| 304 | + /* query reparse tag from srv to determine which type of special file */ |
---|
| 305 | + int (*query_reparse_tag)(const unsigned int xid, struct cifs_tcon *tcon, |
---|
| 306 | + struct cifs_sb_info *cifs_sb, const char *path, |
---|
| 307 | + __u32 *reparse_tag); |
---|
302 | 308 | /* get server index number */ |
---|
303 | 309 | int (*get_srv_inum)(const unsigned int, struct cifs_tcon *, |
---|
304 | 310 | struct cifs_sb_info *, const char *, |
---|
.. | .. |
---|
323 | 329 | umode_t mode, struct cifs_tcon *tcon, |
---|
324 | 330 | const char *full_path, |
---|
325 | 331 | struct cifs_sb_info *cifs_sb); |
---|
326 | | - int (*mkdir)(const unsigned int, struct cifs_tcon *, const char *, |
---|
327 | | - struct cifs_sb_info *); |
---|
| 332 | + int (*mkdir)(const unsigned int xid, struct inode *inode, umode_t mode, |
---|
| 333 | + struct cifs_tcon *tcon, const char *name, |
---|
| 334 | + struct cifs_sb_info *sb); |
---|
328 | 335 | /* set info on created directory */ |
---|
329 | 336 | void (*mkdir_setinfo)(struct inode *, const char *, |
---|
330 | 337 | struct cifs_sb_info *, struct cifs_tcon *, |
---|
.. | .. |
---|
347 | 354 | struct cifs_sb_info *); |
---|
348 | 355 | /* query symlink target */ |
---|
349 | 356 | int (*query_symlink)(const unsigned int, struct cifs_tcon *, |
---|
350 | | - const char *, char **, struct cifs_sb_info *); |
---|
| 357 | + struct cifs_sb_info *, const char *, |
---|
| 358 | + char **, bool); |
---|
351 | 359 | /* open a file for non-posix mounts */ |
---|
352 | 360 | int (*open)(const unsigned int, struct cifs_open_parms *, |
---|
353 | 361 | __u32 *, FILE_ALL_INFO *); |
---|
.. | .. |
---|
356 | 364 | /* close a file */ |
---|
357 | 365 | void (*close)(const unsigned int, struct cifs_tcon *, |
---|
358 | 366 | struct cifs_fid *); |
---|
| 367 | + /* close a file, returning file attributes and timestamps */ |
---|
| 368 | + void (*close_getattr)(const unsigned int xid, struct cifs_tcon *tcon, |
---|
| 369 | + struct cifsFileInfo *pfile_info); |
---|
359 | 370 | /* send a flush request to the server */ |
---|
360 | 371 | int (*flush)(const unsigned int, struct cifs_tcon *, struct cifs_fid *); |
---|
361 | 372 | /* async read from the server */ |
---|
.. | .. |
---|
385 | 396 | struct cifs_fid *); |
---|
386 | 397 | /* calculate a size of SMB message */ |
---|
387 | 398 | unsigned int (*calc_smb_size)(void *buf, struct TCP_Server_Info *ptcpi); |
---|
388 | | - /* check for STATUS_PENDING and process it in a positive case */ |
---|
389 | | - bool (*is_status_pending)(char *, struct TCP_Server_Info *, int); |
---|
| 399 | + /* check for STATUS_PENDING and process the response if yes */ |
---|
| 400 | + bool (*is_status_pending)(char *buf, struct TCP_Server_Info *server); |
---|
390 | 401 | /* check for STATUS_NETWORK_SESSION_EXPIRED */ |
---|
391 | 402 | bool (*is_session_expired)(char *); |
---|
392 | 403 | /* send oplock break response */ |
---|
.. | .. |
---|
394 | 405 | struct cifsInodeInfo *); |
---|
395 | 406 | /* query remote filesystem */ |
---|
396 | 407 | int (*queryfs)(const unsigned int, struct cifs_tcon *, |
---|
397 | | - struct kstatfs *); |
---|
| 408 | + struct cifs_sb_info *, struct kstatfs *); |
---|
398 | 409 | /* send mandatory brlock to the server */ |
---|
399 | 410 | int (*mand_lock)(const unsigned int, struct cifsFileInfo *, __u64, |
---|
400 | 411 | __u64, __u32, int, int, bool); |
---|
.. | .. |
---|
410 | 421 | /* generate new lease key */ |
---|
411 | 422 | void (*new_lease_key)(struct cifs_fid *); |
---|
412 | 423 | int (*generate_signingkey)(struct cifs_ses *); |
---|
413 | | - int (*calc_signature)(struct smb_rqst *, struct TCP_Server_Info *); |
---|
| 424 | + int (*calc_signature)(struct smb_rqst *, struct TCP_Server_Info *, |
---|
| 425 | + bool allocate_crypto); |
---|
414 | 426 | int (*set_integrity)(const unsigned int, struct cifs_tcon *tcon, |
---|
415 | 427 | struct cifsFileInfo *src_file); |
---|
416 | 428 | int (*enum_snapshots)(const unsigned int xid, struct cifs_tcon *tcon, |
---|
417 | 429 | struct cifsFileInfo *src_file, void __user *); |
---|
| 430 | + int (*notify)(const unsigned int xid, struct file *pfile, |
---|
| 431 | + void __user *pbuf); |
---|
418 | 432 | int (*query_mf_symlink)(unsigned int, struct cifs_tcon *, |
---|
419 | 433 | struct cifs_sb_info *, const unsigned char *, |
---|
420 | 434 | char *, unsigned int *); |
---|
.. | .. |
---|
454 | 468 | unsigned int (*wp_retry_size)(struct inode *); |
---|
455 | 469 | /* get mtu credits */ |
---|
456 | 470 | int (*wait_mtu_credits)(struct TCP_Server_Info *, unsigned int, |
---|
457 | | - unsigned int *, unsigned int *); |
---|
| 471 | + unsigned int *, struct cifs_credits *); |
---|
| 472 | + /* adjust previously taken mtu credits to request size */ |
---|
| 473 | + int (*adjust_credits)(struct TCP_Server_Info *server, |
---|
| 474 | + struct cifs_credits *credits, |
---|
| 475 | + const unsigned int payload_size); |
---|
458 | 476 | /* check if we need to issue closedir */ |
---|
459 | 477 | bool (*dir_needs_close)(struct cifsFileInfo *); |
---|
460 | 478 | long (*fallocate)(struct file *, struct cifs_tcon *, int, loff_t, |
---|
.. | .. |
---|
468 | 486 | enum securityEnum (*select_sectype)(struct TCP_Server_Info *, |
---|
469 | 487 | enum securityEnum); |
---|
470 | 488 | int (*next_header)(char *); |
---|
| 489 | + /* ioctl passthrough for query_info */ |
---|
| 490 | + int (*ioctl_query_info)(const unsigned int xid, |
---|
| 491 | + struct cifs_tcon *tcon, |
---|
| 492 | + struct cifs_sb_info *cifs_sb, |
---|
| 493 | + __le16 *path, int is_dir, |
---|
| 494 | + unsigned long p); |
---|
| 495 | + /* make unix special files (block, char, fifo, socket) */ |
---|
| 496 | + int (*make_node)(unsigned int xid, |
---|
| 497 | + struct inode *inode, |
---|
| 498 | + struct dentry *dentry, |
---|
| 499 | + struct cifs_tcon *tcon, |
---|
| 500 | + char *full_path, |
---|
| 501 | + umode_t mode, |
---|
| 502 | + dev_t device_number); |
---|
| 503 | + /* version specific fiemap implementation */ |
---|
| 504 | + int (*fiemap)(struct cifs_tcon *tcon, struct cifsFileInfo *, |
---|
| 505 | + struct fiemap_extent_info *, u64, u64); |
---|
| 506 | + /* version specific llseek implementation */ |
---|
| 507 | + loff_t (*llseek)(struct file *, struct cifs_tcon *, loff_t, int); |
---|
| 508 | + /* Check for STATUS_IO_TIMEOUT */ |
---|
| 509 | + bool (*is_status_io_timeout)(char *buf); |
---|
471 | 510 | }; |
---|
472 | 511 | |
---|
473 | 512 | struct smb_version_values { |
---|
.. | .. |
---|
511 | 550 | umode_t dir_mode; |
---|
512 | 551 | enum securityEnum sectype; /* sectype requested via mnt opts */ |
---|
513 | 552 | bool sign; /* was signing requested via mnt opts? */ |
---|
| 553 | + bool ignore_signature:1; |
---|
514 | 554 | bool retry:1; |
---|
515 | 555 | bool intr:1; |
---|
516 | 556 | bool setuids:1; |
---|
.. | .. |
---|
519 | 559 | bool override_gid:1; |
---|
520 | 560 | bool dynperm:1; |
---|
521 | 561 | bool noperm:1; |
---|
| 562 | + bool nodelete:1; |
---|
| 563 | + bool mode_ace:1; |
---|
522 | 564 | bool no_psx_acl:1; /* set if posix acl support should be disabled */ |
---|
523 | 565 | bool cifs_acl:1; |
---|
524 | 566 | bool backupuid_specified; /* mount option backupuid is specified */ |
---|
.. | .. |
---|
527 | 569 | bool server_ino:1; /* use inode numbers from server ie UniqueId */ |
---|
528 | 570 | bool direct_io:1; |
---|
529 | 571 | bool strict_io:1; /* strict cache behavior */ |
---|
| 572 | + bool cache_ro:1; |
---|
| 573 | + bool cache_rw:1; |
---|
530 | 574 | bool remap:1; /* set to remap seven reserved chars in filenames */ |
---|
531 | 575 | bool sfu_remap:1; /* remap seven reserved chars ala SFU */ |
---|
532 | 576 | bool posix_paths:1; /* unset to not ask for posix pathnames. */ |
---|
.. | .. |
---|
555 | 599 | bool resilient:1; /* noresilient not required since not fored for CA */ |
---|
556 | 600 | bool domainauto:1; |
---|
557 | 601 | bool rdma:1; |
---|
| 602 | + bool multichannel:1; |
---|
| 603 | + bool use_client_guid:1; |
---|
| 604 | + /* reuse existing guid for multichannel */ |
---|
| 605 | + u8 client_guid[SMB2_CLIENT_GUID_SIZE]; |
---|
| 606 | + unsigned int bsize; |
---|
558 | 607 | unsigned int rsize; |
---|
559 | 608 | unsigned int wsize; |
---|
| 609 | + unsigned int min_offload; |
---|
560 | 610 | bool sockopt_tcp_nodelay:1; |
---|
561 | 611 | unsigned long actimeo; /* attribute cache timeout (jiffies) */ |
---|
562 | 612 | struct smb_version_operations *ops; |
---|
.. | .. |
---|
567 | 617 | struct nls_table *local_nls; |
---|
568 | 618 | unsigned int echo_interval; /* echo interval in secs */ |
---|
569 | 619 | __u64 snapshot_time; /* needed for timewarp tokens */ |
---|
| 620 | + __u32 handle_timeout; /* persistent and durable handle timeout in ms */ |
---|
570 | 621 | unsigned int max_credits; /* smb3 max_credits 10 < credits < 60000 */ |
---|
| 622 | + unsigned int max_channels; |
---|
| 623 | + __u16 compression; /* compression algorithm 0xFFFF default 0=disabled */ |
---|
| 624 | + bool rootfs:1; /* if it's a SMB root file system */ |
---|
571 | 625 | }; |
---|
572 | 626 | |
---|
| 627 | +/** |
---|
| 628 | + * CIFS superblock mount flags (mnt_cifs_flags) to consider when |
---|
| 629 | + * trying to reuse existing superblock for a new mount |
---|
| 630 | + */ |
---|
573 | 631 | #define CIFS_MOUNT_MASK (CIFS_MOUNT_NO_PERM | CIFS_MOUNT_SET_UID | \ |
---|
574 | 632 | CIFS_MOUNT_SERVER_INUM | CIFS_MOUNT_DIRECT_IO | \ |
---|
575 | 633 | CIFS_MOUNT_NO_XATTR | CIFS_MOUNT_MAP_SPECIAL_CHR | \ |
---|
.. | .. |
---|
580 | 638 | CIFS_MOUNT_NOPOSIXBRL | CIFS_MOUNT_NOSSYNC | \ |
---|
581 | 639 | CIFS_MOUNT_FSCACHE | CIFS_MOUNT_MF_SYMLINKS | \ |
---|
582 | 640 | CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_STRICT_IO | \ |
---|
583 | | - CIFS_MOUNT_CIFS_BACKUPUID | CIFS_MOUNT_CIFS_BACKUPGID) |
---|
| 641 | + CIFS_MOUNT_CIFS_BACKUPUID | CIFS_MOUNT_CIFS_BACKUPGID | \ |
---|
| 642 | + CIFS_MOUNT_UID_FROM_ACL | CIFS_MOUNT_NO_HANDLE_CACHE | \ |
---|
| 643 | + CIFS_MOUNT_NO_DFS | CIFS_MOUNT_MODE_FROM_SID | \ |
---|
| 644 | + CIFS_MOUNT_RO_CACHE | CIFS_MOUNT_RW_CACHE) |
---|
584 | 645 | |
---|
| 646 | +/** |
---|
| 647 | + * Generic VFS superblock mount flags (s_flags) to consider when |
---|
| 648 | + * trying to reuse existing superblock for a new mount |
---|
| 649 | + */ |
---|
585 | 650 | #define CIFS_MS_MASK (SB_RDONLY | SB_MANDLOCK | SB_NOEXEC | SB_NOSUID | \ |
---|
586 | 651 | SB_NODEV | SB_SYNCHRONOUS) |
---|
587 | 652 | |
---|
.. | .. |
---|
628 | 693 | unsigned int credits; /* send no more requests at once */ |
---|
629 | 694 | unsigned int max_credits; /* can override large 32000 default at mnt */ |
---|
630 | 695 | unsigned int in_flight; /* number of requests on the wire to server */ |
---|
| 696 | + unsigned int max_in_flight; /* max number of requests that were on wire */ |
---|
631 | 697 | spinlock_t req_lock; /* protect the two values above */ |
---|
632 | 698 | struct mutex srv_mutex; |
---|
633 | 699 | struct task_struct *tsk; |
---|
634 | 700 | char server_GUID[16]; |
---|
635 | 701 | __u16 sec_mode; |
---|
636 | 702 | bool sign; /* is signing enabled on this connection? */ |
---|
| 703 | + bool ignore_signature:1; /* skip validation of signatures in SMB2/3 rsp */ |
---|
637 | 704 | bool session_estab; /* mark when very first sess is established */ |
---|
638 | 705 | int echo_credits; /* echo reserved slots */ |
---|
639 | 706 | int oplock_credits; /* oplock break reserved slots */ |
---|
.. | .. |
---|
658 | 725 | /* 16th byte of RFC1001 workstation name is always null */ |
---|
659 | 726 | char workstation_RFC1001_name[RFC1001_NAME_LEN_WITH_NULL]; |
---|
660 | 727 | __u32 sequence_number; /* for signing, protected by srv_mutex */ |
---|
| 728 | + __u32 reconnect_instance; /* incremented on each reconnect */ |
---|
661 | 729 | struct session_key session_key; |
---|
662 | 730 | unsigned long lstrp; /* when we got last response from this server */ |
---|
663 | 731 | struct cifs_secmech secmech; /* crypto sec mech functs, descriptors */ |
---|
.. | .. |
---|
681 | 749 | /* Total size of this PDU. Only valid from cifs_demultiplex_thread */ |
---|
682 | 750 | unsigned int pdu_size; |
---|
683 | 751 | unsigned int total_read; /* total amount of data read in this pass */ |
---|
| 752 | + atomic_t in_send; /* requests trying to send */ |
---|
| 753 | + atomic_t num_waiters; /* blocked waiting to get in sendrecv */ |
---|
684 | 754 | #ifdef CONFIG_CIFS_FSCACHE |
---|
685 | 755 | struct fscache_cookie *fscache; /* client index cache cookie */ |
---|
686 | 756 | #endif |
---|
687 | 757 | #ifdef CONFIG_CIFS_STATS2 |
---|
688 | | - atomic_t in_send; /* requests trying to send */ |
---|
689 | | - atomic_t num_waiters; /* blocked waiting to get in sendrecv */ |
---|
| 758 | + atomic_t num_cmds[NUMBER_OF_SMB2_COMMANDS]; /* total requests by cmd */ |
---|
690 | 759 | atomic_t smb2slowcmd[NUMBER_OF_SMB2_COMMANDS]; /* count resps > 1 sec */ |
---|
| 760 | + __u64 time_per_cmd[NUMBER_OF_SMB2_COMMANDS]; /* total time per cmd */ |
---|
| 761 | + __u32 slowest_cmd[NUMBER_OF_SMB2_COMMANDS]; |
---|
| 762 | + __u32 fastest_cmd[NUMBER_OF_SMB2_COMMANDS]; |
---|
691 | 763 | #endif /* STATS2 */ |
---|
692 | 764 | unsigned int max_read; |
---|
693 | 765 | unsigned int max_write; |
---|
| 766 | + unsigned int min_offload; |
---|
| 767 | + __le16 compress_algorithm; |
---|
694 | 768 | __le16 cipher_type; |
---|
695 | 769 | /* save initital negprot hash */ |
---|
696 | 770 | __u8 preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE]; |
---|
.. | .. |
---|
698 | 772 | struct delayed_work reconnect; /* reconnect workqueue job */ |
---|
699 | 773 | struct mutex reconnect_mutex; /* prevent simultaneous reconnects */ |
---|
700 | 774 | unsigned long echo_interval; |
---|
| 775 | + |
---|
| 776 | + /* |
---|
| 777 | + * Number of targets available for reconnect. The more targets |
---|
| 778 | + * the more tasks have to wait to let the demultiplex thread |
---|
| 779 | + * reconnect. |
---|
| 780 | + */ |
---|
| 781 | + int nr_targets; |
---|
| 782 | + bool noblockcnt; /* use non-blocking connect() */ |
---|
| 783 | + bool is_channel; /* if a session channel */ |
---|
| 784 | +}; |
---|
| 785 | + |
---|
| 786 | +struct cifs_credits { |
---|
| 787 | + unsigned int value; |
---|
| 788 | + unsigned int instance; |
---|
701 | 789 | }; |
---|
702 | 790 | |
---|
703 | 791 | static inline unsigned int |
---|
.. | .. |
---|
711 | 799 | } |
---|
712 | 800 | |
---|
713 | 801 | static inline bool |
---|
714 | | -has_credits(struct TCP_Server_Info *server, int *credits) |
---|
| 802 | +has_credits(struct TCP_Server_Info *server, int *credits, int num_credits) |
---|
715 | 803 | { |
---|
716 | 804 | int num; |
---|
717 | 805 | spin_lock(&server->req_lock); |
---|
718 | 806 | num = *credits; |
---|
719 | 807 | spin_unlock(&server->req_lock); |
---|
720 | | - return num > 0; |
---|
| 808 | + return num >= num_credits; |
---|
721 | 809 | } |
---|
722 | 810 | |
---|
723 | 811 | static inline void |
---|
724 | | -add_credits(struct TCP_Server_Info *server, const unsigned int add, |
---|
| 812 | +add_credits(struct TCP_Server_Info *server, const struct cifs_credits *credits, |
---|
725 | 813 | const int optype) |
---|
726 | 814 | { |
---|
727 | | - server->ops->add_credits(server, add, optype); |
---|
| 815 | + server->ops->add_credits(server, credits, optype); |
---|
728 | 816 | } |
---|
729 | 817 | |
---|
730 | 818 | static inline void |
---|
731 | | -add_credits_and_wake_if(struct TCP_Server_Info *server, const unsigned int add, |
---|
732 | | - const int optype) |
---|
| 819 | +add_credits_and_wake_if(struct TCP_Server_Info *server, |
---|
| 820 | + const struct cifs_credits *credits, const int optype) |
---|
733 | 821 | { |
---|
734 | | - if (add) { |
---|
735 | | - server->ops->add_credits(server, add, optype); |
---|
| 822 | + if (credits->value) { |
---|
| 823 | + server->ops->add_credits(server, credits, optype); |
---|
736 | 824 | wake_up(&server->request_q); |
---|
737 | 825 | } |
---|
738 | 826 | } |
---|
.. | .. |
---|
741 | 829 | set_credits(struct TCP_Server_Info *server, const int val) |
---|
742 | 830 | { |
---|
743 | 831 | server->ops->set_credits(server, val); |
---|
| 832 | +} |
---|
| 833 | + |
---|
| 834 | +static inline int |
---|
| 835 | +adjust_credits(struct TCP_Server_Info *server, struct cifs_credits *credits, |
---|
| 836 | + const unsigned int payload_size) |
---|
| 837 | +{ |
---|
| 838 | + return server->ops->adjust_credits ? |
---|
| 839 | + server->ops->adjust_credits(server, credits, payload_size) : 0; |
---|
744 | 840 | } |
---|
745 | 841 | |
---|
746 | 842 | static inline __le64 |
---|
.. | .. |
---|
818 | 914 | * a single wsize request with a single call. |
---|
819 | 915 | */ |
---|
820 | 916 | #define CIFS_DEFAULT_IOSIZE (1024 * 1024) |
---|
| 917 | +#define SMB3_DEFAULT_IOSIZE (4 * 1024 * 1024) |
---|
821 | 918 | |
---|
822 | 919 | /* |
---|
823 | 920 | * Windows only supports a max of 60kb reads and 65535 byte writes. Default to |
---|
.. | .. |
---|
828 | 925 | * |
---|
829 | 926 | * Citation: |
---|
830 | 927 | * |
---|
831 | | - * http://blogs.msdn.com/b/openspecification/archive/2009/04/10/smb-maximum-transmit-buffer-size-and-performance-tuning.aspx |
---|
| 928 | + * https://blogs.msdn.com/b/openspecification/archive/2009/04/10/smb-maximum-transmit-buffer-size-and-performance-tuning.aspx |
---|
832 | 929 | */ |
---|
833 | 930 | #define CIFS_DEFAULT_NON_POSIX_RSIZE (60 * 1024) |
---|
834 | 931 | #define CIFS_DEFAULT_NON_POSIX_WSIZE (65536) |
---|
.. | .. |
---|
870 | 967 | struct sockaddr_storage sockaddr; |
---|
871 | 968 | }; |
---|
872 | 969 | |
---|
| 970 | +struct cifs_chan { |
---|
| 971 | + struct TCP_Server_Info *server; |
---|
| 972 | + __u8 signkey[SMB3_SIGN_KEY_SIZE]; |
---|
| 973 | +}; |
---|
| 974 | + |
---|
873 | 975 | /* |
---|
874 | 976 | * Session structure. One of these for each uid session with a particular host |
---|
875 | 977 | */ |
---|
.. | .. |
---|
880 | 982 | struct mutex session_mutex; |
---|
881 | 983 | struct TCP_Server_Info *server; /* pointer to server info */ |
---|
882 | 984 | int ses_count; /* reference counter */ |
---|
883 | | - enum statusEnum status; |
---|
| 985 | + enum statusEnum status; /* updates protected by GlobalMid_Lock */ |
---|
884 | 986 | unsigned overrideSecFlg; /* if non-zero override global sec flags */ |
---|
885 | 987 | char *serverOS; /* name of operating system underlying server */ |
---|
886 | 988 | char *serverNOS; /* name of network operating system of server */ |
---|
.. | .. |
---|
900 | 1002 | bool sign; /* is signing required? */ |
---|
901 | 1003 | bool need_reconnect:1; /* connection reset, uid now invalid */ |
---|
902 | 1004 | bool domainAuto:1; |
---|
| 1005 | + bool binding:1; /* are we binding the session? */ |
---|
903 | 1006 | __u16 session_flags; |
---|
904 | 1007 | __u8 smb3signingkey[SMB3_SIGN_KEY_SIZE]; |
---|
905 | | - __u8 smb3encryptionkey[SMB3_SIGN_KEY_SIZE]; |
---|
906 | | - __u8 smb3decryptionkey[SMB3_SIGN_KEY_SIZE]; |
---|
| 1008 | + __u8 smb3encryptionkey[SMB3_ENC_DEC_KEY_SIZE]; |
---|
| 1009 | + __u8 smb3decryptionkey[SMB3_ENC_DEC_KEY_SIZE]; |
---|
907 | 1010 | __u8 preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE]; |
---|
| 1011 | + |
---|
| 1012 | + __u8 binding_preauth_sha_hash[SMB2_PREAUTH_HASH_SIZE]; |
---|
908 | 1013 | |
---|
909 | 1014 | /* |
---|
910 | 1015 | * Network interfaces available on the server this session is |
---|
.. | .. |
---|
919 | 1024 | struct cifs_server_iface *iface_list; |
---|
920 | 1025 | size_t iface_count; |
---|
921 | 1026 | unsigned long iface_last_update; /* jiffies */ |
---|
| 1027 | + |
---|
| 1028 | +#define CIFS_MAX_CHANNELS 16 |
---|
| 1029 | + struct cifs_chan chans[CIFS_MAX_CHANNELS]; |
---|
| 1030 | + struct cifs_chan *binding_chan; |
---|
| 1031 | + size_t chan_count; |
---|
| 1032 | + size_t chan_max; |
---|
| 1033 | + atomic_t chan_seq; /* round robin state */ |
---|
922 | 1034 | }; |
---|
| 1035 | + |
---|
| 1036 | +/* |
---|
| 1037 | + * When binding a new channel, we need to access the channel which isn't fully |
---|
| 1038 | + * established yet. |
---|
| 1039 | + */ |
---|
| 1040 | + |
---|
| 1041 | +static inline |
---|
| 1042 | +struct cifs_chan *cifs_ses_binding_channel(struct cifs_ses *ses) |
---|
| 1043 | +{ |
---|
| 1044 | + if (ses->binding) |
---|
| 1045 | + return ses->binding_chan; |
---|
| 1046 | + else |
---|
| 1047 | + return NULL; |
---|
| 1048 | +} |
---|
| 1049 | + |
---|
| 1050 | +/* |
---|
| 1051 | + * Returns the server pointer of the session. When binding a new |
---|
| 1052 | + * channel this returns the last channel which isn't fully established |
---|
| 1053 | + * yet. |
---|
| 1054 | + * |
---|
| 1055 | + * This function should be use for negprot/sess.setup codepaths. For |
---|
| 1056 | + * the other requests see cifs_pick_channel(). |
---|
| 1057 | + */ |
---|
| 1058 | +static inline |
---|
| 1059 | +struct TCP_Server_Info *cifs_ses_server(struct cifs_ses *ses) |
---|
| 1060 | +{ |
---|
| 1061 | + if (ses->binding) |
---|
| 1062 | + return ses->binding_chan->server; |
---|
| 1063 | + else |
---|
| 1064 | + return ses->server; |
---|
| 1065 | +} |
---|
923 | 1066 | |
---|
924 | 1067 | static inline bool |
---|
925 | 1068 | cap_unix(struct cifs_ses *ses) |
---|
.. | .. |
---|
929 | 1072 | |
---|
930 | 1073 | struct cached_fid { |
---|
931 | 1074 | bool is_valid:1; /* Do we have a useable root fid */ |
---|
| 1075 | + bool file_all_info_is_valid:1; |
---|
| 1076 | + bool has_lease:1; |
---|
932 | 1077 | struct kref refcount; |
---|
933 | 1078 | struct cifs_fid *fid; |
---|
934 | 1079 | struct mutex fid_mutex; |
---|
935 | 1080 | struct cifs_tcon *tcon; |
---|
936 | 1081 | struct work_struct lease_break; |
---|
| 1082 | + struct smb2_file_all_info file_all_info; |
---|
937 | 1083 | }; |
---|
938 | 1084 | |
---|
939 | 1085 | /* |
---|
.. | .. |
---|
944 | 1090 | struct list_head tcon_list; |
---|
945 | 1091 | int tc_count; |
---|
946 | 1092 | struct list_head rlist; /* reconnect list */ |
---|
| 1093 | + atomic_t num_local_opens; /* num of all opens including disconnected */ |
---|
| 1094 | + atomic_t num_remote_opens; /* num of all network opens on server */ |
---|
947 | 1095 | struct list_head openFileList; |
---|
948 | 1096 | spinlock_t open_file_lock; /* protects list above */ |
---|
949 | 1097 | struct cifs_ses *ses; /* pointer to session associated with */ |
---|
.. | .. |
---|
995 | 1143 | bool retry:1; |
---|
996 | 1144 | bool nocase:1; |
---|
997 | 1145 | bool nohandlecache:1; /* if strange server resource prob can turn off */ |
---|
| 1146 | + bool nodelete:1; |
---|
998 | 1147 | bool seal:1; /* transport encryption for this mounted share */ |
---|
999 | 1148 | bool unix_ext:1; /* if false disable Linux extensions to CIFS protocol |
---|
1000 | 1149 | for this mount even if server would support */ |
---|
.. | .. |
---|
1013 | 1162 | __u32 vol_serial_number; |
---|
1014 | 1163 | __le64 vol_create_time; |
---|
1015 | 1164 | __u64 snapshot_time; /* for timewarp tokens - timestamp of snapshot */ |
---|
| 1165 | + __u32 handle_timeout; /* persistent and durable handle timeout in ms */ |
---|
1016 | 1166 | __u32 ss_flags; /* sector size flags */ |
---|
1017 | 1167 | __u32 perf_sector_size; /* best sector size for perf */ |
---|
1018 | 1168 | __u32 max_chunks; |
---|
.. | .. |
---|
1025 | 1175 | struct list_head pending_opens; /* list of incomplete opens */ |
---|
1026 | 1176 | struct cached_fid crfid; /* Cached root fid */ |
---|
1027 | 1177 | /* BB add field for back pointer to sb struct(s)? */ |
---|
| 1178 | +#ifdef CONFIG_CIFS_DFS_UPCALL |
---|
| 1179 | + char *dfs_path; |
---|
| 1180 | + int remap:2; |
---|
| 1181 | + struct list_head ulist; /* cache update list */ |
---|
| 1182 | +#endif |
---|
1028 | 1183 | }; |
---|
1029 | 1184 | |
---|
1030 | 1185 | /* |
---|
.. | .. |
---|
1093 | 1248 | __u64 offset; |
---|
1094 | 1249 | __u64 length; |
---|
1095 | 1250 | __u32 pid; |
---|
1096 | | - __u32 type; |
---|
| 1251 | + __u16 type; |
---|
| 1252 | + __u16 flags; |
---|
1097 | 1253 | }; |
---|
1098 | 1254 | |
---|
1099 | 1255 | /* |
---|
.. | .. |
---|
1115 | 1271 | bool smallBuf:1; /* so we know which buf_release function to call */ |
---|
1116 | 1272 | }; |
---|
1117 | 1273 | |
---|
| 1274 | +#define ACL_NO_MODE ((umode_t)(-1)) |
---|
1118 | 1275 | struct cifs_open_parms { |
---|
1119 | 1276 | struct cifs_tcon *tcon; |
---|
1120 | 1277 | struct cifs_sb_info *cifs_sb; |
---|
.. | .. |
---|
1133 | 1290 | __u64 volatile_fid; /* volatile file id for smb2 */ |
---|
1134 | 1291 | __u8 lease_key[SMB2_LEASE_KEY_SIZE]; /* lease key for smb2 */ |
---|
1135 | 1292 | __u8 create_guid[16]; |
---|
| 1293 | + __u32 access; |
---|
1136 | 1294 | struct cifs_pending_open *pending_open; |
---|
1137 | 1295 | unsigned int epoch; |
---|
| 1296 | +#ifdef CONFIG_CIFS_DEBUG2 |
---|
| 1297 | + __u64 mid; |
---|
| 1298 | +#endif /* CIFS_DEBUG2 */ |
---|
1138 | 1299 | bool purge_cache; |
---|
1139 | 1300 | }; |
---|
1140 | 1301 | |
---|
.. | .. |
---|
1160 | 1321 | struct tcon_link *tlink; |
---|
1161 | 1322 | unsigned int f_flags; |
---|
1162 | 1323 | bool invalidHandle:1; /* file closed via session abend */ |
---|
| 1324 | + bool swapfile:1; |
---|
1163 | 1325 | bool oplock_break_cancelled:1; |
---|
1164 | 1326 | unsigned int oplock_epoch; /* epoch from the lease break */ |
---|
1165 | 1327 | __u32 oplock_level; /* oplock/lease level from the lease break */ |
---|
.. | .. |
---|
1168 | 1330 | struct mutex fh_mutex; /* prevents reopen race after dead ses*/ |
---|
1169 | 1331 | struct cifs_search_info srch_inf; |
---|
1170 | 1332 | struct work_struct oplock_break; /* work for oplock breaks */ |
---|
| 1333 | + struct work_struct put; /* work for the final part of _put */ |
---|
1171 | 1334 | }; |
---|
1172 | 1335 | |
---|
1173 | 1336 | struct cifs_io_parms { |
---|
.. | .. |
---|
1178 | 1341 | __u64 offset; |
---|
1179 | 1342 | unsigned int length; |
---|
1180 | 1343 | struct cifs_tcon *tcon; |
---|
| 1344 | + struct TCP_Server_Info *server; |
---|
1181 | 1345 | }; |
---|
1182 | 1346 | |
---|
1183 | 1347 | struct cifs_aio_ctx { |
---|
.. | .. |
---|
1195 | 1359 | unsigned int len; |
---|
1196 | 1360 | unsigned int total_len; |
---|
1197 | 1361 | bool should_dirty; |
---|
| 1362 | + /* |
---|
| 1363 | + * Indicates if this aio_ctx is for direct_io, |
---|
| 1364 | + * If yes, iter is a copy of the user passed iov_iter |
---|
| 1365 | + */ |
---|
| 1366 | + bool direct_io; |
---|
1198 | 1367 | }; |
---|
1199 | 1368 | |
---|
1200 | 1369 | struct cifs_readdata; |
---|
.. | .. |
---|
1220 | 1389 | struct cifs_readdata *rdata, |
---|
1221 | 1390 | struct iov_iter *iter); |
---|
1222 | 1391 | struct kvec iov[2]; |
---|
| 1392 | + struct TCP_Server_Info *server; |
---|
1223 | 1393 | #ifdef CONFIG_CIFS_SMB_DIRECT |
---|
1224 | 1394 | struct smbd_mr *mr; |
---|
1225 | 1395 | #endif |
---|
1226 | 1396 | unsigned int pagesz; |
---|
1227 | 1397 | unsigned int page_offset; |
---|
1228 | 1398 | unsigned int tailsz; |
---|
1229 | | - unsigned int credits; |
---|
| 1399 | + struct cifs_credits credits; |
---|
1230 | 1400 | unsigned int nr_pages; |
---|
1231 | 1401 | struct page **pages; |
---|
1232 | 1402 | }; |
---|
.. | .. |
---|
1246 | 1416 | pid_t pid; |
---|
1247 | 1417 | unsigned int bytes; |
---|
1248 | 1418 | int result; |
---|
| 1419 | + struct TCP_Server_Info *server; |
---|
1249 | 1420 | #ifdef CONFIG_CIFS_SMB_DIRECT |
---|
1250 | 1421 | struct smbd_mr *mr; |
---|
1251 | 1422 | #endif |
---|
1252 | 1423 | unsigned int pagesz; |
---|
1253 | 1424 | unsigned int page_offset; |
---|
1254 | 1425 | unsigned int tailsz; |
---|
1255 | | - unsigned int credits; |
---|
| 1426 | + struct cifs_credits credits; |
---|
1256 | 1427 | unsigned int nr_pages; |
---|
1257 | 1428 | struct page **pages; |
---|
1258 | 1429 | }; |
---|
.. | .. |
---|
1268 | 1439 | } |
---|
1269 | 1440 | |
---|
1270 | 1441 | struct cifsFileInfo *cifsFileInfo_get(struct cifsFileInfo *cifs_file); |
---|
1271 | | -void _cifsFileInfo_put(struct cifsFileInfo *cifs_file, bool wait_oplock_hdlr); |
---|
| 1442 | +void _cifsFileInfo_put(struct cifsFileInfo *cifs_file, bool wait_oplock_hdlr, |
---|
| 1443 | + bool offload); |
---|
1272 | 1444 | void cifsFileInfo_put(struct cifsFileInfo *cifs_file); |
---|
1273 | 1445 | |
---|
1274 | 1446 | #define CIFS_CACHE_READ_FLG 1 |
---|
.. | .. |
---|
1278 | 1450 | #define CIFS_CACHE_RW_FLG (CIFS_CACHE_READ_FLG | CIFS_CACHE_WRITE_FLG) |
---|
1279 | 1451 | #define CIFS_CACHE_RHW_FLG (CIFS_CACHE_RW_FLG | CIFS_CACHE_HANDLE_FLG) |
---|
1280 | 1452 | |
---|
1281 | | -#define CIFS_CACHE_READ(cinode) (cinode->oplock & CIFS_CACHE_READ_FLG) |
---|
| 1453 | +#define CIFS_CACHE_READ(cinode) ((cinode->oplock & CIFS_CACHE_READ_FLG) || (CIFS_SB(cinode->vfs_inode.i_sb)->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE)) |
---|
1282 | 1454 | #define CIFS_CACHE_HANDLE(cinode) (cinode->oplock & CIFS_CACHE_HANDLE_FLG) |
---|
1283 | | -#define CIFS_CACHE_WRITE(cinode) (cinode->oplock & CIFS_CACHE_WRITE_FLG) |
---|
| 1455 | +#define CIFS_CACHE_WRITE(cinode) ((cinode->oplock & CIFS_CACHE_WRITE_FLG) || (CIFS_SB(cinode->vfs_inode.i_sb)->mnt_cifs_flags & CIFS_MOUNT_RW_CACHE)) |
---|
1284 | 1456 | |
---|
1285 | 1457 | /* |
---|
1286 | 1458 | * One of these for each file inode |
---|
.. | .. |
---|
1291 | 1463 | struct list_head llist; /* locks helb by this inode */ |
---|
1292 | 1464 | /* |
---|
1293 | 1465 | * NOTE: Some code paths call down_read(lock_sem) twice, so |
---|
1294 | | - * we must always use use cifs_down_write() instead of down_write() |
---|
| 1466 | + * we must always use cifs_down_write() instead of down_write() |
---|
1295 | 1467 | * for this semaphore to avoid deadlocks. |
---|
1296 | 1468 | */ |
---|
1297 | 1469 | struct rw_semaphore lock_sem; /* protect the fields above */ |
---|
.. | .. |
---|
1422 | 1594 | struct TCP_Server_Info *server; /* server corresponding to this mid */ |
---|
1423 | 1595 | __u64 mid; /* multiplex id */ |
---|
1424 | 1596 | __u16 credits; /* number of credits consumed by this mid */ |
---|
| 1597 | + __u16 credits_received; /* number of credits from the response */ |
---|
1425 | 1598 | __u32 pid; /* process id */ |
---|
1426 | 1599 | __u32 sequence_number; /* for CIFS signing */ |
---|
1427 | 1600 | unsigned long when_alloc; /* when mid was created */ |
---|
.. | .. |
---|
1433 | 1606 | mid_callback_t *callback; /* call completion callback */ |
---|
1434 | 1607 | mid_handle_t *handle; /* call handle mid callback */ |
---|
1435 | 1608 | void *callback_data; /* general purpose pointer for callback */ |
---|
| 1609 | + struct task_struct *creator; |
---|
1436 | 1610 | void *resp_buf; /* pointer to received SMB header */ |
---|
1437 | 1611 | unsigned int resp_buf_size; |
---|
1438 | 1612 | int mid_state; /* wish this were enum but can not pass to wait_event */ |
---|
1439 | 1613 | unsigned int mid_flags; |
---|
1440 | 1614 | __le16 command; /* smb command code */ |
---|
| 1615 | + unsigned int optype; /* operation type */ |
---|
1441 | 1616 | bool large_buf:1; /* if valid response, is pointer to large buf */ |
---|
1442 | 1617 | bool multiRsp:1; /* multiple trans2 responses for one request */ |
---|
1443 | 1618 | bool multiEnd:1; /* both received */ |
---|
.. | .. |
---|
1448 | 1623 | struct cifs_fid fid; |
---|
1449 | 1624 | struct cifs_tcon *tcon; |
---|
1450 | 1625 | struct work_struct work; |
---|
| 1626 | + __u64 mid; |
---|
| 1627 | + __u16 cmd; |
---|
1451 | 1628 | }; |
---|
1452 | 1629 | |
---|
1453 | 1630 | /* Make code in transport.c a little cleaner by moving |
---|
1454 | 1631 | update of optional stats into function below */ |
---|
1455 | | -#ifdef CONFIG_CIFS_STATS2 |
---|
1456 | | - |
---|
1457 | 1632 | static inline void cifs_in_send_inc(struct TCP_Server_Info *server) |
---|
1458 | 1633 | { |
---|
1459 | 1634 | atomic_inc(&server->in_send); |
---|
.. | .. |
---|
1474 | 1649 | atomic_dec(&server->num_waiters); |
---|
1475 | 1650 | } |
---|
1476 | 1651 | |
---|
| 1652 | +#ifdef CONFIG_CIFS_STATS2 |
---|
1477 | 1653 | static inline void cifs_save_when_sent(struct mid_q_entry *mid) |
---|
1478 | 1654 | { |
---|
1479 | 1655 | mid->when_sent = jiffies; |
---|
1480 | 1656 | } |
---|
1481 | 1657 | #else |
---|
1482 | | -static inline void cifs_in_send_inc(struct TCP_Server_Info *server) |
---|
1483 | | -{ |
---|
1484 | | -} |
---|
1485 | | -static inline void cifs_in_send_dec(struct TCP_Server_Info *server) |
---|
1486 | | -{ |
---|
1487 | | -} |
---|
1488 | | - |
---|
1489 | | -static inline void cifs_num_waiters_inc(struct TCP_Server_Info *server) |
---|
1490 | | -{ |
---|
1491 | | -} |
---|
1492 | | - |
---|
1493 | | -static inline void cifs_num_waiters_dec(struct TCP_Server_Info *server) |
---|
1494 | | -{ |
---|
1495 | | -} |
---|
1496 | | - |
---|
1497 | 1658 | static inline void cifs_save_when_sent(struct mid_q_entry *mid) |
---|
1498 | 1659 | { |
---|
1499 | 1660 | } |
---|
.. | .. |
---|
1520 | 1681 | int ref_flag; |
---|
1521 | 1682 | char *path_name; |
---|
1522 | 1683 | char *node_name; |
---|
| 1684 | + int ttl; |
---|
1523 | 1685 | }; |
---|
1524 | 1686 | |
---|
1525 | 1687 | /* |
---|
.. | .. |
---|
1550 | 1712 | struct timespec64 cf_atime; |
---|
1551 | 1713 | struct timespec64 cf_mtime; |
---|
1552 | 1714 | struct timespec64 cf_ctime; |
---|
| 1715 | + u32 cf_cifstag; |
---|
1553 | 1716 | }; |
---|
1554 | 1717 | |
---|
1555 | 1718 | static inline void free_dfs_info_param(struct dfs_info3_param *param) |
---|
.. | .. |
---|
1557 | 1720 | if (param) { |
---|
1558 | 1721 | kfree(param->path_name); |
---|
1559 | 1722 | kfree(param->node_name); |
---|
1560 | | - kfree(param); |
---|
1561 | 1723 | } |
---|
1562 | 1724 | } |
---|
1563 | 1725 | |
---|
.. | .. |
---|
1593 | 1755 | return false; |
---|
1594 | 1756 | } |
---|
1595 | 1757 | |
---|
| 1758 | + |
---|
| 1759 | +/* cifs_get_writable_file() flags */ |
---|
| 1760 | +#define FIND_WR_ANY 0 |
---|
| 1761 | +#define FIND_WR_FSUID_ONLY 1 |
---|
| 1762 | +#define FIND_WR_WITH_DELETE 2 |
---|
| 1763 | + |
---|
1596 | 1764 | #define MID_FREE 0 |
---|
1597 | 1765 | #define MID_REQUEST_ALLOCATED 1 |
---|
1598 | 1766 | #define MID_REQUEST_SUBMITTED 2 |
---|
.. | .. |
---|
1613 | 1781 | |
---|
1614 | 1782 | /* Type of Request to SendReceive2 */ |
---|
1615 | 1783 | #define CIFS_BLOCKING_OP 1 /* operation can block */ |
---|
1616 | | -#define CIFS_ASYNC_OP 2 /* do not wait for response */ |
---|
| 1784 | +#define CIFS_NON_BLOCKING 2 /* do not block waiting for credits */ |
---|
1617 | 1785 | #define CIFS_TIMEOUT_MASK 0x003 /* only one of above set in req */ |
---|
1618 | 1786 | #define CIFS_LOG_ERROR 0x010 /* log NT STATUS if non-zero */ |
---|
1619 | 1787 | #define CIFS_LARGE_BUF_OP 0x020 /* large request buffer */ |
---|
1620 | | -#define CIFS_NO_RESP 0x040 /* no response buffer required */ |
---|
| 1788 | +#define CIFS_NO_RSP_BUF 0x040 /* no response buffer required */ |
---|
1621 | 1789 | |
---|
1622 | 1790 | /* Type of request operation */ |
---|
1623 | | -#define CIFS_ECHO_OP 0x080 /* echo request */ |
---|
1624 | | -#define CIFS_OBREAK_OP 0x0100 /* oplock break request */ |
---|
1625 | | -#define CIFS_NEG_OP 0x0200 /* negotiate request */ |
---|
1626 | | -#define CIFS_OP_MASK 0x0380 /* mask request type */ |
---|
| 1791 | +#define CIFS_ECHO_OP 0x080 /* echo request */ |
---|
| 1792 | +#define CIFS_OBREAK_OP 0x0100 /* oplock break request */ |
---|
| 1793 | +#define CIFS_NEG_OP 0x0200 /* negotiate request */ |
---|
| 1794 | +#define CIFS_CP_CREATE_CLOSE_OP 0x0400 /* compound create+close request */ |
---|
| 1795 | +#define CIFS_OP_MASK 0x0780 /* mask request type */ |
---|
1627 | 1796 | |
---|
1628 | 1797 | #define CIFS_HAS_CREDITS 0x0400 /* already has credits */ |
---|
1629 | 1798 | #define CIFS_TRANSFORM_REQ 0x0800 /* transform request before sending */ |
---|
| 1799 | +#define CIFS_NO_SRV_RSP 0x1000 /* there is no server response */ |
---|
1630 | 1800 | |
---|
1631 | 1801 | /* Security Flags: indicate type of session setup needed */ |
---|
1632 | 1802 | #define CIFSSEC_MAY_SIGN 0x00001 |
---|
.. | .. |
---|
1695 | 1865 | * GlobalMid_Lock protects: |
---|
1696 | 1866 | * list operations on pending_mid_q and oplockQ |
---|
1697 | 1867 | * updates to XID counters, multiplex id and SMB sequence numbers |
---|
| 1868 | + * list operations on global DnotifyReqList |
---|
| 1869 | + * updates to ses->status |
---|
1698 | 1870 | * tcp_ses_lock protects: |
---|
1699 | 1871 | * list operations on tcp and SMB session lists |
---|
1700 | 1872 | * tcon->open_file_lock protects the list of open files hanging off the tcon |
---|
.. | .. |
---|
1732 | 1904 | /* |
---|
1733 | 1905 | * This lock protects the cifs_tcp_ses_list, the list of smb sessions per |
---|
1734 | 1906 | * tcp session, and the list of tcon's per smb session. It also protects |
---|
1735 | | - * the reference counters for the server, smb session, and tcon. Finally, |
---|
| 1907 | + * the reference counters for the server, smb session, and tcon. It also |
---|
| 1908 | + * protects some fields in the TCP_Server_Info struct such as dstaddr. Finally, |
---|
1736 | 1909 | * changes to the tcon->tidStatus should be done while holding this lock. |
---|
1737 | 1910 | * generally the locks should be taken in order tcp_ses_lock before |
---|
1738 | 1911 | * tcon->open_file_lock and that before file->file_info_lock since the |
---|
.. | .. |
---|
1769 | 1942 | #ifdef CONFIG_CIFS_STATS2 |
---|
1770 | 1943 | GLOBAL_EXTERN atomic_t totBufAllocCount; /* total allocated over all time */ |
---|
1771 | 1944 | GLOBAL_EXTERN atomic_t totSmBufAllocCount; |
---|
| 1945 | +extern unsigned int slow_rsp_threshold; /* number of secs before logging */ |
---|
1772 | 1946 | #endif |
---|
1773 | 1947 | GLOBAL_EXTERN atomic_t smBufAllocCount; |
---|
1774 | 1948 | GLOBAL_EXTERN atomic_t midCount; |
---|
.. | .. |
---|
1779 | 1953 | extern unsigned int global_secflags; /* if on, session setup sent |
---|
1780 | 1954 | with more secure ntlmssp2 challenge/resp */ |
---|
1781 | 1955 | extern unsigned int sign_CIFS_PDUs; /* enable smb packet signing */ |
---|
| 1956 | +extern bool enable_gcm_256; /* allow optional negotiate of strongest signing (aes-gcm-256) */ |
---|
| 1957 | +extern bool require_gcm_256; /* require use of strongest signing (aes-gcm-256) */ |
---|
1782 | 1958 | extern bool linuxExtEnabled;/*enable Linux/Unix CIFS extensions*/ |
---|
1783 | 1959 | extern unsigned int CIFSMaxBufSize; /* max size not including hdr */ |
---|
1784 | 1960 | extern unsigned int cifs_min_rcv; /* min size of big ntwrk buf pool */ |
---|
.. | .. |
---|
1786 | 1962 | extern unsigned int cifs_max_pending; /* MAX requests at once to server*/ |
---|
1787 | 1963 | extern bool disable_legacy_dialects; /* forbid vers=1.0 and vers=2.0 mounts */ |
---|
1788 | 1964 | |
---|
1789 | | -#ifdef CONFIG_CIFS_ACL |
---|
1790 | 1965 | GLOBAL_EXTERN struct rb_root uidtree; |
---|
1791 | 1966 | GLOBAL_EXTERN struct rb_root gidtree; |
---|
1792 | 1967 | GLOBAL_EXTERN spinlock_t siduidlock; |
---|
.. | .. |
---|
1795 | 1970 | GLOBAL_EXTERN struct rb_root sidgidtree; |
---|
1796 | 1971 | GLOBAL_EXTERN spinlock_t uidsidlock; |
---|
1797 | 1972 | GLOBAL_EXTERN spinlock_t gidsidlock; |
---|
1798 | | -#endif /* CONFIG_CIFS_ACL */ |
---|
1799 | 1973 | |
---|
1800 | 1974 | void cifs_oplock_break(struct work_struct *work); |
---|
1801 | 1975 | void cifs_queue_oplock_break(struct cifsFileInfo *cfile); |
---|
1802 | 1976 | |
---|
1803 | 1977 | extern const struct slow_work_ops cifs_oplock_break_ops; |
---|
1804 | 1978 | extern struct workqueue_struct *cifsiod_wq; |
---|
| 1979 | +extern struct workqueue_struct *decrypt_wq; |
---|
| 1980 | +extern struct workqueue_struct *fileinfo_put_wq; |
---|
1805 | 1981 | extern struct workqueue_struct *cifsoplockd_wq; |
---|
1806 | 1982 | extern __u32 cifs_lock_secret; |
---|
1807 | 1983 | |
---|
.. | .. |
---|
1809 | 1985 | |
---|
1810 | 1986 | /* Operations for different SMB versions */ |
---|
1811 | 1987 | #define SMB1_VERSION_STRING "1.0" |
---|
| 1988 | +#define SMB20_VERSION_STRING "2.0" |
---|
| 1989 | +#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY |
---|
1812 | 1990 | extern struct smb_version_operations smb1_operations; |
---|
1813 | 1991 | extern struct smb_version_values smb1_values; |
---|
1814 | | -#define SMB20_VERSION_STRING "2.0" |
---|
1815 | 1992 | extern struct smb_version_operations smb20_operations; |
---|
1816 | 1993 | extern struct smb_version_values smb20_values; |
---|
| 1994 | +#endif /* CIFS_ALLOW_INSECURE_LEGACY */ |
---|
1817 | 1995 | #define SMB21_VERSION_STRING "2.1" |
---|
1818 | 1996 | extern struct smb_version_operations smb21_operations; |
---|
1819 | 1997 | extern struct smb_version_values smb21_values; |
---|
.. | .. |
---|
1825 | 2003 | extern struct smb_version_operations smb30_operations; |
---|
1826 | 2004 | extern struct smb_version_values smb30_values; |
---|
1827 | 2005 | #define SMB302_VERSION_STRING "3.02" |
---|
| 2006 | +#define ALT_SMB302_VERSION_STRING "3.0.2" |
---|
1828 | 2007 | /*extern struct smb_version_operations smb302_operations;*/ /* not needed yet */ |
---|
1829 | 2008 | extern struct smb_version_values smb302_values; |
---|
1830 | 2009 | #define SMB311_VERSION_STRING "3.1.1" |
---|
1831 | 2010 | #define ALT_SMB311_VERSION_STRING "3.11" |
---|
1832 | 2011 | extern struct smb_version_operations smb311_operations; |
---|
1833 | 2012 | extern struct smb_version_values smb311_values; |
---|
| 2013 | + |
---|
| 2014 | +static inline char *get_security_type_str(enum securityEnum sectype) |
---|
| 2015 | +{ |
---|
| 2016 | + switch (sectype) { |
---|
| 2017 | + case RawNTLMSSP: |
---|
| 2018 | + return "RawNTLMSSP"; |
---|
| 2019 | + case Kerberos: |
---|
| 2020 | + return "Kerberos"; |
---|
| 2021 | + case NTLMv2: |
---|
| 2022 | + return "NTLMv2"; |
---|
| 2023 | + case NTLM: |
---|
| 2024 | + return "NTLM"; |
---|
| 2025 | + case LANMAN: |
---|
| 2026 | + return "LANMAN"; |
---|
| 2027 | + default: |
---|
| 2028 | + return "Unknown"; |
---|
| 2029 | + } |
---|
| 2030 | +} |
---|
| 2031 | + |
---|
| 2032 | +static inline bool is_smb1_server(struct TCP_Server_Info *server) |
---|
| 2033 | +{ |
---|
| 2034 | + return strcmp(server->vals->version_string, SMB1_VERSION_STRING) == 0; |
---|
| 2035 | +} |
---|
| 2036 | + |
---|
| 2037 | +static inline bool is_tcon_dfs(struct cifs_tcon *tcon) |
---|
| 2038 | +{ |
---|
| 2039 | + /* |
---|
| 2040 | + * For SMB1, see MS-CIFS 2.4.55 SMB_COM_TREE_CONNECT_ANDX (0x75) and MS-CIFS 3.3.4.4 DFS |
---|
| 2041 | + * Subsystem Notifies That a Share Is a DFS Share. |
---|
| 2042 | + * |
---|
| 2043 | + * For SMB2+, see MS-SMB2 2.2.10 SMB2 TREE_CONNECT Response and MS-SMB2 3.3.4.14 Server |
---|
| 2044 | + * Application Updates a Share. |
---|
| 2045 | + */ |
---|
| 2046 | + if (!tcon || !tcon->ses || !tcon->ses->server) |
---|
| 2047 | + return false; |
---|
| 2048 | + return is_smb1_server(tcon->ses->server) ? tcon->Flags & SMB_SHARE_IS_IN_DFS : |
---|
| 2049 | + tcon->share_flags & (SHI1005_FLAGS_DFS | SHI1005_FLAGS_DFS_ROOT); |
---|
| 2050 | +} |
---|
| 2051 | + |
---|
| 2052 | +static inline unsigned int cifs_get_num_sgs(const struct smb_rqst *rqst, |
---|
| 2053 | + int num_rqst, |
---|
| 2054 | + const u8 *sig) |
---|
| 2055 | +{ |
---|
| 2056 | + unsigned int len, skip; |
---|
| 2057 | + unsigned int nents = 0; |
---|
| 2058 | + unsigned long addr; |
---|
| 2059 | + int i, j; |
---|
| 2060 | + |
---|
| 2061 | + /* Assumes the first rqst has a transform header as the first iov. |
---|
| 2062 | + * I.e. |
---|
| 2063 | + * rqst[0].rq_iov[0] is transform header |
---|
| 2064 | + * rqst[0].rq_iov[1+] data to be encrypted/decrypted |
---|
| 2065 | + * rqst[1+].rq_iov[0+] data to be encrypted/decrypted |
---|
| 2066 | + */ |
---|
| 2067 | + for (i = 0; i < num_rqst; i++) { |
---|
| 2068 | + /* |
---|
| 2069 | + * The first rqst has a transform header where the |
---|
| 2070 | + * first 20 bytes are not part of the encrypted blob. |
---|
| 2071 | + */ |
---|
| 2072 | + for (j = 0; j < rqst[i].rq_nvec; j++) { |
---|
| 2073 | + struct kvec *iov = &rqst[i].rq_iov[j]; |
---|
| 2074 | + |
---|
| 2075 | + skip = (i == 0) && (j == 0) ? 20 : 0; |
---|
| 2076 | + addr = (unsigned long)iov->iov_base + skip; |
---|
| 2077 | + if (unlikely(is_vmalloc_addr((void *)addr))) { |
---|
| 2078 | + len = iov->iov_len - skip; |
---|
| 2079 | + nents += DIV_ROUND_UP(offset_in_page(addr) + len, |
---|
| 2080 | + PAGE_SIZE); |
---|
| 2081 | + } else { |
---|
| 2082 | + nents++; |
---|
| 2083 | + } |
---|
| 2084 | + } |
---|
| 2085 | + nents += rqst[i].rq_npages; |
---|
| 2086 | + } |
---|
| 2087 | + nents += DIV_ROUND_UP(offset_in_page(sig) + SMB2_SIGNATURE_SIZE, PAGE_SIZE); |
---|
| 2088 | + return nents; |
---|
| 2089 | +} |
---|
| 2090 | + |
---|
| 2091 | +/* We can not use the normal sg_set_buf() as we will sometimes pass a |
---|
| 2092 | + * stack object as buf. |
---|
| 2093 | + */ |
---|
| 2094 | +static inline struct scatterlist *cifs_sg_set_buf(struct scatterlist *sg, |
---|
| 2095 | + const void *buf, |
---|
| 2096 | + unsigned int buflen) |
---|
| 2097 | +{ |
---|
| 2098 | + unsigned long addr = (unsigned long)buf; |
---|
| 2099 | + unsigned int off = offset_in_page(addr); |
---|
| 2100 | + |
---|
| 2101 | + addr &= PAGE_MASK; |
---|
| 2102 | + if (unlikely(is_vmalloc_addr((void *)addr))) { |
---|
| 2103 | + do { |
---|
| 2104 | + unsigned int len = min_t(unsigned int, buflen, PAGE_SIZE - off); |
---|
| 2105 | + |
---|
| 2106 | + sg_set_page(sg++, vmalloc_to_page((void *)addr), len, off); |
---|
| 2107 | + |
---|
| 2108 | + off = 0; |
---|
| 2109 | + addr += PAGE_SIZE; |
---|
| 2110 | + buflen -= len; |
---|
| 2111 | + } while (buflen); |
---|
| 2112 | + } else { |
---|
| 2113 | + sg_set_page(sg++, virt_to_page(addr), buflen, off); |
---|
| 2114 | + } |
---|
| 2115 | + return sg; |
---|
| 2116 | +} |
---|
| 2117 | + |
---|
1834 | 2118 | #endif /* _CIFS_GLOB_H */ |
---|