| .. | .. |
|---|
| 52 | 52 | #include "cifs_spnego.h" |
|---|
| 53 | 53 | #include "fscache.h" |
|---|
| 54 | 54 | #include "smb2pdu.h" |
|---|
| 55 | +#ifdef CONFIG_CIFS_DFS_UPCALL |
|---|
| 56 | +#include "dfs_cache.h" |
|---|
| 57 | +#endif |
|---|
| 58 | + |
|---|
| 59 | +/* |
|---|
| 60 | + * DOS dates from 1980/1/1 through 2107/12/31 |
|---|
| 61 | + * Protocol specifications indicate the range should be to 119, which |
|---|
| 62 | + * limits maximum year to 2099. But this range has not been checked. |
|---|
| 63 | + */ |
|---|
| 64 | +#define SMB_DATE_MAX (127<<9 | 12<<5 | 31) |
|---|
| 65 | +#define SMB_DATE_MIN (0<<9 | 1<<5 | 1) |
|---|
| 66 | +#define SMB_TIME_MAX (23<<11 | 59<<5 | 29) |
|---|
| 55 | 67 | |
|---|
| 56 | 68 | int cifsFYI = 0; |
|---|
| 57 | 69 | bool traceSMB; |
|---|
| .. | .. |
|---|
| 59 | 71 | bool linuxExtEnabled = true; |
|---|
| 60 | 72 | bool lookupCacheEnabled = true; |
|---|
| 61 | 73 | bool disable_legacy_dialects; /* false by default */ |
|---|
| 74 | +bool enable_gcm_256; /* false by default, change when more servers support it */ |
|---|
| 75 | +bool require_gcm_256; /* false by default */ |
|---|
| 62 | 76 | unsigned int global_secflags = CIFSSEC_DEF; |
|---|
| 63 | 77 | /* unsigned int ntlmv2_support = 0; */ |
|---|
| 64 | 78 | unsigned int sign_CIFS_PDUs = 1; |
|---|
| .. | .. |
|---|
| 81 | 95 | MODULE_PARM_DESC(cifs_max_pending, "Simultaneous requests to server for " |
|---|
| 82 | 96 | "CIFS/SMB1 dialect (N/A for SMB3) " |
|---|
| 83 | 97 | "Default: 32767 Range: 2 to 32767."); |
|---|
| 98 | +#ifdef CONFIG_CIFS_STATS2 |
|---|
| 99 | +unsigned int slow_rsp_threshold = 1; |
|---|
| 100 | +module_param(slow_rsp_threshold, uint, 0644); |
|---|
| 101 | +MODULE_PARM_DESC(slow_rsp_threshold, "Amount of time (in seconds) to wait " |
|---|
| 102 | + "before logging that a response is delayed. " |
|---|
| 103 | + "Default: 1 (if set to 0 disables msg)."); |
|---|
| 104 | +#endif /* STATS2 */ |
|---|
| 105 | + |
|---|
| 84 | 106 | module_param(enable_oplocks, bool, 0644); |
|---|
| 85 | 107 | MODULE_PARM_DESC(enable_oplocks, "Enable or disable oplocks. Default: y/Y/1"); |
|---|
| 108 | + |
|---|
| 109 | +module_param(enable_gcm_256, bool, 0644); |
|---|
| 110 | +MODULE_PARM_DESC(enable_gcm_256, "Enable requesting strongest (256 bit) GCM encryption. Default: n/N/0"); |
|---|
| 111 | + |
|---|
| 112 | +module_param(require_gcm_256, bool, 0644); |
|---|
| 113 | +MODULE_PARM_DESC(require_gcm_256, "Require strongest (256 bit) GCM encryption. Default: n/N/0"); |
|---|
| 86 | 114 | |
|---|
| 87 | 115 | module_param(disable_legacy_dialects, bool, 0644); |
|---|
| 88 | 116 | MODULE_PARM_DESC(disable_legacy_dialects, "To improve security it may be " |
|---|
| .. | .. |
|---|
| 98 | 126 | extern mempool_t *cifs_mid_poolp; |
|---|
| 99 | 127 | |
|---|
| 100 | 128 | struct workqueue_struct *cifsiod_wq; |
|---|
| 129 | +struct workqueue_struct *decrypt_wq; |
|---|
| 130 | +struct workqueue_struct *fileinfo_put_wq; |
|---|
| 101 | 131 | struct workqueue_struct *cifsoplockd_wq; |
|---|
| 102 | 132 | __u32 cifs_lock_secret; |
|---|
| 103 | 133 | |
|---|
| .. | .. |
|---|
| 131 | 161 | struct inode *inode; |
|---|
| 132 | 162 | struct cifs_sb_info *cifs_sb; |
|---|
| 133 | 163 | struct cifs_tcon *tcon; |
|---|
| 164 | + struct timespec64 ts; |
|---|
| 134 | 165 | int rc = 0; |
|---|
| 135 | 166 | |
|---|
| 136 | 167 | cifs_sb = CIFS_SB(sb); |
|---|
| .. | .. |
|---|
| 147 | 178 | else |
|---|
| 148 | 179 | sb->s_maxbytes = MAX_NON_LFS; |
|---|
| 149 | 180 | |
|---|
| 150 | | - /* BB FIXME fix time_gran to be larger for LANMAN sessions */ |
|---|
| 151 | | - sb->s_time_gran = 100; |
|---|
| 181 | + /* |
|---|
| 182 | + * Some very old servers like DOS and OS/2 used 2 second granularity |
|---|
| 183 | + * (while all current servers use 100ns granularity - see MS-DTYP) |
|---|
| 184 | + * but 1 second is the maximum allowed granularity for the VFS |
|---|
| 185 | + * so for old servers set time granularity to 1 second while for |
|---|
| 186 | + * everything else (current servers) set it to 100ns. |
|---|
| 187 | + */ |
|---|
| 188 | + if ((tcon->ses->server->vals->protocol_id == SMB10_PROT_ID) && |
|---|
| 189 | + ((tcon->ses->capabilities & |
|---|
| 190 | + tcon->ses->server->vals->cap_nt_find) == 0) && |
|---|
| 191 | + !tcon->unix_ext) { |
|---|
| 192 | + sb->s_time_gran = 1000000000; /* 1 second is max allowed gran */ |
|---|
| 193 | + ts = cnvrtDosUnixTm(cpu_to_le16(SMB_DATE_MIN), 0, 0); |
|---|
| 194 | + sb->s_time_min = ts.tv_sec; |
|---|
| 195 | + ts = cnvrtDosUnixTm(cpu_to_le16(SMB_DATE_MAX), |
|---|
| 196 | + cpu_to_le16(SMB_TIME_MAX), 0); |
|---|
| 197 | + sb->s_time_max = ts.tv_sec; |
|---|
| 198 | + } else { |
|---|
| 199 | + /* |
|---|
| 200 | + * Almost every server, including all SMB2+, uses DCE TIME |
|---|
| 201 | + * ie 100 nanosecond units, since 1601. See MS-DTYP and MS-FSCC |
|---|
| 202 | + */ |
|---|
| 203 | + sb->s_time_gran = 100; |
|---|
| 204 | + ts = cifs_NTtimeToUnix(0); |
|---|
| 205 | + sb->s_time_min = ts.tv_sec; |
|---|
| 206 | + ts = cifs_NTtimeToUnix(cpu_to_le64(S64_MAX)); |
|---|
| 207 | + sb->s_time_max = ts.tv_sec; |
|---|
| 208 | + } |
|---|
| 152 | 209 | |
|---|
| 153 | 210 | sb->s_magic = CIFS_MAGIC_NUMBER; |
|---|
| 154 | 211 | sb->s_op = &cifs_super_ops; |
|---|
| .. | .. |
|---|
| 226 | 283 | buf->f_ffree = 0; /* unlimited */ |
|---|
| 227 | 284 | |
|---|
| 228 | 285 | if (server->ops->queryfs) |
|---|
| 229 | | - rc = server->ops->queryfs(xid, tcon, buf); |
|---|
| 286 | + rc = server->ops->queryfs(xid, tcon, cifs_sb, buf); |
|---|
| 230 | 287 | |
|---|
| 231 | 288 | free_xid(xid); |
|---|
| 232 | 289 | return rc; |
|---|
| .. | .. |
|---|
| 305 | 362 | return &cifs_inode->vfs_inode; |
|---|
| 306 | 363 | } |
|---|
| 307 | 364 | |
|---|
| 308 | | -static void cifs_i_callback(struct rcu_head *head) |
|---|
| 309 | | -{ |
|---|
| 310 | | - struct inode *inode = container_of(head, struct inode, i_rcu); |
|---|
| 311 | | - kmem_cache_free(cifs_inode_cachep, CIFS_I(inode)); |
|---|
| 312 | | -} |
|---|
| 313 | | - |
|---|
| 314 | 365 | static void |
|---|
| 315 | | -cifs_destroy_inode(struct inode *inode) |
|---|
| 366 | +cifs_free_inode(struct inode *inode) |
|---|
| 316 | 367 | { |
|---|
| 317 | | - call_rcu(&inode->i_rcu, cifs_i_callback); |
|---|
| 368 | + kmem_cache_free(cifs_inode_cachep, CIFS_I(inode)); |
|---|
| 318 | 369 | } |
|---|
| 319 | 370 | |
|---|
| 320 | 371 | static void |
|---|
| .. | .. |
|---|
| 384 | 435 | |
|---|
| 385 | 436 | if (ses->sign) |
|---|
| 386 | 437 | seq_puts(s, "i"); |
|---|
| 438 | + |
|---|
| 439 | + if (ses->sectype == Kerberos) |
|---|
| 440 | + seq_printf(s, ",cruid=%u", |
|---|
| 441 | + from_kuid_munged(&init_user_ns, ses->cred_uid)); |
|---|
| 387 | 442 | } |
|---|
| 388 | 443 | |
|---|
| 389 | 444 | static void |
|---|
| .. | .. |
|---|
| 395 | 450 | seq_puts(s, "strict"); |
|---|
| 396 | 451 | else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) |
|---|
| 397 | 452 | seq_puts(s, "none"); |
|---|
| 453 | + else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RW_CACHE) |
|---|
| 454 | + seq_puts(s, "singleclient"); /* assume only one client access */ |
|---|
| 455 | + else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE) |
|---|
| 456 | + seq_puts(s, "ro"); /* read only caching assumed */ |
|---|
| 398 | 457 | else |
|---|
| 399 | 458 | seq_puts(s, "loose"); |
|---|
| 400 | 459 | } |
|---|
| .. | .. |
|---|
| 479 | 538 | |
|---|
| 480 | 539 | if (tcon->seal) |
|---|
| 481 | 540 | seq_puts(s, ",seal"); |
|---|
| 541 | + else if (tcon->ses->server->ignore_signature) |
|---|
| 542 | + seq_puts(s, ",signloosely"); |
|---|
| 482 | 543 | if (tcon->nocase) |
|---|
| 483 | 544 | seq_puts(s, ",nocase"); |
|---|
| 545 | + if (tcon->nodelete) |
|---|
| 546 | + seq_puts(s, ",nodelete"); |
|---|
| 547 | + if (tcon->local_lease) |
|---|
| 548 | + seq_puts(s, ",locallease"); |
|---|
| 484 | 549 | if (tcon->retry) |
|---|
| 485 | 550 | seq_puts(s, ",hard"); |
|---|
| 486 | 551 | else |
|---|
| .. | .. |
|---|
| 495 | 560 | seq_puts(s, ",unix"); |
|---|
| 496 | 561 | else |
|---|
| 497 | 562 | seq_puts(s, ",nounix"); |
|---|
| 563 | + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_DFS) |
|---|
| 564 | + seq_puts(s, ",nodfs"); |
|---|
| 498 | 565 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) |
|---|
| 499 | 566 | seq_puts(s, ",posixpaths"); |
|---|
| 500 | 567 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) |
|---|
| .. | .. |
|---|
| 519 | 586 | seq_puts(s, ",nobrl"); |
|---|
| 520 | 587 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_HANDLE_CACHE) |
|---|
| 521 | 588 | seq_puts(s, ",nohandlecache"); |
|---|
| 589 | + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID) |
|---|
| 590 | + seq_puts(s, ",modefromsid"); |
|---|
| 522 | 591 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) |
|---|
| 523 | 592 | seq_puts(s, ",cifsacl"); |
|---|
| 524 | 593 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) |
|---|
| .. | .. |
|---|
| 544 | 613 | |
|---|
| 545 | 614 | seq_printf(s, ",rsize=%u", cifs_sb->rsize); |
|---|
| 546 | 615 | seq_printf(s, ",wsize=%u", cifs_sb->wsize); |
|---|
| 616 | + seq_printf(s, ",bsize=%u", cifs_sb->bsize); |
|---|
| 617 | + if (tcon->ses->server->min_offload) |
|---|
| 618 | + seq_printf(s, ",esize=%u", tcon->ses->server->min_offload); |
|---|
| 547 | 619 | seq_printf(s, ",echo_interval=%lu", |
|---|
| 548 | 620 | tcon->ses->server->echo_interval / HZ); |
|---|
| 621 | + |
|---|
| 622 | + /* Only display the following if overridden on mount */ |
|---|
| 623 | + if (tcon->ses->server->max_credits != SMB2_MAX_CREDITS_AVAILABLE) |
|---|
| 624 | + seq_printf(s, ",max_credits=%u", tcon->ses->server->max_credits); |
|---|
| 625 | + if (tcon->ses->server->tcp_nodelay) |
|---|
| 626 | + seq_puts(s, ",tcpnodelay"); |
|---|
| 627 | + if (tcon->ses->server->noautotune) |
|---|
| 628 | + seq_puts(s, ",noautotune"); |
|---|
| 629 | + if (tcon->ses->server->noblocksnd) |
|---|
| 630 | + seq_puts(s, ",noblocksend"); |
|---|
| 631 | + |
|---|
| 549 | 632 | if (tcon->snapshot_time) |
|---|
| 550 | 633 | seq_printf(s, ",snapshot=%llu", tcon->snapshot_time); |
|---|
| 634 | + if (tcon->handle_timeout) |
|---|
| 635 | + seq_printf(s, ",handletimeout=%u", tcon->handle_timeout); |
|---|
| 551 | 636 | /* convert actimeo and display it in seconds */ |
|---|
| 552 | 637 | seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ); |
|---|
| 638 | + |
|---|
| 639 | + if (tcon->ses->chan_max > 1) |
|---|
| 640 | + seq_printf(s, ",multichannel,max_channels=%zu", |
|---|
| 641 | + tcon->ses->chan_max); |
|---|
| 553 | 642 | |
|---|
| 554 | 643 | return 0; |
|---|
| 555 | 644 | } |
|---|
| .. | .. |
|---|
| 617 | 706 | static const struct super_operations cifs_super_ops = { |
|---|
| 618 | 707 | .statfs = cifs_statfs, |
|---|
| 619 | 708 | .alloc_inode = cifs_alloc_inode, |
|---|
| 620 | | - .destroy_inode = cifs_destroy_inode, |
|---|
| 709 | + .free_inode = cifs_free_inode, |
|---|
| 621 | 710 | .drop_inode = cifs_drop_inode, |
|---|
| 622 | 711 | .evict_inode = cifs_evict_inode, |
|---|
| 623 | 712 | /* .delete_inode = cifs_delete_inode, */ /* Do not need above |
|---|
| .. | .. |
|---|
| 663 | 752 | struct inode *dir = d_inode(dentry); |
|---|
| 664 | 753 | struct dentry *child; |
|---|
| 665 | 754 | |
|---|
| 666 | | - if (!dir) { |
|---|
| 667 | | - dput(dentry); |
|---|
| 668 | | - dentry = ERR_PTR(-ENOENT); |
|---|
| 669 | | - break; |
|---|
| 670 | | - } |
|---|
| 671 | 755 | if (!S_ISDIR(dir->i_mode)) { |
|---|
| 672 | 756 | dput(dentry); |
|---|
| 673 | 757 | dentry = ERR_PTR(-ENOTDIR); |
|---|
| .. | .. |
|---|
| 684 | 768 | while (*s && *s != sep) |
|---|
| 685 | 769 | s++; |
|---|
| 686 | 770 | |
|---|
| 687 | | - child = lookup_one_len_unlocked(p, dentry, s - p); |
|---|
| 771 | + child = lookup_positive_unlocked(p, dentry, s - p); |
|---|
| 688 | 772 | dput(dentry); |
|---|
| 689 | 773 | dentry = child; |
|---|
| 690 | 774 | } while (!IS_ERR(dentry)); |
|---|
| .. | .. |
|---|
| 710 | 794 | struct cifs_mnt_data mnt_data; |
|---|
| 711 | 795 | struct dentry *root; |
|---|
| 712 | 796 | |
|---|
| 713 | | - cifs_dbg(FYI, "Devname: %s flags: %d\n", dev_name, flags); |
|---|
| 797 | + /* |
|---|
| 798 | + * Prints in Kernel / CIFS log the attempted mount operation |
|---|
| 799 | + * If CIFS_DEBUG && cifs_FYI |
|---|
| 800 | + */ |
|---|
| 801 | + if (cifsFYI) |
|---|
| 802 | + cifs_dbg(FYI, "Devname: %s flags: %d\n", dev_name, flags); |
|---|
| 803 | + else |
|---|
| 804 | + cifs_info("Attempting to mount %s\n", dev_name); |
|---|
| 714 | 805 | |
|---|
| 715 | 806 | volume_info = cifs_get_volume_info((char *)data, dev_name, is_smb3); |
|---|
| 716 | 807 | if (IS_ERR(volume_info)) |
|---|
| .. | .. |
|---|
| 779 | 870 | |
|---|
| 780 | 871 | out_super: |
|---|
| 781 | 872 | deactivate_locked_super(sb); |
|---|
| 873 | + return root; |
|---|
| 782 | 874 | out: |
|---|
| 783 | 875 | cifs_cleanup_volume_info(volume_info); |
|---|
| 784 | 876 | return root; |
|---|
| .. | .. |
|---|
| 812 | 904 | ssize_t rc; |
|---|
| 813 | 905 | struct inode *inode = file_inode(iocb->ki_filp); |
|---|
| 814 | 906 | |
|---|
| 815 | | - if (iocb->ki_filp->f_flags & O_DIRECT) |
|---|
| 907 | + if (iocb->ki_flags & IOCB_DIRECT) |
|---|
| 816 | 908 | return cifs_user_readv(iocb, iter); |
|---|
| 817 | 909 | |
|---|
| 818 | 910 | rc = cifs_revalidate_mapping(inode); |
|---|
| .. | .. |
|---|
| 862 | 954 | |
|---|
| 863 | 955 | static loff_t cifs_llseek(struct file *file, loff_t offset, int whence) |
|---|
| 864 | 956 | { |
|---|
| 957 | + struct cifsFileInfo *cfile = file->private_data; |
|---|
| 958 | + struct cifs_tcon *tcon; |
|---|
| 959 | + |
|---|
| 865 | 960 | /* |
|---|
| 866 | 961 | * whence == SEEK_END || SEEK_DATA || SEEK_HOLE => we must revalidate |
|---|
| 867 | 962 | * the cached file length |
|---|
| .. | .. |
|---|
| 892 | 987 | rc = cifs_revalidate_file_attr(file); |
|---|
| 893 | 988 | if (rc < 0) |
|---|
| 894 | 989 | return (loff_t)rc; |
|---|
| 990 | + } |
|---|
| 991 | + if (cfile && cfile->tlink) { |
|---|
| 992 | + tcon = tlink_tcon(cfile->tlink); |
|---|
| 993 | + if (tcon->ses->server->ops->llseek) |
|---|
| 994 | + return tcon->ses->server->ops->llseek(file, tcon, |
|---|
| 995 | + offset, whence); |
|---|
| 895 | 996 | } |
|---|
| 896 | 997 | return generic_file_llseek(file, offset, whence); |
|---|
| 897 | 998 | } |
|---|
| .. | .. |
|---|
| 934 | 1035 | .name = "cifs", |
|---|
| 935 | 1036 | .mount = cifs_do_mount, |
|---|
| 936 | 1037 | .kill_sb = cifs_kill_sb, |
|---|
| 937 | | - /* .fs_flags */ |
|---|
| 1038 | + .fs_flags = FS_RENAME_DOES_D_MOVE, |
|---|
| 938 | 1039 | }; |
|---|
| 939 | 1040 | MODULE_ALIAS_FS("cifs"); |
|---|
| 940 | 1041 | |
|---|
| 941 | | -static struct file_system_type smb3_fs_type = { |
|---|
| 1042 | +struct file_system_type smb3_fs_type = { |
|---|
| 942 | 1043 | .owner = THIS_MODULE, |
|---|
| 943 | 1044 | .name = "smb3", |
|---|
| 944 | 1045 | .mount = smb3_do_mount, |
|---|
| 945 | 1046 | .kill_sb = cifs_kill_sb, |
|---|
| 946 | | - /* .fs_flags */ |
|---|
| 1047 | + .fs_flags = FS_RENAME_DOES_D_MOVE, |
|---|
| 947 | 1048 | }; |
|---|
| 948 | 1049 | MODULE_ALIAS_FS("smb3"); |
|---|
| 949 | 1050 | MODULE_ALIAS("smb3"); |
|---|
| .. | .. |
|---|
| 970 | 1071 | .getattr = cifs_getattr, |
|---|
| 971 | 1072 | .permission = cifs_permission, |
|---|
| 972 | 1073 | .listxattr = cifs_listxattr, |
|---|
| 1074 | + .fiemap = cifs_fiemap, |
|---|
| 973 | 1075 | }; |
|---|
| 974 | 1076 | |
|---|
| 975 | 1077 | const struct inode_operations cifs_symlink_inode_ops = { |
|---|
| .. | .. |
|---|
| 978 | 1080 | .listxattr = cifs_listxattr, |
|---|
| 979 | 1081 | }; |
|---|
| 980 | 1082 | |
|---|
| 981 | | -static int cifs_clone_file_range(struct file *src_file, loff_t off, |
|---|
| 982 | | - struct file *dst_file, loff_t destoff, u64 len) |
|---|
| 1083 | +static loff_t cifs_remap_file_range(struct file *src_file, loff_t off, |
|---|
| 1084 | + struct file *dst_file, loff_t destoff, loff_t len, |
|---|
| 1085 | + unsigned int remap_flags) |
|---|
| 983 | 1086 | { |
|---|
| 984 | 1087 | struct inode *src_inode = file_inode(src_file); |
|---|
| 985 | 1088 | struct inode *target_inode = file_inode(dst_file); |
|---|
| .. | .. |
|---|
| 988 | 1091 | struct cifs_tcon *target_tcon; |
|---|
| 989 | 1092 | unsigned int xid; |
|---|
| 990 | 1093 | int rc; |
|---|
| 1094 | + |
|---|
| 1095 | + if (remap_flags & ~(REMAP_FILE_DEDUP | REMAP_FILE_ADVISORY)) |
|---|
| 1096 | + return -EINVAL; |
|---|
| 991 | 1097 | |
|---|
| 992 | 1098 | cifs_dbg(FYI, "clone range\n"); |
|---|
| 993 | 1099 | |
|---|
| .. | .. |
|---|
| 1031 | 1137 | unlock_two_nondirectories(src_inode, target_inode); |
|---|
| 1032 | 1138 | out: |
|---|
| 1033 | 1139 | free_xid(xid); |
|---|
| 1034 | | - return rc; |
|---|
| 1140 | + return rc < 0 ? rc : len; |
|---|
| 1035 | 1141 | } |
|---|
| 1036 | 1142 | |
|---|
| 1037 | 1143 | ssize_t cifs_file_copychunk_range(unsigned int xid, |
|---|
| .. | .. |
|---|
| 1048 | 1154 | ssize_t rc; |
|---|
| 1049 | 1155 | |
|---|
| 1050 | 1156 | cifs_dbg(FYI, "copychunk range\n"); |
|---|
| 1051 | | - |
|---|
| 1052 | | - if (src_inode == target_inode) { |
|---|
| 1053 | | - rc = -EINVAL; |
|---|
| 1054 | | - goto out; |
|---|
| 1055 | | - } |
|---|
| 1056 | 1157 | |
|---|
| 1057 | 1158 | if (!src_file->private_data || !dst_file->private_data) { |
|---|
| 1058 | 1159 | rc = -EBADF; |
|---|
| .. | .. |
|---|
| 1071 | 1172 | goto out; |
|---|
| 1072 | 1173 | } |
|---|
| 1073 | 1174 | |
|---|
| 1175 | + rc = -EOPNOTSUPP; |
|---|
| 1176 | + if (!target_tcon->ses->server->ops->copychunk_range) |
|---|
| 1177 | + goto out; |
|---|
| 1178 | + |
|---|
| 1074 | 1179 | /* |
|---|
| 1075 | 1180 | * Note: cifs case is easier than btrfs since server responsible for |
|---|
| 1076 | 1181 | * checks for proper open modes and file type and if it wants |
|---|
| .. | .. |
|---|
| 1082 | 1187 | /* should we flush first and last page first */ |
|---|
| 1083 | 1188 | truncate_inode_pages(&target_inode->i_data, 0); |
|---|
| 1084 | 1189 | |
|---|
| 1085 | | - if (target_tcon->ses->server->ops->copychunk_range) |
|---|
| 1190 | + rc = file_modified(dst_file); |
|---|
| 1191 | + if (!rc) |
|---|
| 1086 | 1192 | rc = target_tcon->ses->server->ops->copychunk_range(xid, |
|---|
| 1087 | 1193 | smb_file_src, smb_file_target, off, len, destoff); |
|---|
| 1088 | | - else |
|---|
| 1089 | | - rc = -EOPNOTSUPP; |
|---|
| 1194 | + |
|---|
| 1195 | + file_accessed(src_file); |
|---|
| 1090 | 1196 | |
|---|
| 1091 | 1197 | /* force revalidate of size and timestamps of target file now |
|---|
| 1092 | 1198 | * that target is updated on the server |
|---|
| .. | .. |
|---|
| 1119 | 1225 | { |
|---|
| 1120 | 1226 | unsigned int xid = get_xid(); |
|---|
| 1121 | 1227 | ssize_t rc; |
|---|
| 1228 | + struct cifsFileInfo *cfile = dst_file->private_data; |
|---|
| 1229 | + |
|---|
| 1230 | + if (cfile->swapfile) { |
|---|
| 1231 | + rc = -EOPNOTSUPP; |
|---|
| 1232 | + free_xid(xid); |
|---|
| 1233 | + return rc; |
|---|
| 1234 | + } |
|---|
| 1122 | 1235 | |
|---|
| 1123 | 1236 | rc = cifs_file_copychunk_range(xid, src_file, off, dst_file, destoff, |
|---|
| 1124 | 1237 | len, flags); |
|---|
| 1125 | 1238 | free_xid(xid); |
|---|
| 1239 | + |
|---|
| 1240 | + if (rc == -EOPNOTSUPP || rc == -EXDEV) |
|---|
| 1241 | + rc = generic_copy_file_range(src_file, off, dst_file, |
|---|
| 1242 | + destoff, len, flags); |
|---|
| 1126 | 1243 | return rc; |
|---|
| 1127 | 1244 | } |
|---|
| 1128 | 1245 | |
|---|
| .. | .. |
|---|
| 1132 | 1249 | .open = cifs_open, |
|---|
| 1133 | 1250 | .release = cifs_close, |
|---|
| 1134 | 1251 | .lock = cifs_lock, |
|---|
| 1252 | + .flock = cifs_flock, |
|---|
| 1135 | 1253 | .fsync = cifs_fsync, |
|---|
| 1136 | 1254 | .flush = cifs_flush, |
|---|
| 1137 | 1255 | .mmap = cifs_file_mmap, |
|---|
| .. | .. |
|---|
| 1140 | 1258 | .llseek = cifs_llseek, |
|---|
| 1141 | 1259 | .unlocked_ioctl = cifs_ioctl, |
|---|
| 1142 | 1260 | .copy_file_range = cifs_copy_file_range, |
|---|
| 1143 | | - .clone_file_range = cifs_clone_file_range, |
|---|
| 1261 | + .remap_file_range = cifs_remap_file_range, |
|---|
| 1144 | 1262 | .setlease = cifs_setlease, |
|---|
| 1145 | 1263 | .fallocate = cifs_fallocate, |
|---|
| 1146 | 1264 | }; |
|---|
| .. | .. |
|---|
| 1151 | 1269 | .open = cifs_open, |
|---|
| 1152 | 1270 | .release = cifs_close, |
|---|
| 1153 | 1271 | .lock = cifs_lock, |
|---|
| 1272 | + .flock = cifs_flock, |
|---|
| 1154 | 1273 | .fsync = cifs_strict_fsync, |
|---|
| 1155 | 1274 | .flush = cifs_flush, |
|---|
| 1156 | 1275 | .mmap = cifs_file_strict_mmap, |
|---|
| .. | .. |
|---|
| 1159 | 1278 | .llseek = cifs_llseek, |
|---|
| 1160 | 1279 | .unlocked_ioctl = cifs_ioctl, |
|---|
| 1161 | 1280 | .copy_file_range = cifs_copy_file_range, |
|---|
| 1162 | | - .clone_file_range = cifs_clone_file_range, |
|---|
| 1281 | + .remap_file_range = cifs_remap_file_range, |
|---|
| 1163 | 1282 | .setlease = cifs_setlease, |
|---|
| 1164 | 1283 | .fallocate = cifs_fallocate, |
|---|
| 1165 | 1284 | }; |
|---|
| 1166 | 1285 | |
|---|
| 1167 | 1286 | const struct file_operations cifs_file_direct_ops = { |
|---|
| 1168 | | - /* BB reevaluate whether they can be done with directio, no cache */ |
|---|
| 1169 | | - .read_iter = cifs_user_readv, |
|---|
| 1170 | | - .write_iter = cifs_user_writev, |
|---|
| 1287 | + .read_iter = cifs_direct_readv, |
|---|
| 1288 | + .write_iter = cifs_direct_writev, |
|---|
| 1171 | 1289 | .open = cifs_open, |
|---|
| 1172 | 1290 | .release = cifs_close, |
|---|
| 1173 | 1291 | .lock = cifs_lock, |
|---|
| 1292 | + .flock = cifs_flock, |
|---|
| 1174 | 1293 | .fsync = cifs_fsync, |
|---|
| 1175 | 1294 | .flush = cifs_flush, |
|---|
| 1176 | 1295 | .mmap = cifs_file_mmap, |
|---|
| .. | .. |
|---|
| 1178 | 1297 | .splice_write = iter_file_splice_write, |
|---|
| 1179 | 1298 | .unlocked_ioctl = cifs_ioctl, |
|---|
| 1180 | 1299 | .copy_file_range = cifs_copy_file_range, |
|---|
| 1181 | | - .clone_file_range = cifs_clone_file_range, |
|---|
| 1300 | + .remap_file_range = cifs_remap_file_range, |
|---|
| 1182 | 1301 | .llseek = cifs_llseek, |
|---|
| 1183 | 1302 | .setlease = cifs_setlease, |
|---|
| 1184 | 1303 | .fallocate = cifs_fallocate, |
|---|
| .. | .. |
|---|
| 1197 | 1316 | .llseek = cifs_llseek, |
|---|
| 1198 | 1317 | .unlocked_ioctl = cifs_ioctl, |
|---|
| 1199 | 1318 | .copy_file_range = cifs_copy_file_range, |
|---|
| 1200 | | - .clone_file_range = cifs_clone_file_range, |
|---|
| 1319 | + .remap_file_range = cifs_remap_file_range, |
|---|
| 1201 | 1320 | .setlease = cifs_setlease, |
|---|
| 1202 | 1321 | .fallocate = cifs_fallocate, |
|---|
| 1203 | 1322 | }; |
|---|
| .. | .. |
|---|
| 1215 | 1334 | .llseek = cifs_llseek, |
|---|
| 1216 | 1335 | .unlocked_ioctl = cifs_ioctl, |
|---|
| 1217 | 1336 | .copy_file_range = cifs_copy_file_range, |
|---|
| 1218 | | - .clone_file_range = cifs_clone_file_range, |
|---|
| 1337 | + .remap_file_range = cifs_remap_file_range, |
|---|
| 1219 | 1338 | .setlease = cifs_setlease, |
|---|
| 1220 | 1339 | .fallocate = cifs_fallocate, |
|---|
| 1221 | 1340 | }; |
|---|
| 1222 | 1341 | |
|---|
| 1223 | 1342 | const struct file_operations cifs_file_direct_nobrl_ops = { |
|---|
| 1224 | | - /* BB reevaluate whether they can be done with directio, no cache */ |
|---|
| 1225 | | - .read_iter = cifs_user_readv, |
|---|
| 1226 | | - .write_iter = cifs_user_writev, |
|---|
| 1343 | + .read_iter = cifs_direct_readv, |
|---|
| 1344 | + .write_iter = cifs_direct_writev, |
|---|
| 1227 | 1345 | .open = cifs_open, |
|---|
| 1228 | 1346 | .release = cifs_close, |
|---|
| 1229 | 1347 | .fsync = cifs_fsync, |
|---|
| .. | .. |
|---|
| 1233 | 1351 | .splice_write = iter_file_splice_write, |
|---|
| 1234 | 1352 | .unlocked_ioctl = cifs_ioctl, |
|---|
| 1235 | 1353 | .copy_file_range = cifs_copy_file_range, |
|---|
| 1236 | | - .clone_file_range = cifs_clone_file_range, |
|---|
| 1354 | + .remap_file_range = cifs_remap_file_range, |
|---|
| 1237 | 1355 | .llseek = cifs_llseek, |
|---|
| 1238 | 1356 | .setlease = cifs_setlease, |
|---|
| 1239 | 1357 | .fallocate = cifs_fallocate, |
|---|
| .. | .. |
|---|
| 1245 | 1363 | .read = generic_read_dir, |
|---|
| 1246 | 1364 | .unlocked_ioctl = cifs_ioctl, |
|---|
| 1247 | 1365 | .copy_file_range = cifs_copy_file_range, |
|---|
| 1248 | | - .clone_file_range = cifs_clone_file_range, |
|---|
| 1366 | + .remap_file_range = cifs_remap_file_range, |
|---|
| 1249 | 1367 | .llseek = generic_file_llseek, |
|---|
| 1250 | 1368 | .fsync = cifs_dir_fsync, |
|---|
| 1251 | 1369 | }; |
|---|
| .. | .. |
|---|
| 1424 | 1542 | #ifdef CONFIG_CIFS_STATS2 |
|---|
| 1425 | 1543 | atomic_set(&totBufAllocCount, 0); |
|---|
| 1426 | 1544 | atomic_set(&totSmBufAllocCount, 0); |
|---|
| 1545 | + if (slow_rsp_threshold < 1) |
|---|
| 1546 | + cifs_dbg(FYI, "slow_response_threshold msgs disabled\n"); |
|---|
| 1547 | + else if (slow_rsp_threshold > 32767) |
|---|
| 1548 | + cifs_dbg(VFS, |
|---|
| 1549 | + "slow response threshold set higher than recommended (0 to 32767)\n"); |
|---|
| 1427 | 1550 | #endif /* CONFIG_CIFS_STATS2 */ |
|---|
| 1428 | 1551 | |
|---|
| 1429 | 1552 | atomic_set(&midCount, 0); |
|---|
| .. | .. |
|---|
| 1450 | 1573 | goto out_clean_proc; |
|---|
| 1451 | 1574 | } |
|---|
| 1452 | 1575 | |
|---|
| 1576 | + /* |
|---|
| 1577 | + * Consider in future setting limit!=0 maybe to min(num_of_cores - 1, 3) |
|---|
| 1578 | + * so that we don't launch too many worker threads but |
|---|
| 1579 | + * Documentation/core-api/workqueue.rst recommends setting it to 0 |
|---|
| 1580 | + */ |
|---|
| 1581 | + |
|---|
| 1582 | + /* WQ_UNBOUND allows decrypt tasks to run on any CPU */ |
|---|
| 1583 | + decrypt_wq = alloc_workqueue("smb3decryptd", |
|---|
| 1584 | + WQ_UNBOUND|WQ_FREEZABLE|WQ_MEM_RECLAIM, 0); |
|---|
| 1585 | + if (!decrypt_wq) { |
|---|
| 1586 | + rc = -ENOMEM; |
|---|
| 1587 | + goto out_destroy_cifsiod_wq; |
|---|
| 1588 | + } |
|---|
| 1589 | + |
|---|
| 1590 | + fileinfo_put_wq = alloc_workqueue("cifsfileinfoput", |
|---|
| 1591 | + WQ_UNBOUND|WQ_FREEZABLE|WQ_MEM_RECLAIM, 0); |
|---|
| 1592 | + if (!fileinfo_put_wq) { |
|---|
| 1593 | + rc = -ENOMEM; |
|---|
| 1594 | + goto out_destroy_decrypt_wq; |
|---|
| 1595 | + } |
|---|
| 1596 | + |
|---|
| 1453 | 1597 | cifsoplockd_wq = alloc_workqueue("cifsoplockd", |
|---|
| 1454 | 1598 | WQ_FREEZABLE|WQ_MEM_RECLAIM, 0); |
|---|
| 1455 | 1599 | if (!cifsoplockd_wq) { |
|---|
| 1456 | 1600 | rc = -ENOMEM; |
|---|
| 1457 | | - goto out_destroy_cifsiod_wq; |
|---|
| 1601 | + goto out_destroy_fileinfo_put_wq; |
|---|
| 1458 | 1602 | } |
|---|
| 1459 | 1603 | |
|---|
| 1460 | 1604 | rc = cifs_fscache_register(); |
|---|
| .. | .. |
|---|
| 1473 | 1617 | if (rc) |
|---|
| 1474 | 1618 | goto out_destroy_mids; |
|---|
| 1475 | 1619 | |
|---|
| 1620 | +#ifdef CONFIG_CIFS_DFS_UPCALL |
|---|
| 1621 | + rc = dfs_cache_init(); |
|---|
| 1622 | + if (rc) |
|---|
| 1623 | + goto out_destroy_request_bufs; |
|---|
| 1624 | +#endif /* CONFIG_CIFS_DFS_UPCALL */ |
|---|
| 1476 | 1625 | #ifdef CONFIG_CIFS_UPCALL |
|---|
| 1477 | 1626 | rc = init_cifs_spnego(); |
|---|
| 1478 | 1627 | if (rc) |
|---|
| 1479 | | - goto out_destroy_request_bufs; |
|---|
| 1628 | + goto out_destroy_dfs_cache; |
|---|
| 1480 | 1629 | #endif /* CONFIG_CIFS_UPCALL */ |
|---|
| 1481 | 1630 | |
|---|
| 1482 | | -#ifdef CONFIG_CIFS_ACL |
|---|
| 1483 | 1631 | rc = init_cifs_idmap(); |
|---|
| 1484 | 1632 | if (rc) |
|---|
| 1485 | 1633 | goto out_register_key_type; |
|---|
| 1486 | | -#endif /* CONFIG_CIFS_ACL */ |
|---|
| 1487 | 1634 | |
|---|
| 1488 | 1635 | rc = register_filesystem(&cifs_fs_type); |
|---|
| 1489 | 1636 | if (rc) |
|---|
| .. | .. |
|---|
| 1498 | 1645 | return 0; |
|---|
| 1499 | 1646 | |
|---|
| 1500 | 1647 | out_init_cifs_idmap: |
|---|
| 1501 | | -#ifdef CONFIG_CIFS_ACL |
|---|
| 1502 | 1648 | exit_cifs_idmap(); |
|---|
| 1503 | 1649 | out_register_key_type: |
|---|
| 1504 | | -#endif |
|---|
| 1505 | 1650 | #ifdef CONFIG_CIFS_UPCALL |
|---|
| 1506 | 1651 | exit_cifs_spnego(); |
|---|
| 1652 | +out_destroy_dfs_cache: |
|---|
| 1653 | +#endif |
|---|
| 1654 | +#ifdef CONFIG_CIFS_DFS_UPCALL |
|---|
| 1655 | + dfs_cache_destroy(); |
|---|
| 1507 | 1656 | out_destroy_request_bufs: |
|---|
| 1508 | 1657 | #endif |
|---|
| 1509 | 1658 | cifs_destroy_request_bufs(); |
|---|
| .. | .. |
|---|
| 1515 | 1664 | cifs_fscache_unregister(); |
|---|
| 1516 | 1665 | out_destroy_cifsoplockd_wq: |
|---|
| 1517 | 1666 | destroy_workqueue(cifsoplockd_wq); |
|---|
| 1667 | +out_destroy_fileinfo_put_wq: |
|---|
| 1668 | + destroy_workqueue(fileinfo_put_wq); |
|---|
| 1669 | +out_destroy_decrypt_wq: |
|---|
| 1670 | + destroy_workqueue(decrypt_wq); |
|---|
| 1518 | 1671 | out_destroy_cifsiod_wq: |
|---|
| 1519 | 1672 | destroy_workqueue(cifsiod_wq); |
|---|
| 1520 | 1673 | out_clean_proc: |
|---|
| .. | .. |
|---|
| 1529 | 1682 | unregister_filesystem(&cifs_fs_type); |
|---|
| 1530 | 1683 | unregister_filesystem(&smb3_fs_type); |
|---|
| 1531 | 1684 | cifs_dfs_release_automount_timer(); |
|---|
| 1532 | | -#ifdef CONFIG_CIFS_ACL |
|---|
| 1533 | 1685 | exit_cifs_idmap(); |
|---|
| 1534 | | -#endif |
|---|
| 1535 | 1686 | #ifdef CONFIG_CIFS_UPCALL |
|---|
| 1536 | 1687 | exit_cifs_spnego(); |
|---|
| 1688 | +#endif |
|---|
| 1689 | +#ifdef CONFIG_CIFS_DFS_UPCALL |
|---|
| 1690 | + dfs_cache_destroy(); |
|---|
| 1537 | 1691 | #endif |
|---|
| 1538 | 1692 | cifs_destroy_request_bufs(); |
|---|
| 1539 | 1693 | cifs_destroy_mids(); |
|---|
| 1540 | 1694 | cifs_destroy_inodecache(); |
|---|
| 1541 | 1695 | cifs_fscache_unregister(); |
|---|
| 1542 | 1696 | destroy_workqueue(cifsoplockd_wq); |
|---|
| 1697 | + destroy_workqueue(decrypt_wq); |
|---|
| 1698 | + destroy_workqueue(fileinfo_put_wq); |
|---|
| 1543 | 1699 | destroy_workqueue(cifsiod_wq); |
|---|
| 1544 | 1700 | cifs_proc_clean(); |
|---|
| 1545 | 1701 | } |
|---|
| 1546 | 1702 | |
|---|
| 1547 | | -MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>"); |
|---|
| 1703 | +MODULE_AUTHOR("Steve French"); |
|---|
| 1548 | 1704 | MODULE_LICENSE("GPL"); /* combination of LGPL + GPL source behaves as GPL */ |
|---|
| 1705 | +MODULE_IMPORT_NS(ANDROID_GKI_VFS_EXPORT_ONLY); |
|---|
| 1549 | 1706 | MODULE_DESCRIPTION |
|---|
| 1550 | | - ("VFS to access servers complying with the SNIA CIFS Specification " |
|---|
| 1551 | | - "e.g. Samba and Windows"); |
|---|
| 1707 | + ("VFS to access SMB3 servers e.g. Samba, Macs, Azure and Windows (and " |
|---|
| 1708 | + "also older servers complying with the SNIA CIFS Specification)"); |
|---|
| 1552 | 1709 | MODULE_VERSION(CIFS_VERSION); |
|---|
| 1553 | | -MODULE_SOFTDEP("pre: arc4"); |
|---|
| 1554 | | -MODULE_SOFTDEP("pre: des"); |
|---|
| 1555 | | -MODULE_SOFTDEP("pre: ecb"); |
|---|
| 1556 | | -MODULE_SOFTDEP("pre: hmac"); |
|---|
| 1557 | | -MODULE_SOFTDEP("pre: md4"); |
|---|
| 1558 | | -MODULE_SOFTDEP("pre: md5"); |
|---|
| 1559 | | -MODULE_SOFTDEP("pre: nls"); |
|---|
| 1560 | | -MODULE_SOFTDEP("pre: aes"); |
|---|
| 1561 | | -MODULE_SOFTDEP("pre: cmac"); |
|---|
| 1562 | | -MODULE_SOFTDEP("pre: sha256"); |
|---|
| 1563 | | -MODULE_SOFTDEP("pre: sha512"); |
|---|
| 1564 | | -MODULE_SOFTDEP("pre: aead2"); |
|---|
| 1565 | | -MODULE_SOFTDEP("pre: ccm"); |
|---|
| 1710 | +MODULE_SOFTDEP("ecb"); |
|---|
| 1711 | +MODULE_SOFTDEP("hmac"); |
|---|
| 1712 | +MODULE_SOFTDEP("md4"); |
|---|
| 1713 | +MODULE_SOFTDEP("md5"); |
|---|
| 1714 | +MODULE_SOFTDEP("nls"); |
|---|
| 1715 | +MODULE_SOFTDEP("aes"); |
|---|
| 1716 | +MODULE_SOFTDEP("cmac"); |
|---|
| 1717 | +MODULE_SOFTDEP("sha256"); |
|---|
| 1718 | +MODULE_SOFTDEP("sha512"); |
|---|
| 1719 | +MODULE_SOFTDEP("aead2"); |
|---|
| 1720 | +MODULE_SOFTDEP("ccm"); |
|---|
| 1721 | +MODULE_SOFTDEP("gcm"); |
|---|
| 1566 | 1722 | module_init(init_cifs) |
|---|
| 1567 | 1723 | module_exit(exit_cifs) |
|---|