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