Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag '5.4-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6

Pull cifs updates from Steve French:
"Various cifs/smb3 fixes (including for share deleted cases) and
features including improved encrypted read performance, and various
debugging improvements.

Note that since I am at a test event this week with the Samba team,
and at the annual Storage Developer Conference/SMB3 Plugfest test
event next week a higher than usual number of fixes is expected later
next week as other features in progress get additional testing and
review during these two events"

* tag '5.4-smb3-fixes' of git://git.samba.org/sfrench/cifs-2.6: (38 commits)
cifs: update internal module version number
cifs: modefromsid: write mode ACE first
cifs: cifsroot: add more err checking
smb3: add missing worker function for SMB3 change notify
cifs: Add support for root file systems
cifs: modefromsid: make room for 4 ACE
smb3: fix potential null dereference in decrypt offload
smb3: fix unmount hang in open_shroot
smb3: allow disabling requesting leases
smb3: improve handling of share deleted (and share recreated)
smb3: display max smb3 requests in flight at any one time
smb3: only offload decryption of read responses if multiple requests
cifs: add a helper to find an existing readable handle to a file
smb3: enable offload of decryption of large reads via mount option
smb3: allow parallelizing decryption of reads
cifs: add a debug macro that prints \\server\share for errors
smb3: fix signing verification of large reads
smb3: allow skipping signature verification for perf sensitive configurations
smb3: add dynamic tracepoints for flush and close
smb3: log warning if CSC policy conflicts with cache mount option
...

+1218 -319
+97
Documentation/filesystems/cifs/cifsroot.txt
··· 1 + Mounting root file system via SMB (cifs.ko) 2 + =========================================== 3 + 4 + Written 2019 by Paulo Alcantara <palcantara@suse.de> 5 + Written 2019 by Aurelien Aptel <aaptel@suse.com> 6 + 7 + The CONFIG_CIFS_ROOT option enables experimental root file system 8 + support over the SMB protocol via cifs.ko. 9 + 10 + It introduces a new kernel command-line option called 'cifsroot=' 11 + which will tell the kernel to mount the root file system over the 12 + network by utilizing SMB or CIFS protocol. 13 + 14 + In order to mount, the network stack will also need to be set up by 15 + using 'ip=' config option. For more details, see 16 + Documentation/filesystems/nfs/nfsroot.txt. 17 + 18 + A CIFS root mount currently requires the use of SMB1+UNIX Extensions 19 + which is only supported by the Samba server. SMB1 is the older 20 + deprecated version of the protocol but it has been extended to support 21 + POSIX features (See [1]). The equivalent extensions for the newer 22 + recommended version of the protocol (SMB3) have not been fully 23 + implemented yet which means SMB3 doesn't support some required POSIX 24 + file system objects (e.g. block devices, pipes, sockets). 25 + 26 + As a result, a CIFS root will default to SMB1 for now but the version 27 + to use can nonetheless be changed via the 'vers=' mount option. This 28 + default will change once the SMB3 POSIX extensions are fully 29 + implemented. 30 + 31 + Server configuration 32 + ==================== 33 + 34 + To enable SMB1+UNIX extensions you will need to set these global 35 + settings in Samba smb.conf: 36 + 37 + [global] 38 + server min protocol = NT1 39 + unix extension = yes # default 40 + 41 + Kernel command line 42 + =================== 43 + 44 + root=/dev/cifs 45 + 46 + This is just a virtual device that basically tells the kernel to mount 47 + the root file system via SMB protocol. 48 + 49 + cifsroot=//<server-ip>/<share>[,options] 50 + 51 + Enables the kernel to mount the root file system via SMB that are 52 + located in the <server-ip> and <share> specified in this option. 53 + 54 + The default mount options are set in fs/cifs/cifsroot.c. 55 + 56 + server-ip 57 + IPv4 address of the server. 58 + 59 + share 60 + Path to SMB share (rootfs). 61 + 62 + options 63 + Optional mount options. For more information, see mount.cifs(8). 64 + 65 + Examples 66 + ======== 67 + 68 + Export root file system as a Samba share in smb.conf file. 69 + 70 + ... 71 + [linux] 72 + path = /path/to/rootfs 73 + read only = no 74 + guest ok = yes 75 + force user = root 76 + force group = root 77 + browseable = yes 78 + writeable = yes 79 + admin users = root 80 + public = yes 81 + create mask = 0777 82 + directory mask = 0777 83 + ... 84 + 85 + Restart smb service. 86 + 87 + # systemctl restart smb 88 + 89 + Test it under QEMU on a kernel built with CONFIG_CIFS_ROOT and 90 + CONFIG_IP_PNP options enabled. 91 + 92 + # qemu-system-x86_64 -enable-kvm -cpu host -m 1024 \ 93 + -kernel /path/to/linux/arch/x86/boot/bzImage -nographic \ 94 + -append "root=/dev/cifs rw ip=dhcp cifsroot=//10.0.2.2/linux,username=foo,password=bar console=ttyS0 3" 95 + 96 + 97 + 1: https://wiki.samba.org/index.php/UNIX_Extensions
+8
fs/cifs/Kconfig
··· 211 211 Makes CIFS FS-Cache capable. Say Y here if you want your CIFS data 212 212 to be cached locally on disk through the general filesystem cache 213 213 manager. If unsure, say N. 214 + 215 + config CIFS_ROOT 216 + bool "SMB root file system (Experimental)" 217 + depends on CIFS=y && IP_PNP 218 + help 219 + Enables root file system support over SMB protocol. 220 + 221 + Most people say N here.
+2
fs/cifs/Makefile
··· 21 21 cifs-$(CONFIG_CIFS_FSCACHE) += fscache.o cache.o 22 22 23 23 cifs-$(CONFIG_CIFS_SMB_DIRECT) += smbdirect.o 24 + 25 + cifs-$(CONFIG_CIFS_ROOT) += cifsroot.o
+2
fs/cifs/cifs_debug.c
··· 452 452 list_for_each(tmp1, &cifs_tcp_ses_list) { 453 453 server = list_entry(tmp1, struct TCP_Server_Info, 454 454 tcp_ses_list); 455 + server->max_in_flight = 0; 455 456 #ifdef CONFIG_CIFS_STATS2 456 457 for (i = 0; i < NUMBER_OF_SMB2_COMMANDS; i++) { 457 458 atomic_set(&server->num_cmds[i], 0); ··· 527 526 list_for_each(tmp1, &cifs_tcp_ses_list) { 528 527 server = list_entry(tmp1, struct TCP_Server_Info, 529 528 tcp_ses_list); 529 + seq_printf(m, "\nMax requests in flight: %d", server->max_in_flight); 530 530 #ifdef CONFIG_CIFS_STATS2 531 531 seq_puts(m, "\nTotal time spent processing by command. Time "); 532 532 seq_printf(m, "units are jiffies (%d per second)\n", HZ);
+67
fs/cifs/cifs_debug.h
··· 80 80 type, fmt, ##__VA_ARGS__); \ 81 81 } while (0) 82 82 83 + #define cifs_server_dbg_func(ratefunc, type, fmt, ...) \ 84 + do { \ 85 + const char *sn = ""; \ 86 + if (server && server->hostname) \ 87 + sn = server->hostname; \ 88 + if ((type) & FYI && cifsFYI & CIFS_INFO) { \ 89 + pr_debug_ ## ratefunc("%s: \\\\%s " fmt, \ 90 + __FILE__, sn, ##__VA_ARGS__); \ 91 + } else if ((type) & VFS) { \ 92 + pr_err_ ## ratefunc("CIFS VFS: \\\\%s " fmt, \ 93 + sn, ##__VA_ARGS__); \ 94 + } else if ((type) & NOISY && (NOISY != 0)) { \ 95 + pr_debug_ ## ratefunc("\\\\%s " fmt, \ 96 + sn, ##__VA_ARGS__); \ 97 + } \ 98 + } while (0) 99 + 100 + #define cifs_server_dbg(type, fmt, ...) \ 101 + do { \ 102 + if ((type) & ONCE) \ 103 + cifs_server_dbg_func(once, \ 104 + type, fmt, ##__VA_ARGS__); \ 105 + else \ 106 + cifs_server_dbg_func(ratelimited, \ 107 + type, fmt, ##__VA_ARGS__); \ 108 + } while (0) 109 + 110 + #define cifs_tcon_dbg_func(ratefunc, type, fmt, ...) \ 111 + do { \ 112 + const char *tn = ""; \ 113 + if (tcon && tcon->treeName) \ 114 + tn = tcon->treeName; \ 115 + if ((type) & FYI && cifsFYI & CIFS_INFO) { \ 116 + pr_debug_ ## ratefunc("%s: %s " fmt, \ 117 + __FILE__, tn, ##__VA_ARGS__); \ 118 + } else if ((type) & VFS) { \ 119 + pr_err_ ## ratefunc("CIFS VFS: %s " fmt, \ 120 + tn, ##__VA_ARGS__); \ 121 + } else if ((type) & NOISY && (NOISY != 0)) { \ 122 + pr_debug_ ## ratefunc("%s " fmt, \ 123 + tn, ##__VA_ARGS__); \ 124 + } \ 125 + } while (0) 126 + 127 + #define cifs_tcon_dbg(type, fmt, ...) \ 128 + do { \ 129 + if ((type) & ONCE) \ 130 + cifs_tcon_dbg_func(once, \ 131 + type, fmt, ##__VA_ARGS__); \ 132 + else \ 133 + cifs_tcon_dbg_func(ratelimited, \ 134 + type, fmt, ##__VA_ARGS__); \ 135 + } while (0) 136 + 83 137 /* 84 138 * debug OFF 85 139 * --------- ··· 143 89 do { \ 144 90 if (0) \ 145 91 pr_debug(fmt, ##__VA_ARGS__); \ 92 + } while (0) 93 + 94 + #define cifs_server_dbg(type, fmt, ...) \ 95 + do { \ 96 + if (0) \ 97 + pr_debug("\\\\%s " fmt, \ 98 + server->hostname, ##__VA_ARGS__); \ 99 + } while (0) 100 + 101 + #define cifs_tcon_dbg(type, fmt, ...) \ 102 + do { \ 103 + if (0) \ 104 + pr_debug("%s " fmt, tcon->treeName, ##__VA_ARGS__); \ 146 105 } while (0) 147 106 148 107 #define cifs_info(fmt, ...) \
+2
fs/cifs/cifs_fs_sb.h
··· 53 53 #define CIFS_MOUNT_NO_HANDLE_CACHE 0x4000000 /* disable caching dir handles */ 54 54 #define CIFS_MOUNT_NO_DFS 0x8000000 /* disable DFS resolving */ 55 55 #define CIFS_MOUNT_MODE_FROM_SID 0x10000000 /* retrieve mode from special ACE */ 56 + #define CIFS_MOUNT_RO_CACHE 0x20000000 /* assumes share will not change */ 57 + #define CIFS_MOUNT_RW_CACHE 0x40000000 /* assumes only client accessing */ 56 58 57 59 struct cifs_sb_info { 58 60 struct rb_root tlink_tree;
+1
fs/cifs/cifs_ioctl.h
··· 46 46 /* query_info flags */ 47 47 #define PASSTHRU_QUERY_INFO 0x00000000 48 48 #define PASSTHRU_FSCTL 0x00000001 49 + #define PASSTHRU_SET_INFO 0x00000002 49 50 struct smb_query_info { 50 51 __u32 info_type; 51 52 __u32 file_info_class;
+65 -16
fs/cifs/cifsacl.c
··· 701 701 } 702 702 #endif 703 703 704 - 705 704 static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, 706 705 struct cifs_sid *pownersid, struct cifs_sid *pgrpsid, 707 - struct cifs_fattr *fattr) 706 + struct cifs_fattr *fattr, bool mode_from_special_sid) 708 707 { 709 708 int i; 710 709 int num_aces = 0; ··· 756 757 #ifdef CONFIG_CIFS_DEBUG2 757 758 dump_ace(ppace[i], end_of_acl); 758 759 #endif 759 - if (compare_sids(&(ppace[i]->sid), pownersid) == 0) 760 + if (mode_from_special_sid && 761 + (compare_sids(&(ppace[i]->sid), 762 + &sid_unix_NFS_mode) == 0)) { 763 + /* 764 + * Full permissions are: 765 + * 07777 = S_ISUID | S_ISGID | S_ISVTX | 766 + * S_IRWXU | S_IRWXG | S_IRWXO 767 + */ 768 + fattr->cf_mode &= ~07777; 769 + fattr->cf_mode |= 770 + le32_to_cpu(ppace[i]->sid.sub_auth[2]); 771 + break; 772 + } else if (compare_sids(&(ppace[i]->sid), pownersid) == 0) 760 773 access_flags_to_mode(ppace[i]->access_req, 761 774 ppace[i]->type, 762 775 &fattr->cf_mode, 763 776 &user_mask); 764 - if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0) 777 + else if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0) 765 778 access_flags_to_mode(ppace[i]->access_req, 766 779 ppace[i]->type, 767 780 &fattr->cf_mode, 768 781 &group_mask); 769 - if (compare_sids(&(ppace[i]->sid), &sid_everyone) == 0) 782 + else if (compare_sids(&(ppace[i]->sid), &sid_everyone) == 0) 770 783 access_flags_to_mode(ppace[i]->access_req, 771 784 ppace[i]->type, 772 785 &fattr->cf_mode, 773 786 &other_mask); 774 - if (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0) 787 + else if (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0) 775 788 access_flags_to_mode(ppace[i]->access_req, 776 789 ppace[i]->type, 777 790 &fattr->cf_mode, ··· 806 795 807 796 808 797 static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid, 809 - struct cifs_sid *pgrpsid, __u64 nmode) 798 + struct cifs_sid *pgrpsid, __u64 nmode, bool modefromsid) 810 799 { 811 800 u16 size = 0; 801 + u32 num_aces = 0; 812 802 struct cifs_acl *pnndacl; 813 803 814 804 pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl)); 815 805 806 + if (modefromsid) { 807 + struct cifs_ace *pntace = 808 + (struct cifs_ace *)((char *)pnndacl + size); 809 + int i; 810 + 811 + pntace->type = ACCESS_ALLOWED; 812 + pntace->flags = 0x0; 813 + pntace->access_req = 0; 814 + pntace->sid.num_subauth = 3; 815 + pntace->sid.revision = 1; 816 + for (i = 0; i < NUM_AUTHS; i++) 817 + pntace->sid.authority[i] = 818 + sid_unix_NFS_mode.authority[i]; 819 + pntace->sid.sub_auth[0] = sid_unix_NFS_mode.sub_auth[0]; 820 + pntace->sid.sub_auth[1] = sid_unix_NFS_mode.sub_auth[1]; 821 + pntace->sid.sub_auth[2] = cpu_to_le32(nmode & 07777); 822 + 823 + /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */ 824 + pntace->size = cpu_to_le16(28); 825 + size += 28; 826 + num_aces++; 827 + } 828 + 816 829 size += fill_ace_for_sid((struct cifs_ace *) ((char *)pnndacl + size), 817 830 pownersid, nmode, S_IRWXU); 831 + num_aces++; 818 832 size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size), 819 833 pgrpsid, nmode, S_IRWXG); 834 + num_aces++; 820 835 size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size), 821 836 &sid_everyone, nmode, S_IRWXO); 837 + num_aces++; 822 838 839 + pndacl->num_aces = cpu_to_le32(num_aces); 823 840 pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl)); 824 - pndacl->num_aces = cpu_to_le32(3); 825 841 826 842 return 0; 827 843 } ··· 889 851 890 852 /* Convert CIFS ACL to POSIX form */ 891 853 static int parse_sec_desc(struct cifs_sb_info *cifs_sb, 892 - struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr) 854 + struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr, 855 + bool get_mode_from_special_sid) 893 856 { 894 857 int rc = 0; 895 858 struct cifs_sid *owner_sid_ptr, *group_sid_ptr; ··· 939 900 940 901 if (dacloffset) 941 902 parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr, 942 - group_sid_ptr, fattr); 903 + group_sid_ptr, fattr, get_mode_from_special_sid); 943 904 else 944 905 cifs_dbg(FYI, "no ACL\n"); /* BB grant all or default perms? */ 945 906 ··· 948 909 949 910 /* Convert permission bits from mode to equivalent CIFS ACL */ 950 911 static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, 951 - __u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid, int *aclflag) 912 + __u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid, 913 + bool mode_from_sid, int *aclflag) 952 914 { 953 915 int rc = 0; 954 916 __u32 dacloffset; ··· 974 934 ndacl_ptr->num_aces = 0; 975 935 976 936 rc = set_chmod_dacl(ndacl_ptr, owner_sid_ptr, group_sid_ptr, 977 - nmode); 937 + nmode, mode_from_sid); 978 938 sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size); 979 939 /* copy sec desc control portion & owner and group sids */ 980 940 copy_sec_desc(pntsd, pnntsd, sidsoffset); ··· 1168 1128 /* Translate the CIFS ACL (similar to NTFS ACL) for a file into mode bits */ 1169 1129 int 1170 1130 cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, 1171 - struct inode *inode, const char *path, 1172 - const struct cifs_fid *pfid) 1131 + struct inode *inode, bool mode_from_special_sid, 1132 + const char *path, const struct cifs_fid *pfid) 1173 1133 { 1174 1134 struct cifs_ntsd *pntsd = NULL; 1175 1135 u32 acllen = 0; ··· 1196 1156 if (IS_ERR(pntsd)) { 1197 1157 rc = PTR_ERR(pntsd); 1198 1158 cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc); 1159 + } else if (mode_from_special_sid) { 1160 + rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, true); 1199 1161 } else { 1200 - rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr); 1162 + /* get approximated mode from ACL */ 1163 + rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, false); 1201 1164 kfree(pntsd); 1202 1165 if (rc) 1203 1166 cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc); ··· 1224 1181 struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); 1225 1182 struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); 1226 1183 struct smb_version_operations *ops; 1184 + bool mode_from_sid; 1227 1185 1228 1186 if (IS_ERR(tlink)) 1229 1187 return PTR_ERR(tlink); ··· 1262 1218 return -ENOMEM; 1263 1219 } 1264 1220 1221 + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID) 1222 + mode_from_sid = true; 1223 + else 1224 + mode_from_sid = false; 1225 + 1265 1226 rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid, 1266 - &aclflag); 1227 + mode_from_sid, &aclflag); 1267 1228 1268 1229 cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc); 1269 1230
+1 -1
fs/cifs/cifsacl.h
··· 45 45 */ 46 46 #define DEFAULT_SEC_DESC_LEN (sizeof(struct cifs_ntsd) + \ 47 47 sizeof(struct cifs_acl) + \ 48 - (sizeof(struct cifs_ace) * 3)) 48 + (sizeof(struct cifs_ace) * 4)) 49 49 50 50 /* 51 51 * Maximum size of a string representation of a SID:
+27 -1
fs/cifs/cifsfs.c
··· 118 118 extern mempool_t *cifs_mid_poolp; 119 119 120 120 struct workqueue_struct *cifsiod_wq; 121 + struct workqueue_struct *decrypt_wq; 121 122 struct workqueue_struct *cifsoplockd_wq; 122 123 __u32 cifs_lock_secret; 123 124 ··· 423 422 seq_puts(s, "strict"); 424 423 else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) 425 424 seq_puts(s, "none"); 425 + else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RW_CACHE) 426 + seq_puts(s, "singleclient"); /* assume only one client access */ 427 + else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE) 428 + seq_puts(s, "ro"); /* read only caching assumed */ 426 429 else 427 430 seq_puts(s, "loose"); 428 431 } ··· 460 455 cifs_show_security(s, tcon->ses); 461 456 cifs_show_cache_flavor(s, cifs_sb); 462 457 458 + if (tcon->no_lease) 459 + seq_puts(s, ",nolease"); 463 460 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) 464 461 seq_puts(s, ",multiuser"); 465 462 else if (tcon->ses->user_name) ··· 583 576 seq_printf(s, ",rsize=%u", cifs_sb->rsize); 584 577 seq_printf(s, ",wsize=%u", cifs_sb->wsize); 585 578 seq_printf(s, ",bsize=%u", cifs_sb->bsize); 579 + if (tcon->ses->server->min_offload) 580 + seq_printf(s, ",esize=%u", tcon->ses->server->min_offload); 586 581 seq_printf(s, ",echo_interval=%lu", 587 582 tcon->ses->server->echo_interval / HZ); 588 583 ··· 1526 1517 goto out_clean_proc; 1527 1518 } 1528 1519 1520 + /* 1521 + * Consider in future setting limit!=0 maybe to min(num_of_cores - 1, 3) 1522 + * so that we don't launch too many worker threads but 1523 + * Documentation/workqueue.txt recommends setting it to 0 1524 + */ 1525 + 1526 + /* WQ_UNBOUND allows decrypt tasks to run on any CPU */ 1527 + decrypt_wq = alloc_workqueue("smb3decryptd", 1528 + WQ_UNBOUND|WQ_FREEZABLE|WQ_MEM_RECLAIM, 0); 1529 + if (!decrypt_wq) { 1530 + rc = -ENOMEM; 1531 + goto out_destroy_cifsiod_wq; 1532 + } 1533 + 1529 1534 cifsoplockd_wq = alloc_workqueue("cifsoplockd", 1530 1535 WQ_FREEZABLE|WQ_MEM_RECLAIM, 0); 1531 1536 if (!cifsoplockd_wq) { 1532 1537 rc = -ENOMEM; 1533 - goto out_destroy_cifsiod_wq; 1538 + goto out_destroy_decrypt_wq; 1534 1539 } 1535 1540 1536 1541 rc = cifs_fscache_register(); ··· 1610 1587 cifs_fscache_unregister(); 1611 1588 out_destroy_cifsoplockd_wq: 1612 1589 destroy_workqueue(cifsoplockd_wq); 1590 + out_destroy_decrypt_wq: 1591 + destroy_workqueue(decrypt_wq); 1613 1592 out_destroy_cifsiod_wq: 1614 1593 destroy_workqueue(cifsiod_wq); 1615 1594 out_clean_proc: ··· 1638 1613 cifs_destroy_inodecache(); 1639 1614 cifs_fscache_unregister(); 1640 1615 destroy_workqueue(cifsoplockd_wq); 1616 + destroy_workqueue(decrypt_wq); 1641 1617 destroy_workqueue(cifsiod_wq); 1642 1618 cifs_proc_clean(); 1643 1619 }
+1 -1
fs/cifs/cifsfs.h
··· 152 152 extern const struct export_operations cifs_export_ops; 153 153 #endif /* CONFIG_CIFS_NFSD_EXPORT */ 154 154 155 - #define CIFS_VERSION "2.22" 155 + #define CIFS_VERSION "2.23" 156 156 #endif /* _CIFSFS_H */
+16 -3
fs/cifs/cifsglob.h
··· 542 542 umode_t dir_mode; 543 543 enum securityEnum sectype; /* sectype requested via mnt opts */ 544 544 bool sign; /* was signing requested via mnt opts? */ 545 + bool ignore_signature:1; 545 546 bool retry:1; 546 547 bool intr:1; 547 548 bool setuids:1; ··· 560 559 bool server_ino:1; /* use inode numbers from server ie UniqueId */ 561 560 bool direct_io:1; 562 561 bool strict_io:1; /* strict cache behavior */ 562 + bool cache_ro:1; 563 + bool cache_rw:1; 563 564 bool remap:1; /* set to remap seven reserved chars in filenames */ 564 565 bool sfu_remap:1; /* remap seven reserved chars ala SFU */ 565 566 bool posix_paths:1; /* unset to not ask for posix pathnames. */ ··· 579 576 bool noblocksnd:1; 580 577 bool noautotune:1; 581 578 bool nostrictsync:1; /* do not force expensive SMBflush on every sync */ 579 + bool no_lease:1; /* disable requesting leases */ 582 580 bool fsc:1; /* enable fscache */ 583 581 bool mfsymlinks:1; /* use Minshall+French Symlinks */ 584 582 bool multiuser:1; ··· 593 589 unsigned int bsize; 594 590 unsigned int rsize; 595 591 unsigned int wsize; 592 + unsigned int min_offload; 596 593 bool sockopt_tcp_nodelay:1; 597 594 unsigned long actimeo; /* attribute cache timeout (jiffies) */ 598 595 struct smb_version_operations *ops; ··· 607 602 __u32 handle_timeout; /* persistent and durable handle timeout in ms */ 608 603 unsigned int max_credits; /* smb3 max_credits 10 < credits < 60000 */ 609 604 __u16 compression; /* compression algorithm 0xFFFF default 0=disabled */ 605 + bool rootfs:1; /* if it's a SMB root file system */ 610 606 }; 611 607 612 608 /** ··· 626 620 CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_STRICT_IO | \ 627 621 CIFS_MOUNT_CIFS_BACKUPUID | CIFS_MOUNT_CIFS_BACKUPGID | \ 628 622 CIFS_MOUNT_UID_FROM_ACL | CIFS_MOUNT_NO_HANDLE_CACHE | \ 629 - CIFS_MOUNT_NO_DFS | CIFS_MOUNT_MODE_FROM_SID) 623 + CIFS_MOUNT_NO_DFS | CIFS_MOUNT_MODE_FROM_SID | \ 624 + CIFS_MOUNT_RO_CACHE | CIFS_MOUNT_RW_CACHE) 630 625 631 626 /** 632 627 * Generic VFS superblock mount flags (s_flags) to consider when ··· 679 672 unsigned int credits; /* send no more requests at once */ 680 673 unsigned int max_credits; /* can override large 32000 default at mnt */ 681 674 unsigned int in_flight; /* number of requests on the wire to server */ 675 + unsigned int max_in_flight; /* max number of requests that were on wire */ 682 676 spinlock_t req_lock; /* protect the two values above */ 683 677 struct mutex srv_mutex; 684 678 struct task_struct *tsk; 685 679 char server_GUID[16]; 686 680 __u16 sec_mode; 687 681 bool sign; /* is signing enabled on this connection? */ 682 + bool ignore_signature:1; /* skip validation of signatures in SMB2/3 rsp */ 688 683 bool session_estab; /* mark when very first sess is established */ 689 684 int echo_credits; /* echo reserved slots */ 690 685 int oplock_credits; /* oplock break reserved slots */ ··· 749 740 #endif /* STATS2 */ 750 741 unsigned int max_read; 751 742 unsigned int max_write; 743 + unsigned int min_offload; 752 744 __le16 compress_algorithm; 753 745 __le16 cipher_type; 754 746 /* save initital negprot hash */ ··· 765 755 * reconnect. 766 756 */ 767 757 int nr_targets; 758 + bool noblockcnt; /* use non-blocking connect() */ 768 759 }; 769 760 770 761 struct cifs_credits { ··· 1093 1082 bool need_reopen_files:1; /* need to reopen tcon file handles */ 1094 1083 bool use_resilient:1; /* use resilient instead of durable handles */ 1095 1084 bool use_persistent:1; /* use persistent instead of durable handles */ 1085 + bool no_lease:1; /* Do not request leases on files or directories */ 1096 1086 __le32 capabilities; 1097 1087 __u32 share_flags; 1098 1088 __u32 maximal_access; ··· 1378 1366 #define CIFS_CACHE_RW_FLG (CIFS_CACHE_READ_FLG | CIFS_CACHE_WRITE_FLG) 1379 1367 #define CIFS_CACHE_RHW_FLG (CIFS_CACHE_RW_FLG | CIFS_CACHE_HANDLE_FLG) 1380 1368 1381 - #define CIFS_CACHE_READ(cinode) (cinode->oplock & CIFS_CACHE_READ_FLG) 1369 + #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)) 1382 1370 #define CIFS_CACHE_HANDLE(cinode) (cinode->oplock & CIFS_CACHE_HANDLE_FLG) 1383 - #define CIFS_CACHE_WRITE(cinode) (cinode->oplock & CIFS_CACHE_WRITE_FLG) 1371 + #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)) 1384 1372 1385 1373 /* 1386 1374 * One of these for each file inode ··· 1899 1887 1900 1888 extern const struct slow_work_ops cifs_oplock_break_ops; 1901 1889 extern struct workqueue_struct *cifsiod_wq; 1890 + extern struct workqueue_struct *decrypt_wq; 1902 1891 extern struct workqueue_struct *cifsoplockd_wq; 1903 1892 extern __u32 cifs_lock_secret; 1904 1893
+5
fs/cifs/cifsproto.h
··· 137 137 extern int cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, 138 138 bool fsuid_only, 139 139 struct cifsFileInfo **ret_file); 140 + extern int cifs_get_writable_path(struct cifs_tcon *tcon, const char *name, 141 + struct cifsFileInfo **ret_file); 140 142 extern struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *, bool); 143 + extern int cifs_get_readable_path(struct cifs_tcon *tcon, const char *name, 144 + struct cifsFileInfo **ret_file); 141 145 extern unsigned int smbCalcSize(void *buf, struct TCP_Server_Info *server); 142 146 extern int decode_negTokenInit(unsigned char *security_blob, int length, 143 147 struct TCP_Server_Info *server); ··· 201 197 const unsigned int xid); 202 198 extern int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, 203 199 struct cifs_fattr *fattr, struct inode *inode, 200 + bool get_mode_from_special_sid, 204 201 const char *path, const struct cifs_fid *pfid); 205 202 extern int id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64, 206 203 kuid_t, kgid_t);
+94
fs/cifs/cifsroot.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * SMB root file system support 4 + * 5 + * Copyright (c) 2019 Paulo Alcantara <palcantara@suse.de> 6 + */ 7 + #include <linux/init.h> 8 + #include <linux/fs.h> 9 + #include <linux/types.h> 10 + #include <linux/ctype.h> 11 + #include <linux/string.h> 12 + #include <linux/root_dev.h> 13 + #include <linux/kernel.h> 14 + #include <linux/in.h> 15 + #include <linux/inet.h> 16 + #include <net/ipconfig.h> 17 + 18 + #define DEFAULT_MNT_OPTS \ 19 + "vers=1.0,cifsacl,mfsymlinks,rsize=1048576,wsize=65536,uid=0,gid=0," \ 20 + "hard,rootfs" 21 + 22 + static char root_dev[2048] __initdata = ""; 23 + static char root_opts[1024] __initdata = DEFAULT_MNT_OPTS; 24 + 25 + static __be32 __init parse_srvaddr(char *start, char *end) 26 + { 27 + /* TODO: ipv6 support */ 28 + char addr[sizeof("aaa.bbb.ccc.ddd")]; 29 + int i = 0; 30 + 31 + while (start < end && i < sizeof(addr) - 1) { 32 + if (isdigit(*start) || *start == '.') 33 + addr[i++] = *start; 34 + start++; 35 + } 36 + addr[i] = '\0'; 37 + return in_aton(addr); 38 + } 39 + 40 + /* cifsroot=//<server-ip>/<share>[,options] */ 41 + static int __init cifs_root_setup(char *line) 42 + { 43 + char *s; 44 + int len; 45 + __be32 srvaddr = htonl(INADDR_NONE); 46 + 47 + ROOT_DEV = Root_CIFS; 48 + 49 + if (strlen(line) > 3 && line[0] == '/' && line[1] == '/') { 50 + s = strchr(&line[2], '/'); 51 + if (!s || s[1] == '\0') 52 + return 1; 53 + 54 + /* make s point to ',' or '\0' at end of line */ 55 + s = strchrnul(s, ','); 56 + /* len is strlen(unc) + '\0' */ 57 + len = s - line + 1; 58 + if (len > sizeof(root_dev)) { 59 + printk(KERN_ERR "Root-CIFS: UNC path too long\n"); 60 + return 1; 61 + } 62 + strlcpy(root_dev, line, len); 63 + srvaddr = parse_srvaddr(&line[2], s); 64 + if (*s) { 65 + int n = snprintf(root_opts, 66 + sizeof(root_opts), "%s,%s", 67 + DEFAULT_MNT_OPTS, s + 1); 68 + if (n >= sizeof(root_opts)) { 69 + printk(KERN_ERR "Root-CIFS: mount options string too long\n"); 70 + root_opts[sizeof(root_opts)-1] = '\0'; 71 + return 1; 72 + } 73 + } 74 + } 75 + 76 + root_server_addr = srvaddr; 77 + 78 + return 1; 79 + } 80 + 81 + __setup("cifsroot=", cifs_root_setup); 82 + 83 + int __init cifs_root_data(char **dev, char **opts) 84 + { 85 + if (!root_dev[0] || root_server_addr == htonl(INADDR_NONE)) { 86 + printk(KERN_ERR "Root-CIFS: no SMB server address\n"); 87 + return -1; 88 + } 89 + 90 + *dev = root_dev; 91 + *opts = root_opts; 92 + 93 + return 0; 94 + }
+1 -1
fs/cifs/cifssmb.c
··· 1393 1393 CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock, 1394 1394 FILE_ALL_INFO *buf) 1395 1395 { 1396 - int rc = -EACCES; 1396 + int rc; 1397 1397 OPEN_REQ *req = NULL; 1398 1398 OPEN_RSP *rsp = NULL; 1399 1399 int bytes_returned;
+120 -32
fs/cifs/connect.c
··· 74 74 Opt_user_xattr, Opt_nouser_xattr, 75 75 Opt_forceuid, Opt_noforceuid, 76 76 Opt_forcegid, Opt_noforcegid, 77 - Opt_noblocksend, Opt_noautotune, 77 + Opt_noblocksend, Opt_noautotune, Opt_nolease, 78 78 Opt_hard, Opt_soft, Opt_perm, Opt_noperm, 79 79 Opt_mapposix, Opt_nomapposix, 80 80 Opt_mapchars, Opt_nomapchars, Opt_sfu, ··· 91 91 Opt_serverino, Opt_noserverino, 92 92 Opt_rwpidforward, Opt_cifsacl, Opt_nocifsacl, 93 93 Opt_acl, Opt_noacl, Opt_locallease, 94 - Opt_sign, Opt_seal, Opt_noac, 94 + Opt_sign, Opt_ignore_signature, Opt_seal, Opt_noac, 95 95 Opt_fsc, Opt_mfsymlinks, 96 96 Opt_multiuser, Opt_sloppy, Opt_nosharesock, 97 97 Opt_persistent, Opt_nopersistent, 98 98 Opt_resilient, Opt_noresilient, 99 - Opt_domainauto, Opt_rdma, Opt_modesid, 99 + Opt_domainauto, Opt_rdma, Opt_modesid, Opt_rootfs, 100 100 Opt_compress, 101 101 102 102 /* Mount options which take numeric value */ 103 103 Opt_backupuid, Opt_backupgid, Opt_uid, 104 104 Opt_cruid, Opt_gid, Opt_file_mode, 105 105 Opt_dirmode, Opt_port, 106 + Opt_min_enc_offload, 106 107 Opt_blocksize, Opt_rsize, Opt_wsize, Opt_actimeo, 107 108 Opt_echo_interval, Opt_max_credits, Opt_handletimeout, 108 109 Opt_snapshot, ··· 135 134 { Opt_noforcegid, "noforcegid" }, 136 135 { Opt_noblocksend, "noblocksend" }, 137 136 { Opt_noautotune, "noautotune" }, 137 + { Opt_nolease, "nolease" }, 138 138 { Opt_hard, "hard" }, 139 139 { Opt_soft, "soft" }, 140 140 { Opt_perm, "perm" }, ··· 185 183 { Opt_noacl, "noacl" }, 186 184 { Opt_locallease, "locallease" }, 187 185 { Opt_sign, "sign" }, 186 + { Opt_ignore_signature, "signloosely" }, 188 187 { Opt_seal, "seal" }, 189 188 { Opt_noac, "noac" }, 190 189 { Opt_fsc, "fsc" }, ··· 209 206 { Opt_dirmode, "dirmode=%s" }, 210 207 { Opt_dirmode, "dir_mode=%s" }, 211 208 { Opt_port, "port=%s" }, 209 + { Opt_min_enc_offload, "esize=%s" }, 212 210 { Opt_blocksize, "bsize=%s" }, 213 211 { Opt_rsize, "rsize=%s" }, 214 212 { Opt_wsize, "wsize=%s" }, ··· 266 262 { Opt_ignore, "nomand" }, 267 263 { Opt_ignore, "relatime" }, 268 264 { Opt_ignore, "_netdev" }, 265 + { Opt_rootfs, "rootfs" }, 269 266 270 267 { Opt_err, NULL } 271 268 }; ··· 303 298 Opt_cache_loose, 304 299 Opt_cache_strict, 305 300 Opt_cache_none, 301 + Opt_cache_ro, 302 + Opt_cache_rw, 306 303 Opt_cache_err 307 304 }; 308 305 ··· 312 305 { Opt_cache_loose, "loose" }, 313 306 { Opt_cache_strict, "strict" }, 314 307 { Opt_cache_none, "none" }, 308 + { Opt_cache_ro, "ro" }, 309 + { Opt_cache_rw, "singleclient" }, 315 310 { Opt_cache_err, NULL } 316 311 }; 317 312 ··· 498 489 } else { 499 490 rc = reconn_setup_dfs_targets(cifs_sb, &tgt_list, &tgt_it); 500 491 if (rc && (rc != -EOPNOTSUPP)) { 501 - cifs_dbg(VFS, "%s: no target servers for DFS failover\n", 492 + cifs_server_dbg(VFS, "%s: no target servers for DFS failover\n", 502 493 __func__); 503 494 } else { 504 495 server->nr_targets = dfs_cache_get_nr_tgts(&tgt_list); ··· 626 617 rc = dfs_cache_noreq_update_tgthint(cifs_sb->origin_fullpath + 1, 627 618 tgt_it); 628 619 if (rc) { 629 - cifs_dbg(VFS, "%s: failed to update DFS target hint: rc = %d\n", 620 + cifs_server_dbg(VFS, "%s: failed to update DFS target hint: rc = %d\n", 630 621 __func__, rc); 631 622 } 632 623 rc = dfs_cache_update_vol(cifs_sb->origin_fullpath, server); 633 624 if (rc) { 634 - cifs_dbg(VFS, "%s: failed to update vol info in DFS cache: rc = %d\n", 625 + cifs_server_dbg(VFS, "%s: failed to update vol info in DFS cache: rc = %d\n", 635 626 __func__, rc); 636 627 } 637 628 dfs_cache_free_tgts(&tgt_list); ··· 687 678 if (!server->bigbuf) { 688 679 server->bigbuf = (char *)cifs_buf_get(); 689 680 if (!server->bigbuf) { 690 - cifs_dbg(VFS, "No memory for large SMB response\n"); 681 + cifs_server_dbg(VFS, "No memory for large SMB response\n"); 691 682 msleep(3000); 692 683 /* retry will check if exiting */ 693 684 return false; ··· 700 691 if (!server->smallbuf) { 701 692 server->smallbuf = (char *)cifs_small_buf_get(); 702 693 if (!server->smallbuf) { 703 - cifs_dbg(VFS, "No memory for SMB response\n"); 694 + cifs_server_dbg(VFS, "No memory for SMB response\n"); 704 695 msleep(1000); 705 696 /* retry will check if exiting */ 706 697 return false; ··· 721 712 * We need to wait 3 echo intervals to make sure we handle such 722 713 * situations right: 723 714 * 1s client sends a normal SMB request 724 - * 3s client gets a response 715 + * 2s client gets a response 725 716 * 30s echo workqueue job pops, and decides we got a response recently 726 717 * and don't need to send another 727 718 * ... ··· 731 722 if ((server->tcpStatus == CifsGood || 732 723 server->tcpStatus == CifsNeedNegotiate) && 733 724 time_after(jiffies, server->lstrp + 3 * server->echo_interval)) { 734 - cifs_dbg(VFS, "Server %s has not responded in %lu seconds. Reconnecting...\n", 735 - server->hostname, (3 * server->echo_interval) / HZ); 725 + cifs_server_dbg(VFS, "has not responded in %lu seconds. Reconnecting...\n", 726 + (3 * server->echo_interval) / HZ); 736 727 cifs_reconnect(server); 737 728 wake_up(&server->response_q); 738 729 return true; ··· 870 861 wake_up(&server->response_q); 871 862 break; 872 863 default: 873 - cifs_dbg(VFS, "RFC 1002 unknown response type 0x%x\n", type); 864 + cifs_server_dbg(VFS, "RFC 1002 unknown response type 0x%x\n", type); 874 865 cifs_reconnect(server); 875 866 } 876 867 ··· 1017 1008 /* make sure this will fit in a large buffer */ 1018 1009 if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE(server) - 1019 1010 server->vals->header_preamble_size) { 1020 - cifs_dbg(VFS, "SMB response too long (%u bytes)\n", pdu_length); 1011 + cifs_server_dbg(VFS, "SMB response too long (%u bytes)\n", pdu_length); 1021 1012 cifs_reconnect(server); 1022 1013 wake_up(&server->response_q); 1023 1014 return -ECONNABORTED; ··· 1158 1149 /* make sure we have enough to get to the MID */ 1159 1150 if (server->pdu_size < HEADER_SIZE(server) - 1 - 1160 1151 server->vals->header_preamble_size) { 1161 - cifs_dbg(VFS, "SMB response too short (%u bytes)\n", 1152 + cifs_server_dbg(VFS, "SMB response too short (%u bytes)\n", 1162 1153 server->pdu_size); 1163 1154 cifs_reconnect(server); 1164 1155 wake_up(&server->response_q); ··· 1231 1222 smb2_add_credits_from_hdr(bufs[i], server); 1232 1223 cifs_dbg(FYI, "Received oplock break\n"); 1233 1224 } else { 1234 - cifs_dbg(VFS, "No task to wake, unknown frame " 1225 + cifs_server_dbg(VFS, "No task to wake, unknown frame " 1235 1226 "received! NumMids %d\n", 1236 1227 atomic_read(&midCount)); 1237 1228 cifs_dump_mem("Received Data is: ", bufs[i], ··· 1427 1418 case Opt_cache_loose: 1428 1419 vol->direct_io = false; 1429 1420 vol->strict_io = false; 1421 + vol->cache_ro = false; 1422 + vol->cache_rw = false; 1430 1423 break; 1431 1424 case Opt_cache_strict: 1432 1425 vol->direct_io = false; 1433 1426 vol->strict_io = true; 1427 + vol->cache_ro = false; 1428 + vol->cache_rw = false; 1434 1429 break; 1435 1430 case Opt_cache_none: 1436 1431 vol->direct_io = true; 1437 1432 vol->strict_io = false; 1433 + vol->cache_ro = false; 1434 + vol->cache_rw = false; 1435 + break; 1436 + case Opt_cache_ro: 1437 + vol->direct_io = false; 1438 + vol->strict_io = false; 1439 + vol->cache_ro = true; 1440 + vol->cache_rw = false; 1441 + break; 1442 + case Opt_cache_rw: 1443 + vol->direct_io = false; 1444 + vol->strict_io = false; 1445 + vol->cache_ro = false; 1446 + vol->cache_rw = true; 1438 1447 break; 1439 1448 default: 1440 1449 cifs_dbg(VFS, "bad cache= option: %s\n", value); ··· 1740 1713 case Opt_noautotune: 1741 1714 vol->noautotune = 1; 1742 1715 break; 1716 + case Opt_nolease: 1717 + vol->no_lease = 1; 1718 + break; 1743 1719 case Opt_hard: 1744 1720 vol->retry = 1; 1745 1721 break; ··· 1777 1747 break; 1778 1748 case Opt_nodfs: 1779 1749 vol->nodfs = 1; 1750 + break; 1751 + case Opt_rootfs: 1752 + #ifdef CONFIG_CIFS_ROOT 1753 + vol->rootfs = true; 1754 + #endif 1780 1755 break; 1781 1756 case Opt_posixpaths: 1782 1757 vol->posix_paths = 1; ··· 1889 1854 break; 1890 1855 case Opt_sign: 1891 1856 vol->sign = true; 1857 + break; 1858 + case Opt_ignore_signature: 1859 + vol->sign = true; 1860 + vol->ignore_signature = true; 1892 1861 break; 1893 1862 case Opt_seal: 1894 1863 /* we do not do the following in secFlags because seal ··· 2027 1988 goto cifs_parse_mount_err; 2028 1989 } 2029 1990 port = (unsigned short)option; 1991 + break; 1992 + case Opt_min_enc_offload: 1993 + if (get_option_ul(args, &option)) { 1994 + cifs_dbg(VFS, "Invalid minimum encrypted read offload size (esize)\n"); 1995 + goto cifs_parse_mount_err; 1996 + } 1997 + vol->min_offload = option; 2030 1998 break; 2031 1999 case Opt_blocksize: 2032 2000 if (get_option_ul(args, &option)) { ··· 2632 2586 if (server->rdma != vol->rdma) 2633 2587 return 0; 2634 2588 2589 + if (server->ignore_signature != vol->ignore_signature) 2590 + return 0; 2591 + 2592 + if (server->min_offload != vol->min_offload) 2593 + return 0; 2594 + 2635 2595 return 1; 2636 2596 } 2637 2597 ··· 2733 2681 goto out_err_crypto_release; 2734 2682 } 2735 2683 2736 - tcp_ses->noblocksnd = volume_info->noblocksnd; 2684 + tcp_ses->noblockcnt = volume_info->rootfs; 2685 + tcp_ses->noblocksnd = volume_info->noblocksnd || volume_info->rootfs; 2737 2686 tcp_ses->noautotune = volume_info->noautotune; 2738 2687 tcp_ses->tcp_nodelay = volume_info->sockopt_tcp_nodelay; 2739 2688 tcp_ses->rdma = volume_info->rdma; 2740 2689 tcp_ses->in_flight = 0; 2690 + tcp_ses->max_in_flight = 0; 2741 2691 tcp_ses->credits = 1; 2742 2692 init_waitqueue_head(&tcp_ses->response_q); 2743 2693 init_waitqueue_head(&tcp_ses->request_q); ··· 2814 2760 module_put(THIS_MODULE); 2815 2761 goto out_err_crypto_release; 2816 2762 } 2763 + tcp_ses->min_offload = volume_info->min_offload; 2817 2764 tcp_ses->tcpStatus = CifsNeedNegotiate; 2818 2765 2819 2766 tcp_ses->nr_targets = 1; 2820 - 2767 + tcp_ses->ignore_signature = volume_info->ignore_signature; 2821 2768 /* thread spawned, put it on the list */ 2822 2769 spin_lock(&cifs_tcp_ses_lock); 2823 2770 list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list); ··· 2895 2840 struct nls_table *nls_codepage; 2896 2841 char unc[SERVER_NAME_LENGTH + sizeof("//x/IPC$")] = {0}; 2897 2842 bool seal = false; 2843 + struct TCP_Server_Info *server = ses->server; 2898 2844 2899 2845 /* 2900 2846 * If the mount request that resulted in the creation of the 2901 2847 * session requires encryption, force IPC to be encrypted too. 2902 2848 */ 2903 2849 if (volume_info->seal) { 2904 - if (ses->server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION) 2850 + if (server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION) 2905 2851 seal = true; 2906 2852 else { 2907 - cifs_dbg(VFS, 2853 + cifs_server_dbg(VFS, 2908 2854 "IPC: server doesn't support encryption\n"); 2909 2855 return -EOPNOTSUPP; 2910 2856 } ··· 2915 2859 if (tcon == NULL) 2916 2860 return -ENOMEM; 2917 2861 2918 - scnprintf(unc, sizeof(unc), "\\\\%s\\IPC$", ses->server->hostname); 2862 + scnprintf(unc, sizeof(unc), "\\\\%s\\IPC$", server->hostname); 2919 2863 2920 2864 /* cannot fail */ 2921 2865 nls_codepage = load_nls_default(); ··· 2924 2868 tcon->ses = ses; 2925 2869 tcon->ipc = true; 2926 2870 tcon->seal = seal; 2927 - rc = ses->server->ops->tree_connect(xid, ses, unc, tcon, nls_codepage); 2871 + rc = server->ops->tree_connect(xid, ses, unc, tcon, nls_codepage); 2928 2872 free_xid(xid); 2929 2873 2930 2874 if (rc) { 2931 - cifs_dbg(VFS, "failed to connect to IPC (rc=%d)\n", rc); 2875 + cifs_server_dbg(VFS, "failed to connect to IPC (rc=%d)\n", rc); 2932 2876 tconInfoFree(tcon); 2933 2877 goto out; 2934 2878 } ··· 3014 2958 xid = get_xid(); 3015 2959 rc = server->ops->logoff(xid, ses); 3016 2960 if (rc) 3017 - cifs_dbg(VFS, "%s: Session Logoff failure rc=%d\n", 2961 + cifs_server_dbg(VFS, "%s: Session Logoff failure rc=%d\n", 3018 2962 __func__, rc); 3019 2963 _free_xid(xid); 3020 2964 } ··· 3268 3212 3269 3213 ses->sectype = volume_info->sectype; 3270 3214 ses->sign = volume_info->sign; 3271 - 3272 3215 mutex_lock(&ses->session_mutex); 3273 3216 rc = cifs_negotiate_protocol(xid, ses); 3274 3217 if (!rc) ··· 3304 3249 if (tcon->snapshot_time != volume_info->snapshot_time) 3305 3250 return 0; 3306 3251 if (tcon->handle_timeout != volume_info->handle_timeout) 3252 + return 0; 3253 + if (tcon->no_lease != volume_info->no_lease) 3307 3254 return 0; 3308 3255 return 1; 3309 3256 } ··· 3512 3455 tcon->use_resilient = true; 3513 3456 } 3514 3457 3458 + /* If the user really knows what they are doing they can override */ 3459 + if (tcon->share_flags & SMB2_SHAREFLAG_NO_CACHING) { 3460 + if (volume_info->cache_ro) 3461 + cifs_dbg(VFS, "cache=ro requested on mount but NO_CACHING flag set on share\n"); 3462 + else if (volume_info->cache_rw) 3463 + cifs_dbg(VFS, "cache=singleclient requested on mount but NO_CACHING flag set on share\n"); 3464 + } 3465 + 3515 3466 /* 3516 3467 * We can have only one retry value for a connection to a share so for 3517 3468 * resources mounted more than once to the same server share the last ··· 3529 3464 tcon->nocase = volume_info->nocase; 3530 3465 tcon->nohandlecache = volume_info->nohandlecache; 3531 3466 tcon->local_lease = volume_info->local_lease; 3467 + tcon->no_lease = volume_info->no_lease; 3532 3468 INIT_LIST_HEAD(&tcon->pending_opens); 3533 3469 3534 3470 spin_lock(&cifs_tcp_ses_lock); ··· 3725 3659 saddr4 = (struct sockaddr_in *)&server->srcaddr; 3726 3660 saddr6 = (struct sockaddr_in6 *)&server->srcaddr; 3727 3661 if (saddr6->sin6_family == AF_INET6) 3728 - cifs_dbg(VFS, "Failed to bind to: %pI6c, error: %d\n", 3662 + cifs_server_dbg(VFS, "Failed to bind to: %pI6c, error: %d\n", 3729 3663 &saddr6->sin6_addr, rc); 3730 3664 else 3731 - cifs_dbg(VFS, "Failed to bind to: %pI4, error: %d\n", 3665 + cifs_server_dbg(VFS, "Failed to bind to: %pI4, error: %d\n", 3732 3666 &saddr4->sin_addr.s_addr, rc); 3733 3667 } 3734 3668 } ··· 3832 3766 rc = __sock_create(cifs_net_ns(server), sfamily, SOCK_STREAM, 3833 3767 IPPROTO_TCP, &socket, 1); 3834 3768 if (rc < 0) { 3835 - cifs_dbg(VFS, "Error %d creating socket\n", rc); 3769 + cifs_server_dbg(VFS, "Error %d creating socket\n", rc); 3836 3770 server->ssocket = NULL; 3837 3771 return rc; 3838 3772 } ··· 3880 3814 socket->sk->sk_sndbuf, 3881 3815 socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo); 3882 3816 3883 - rc = socket->ops->connect(socket, saddr, slen, 0); 3817 + rc = socket->ops->connect(socket, saddr, slen, 3818 + server->noblockcnt ? O_NONBLOCK : 0); 3819 + 3820 + if (rc == -EINPROGRESS) 3821 + rc = 0; 3884 3822 if (rc < 0) { 3885 3823 cifs_dbg(FYI, "Error %d connecting to server\n", rc); 3886 3824 sock_release(socket); ··· 4110 4040 cifs_dbg(FYI, "mounting share using direct i/o\n"); 4111 4041 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; 4112 4042 } 4043 + if (pvolume_info->cache_ro) { 4044 + cifs_dbg(VFS, "mounting share with read only caching. Ensure that the share will not be modified while in use.\n"); 4045 + cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RO_CACHE; 4046 + } else if (pvolume_info->cache_rw) { 4047 + cifs_dbg(VFS, "mounting share in single client RW caching mode. Ensure that no other systems will be accessing the share.\n"); 4048 + cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_RO_CACHE | 4049 + CIFS_MOUNT_RW_CACHE); 4050 + } 4113 4051 if (pvolume_info->mfsymlinks) { 4114 4052 if (pvolume_info->sfu_emul) { 4115 4053 /* ··· 4228 4150 4229 4151 if ((vol->persistent == true) && (!(ses->server->capabilities & 4230 4152 SMB2_GLOBAL_CAP_PERSISTENT_HANDLES))) { 4231 - cifs_dbg(VFS, "persistent handles not supported by server\n"); 4153 + cifs_server_dbg(VFS, "persistent handles not supported by server\n"); 4232 4154 return -EOPNOTSUPP; 4233 4155 } 4234 4156 ··· 4260 4182 tcon->unix_ext = 0; /* server does not support them */ 4261 4183 4262 4184 /* do not care if a following call succeed - informational */ 4263 - if (!tcon->pipe && server->ops->qfs_tcon) 4185 + if (!tcon->pipe && server->ops->qfs_tcon) { 4264 4186 server->ops->qfs_tcon(*xid, tcon); 4187 + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE) { 4188 + if (tcon->fsDevInfo.DeviceCharacteristics & 4189 + FILE_READ_ONLY_DEVICE) 4190 + cifs_dbg(VFS, "mounted to read only share\n"); 4191 + else if ((cifs_sb->mnt_cifs_flags & 4192 + CIFS_MOUNT_RW_CACHE) == 0) 4193 + cifs_dbg(VFS, "read only mount of RW share\n"); 4194 + /* no need to log a RW mount of a typical RW share */ 4195 + } 4196 + } 4265 4197 4266 4198 cifs_sb->wsize = server->ops->negotiate_wsize(tcon, vol); 4267 4199 cifs_sb->rsize = server->ops->negotiate_rsize(tcon, vol); ··· 4676 4588 rc = cifs_are_all_path_components_accessible(server, xid, tcon, 4677 4589 cifs_sb, full_path, tcon->Flags & SMB_SHARE_IS_IN_DFS); 4678 4590 if (rc != 0) { 4679 - cifs_dbg(VFS, "cannot query dirs between root and final path, " 4591 + cifs_server_dbg(VFS, "cannot query dirs between root and final path, " 4680 4592 "enabling CIFS_MOUNT_USE_PREFIX_PATH\n"); 4681 4593 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH; 4682 4594 rc = 0; ··· 5178 5090 rc = server->ops->sess_setup(xid, ses, nls_info); 5179 5091 5180 5092 if (rc) 5181 - cifs_dbg(VFS, "Send error in SessSetup = %d\n", rc); 5093 + cifs_server_dbg(VFS, "Send error in SessSetup = %d\n", rc); 5182 5094 5183 5095 return rc; 5184 5096 }
+1 -1
fs/cifs/dir.c
··· 125 125 } 126 126 rcu_read_unlock(); 127 127 128 - full_path = kmalloc(namelen+1, GFP_KERNEL); 128 + full_path = kmalloc(namelen+1, GFP_ATOMIC); 129 129 if (full_path == NULL) 130 130 return full_path; 131 131 full_path[namelen] = 0; /* trailing null */
+71 -9
fs/cifs/file.c
··· 1693 1693 bool posix_lck = false; 1694 1694 struct cifs_sb_info *cifs_sb; 1695 1695 struct cifs_tcon *tcon; 1696 - struct cifsInodeInfo *cinode; 1697 1696 struct cifsFileInfo *cfile; 1698 - __u16 netfid; 1699 1697 __u32 type; 1700 1698 1701 1699 rc = -EACCES; ··· 1709 1711 cifs_read_flock(flock, &type, &lock, &unlock, &wait_flag, 1710 1712 tcon->ses->server); 1711 1713 cifs_sb = CIFS_FILE_SB(file); 1712 - netfid = cfile->fid.netfid; 1713 - cinode = CIFS_I(file_inode(file)); 1714 1714 1715 1715 if (cap_unix(tcon->ses) && 1716 1716 (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) && ··· 1760 1764 int rc = 0; 1761 1765 unsigned int bytes_written = 0; 1762 1766 unsigned int total_written; 1763 - struct cifs_sb_info *cifs_sb; 1764 1767 struct cifs_tcon *tcon; 1765 1768 struct TCP_Server_Info *server; 1766 1769 unsigned int xid; 1767 1770 struct dentry *dentry = open_file->dentry; 1768 1771 struct cifsInodeInfo *cifsi = CIFS_I(d_inode(dentry)); 1769 1772 struct cifs_io_parms io_parms; 1770 - 1771 - cifs_sb = CIFS_SB(dentry->d_sb); 1772 1773 1773 1774 cifs_dbg(FYI, "write %zd bytes to offset %lld of %pd\n", 1774 1775 write_size, *offset, dentry); ··· 1971 1978 cifs_dbg(FYI, "couldn't find writable handle rc=%d", rc); 1972 1979 1973 1980 return cfile; 1981 + } 1982 + 1983 + int 1984 + cifs_get_writable_path(struct cifs_tcon *tcon, const char *name, 1985 + struct cifsFileInfo **ret_file) 1986 + { 1987 + struct list_head *tmp; 1988 + struct cifsFileInfo *cfile; 1989 + struct cifsInodeInfo *cinode; 1990 + char *full_path; 1991 + 1992 + *ret_file = NULL; 1993 + 1994 + spin_lock(&tcon->open_file_lock); 1995 + list_for_each(tmp, &tcon->openFileList) { 1996 + cfile = list_entry(tmp, struct cifsFileInfo, 1997 + tlist); 1998 + full_path = build_path_from_dentry(cfile->dentry); 1999 + if (full_path == NULL) { 2000 + spin_unlock(&tcon->open_file_lock); 2001 + return -ENOMEM; 2002 + } 2003 + if (strcmp(full_path, name)) { 2004 + kfree(full_path); 2005 + continue; 2006 + } 2007 + 2008 + kfree(full_path); 2009 + cinode = CIFS_I(d_inode(cfile->dentry)); 2010 + spin_unlock(&tcon->open_file_lock); 2011 + return cifs_get_writable_file(cinode, 0, ret_file); 2012 + } 2013 + 2014 + spin_unlock(&tcon->open_file_lock); 2015 + return -ENOENT; 2016 + } 2017 + 2018 + int 2019 + cifs_get_readable_path(struct cifs_tcon *tcon, const char *name, 2020 + struct cifsFileInfo **ret_file) 2021 + { 2022 + struct list_head *tmp; 2023 + struct cifsFileInfo *cfile; 2024 + struct cifsInodeInfo *cinode; 2025 + char *full_path; 2026 + 2027 + *ret_file = NULL; 2028 + 2029 + spin_lock(&tcon->open_file_lock); 2030 + list_for_each(tmp, &tcon->openFileList) { 2031 + cfile = list_entry(tmp, struct cifsFileInfo, 2032 + tlist); 2033 + full_path = build_path_from_dentry(cfile->dentry); 2034 + if (full_path == NULL) { 2035 + spin_unlock(&tcon->open_file_lock); 2036 + return -ENOMEM; 2037 + } 2038 + if (strcmp(full_path, name)) { 2039 + kfree(full_path); 2040 + continue; 2041 + } 2042 + 2043 + kfree(full_path); 2044 + cinode = CIFS_I(d_inode(cfile->dentry)); 2045 + spin_unlock(&tcon->open_file_lock); 2046 + *ret_file = find_readable_file(cinode, 0); 2047 + return *ret_file ? 0 : -ENOENT; 2048 + } 2049 + 2050 + spin_unlock(&tcon->open_file_lock); 2051 + return -ENOENT; 1974 2052 } 1975 2053 1976 2054 static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) ··· 3641 3577 struct cifs_readdata *rdata, *tmp; 3642 3578 struct iov_iter *to = &ctx->iter; 3643 3579 struct cifs_sb_info *cifs_sb; 3644 - struct cifs_tcon *tcon; 3645 3580 int rc; 3646 3581 3647 - tcon = tlink_tcon(ctx->cfile->tlink); 3648 3582 cifs_sb = CIFS_SB(ctx->cfile->dentry->d_sb); 3649 3583 3650 3584 mutex_lock(&ctx->aio_mutex);
+15 -4
fs/cifs/inode.c
··· 893 893 } 894 894 895 895 /* fill in 0777 bits from ACL */ 896 - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { 897 - rc = cifs_acl_to_fattr(cifs_sb, &fattr, *inode, full_path, fid); 896 + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID) { 897 + rc = cifs_acl_to_fattr(cifs_sb, &fattr, *inode, true, 898 + full_path, fid); 899 + if (rc) { 900 + cifs_dbg(FYI, "%s: Get mode from SID failed. rc=%d\n", 901 + __func__, rc); 902 + goto cgii_exit; 903 + } 904 + } else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { 905 + rc = cifs_acl_to_fattr(cifs_sb, &fattr, *inode, false, 906 + full_path, fid); 898 907 if (rc) { 899 908 cifs_dbg(FYI, "%s: Getting ACL failed with error: %d\n", 900 909 __func__, rc); ··· 2489 2480 if (attrs->ia_valid & ATTR_GID) 2490 2481 gid = attrs->ia_gid; 2491 2482 2492 - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { 2483 + if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) || 2484 + (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)) { 2493 2485 if (uid_valid(uid) || gid_valid(gid)) { 2494 2486 rc = id_mode_to_cifs_acl(inode, full_path, NO_CHANGE_64, 2495 2487 uid, gid); ··· 2511 2501 if (attrs->ia_valid & ATTR_MODE) { 2512 2502 mode = attrs->ia_mode; 2513 2503 rc = 0; 2514 - if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { 2504 + if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) || 2505 + (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)) { 2515 2506 rc = id_mode_to_cifs_acl(inode, full_path, mode, 2516 2507 INVALID_UID, INVALID_GID); 2517 2508 if (rc) {
+118 -35
fs/cifs/smb2inode.c
··· 51 51 smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, 52 52 struct cifs_sb_info *cifs_sb, const char *full_path, 53 53 __u32 desired_access, __u32 create_disposition, 54 - __u32 create_options, void *ptr, int command) 54 + __u32 create_options, void *ptr, int command, 55 + struct cifsFileInfo *cfile) 55 56 { 56 57 int rc; 57 58 __le16 *utf16_path = NULL; ··· 84 83 resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER; 85 84 memset(rsp_iov, 0, sizeof(rsp_iov)); 86 85 86 + /* We already have a handle so we can skip the open */ 87 + if (cfile) 88 + goto after_open; 89 + 87 90 /* Open */ 88 91 utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb); 89 - if (!utf16_path) 90 - return -ENOMEM; 92 + if (!utf16_path) { 93 + rc = -ENOMEM; 94 + goto finished; 95 + } 91 96 92 97 oparms.tcon = tcon; 93 98 oparms.desired_access = desired_access; ··· 113 106 if (rc) 114 107 goto finished; 115 108 116 - smb2_set_next_command(tcon, &rqst[num_rqst++]); 109 + smb2_set_next_command(tcon, &rqst[num_rqst]); 110 + after_open: 111 + num_rqst++; 112 + rc = 0; 117 113 118 114 /* Operation */ 119 115 switch (command) { ··· 125 115 rqst[num_rqst].rq_iov = qi_iov; 126 116 rqst[num_rqst].rq_nvec = 1; 127 117 128 - rc = SMB2_query_info_init(tcon, &rqst[num_rqst], COMPOUND_FID, 129 - COMPOUND_FID, FILE_ALL_INFORMATION, 118 + if (cfile) 119 + rc = SMB2_query_info_init(tcon, &rqst[num_rqst], 120 + cfile->fid.persistent_fid, 121 + cfile->fid.volatile_fid, 122 + FILE_ALL_INFORMATION, 130 123 SMB2_O_INFO_FILE, 0, 131 124 sizeof(struct smb2_file_all_info) + 132 125 PATH_MAX * 2, 0, NULL); 126 + else { 127 + rc = SMB2_query_info_init(tcon, &rqst[num_rqst], 128 + COMPOUND_FID, 129 + COMPOUND_FID, 130 + FILE_ALL_INFORMATION, 131 + SMB2_O_INFO_FILE, 0, 132 + sizeof(struct smb2_file_all_info) + 133 + PATH_MAX * 2, 0, NULL); 134 + if (!rc) { 135 + smb2_set_next_command(tcon, &rqst[num_rqst]); 136 + smb2_set_related(&rqst[num_rqst]); 137 + } 138 + } 139 + 133 140 if (rc) 134 141 goto finished; 135 - smb2_set_next_command(tcon, &rqst[num_rqst]); 136 - smb2_set_related(&rqst[num_rqst++]); 142 + num_rqst++; 137 143 trace_smb3_query_info_compound_enter(xid, ses->Suid, tcon->tid, 138 144 full_path); 139 145 break; ··· 208 182 size[0] = sizeof(FILE_BASIC_INFO); 209 183 data[0] = ptr; 210 184 211 - rc = SMB2_set_info_init(tcon, &rqst[num_rqst], COMPOUND_FID, 212 - COMPOUND_FID, current->tgid, 213 - FILE_BASIC_INFORMATION, 214 - SMB2_O_INFO_FILE, 0, data, size); 185 + if (cfile) 186 + rc = SMB2_set_info_init(tcon, &rqst[num_rqst], 187 + cfile->fid.persistent_fid, 188 + cfile->fid.volatile_fid, current->tgid, 189 + FILE_BASIC_INFORMATION, 190 + SMB2_O_INFO_FILE, 0, data, size); 191 + else { 192 + rc = SMB2_set_info_init(tcon, &rqst[num_rqst], 193 + COMPOUND_FID, 194 + COMPOUND_FID, current->tgid, 195 + FILE_BASIC_INFORMATION, 196 + SMB2_O_INFO_FILE, 0, data, size); 197 + if (!rc) { 198 + smb2_set_next_command(tcon, &rqst[num_rqst]); 199 + smb2_set_related(&rqst[num_rqst]); 200 + } 201 + } 202 + 215 203 if (rc) 216 204 goto finished; 217 - smb2_set_next_command(tcon, &rqst[num_rqst]); 218 - smb2_set_related(&rqst[num_rqst++]); 205 + num_rqst++; 219 206 trace_smb3_set_info_compound_enter(xid, ses->Suid, tcon->tid, 220 207 full_path); 221 208 break; ··· 249 210 size[1] = len + 2 /* null */; 250 211 data[1] = (__le16 *)ptr; 251 212 252 - rc = SMB2_set_info_init(tcon, &rqst[num_rqst], COMPOUND_FID, 253 - COMPOUND_FID, current->tgid, 254 - FILE_RENAME_INFORMATION, 213 + if (cfile) 214 + rc = SMB2_set_info_init(tcon, &rqst[num_rqst], 215 + cfile->fid.persistent_fid, 216 + cfile->fid.volatile_fid, 217 + current->tgid, FILE_RENAME_INFORMATION, 255 218 SMB2_O_INFO_FILE, 0, data, size); 219 + else { 220 + rc = SMB2_set_info_init(tcon, &rqst[num_rqst], 221 + COMPOUND_FID, COMPOUND_FID, 222 + current->tgid, FILE_RENAME_INFORMATION, 223 + SMB2_O_INFO_FILE, 0, data, size); 224 + if (!rc) { 225 + smb2_set_next_command(tcon, &rqst[num_rqst]); 226 + smb2_set_related(&rqst[num_rqst]); 227 + } 228 + } 256 229 if (rc) 257 230 goto finished; 258 - smb2_set_next_command(tcon, &rqst[num_rqst]); 259 - smb2_set_related(&rqst[num_rqst++]); 231 + num_rqst++; 260 232 trace_smb3_rename_enter(xid, ses->Suid, tcon->tid, full_path); 261 233 break; 262 234 case SMB2_OP_HARDLINK: ··· 304 254 if (rc) 305 255 goto finished; 306 256 257 + /* We already have a handle so we can skip the close */ 258 + if (cfile) 259 + goto after_close; 307 260 /* Close */ 308 261 memset(&close_iov, 0, sizeof(close_iov)); 309 262 rqst[num_rqst].rq_iov = close_iov; 310 263 rqst[num_rqst].rq_nvec = 1; 311 264 rc = SMB2_close_init(tcon, &rqst[num_rqst], COMPOUND_FID, 312 265 COMPOUND_FID); 313 - smb2_set_related(&rqst[num_rqst++]); 266 + smb2_set_related(&rqst[num_rqst]); 314 267 if (rc) 315 268 goto finished; 269 + after_close: 270 + num_rqst++; 316 271 317 - rc = compound_send_recv(xid, ses, flags, num_rqst, rqst, 318 - resp_buftype, rsp_iov); 272 + if (cfile) { 273 + cifsFileInfo_put(cfile); 274 + cfile = NULL; 275 + rc = compound_send_recv(xid, ses, flags, num_rqst - 2, 276 + &rqst[1], &resp_buftype[1], 277 + &rsp_iov[1]); 278 + } else 279 + rc = compound_send_recv(xid, ses, flags, num_rqst, 280 + rqst, resp_buftype, 281 + rsp_iov); 319 282 320 283 finished: 284 + if (cfile) 285 + cifsFileInfo_put(cfile); 286 + 321 287 SMB2_open_free(&rqst[0]); 288 + if (rc == -EREMCHG) { 289 + printk_once(KERN_WARNING "server share %s deleted\n", 290 + tcon->treeName); 291 + tcon->need_reconnect = true; 292 + } 293 + 322 294 switch (command) { 323 295 case SMB2_OP_QUERY_INFO: 324 296 if (rc == 0) { ··· 443 371 __u32 create_options = 0; 444 372 struct cifs_fid fid; 445 373 bool no_cached_open = tcon->nohandlecache; 374 + struct cifsFileInfo *cfile; 446 375 447 376 *adjust_tz = false; 448 377 *symlink = false; ··· 475 402 if (backup_cred(cifs_sb)) 476 403 create_options |= CREATE_OPEN_BACKUP_INTENT; 477 404 405 + cifs_get_readable_path(tcon, full_path, &cfile); 478 406 rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, 479 407 FILE_READ_ATTRIBUTES, FILE_OPEN, create_options, 480 - smb2_data, SMB2_OP_QUERY_INFO); 408 + smb2_data, SMB2_OP_QUERY_INFO, cfile); 481 409 if (rc == -EOPNOTSUPP) { 482 410 *symlink = true; 483 411 create_options |= OPEN_REPARSE_POINT; ··· 487 413 rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, 488 414 FILE_READ_ATTRIBUTES, FILE_OPEN, 489 415 create_options, smb2_data, 490 - SMB2_OP_QUERY_INFO); 416 + SMB2_OP_QUERY_INFO, NULL); 491 417 } 492 418 if (rc) 493 419 goto out; ··· 504 430 { 505 431 return smb2_compound_op(xid, tcon, cifs_sb, name, 506 432 FILE_WRITE_ATTRIBUTES, FILE_CREATE, 507 - CREATE_NOT_FILE, NULL, SMB2_OP_MKDIR); 433 + CREATE_NOT_FILE, NULL, SMB2_OP_MKDIR, NULL); 508 434 } 509 435 510 436 void ··· 514 440 { 515 441 FILE_BASIC_INFO data; 516 442 struct cifsInodeInfo *cifs_i; 443 + struct cifsFileInfo *cfile; 517 444 u32 dosattrs; 518 445 int tmprc; 519 446 ··· 522 447 cifs_i = CIFS_I(inode); 523 448 dosattrs = cifs_i->cifsAttrs | ATTR_READONLY; 524 449 data.Attributes = cpu_to_le32(dosattrs); 450 + cifs_get_writable_path(tcon, name, &cfile); 525 451 tmprc = smb2_compound_op(xid, tcon, cifs_sb, name, 526 452 FILE_WRITE_ATTRIBUTES, FILE_CREATE, 527 - CREATE_NOT_FILE, &data, SMB2_OP_SET_INFO); 453 + CREATE_NOT_FILE, &data, SMB2_OP_SET_INFO, 454 + cfile); 528 455 if (tmprc == 0) 529 456 cifs_i->cifsAttrs = dosattrs; 530 457 } ··· 537 460 { 538 461 return smb2_compound_op(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN, 539 462 CREATE_NOT_FILE, 540 - NULL, SMB2_OP_RMDIR); 463 + NULL, SMB2_OP_RMDIR, NULL); 541 464 } 542 465 543 466 int ··· 546 469 { 547 470 return smb2_compound_op(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN, 548 471 CREATE_DELETE_ON_CLOSE | OPEN_REPARSE_POINT, 549 - NULL, SMB2_OP_DELETE); 472 + NULL, SMB2_OP_DELETE, NULL); 550 473 } 551 474 552 475 static int 553 476 smb2_set_path_attr(const unsigned int xid, struct cifs_tcon *tcon, 554 477 const char *from_name, const char *to_name, 555 - struct cifs_sb_info *cifs_sb, __u32 access, int command) 478 + struct cifs_sb_info *cifs_sb, __u32 access, int command, 479 + struct cifsFileInfo *cfile) 556 480 { 557 481 __le16 *smb2_to_name = NULL; 558 482 int rc; ··· 564 486 goto smb2_rename_path; 565 487 } 566 488 rc = smb2_compound_op(xid, tcon, cifs_sb, from_name, access, 567 - FILE_OPEN, 0, smb2_to_name, command); 489 + FILE_OPEN, 0, smb2_to_name, command, cfile); 568 490 smb2_rename_path: 569 491 kfree(smb2_to_name); 570 492 return rc; ··· 575 497 const char *from_name, const char *to_name, 576 498 struct cifs_sb_info *cifs_sb) 577 499 { 578 - return smb2_set_path_attr(xid, tcon, from_name, to_name, cifs_sb, 579 - DELETE, SMB2_OP_RENAME); 500 + struct cifsFileInfo *cfile; 501 + 502 + cifs_get_writable_path(tcon, from_name, &cfile); 503 + 504 + return smb2_set_path_attr(xid, tcon, from_name, to_name, 505 + cifs_sb, DELETE, SMB2_OP_RENAME, cfile); 580 506 } 581 507 582 508 int ··· 589 507 struct cifs_sb_info *cifs_sb) 590 508 { 591 509 return smb2_set_path_attr(xid, tcon, from_name, to_name, cifs_sb, 592 - FILE_READ_ATTRIBUTES, SMB2_OP_HARDLINK); 510 + FILE_READ_ATTRIBUTES, SMB2_OP_HARDLINK, 511 + NULL); 593 512 } 594 513 595 514 int ··· 602 519 603 520 return smb2_compound_op(xid, tcon, cifs_sb, full_path, 604 521 FILE_WRITE_DATA, FILE_OPEN, 0, &eof, 605 - SMB2_OP_SET_EOF); 522 + SMB2_OP_SET_EOF, NULL); 606 523 } 607 524 608 525 int ··· 624 541 625 542 rc = smb2_compound_op(xid, tlink_tcon(tlink), cifs_sb, full_path, 626 543 FILE_WRITE_ATTRIBUTES, FILE_OPEN, 0, buf, 627 - SMB2_OP_SET_INFO); 544 + SMB2_OP_SET_INFO, NULL); 628 545 cifs_put_tlink(tlink); 629 546 return rc; 630 547 }
+1 -1
fs/cifs/smb2maperror.c
··· 511 511 {STATUS_PRINT_QUEUE_FULL, -EIO, "STATUS_PRINT_QUEUE_FULL"}, 512 512 {STATUS_NO_SPOOL_SPACE, -EIO, "STATUS_NO_SPOOL_SPACE"}, 513 513 {STATUS_PRINT_CANCELLED, -EIO, "STATUS_PRINT_CANCELLED"}, 514 - {STATUS_NETWORK_NAME_DELETED, -EIO, "STATUS_NETWORK_NAME_DELETED"}, 514 + {STATUS_NETWORK_NAME_DELETED, -EREMCHG, "STATUS_NETWORK_NAME_DELETED"}, 515 515 {STATUS_NETWORK_ACCESS_DENIED, -EACCES, "STATUS_NETWORK_ACCESS_DENIED"}, 516 516 {STATUS_BAD_DEVICE_TYPE, -EIO, "STATUS_BAD_DEVICE_TYPE"}, 517 517 {STATUS_BAD_NETWORK_NAME, -ENOENT, "STATUS_BAD_NETWORK_NAME"},
+154 -47
fs/cifs/smb2ops.c
··· 109 109 /* change_conf hasn't been executed */ 110 110 break; 111 111 case 0: 112 - cifs_dbg(VFS, "Possible client or server bug - zero credits\n"); 112 + cifs_server_dbg(VFS, "Possible client or server bug - zero credits\n"); 113 113 break; 114 114 case 1: 115 - cifs_dbg(VFS, "disabling echoes and oplocks\n"); 115 + cifs_server_dbg(VFS, "disabling echoes and oplocks\n"); 116 116 break; 117 117 case 2: 118 118 cifs_dbg(FYI, "disabling oplocks\n"); ··· 203 203 credits->instance = server->reconnect_instance; 204 204 server->credits -= credits->value; 205 205 server->in_flight++; 206 + if (server->in_flight > server->max_in_flight) 207 + server->max_in_flight = server->in_flight; 206 208 break; 207 209 } 208 210 } ··· 232 230 233 231 if (server->reconnect_instance != credits->instance) { 234 232 spin_unlock(&server->req_lock); 235 - cifs_dbg(VFS, "trying to return %d credits to old session\n", 233 + cifs_server_dbg(VFS, "trying to return %d credits to old session\n", 236 234 credits->value - new_val); 237 235 return -EAGAIN; 238 236 } ··· 272 270 __u64 wire_mid = le64_to_cpu(shdr->MessageId); 273 271 274 272 if (shdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM) { 275 - cifs_dbg(VFS, "Encrypted frame parsing not supported yet\n"); 273 + cifs_server_dbg(VFS, "Encrypted frame parsing not supported yet\n"); 276 274 return NULL; 277 275 } 278 276 ··· 296 294 #ifdef CONFIG_CIFS_DEBUG2 297 295 struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf; 298 296 299 - cifs_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Mid: %llu Pid: %d\n", 297 + cifs_server_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Mid: %llu Pid: %d\n", 300 298 shdr->Command, shdr->Status, shdr->Flags, shdr->MessageId, 301 299 shdr->ProcessId); 302 - cifs_dbg(VFS, "smb buf %p len %u\n", buf, 300 + cifs_server_dbg(VFS, "smb buf %p len %u\n", buf, 303 301 server->ops->calc_smb_size(buf, server)); 304 302 #endif 305 303 } ··· 578 576 "server does not support query network interfaces\n"); 579 577 goto out; 580 578 } else if (rc != 0) { 581 - cifs_dbg(VFS, "error %d on ioctl to get interface list\n", rc); 579 + cifs_tcon_dbg(VFS, "error %d on ioctl to get interface list\n", rc); 582 580 goto out; 583 581 } 584 582 ··· 658 656 return 0; 659 657 } 660 658 659 + /* 660 + * We do not hold the lock for the open because in case 661 + * SMB2_open needs to reconnect, it will end up calling 662 + * cifs_mark_open_files_invalid() which takes the lock again 663 + * thus causing a deadlock 664 + */ 665 + 666 + mutex_unlock(&tcon->crfid.fid_mutex); 667 + 661 668 if (smb3_encryption_required(tcon)) 662 669 flags |= CIFS_TRANSFORM_REQ; 663 670 ··· 688 677 689 678 rc = SMB2_open_init(tcon, &rqst[0], &oplock, &oparms, &utf16_path); 690 679 if (rc) 691 - goto oshr_exit; 680 + goto oshr_free; 692 681 smb2_set_next_command(tcon, &rqst[0]); 693 682 694 683 memset(&qi_iov, 0, sizeof(qi_iov)); ··· 701 690 sizeof(struct smb2_file_all_info) + 702 691 PATH_MAX * 2, 0, NULL); 703 692 if (rc) 704 - goto oshr_exit; 693 + goto oshr_free; 705 694 706 695 smb2_set_related(&rqst[1]); 707 696 708 - /* 709 - * We do not hold the lock for the open because in case 710 - * SMB2_open needs to reconnect, it will end up calling 711 - * cifs_mark_open_files_invalid() which takes the lock again 712 - * thus causing a deadlock 713 - */ 714 - 715 - mutex_unlock(&tcon->crfid.fid_mutex); 716 697 rc = compound_send_recv(xid, ses, flags, 2, rqst, 717 698 resp_buftype, rsp_iov); 718 699 mutex_lock(&tcon->crfid.fid_mutex); ··· 742 739 743 740 /* Cached root is still invalid, continue normaly */ 744 741 745 - if (rc) 742 + if (rc) { 743 + if (rc == -EREMCHG) { 744 + tcon->need_reconnect = true; 745 + printk_once(KERN_WARNING "server share %s deleted\n", 746 + tcon->treeName); 747 + } 746 748 goto oshr_exit; 749 + } 747 750 748 751 o_rsp = (struct smb2_create_rsp *)rsp_iov[0].iov_base; 749 752 oparms.fid->persistent_fid = o_rsp->PersistentFileId; ··· 1339 1330 (char **)&res_key, &ret_data_len); 1340 1331 1341 1332 if (rc) { 1342 - cifs_dbg(VFS, "refcpy ioctl error %d getting resume key\n", rc); 1333 + cifs_tcon_dbg(VFS, "refcpy ioctl error %d getting resume key\n", rc); 1343 1334 goto req_res_key_exit; 1344 1335 } 1345 1336 if (ret_data_len < sizeof(struct resume_key_req)) { 1346 - cifs_dbg(VFS, "Invalid refcopy resume key length\n"); 1337 + cifs_tcon_dbg(VFS, "Invalid refcopy resume key length\n"); 1347 1338 rc = -EINVAL; 1348 1339 goto req_res_key_exit; 1349 1340 } ··· 1378 1369 struct cifs_fid fid; 1379 1370 struct kvec qi_iov[1]; 1380 1371 struct kvec io_iov[SMB2_IOCTL_IOV_SIZE]; 1372 + struct kvec si_iov[SMB2_SET_INFO_IOV_SIZE]; 1381 1373 struct kvec close_iov[1]; 1374 + unsigned int size[2]; 1375 + void *data[2]; 1382 1376 1383 1377 memset(rqst, 0, sizeof(rqst)); 1384 1378 resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER; ··· 1416 1404 1417 1405 memset(&oparms, 0, sizeof(oparms)); 1418 1406 oparms.tcon = tcon; 1419 - oparms.desired_access = FILE_READ_ATTRIBUTES | READ_CONTROL; 1420 1407 oparms.disposition = FILE_OPEN; 1421 1408 if (is_dir) 1422 1409 oparms.create_options = CREATE_NOT_FILE; ··· 1424 1413 oparms.fid = &fid; 1425 1414 oparms.reconnect = false; 1426 1415 1427 - /* 1428 - * FSCTL codes encode the special access they need in the fsctl code. 1429 - */ 1430 1416 if (qi.flags & PASSTHRU_FSCTL) { 1431 1417 switch (qi.info_type & FSCTL_DEVICE_ACCESS_MASK) { 1432 1418 case FSCTL_DEVICE_ACCESS_FILE_READ_WRITE_ACCESS: ··· 1439 1431 oparms.desired_access = GENERIC_WRITE; 1440 1432 break; 1441 1433 } 1434 + } else if (qi.flags & PASSTHRU_SET_INFO) { 1435 + oparms.desired_access = GENERIC_WRITE; 1436 + } else { 1437 + oparms.desired_access = FILE_READ_ATTRIBUTES | READ_CONTROL; 1442 1438 } 1443 1439 1444 1440 rc = SMB2_open_init(tcon, &rqst[0], &oplock, &oparms, path); ··· 1466 1454 qi.output_buffer_length, 1467 1455 CIFSMaxBufSize); 1468 1456 } 1457 + } else if (qi.flags == PASSTHRU_SET_INFO) { 1458 + /* Can eventually relax perm check since server enforces too */ 1459 + if (!capable(CAP_SYS_ADMIN)) 1460 + rc = -EPERM; 1461 + else { 1462 + memset(&si_iov, 0, sizeof(si_iov)); 1463 + rqst[1].rq_iov = si_iov; 1464 + rqst[1].rq_nvec = 1; 1465 + 1466 + size[0] = 8; 1467 + data[0] = buffer; 1468 + 1469 + rc = SMB2_set_info_init(tcon, &rqst[1], 1470 + COMPOUND_FID, COMPOUND_FID, 1471 + current->tgid, 1472 + FILE_END_OF_FILE_INFORMATION, 1473 + SMB2_O_INFO_FILE, 0, data, size); 1474 + } 1469 1475 } else if (qi.flags == PASSTHRU_QUERY_INFO) { 1470 1476 memset(&qi_iov, 0, sizeof(qi_iov)); 1471 1477 rqst[1].rq_iov = qi_iov; ··· 1495 1465 qi.input_buffer_length, 1496 1466 qi.output_buffer_length, buffer); 1497 1467 } else { /* unknown flags */ 1498 - cifs_dbg(VFS, "invalid passthru query flags: 0x%x\n", qi.flags); 1468 + cifs_tcon_dbg(VFS, "invalid passthru query flags: 0x%x\n", qi.flags); 1499 1469 rc = -EINVAL; 1500 1470 } 1501 1471 ··· 1622 1592 if (rc == 0) { 1623 1593 if (ret_data_len != 1624 1594 sizeof(struct copychunk_ioctl_rsp)) { 1625 - cifs_dbg(VFS, "invalid cchunk response size\n"); 1595 + cifs_tcon_dbg(VFS, "invalid cchunk response size\n"); 1626 1596 rc = -EIO; 1627 1597 goto cchunk_out; 1628 1598 } ··· 1636 1606 */ 1637 1607 if (le32_to_cpu(retbuf->TotalBytesWritten) > 1638 1608 le32_to_cpu(pcchunk->Length)) { 1639 - cifs_dbg(VFS, "invalid copy chunk response\n"); 1609 + cifs_tcon_dbg(VFS, "invalid copy chunk response\n"); 1640 1610 rc = -EIO; 1641 1611 goto cchunk_out; 1642 1612 } 1643 1613 if (le32_to_cpu(retbuf->ChunksWritten) != 1) { 1644 - cifs_dbg(VFS, "invalid num chunks written\n"); 1614 + cifs_tcon_dbg(VFS, "invalid num chunks written\n"); 1645 1615 rc = -EIO; 1646 1616 goto cchunk_out; 1647 1617 } ··· 2244 2214 resp_buftype, rsp_iov); 2245 2215 if (rc) { 2246 2216 free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base); 2217 + if (rc == -EREMCHG) { 2218 + tcon->need_reconnect = true; 2219 + printk_once(KERN_WARNING "server share %s deleted\n", 2220 + tcon->treeName); 2221 + } 2247 2222 goto qic_exit; 2248 2223 } 2249 2224 *rsp = rsp_iov[1]; ··· 2436 2401 2437 2402 if (rc) { 2438 2403 if ((rc != -ENOENT) && (rc != -EOPNOTSUPP)) 2439 - cifs_dbg(VFS, "ioctl error in %s rc=%d\n", __func__, rc); 2404 + cifs_tcon_dbg(VFS, "ioctl error in %s rc=%d\n", __func__, rc); 2440 2405 goto out; 2441 2406 } 2442 2407 ··· 2445 2410 nls_codepage, remap, search_name, 2446 2411 true /* is_unicode */); 2447 2412 if (rc) { 2448 - cifs_dbg(VFS, "parse error in %s rc=%d\n", __func__, rc); 2413 + cifs_tcon_dbg(VFS, "parse error in %s rc=%d\n", __func__, rc); 2449 2414 goto out; 2450 2415 } 2451 2416 ··· 2675 2640 2676 2641 if (plen + le32_to_cpu(ioctl_rsp->OutputOffset) > 2677 2642 rsp_iov[1].iov_len) { 2678 - cifs_dbg(VFS, "srv returned invalid ioctl len: %d\n", 2643 + cifs_tcon_dbg(VFS, "srv returned invalid ioctl len: %d\n", 2679 2644 plen); 2680 2645 rc = -EIO; 2681 2646 goto querty_exit; ··· 2974 2939 loff_t offset, loff_t len) 2975 2940 { 2976 2941 struct inode *inode; 2977 - struct cifsInodeInfo *cifsi; 2978 2942 struct cifsFileInfo *cfile = file->private_data; 2979 2943 struct file_zero_data_information fsctl_buf; 2980 2944 long rc; ··· 2983 2949 xid = get_xid(); 2984 2950 2985 2951 inode = d_inode(cfile->dentry); 2986 - cifsi = CIFS_I(inode); 2987 2952 2988 2953 /* Need to make file sparse, if not already, before freeing range. */ 2989 2954 /* Consider adding equivalent for compressed since it could also work */ ··· 3628 3595 3629 3596 rc = smb2_get_enc_key(server, tr_hdr->SessionId, enc, key); 3630 3597 if (rc) { 3631 - cifs_dbg(VFS, "%s: Could not get %scryption key\n", __func__, 3598 + cifs_server_dbg(VFS, "%s: Could not get %scryption key\n", __func__, 3632 3599 enc ? "en" : "de"); 3633 3600 return 0; 3634 3601 } 3635 3602 3636 3603 rc = smb3_crypto_aead_allocate(server); 3637 3604 if (rc) { 3638 - cifs_dbg(VFS, "%s: crypto alloc failed\n", __func__); 3605 + cifs_server_dbg(VFS, "%s: crypto alloc failed\n", __func__); 3639 3606 return rc; 3640 3607 } 3641 3608 ··· 3643 3610 server->secmech.ccmaesdecrypt; 3644 3611 rc = crypto_aead_setkey(tfm, key, SMB3_SIGN_KEY_SIZE); 3645 3612 if (rc) { 3646 - cifs_dbg(VFS, "%s: Failed to set aead key %d\n", __func__, rc); 3613 + cifs_server_dbg(VFS, "%s: Failed to set aead key %d\n", __func__, rc); 3647 3614 return rc; 3648 3615 } 3649 3616 3650 3617 rc = crypto_aead_setauthsize(tfm, SMB2_SIGNATURE_SIZE); 3651 3618 if (rc) { 3652 - cifs_dbg(VFS, "%s: Failed to set authsize %d\n", __func__, rc); 3619 + cifs_server_dbg(VFS, "%s: Failed to set authsize %d\n", __func__, rc); 3653 3620 return rc; 3654 3621 } 3655 3622 3656 3623 req = aead_request_alloc(tfm, GFP_KERNEL); 3657 3624 if (!req) { 3658 - cifs_dbg(VFS, "%s: Failed to alloc aead request\n", __func__); 3625 + cifs_server_dbg(VFS, "%s: Failed to alloc aead request\n", __func__); 3659 3626 return -ENOMEM; 3660 3627 } 3661 3628 ··· 3666 3633 3667 3634 sg = init_sg(num_rqst, rqst, sign); 3668 3635 if (!sg) { 3669 - cifs_dbg(VFS, "%s: Failed to init sg\n", __func__); 3636 + cifs_server_dbg(VFS, "%s: Failed to init sg\n", __func__); 3670 3637 rc = -ENOMEM; 3671 3638 goto free_req; 3672 3639 } ··· 3674 3641 iv_len = crypto_aead_ivsize(tfm); 3675 3642 iv = kzalloc(iv_len, GFP_KERNEL); 3676 3643 if (!iv) { 3677 - cifs_dbg(VFS, "%s: Failed to alloc iv\n", __func__); 3644 + cifs_server_dbg(VFS, "%s: Failed to alloc iv\n", __func__); 3678 3645 rc = -ENOMEM; 3679 3646 goto free_sg; 3680 3647 } ··· 3916 3883 bool use_rdma_mr = false; 3917 3884 3918 3885 if (shdr->Command != SMB2_READ) { 3919 - cifs_dbg(VFS, "only big read responses are supported\n"); 3886 + cifs_server_dbg(VFS, "only big read responses are supported\n"); 3920 3887 return -ENOTSUPP; 3921 3888 } 3922 3889 ··· 4031 3998 return length; 4032 3999 } 4033 4000 4001 + struct smb2_decrypt_work { 4002 + struct work_struct decrypt; 4003 + struct TCP_Server_Info *server; 4004 + struct page **ppages; 4005 + char *buf; 4006 + unsigned int npages; 4007 + unsigned int len; 4008 + }; 4009 + 4010 + 4011 + static void smb2_decrypt_offload(struct work_struct *work) 4012 + { 4013 + struct smb2_decrypt_work *dw = container_of(work, 4014 + struct smb2_decrypt_work, decrypt); 4015 + int i, rc; 4016 + struct mid_q_entry *mid; 4017 + 4018 + rc = decrypt_raw_data(dw->server, dw->buf, dw->server->vals->read_rsp_size, 4019 + dw->ppages, dw->npages, dw->len); 4020 + if (rc) { 4021 + cifs_dbg(VFS, "error decrypting rc=%d\n", rc); 4022 + goto free_pages; 4023 + } 4024 + 4025 + dw->server->lstrp = jiffies; 4026 + mid = smb2_find_mid(dw->server, dw->buf); 4027 + if (mid == NULL) 4028 + cifs_dbg(FYI, "mid not found\n"); 4029 + else { 4030 + mid->decrypted = true; 4031 + rc = handle_read_data(dw->server, mid, dw->buf, 4032 + dw->server->vals->read_rsp_size, 4033 + dw->ppages, dw->npages, dw->len); 4034 + mid->callback(mid); 4035 + cifs_mid_q_entry_release(mid); 4036 + } 4037 + 4038 + free_pages: 4039 + for (i = dw->npages-1; i >= 0; i--) 4040 + put_page(dw->ppages[i]); 4041 + 4042 + kfree(dw->ppages); 4043 + cifs_small_buf_release(dw->buf); 4044 + } 4045 + 4046 + 4034 4047 static int 4035 - receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid) 4048 + receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid, 4049 + int *num_mids) 4036 4050 { 4037 4051 char *buf = server->smallbuf; 4038 4052 struct smb2_transform_hdr *tr_hdr = (struct smb2_transform_hdr *)buf; ··· 4089 4009 unsigned int buflen = server->pdu_size; 4090 4010 int rc; 4091 4011 int i = 0; 4012 + struct smb2_decrypt_work *dw; 4092 4013 4014 + *num_mids = 1; 4093 4015 len = min_t(unsigned int, buflen, server->vals->read_rsp_size + 4094 4016 sizeof(struct smb2_transform_hdr)) - HEADER_SIZE(server) + 1; 4095 4017 ··· 4127 4045 if (rc) 4128 4046 goto free_pages; 4129 4047 4048 + /* 4049 + * For large reads, offload to different thread for better performance, 4050 + * use more cores decrypting which can be expensive 4051 + */ 4052 + 4053 + if ((server->min_offload) && (server->in_flight > 1) && 4054 + (server->pdu_size >= server->min_offload)) { 4055 + dw = kmalloc(sizeof(struct smb2_decrypt_work), GFP_KERNEL); 4056 + if (dw == NULL) 4057 + goto non_offloaded_decrypt; 4058 + 4059 + dw->buf = server->smallbuf; 4060 + server->smallbuf = (char *)cifs_small_buf_get(); 4061 + 4062 + INIT_WORK(&dw->decrypt, smb2_decrypt_offload); 4063 + 4064 + dw->npages = npages; 4065 + dw->server = server; 4066 + dw->ppages = pages; 4067 + dw->len = len; 4068 + queue_work(cifsiod_wq, &dw->decrypt); 4069 + *num_mids = 0; /* worker thread takes care of finding mid */ 4070 + return -1; 4071 + } 4072 + 4073 + non_offloaded_decrypt: 4130 4074 rc = decrypt_raw_data(server, buf, server->vals->read_rsp_size, 4131 4075 pages, npages, len); 4132 4076 if (rc) ··· 4237 4129 } 4238 4130 4239 4131 if (*num_mids >= MAX_COMPOUND) { 4240 - cifs_dbg(VFS, "too many PDUs in compound\n"); 4132 + cifs_server_dbg(VFS, "too many PDUs in compound\n"); 4241 4133 return -1; 4242 4134 } 4243 4135 bufs[*num_mids] = buf; ··· 4283 4175 4284 4176 if (pdu_length < sizeof(struct smb2_transform_hdr) + 4285 4177 sizeof(struct smb2_sync_hdr)) { 4286 - cifs_dbg(VFS, "Transform message is too small (%u)\n", 4178 + cifs_server_dbg(VFS, "Transform message is too small (%u)\n", 4287 4179 pdu_length); 4288 4180 cifs_reconnect(server); 4289 4181 wake_up(&server->response_q); ··· 4291 4183 } 4292 4184 4293 4185 if (pdu_length < orig_len + sizeof(struct smb2_transform_hdr)) { 4294 - cifs_dbg(VFS, "Transform message is broken\n"); 4186 + cifs_server_dbg(VFS, "Transform message is broken\n"); 4295 4187 cifs_reconnect(server); 4296 4188 wake_up(&server->response_q); 4297 4189 return -ECONNABORTED; ··· 4299 4191 4300 4192 /* TODO: add support for compounds containing READ. */ 4301 4193 if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE(server)) { 4302 - *num_mids = 1; 4303 - return receive_encrypted_read(server, &mids[0]); 4194 + return receive_encrypted_read(server, &mids[0], num_mids); 4304 4195 } 4305 4196 4306 4197 return receive_encrypted_standard(server, mids, bufs, num_mids);
+208 -81
fs/cifs/smb2pdu.c
··· 503 503 pneg_ctxt->ContextType = SMB2_NETNAME_NEGOTIATE_CONTEXT_ID; 504 504 505 505 /* copy up to max of first 100 bytes of server name to NetName field */ 506 - pneg_ctxt->DataLength = cpu_to_le16(2 + 507 - (2 * cifs_strtoUTF16(pneg_ctxt->NetName, hostname, 100, cp))); 506 + pneg_ctxt->DataLength = cpu_to_le16(2 * cifs_strtoUTF16(pneg_ctxt->NetName, hostname, 100, cp)); 508 507 /* context size is DataLength + minimal smb2_neg_context */ 509 508 return DIV_ROUND_UP(le16_to_cpu(pneg_ctxt->DataLength) + 510 509 sizeof(struct smb2_neg_context), 8) * 8; ··· 542 543 543 544 if (*total_len > 200) { 544 545 /* In case length corrupted don't want to overrun smb buffer */ 545 - cifs_dbg(VFS, "Bad frame length assembling neg contexts\n"); 546 + cifs_server_dbg(VFS, "Bad frame length assembling neg contexts\n"); 546 547 return; 547 548 } 548 549 ··· 660 661 661 662 cifs_dbg(FYI, "decoding %d negotiate contexts\n", ctxt_cnt); 662 663 if (len_of_smb <= offset) { 663 - cifs_dbg(VFS, "Invalid response: negotiate context offset\n"); 664 + cifs_server_dbg(VFS, "Invalid response: negotiate context offset\n"); 664 665 return -EINVAL; 665 666 } 666 667 ··· 692 693 else if (pctx->ContextType == SMB2_POSIX_EXTENSIONS_AVAILABLE) 693 694 server->posix_ext_supported = true; 694 695 else 695 - cifs_dbg(VFS, "unknown negcontext of type %d ignored\n", 696 + cifs_server_dbg(VFS, "unknown negcontext of type %d ignored\n", 696 697 le16_to_cpu(pctx->ContextType)); 697 698 698 699 if (rc) ··· 817 818 req->Dialects[1] = cpu_to_le16(SMB302_PROT_ID); 818 819 req->DialectCount = cpu_to_le16(2); 819 820 total_len += 4; 820 - } else if (strcmp(ses->server->vals->version_string, 821 + } else if (strcmp(server->vals->version_string, 821 822 SMBDEFAULT_VERSION_STRING) == 0) { 822 823 req->Dialects[0] = cpu_to_le16(SMB21_PROT_ID); 823 824 req->Dialects[1] = cpu_to_le16(SMB30_PROT_ID); ··· 840 841 else 841 842 req->SecurityMode = 0; 842 843 843 - req->Capabilities = cpu_to_le32(ses->server->vals->req_capabilities); 844 + req->Capabilities = cpu_to_le32(server->vals->req_capabilities); 844 845 845 846 /* ClientGUID must be zero for SMB2.02 dialect */ 846 - if (ses->server->vals->protocol_id == SMB20_PROT_ID) 847 + if (server->vals->protocol_id == SMB20_PROT_ID) 847 848 memset(req->ClientGUID, 0, SMB2_CLIENT_GUID_SIZE); 848 849 else { 849 850 memcpy(req->ClientGUID, server->client_guid, 850 851 SMB2_CLIENT_GUID_SIZE); 851 - if ((ses->server->vals->protocol_id == SMB311_PROT_ID) || 852 - (strcmp(ses->server->vals->version_string, 852 + if ((server->vals->protocol_id == SMB311_PROT_ID) || 853 + (strcmp(server->vals->version_string, 853 854 SMBDEFAULT_VERSION_STRING) == 0)) 854 855 assemble_neg_contexts(req, server, &total_len); 855 856 } ··· 868 869 * cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2...]); 869 870 */ 870 871 if (rc == -EOPNOTSUPP) { 871 - cifs_dbg(VFS, "Dialect not supported by server. Consider " 872 + cifs_server_dbg(VFS, "Dialect not supported by server. Consider " 872 873 "specifying vers=1.0 or vers=2.0 on mount for accessing" 873 874 " older servers\n"); 874 875 goto neg_exit; 875 876 } else if (rc != 0) 876 877 goto neg_exit; 877 878 878 - if (strcmp(ses->server->vals->version_string, 879 + if (strcmp(server->vals->version_string, 879 880 SMB3ANY_VERSION_STRING) == 0) { 880 881 if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID)) { 881 - cifs_dbg(VFS, 882 + cifs_server_dbg(VFS, 882 883 "SMB2 dialect returned but not requested\n"); 883 884 return -EIO; 884 885 } else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) { 885 - cifs_dbg(VFS, 886 + cifs_server_dbg(VFS, 886 887 "SMB2.1 dialect returned but not requested\n"); 887 888 return -EIO; 888 889 } 889 - } else if (strcmp(ses->server->vals->version_string, 890 + } else if (strcmp(server->vals->version_string, 890 891 SMBDEFAULT_VERSION_STRING) == 0) { 891 892 if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID)) { 892 - cifs_dbg(VFS, 893 + cifs_server_dbg(VFS, 893 894 "SMB2 dialect returned but not requested\n"); 894 895 return -EIO; 895 896 } else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) { 896 897 /* ops set to 3.0 by default for default so update */ 897 - ses->server->ops = &smb21_operations; 898 - ses->server->vals = &smb21_values; 898 + server->ops = &smb21_operations; 899 + server->vals = &smb21_values; 899 900 } else if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID)) { 900 - ses->server->ops = &smb311_operations; 901 - ses->server->vals = &smb311_values; 901 + server->ops = &smb311_operations; 902 + server->vals = &smb311_values; 902 903 } 903 904 } else if (le16_to_cpu(rsp->DialectRevision) != 904 - ses->server->vals->protocol_id) { 905 + server->vals->protocol_id) { 905 906 /* if requested single dialect ensure returned dialect matched */ 906 - cifs_dbg(VFS, "Illegal 0x%x dialect returned: not requested\n", 907 + cifs_server_dbg(VFS, "Illegal 0x%x dialect returned: not requested\n", 907 908 le16_to_cpu(rsp->DialectRevision)); 908 909 return -EIO; 909 910 } ··· 921 922 else if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID)) 922 923 cifs_dbg(FYI, "negotiated smb3.1.1 dialect\n"); 923 924 else { 924 - cifs_dbg(VFS, "Illegal dialect returned by server 0x%x\n", 925 + cifs_server_dbg(VFS, "Illegal dialect returned by server 0x%x\n", 925 926 le16_to_cpu(rsp->DialectRevision)); 926 927 rc = -EIO; 927 928 goto neg_exit; ··· 981 982 rc = smb311_decode_neg_context(rsp, server, 982 983 rsp_iov.iov_len); 983 984 else 984 - cifs_dbg(VFS, "Missing expected negotiate contexts\n"); 985 + cifs_server_dbg(VFS, "Missing expected negotiate contexts\n"); 985 986 } 986 987 neg_exit: 987 988 free_rsp_buf(resp_buftype, rsp); ··· 995 996 struct validate_negotiate_info_rsp *pneg_rsp = NULL; 996 997 u32 rsplen; 997 998 u32 inbuflen; /* max of 4 dialects */ 999 + struct TCP_Server_Info *server = tcon->ses->server; 998 1000 999 1001 cifs_dbg(FYI, "validate negotiate\n"); 1000 1002 1001 1003 /* In SMB3.11 preauth integrity supersedes validate negotiate */ 1002 - if (tcon->ses->server->dialect == SMB311_PROT_ID) 1004 + if (server->dialect == SMB311_PROT_ID) 1003 1005 return 0; 1004 1006 1005 1007 /* ··· 1019 1019 } 1020 1020 1021 1021 if (tcon->ses->session_flags & SMB2_SESSION_FLAG_IS_NULL) 1022 - cifs_dbg(VFS, "Unexpected null user (anonymous) auth flag sent by server\n"); 1022 + cifs_tcon_dbg(VFS, "Unexpected null user (anonymous) auth flag sent by server\n"); 1023 1023 1024 1024 pneg_inbuf = kmalloc(sizeof(*pneg_inbuf), GFP_NOFS); 1025 1025 if (!pneg_inbuf) 1026 1026 return -ENOMEM; 1027 1027 1028 1028 pneg_inbuf->Capabilities = 1029 - cpu_to_le32(tcon->ses->server->vals->req_capabilities); 1030 - memcpy(pneg_inbuf->Guid, tcon->ses->server->client_guid, 1029 + cpu_to_le32(server->vals->req_capabilities); 1030 + memcpy(pneg_inbuf->Guid, server->client_guid, 1031 1031 SMB2_CLIENT_GUID_SIZE); 1032 1032 1033 1033 if (tcon->ses->sign) ··· 1040 1040 pneg_inbuf->SecurityMode = 0; 1041 1041 1042 1042 1043 - if (strcmp(tcon->ses->server->vals->version_string, 1043 + if (strcmp(server->vals->version_string, 1044 1044 SMB3ANY_VERSION_STRING) == 0) { 1045 1045 pneg_inbuf->Dialects[0] = cpu_to_le16(SMB30_PROT_ID); 1046 1046 pneg_inbuf->Dialects[1] = cpu_to_le16(SMB302_PROT_ID); ··· 1048 1048 /* structure is big enough for 3 dialects, sending only 2 */ 1049 1049 inbuflen = sizeof(*pneg_inbuf) - 1050 1050 (2 * sizeof(pneg_inbuf->Dialects[0])); 1051 - } else if (strcmp(tcon->ses->server->vals->version_string, 1051 + } else if (strcmp(server->vals->version_string, 1052 1052 SMBDEFAULT_VERSION_STRING) == 0) { 1053 1053 pneg_inbuf->Dialects[0] = cpu_to_le16(SMB21_PROT_ID); 1054 1054 pneg_inbuf->Dialects[1] = cpu_to_le16(SMB30_PROT_ID); ··· 1060 1060 } else { 1061 1061 /* otherwise specific dialect was requested */ 1062 1062 pneg_inbuf->Dialects[0] = 1063 - cpu_to_le16(tcon->ses->server->vals->protocol_id); 1063 + cpu_to_le16(server->vals->protocol_id); 1064 1064 pneg_inbuf->DialectCount = cpu_to_le16(1); 1065 1065 /* structure is big enough for 3 dialects, sending only 1 */ 1066 1066 inbuflen = sizeof(*pneg_inbuf) - ··· 1076 1076 * Old Windows versions or Netapp SMB server can return 1077 1077 * not supported error. Client should accept it. 1078 1078 */ 1079 - cifs_dbg(VFS, "Server does not support validate negotiate\n"); 1079 + cifs_tcon_dbg(VFS, "Server does not support validate negotiate\n"); 1080 1080 rc = 0; 1081 1081 goto out_free_inbuf; 1082 1082 } else if (rc != 0) { 1083 - cifs_dbg(VFS, "validate protocol negotiate failed: %d\n", rc); 1083 + cifs_tcon_dbg(VFS, "validate protocol negotiate failed: %d\n", rc); 1084 1084 rc = -EIO; 1085 1085 goto out_free_inbuf; 1086 1086 } 1087 1087 1088 1088 rc = -EIO; 1089 1089 if (rsplen != sizeof(*pneg_rsp)) { 1090 - cifs_dbg(VFS, "invalid protocol negotiate response size: %d\n", 1090 + cifs_tcon_dbg(VFS, "invalid protocol negotiate response size: %d\n", 1091 1091 rsplen); 1092 1092 1093 1093 /* relax check since Mac returns max bufsize allowed on ioctl */ ··· 1096 1096 } 1097 1097 1098 1098 /* check validate negotiate info response matches what we got earlier */ 1099 - if (pneg_rsp->Dialect != cpu_to_le16(tcon->ses->server->dialect)) 1099 + if (pneg_rsp->Dialect != cpu_to_le16(server->dialect)) 1100 1100 goto vneg_out; 1101 1101 1102 - if (pneg_rsp->SecurityMode != cpu_to_le16(tcon->ses->server->sec_mode)) 1102 + if (pneg_rsp->SecurityMode != cpu_to_le16(server->sec_mode)) 1103 1103 goto vneg_out; 1104 1104 1105 1105 /* do not validate server guid because not saved at negprot time yet */ 1106 1106 1107 1107 if ((le32_to_cpu(pneg_rsp->Capabilities) | SMB2_NT_FIND | 1108 - SMB2_LARGE_FILES) != tcon->ses->server->capabilities) 1108 + SMB2_LARGE_FILES) != server->capabilities) 1109 1109 goto vneg_out; 1110 1110 1111 1111 /* validate negotiate successful */ ··· 1114 1114 goto out_free_rsp; 1115 1115 1116 1116 vneg_out: 1117 - cifs_dbg(VFS, "protocol revalidation - security settings mismatch\n"); 1117 + cifs_tcon_dbg(VFS, "protocol revalidation - security settings mismatch\n"); 1118 1118 out_free_rsp: 1119 1119 kfree(pneg_rsp); 1120 1120 out_free_inbuf: ··· 1568 1568 sess_data->func(sess_data); 1569 1569 1570 1570 if ((ses->session_flags & SMB2_SESSION_FLAG_IS_GUEST) && (ses->sign)) 1571 - cifs_dbg(VFS, "signing requested but authenticated as guest\n"); 1571 + cifs_server_dbg(VFS, "signing requested but authenticated as guest\n"); 1572 1572 rc = sess_data->result; 1573 1573 out: 1574 1574 kfree(sess_data); ··· 1661 1661 __le16 *unc_path = NULL; 1662 1662 int flags = 0; 1663 1663 unsigned int total_len; 1664 + struct TCP_Server_Info *server = ses->server; 1664 1665 1665 1666 cifs_dbg(FYI, "TCON\n"); 1666 1667 1667 - if (!(ses->server) || !tree) 1668 + if (!server || !tree) 1668 1669 return -EIO; 1669 1670 1670 1671 unc_path = kmalloc(MAX_SHARENAME_LENGTH * 2, GFP_KERNEL); ··· 1708 1707 * unless it is guest or anonymous user. See MS-SMB2 3.2.5.3.1 1709 1708 * (Samba servers don't always set the flag so also check if null user) 1710 1709 */ 1711 - if ((ses->server->dialect == SMB311_PROT_ID) && 1710 + if ((server->dialect == SMB311_PROT_ID) && 1712 1711 !smb3_encryption_required(tcon) && 1713 1712 !(ses->session_flags & 1714 1713 (SMB2_SESSION_FLAG_IS_GUEST|SMB2_SESSION_FLAG_IS_NULL)) && ··· 1747 1746 cifs_dbg(FYI, "connection to printer\n"); 1748 1747 break; 1749 1748 default: 1750 - cifs_dbg(VFS, "unknown share type %d\n", rsp->ShareType); 1749 + cifs_server_dbg(VFS, "unknown share type %d\n", rsp->ShareType); 1751 1750 rc = -EOPNOTSUPP; 1752 1751 goto tcon_error_exit; 1753 1752 } ··· 1762 1761 1763 1762 if ((rsp->Capabilities & SMB2_SHARE_CAP_DFS) && 1764 1763 ((tcon->share_flags & SHI1005_FLAGS_DFS) == 0)) 1765 - cifs_dbg(VFS, "DFS capability contradicts DFS flag\n"); 1764 + cifs_tcon_dbg(VFS, "DFS capability contradicts DFS flag\n"); 1766 1765 1767 1766 if (tcon->seal && 1768 - !(tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION)) 1769 - cifs_dbg(VFS, "Encryption is requested but not supported\n"); 1767 + !(server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION)) 1768 + cifs_tcon_dbg(VFS, "Encryption is requested but not supported\n"); 1770 1769 1771 1770 init_copy_chunk_defaults(tcon); 1772 - if (tcon->ses->server->ops->validate_negotiate) 1773 - rc = tcon->ses->server->ops->validate_negotiate(xid, tcon); 1771 + if (server->ops->validate_negotiate) 1772 + rc = server->ops->validate_negotiate(xid, tcon); 1774 1773 tcon_exit: 1775 1774 1776 1775 free_rsp_buf(resp_buftype, rsp); ··· 1779 1778 1780 1779 tcon_error_exit: 1781 1780 if (rsp && rsp->sync_hdr.Status == STATUS_BAD_NETWORK_NAME) { 1782 - cifs_dbg(VFS, "BAD_NETWORK_NAME: %s\n", tree); 1781 + cifs_tcon_dbg(VFS, "BAD_NETWORK_NAME: %s\n", tree); 1783 1782 } 1784 1783 goto tcon_exit; 1785 1784 } ··· 2459 2458 iov[1].iov_len = uni_path_len; 2460 2459 iov[1].iov_base = path; 2461 2460 2462 - if (!server->oplocks) 2461 + if ((!server->oplocks) || (tcon->no_lease)) 2463 2462 *oplock = SMB2_OPLOCK_LEVEL_NONE; 2464 2463 2465 2464 if (!(server->capabilities & SMB2_GLOBAL_CAP_LEASING) || ··· 2595 2594 } 2596 2595 trace_smb3_open_err(xid, tcon->tid, ses->Suid, 2597 2596 oparms->create_options, oparms->desired_access, rc); 2597 + if (rc == -EREMCHG) { 2598 + printk_once(KERN_WARNING "server share %s deleted\n", 2599 + tcon->treeName); 2600 + tcon->need_reconnect = true; 2601 + } 2598 2602 goto creat_exit; 2599 2603 } else 2600 2604 trace_smb3_open_done(xid, rsp->PersistentFileId, tcon->tid, ··· 2748 2742 int resp_buftype = CIFS_NO_BUFFER; 2749 2743 int rc = 0; 2750 2744 int flags = 0; 2745 + struct TCP_Server_Info *server; 2751 2746 2752 2747 cifs_dbg(FYI, "SMB2 IOCTL\n"); 2753 2748 ··· 2764 2757 else 2765 2758 return -EIO; 2766 2759 2767 - if (!ses || !(ses->server)) 2760 + if (!ses) 2761 + return -EIO; 2762 + server = ses->server; 2763 + if (!server) 2768 2764 return -EIO; 2769 2765 2770 2766 if (smb3_encryption_required(tcon)) ··· 2817 2807 if (*plen == 0) 2818 2808 goto ioctl_exit; /* server returned no data */ 2819 2809 else if (*plen > rsp_iov.iov_len || *plen > 0xFF00) { 2820 - cifs_dbg(VFS, "srv returned invalid ioctl length: %d\n", *plen); 2810 + cifs_tcon_dbg(VFS, "srv returned invalid ioctl length: %d\n", *plen); 2821 2811 *plen = 0; 2822 2812 rc = -EIO; 2823 2813 goto ioctl_exit; 2824 2814 } 2825 2815 2826 2816 if (rsp_iov.iov_len - *plen < le32_to_cpu(rsp->OutputOffset)) { 2827 - cifs_dbg(VFS, "Malformed ioctl resp: len %d offset %d\n", *plen, 2817 + cifs_tcon_dbg(VFS, "Malformed ioctl resp: len %d offset %d\n", *plen, 2828 2818 le32_to_cpu(rsp->OutputOffset)); 2829 2819 *plen = 0; 2830 2820 rc = -EIO; ··· 2923 2913 rqst.rq_iov = iov; 2924 2914 rqst.rq_nvec = 1; 2925 2915 2916 + trace_smb3_close_enter(xid, persistent_fid, tcon->tid, ses->Suid); 2926 2917 rc = SMB2_close_init(tcon, &rqst, persistent_fid, volatile_fid); 2927 2918 if (rc) 2928 2919 goto close_exit; ··· 2936 2925 trace_smb3_close_err(xid, persistent_fid, tcon->tid, ses->Suid, 2937 2926 rc); 2938 2927 goto close_exit; 2939 - } 2928 + } else 2929 + trace_smb3_close_done(xid, persistent_fid, tcon->tid, 2930 + ses->Suid); 2940 2931 2941 2932 atomic_dec(&tcon->num_remote_opens); 2942 2933 ··· 3068 3055 int rc = 0; 3069 3056 int resp_buftype = CIFS_NO_BUFFER; 3070 3057 struct cifs_ses *ses = tcon->ses; 3058 + struct TCP_Server_Info *server; 3071 3059 int flags = 0; 3072 3060 bool allocated = false; 3073 3061 3074 3062 cifs_dbg(FYI, "Query Info\n"); 3075 3063 3076 - if (!ses || !(ses->server)) 3064 + if (!ses) 3065 + return -EIO; 3066 + server = ses->server; 3067 + if (!server) 3077 3068 return -EIO; 3078 3069 3079 3070 if (smb3_encryption_required(tcon)) ··· 3115 3098 if (!*data) { 3116 3099 *data = kmalloc(*dlen, GFP_KERNEL); 3117 3100 if (!*data) { 3118 - cifs_dbg(VFS, 3101 + cifs_tcon_dbg(VFS, 3119 3102 "Error %d allocating memory for acl\n", 3120 3103 rc); 3121 3104 *dlen = 0; ··· 3174 3157 sizeof(struct smb2_file_internal_info), 3175 3158 (void **)&uniqueid, NULL); 3176 3159 } 3160 + 3161 + /* 3162 + * CHANGE_NOTIFY Request is sent to get notifications on changes to a directory 3163 + * See MS-SMB2 2.2.35 and 2.2.36 3164 + */ 3165 + 3166 + int 3167 + SMB2_notify_init(const unsigned int xid, struct smb_rqst *rqst, 3168 + struct cifs_tcon *tcon, u64 persistent_fid, u64 volatile_fid, 3169 + u32 completion_filter, bool watch_tree) 3170 + { 3171 + struct smb2_change_notify_req *req; 3172 + struct kvec *iov = rqst->rq_iov; 3173 + unsigned int total_len; 3174 + int rc; 3175 + 3176 + rc = smb2_plain_req_init(SMB2_CHANGE_NOTIFY, tcon, (void **) &req, &total_len); 3177 + if (rc) 3178 + return rc; 3179 + 3180 + req->PersistentFileId = persistent_fid; 3181 + req->VolatileFileId = volatile_fid; 3182 + req->OutputBufferLength = SMB2_MAX_BUFFER_SIZE - MAX_SMB2_HDR_SIZE; 3183 + req->CompletionFilter = cpu_to_le32(completion_filter); 3184 + if (watch_tree) 3185 + req->Flags = cpu_to_le16(SMB2_WATCH_TREE); 3186 + else 3187 + req->Flags = 0; 3188 + 3189 + iov[0].iov_base = (char *)req; 3190 + iov[0].iov_len = total_len; 3191 + 3192 + return 0; 3193 + } 3194 + 3195 + int 3196 + SMB2_change_notify(const unsigned int xid, struct cifs_tcon *tcon, 3197 + u64 persistent_fid, u64 volatile_fid, bool watch_tree, 3198 + u32 completion_filter) 3199 + { 3200 + struct cifs_ses *ses = tcon->ses; 3201 + struct smb_rqst rqst; 3202 + struct kvec iov[1]; 3203 + struct kvec rsp_iov = {NULL, 0}; 3204 + int resp_buftype = CIFS_NO_BUFFER; 3205 + int flags = 0; 3206 + int rc = 0; 3207 + 3208 + cifs_dbg(FYI, "change notify\n"); 3209 + if (!ses || !(ses->server)) 3210 + return -EIO; 3211 + 3212 + if (smb3_encryption_required(tcon)) 3213 + flags |= CIFS_TRANSFORM_REQ; 3214 + 3215 + memset(&rqst, 0, sizeof(struct smb_rqst)); 3216 + memset(&iov, 0, sizeof(iov)); 3217 + rqst.rq_iov = iov; 3218 + rqst.rq_nvec = 1; 3219 + 3220 + rc = SMB2_notify_init(xid, &rqst, tcon, persistent_fid, volatile_fid, 3221 + completion_filter, watch_tree); 3222 + if (rc) 3223 + goto cnotify_exit; 3224 + 3225 + trace_smb3_notify_enter(xid, persistent_fid, tcon->tid, ses->Suid, 3226 + (u8)watch_tree, completion_filter); 3227 + rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov); 3228 + 3229 + if (rc != 0) { 3230 + cifs_stats_fail_inc(tcon, SMB2_CHANGE_NOTIFY_HE); 3231 + trace_smb3_notify_err(xid, persistent_fid, tcon->tid, ses->Suid, 3232 + (u8)watch_tree, completion_filter, rc); 3233 + } else 3234 + trace_smb3_notify_done(xid, persistent_fid, tcon->tid, 3235 + ses->Suid, (u8)watch_tree, completion_filter); 3236 + 3237 + cnotify_exit: 3238 + if (rqst.rq_iov) 3239 + cifs_small_buf_release(rqst.rq_iov[0].iov_base); /* request */ 3240 + free_rsp_buf(resp_buftype, rsp_iov.iov_base); 3241 + return rc; 3242 + } 3243 + 3244 + 3177 3245 3178 3246 /* 3179 3247 * This is a no-op for now. We're not really interested in the reply, but ··· 3389 3287 return rc; 3390 3288 } 3391 3289 3392 - int 3393 - SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, 3394 - u64 volatile_fid) 3290 + void 3291 + SMB2_flush_free(struct smb_rqst *rqst) 3395 3292 { 3396 - struct smb_rqst rqst; 3293 + if (rqst && rqst->rq_iov) 3294 + cifs_small_buf_release(rqst->rq_iov[0].iov_base); /* request */ 3295 + } 3296 + 3297 + int 3298 + SMB2_flush_init(const unsigned int xid, struct smb_rqst *rqst, 3299 + struct cifs_tcon *tcon, u64 persistent_fid, u64 volatile_fid) 3300 + { 3397 3301 struct smb2_flush_req *req; 3398 - struct cifs_ses *ses = tcon->ses; 3399 - struct kvec iov[1]; 3400 - struct kvec rsp_iov; 3401 - int resp_buftype; 3402 - int rc = 0; 3403 - int flags = 0; 3302 + struct kvec *iov = rqst->rq_iov; 3404 3303 unsigned int total_len; 3405 - 3406 - cifs_dbg(FYI, "Flush\n"); 3407 - 3408 - if (!ses || !(ses->server)) 3409 - return -EIO; 3304 + int rc; 3410 3305 3411 3306 rc = smb2_plain_req_init(SMB2_FLUSH, tcon, (void **) &req, &total_len); 3412 3307 if (rc) 3413 3308 return rc; 3414 - 3415 - if (smb3_encryption_required(tcon)) 3416 - flags |= CIFS_TRANSFORM_REQ; 3417 3309 3418 3310 req->PersistentFileId = persistent_fid; 3419 3311 req->VolatileFileId = volatile_fid; ··· 3415 3319 iov[0].iov_base = (char *)req; 3416 3320 iov[0].iov_len = total_len; 3417 3321 3322 + return 0; 3323 + } 3324 + 3325 + int 3326 + SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, 3327 + u64 volatile_fid) 3328 + { 3329 + struct cifs_ses *ses = tcon->ses; 3330 + struct smb_rqst rqst; 3331 + struct kvec iov[1]; 3332 + struct kvec rsp_iov = {NULL, 0}; 3333 + int resp_buftype = CIFS_NO_BUFFER; 3334 + int flags = 0; 3335 + int rc = 0; 3336 + 3337 + cifs_dbg(FYI, "flush\n"); 3338 + if (!ses || !(ses->server)) 3339 + return -EIO; 3340 + 3341 + if (smb3_encryption_required(tcon)) 3342 + flags |= CIFS_TRANSFORM_REQ; 3343 + 3418 3344 memset(&rqst, 0, sizeof(struct smb_rqst)); 3345 + memset(&iov, 0, sizeof(iov)); 3419 3346 rqst.rq_iov = iov; 3420 3347 rqst.rq_nvec = 1; 3421 3348 3349 + rc = SMB2_flush_init(xid, &rqst, tcon, persistent_fid, volatile_fid); 3350 + if (rc) 3351 + goto flush_exit; 3352 + 3353 + trace_smb3_flush_enter(xid, persistent_fid, tcon->tid, ses->Suid); 3422 3354 rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov); 3423 - cifs_small_buf_release(req); 3424 3355 3425 3356 if (rc != 0) { 3426 3357 cifs_stats_fail_inc(tcon, SMB2_FLUSH_HE); 3427 3358 trace_smb3_flush_err(xid, persistent_fid, tcon->tid, ses->Suid, 3428 3359 rc); 3429 - } 3360 + } else 3361 + trace_smb3_flush_done(xid, persistent_fid, tcon->tid, 3362 + ses->Suid); 3430 3363 3364 + flush_exit: 3365 + SMB2_flush_free(&rqst); 3431 3366 free_rsp_buf(resp_buftype, rsp_iov.iov_base); 3432 3367 return rc; 3433 3368 } ··· 3573 3446 struct smb2_sync_hdr *shdr = 3574 3447 (struct smb2_sync_hdr *)rdata->iov[0].iov_base; 3575 3448 struct cifs_credits credits = { .value = 0, .instance = 0 }; 3576 - struct smb_rqst rqst = { .rq_iov = rdata->iov, 3577 - .rq_nvec = 2, 3449 + struct smb_rqst rqst = { .rq_iov = &rdata->iov[1], 3450 + .rq_nvec = 1, 3578 3451 .rq_pages = rdata->pages, 3579 3452 .rq_offset = rdata->page_offset, 3580 3453 .rq_npages = rdata->nr_pages, ··· 3595 3468 3596 3469 rc = smb2_verify_signature(&rqst, server); 3597 3470 if (rc) 3598 - cifs_dbg(VFS, "SMB signature verification returned error = %d\n", 3471 + cifs_tcon_dbg(VFS, "SMB signature verification returned error = %d\n", 3599 3472 rc); 3600 3473 } 3601 3474 /* FIXME: should this be counted toward the initiating task? */ ··· 3722 3595 unsigned int *nbytes, char **buf, int *buf_type) 3723 3596 { 3724 3597 struct smb_rqst rqst; 3725 - int resp_buftype, rc = -EACCES; 3598 + int resp_buftype, rc; 3726 3599 struct smb2_read_plain_req *req = NULL; 3727 3600 struct smb2_read_rsp *rsp = NULL; 3728 3601 struct kvec iov[1]; ··· 4185 4058 info_buf_size = sizeof(SEARCH_ID_FULL_DIR_INFO) - 1; 4186 4059 break; 4187 4060 default: 4188 - cifs_dbg(VFS, "info level %u isn't supported\n", 4061 + cifs_tcon_dbg(VFS, "info level %u isn't supported\n", 4189 4062 srch_inf->info_level); 4190 4063 rc = -EINVAL; 4191 4064 goto qdir_exit; ··· 4276 4149 else if (resp_buftype == CIFS_SMALL_BUFFER) 4277 4150 srch_inf->smallBuf = true; 4278 4151 else 4279 - cifs_dbg(VFS, "illegal search buffer type\n"); 4152 + cifs_tcon_dbg(VFS, "illegal search buffer type\n"); 4280 4153 4281 4154 trace_smb3_query_dir_done(xid, persistent_fid, tcon->tid, 4282 4155 tcon->ses->Suid, index, srch_inf->entries_in_buffer);
+2
fs/cifs/smb2pdu.h
··· 143 143 #define SMB2_FLAGS_ASYNC_COMMAND cpu_to_le32(0x00000002) 144 144 #define SMB2_FLAGS_RELATED_OPERATIONS cpu_to_le32(0x00000004) 145 145 #define SMB2_FLAGS_SIGNED cpu_to_le32(0x00000008) 146 + #define SMB2_FLAGS_PRIORITY_MASK cpu_to_le32(0x00000070) /* SMB3.1.1 */ 146 147 #define SMB2_FLAGS_DFS_OPERATIONS cpu_to_le32(0x10000000) 148 + #define SMB2_FLAGS_REPLAY_OPERATION cpu_to_le32(0x20000000) /* SMB3 & up */ 147 149 148 150 /* 149 151 * Definitions for SMB2 Protocol Data Units (network frames)
+4
fs/cifs/smb2proto.h
··· 158 158 extern void SMB2_close_free(struct smb_rqst *rqst); 159 159 extern int SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, 160 160 u64 persistent_file_id, u64 volatile_file_id); 161 + extern int SMB2_flush_init(const unsigned int xid, struct smb_rqst *rqst, 162 + struct cifs_tcon *tcon, 163 + u64 persistent_file_id, u64 volatile_file_id); 164 + extern void SMB2_flush_free(struct smb_rqst *rqst); 161 165 extern int SMB2_query_info(const unsigned int xid, struct cifs_tcon *tcon, 162 166 u64 persistent_file_id, u64 volatile_file_id, 163 167 struct smb2_file_all_info *data);
+32 -30
fs/cifs/smb2transport.c
··· 176 176 177 177 ses = smb2_find_smb_ses(server, shdr->SessionId); 178 178 if (!ses) { 179 - cifs_dbg(VFS, "%s: Could not find session\n", __func__); 179 + cifs_server_dbg(VFS, "%s: Could not find session\n", __func__); 180 180 return 0; 181 181 } 182 182 ··· 185 185 186 186 rc = smb2_crypto_shash_allocate(server); 187 187 if (rc) { 188 - cifs_dbg(VFS, "%s: sha256 alloc failed\n", __func__); 188 + cifs_server_dbg(VFS, "%s: sha256 alloc failed\n", __func__); 189 189 return rc; 190 190 } 191 191 192 192 rc = crypto_shash_setkey(server->secmech.hmacsha256, 193 193 ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE); 194 194 if (rc) { 195 - cifs_dbg(VFS, "%s: Could not update with response\n", __func__); 195 + cifs_server_dbg(VFS, "%s: Could not update with response\n", __func__); 196 196 return rc; 197 197 } 198 198 199 199 shash = &server->secmech.sdeschmacsha256->shash; 200 200 rc = crypto_shash_init(shash); 201 201 if (rc) { 202 - cifs_dbg(VFS, "%s: Could not init sha256", __func__); 202 + cifs_server_dbg(VFS, "%s: Could not init sha256", __func__); 203 203 return rc; 204 204 } 205 205 ··· 215 215 rc = crypto_shash_update(shash, iov[0].iov_base, 216 216 iov[0].iov_len); 217 217 if (rc) { 218 - cifs_dbg(VFS, "%s: Could not update with payload\n", 218 + cifs_server_dbg(VFS, "%s: Could not update with payload\n", 219 219 __func__); 220 220 return rc; 221 221 } ··· 239 239 int rc = 0; 240 240 unsigned char prfhash[SMB2_HMACSHA256_SIZE]; 241 241 unsigned char *hashptr = prfhash; 242 + struct TCP_Server_Info *server = ses->server; 242 243 243 244 memset(prfhash, 0x0, SMB2_HMACSHA256_SIZE); 244 245 memset(key, 0x0, key_size); 245 246 246 - rc = smb3_crypto_shash_allocate(ses->server); 247 + rc = smb3_crypto_shash_allocate(server); 247 248 if (rc) { 248 - cifs_dbg(VFS, "%s: crypto alloc failed\n", __func__); 249 + cifs_server_dbg(VFS, "%s: crypto alloc failed\n", __func__); 249 250 goto smb3signkey_ret; 250 251 } 251 252 252 - rc = crypto_shash_setkey(ses->server->secmech.hmacsha256, 253 + rc = crypto_shash_setkey(server->secmech.hmacsha256, 253 254 ses->auth_key.response, SMB2_NTLMV2_SESSKEY_SIZE); 254 255 if (rc) { 255 - cifs_dbg(VFS, "%s: Could not set with session key\n", __func__); 256 + cifs_server_dbg(VFS, "%s: Could not set with session key\n", __func__); 256 257 goto smb3signkey_ret; 257 258 } 258 259 259 - rc = crypto_shash_init(&ses->server->secmech.sdeschmacsha256->shash); 260 + rc = crypto_shash_init(&server->secmech.sdeschmacsha256->shash); 260 261 if (rc) { 261 - cifs_dbg(VFS, "%s: Could not init sign hmac\n", __func__); 262 + cifs_server_dbg(VFS, "%s: Could not init sign hmac\n", __func__); 262 263 goto smb3signkey_ret; 263 264 } 264 265 265 - rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash, 266 + rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash, 266 267 i, 4); 267 268 if (rc) { 268 - cifs_dbg(VFS, "%s: Could not update with n\n", __func__); 269 + cifs_server_dbg(VFS, "%s: Could not update with n\n", __func__); 269 270 goto smb3signkey_ret; 270 271 } 271 272 272 - rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash, 273 + rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash, 273 274 label.iov_base, label.iov_len); 274 275 if (rc) { 275 - cifs_dbg(VFS, "%s: Could not update with label\n", __func__); 276 + cifs_server_dbg(VFS, "%s: Could not update with label\n", __func__); 276 277 goto smb3signkey_ret; 277 278 } 278 279 279 - rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash, 280 + rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash, 280 281 &zero, 1); 281 282 if (rc) { 282 - cifs_dbg(VFS, "%s: Could not update with zero\n", __func__); 283 + cifs_server_dbg(VFS, "%s: Could not update with zero\n", __func__); 283 284 goto smb3signkey_ret; 284 285 } 285 286 286 - rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash, 287 + rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash, 287 288 context.iov_base, context.iov_len); 288 289 if (rc) { 289 - cifs_dbg(VFS, "%s: Could not update with context\n", __func__); 290 + cifs_server_dbg(VFS, "%s: Could not update with context\n", __func__); 290 291 goto smb3signkey_ret; 291 292 } 292 293 293 - rc = crypto_shash_update(&ses->server->secmech.sdeschmacsha256->shash, 294 + rc = crypto_shash_update(&server->secmech.sdeschmacsha256->shash, 294 295 L, 4); 295 296 if (rc) { 296 - cifs_dbg(VFS, "%s: Could not update with L\n", __func__); 297 + cifs_server_dbg(VFS, "%s: Could not update with L\n", __func__); 297 298 goto smb3signkey_ret; 298 299 } 299 300 300 - rc = crypto_shash_final(&ses->server->secmech.sdeschmacsha256->shash, 301 + rc = crypto_shash_final(&server->secmech.sdeschmacsha256->shash, 301 302 hashptr); 302 303 if (rc) { 303 - cifs_dbg(VFS, "%s: Could not generate sha256 hash\n", __func__); 304 + cifs_server_dbg(VFS, "%s: Could not generate sha256 hash\n", __func__); 304 305 goto smb3signkey_ret; 305 306 } 306 307 ··· 437 436 438 437 ses = smb2_find_smb_ses(server, shdr->SessionId); 439 438 if (!ses) { 440 - cifs_dbg(VFS, "%s: Could not find session\n", __func__); 439 + cifs_server_dbg(VFS, "%s: Could not find session\n", __func__); 441 440 return 0; 442 441 } 443 442 ··· 447 446 rc = crypto_shash_setkey(server->secmech.cmacaes, 448 447 ses->smb3signingkey, SMB2_CMACAES_SIZE); 449 448 if (rc) { 450 - cifs_dbg(VFS, "%s: Could not set key for cmac aes\n", __func__); 449 + cifs_server_dbg(VFS, "%s: Could not set key for cmac aes\n", __func__); 451 450 return rc; 452 451 } 453 452 ··· 458 457 */ 459 458 rc = crypto_shash_init(shash); 460 459 if (rc) { 461 - cifs_dbg(VFS, "%s: Could not init cmac aes\n", __func__); 460 + cifs_server_dbg(VFS, "%s: Could not init cmac aes\n", __func__); 462 461 return rc; 463 462 } 464 463 ··· 474 473 rc = crypto_shash_update(shash, iov[0].iov_base, 475 474 iov[0].iov_len); 476 475 if (rc) { 477 - cifs_dbg(VFS, "%s: Could not update with payload\n", 476 + cifs_server_dbg(VFS, "%s: Could not update with payload\n", 478 477 __func__); 479 478 return rc; 480 479 } ··· 522 521 if ((shdr->Command == SMB2_NEGOTIATE) || 523 522 (shdr->Command == SMB2_SESSION_SETUP) || 524 523 (shdr->Command == SMB2_OPLOCK_BREAK) || 524 + server->ignore_signature || 525 525 (!server->session_estab)) 526 526 return 0; 527 527 ··· 667 665 668 666 rc = smb2_verify_signature(&rqst, server); 669 667 if (rc) 670 - cifs_dbg(VFS, "SMB signature verification returned error = %d\n", 668 + cifs_server_dbg(VFS, "SMB signature verification returned error = %d\n", 671 669 rc); 672 670 } 673 671 ··· 741 739 else 742 740 tfm = crypto_alloc_aead("ccm(aes)", 0, 0); 743 741 if (IS_ERR(tfm)) { 744 - cifs_dbg(VFS, "%s: Failed to alloc encrypt aead\n", 742 + cifs_server_dbg(VFS, "%s: Failed to alloc encrypt aead\n", 745 743 __func__); 746 744 return PTR_ERR(tfm); 747 745 } ··· 756 754 if (IS_ERR(tfm)) { 757 755 crypto_free_aead(server->secmech.ccmaesencrypt); 758 756 server->secmech.ccmaesencrypt = NULL; 759 - cifs_dbg(VFS, "%s: Failed to alloc decrypt aead\n", 757 + cifs_server_dbg(VFS, "%s: Failed to alloc decrypt aead\n", 760 758 __func__); 761 759 return PTR_ERR(tfm); 762 760 }
+38
fs/cifs/trace.h
··· 117 117 /* 118 118 * For handle based calls other than read and write, and get/set info 119 119 */ 120 + DECLARE_EVENT_CLASS(smb3_fd_class, 121 + TP_PROTO(unsigned int xid, 122 + __u64 fid, 123 + __u32 tid, 124 + __u64 sesid), 125 + TP_ARGS(xid, fid, tid, sesid), 126 + TP_STRUCT__entry( 127 + __field(unsigned int, xid) 128 + __field(__u64, fid) 129 + __field(__u32, tid) 130 + __field(__u64, sesid) 131 + ), 132 + TP_fast_assign( 133 + __entry->xid = xid; 134 + __entry->fid = fid; 135 + __entry->tid = tid; 136 + __entry->sesid = sesid; 137 + ), 138 + TP_printk("\txid=%u sid=0x%llx tid=0x%x fid=0x%llx", 139 + __entry->xid, __entry->sesid, __entry->tid, __entry->fid) 140 + ) 141 + 142 + #define DEFINE_SMB3_FD_EVENT(name) \ 143 + DEFINE_EVENT(smb3_fd_class, smb3_##name, \ 144 + TP_PROTO(unsigned int xid, \ 145 + __u64 fid, \ 146 + __u32 tid, \ 147 + __u64 sesid), \ 148 + TP_ARGS(xid, fid, tid, sesid)) 149 + 150 + DEFINE_SMB3_FD_EVENT(flush_enter); 151 + DEFINE_SMB3_FD_EVENT(flush_done); 152 + DEFINE_SMB3_FD_EVENT(close_enter); 153 + DEFINE_SMB3_FD_EVENT(close_done); 154 + 120 155 DECLARE_EVENT_CLASS(smb3_fd_err_class, 121 156 TP_PROTO(unsigned int xid, 122 157 __u64 fid, ··· 235 200 236 201 DEFINE_SMB3_INF_ENTER_EVENT(query_info_enter); 237 202 DEFINE_SMB3_INF_ENTER_EVENT(query_info_done); 203 + DEFINE_SMB3_INF_ENTER_EVENT(notify_enter); 204 + DEFINE_SMB3_INF_ENTER_EVENT(notify_done); 238 205 239 206 DECLARE_EVENT_CLASS(smb3_inf_err_class, 240 207 TP_PROTO(unsigned int xid, ··· 283 246 284 247 DEFINE_SMB3_INF_ERR_EVENT(query_info_err); 285 248 DEFINE_SMB3_INF_ERR_EVENT(set_info_err); 249 + DEFINE_SMB3_INF_ERR_EVENT(notify_err); 286 250 DEFINE_SMB3_INF_ERR_EVENT(fsctl_err); 287 251 288 252 DECLARE_EVENT_CLASS(smb3_inf_compound_enter_class,
+64 -56
fs/cifs/transport.c
··· 118 118 #ifdef CONFIG_CIFS_STATS2 119 119 now = jiffies; 120 120 if (now < midEntry->when_alloc) 121 - cifs_dbg(VFS, "invalid mid allocation time\n"); 121 + cifs_server_dbg(VFS, "invalid mid allocation time\n"); 122 122 roundtrip_time = now - midEntry->when_alloc; 123 123 124 124 if (smb_cmd < NUMBER_OF_SMB2_COMMANDS) { ··· 232 232 retries++; 233 233 if (retries >= 14 || 234 234 (!server->noblocksnd && (retries > 2))) { 235 - cifs_dbg(VFS, "sends on sock %p stuck for 15 seconds\n", 235 + cifs_server_dbg(VFS, "sends on sock %p stuck for 15 seconds\n", 236 236 ssocket); 237 237 return -EAGAIN; 238 238 } ··· 246 246 if (rc == 0) { 247 247 /* should never happen, letting socket clear before 248 248 retrying is our only obvious option here */ 249 - cifs_dbg(VFS, "tcp sent no data\n"); 249 + cifs_server_dbg(VFS, "tcp sent no data\n"); 250 250 msleep(500); 251 251 continue; 252 252 } ··· 440 440 } 441 441 smbd_done: 442 442 if (rc < 0 && rc != -EINTR) 443 - cifs_dbg(VFS, "Error %d sending data on socket to server\n", 443 + cifs_server_dbg(VFS, "Error %d sending data on socket to server\n", 444 444 rc); 445 445 else if (rc > 0) 446 446 rc = 0; ··· 473 473 cur_rqst[0].rq_nvec = 1; 474 474 475 475 if (!server->ops->init_transform_rq) { 476 - cifs_dbg(VFS, "Encryption requested but transform callback " 477 - "is missing\n"); 476 + cifs_server_dbg(VFS, "Encryption requested but transform " 477 + "callback is missing\n"); 478 478 return -EIO; 479 479 } 480 480 ··· 532 532 if ((flags & CIFS_TIMEOUT_MASK) == CIFS_NON_BLOCKING) { 533 533 /* oplock breaks must not be held up */ 534 534 server->in_flight++; 535 + if (server->in_flight > server->max_in_flight) 536 + server->max_in_flight = server->in_flight; 535 537 *credits -= 1; 536 538 *instance = server->reconnect_instance; 537 539 spin_unlock(&server->req_lock); ··· 550 548 if (!rc) { 551 549 trace_smb3_credit_timeout(server->CurrentMid, 552 550 server->hostname, num_credits); 553 - cifs_dbg(VFS, "wait timed out after %d ms\n", 551 + cifs_server_dbg(VFS, "wait timed out after %d ms\n", 554 552 timeout); 555 553 return -ENOTSUPP; 556 554 } ··· 591 589 trace_smb3_credit_timeout( 592 590 server->CurrentMid, 593 591 server->hostname, num_credits); 594 - cifs_dbg(VFS, "wait timed out after %d ms\n", 592 + cifs_server_dbg(VFS, "wait timed out after %d ms\n", 595 593 timeout); 596 594 return -ENOTSUPP; 597 595 } ··· 610 608 if ((flags & CIFS_TIMEOUT_MASK) != CIFS_BLOCKING_OP) { 611 609 *credits -= num_credits; 612 610 server->in_flight += num_credits; 611 + if (server->in_flight > server->max_in_flight) 612 + server->max_in_flight = server->in_flight; 613 613 *instance = server->reconnect_instance; 614 614 } 615 615 spin_unlock(&server->req_lock); ··· 873 869 break; 874 870 default: 875 871 list_del_init(&mid->qhead); 876 - cifs_dbg(VFS, "%s: invalid mid state mid=%llu state=%d\n", 872 + cifs_server_dbg(VFS, "%s: invalid mid state mid=%llu state=%d\n", 877 873 __func__, mid->mid, mid->mid_state); 878 874 rc = -EIO; 879 875 } ··· 914 910 rc = cifs_verify_signature(&rqst, server, 915 911 mid->sequence_number); 916 912 if (rc) 917 - cifs_dbg(VFS, "SMB signature verification returned error = %d\n", 913 + cifs_server_dbg(VFS, "SMB signature verification returned error = %d\n", 918 914 rc); 919 915 } 920 916 ··· 1111 1107 } 1112 1108 if (rc != 0) { 1113 1109 for (; i < num_rqst; i++) { 1114 - cifs_dbg(VFS, "Cancelling wait for mid %llu cmd: %d\n", 1110 + cifs_server_dbg(VFS, "Cancelling wait for mid %llu cmd: %d\n", 1115 1111 midQ[i]->mid, le16_to_cpu(midQ[i]->command)); 1116 1112 send_cancel(server, &rqst[i], midQ[i]); 1117 1113 spin_lock(&GlobalMid_Lock); ··· 1246 1242 struct kvec iov = { .iov_base = in_buf, .iov_len = len }; 1247 1243 struct smb_rqst rqst = { .rq_iov = &iov, .rq_nvec = 1 }; 1248 1244 struct cifs_credits credits = { .value = 1, .instance = 0 }; 1245 + struct TCP_Server_Info *server; 1249 1246 1250 1247 if (ses == NULL) { 1251 1248 cifs_dbg(VFS, "Null smb session\n"); 1252 1249 return -EIO; 1253 1250 } 1254 - if (ses->server == NULL) { 1251 + server = ses->server; 1252 + if (server == NULL) { 1255 1253 cifs_dbg(VFS, "Null tcp session\n"); 1256 1254 return -EIO; 1257 1255 } 1258 1256 1259 - if (ses->server->tcpStatus == CifsExiting) 1257 + if (server->tcpStatus == CifsExiting) 1260 1258 return -ENOENT; 1261 1259 1262 1260 /* Ensure that we do not send more than 50 overlapping requests ··· 1266 1260 use ses->maxReq */ 1267 1261 1268 1262 if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { 1269 - cifs_dbg(VFS, "Illegal length, greater than maximum frame, %d\n", 1263 + cifs_server_dbg(VFS, "Illegal length, greater than maximum frame, %d\n", 1270 1264 len); 1271 1265 return -EIO; 1272 1266 } 1273 1267 1274 - rc = wait_for_free_request(ses->server, flags, &credits.instance); 1268 + rc = wait_for_free_request(server, flags, &credits.instance); 1275 1269 if (rc) 1276 1270 return rc; 1277 1271 ··· 1279 1273 and avoid races inside tcp sendmsg code that could cause corruption 1280 1274 of smb data */ 1281 1275 1282 - mutex_lock(&ses->server->srv_mutex); 1276 + mutex_lock(&server->srv_mutex); 1283 1277 1284 1278 rc = allocate_mid(ses, in_buf, &midQ); 1285 1279 if (rc) { 1286 1280 mutex_unlock(&ses->server->srv_mutex); 1287 1281 /* Update # of requests on wire to server */ 1288 - add_credits(ses->server, &credits, 0); 1282 + add_credits(server, &credits, 0); 1289 1283 return rc; 1290 1284 } 1291 1285 1292 - rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number); 1286 + rc = cifs_sign_smb(in_buf, server, &midQ->sequence_number); 1293 1287 if (rc) { 1294 - mutex_unlock(&ses->server->srv_mutex); 1288 + mutex_unlock(&server->srv_mutex); 1295 1289 goto out; 1296 1290 } 1297 1291 1298 1292 midQ->mid_state = MID_REQUEST_SUBMITTED; 1299 1293 1300 - cifs_in_send_inc(ses->server); 1301 - rc = smb_send(ses->server, in_buf, len); 1302 - cifs_in_send_dec(ses->server); 1294 + cifs_in_send_inc(server); 1295 + rc = smb_send(server, in_buf, len); 1296 + cifs_in_send_dec(server); 1303 1297 cifs_save_when_sent(midQ); 1304 1298 1305 1299 if (rc < 0) 1306 - ses->server->sequence_number -= 2; 1300 + server->sequence_number -= 2; 1307 1301 1308 - mutex_unlock(&ses->server->srv_mutex); 1302 + mutex_unlock(&server->srv_mutex); 1309 1303 1310 1304 if (rc < 0) 1311 1305 goto out; 1312 1306 1313 - rc = wait_for_response(ses->server, midQ); 1307 + rc = wait_for_response(server, midQ); 1314 1308 if (rc != 0) { 1315 - send_cancel(ses->server, &rqst, midQ); 1309 + send_cancel(server, &rqst, midQ); 1316 1310 spin_lock(&GlobalMid_Lock); 1317 1311 if (midQ->mid_state == MID_REQUEST_SUBMITTED) { 1318 1312 /* no longer considered to be "in-flight" */ 1319 1313 midQ->callback = DeleteMidQEntry; 1320 1314 spin_unlock(&GlobalMid_Lock); 1321 - add_credits(ses->server, &credits, 0); 1315 + add_credits(server, &credits, 0); 1322 1316 return rc; 1323 1317 } 1324 1318 spin_unlock(&GlobalMid_Lock); 1325 1319 } 1326 1320 1327 - rc = cifs_sync_mid_result(midQ, ses->server); 1321 + rc = cifs_sync_mid_result(midQ, server); 1328 1322 if (rc != 0) { 1329 - add_credits(ses->server, &credits, 0); 1323 + add_credits(server, &credits, 0); 1330 1324 return rc; 1331 1325 } 1332 1326 1333 1327 if (!midQ->resp_buf || !out_buf || 1334 1328 midQ->mid_state != MID_RESPONSE_RECEIVED) { 1335 1329 rc = -EIO; 1336 - cifs_dbg(VFS, "Bad MID state?\n"); 1330 + cifs_server_dbg(VFS, "Bad MID state?\n"); 1337 1331 goto out; 1338 1332 } 1339 1333 1340 1334 *pbytes_returned = get_rfc1002_length(midQ->resp_buf); 1341 1335 memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4); 1342 - rc = cifs_check_receive(midQ, ses->server, 0); 1336 + rc = cifs_check_receive(midQ, server, 0); 1343 1337 out: 1344 1338 cifs_delete_mid(midQ); 1345 - add_credits(ses->server, &credits, 0); 1339 + add_credits(server, &credits, 0); 1346 1340 1347 1341 return rc; 1348 1342 } ··· 1385 1379 struct kvec iov = { .iov_base = in_buf, .iov_len = len }; 1386 1380 struct smb_rqst rqst = { .rq_iov = &iov, .rq_nvec = 1 }; 1387 1381 unsigned int instance; 1382 + struct TCP_Server_Info *server; 1388 1383 1389 1384 if (tcon == NULL || tcon->ses == NULL) { 1390 1385 cifs_dbg(VFS, "Null smb session\n"); 1391 1386 return -EIO; 1392 1387 } 1393 1388 ses = tcon->ses; 1389 + server = ses->server; 1394 1390 1395 - if (ses->server == NULL) { 1391 + if (server == NULL) { 1396 1392 cifs_dbg(VFS, "Null tcp session\n"); 1397 1393 return -EIO; 1398 1394 } 1399 1395 1400 - if (ses->server->tcpStatus == CifsExiting) 1396 + if (server->tcpStatus == CifsExiting) 1401 1397 return -ENOENT; 1402 1398 1403 1399 /* Ensure that we do not send more than 50 overlapping requests ··· 1407 1399 use ses->maxReq */ 1408 1400 1409 1401 if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { 1410 - cifs_dbg(VFS, "Illegal length, greater than maximum frame, %d\n", 1402 + cifs_tcon_dbg(VFS, "Illegal length, greater than maximum frame, %d\n", 1411 1403 len); 1412 1404 return -EIO; 1413 1405 } 1414 1406 1415 - rc = wait_for_free_request(ses->server, CIFS_BLOCKING_OP, &instance); 1407 + rc = wait_for_free_request(server, CIFS_BLOCKING_OP, &instance); 1416 1408 if (rc) 1417 1409 return rc; 1418 1410 ··· 1420 1412 and avoid races inside tcp sendmsg code that could cause corruption 1421 1413 of smb data */ 1422 1414 1423 - mutex_lock(&ses->server->srv_mutex); 1415 + mutex_lock(&server->srv_mutex); 1424 1416 1425 1417 rc = allocate_mid(ses, in_buf, &midQ); 1426 1418 if (rc) { 1427 - mutex_unlock(&ses->server->srv_mutex); 1419 + mutex_unlock(&server->srv_mutex); 1428 1420 return rc; 1429 1421 } 1430 1422 1431 - rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number); 1423 + rc = cifs_sign_smb(in_buf, server, &midQ->sequence_number); 1432 1424 if (rc) { 1433 1425 cifs_delete_mid(midQ); 1434 - mutex_unlock(&ses->server->srv_mutex); 1426 + mutex_unlock(&server->srv_mutex); 1435 1427 return rc; 1436 1428 } 1437 1429 1438 1430 midQ->mid_state = MID_REQUEST_SUBMITTED; 1439 - cifs_in_send_inc(ses->server); 1440 - rc = smb_send(ses->server, in_buf, len); 1441 - cifs_in_send_dec(ses->server); 1431 + cifs_in_send_inc(server); 1432 + rc = smb_send(server, in_buf, len); 1433 + cifs_in_send_dec(server); 1442 1434 cifs_save_when_sent(midQ); 1443 1435 1444 1436 if (rc < 0) 1445 - ses->server->sequence_number -= 2; 1437 + server->sequence_number -= 2; 1446 1438 1447 - mutex_unlock(&ses->server->srv_mutex); 1439 + mutex_unlock(&server->srv_mutex); 1448 1440 1449 1441 if (rc < 0) { 1450 1442 cifs_delete_mid(midQ); ··· 1452 1444 } 1453 1445 1454 1446 /* Wait for a reply - allow signals to interrupt. */ 1455 - rc = wait_event_interruptible(ses->server->response_q, 1447 + rc = wait_event_interruptible(server->response_q, 1456 1448 (!(midQ->mid_state == MID_REQUEST_SUBMITTED)) || 1457 - ((ses->server->tcpStatus != CifsGood) && 1458 - (ses->server->tcpStatus != CifsNew))); 1449 + ((server->tcpStatus != CifsGood) && 1450 + (server->tcpStatus != CifsNew))); 1459 1451 1460 1452 /* Were we interrupted by a signal ? */ 1461 1453 if ((rc == -ERESTARTSYS) && 1462 1454 (midQ->mid_state == MID_REQUEST_SUBMITTED) && 1463 - ((ses->server->tcpStatus == CifsGood) || 1464 - (ses->server->tcpStatus == CifsNew))) { 1455 + ((server->tcpStatus == CifsGood) || 1456 + (server->tcpStatus == CifsNew))) { 1465 1457 1466 1458 if (in_buf->Command == SMB_COM_TRANSACTION2) { 1467 1459 /* POSIX lock. We send a NT_CANCEL SMB to cause the 1468 1460 blocking lock to return. */ 1469 - rc = send_cancel(ses->server, &rqst, midQ); 1461 + rc = send_cancel(server, &rqst, midQ); 1470 1462 if (rc) { 1471 1463 cifs_delete_mid(midQ); 1472 1464 return rc; ··· 1485 1477 } 1486 1478 } 1487 1479 1488 - rc = wait_for_response(ses->server, midQ); 1480 + rc = wait_for_response(server, midQ); 1489 1481 if (rc) { 1490 - send_cancel(ses->server, &rqst, midQ); 1482 + send_cancel(server, &rqst, midQ); 1491 1483 spin_lock(&GlobalMid_Lock); 1492 1484 if (midQ->mid_state == MID_REQUEST_SUBMITTED) { 1493 1485 /* no longer considered to be "in-flight" */ ··· 1502 1494 rstart = 1; 1503 1495 } 1504 1496 1505 - rc = cifs_sync_mid_result(midQ, ses->server); 1497 + rc = cifs_sync_mid_result(midQ, server); 1506 1498 if (rc != 0) 1507 1499 return rc; 1508 1500 1509 1501 /* rcvd frame is ok */ 1510 1502 if (out_buf == NULL || midQ->mid_state != MID_RESPONSE_RECEIVED) { 1511 1503 rc = -EIO; 1512 - cifs_dbg(VFS, "Bad MID state?\n"); 1504 + cifs_tcon_dbg(VFS, "Bad MID state?\n"); 1513 1505 goto out; 1514 1506 } 1515 1507 1516 1508 *pbytes_returned = get_rfc1002_length(midQ->resp_buf); 1517 1509 memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4); 1518 - rc = cifs_check_receive(midQ, ses->server, 0); 1510 + rc = cifs_check_receive(midQ, server, 0); 1519 1511 out: 1520 1512 cifs_delete_mid(midQ); 1521 1513 if (rstart && rc == -EACCES)
+1
include/linux/root_dev.h
··· 8 8 9 9 enum { 10 10 Root_NFS = MKDEV(UNNAMED_MAJOR, 255), 11 + Root_CIFS = MKDEV(UNNAMED_MAJOR, 254), 11 12 Root_RAM0 = MKDEV(RAMDISK_MAJOR, 0), 12 13 Root_RAM1 = MKDEV(RAMDISK_MAJOR, 1), 13 14 Root_FD0 = MKDEV(FLOPPY_MAJOR, 0),