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 ...
Unified · Split
| @@ -0,0 +1,97 @@ | ||
| 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 | |
| @@ -211,3 +211,11 @@ config CIFS_FSCACHE · 210 unmodified lines | ||
| 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. | |
| @@ -21,3 +21,5 @@ cifs-$(CONFIG_CIFS_DFS_UPCALL) += dns_resolve.o cifs_dfs_ref.o dfs_cache.o · 20 unmodified lines | ||
| 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 | |
| @@ -452,6 +452,7 @@ static ssize_t cifs_stats_proc_write(struct file *file, · 451 unmodified lines | ||
| 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); |
| @@ -526,6 +527,7 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v) · 68 unmodified lines | ||
| 526 | 527 | list_for_each(tmp1, &cifs_tcp_ses_list) { |
| 527 | 528 | server = list_entry(tmp1, struct TCP_Server_Info, |
| 528 | 529 | tcp_ses_list); |
| 530 | + seq_printf(m, "\nMax requests in flight: %d", server->max_in_flight); | |
| 529 | 531 | #ifdef CONFIG_CIFS_STATS2 |
| 530 | 532 | seq_puts(m, "\nTotal time spent processing by command. Time "); |
| 531 | 533 | seq_printf(m, "units are jiffies (%d per second)\n", HZ); |
| @@ -80,6 +80,60 @@ do { \ · 79 unmodified lines | ||
| 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 | * --------- |
| @@ -91,6 +145,19 @@ do { \ · 5 unmodified lines | ||
| 91 | 145 | pr_debug(fmt, ##__VA_ARGS__); \ |
| 92 | 146 | } while (0) |
| 93 | 147 | |
| 148 | +#define cifs_server_dbg(type, fmt, ...) \ | |
| 149 | +do { \ | |
| 150 | + if (0) \ | |
| 151 | + pr_debug("\\\\%s " fmt, \ | |
| 152 | + server->hostname, ##__VA_ARGS__); \ | |
| 153 | +} while (0) | |
| 154 | + | |
| 155 | +#define cifs_tcon_dbg(type, fmt, ...) \ | |
| 156 | +do { \ | |
| 157 | + if (0) \ | |
| 158 | + pr_debug("%s " fmt, tcon->treeName, ##__VA_ARGS__); \ | |
| 159 | +} while (0) | |
| 160 | + | |
| 94 | 161 | #define cifs_info(fmt, ...) \ |
| 95 | 162 | do { \ |
| 96 | 163 | pr_info("CIFS: "fmt, ##__VA_ARGS__); \ |
| @@ -53,6 +53,8 @@ · 52 unmodified lines | ||
| 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; |
| @@ -46,6 +46,7 @@ struct smb_snapshot_array { · 45 unmodified lines | ||
| 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; |
| @@ -701,10 +701,9 @@ static void dump_ace(struct cifs_ace *pace, char *end_of_acl) · 700 unmodified lines | ||
| 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; |
| @@ -757,22 +756,34 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, · 46 unmodified lines | ||
| 757 | 756 | #ifdef CONFIG_CIFS_DEBUG2 |
| 758 | 757 | dump_ace(ppace[i], end_of_acl); |
| 759 | 758 | #endif |
| 760 | − if (compare_sids(&(ppace[i]->sid), pownersid) == 0) | |
| 759 | + if (mode_from_special_sid && | |
| 760 | + (compare_sids(&(ppace[i]->sid), | |
| 761 | + &sid_unix_NFS_mode) == 0)) { | |
| 762 | + /* | |
| 763 | + * Full permissions are: | |
| 764 | + * 07777 = S_ISUID | S_ISGID | S_ISVTX | | |
| 765 | + * S_IRWXU | S_IRWXG | S_IRWXO | |
| 766 | + */ | |
| 767 | + fattr->cf_mode &= ~07777; | |
| 768 | + fattr->cf_mode |= | |
| 769 | + le32_to_cpu(ppace[i]->sid.sub_auth[2]); | |
| 770 | + break; | |
| 771 | + } else if (compare_sids(&(ppace[i]->sid), pownersid) == 0) | |
| 761 | 772 | access_flags_to_mode(ppace[i]->access_req, |
| 762 | 773 | ppace[i]->type, |
| 763 | 774 | &fattr->cf_mode, |
| 764 | 775 | &user_mask); |
| 765 | − if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0) | |
| 776 | + else if (compare_sids(&(ppace[i]->sid), pgrpsid) == 0) | |
| 766 | 777 | access_flags_to_mode(ppace[i]->access_req, |
| 767 | 778 | ppace[i]->type, |
| 768 | 779 | &fattr->cf_mode, |
| 769 | 780 | &group_mask); |
| 770 | − if (compare_sids(&(ppace[i]->sid), &sid_everyone) == 0) | |
| 781 | + else if (compare_sids(&(ppace[i]->sid), &sid_everyone) == 0) | |
| 771 | 782 | access_flags_to_mode(ppace[i]->access_req, |
| 772 | 783 | ppace[i]->type, |
| 773 | 784 | &fattr->cf_mode, |
| 774 | 785 | &other_mask); |
| 775 | − if (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0) | |
| 786 | + else if (compare_sids(&(ppace[i]->sid), &sid_authusers) == 0) | |
| 776 | 787 | access_flags_to_mode(ppace[i]->access_req, |
| 777 | 788 | ppace[i]->type, |
| 778 | 789 | &fattr->cf_mode, |
| @@ -795,22 +806,49 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, · 16 unmodified lines | ||
| 795 | 806 | |
| 796 | 807 | |
| 797 | 808 | static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid, |
| 798 | − struct cifs_sid *pgrpsid, __u64 nmode) | |
| 809 | + struct cifs_sid *pgrpsid, __u64 nmode, bool modefromsid) | |
| 799 | 810 | { |
| 800 | 811 | u16 size = 0; |
| 812 | + u32 num_aces = 0; | |
| 801 | 813 | struct cifs_acl *pnndacl; |
| 802 | 814 | |
| 803 | 815 | pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl)); |
| 804 | 816 | |
| 817 | + if (modefromsid) { | |
| 818 | + struct cifs_ace *pntace = | |
| 819 | + (struct cifs_ace *)((char *)pnndacl + size); | |
| 820 | + int i; | |
| 821 | + | |
| 822 | + pntace->type = ACCESS_ALLOWED; | |
| 823 | + pntace->flags = 0x0; | |
| 824 | + pntace->access_req = 0; | |
| 825 | + pntace->sid.num_subauth = 3; | |
| 826 | + pntace->sid.revision = 1; | |
| 827 | + for (i = 0; i < NUM_AUTHS; i++) | |
| 828 | + pntace->sid.authority[i] = | |
| 829 | + sid_unix_NFS_mode.authority[i]; | |
| 830 | + pntace->sid.sub_auth[0] = sid_unix_NFS_mode.sub_auth[0]; | |
| 831 | + pntace->sid.sub_auth[1] = sid_unix_NFS_mode.sub_auth[1]; | |
| 832 | + pntace->sid.sub_auth[2] = cpu_to_le32(nmode & 07777); | |
| 833 | + | |
| 834 | + /* size = 1 + 1 + 2 + 4 + 1 + 1 + 6 + (psid->num_subauth*4) */ | |
| 835 | + pntace->size = cpu_to_le16(28); | |
| 836 | + size += 28; | |
| 837 | + num_aces++; | |
| 838 | + } | |
| 839 | + | |
| 805 | 840 | size += fill_ace_for_sid((struct cifs_ace *) ((char *)pnndacl + size), |
| 806 | 841 | pownersid, nmode, S_IRWXU); |
| 842 | + num_aces++; | |
| 807 | 843 | size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size), |
| 808 | 844 | pgrpsid, nmode, S_IRWXG); |
| 845 | + num_aces++; | |
| 809 | 846 | size += fill_ace_for_sid((struct cifs_ace *)((char *)pnndacl + size), |
| 810 | 847 | &sid_everyone, nmode, S_IRWXO); |
| 848 | + num_aces++; | |
| 811 | 849 | |
| 850 | + pndacl->num_aces = cpu_to_le32(num_aces); | |
| 812 | 851 | pndacl->size = cpu_to_le16(size + sizeof(struct cifs_acl)); |
| 813 | − pndacl->num_aces = cpu_to_le32(3); | |
| 814 | 852 | |
| 815 | 853 | return 0; |
| 816 | 854 | } |
| @@ -851,7 +889,8 @@ static int parse_sid(struct cifs_sid *psid, char *end_of_acl) · 34 unmodified lines | ||
| 851 | 889 | |
| 852 | 890 | /* Convert CIFS ACL to POSIX form */ |
| 853 | 891 | static int parse_sec_desc(struct cifs_sb_info *cifs_sb, |
| 854 | − struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr) | |
| 892 | + struct cifs_ntsd *pntsd, int acl_len, struct cifs_fattr *fattr, | |
| 893 | + bool get_mode_from_special_sid) | |
| 855 | 894 | { |
| 856 | 895 | int rc = 0; |
| 857 | 896 | struct cifs_sid *owner_sid_ptr, *group_sid_ptr; |
| @@ -900,7 +939,7 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb, · 42 unmodified lines | ||
| 900 | 939 | |
| 901 | 940 | if (dacloffset) |
| 902 | 941 | parse_dacl(dacl_ptr, end_of_acl, owner_sid_ptr, |
| 903 | − group_sid_ptr, fattr); | |
| 942 | + group_sid_ptr, fattr, get_mode_from_special_sid); | |
| 904 | 943 | else |
| 905 | 944 | cifs_dbg(FYI, "no ACL\n"); /* BB grant all or default perms? */ |
| 906 | 945 | |
| @@ -909,7 +948,8 @@ static int parse_sec_desc(struct cifs_sb_info *cifs_sb, · 2 unmodified lines | ||
| 909 | 948 | |
| 910 | 949 | /* Convert permission bits from mode to equivalent CIFS ACL */ |
| 911 | 950 | static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, |
| 912 | − __u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid, int *aclflag) | |
| 951 | + __u32 secdesclen, __u64 nmode, kuid_t uid, kgid_t gid, | |
| 952 | + bool mode_from_sid, int *aclflag) | |
| 913 | 953 | { |
| 914 | 954 | int rc = 0; |
| 915 | 955 | __u32 dacloffset; |
| @@ -934,7 +974,7 @@ static int build_sec_desc(struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd, · 18 unmodified lines | ||
| 934 | 974 | ndacl_ptr->num_aces = 0; |
| 935 | 975 | |
| 936 | 976 | rc = set_chmod_dacl(ndacl_ptr, owner_sid_ptr, group_sid_ptr, |
| 937 | − nmode); | |
| 977 | + nmode, mode_from_sid); | |
| 938 | 978 | sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size); |
| 939 | 979 | /* copy sec desc control portion & owner and group sids */ |
| 940 | 980 | copy_sec_desc(pntsd, pnntsd, sidsoffset); |
| @@ -1128,8 +1168,8 @@ out: · 187 unmodified lines | ||
| 1128 | 1168 | /* Translate the CIFS ACL (similar to NTFS ACL) for a file into mode bits */ |
| 1129 | 1169 | int |
| 1130 | 1170 | cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, |
| 1131 | − struct inode *inode, const char *path, | |
| 1132 | − const struct cifs_fid *pfid) | |
| 1171 | + struct inode *inode, bool mode_from_special_sid, | |
| 1172 | + const char *path, const struct cifs_fid *pfid) | |
| 1133 | 1173 | { |
| 1134 | 1174 | struct cifs_ntsd *pntsd = NULL; |
| 1135 | 1175 | u32 acllen = 0; |
| @@ -1156,8 +1196,11 @@ cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, struct cifs_fattr *fattr, · 20 unmodified lines | ||
| 1156 | 1196 | if (IS_ERR(pntsd)) { |
| 1157 | 1197 | rc = PTR_ERR(pntsd); |
| 1158 | 1198 | cifs_dbg(VFS, "%s: error %d getting sec desc\n", __func__, rc); |
| 1199 | + } else if (mode_from_special_sid) { | |
| 1200 | + rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, true); | |
| 1159 | 1201 | } else { |
| 1160 | − rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr); | |
| 1202 | + /* get approximated mode from ACL */ | |
| 1203 | + rc = parse_sec_desc(cifs_sb, pntsd, acllen, fattr, false); | |
| 1161 | 1204 | kfree(pntsd); |
| 1162 | 1205 | if (rc) |
| 1163 | 1206 | cifs_dbg(VFS, "parse sec desc failed rc = %d\n", rc); |
| @@ -1181,6 +1224,7 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode, · 17 unmodified lines | ||
| 1181 | 1224 | struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); |
| 1182 | 1225 | struct tcon_link *tlink = cifs_sb_tlink(cifs_sb); |
| 1183 | 1226 | struct smb_version_operations *ops; |
| 1227 | + bool mode_from_sid; | |
| 1184 | 1228 | |
| 1185 | 1229 | if (IS_ERR(tlink)) |
| 1186 | 1230 | return PTR_ERR(tlink); |
| @@ -1218,8 +1262,13 @@ id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64 nmode, · 31 unmodified lines | ||
| 1218 | 1262 | return -ENOMEM; |
| 1219 | 1263 | } |
| 1220 | 1264 | |
| 1265 | + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID) | |
| 1266 | + mode_from_sid = true; | |
| 1267 | + else | |
| 1268 | + mode_from_sid = false; | |
| 1269 | + | |
| 1221 | 1270 | rc = build_sec_desc(pntsd, pnntsd, secdesclen, nmode, uid, gid, |
| 1222 | − &aclflag); | |
| 1271 | + mode_from_sid, &aclflag); | |
| 1223 | 1272 | |
| 1224 | 1273 | cifs_dbg(NOISY, "build_sec_desc rc: %d\n", rc); |
| 1225 | 1274 | |
| @@ -45,7 +45,7 @@ · 44 unmodified lines | ||
| 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: |
| @@ -118,6 +118,7 @@ extern mempool_t *cifs_req_poolp; · 117 unmodified lines | ||
| 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 | |
| @@ -422,6 +423,10 @@ cifs_show_cache_flavor(struct seq_file *s, struct cifs_sb_info *cifs_sb) · 298 unmodified lines | ||
| 422 | 423 | seq_puts(s, "strict"); |
| 423 | 424 | else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) |
| 424 | 425 | seq_puts(s, "none"); |
| 426 | + else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RW_CACHE) | |
| 427 | + seq_puts(s, "singleclient"); /* assume only one client access */ | |
| 428 | + else if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE) | |
| 429 | + seq_puts(s, "ro"); /* read only caching assumed */ | |
| 425 | 430 | else |
| 426 | 431 | seq_puts(s, "loose"); |
| 427 | 432 | } |
| @@ -455,6 +460,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root) · 27 unmodified lines | ||
| 455 | 460 | cifs_show_security(s, tcon->ses); |
| 456 | 461 | cifs_show_cache_flavor(s, cifs_sb); |
| 457 | 462 | |
| 463 | + if (tcon->no_lease) | |
| 464 | + seq_puts(s, ",nolease"); | |
| 458 | 465 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER) |
| 459 | 466 | seq_puts(s, ",multiuser"); |
| 460 | 467 | else if (tcon->ses->user_name) |
| @@ -576,6 +583,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root) · 115 unmodified lines | ||
| 576 | 583 | seq_printf(s, ",rsize=%u", cifs_sb->rsize); |
| 577 | 584 | seq_printf(s, ",wsize=%u", cifs_sb->wsize); |
| 578 | 585 | seq_printf(s, ",bsize=%u", cifs_sb->bsize); |
| 586 | + if (tcon->ses->server->min_offload) | |
| 587 | + seq_printf(s, ",esize=%u", tcon->ses->server->min_offload); | |
| 579 | 588 | seq_printf(s, ",echo_interval=%lu", |
| 580 | 589 | tcon->ses->server->echo_interval / HZ); |
| 581 | 590 | |
| @@ -1517,11 +1526,25 @@ init_cifs(void) · 935 unmodified lines | ||
| 1517 | 1526 | goto out_clean_proc; |
| 1518 | 1527 | } |
| 1519 | 1528 | |
| 1529 | + /* | |
| 1530 | + * Consider in future setting limit!=0 maybe to min(num_of_cores - 1, 3) | |
| 1531 | + * so that we don't launch too many worker threads but | |
| 1532 | + * Documentation/workqueue.txt recommends setting it to 0 | |
| 1533 | + */ | |
| 1534 | + | |
| 1535 | + /* WQ_UNBOUND allows decrypt tasks to run on any CPU */ | |
| 1536 | + decrypt_wq = alloc_workqueue("smb3decryptd", | |
| 1537 | + WQ_UNBOUND|WQ_FREEZABLE|WQ_MEM_RECLAIM, 0); | |
| 1538 | + if (!decrypt_wq) { | |
| 1539 | + rc = -ENOMEM; | |
| 1540 | + goto out_destroy_cifsiod_wq; | |
| 1541 | + } | |
| 1542 | + | |
| 1520 | 1543 | cifsoplockd_wq = alloc_workqueue("cifsoplockd", |
| 1521 | 1544 | WQ_FREEZABLE|WQ_MEM_RECLAIM, 0); |
| 1522 | 1545 | if (!cifsoplockd_wq) { |
| 1523 | 1546 | rc = -ENOMEM; |
| 1524 | − goto out_destroy_cifsiod_wq; | |
| 1547 | + goto out_destroy_decrypt_wq; | |
| 1525 | 1548 | } |
| 1526 | 1549 | |
| 1527 | 1550 | rc = cifs_fscache_register(); |
| @@ -1587,6 +1610,8 @@ out_unreg_fscache: · 59 unmodified lines | ||
| 1587 | 1610 | cifs_fscache_unregister(); |
| 1588 | 1611 | out_destroy_cifsoplockd_wq: |
| 1589 | 1612 | destroy_workqueue(cifsoplockd_wq); |
| 1613 | +out_destroy_decrypt_wq: | |
| 1614 | + destroy_workqueue(decrypt_wq); | |
| 1590 | 1615 | out_destroy_cifsiod_wq: |
| 1591 | 1616 | destroy_workqueue(cifsiod_wq); |
| 1592 | 1617 | out_clean_proc: |
| @@ -1613,6 +1638,7 @@ exit_cifs(void) · 20 unmodified lines | ||
| 1613 | 1638 | cifs_destroy_inodecache(); |
| 1614 | 1639 | cifs_fscache_unregister(); |
| 1615 | 1640 | destroy_workqueue(cifsoplockd_wq); |
| 1641 | + destroy_workqueue(decrypt_wq); | |
| 1616 | 1642 | destroy_workqueue(cifsiod_wq); |
| 1617 | 1643 | cifs_proc_clean(); |
| 1618 | 1644 | } |
| @@ -152,5 +152,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); · 151 unmodified lines | ||
| 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 */ |
| @@ -542,6 +542,7 @@ struct smb_vol { · 541 unmodified lines | ||
| 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; |
| @@ -559,6 +560,8 @@ struct smb_vol { · 11 unmodified lines | ||
| 559 | 560 | bool server_ino:1; /* use inode numbers from server ie UniqueId */ |
| 560 | 561 | bool direct_io:1; |
| 561 | 562 | bool strict_io:1; /* strict cache behavior */ |
| 563 | + bool cache_ro:1; | |
| 564 | + bool cache_rw:1; | |
| 562 | 565 | bool remap:1; /* set to remap seven reserved chars in filenames */ |
| 563 | 566 | bool sfu_remap:1; /* remap seven reserved chars ala SFU */ |
| 564 | 567 | bool posix_paths:1; /* unset to not ask for posix pathnames. */ |
| @@ -576,6 +579,7 @@ struct smb_vol { · 11 unmodified lines | ||
| 576 | 579 | bool noblocksnd:1; |
| 577 | 580 | bool noautotune:1; |
| 578 | 581 | bool nostrictsync:1; /* do not force expensive SMBflush on every sync */ |
| 582 | + bool no_lease:1; /* disable requesting leases */ | |
| 579 | 583 | bool fsc:1; /* enable fscache */ |
| 580 | 584 | bool mfsymlinks:1; /* use Minshall+French Symlinks */ |
| 581 | 585 | bool multiuser:1; |
| @@ -589,6 +593,7 @@ struct smb_vol { · 7 unmodified lines | ||
| 589 | 593 | unsigned int bsize; |
| 590 | 594 | unsigned int rsize; |
| 591 | 595 | unsigned int wsize; |
| 596 | + unsigned int min_offload; | |
| 592 | 597 | bool sockopt_tcp_nodelay:1; |
| 593 | 598 | unsigned long actimeo; /* attribute cache timeout (jiffies) */ |
| 594 | 599 | struct smb_version_operations *ops; |
| @@ -602,6 +607,7 @@ struct smb_vol { · 7 unmodified lines | ||
| 602 | 607 | __u32 handle_timeout; /* persistent and durable handle timeout in ms */ |
| 603 | 608 | unsigned int max_credits; /* smb3 max_credits 10 < credits < 60000 */ |
| 604 | 609 | __u16 compression; /* compression algorithm 0xFFFF default 0=disabled */ |
| 610 | + bool rootfs:1; /* if it's a SMB root file system */ | |
| 605 | 611 | }; |
| 606 | 612 | |
| 607 | 613 | /** |
| @@ -620,7 +626,8 @@ struct smb_vol { · 12 unmodified lines | ||
| 620 | 626 | CIFS_MOUNT_MULTIUSER | CIFS_MOUNT_STRICT_IO | \ |
| 621 | 627 | CIFS_MOUNT_CIFS_BACKUPUID | CIFS_MOUNT_CIFS_BACKUPGID | \ |
| 622 | 628 | CIFS_MOUNT_UID_FROM_ACL | CIFS_MOUNT_NO_HANDLE_CACHE | \ |
| 623 | − CIFS_MOUNT_NO_DFS | CIFS_MOUNT_MODE_FROM_SID) | |
| 629 | + CIFS_MOUNT_NO_DFS | CIFS_MOUNT_MODE_FROM_SID | \ | |
| 630 | + CIFS_MOUNT_RO_CACHE | CIFS_MOUNT_RW_CACHE) | |
| 624 | 631 | |
| 625 | 632 | /** |
| 626 | 633 | * Generic VFS superblock mount flags (s_flags) to consider when |
| @@ -672,12 +679,14 @@ struct TCP_Server_Info { · 45 unmodified lines | ||
| 672 | 679 | unsigned int credits; /* send no more requests at once */ |
| 673 | 680 | unsigned int max_credits; /* can override large 32000 default at mnt */ |
| 674 | 681 | unsigned int in_flight; /* number of requests on the wire to server */ |
| 682 | + unsigned int max_in_flight; /* max number of requests that were on wire */ | |
| 675 | 683 | spinlock_t req_lock; /* protect the two values above */ |
| 676 | 684 | struct mutex srv_mutex; |
| 677 | 685 | struct task_struct *tsk; |
| 678 | 686 | char server_GUID[16]; |
| 679 | 687 | __u16 sec_mode; |
| 680 | 688 | bool sign; /* is signing enabled on this connection? */ |
| 689 | + bool ignore_signature:1; /* skip validation of signatures in SMB2/3 rsp */ | |
| 681 | 690 | bool session_estab; /* mark when very first sess is established */ |
| 682 | 691 | int echo_credits; /* echo reserved slots */ |
| 683 | 692 | int oplock_credits; /* oplock break reserved slots */ |
| @@ -740,6 +749,7 @@ struct TCP_Server_Info { · 56 unmodified lines | ||
| 740 | 749 | #endif /* STATS2 */ |
| 741 | 750 | unsigned int max_read; |
| 742 | 751 | unsigned int max_write; |
| 752 | + unsigned int min_offload; | |
| 743 | 753 | __le16 compress_algorithm; |
| 744 | 754 | __le16 cipher_type; |
| 745 | 755 | /* save initital negprot hash */ |
| @@ -755,6 +765,7 @@ struct TCP_Server_Info { · 9 unmodified lines | ||
| 755 | 765 | * reconnect. |
| 756 | 766 | */ |
| 757 | 767 | int nr_targets; |
| 768 | + bool noblockcnt; /* use non-blocking connect() */ | |
| 758 | 769 | }; |
| 759 | 770 | |
| 760 | 771 | struct cifs_credits { |
| @@ -1082,6 +1093,7 @@ struct cifs_tcon { · 321 unmodified lines | ||
| 1082 | 1093 | bool need_reopen_files:1; /* need to reopen tcon file handles */ |
| 1083 | 1094 | bool use_resilient:1; /* use resilient instead of durable handles */ |
| 1084 | 1095 | bool use_persistent:1; /* use persistent instead of durable handles */ |
| 1096 | + bool no_lease:1; /* Do not request leases on files or directories */ | |
| 1085 | 1097 | __le32 capabilities; |
| 1086 | 1098 | __u32 share_flags; |
| 1087 | 1099 | __u32 maximal_access; |
| @@ -1366,9 +1378,9 @@ void cifsFileInfo_put(struct cifsFileInfo *cifs_file); · 278 unmodified lines | ||
| 1366 | 1378 | #define CIFS_CACHE_RW_FLG (CIFS_CACHE_READ_FLG | CIFS_CACHE_WRITE_FLG) |
| 1367 | 1379 | #define CIFS_CACHE_RHW_FLG (CIFS_CACHE_RW_FLG | CIFS_CACHE_HANDLE_FLG) |
| 1368 | 1380 | |
| 1369 | −#define CIFS_CACHE_READ(cinode) (cinode->oplock & CIFS_CACHE_READ_FLG) | |
| 1381 | +#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)) | |
| 1370 | 1382 | #define CIFS_CACHE_HANDLE(cinode) (cinode->oplock & CIFS_CACHE_HANDLE_FLG) |
| 1371 | −#define CIFS_CACHE_WRITE(cinode) (cinode->oplock & CIFS_CACHE_WRITE_FLG) | |
| 1383 | +#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)) | |
| 1372 | 1384 | |
| 1373 | 1385 | /* |
| 1374 | 1386 | * One of these for each file inode |
| @@ -1887,6 +1899,7 @@ void cifs_queue_oplock_break(struct cifsFileInfo *cfile); · 512 unmodified lines | ||
| 1887 | 1899 | |
| 1888 | 1900 | extern const struct slow_work_ops cifs_oplock_break_ops; |
| 1889 | 1901 | extern struct workqueue_struct *cifsiod_wq; |
| 1902 | +extern struct workqueue_struct *decrypt_wq; | |
| 1890 | 1903 | extern struct workqueue_struct *cifsoplockd_wq; |
| 1891 | 1904 | extern __u32 cifs_lock_secret; |
| 1892 | 1905 | |
| @@ -137,7 +137,11 @@ extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, bool); · 136 unmodified lines | ||
| 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); |
| @@ -197,6 +201,7 @@ extern int cifs_rename_pending_delete(const char *full_path, · 53 unmodified lines | ||
| 197 | 201 | const unsigned int xid); |
| 198 | 202 | extern int cifs_acl_to_fattr(struct cifs_sb_info *cifs_sb, |
| 199 | 203 | struct cifs_fattr *fattr, struct inode *inode, |
| 204 | + bool get_mode_from_special_sid, | |
| 200 | 205 | const char *path, const struct cifs_fid *pfid); |
| 201 | 206 | extern int id_mode_to_cifs_acl(struct inode *inode, const char *path, __u64, |
| 202 | 207 | kuid_t, kgid_t); |
| @@ -0,0 +1,94 @@ | ||
| 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 | +} | |
| @@ -1393,7 +1393,7 @@ int · 1392 unmodified lines | ||
| 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; |
| @@ -74,7 +74,7 @@ enum { · 73 unmodified lines | ||
| 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,18 +91,19 @@ enum { · 10 unmodified lines | ||
| 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, |
| @@ -134,6 +135,7 @@ static const match_table_t cifs_mount_option_tokens = { · 25 unmodified lines | ||
| 134 | 135 | { Opt_noforcegid, "noforcegid" }, |
| 135 | 136 | { Opt_noblocksend, "noblocksend" }, |
| 136 | 137 | { Opt_noautotune, "noautotune" }, |
| 138 | + { Opt_nolease, "nolease" }, | |
| 137 | 139 | { Opt_hard, "hard" }, |
| 138 | 140 | { Opt_soft, "soft" }, |
| 139 | 141 | { Opt_perm, "perm" }, |
| @@ -183,6 +185,7 @@ static const match_table_t cifs_mount_option_tokens = { · 43 unmodified lines | ||
| 183 | 185 | { Opt_noacl, "noacl" }, |
| 184 | 186 | { Opt_locallease, "locallease" }, |
| 185 | 187 | { Opt_sign, "sign" }, |
| 188 | + { Opt_ignore_signature, "signloosely" }, | |
| 186 | 189 | { Opt_seal, "seal" }, |
| 187 | 190 | { Opt_noac, "noac" }, |
| 188 | 191 | { Opt_fsc, "fsc" }, |
| @@ -206,6 +209,7 @@ static const match_table_t cifs_mount_option_tokens = { · 17 unmodified lines | ||
| 206 | 209 | { Opt_dirmode, "dirmode=%s" }, |
| 207 | 210 | { Opt_dirmode, "dir_mode=%s" }, |
| 208 | 211 | { Opt_port, "port=%s" }, |
| 212 | + { Opt_min_enc_offload, "esize=%s" }, | |
| 209 | 213 | { Opt_blocksize, "bsize=%s" }, |
| 210 | 214 | { Opt_rsize, "rsize=%s" }, |
| 211 | 215 | { Opt_wsize, "wsize=%s" }, |
| @@ -262,6 +266,7 @@ static const match_table_t cifs_mount_option_tokens = { · 50 unmodified lines | ||
| 262 | 266 | { Opt_ignore, "nomand" }, |
| 263 | 267 | { Opt_ignore, "relatime" }, |
| 264 | 268 | { Opt_ignore, "_netdev" }, |
| 269 | + { Opt_rootfs, "rootfs" }, | |
| 265 | 270 | |
| 266 | 271 | { Opt_err, NULL } |
| 267 | 272 | }; |
| @@ -298,6 +303,8 @@ enum { · 30 unmodified lines | ||
| 298 | 303 | Opt_cache_loose, |
| 299 | 304 | Opt_cache_strict, |
| 300 | 305 | Opt_cache_none, |
| 306 | + Opt_cache_ro, | |
| 307 | + Opt_cache_rw, | |
| 301 | 308 | Opt_cache_err |
| 302 | 309 | }; |
| 303 | 310 | |
| @@ -305,6 +312,8 @@ static const match_table_t cifs_cacheflavor_tokens = { · 1 unmodified line | ||
| 305 | 312 | { Opt_cache_loose, "loose" }, |
| 306 | 313 | { Opt_cache_strict, "strict" }, |
| 307 | 314 | { Opt_cache_none, "none" }, |
| 315 | + { Opt_cache_ro, "ro" }, | |
| 316 | + { Opt_cache_rw, "singleclient" }, | |
| 308 | 317 | { Opt_cache_err, NULL } |
| 309 | 318 | }; |
| 310 | 319 | |
| @@ -489,7 +498,7 @@ cifs_reconnect(struct TCP_Server_Info *server) · 178 unmodified lines | ||
| 489 | 498 | } else { |
| 490 | 499 | rc = reconn_setup_dfs_targets(cifs_sb, &tgt_list, &tgt_it); |
| 491 | 500 | if (rc && (rc != -EOPNOTSUPP)) { |
| 492 | − cifs_dbg(VFS, "%s: no target servers for DFS failover\n", | |
| 501 | + cifs_server_dbg(VFS, "%s: no target servers for DFS failover\n", | |
| 493 | 502 | __func__); |
| 494 | 503 | } else { |
| 495 | 504 | server->nr_targets = dfs_cache_get_nr_tgts(&tgt_list); |
| @@ -617,12 +626,12 @@ cifs_reconnect(struct TCP_Server_Info *server) · 121 unmodified lines | ||
| 617 | 626 | rc = dfs_cache_noreq_update_tgthint(cifs_sb->origin_fullpath + 1, |
| 618 | 627 | tgt_it); |
| 619 | 628 | if (rc) { |
| 620 | − cifs_dbg(VFS, "%s: failed to update DFS target hint: rc = %d\n", | |
| 629 | + cifs_server_dbg(VFS, "%s: failed to update DFS target hint: rc = %d\n", | |
| 621 | 630 | __func__, rc); |
| 622 | 631 | } |
| 623 | 632 | rc = dfs_cache_update_vol(cifs_sb->origin_fullpath, server); |
| 624 | 633 | if (rc) { |
| 625 | − cifs_dbg(VFS, "%s: failed to update vol info in DFS cache: rc = %d\n", | |
| 634 | + cifs_server_dbg(VFS, "%s: failed to update vol info in DFS cache: rc = %d\n", | |
| 626 | 635 | __func__, rc); |
| 627 | 636 | } |
| 628 | 637 | dfs_cache_free_tgts(&tgt_list); |
| @@ -678,7 +687,7 @@ allocate_buffers(struct TCP_Server_Info *server) · 49 unmodified lines | ||
| 678 | 687 | if (!server->bigbuf) { |
| 679 | 688 | server->bigbuf = (char *)cifs_buf_get(); |
| 680 | 689 | if (!server->bigbuf) { |
| 681 | − cifs_dbg(VFS, "No memory for large SMB response\n"); | |
| 690 | + cifs_server_dbg(VFS, "No memory for large SMB response\n"); | |
| 682 | 691 | msleep(3000); |
| 683 | 692 | /* retry will check if exiting */ |
| 684 | 693 | return false; |
| @@ -691,7 +700,7 @@ allocate_buffers(struct TCP_Server_Info *server) · 6 unmodified lines | ||
| 691 | 700 | if (!server->smallbuf) { |
| 692 | 701 | server->smallbuf = (char *)cifs_small_buf_get(); |
| 693 | 702 | if (!server->smallbuf) { |
| 694 | − cifs_dbg(VFS, "No memory for SMB response\n"); | |
| 703 | + cifs_server_dbg(VFS, "No memory for SMB response\n"); | |
| 695 | 704 | msleep(1000); |
| 696 | 705 | /* retry will check if exiting */ |
| 697 | 706 | return false; |
| @@ -712,7 +721,7 @@ server_unresponsive(struct TCP_Server_Info *server) · 14 unmodified lines | ||
| 712 | 721 | * We need to wait 3 echo intervals to make sure we handle such |
| 713 | 722 | * situations right: |
| 714 | 723 | * 1s client sends a normal SMB request |
| 715 | − * 3s client gets a response | |
| 724 | + * 2s client gets a response | |
| 716 | 725 | * 30s echo workqueue job pops, and decides we got a response recently |
| 717 | 726 | * and don't need to send another |
| 718 | 727 | * ... |
| @@ -722,8 +731,8 @@ server_unresponsive(struct TCP_Server_Info *server) · 3 unmodified lines | ||
| 722 | 731 | if ((server->tcpStatus == CifsGood || |
| 723 | 732 | server->tcpStatus == CifsNeedNegotiate) && |
| 724 | 733 | time_after(jiffies, server->lstrp + 3 * server->echo_interval)) { |
| 725 | − cifs_dbg(VFS, "Server %s has not responded in %lu seconds. Reconnecting...\n", | |
| 726 | − server->hostname, (3 * server->echo_interval) / HZ); | |
| 734 | + cifs_server_dbg(VFS, "has not responded in %lu seconds. Reconnecting...\n", | |
| 735 | + (3 * server->echo_interval) / HZ); | |
| 727 | 736 | cifs_reconnect(server); |
| 728 | 737 | wake_up(&server->response_q); |
| 729 | 738 | return true; |
| @@ -861,7 +870,7 @@ is_smb_response(struct TCP_Server_Info *server, unsigned char type) · 131 unmodified lines | ||
| 861 | 870 | wake_up(&server->response_q); |
| 862 | 871 | break; |
| 863 | 872 | default: |
| 864 | − cifs_dbg(VFS, "RFC 1002 unknown response type 0x%x\n", type); | |
| 873 | + cifs_server_dbg(VFS, "RFC 1002 unknown response type 0x%x\n", type); | |
| 865 | 874 | cifs_reconnect(server); |
| 866 | 875 | } |
| 867 | 876 | |
| @@ -1008,7 +1017,7 @@ standard_receive3(struct TCP_Server_Info *server, struct mid_q_entry *mid) · 140 unmodified lines | ||
| 1008 | 1017 | /* make sure this will fit in a large buffer */ |
| 1009 | 1018 | if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE(server) - |
| 1010 | 1019 | server->vals->header_preamble_size) { |
| 1011 | − cifs_dbg(VFS, "SMB response too long (%u bytes)\n", pdu_length); | |
| 1020 | + cifs_server_dbg(VFS, "SMB response too long (%u bytes)\n", pdu_length); | |
| 1012 | 1021 | cifs_reconnect(server); |
| 1013 | 1022 | wake_up(&server->response_q); |
| 1014 | 1023 | return -ECONNABORTED; |
| @@ -1149,7 +1158,7 @@ next_pdu: · 134 unmodified lines | ||
| 1149 | 1158 | /* make sure we have enough to get to the MID */ |
| 1150 | 1159 | if (server->pdu_size < HEADER_SIZE(server) - 1 - |
| 1151 | 1160 | server->vals->header_preamble_size) { |
| 1152 | − cifs_dbg(VFS, "SMB response too short (%u bytes)\n", | |
| 1161 | + cifs_server_dbg(VFS, "SMB response too short (%u bytes)\n", | |
| 1153 | 1162 | server->pdu_size); |
| 1154 | 1163 | cifs_reconnect(server); |
| 1155 | 1164 | wake_up(&server->response_q); |
| @@ -1222,7 +1231,7 @@ next_pdu: · 66 unmodified lines | ||
| 1222 | 1231 | smb2_add_credits_from_hdr(bufs[i], server); |
| 1223 | 1232 | cifs_dbg(FYI, "Received oplock break\n"); |
| 1224 | 1233 | } else { |
| 1225 | − cifs_dbg(VFS, "No task to wake, unknown frame " | |
| 1234 | + cifs_server_dbg(VFS, "No task to wake, unknown frame " | |
| 1226 | 1235 | "received! NumMids %d\n", |
| 1227 | 1236 | atomic_read(&midCount)); |
| 1228 | 1237 | cifs_dump_mem("Received Data is: ", bufs[i], |
| @@ -1418,14 +1427,32 @@ cifs_parse_cache_flavor(char *value, struct smb_vol *vol) · 189 unmodified lines | ||
| 1418 | 1427 | case Opt_cache_loose: |
| 1419 | 1428 | vol->direct_io = false; |
| 1420 | 1429 | vol->strict_io = false; |
| 1430 | + vol->cache_ro = false; | |
| 1431 | + vol->cache_rw = false; | |
| 1421 | 1432 | break; |
| 1422 | 1433 | case Opt_cache_strict: |
| 1423 | 1434 | vol->direct_io = false; |
| 1424 | 1435 | vol->strict_io = true; |
| 1436 | + vol->cache_ro = false; | |
| 1437 | + vol->cache_rw = false; | |
| 1425 | 1438 | break; |
| 1426 | 1439 | case Opt_cache_none: |
| 1427 | 1440 | vol->direct_io = true; |
| 1428 | 1441 | vol->strict_io = false; |
| 1442 | + vol->cache_ro = false; | |
| 1443 | + vol->cache_rw = false; | |
| 1444 | + break; | |
| 1445 | + case Opt_cache_ro: | |
| 1446 | + vol->direct_io = false; | |
| 1447 | + vol->strict_io = false; | |
| 1448 | + vol->cache_ro = true; | |
| 1449 | + vol->cache_rw = false; | |
| 1450 | + break; | |
| 1451 | + case Opt_cache_rw: | |
| 1452 | + vol->direct_io = false; | |
| 1453 | + vol->strict_io = false; | |
| 1454 | + vol->cache_ro = false; | |
| 1455 | + vol->cache_rw = true; | |
| 1429 | 1456 | break; |
| 1430 | 1457 | default: |
| 1431 | 1458 | cifs_dbg(VFS, "bad cache= option: %s\n", value); |
| @@ -1713,6 +1740,9 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, · 281 unmodified lines | ||
| 1713 | 1740 | case Opt_noautotune: |
| 1714 | 1741 | vol->noautotune = 1; |
| 1715 | 1742 | break; |
| 1743 | + case Opt_nolease: | |
| 1744 | + vol->no_lease = 1; | |
| 1745 | + break; | |
| 1716 | 1746 | case Opt_hard: |
| 1717 | 1747 | vol->retry = 1; |
| 1718 | 1748 | break; |
| @@ -1748,6 +1778,11 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, · 29 unmodified lines | ||
| 1748 | 1778 | case Opt_nodfs: |
| 1749 | 1779 | vol->nodfs = 1; |
| 1750 | 1780 | break; |
| 1781 | + case Opt_rootfs: | |
| 1782 | +#ifdef CONFIG_CIFS_ROOT | |
| 1783 | + vol->rootfs = true; | |
| 1784 | +#endif | |
| 1785 | + break; | |
| 1751 | 1786 | case Opt_posixpaths: |
| 1752 | 1787 | vol->posix_paths = 1; |
| 1753 | 1788 | break; |
| @@ -1855,6 +1890,10 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, · 101 unmodified lines | ||
| 1855 | 1890 | case Opt_sign: |
| 1856 | 1891 | vol->sign = true; |
| 1857 | 1892 | break; |
| 1893 | + case Opt_ignore_signature: | |
| 1894 | + vol->sign = true; | |
| 1895 | + vol->ignore_signature = true; | |
| 1896 | + break; | |
| 1858 | 1897 | case Opt_seal: |
| 1859 | 1898 | /* we do not do the following in secFlags because seal |
| 1860 | 1899 | * is a per tree connection (mount) not a per socket |
| @@ -1989,6 +2028,13 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, · 128 unmodified lines | ||
| 1989 | 2028 | } |
| 1990 | 2029 | port = (unsigned short)option; |
| 1991 | 2030 | break; |
| 2031 | + case Opt_min_enc_offload: | |
| 2032 | + if (get_option_ul(args, &option)) { | |
| 2033 | + cifs_dbg(VFS, "Invalid minimum encrypted read offload size (esize)\n"); | |
| 2034 | + goto cifs_parse_mount_err; | |
| 2035 | + } | |
| 2036 | + vol->min_offload = option; | |
| 2037 | + break; | |
| 1992 | 2038 | case Opt_blocksize: |
| 1993 | 2039 | if (get_option_ul(args, &option)) { |
| 1994 | 2040 | cifs_dbg(VFS, "%s: Invalid blocksize value\n", |
| @@ -2586,6 +2632,12 @@ static int match_server(struct TCP_Server_Info *server, struct smb_vol *vol) · 591 unmodified lines | ||
| 2586 | 2632 | if (server->rdma != vol->rdma) |
| 2587 | 2633 | return 0; |
| 2588 | 2634 | |
| 2635 | + if (server->ignore_signature != vol->ignore_signature) | |
| 2636 | + return 0; | |
| 2637 | + | |
| 2638 | + if (server->min_offload != vol->min_offload) | |
| 2639 | + return 0; | |
| 2640 | + | |
| 2589 | 2641 | return 1; |
| 2590 | 2642 | } |
| 2591 | 2643 | |
| @@ -2681,11 +2733,13 @@ cifs_get_tcp_session(struct smb_vol *volume_info) · 89 unmodified lines | ||
| 2681 | 2733 | goto out_err_crypto_release; |
| 2682 | 2734 | } |
| 2683 | 2735 | |
| 2684 | − tcp_ses->noblocksnd = volume_info->noblocksnd; | |
| 2736 | + tcp_ses->noblockcnt = volume_info->rootfs; | |
| 2737 | + tcp_ses->noblocksnd = volume_info->noblocksnd || volume_info->rootfs; | |
| 2685 | 2738 | tcp_ses->noautotune = volume_info->noautotune; |
| 2686 | 2739 | tcp_ses->tcp_nodelay = volume_info->sockopt_tcp_nodelay; |
| 2687 | 2740 | tcp_ses->rdma = volume_info->rdma; |
| 2688 | 2741 | tcp_ses->in_flight = 0; |
| 2742 | + tcp_ses->max_in_flight = 0; | |
| 2689 | 2743 | tcp_ses->credits = 1; |
| 2690 | 2744 | init_waitqueue_head(&tcp_ses->response_q); |
| 2691 | 2745 | init_waitqueue_head(&tcp_ses->request_q); |
| @@ -2760,10 +2814,11 @@ smbd_connected: · 68 unmodified lines | ||
| 2760 | 2814 | module_put(THIS_MODULE); |
| 2761 | 2815 | goto out_err_crypto_release; |
| 2762 | 2816 | } |
| 2817 | + tcp_ses->min_offload = volume_info->min_offload; | |
| 2763 | 2818 | tcp_ses->tcpStatus = CifsNeedNegotiate; |
| 2764 | 2819 | |
| 2765 | 2820 | tcp_ses->nr_targets = 1; |
| 2766 | − | |
| 2821 | + tcp_ses->ignore_signature = volume_info->ignore_signature; | |
| 2767 | 2822 | /* thread spawned, put it on the list */ |
| 2768 | 2823 | spin_lock(&cifs_tcp_ses_lock); |
| 2769 | 2824 | list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list); |
| @@ -2840,16 +2895,17 @@ cifs_setup_ipc(struct cifs_ses *ses, struct smb_vol *volume_info) · 70 unmodified lines | ||
| 2840 | 2895 | struct nls_table *nls_codepage; |
| 2841 | 2896 | char unc[SERVER_NAME_LENGTH + sizeof("//x/IPC$")] = {0}; |
| 2842 | 2897 | bool seal = false; |
| 2898 | + struct TCP_Server_Info *server = ses->server; | |
| 2843 | 2899 | |
| 2844 | 2900 | /* |
| 2845 | 2901 | * If the mount request that resulted in the creation of the |
| 2846 | 2902 | * session requires encryption, force IPC to be encrypted too. |
| 2847 | 2903 | */ |
| 2848 | 2904 | if (volume_info->seal) { |
| 2849 | − if (ses->server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION) | |
| 2905 | + if (server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION) | |
| 2850 | 2906 | seal = true; |
| 2851 | 2907 | else { |
| 2852 | − cifs_dbg(VFS, | |
| 2908 | + cifs_server_dbg(VFS, | |
| 2853 | 2909 | "IPC: server doesn't support encryption\n"); |
| 2854 | 2910 | return -EOPNOTSUPP; |
| 2855 | 2911 | } |
| @@ -2859,7 +2915,7 @@ cifs_setup_ipc(struct cifs_ses *ses, struct smb_vol *volume_info) · 3 unmodified lines | ||
| 2859 | 2915 | if (tcon == NULL) |
| 2860 | 2916 | return -ENOMEM; |
| 2861 | 2917 | |
| 2862 | − scnprintf(unc, sizeof(unc), "\\\\%s\\IPC$", ses->server->hostname); | |
| 2918 | + scnprintf(unc, sizeof(unc), "\\\\%s\\IPC$", server->hostname); | |
| 2863 | 2919 | |
| 2864 | 2920 | /* cannot fail */ |
| 2865 | 2921 | nls_codepage = load_nls_default(); |
| @@ -2868,11 +2924,11 @@ cifs_setup_ipc(struct cifs_ses *ses, struct smb_vol *volume_info) · 2 unmodified lines | ||
| 2868 | 2924 | tcon->ses = ses; |
| 2869 | 2925 | tcon->ipc = true; |
| 2870 | 2926 | tcon->seal = seal; |
| 2871 | − rc = ses->server->ops->tree_connect(xid, ses, unc, tcon, nls_codepage); | |
| 2927 | + rc = server->ops->tree_connect(xid, ses, unc, tcon, nls_codepage); | |
| 2872 | 2928 | free_xid(xid); |
| 2873 | 2929 | |
| 2874 | 2930 | if (rc) { |
| 2875 | − cifs_dbg(VFS, "failed to connect to IPC (rc=%d)\n", rc); | |
| 2931 | + cifs_server_dbg(VFS, "failed to connect to IPC (rc=%d)\n", rc); | |
| 2876 | 2932 | tconInfoFree(tcon); |
| 2877 | 2933 | goto out; |
| 2878 | 2934 | } |
| @@ -2958,7 +3014,7 @@ void cifs_put_smb_ses(struct cifs_ses *ses) · 79 unmodified lines | ||
| 2958 | 3014 | xid = get_xid(); |
| 2959 | 3015 | rc = server->ops->logoff(xid, ses); |
| 2960 | 3016 | if (rc) |
| 2961 | − cifs_dbg(VFS, "%s: Session Logoff failure rc=%d\n", | |
| 3017 | + cifs_server_dbg(VFS, "%s: Session Logoff failure rc=%d\n", | |
| 2962 | 3018 | __func__, rc); |
| 2963 | 3019 | _free_xid(xid); |
| 2964 | 3020 | } |
| @@ -3212,7 +3268,6 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) · 247 unmodified lines | ||
| 3212 | 3268 | |
| 3213 | 3269 | ses->sectype = volume_info->sectype; |
| 3214 | 3270 | ses->sign = volume_info->sign; |
| 3215 | − | |
| 3216 | 3271 | mutex_lock(&ses->session_mutex); |
| 3217 | 3272 | rc = cifs_negotiate_protocol(xid, ses); |
| 3218 | 3273 | if (!rc) |
| @@ -3250,6 +3305,8 @@ static int match_tcon(struct cifs_tcon *tcon, struct smb_vol *volume_info) · 31 unmodified lines | ||
| 3250 | 3305 | return 0; |
| 3251 | 3306 | if (tcon->handle_timeout != volume_info->handle_timeout) |
| 3252 | 3307 | return 0; |
| 3308 | + if (tcon->no_lease != volume_info->no_lease) | |
| 3309 | + return 0; | |
| 3253 | 3310 | return 1; |
| 3254 | 3311 | } |
| 3255 | 3312 | |
| @@ -3455,6 +3512,14 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info) · 199 unmodified lines | ||
| 3455 | 3512 | tcon->use_resilient = true; |
| 3456 | 3513 | } |
| 3457 | 3514 | |
| 3515 | + /* If the user really knows what they are doing they can override */ | |
| 3516 | + if (tcon->share_flags & SMB2_SHAREFLAG_NO_CACHING) { | |
| 3517 | + if (volume_info->cache_ro) | |
| 3518 | + cifs_dbg(VFS, "cache=ro requested on mount but NO_CACHING flag set on share\n"); | |
| 3519 | + else if (volume_info->cache_rw) | |
| 3520 | + cifs_dbg(VFS, "cache=singleclient requested on mount but NO_CACHING flag set on share\n"); | |
| 3521 | + } | |
| 3522 | + | |
| 3458 | 3523 | /* |
| 3459 | 3524 | * We can have only one retry value for a connection to a share so for |
| 3460 | 3525 | * resources mounted more than once to the same server share the last |
| @@ -3464,6 +3529,7 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info) · 3 unmodified lines | ||
| 3464 | 3529 | tcon->nocase = volume_info->nocase; |
| 3465 | 3530 | tcon->nohandlecache = volume_info->nohandlecache; |
| 3466 | 3531 | tcon->local_lease = volume_info->local_lease; |
| 3532 | + tcon->no_lease = volume_info->no_lease; | |
| 3467 | 3533 | INIT_LIST_HEAD(&tcon->pending_opens); |
| 3468 | 3534 | |
| 3469 | 3535 | spin_lock(&cifs_tcp_ses_lock); |
| @@ -3659,10 +3725,10 @@ bind_socket(struct TCP_Server_Info *server) · 189 unmodified lines | ||
| 3659 | 3725 | saddr4 = (struct sockaddr_in *)&server->srcaddr; |
| 3660 | 3726 | saddr6 = (struct sockaddr_in6 *)&server->srcaddr; |
| 3661 | 3727 | if (saddr6->sin6_family == AF_INET6) |
| 3662 | − cifs_dbg(VFS, "Failed to bind to: %pI6c, error: %d\n", | |
| 3728 | + cifs_server_dbg(VFS, "Failed to bind to: %pI6c, error: %d\n", | |
| 3663 | 3729 | &saddr6->sin6_addr, rc); |
| 3664 | 3730 | else |
| 3665 | − cifs_dbg(VFS, "Failed to bind to: %pI4, error: %d\n", | |
| 3731 | + cifs_server_dbg(VFS, "Failed to bind to: %pI4, error: %d\n", | |
| 3666 | 3732 | &saddr4->sin_addr.s_addr, rc); |
| 3667 | 3733 | } |
| 3668 | 3734 | } |
| @@ -3766,7 +3832,7 @@ generic_ip_connect(struct TCP_Server_Info *server) · 97 unmodified lines | ||
| 3766 | 3832 | rc = __sock_create(cifs_net_ns(server), sfamily, SOCK_STREAM, |
| 3767 | 3833 | IPPROTO_TCP, &socket, 1); |
| 3768 | 3834 | if (rc < 0) { |
| 3769 | − cifs_dbg(VFS, "Error %d creating socket\n", rc); | |
| 3835 | + cifs_server_dbg(VFS, "Error %d creating socket\n", rc); | |
| 3770 | 3836 | server->ssocket = NULL; |
| 3771 | 3837 | return rc; |
| 3772 | 3838 | } |
| @@ -3814,7 +3880,11 @@ generic_ip_connect(struct TCP_Server_Info *server) · 41 unmodified lines | ||
| 3814 | 3880 | socket->sk->sk_sndbuf, |
| 3815 | 3881 | socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo); |
| 3816 | 3882 | |
| 3817 | − rc = socket->ops->connect(socket, saddr, slen, 0); | |
| 3883 | + rc = socket->ops->connect(socket, saddr, slen, | |
| 3884 | + server->noblockcnt ? O_NONBLOCK : 0); | |
| 3885 | + | |
| 3886 | + if (rc == -EINPROGRESS) | |
| 3887 | + rc = 0; | |
| 3818 | 3888 | if (rc < 0) { |
| 3819 | 3889 | cifs_dbg(FYI, "Error %d connecting to server\n", rc); |
| 3820 | 3890 | sock_release(socket); |
| @@ -4040,6 +4110,14 @@ int cifs_setup_cifs_sb(struct smb_vol *pvolume_info, · 219 unmodified lines | ||
| 4040 | 4110 | cifs_dbg(FYI, "mounting share using direct i/o\n"); |
| 4041 | 4111 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO; |
| 4042 | 4112 | } |
| 4113 | + if (pvolume_info->cache_ro) { | |
| 4114 | + cifs_dbg(VFS, "mounting share with read only caching. Ensure that the share will not be modified while in use.\n"); | |
| 4115 | + cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RO_CACHE; | |
| 4116 | + } else if (pvolume_info->cache_rw) { | |
| 4117 | + cifs_dbg(VFS, "mounting share in single client RW caching mode. Ensure that no other systems will be accessing the share.\n"); | |
| 4118 | + cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_RO_CACHE | | |
| 4119 | + CIFS_MOUNT_RW_CACHE); | |
| 4120 | + } | |
| 4043 | 4121 | if (pvolume_info->mfsymlinks) { |
| 4044 | 4122 | if (pvolume_info->sfu_emul) { |
| 4045 | 4123 | /* |
| @@ -4150,7 +4228,7 @@ static int mount_get_conns(struct smb_vol *vol, struct cifs_sb_info *cifs_sb, · 104 unmodified lines | ||
| 4150 | 4228 | |
| 4151 | 4229 | if ((vol->persistent == true) && (!(ses->server->capabilities & |
| 4152 | 4230 | SMB2_GLOBAL_CAP_PERSISTENT_HANDLES))) { |
| 4153 | − cifs_dbg(VFS, "persistent handles not supported by server\n"); | |
| 4231 | + cifs_server_dbg(VFS, "persistent handles not supported by server\n"); | |
| 4154 | 4232 | return -EOPNOTSUPP; |
| 4155 | 4233 | } |
| 4156 | 4234 | |
| @@ -4182,8 +4260,18 @@ static int mount_get_conns(struct smb_vol *vol, struct cifs_sb_info *cifs_sb, · 25 unmodified lines | ||
| 4182 | 4260 | tcon->unix_ext = 0; /* server does not support them */ |
| 4183 | 4261 | |
| 4184 | 4262 | /* do not care if a following call succeed - informational */ |
| 4185 | − if (!tcon->pipe && server->ops->qfs_tcon) | |
| 4263 | + if (!tcon->pipe && server->ops->qfs_tcon) { | |
| 4186 | 4264 | server->ops->qfs_tcon(*xid, tcon); |
| 4265 | + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE) { | |
| 4266 | + if (tcon->fsDevInfo.DeviceCharacteristics & | |
| 4267 | + FILE_READ_ONLY_DEVICE) | |
| 4268 | + cifs_dbg(VFS, "mounted to read only share\n"); | |
| 4269 | + else if ((cifs_sb->mnt_cifs_flags & | |
| 4270 | + CIFS_MOUNT_RW_CACHE) == 0) | |
| 4271 | + cifs_dbg(VFS, "read only mount of RW share\n"); | |
| 4272 | + /* no need to log a RW mount of a typical RW share */ | |
| 4273 | + } | |
| 4274 | + } | |
| 4187 | 4275 | |
| 4188 | 4276 | cifs_sb->wsize = server->ops->negotiate_wsize(tcon, vol); |
| 4189 | 4277 | cifs_sb->rsize = server->ops->negotiate_rsize(tcon, vol); |
| @@ -4588,7 +4676,7 @@ static int is_path_remote(struct cifs_sb_info *cifs_sb, struct smb_vol *vol, · 398 unmodified lines | ||
| 4588 | 4676 | rc = cifs_are_all_path_components_accessible(server, xid, tcon, |
| 4589 | 4677 | cifs_sb, full_path, tcon->Flags & SMB_SHARE_IS_IN_DFS); |
| 4590 | 4678 | if (rc != 0) { |
| 4591 | − cifs_dbg(VFS, "cannot query dirs between root and final path, " | |
| 4679 | + cifs_server_dbg(VFS, "cannot query dirs between root and final path, " | |
| 4592 | 4680 | "enabling CIFS_MOUNT_USE_PREFIX_PATH\n"); |
| 4593 | 4681 | cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_USE_PREFIX_PATH; |
| 4594 | 4682 | rc = 0; |
| @@ -5090,7 +5178,7 @@ cifs_setup_session(const unsigned int xid, struct cifs_ses *ses, · 495 unmodified lines | ||
| 5090 | 5178 | rc = server->ops->sess_setup(xid, ses, nls_info); |
| 5091 | 5179 | |
| 5092 | 5180 | if (rc) |
| 5093 | − cifs_dbg(VFS, "Send error in SessSetup = %d\n", rc); | |
| 5181 | + cifs_server_dbg(VFS, "Send error in SessSetup = %d\n", rc); | |
| 5094 | 5182 | |
| 5095 | 5183 | return rc; |
| 5096 | 5184 | } |
| @@ -125,7 +125,7 @@ cifs_bp_rename_retry: · 124 unmodified lines | ||
| 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 */ |
| @@ -1693,9 +1693,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *flock) · 1692 unmodified lines | ||
| 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; |
| @@ -1711,8 +1709,6 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *flock) · 9 unmodified lines | ||
| 1711 | 1709 | cifs_read_flock(flock, &type, &lock, &unlock, &wait_flag, |
| 1712 | 1710 | tcon->ses->server); |
| 1713 | 1711 | cifs_sb = CIFS_FILE_SB(file); |
| 1714 | − netfid = cfile->fid.netfid; | |
| 1715 | − cinode = CIFS_I(file_inode(file)); | |
| 1716 | 1712 | |
| 1717 | 1713 | if (cap_unix(tcon->ses) && |
| 1718 | 1714 | (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) && |
| @@ -1764,7 +1760,6 @@ cifs_write(struct cifsFileInfo *open_file, __u32 pid, const char *write_data, · 45 unmodified lines | ||
| 1764 | 1760 | int rc = 0; |
| 1765 | 1761 | unsigned int bytes_written = 0; |
| 1766 | 1762 | unsigned int total_written; |
| 1767 | − struct cifs_sb_info *cifs_sb; | |
| 1768 | 1763 | struct cifs_tcon *tcon; |
| 1769 | 1764 | struct TCP_Server_Info *server; |
| 1770 | 1765 | unsigned int xid; |
| @@ -1772,8 +1767,6 @@ cifs_write(struct cifsFileInfo *open_file, __u32 pid, const char *write_data, · 1 unmodified line | ||
| 1772 | 1767 | struct cifsInodeInfo *cifsi = CIFS_I(d_inode(dentry)); |
| 1773 | 1768 | struct cifs_io_parms io_parms; |
| 1774 | 1769 | |
| 1775 | − cifs_sb = CIFS_SB(dentry->d_sb); | |
| 1776 | − | |
| 1777 | 1770 | cifs_dbg(FYI, "write %zd bytes to offset %lld of %pd\n", |
| 1778 | 1771 | write_size, *offset, dentry); |
| 1779 | 1772 | |
| @@ -1980,6 +1973,77 @@ find_writable_file(struct cifsInodeInfo *cifs_inode, bool fsuid_only) · 200 unmodified lines | ||
| 1980 | 1973 | return cfile; |
| 1981 | 1974 | } |
| 1982 | 1975 | |
| 1976 | +int | |
| 1977 | +cifs_get_writable_path(struct cifs_tcon *tcon, const char *name, | |
| 1978 | + struct cifsFileInfo **ret_file) | |
| 1979 | +{ | |
| 1980 | + struct list_head *tmp; | |
| 1981 | + struct cifsFileInfo *cfile; | |
| 1982 | + struct cifsInodeInfo *cinode; | |
| 1983 | + char *full_path; | |
| 1984 | + | |
| 1985 | + *ret_file = NULL; | |
| 1986 | + | |
| 1987 | + spin_lock(&tcon->open_file_lock); | |
| 1988 | + list_for_each(tmp, &tcon->openFileList) { | |
| 1989 | + cfile = list_entry(tmp, struct cifsFileInfo, | |
| 1990 | + tlist); | |
| 1991 | + full_path = build_path_from_dentry(cfile->dentry); | |
| 1992 | + if (full_path == NULL) { | |
| 1993 | + spin_unlock(&tcon->open_file_lock); | |
| 1994 | + return -ENOMEM; | |
| 1995 | + } | |
| 1996 | + if (strcmp(full_path, name)) { | |
| 1997 | + kfree(full_path); | |
| 1998 | + continue; | |
| 1999 | + } | |
| 2000 | + | |
| 2001 | + kfree(full_path); | |
| 2002 | + cinode = CIFS_I(d_inode(cfile->dentry)); | |
| 2003 | + spin_unlock(&tcon->open_file_lock); | |
| 2004 | + return cifs_get_writable_file(cinode, 0, ret_file); | |
| 2005 | + } | |
| 2006 | + | |
| 2007 | + spin_unlock(&tcon->open_file_lock); | |
| 2008 | + return -ENOENT; | |
| 2009 | +} | |
| 2010 | + | |
| 2011 | +int | |
| 2012 | +cifs_get_readable_path(struct cifs_tcon *tcon, const char *name, | |
| 2013 | + struct cifsFileInfo **ret_file) | |
| 2014 | +{ | |
| 2015 | + struct list_head *tmp; | |
| 2016 | + struct cifsFileInfo *cfile; | |
| 2017 | + struct cifsInodeInfo *cinode; | |
| 2018 | + char *full_path; | |
| 2019 | + | |
| 2020 | + *ret_file = NULL; | |
| 2021 | + | |
| 2022 | + spin_lock(&tcon->open_file_lock); | |
| 2023 | + list_for_each(tmp, &tcon->openFileList) { | |
| 2024 | + cfile = list_entry(tmp, struct cifsFileInfo, | |
| 2025 | + tlist); | |
| 2026 | + full_path = build_path_from_dentry(cfile->dentry); | |
| 2027 | + if (full_path == NULL) { | |
| 2028 | + spin_unlock(&tcon->open_file_lock); | |
| 2029 | + return -ENOMEM; | |
| 2030 | + } | |
| 2031 | + if (strcmp(full_path, name)) { | |
| 2032 | + kfree(full_path); | |
| 2033 | + continue; | |
| 2034 | + } | |
| 2035 | + | |
| 2036 | + kfree(full_path); | |
| 2037 | + cinode = CIFS_I(d_inode(cfile->dentry)); | |
| 2038 | + spin_unlock(&tcon->open_file_lock); | |
| 2039 | + *ret_file = find_readable_file(cinode, 0); | |
| 2040 | + return *ret_file ? 0 : -ENOENT; | |
| 2041 | + } | |
| 2042 | + | |
| 2043 | + spin_unlock(&tcon->open_file_lock); | |
| 2044 | + return -ENOENT; | |
| 2045 | +} | |
| 2046 | + | |
| 1983 | 2047 | static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to) |
| 1984 | 2048 | { |
| 1985 | 2049 | struct address_space *mapping = page->mapping; |
| @@ -3577,10 +3641,8 @@ collect_uncached_read_data(struct cifs_aio_ctx *ctx) · 1591 unmodified lines | ||
| 3577 | 3641 | struct cifs_readdata *rdata, *tmp; |
| 3578 | 3642 | struct iov_iter *to = &ctx->iter; |
| 3579 | 3643 | struct cifs_sb_info *cifs_sb; |
| 3580 | − struct cifs_tcon *tcon; | |
| 3581 | 3644 | int rc; |
| 3582 | 3645 | |
| 3583 | − tcon = tlink_tcon(ctx->cfile->tlink); | |
| 3584 | 3646 | cifs_sb = CIFS_SB(ctx->cfile->dentry->d_sb); |
| 3585 | 3647 | |
| 3586 | 3648 | mutex_lock(&ctx->aio_mutex); |
| @@ -893,8 +893,17 @@ cifs_get_inode_info(struct inode **inode, const char *full_path, · 892 unmodified lines | ||
| 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); |
| @@ -2480,7 +2489,8 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) · 1579 unmodified lines | ||
| 2480 | 2489 | if (attrs->ia_valid & ATTR_GID) |
| 2481 | 2490 | gid = attrs->ia_gid; |
| 2482 | 2491 | |
| 2483 | − if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | |
| 2492 | + if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) || | |
| 2493 | + (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)) { | |
| 2484 | 2494 | if (uid_valid(uid) || gid_valid(gid)) { |
| 2485 | 2495 | rc = id_mode_to_cifs_acl(inode, full_path, NO_CHANGE_64, |
| 2486 | 2496 | uid, gid); |
| @@ -2501,7 +2511,8 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs) · 14 unmodified lines | ||
| 2501 | 2511 | if (attrs->ia_valid & ATTR_MODE) { |
| 2502 | 2512 | mode = attrs->ia_mode; |
| 2503 | 2513 | rc = 0; |
| 2504 | − if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) { | |
| 2514 | + if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) || | |
| 2515 | + (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MODE_FROM_SID)) { | |
| 2505 | 2516 | rc = id_mode_to_cifs_acl(inode, full_path, mode, |
| 2506 | 2517 | INVALID_UID, INVALID_GID); |
| 2507 | 2518 | if (rc) { |
| @@ -51,7 +51,8 @@ static int · 50 unmodified lines | ||
| 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; |
| @@ -83,10 +84,16 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, · 25 unmodified lines | ||
| 83 | 84 | resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER; |
| 84 | 85 | memset(rsp_iov, 0, sizeof(rsp_iov)); |
| 85 | 86 | |
| 87 | + /* We already have a handle so we can skip the open */ | |
| 88 | + if (cfile) | |
| 89 | + goto after_open; | |
| 90 | + | |
| 86 | 91 | /* Open */ |
| 87 | 92 | utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb); |
| 88 | − if (!utf16_path) | |
| 89 | − return -ENOMEM; | |
| 93 | + if (!utf16_path) { | |
| 94 | + rc = -ENOMEM; | |
| 95 | + goto finished; | |
| 96 | + } | |
| 90 | 97 | |
| 91 | 98 | oparms.tcon = tcon; |
| 92 | 99 | oparms.desired_access = desired_access; |
| @@ -106,7 +113,10 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, · 13 unmodified lines | ||
| 106 | 113 | if (rc) |
| 107 | 114 | goto finished; |
| 108 | 115 | |
| 109 | − smb2_set_next_command(tcon, &rqst[num_rqst++]); | |
| 116 | + smb2_set_next_command(tcon, &rqst[num_rqst]); | |
| 117 | + after_open: | |
| 118 | + num_rqst++; | |
| 119 | + rc = 0; | |
| 110 | 120 | |
| 111 | 121 | /* Operation */ |
| 112 | 122 | switch (command) { |
| @@ -115,15 +125,31 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, · 2 unmodified lines | ||
| 115 | 125 | rqst[num_rqst].rq_iov = qi_iov; |
| 116 | 126 | rqst[num_rqst].rq_nvec = 1; |
| 117 | 127 | |
| 118 | − rc = SMB2_query_info_init(tcon, &rqst[num_rqst], COMPOUND_FID, | |
| 119 | − COMPOUND_FID, FILE_ALL_INFORMATION, | |
| 128 | + if (cfile) | |
| 129 | + rc = SMB2_query_info_init(tcon, &rqst[num_rqst], | |
| 130 | + cfile->fid.persistent_fid, | |
| 131 | + cfile->fid.volatile_fid, | |
| 132 | + FILE_ALL_INFORMATION, | |
| 133 | + SMB2_O_INFO_FILE, 0, | |
| 134 | + sizeof(struct smb2_file_all_info) + | |
| 135 | + PATH_MAX * 2, 0, NULL); | |
| 136 | + else { | |
| 137 | + rc = SMB2_query_info_init(tcon, &rqst[num_rqst], | |
| 138 | + COMPOUND_FID, | |
| 139 | + COMPOUND_FID, | |
| 140 | + FILE_ALL_INFORMATION, | |
| 120 | 141 | SMB2_O_INFO_FILE, 0, |
| 121 | 142 | sizeof(struct smb2_file_all_info) + |
| 122 | 143 | PATH_MAX * 2, 0, NULL); |
| 144 | + if (!rc) { | |
| 145 | + smb2_set_next_command(tcon, &rqst[num_rqst]); | |
| 146 | + smb2_set_related(&rqst[num_rqst]); | |
| 147 | + } | |
| 148 | + } | |
| 149 | + | |
| 123 | 150 | if (rc) |
| 124 | 151 | goto finished; |
| 125 | − smb2_set_next_command(tcon, &rqst[num_rqst]); | |
| 126 | − smb2_set_related(&rqst[num_rqst++]); | |
| 152 | + num_rqst++; | |
| 127 | 153 | trace_smb3_query_info_compound_enter(xid, ses->Suid, tcon->tid, |
| 128 | 154 | full_path); |
| 129 | 155 | break; |
| @@ -182,14 +208,27 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, · 52 unmodified lines | ||
| 182 | 208 | size[0] = sizeof(FILE_BASIC_INFO); |
| 183 | 209 | data[0] = ptr; |
| 184 | 210 | |
| 185 | − rc = SMB2_set_info_init(tcon, &rqst[num_rqst], COMPOUND_FID, | |
| 186 | − COMPOUND_FID, current->tgid, | |
| 187 | − FILE_BASIC_INFORMATION, | |
| 188 | − SMB2_O_INFO_FILE, 0, data, size); | |
| 211 | + if (cfile) | |
| 212 | + rc = SMB2_set_info_init(tcon, &rqst[num_rqst], | |
| 213 | + cfile->fid.persistent_fid, | |
| 214 | + cfile->fid.volatile_fid, current->tgid, | |
| 215 | + FILE_BASIC_INFORMATION, | |
| 216 | + SMB2_O_INFO_FILE, 0, data, size); | |
| 217 | + else { | |
| 218 | + rc = SMB2_set_info_init(tcon, &rqst[num_rqst], | |
| 219 | + COMPOUND_FID, | |
| 220 | + COMPOUND_FID, current->tgid, | |
| 221 | + FILE_BASIC_INFORMATION, | |
| 222 | + SMB2_O_INFO_FILE, 0, data, size); | |
| 223 | + if (!rc) { | |
| 224 | + smb2_set_next_command(tcon, &rqst[num_rqst]); | |
| 225 | + smb2_set_related(&rqst[num_rqst]); | |
| 226 | + } | |
| 227 | + } | |
| 228 | + | |
| 189 | 229 | if (rc) |
| 190 | 230 | goto finished; |
| 191 | − smb2_set_next_command(tcon, &rqst[num_rqst]); | |
| 192 | − smb2_set_related(&rqst[num_rqst++]); | |
| 231 | + num_rqst++; | |
| 193 | 232 | trace_smb3_set_info_compound_enter(xid, ses->Suid, tcon->tid, |
| 194 | 233 | full_path); |
| 195 | 234 | break; |
| @@ -210,14 +249,25 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, · 14 unmodified lines | ||
| 210 | 249 | size[1] = len + 2 /* null */; |
| 211 | 250 | data[1] = (__le16 *)ptr; |
| 212 | 251 | |
| 213 | − rc = SMB2_set_info_init(tcon, &rqst[num_rqst], COMPOUND_FID, | |
| 214 | − COMPOUND_FID, current->tgid, | |
| 215 | − FILE_RENAME_INFORMATION, | |
| 252 | + if (cfile) | |
| 253 | + rc = SMB2_set_info_init(tcon, &rqst[num_rqst], | |
| 254 | + cfile->fid.persistent_fid, | |
| 255 | + cfile->fid.volatile_fid, | |
| 256 | + current->tgid, FILE_RENAME_INFORMATION, | |
| 257 | + SMB2_O_INFO_FILE, 0, data, size); | |
| 258 | + else { | |
| 259 | + rc = SMB2_set_info_init(tcon, &rqst[num_rqst], | |
| 260 | + COMPOUND_FID, COMPOUND_FID, | |
| 261 | + current->tgid, FILE_RENAME_INFORMATION, | |
| 216 | 262 | SMB2_O_INFO_FILE, 0, data, size); |
| 263 | + if (!rc) { | |
| 264 | + smb2_set_next_command(tcon, &rqst[num_rqst]); | |
| 265 | + smb2_set_related(&rqst[num_rqst]); | |
| 266 | + } | |
| 267 | + } | |
| 217 | 268 | if (rc) |
| 218 | 269 | goto finished; |
| 219 | − smb2_set_next_command(tcon, &rqst[num_rqst]); | |
| 220 | − smb2_set_related(&rqst[num_rqst++]); | |
| 270 | + num_rqst++; | |
| 221 | 271 | trace_smb3_rename_enter(xid, ses->Suid, tcon->tid, full_path); |
| 222 | 272 | break; |
| 223 | 273 | case SMB2_OP_HARDLINK: |
| @@ -254,21 +304,43 @@ smb2_compound_op(const unsigned int xid, struct cifs_tcon *tcon, · 30 unmodified lines | ||
| 254 | 304 | if (rc) |
| 255 | 305 | goto finished; |
| 256 | 306 | |
| 307 | + /* We already have a handle so we can skip the close */ | |
| 308 | + if (cfile) | |
| 309 | + goto after_close; | |
| 257 | 310 | /* Close */ |
| 258 | 311 | memset(&close_iov, 0, sizeof(close_iov)); |
| 259 | 312 | rqst[num_rqst].rq_iov = close_iov; |
| 260 | 313 | rqst[num_rqst].rq_nvec = 1; |
| 261 | 314 | rc = SMB2_close_init(tcon, &rqst[num_rqst], COMPOUND_FID, |
| 262 | 315 | COMPOUND_FID); |
| 263 | − smb2_set_related(&rqst[num_rqst++]); | |
| 316 | + smb2_set_related(&rqst[num_rqst]); | |
| 264 | 317 | if (rc) |
| 265 | 318 | goto finished; |
| 266 | − | |
| 267 | − rc = compound_send_recv(xid, ses, flags, num_rqst, rqst, | |
| 268 | − resp_buftype, rsp_iov); | |
| 319 | + after_close: | |
| 320 | + num_rqst++; | |
| 321 | + | |
| 322 | + if (cfile) { | |
| 323 | + cifsFileInfo_put(cfile); | |
| 324 | + cfile = NULL; | |
| 325 | + rc = compound_send_recv(xid, ses, flags, num_rqst - 2, | |
| 326 | + &rqst[1], &resp_buftype[1], | |
| 327 | + &rsp_iov[1]); | |
| 328 | + } else | |
| 329 | + rc = compound_send_recv(xid, ses, flags, num_rqst, | |
| 330 | + rqst, resp_buftype, | |
| 331 | + rsp_iov); | |
| 269 | 332 | |
| 270 | 333 | finished: |
| 334 | + if (cfile) | |
| 335 | + cifsFileInfo_put(cfile); | |
| 336 | + | |
| 271 | 337 | SMB2_open_free(&rqst[0]); |
| 338 | + if (rc == -EREMCHG) { | |
| 339 | + printk_once(KERN_WARNING "server share %s deleted\n", | |
| 340 | + tcon->treeName); | |
| 341 | + tcon->need_reconnect = true; | |
| 342 | + } | |
| 343 | + | |
| 272 | 344 | switch (command) { |
| 273 | 345 | case SMB2_OP_QUERY_INFO: |
| 274 | 346 | if (rc == 0) { |
| @@ -371,6 +443,7 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, · 96 unmodified lines | ||
| 371 | 443 | __u32 create_options = 0; |
| 372 | 444 | struct cifs_fid fid; |
| 373 | 445 | bool no_cached_open = tcon->nohandlecache; |
| 446 | + struct cifsFileInfo *cfile; | |
| 374 | 447 | |
| 375 | 448 | *adjust_tz = false; |
| 376 | 449 | *symlink = false; |
| @@ -402,9 +475,10 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, · 25 unmodified lines | ||
| 402 | 475 | if (backup_cred(cifs_sb)) |
| 403 | 476 | create_options |= CREATE_OPEN_BACKUP_INTENT; |
| 404 | 477 | |
| 478 | + cifs_get_readable_path(tcon, full_path, &cfile); | |
| 405 | 479 | rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, |
| 406 | 480 | FILE_READ_ATTRIBUTES, FILE_OPEN, create_options, |
| 407 | − smb2_data, SMB2_OP_QUERY_INFO); | |
| 481 | + smb2_data, SMB2_OP_QUERY_INFO, cfile); | |
| 408 | 482 | if (rc == -EOPNOTSUPP) { |
| 409 | 483 | *symlink = true; |
| 410 | 484 | create_options |= OPEN_REPARSE_POINT; |
| @@ -413,7 +487,7 @@ smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, · 2 unmodified lines | ||
| 413 | 487 | rc = smb2_compound_op(xid, tcon, cifs_sb, full_path, |
| 414 | 488 | FILE_READ_ATTRIBUTES, FILE_OPEN, |
| 415 | 489 | create_options, smb2_data, |
| 416 | − SMB2_OP_QUERY_INFO); | |
| 490 | + SMB2_OP_QUERY_INFO, NULL); | |
| 417 | 491 | } |
| 418 | 492 | if (rc) |
| 419 | 493 | goto out; |
| @@ -430,7 +504,7 @@ smb2_mkdir(const unsigned int xid, struct cifs_tcon *tcon, const char *name, · 10 unmodified lines | ||
| 430 | 504 | { |
| 431 | 505 | return smb2_compound_op(xid, tcon, cifs_sb, name, |
| 432 | 506 | FILE_WRITE_ATTRIBUTES, FILE_CREATE, |
| 433 | − CREATE_NOT_FILE, NULL, SMB2_OP_MKDIR); | |
| 507 | + CREATE_NOT_FILE, NULL, SMB2_OP_MKDIR, NULL); | |
| 434 | 508 | } |
| 435 | 509 | |
| 436 | 510 | void |
| @@ -440,6 +514,7 @@ smb2_mkdir_setinfo(struct inode *inode, const char *name, · 3 unmodified lines | ||
| 440 | 514 | { |
| 441 | 515 | FILE_BASIC_INFO data; |
| 442 | 516 | struct cifsInodeInfo *cifs_i; |
| 517 | + struct cifsFileInfo *cfile; | |
| 443 | 518 | u32 dosattrs; |
| 444 | 519 | int tmprc; |
| 445 | 520 | |
| @@ -447,9 +522,11 @@ smb2_mkdir_setinfo(struct inode *inode, const char *name, · 1 unmodified line | ||
| 447 | 522 | cifs_i = CIFS_I(inode); |
| 448 | 523 | dosattrs = cifs_i->cifsAttrs | ATTR_READONLY; |
| 449 | 524 | data.Attributes = cpu_to_le32(dosattrs); |
| 525 | + cifs_get_writable_path(tcon, name, &cfile); | |
| 450 | 526 | tmprc = smb2_compound_op(xid, tcon, cifs_sb, name, |
| 451 | 527 | FILE_WRITE_ATTRIBUTES, FILE_CREATE, |
| 452 | − CREATE_NOT_FILE, &data, SMB2_OP_SET_INFO); | |
| 528 | + CREATE_NOT_FILE, &data, SMB2_OP_SET_INFO, | |
| 529 | + cfile); | |
| 453 | 530 | if (tmprc == 0) |
| 454 | 531 | cifs_i->cifsAttrs = dosattrs; |
| 455 | 532 | } |
| @@ -460,7 +537,7 @@ smb2_rmdir(const unsigned int xid, struct cifs_tcon *tcon, const char *name, · 4 unmodified lines | ||
| 460 | 537 | { |
| 461 | 538 | return smb2_compound_op(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN, |
| 462 | 539 | CREATE_NOT_FILE, |
| 463 | − NULL, SMB2_OP_RMDIR); | |
| 540 | + NULL, SMB2_OP_RMDIR, NULL); | |
| 464 | 541 | } |
| 465 | 542 | |
| 466 | 543 | int |
| @@ -469,13 +546,14 @@ smb2_unlink(const unsigned int xid, struct cifs_tcon *tcon, const char *name, · 2 unmodified lines | ||
| 469 | 546 | { |
| 470 | 547 | return smb2_compound_op(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN, |
| 471 | 548 | CREATE_DELETE_ON_CLOSE | OPEN_REPARSE_POINT, |
| 472 | − NULL, SMB2_OP_DELETE); | |
| 549 | + NULL, SMB2_OP_DELETE, NULL); | |
| 473 | 550 | } |
| 474 | 551 | |
| 475 | 552 | static int |
| 476 | 553 | smb2_set_path_attr(const unsigned int xid, struct cifs_tcon *tcon, |
| 477 | 554 | const char *from_name, const char *to_name, |
| 478 | − struct cifs_sb_info *cifs_sb, __u32 access, int command) | |
| 555 | + struct cifs_sb_info *cifs_sb, __u32 access, int command, | |
| 556 | + struct cifsFileInfo *cfile) | |
| 479 | 557 | { |
| 480 | 558 | __le16 *smb2_to_name = NULL; |
| 481 | 559 | int rc; |
| @@ -486,7 +564,7 @@ smb2_set_path_attr(const unsigned int xid, struct cifs_tcon *tcon, · 4 unmodified lines | ||
| 486 | 564 | goto smb2_rename_path; |
| 487 | 565 | } |
| 488 | 566 | rc = smb2_compound_op(xid, tcon, cifs_sb, from_name, access, |
| 489 | − FILE_OPEN, 0, smb2_to_name, command); | |
| 567 | + FILE_OPEN, 0, smb2_to_name, command, cfile); | |
| 490 | 568 | smb2_rename_path: |
| 491 | 569 | kfree(smb2_to_name); |
| 492 | 570 | return rc; |
| @@ -497,8 +575,12 @@ smb2_rename_path(const unsigned int xid, struct cifs_tcon *tcon, · 4 unmodified lines | ||
| 497 | 575 | const char *from_name, const char *to_name, |
| 498 | 576 | struct cifs_sb_info *cifs_sb) |
| 499 | 577 | { |
| 500 | − return smb2_set_path_attr(xid, tcon, from_name, to_name, cifs_sb, | |
| 501 | − DELETE, SMB2_OP_RENAME); | |
| 578 | + struct cifsFileInfo *cfile; | |
| 579 | + | |
| 580 | + cifs_get_writable_path(tcon, from_name, &cfile); | |
| 581 | + | |
| 582 | + return smb2_set_path_attr(xid, tcon, from_name, to_name, | |
| 583 | + cifs_sb, DELETE, SMB2_OP_RENAME, cfile); | |
| 502 | 584 | } |
| 503 | 585 | |
| 504 | 586 | int |
| @@ -507,7 +589,8 @@ smb2_create_hardlink(const unsigned int xid, struct cifs_tcon *tcon, · 2 unmodified lines | ||
| 507 | 589 | struct cifs_sb_info *cifs_sb) |
| 508 | 590 | { |
| 509 | 591 | return smb2_set_path_attr(xid, tcon, from_name, to_name, cifs_sb, |
| 510 | − FILE_READ_ATTRIBUTES, SMB2_OP_HARDLINK); | |
| 592 | + FILE_READ_ATTRIBUTES, SMB2_OP_HARDLINK, | |
| 593 | + NULL); | |
| 511 | 594 | } |
| 512 | 595 | |
| 513 | 596 | int |
| @@ -519,7 +602,7 @@ smb2_set_path_size(const unsigned int xid, struct cifs_tcon *tcon, · 5 unmodified lines | ||
| 519 | 602 | |
| 520 | 603 | return smb2_compound_op(xid, tcon, cifs_sb, full_path, |
| 521 | 604 | FILE_WRITE_DATA, FILE_OPEN, 0, &eof, |
| 522 | − SMB2_OP_SET_EOF); | |
| 605 | + SMB2_OP_SET_EOF, NULL); | |
| 523 | 606 | } |
| 524 | 607 | |
| 525 | 608 | int |
| @@ -541,7 +624,7 @@ smb2_set_file_info(struct inode *inode, const char *full_path, · 15 unmodified lines | ||
| 541 | 624 | |
| 542 | 625 | rc = smb2_compound_op(xid, tlink_tcon(tlink), cifs_sb, full_path, |
| 543 | 626 | FILE_WRITE_ATTRIBUTES, FILE_OPEN, 0, buf, |
| 544 | − SMB2_OP_SET_INFO); | |
| 627 | + SMB2_OP_SET_INFO, NULL); | |
| 545 | 628 | cifs_put_tlink(tlink); |
| 546 | 629 | return rc; |
| 547 | 630 | } |
| @@ -511,7 +511,7 @@ static const struct status_to_posix_error smb2_error_map_table[] = { · 510 unmodified lines | ||
| 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"}, |
| @@ -109,10 +109,10 @@ smb2_add_credits(struct TCP_Server_Info *server, · 108 unmodified lines | ||
| 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,6 +203,8 @@ smb2_wait_mtu_credits(struct TCP_Server_Info *server, unsigned int size, · 84 unmodified lines | ||
| 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 | } |
| @@ -230,7 +232,7 @@ smb2_adjust_credits(struct TCP_Server_Info *server, · 21 unmodified lines | ||
| 230 | 232 | |
| 231 | 233 | if (server->reconnect_instance != credits->instance) { |
| 232 | 234 | spin_unlock(&server->req_lock); |
| 233 | − cifs_dbg(VFS, "trying to return %d credits to old session\n", | |
| 235 | + cifs_server_dbg(VFS, "trying to return %d credits to old session\n", | |
| 234 | 236 | credits->value - new_val); |
| 235 | 237 | return -EAGAIN; |
| 236 | 238 | } |
| @@ -270,7 +272,7 @@ smb2_find_mid(struct TCP_Server_Info *server, char *buf) · 33 unmodified lines | ||
| 270 | 272 | __u64 wire_mid = le64_to_cpu(shdr->MessageId); |
| 271 | 273 | |
| 272 | 274 | if (shdr->ProtocolId == SMB2_TRANSFORM_PROTO_NUM) { |
| 273 | − cifs_dbg(VFS, "Encrypted frame parsing not supported yet\n"); | |
| 275 | + cifs_server_dbg(VFS, "Encrypted frame parsing not supported yet\n"); | |
| 274 | 276 | return NULL; |
| 275 | 277 | } |
| 276 | 278 | |
| @@ -294,10 +296,10 @@ smb2_dump_detail(void *buf, struct TCP_Server_Info *server) · 17 unmodified lines | ||
| 294 | 296 | #ifdef CONFIG_CIFS_DEBUG2 |
| 295 | 297 | struct smb2_sync_hdr *shdr = (struct smb2_sync_hdr *)buf; |
| 296 | 298 | |
| 297 | − cifs_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Mid: %llu Pid: %d\n", | |
| 299 | + cifs_server_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Mid: %llu Pid: %d\n", | |
| 298 | 300 | shdr->Command, shdr->Status, shdr->Flags, shdr->MessageId, |
| 299 | 301 | shdr->ProcessId); |
| 300 | − cifs_dbg(VFS, "smb buf %p len %u\n", buf, | |
| 302 | + cifs_server_dbg(VFS, "smb buf %p len %u\n", buf, | |
| 301 | 303 | server->ops->calc_smb_size(buf, server)); |
| 302 | 304 | #endif |
| 303 | 305 | } |
| @@ -576,7 +578,7 @@ SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon) · 272 unmodified lines | ||
| 576 | 578 | "server does not support query network interfaces\n"); |
| 577 | 579 | goto out; |
| 578 | 580 | } else if (rc != 0) { |
| 579 | − cifs_dbg(VFS, "error %d on ioctl to get interface list\n", rc); | |
| 581 | + cifs_tcon_dbg(VFS, "error %d on ioctl to get interface list\n", rc); | |
| 580 | 582 | goto out; |
| 581 | 583 | } |
| 582 | 584 | |
| @@ -656,6 +658,15 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon, struct cifs_fid *pfid) · 73 unmodified lines | ||
| 656 | 658 | return 0; |
| 657 | 659 | } |
| 658 | 660 | |
| 661 | + /* | |
| 662 | + * We do not hold the lock for the open because in case | |
| 663 | + * SMB2_open needs to reconnect, it will end up calling | |
| 664 | + * cifs_mark_open_files_invalid() which takes the lock again | |
| 665 | + * thus causing a deadlock | |
| 666 | + */ | |
| 667 | + | |
| 668 | + mutex_unlock(&tcon->crfid.fid_mutex); | |
| 669 | + | |
| 659 | 670 | if (smb3_encryption_required(tcon)) |
| 660 | 671 | flags |= CIFS_TRANSFORM_REQ; |
| 661 | 672 | |
| @@ -677,7 +688,7 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon, struct cifs_fid *pfid) · 15 unmodified lines | ||
| 677 | 688 | |
| 678 | 689 | rc = SMB2_open_init(tcon, &rqst[0], &oplock, &oparms, &utf16_path); |
| 679 | 690 | if (rc) |
| 680 | − goto oshr_exit; | |
| 691 | + goto oshr_free; | |
| 681 | 692 | smb2_set_next_command(tcon, &rqst[0]); |
| 682 | 693 | |
| 683 | 694 | memset(&qi_iov, 0, sizeof(qi_iov)); |
| @@ -690,18 +701,10 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon, struct cifs_fid *pfid) · 6 unmodified lines | ||
| 690 | 701 | sizeof(struct smb2_file_all_info) + |
| 691 | 702 | PATH_MAX * 2, 0, NULL); |
| 692 | 703 | if (rc) |
| 693 | − goto oshr_exit; | |
| 704 | + goto oshr_free; | |
| 694 | 705 | |
| 695 | 706 | smb2_set_related(&rqst[1]); |
| 696 | 707 | |
| 697 | − /* | |
| 698 | − * We do not hold the lock for the open because in case | |
| 699 | − * SMB2_open needs to reconnect, it will end up calling | |
| 700 | − * cifs_mark_open_files_invalid() which takes the lock again | |
| 701 | − * thus causing a deadlock | |
| 702 | − */ | |
| 703 | − | |
| 704 | − mutex_unlock(&tcon->crfid.fid_mutex); | |
| 705 | 708 | rc = compound_send_recv(xid, ses, flags, 2, rqst, |
| 706 | 709 | resp_buftype, rsp_iov); |
| 707 | 710 | mutex_lock(&tcon->crfid.fid_mutex); |
| @@ -739,8 +742,14 @@ int open_shroot(unsigned int xid, struct cifs_tcon *tcon, struct cifs_fid *pfid) · 31 unmodified lines | ||
| 739 | 742 | |
| 740 | 743 | /* Cached root is still invalid, continue normaly */ |
| 741 | 744 | |
| 742 | − if (rc) | |
| 745 | + if (rc) { | |
| 746 | + if (rc == -EREMCHG) { | |
| 747 | + tcon->need_reconnect = true; | |
| 748 | + printk_once(KERN_WARNING "server share %s deleted\n", | |
| 749 | + tcon->treeName); | |
| 750 | + } | |
| 743 | 751 | goto oshr_exit; |
| 752 | + } | |
| 744 | 753 | |
| 745 | 754 | o_rsp = (struct smb2_create_rsp *)rsp_iov[0].iov_base; |
| 746 | 755 | oparms.fid->persistent_fid = o_rsp->PersistentFileId; |
| @@ -1330,11 +1339,11 @@ SMB2_request_res_key(const unsigned int xid, struct cifs_tcon *tcon, · 583 unmodified lines | ||
| 1330 | 1339 | (char **)&res_key, &ret_data_len); |
| 1331 | 1340 | |
| 1332 | 1341 | if (rc) { |
| 1333 | − cifs_dbg(VFS, "refcpy ioctl error %d getting resume key\n", rc); | |
| 1342 | + cifs_tcon_dbg(VFS, "refcpy ioctl error %d getting resume key\n", rc); | |
| 1334 | 1343 | goto req_res_key_exit; |
| 1335 | 1344 | } |
| 1336 | 1345 | if (ret_data_len < sizeof(struct resume_key_req)) { |
| 1337 | − cifs_dbg(VFS, "Invalid refcopy resume key length\n"); | |
| 1346 | + cifs_tcon_dbg(VFS, "Invalid refcopy resume key length\n"); | |
| 1338 | 1347 | rc = -EINVAL; |
| 1339 | 1348 | goto req_res_key_exit; |
| 1340 | 1349 | } |
| @@ -1369,7 +1378,10 @@ smb2_ioctl_query_info(const unsigned int xid, · 28 unmodified lines | ||
| 1369 | 1378 | struct cifs_fid fid; |
| 1370 | 1379 | struct kvec qi_iov[1]; |
| 1371 | 1380 | struct kvec io_iov[SMB2_IOCTL_IOV_SIZE]; |
| 1381 | + struct kvec si_iov[SMB2_SET_INFO_IOV_SIZE]; | |
| 1372 | 1382 | struct kvec close_iov[1]; |
| 1383 | + unsigned int size[2]; | |
| 1384 | + void *data[2]; | |
| 1373 | 1385 | |
| 1374 | 1386 | memset(rqst, 0, sizeof(rqst)); |
| 1375 | 1387 | resp_buftype[0] = resp_buftype[1] = resp_buftype[2] = CIFS_NO_BUFFER; |
| @@ -1404,7 +1416,6 @@ smb2_ioctl_query_info(const unsigned int xid, · 28 unmodified lines | ||
| 1404 | 1416 | |
| 1405 | 1417 | memset(&oparms, 0, sizeof(oparms)); |
| 1406 | 1418 | oparms.tcon = tcon; |
| 1407 | − oparms.desired_access = FILE_READ_ATTRIBUTES | READ_CONTROL; | |
| 1408 | 1419 | oparms.disposition = FILE_OPEN; |
| 1409 | 1420 | if (is_dir) |
| 1410 | 1421 | oparms.create_options = CREATE_NOT_FILE; |
| @@ -1413,9 +1424,6 @@ smb2_ioctl_query_info(const unsigned int xid, · 2 unmodified lines | ||
| 1413 | 1424 | oparms.fid = &fid; |
| 1414 | 1425 | oparms.reconnect = false; |
| 1415 | 1426 | |
| 1416 | − /* | |
| 1417 | − * FSCTL codes encode the special access they need in the fsctl code. | |
| 1418 | − */ | |
| 1419 | 1427 | if (qi.flags & PASSTHRU_FSCTL) { |
| 1420 | 1428 | switch (qi.info_type & FSCTL_DEVICE_ACCESS_MASK) { |
| 1421 | 1429 | case FSCTL_DEVICE_ACCESS_FILE_READ_WRITE_ACCESS: |
| @@ -1431,6 +1439,10 @@ smb2_ioctl_query_info(const unsigned int xid, · 9 unmodified lines | ||
| 1431 | 1439 | oparms.desired_access = GENERIC_WRITE; |
| 1432 | 1440 | break; |
| 1433 | 1441 | } |
| 1442 | + } else if (qi.flags & PASSTHRU_SET_INFO) { | |
| 1443 | + oparms.desired_access = GENERIC_WRITE; | |
| 1444 | + } else { | |
| 1445 | + oparms.desired_access = FILE_READ_ATTRIBUTES | READ_CONTROL; | |
| 1434 | 1446 | } |
| 1435 | 1447 | |
| 1436 | 1448 | rc = SMB2_open_init(tcon, &rqst[0], &oplock, &oparms, path); |
| @@ -1454,6 +1466,24 @@ smb2_ioctl_query_info(const unsigned int xid, · 17 unmodified lines | ||
| 1454 | 1466 | qi.output_buffer_length, |
| 1455 | 1467 | CIFSMaxBufSize); |
| 1456 | 1468 | } |
| 1469 | + } else if (qi.flags == PASSTHRU_SET_INFO) { | |
| 1470 | + /* Can eventually relax perm check since server enforces too */ | |
| 1471 | + if (!capable(CAP_SYS_ADMIN)) | |
| 1472 | + rc = -EPERM; | |
| 1473 | + else { | |
| 1474 | + memset(&si_iov, 0, sizeof(si_iov)); | |
| 1475 | + rqst[1].rq_iov = si_iov; | |
| 1476 | + rqst[1].rq_nvec = 1; | |
| 1477 | + | |
| 1478 | + size[0] = 8; | |
| 1479 | + data[0] = buffer; | |
| 1480 | + | |
| 1481 | + rc = SMB2_set_info_init(tcon, &rqst[1], | |
| 1482 | + COMPOUND_FID, COMPOUND_FID, | |
| 1483 | + current->tgid, | |
| 1484 | + FILE_END_OF_FILE_INFORMATION, | |
| 1485 | + SMB2_O_INFO_FILE, 0, data, size); | |
| 1486 | + } | |
| 1457 | 1487 | } else if (qi.flags == PASSTHRU_QUERY_INFO) { |
| 1458 | 1488 | memset(&qi_iov, 0, sizeof(qi_iov)); |
| 1459 | 1489 | rqst[1].rq_iov = qi_iov; |
| @@ -1465,7 +1495,7 @@ smb2_ioctl_query_info(const unsigned int xid, · 5 unmodified lines | ||
| 1465 | 1495 | qi.input_buffer_length, |
| 1466 | 1496 | qi.output_buffer_length, buffer); |
| 1467 | 1497 | } else { /* unknown flags */ |
| 1468 | − cifs_dbg(VFS, "invalid passthru query flags: 0x%x\n", qi.flags); | |
| 1498 | + cifs_tcon_dbg(VFS, "invalid passthru query flags: 0x%x\n", qi.flags); | |
| 1469 | 1499 | rc = -EINVAL; |
| 1470 | 1500 | } |
| 1471 | 1501 | |
| @@ -1592,7 +1622,7 @@ smb2_copychunk_range(const unsigned int xid, · 120 unmodified lines | ||
| 1592 | 1622 | if (rc == 0) { |
| 1593 | 1623 | if (ret_data_len != |
| 1594 | 1624 | sizeof(struct copychunk_ioctl_rsp)) { |
| 1595 | − cifs_dbg(VFS, "invalid cchunk response size\n"); | |
| 1625 | + cifs_tcon_dbg(VFS, "invalid cchunk response size\n"); | |
| 1596 | 1626 | rc = -EIO; |
| 1597 | 1627 | goto cchunk_out; |
| 1598 | 1628 | } |
| @@ -1606,12 +1636,12 @@ smb2_copychunk_range(const unsigned int xid, · 7 unmodified lines | ||
| 1606 | 1636 | */ |
| 1607 | 1637 | if (le32_to_cpu(retbuf->TotalBytesWritten) > |
| 1608 | 1638 | le32_to_cpu(pcchunk->Length)) { |
| 1609 | − cifs_dbg(VFS, "invalid copy chunk response\n"); | |
| 1639 | + cifs_tcon_dbg(VFS, "invalid copy chunk response\n"); | |
| 1610 | 1640 | rc = -EIO; |
| 1611 | 1641 | goto cchunk_out; |
| 1612 | 1642 | } |
| 1613 | 1643 | if (le32_to_cpu(retbuf->ChunksWritten) != 1) { |
| 1614 | − cifs_dbg(VFS, "invalid num chunks written\n"); | |
| 1644 | + cifs_tcon_dbg(VFS, "invalid num chunks written\n"); | |
| 1615 | 1645 | rc = -EIO; |
| 1616 | 1646 | goto cchunk_out; |
| 1617 | 1647 | } |
| @@ -2214,6 +2244,11 @@ smb2_query_info_compound(const unsigned int xid, struct cifs_tcon *tcon, · 596 unmodified lines | ||
| 2214 | 2244 | resp_buftype, rsp_iov); |
| 2215 | 2245 | if (rc) { |
| 2216 | 2246 | free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base); |
| 2247 | + if (rc == -EREMCHG) { | |
| 2248 | + tcon->need_reconnect = true; | |
| 2249 | + printk_once(KERN_WARNING "server share %s deleted\n", | |
| 2250 | + tcon->treeName); | |
| 2251 | + } | |
| 2217 | 2252 | goto qic_exit; |
| 2218 | 2253 | } |
| 2219 | 2254 | *rsp = rsp_iov[1]; |
| @@ -2401,7 +2436,7 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses, · 181 unmodified lines | ||
| 2401 | 2436 | |
| 2402 | 2437 | if (rc) { |
| 2403 | 2438 | if ((rc != -ENOENT) && (rc != -EOPNOTSUPP)) |
| 2404 | − cifs_dbg(VFS, "ioctl error in %s rc=%d\n", __func__, rc); | |
| 2439 | + cifs_tcon_dbg(VFS, "ioctl error in %s rc=%d\n", __func__, rc); | |
| 2405 | 2440 | goto out; |
| 2406 | 2441 | } |
| 2407 | 2442 | |
| @@ -2410,7 +2445,7 @@ smb2_get_dfs_refer(const unsigned int xid, struct cifs_ses *ses, · 2 unmodified lines | ||
| 2410 | 2445 | nls_codepage, remap, search_name, |
| 2411 | 2446 | true /* is_unicode */); |
| 2412 | 2447 | if (rc) { |
| 2413 | − cifs_dbg(VFS, "parse error in %s rc=%d\n", __func__, rc); | |
| 2448 | + cifs_tcon_dbg(VFS, "parse error in %s rc=%d\n", __func__, rc); | |
| 2414 | 2449 | goto out; |
| 2415 | 2450 | } |
| 2416 | 2451 | |
| @@ -2640,7 +2675,7 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon, · 223 unmodified lines | ||
| 2640 | 2675 | |
| 2641 | 2676 | if (plen + le32_to_cpu(ioctl_rsp->OutputOffset) > |
| 2642 | 2677 | rsp_iov[1].iov_len) { |
| 2643 | − cifs_dbg(VFS, "srv returned invalid ioctl len: %d\n", | |
| 2678 | + cifs_tcon_dbg(VFS, "srv returned invalid ioctl len: %d\n", | |
| 2644 | 2679 | plen); |
| 2645 | 2680 | rc = -EIO; |
| 2646 | 2681 | goto querty_exit; |
| @@ -2939,7 +2974,6 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon, · 292 unmodified lines | ||
| 2939 | 2974 | loff_t offset, loff_t len) |
| 2940 | 2975 | { |
| 2941 | 2976 | struct inode *inode; |
| 2942 | − struct cifsInodeInfo *cifsi; | |
| 2943 | 2977 | struct cifsFileInfo *cfile = file->private_data; |
| 2944 | 2978 | struct file_zero_data_information fsctl_buf; |
| 2945 | 2979 | long rc; |
| @@ -2949,7 +2983,6 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon, · 3 unmodified lines | ||
| 2949 | 2983 | xid = get_xid(); |
| 2950 | 2984 | |
| 2951 | 2985 | inode = d_inode(cfile->dentry); |
| 2952 | − cifsi = CIFS_I(inode); | |
| 2953 | 2986 | |
| 2954 | 2987 | /* Need to make file sparse, if not already, before freeing range. */ |
| 2955 | 2988 | /* Consider adding equivalent for compressed since it could also work */ |
| @@ -3595,14 +3628,14 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst, · 639 unmodified lines | ||
| 3595 | 3628 | |
| 3596 | 3629 | rc = smb2_get_enc_key(server, tr_hdr->SessionId, enc, key); |
| 3597 | 3630 | if (rc) { |
| 3598 | − cifs_dbg(VFS, "%s: Could not get %scryption key\n", __func__, | |
| 3631 | + cifs_server_dbg(VFS, "%s: Could not get %scryption key\n", __func__, | |
| 3599 | 3632 | enc ? "en" : "de"); |
| 3600 | 3633 | return 0; |
| 3601 | 3634 | } |
| 3602 | 3635 | |
| 3603 | 3636 | rc = smb3_crypto_aead_allocate(server); |
| 3604 | 3637 | if (rc) { |
| 3605 | − cifs_dbg(VFS, "%s: crypto alloc failed\n", __func__); | |
| 3638 | + cifs_server_dbg(VFS, "%s: crypto alloc failed\n", __func__); | |
| 3606 | 3639 | return rc; |
| 3607 | 3640 | } |
| 3608 | 3641 | |
| @@ -3610,19 +3643,19 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst, · 1 unmodified line | ||
| 3610 | 3643 | server->secmech.ccmaesdecrypt; |
| 3611 | 3644 | rc = crypto_aead_setkey(tfm, key, SMB3_SIGN_KEY_SIZE); |
| 3612 | 3645 | if (rc) { |
| 3613 | − cifs_dbg(VFS, "%s: Failed to set aead key %d\n", __func__, rc); | |
| 3646 | + cifs_server_dbg(VFS, "%s: Failed to set aead key %d\n", __func__, rc); | |
| 3614 | 3647 | return rc; |
| 3615 | 3648 | } |
| 3616 | 3649 | |
| 3617 | 3650 | rc = crypto_aead_setauthsize(tfm, SMB2_SIGNATURE_SIZE); |
| 3618 | 3651 | if (rc) { |
| 3619 | − cifs_dbg(VFS, "%s: Failed to set authsize %d\n", __func__, rc); | |
| 3652 | + cifs_server_dbg(VFS, "%s: Failed to set authsize %d\n", __func__, rc); | |
| 3620 | 3653 | return rc; |
| 3621 | 3654 | } |
| 3622 | 3655 | |
| 3623 | 3656 | req = aead_request_alloc(tfm, GFP_KERNEL); |
| 3624 | 3657 | if (!req) { |
| 3625 | − cifs_dbg(VFS, "%s: Failed to alloc aead request\n", __func__); | |
| 3658 | + cifs_server_dbg(VFS, "%s: Failed to alloc aead request\n", __func__); | |
| 3626 | 3659 | return -ENOMEM; |
| 3627 | 3660 | } |
| 3628 | 3661 | |
| @@ -3633,7 +3666,7 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst, · 4 unmodified lines | ||
| 3633 | 3666 | |
| 3634 | 3667 | sg = init_sg(num_rqst, rqst, sign); |
| 3635 | 3668 | if (!sg) { |
| 3636 | − cifs_dbg(VFS, "%s: Failed to init sg\n", __func__); | |
| 3669 | + cifs_server_dbg(VFS, "%s: Failed to init sg\n", __func__); | |
| 3637 | 3670 | rc = -ENOMEM; |
| 3638 | 3671 | goto free_req; |
| 3639 | 3672 | } |
| @@ -3641,7 +3674,7 @@ crypt_message(struct TCP_Server_Info *server, int num_rqst, · 1 unmodified line | ||
| 3641 | 3674 | iv_len = crypto_aead_ivsize(tfm); |
| 3642 | 3675 | iv = kzalloc(iv_len, GFP_KERNEL); |
| 3643 | 3676 | if (!iv) { |
| 3644 | − cifs_dbg(VFS, "%s: Failed to alloc iv\n", __func__); | |
| 3677 | + cifs_server_dbg(VFS, "%s: Failed to alloc iv\n", __func__); | |
| 3645 | 3678 | rc = -ENOMEM; |
| 3646 | 3679 | goto free_sg; |
| 3647 | 3680 | } |
| @@ -3883,7 +3916,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid, · 235 unmodified lines | ||
| 3883 | 3916 | bool use_rdma_mr = false; |
| 3884 | 3917 | |
| 3885 | 3918 | if (shdr->Command != SMB2_READ) { |
| 3886 | − cifs_dbg(VFS, "only big read responses are supported\n"); | |
| 3919 | + cifs_server_dbg(VFS, "only big read responses are supported\n"); | |
| 3887 | 3920 | return -ENOTSUPP; |
| 3888 | 3921 | } |
| 3889 | 3922 | |
| @@ -3998,8 +4031,55 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid, · 108 unmodified lines | ||
| 3998 | 4031 | return length; |
| 3999 | 4032 | } |
| 4000 | 4033 | |
| 4034 | +struct smb2_decrypt_work { | |
| 4035 | + struct work_struct decrypt; | |
| 4036 | + struct TCP_Server_Info *server; | |
| 4037 | + struct page **ppages; | |
| 4038 | + char *buf; | |
| 4039 | + unsigned int npages; | |
| 4040 | + unsigned int len; | |
| 4041 | +}; | |
| 4042 | + | |
| 4043 | + | |
| 4044 | +static void smb2_decrypt_offload(struct work_struct *work) | |
| 4045 | +{ | |
| 4046 | + struct smb2_decrypt_work *dw = container_of(work, | |
| 4047 | + struct smb2_decrypt_work, decrypt); | |
| 4048 | + int i, rc; | |
| 4049 | + struct mid_q_entry *mid; | |
| 4050 | + | |
| 4051 | + rc = decrypt_raw_data(dw->server, dw->buf, dw->server->vals->read_rsp_size, | |
| 4052 | + dw->ppages, dw->npages, dw->len); | |
| 4053 | + if (rc) { | |
| 4054 | + cifs_dbg(VFS, "error decrypting rc=%d\n", rc); | |
| 4055 | + goto free_pages; | |
| 4056 | + } | |
| 4057 | + | |
| 4058 | + dw->server->lstrp = jiffies; | |
| 4059 | + mid = smb2_find_mid(dw->server, dw->buf); | |
| 4060 | + if (mid == NULL) | |
| 4061 | + cifs_dbg(FYI, "mid not found\n"); | |
| 4062 | + else { | |
| 4063 | + mid->decrypted = true; | |
| 4064 | + rc = handle_read_data(dw->server, mid, dw->buf, | |
| 4065 | + dw->server->vals->read_rsp_size, | |
| 4066 | + dw->ppages, dw->npages, dw->len); | |
| 4067 | + mid->callback(mid); | |
| 4068 | + cifs_mid_q_entry_release(mid); | |
| 4069 | + } | |
| 4070 | + | |
| 4071 | +free_pages: | |
| 4072 | + for (i = dw->npages-1; i >= 0; i--) | |
| 4073 | + put_page(dw->ppages[i]); | |
| 4074 | + | |
| 4075 | + kfree(dw->ppages); | |
| 4076 | + cifs_small_buf_release(dw->buf); | |
| 4077 | +} | |
| 4078 | + | |
| 4079 | + | |
| 4001 | 4080 | static int |
| 4002 | −receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid) | |
| 4081 | +receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid, | |
| 4082 | + int *num_mids) | |
| 4003 | 4083 | { |
| 4004 | 4084 | char *buf = server->smallbuf; |
| 4005 | 4085 | struct smb2_transform_hdr *tr_hdr = (struct smb2_transform_hdr *)buf; |
| @@ -4009,7 +4089,9 @@ receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid) · 3 unmodified lines | ||
| 4009 | 4089 | unsigned int buflen = server->pdu_size; |
| 4010 | 4090 | int rc; |
| 4011 | 4091 | int i = 0; |
| 4092 | + struct smb2_decrypt_work *dw; | |
| 4012 | 4093 | |
| 4094 | + *num_mids = 1; | |
| 4013 | 4095 | len = min_t(unsigned int, buflen, server->vals->read_rsp_size + |
| 4014 | 4096 | sizeof(struct smb2_transform_hdr)) - HEADER_SIZE(server) + 1; |
| 4015 | 4097 | |
| @@ -4045,6 +4127,32 @@ receive_encrypted_read(struct TCP_Server_Info *server, struct mid_q_entry **mid) · 29 unmodified lines | ||
| 4045 | 4127 | if (rc) |
| 4046 | 4128 | goto free_pages; |
| 4047 | 4129 | |
| 4130 | + /* | |
| 4131 | + * For large reads, offload to different thread for better performance, | |
| 4132 | + * use more cores decrypting which can be expensive | |
| 4133 | + */ | |
| 4134 | + | |
| 4135 | + if ((server->min_offload) && (server->in_flight > 1) && | |
| 4136 | + (server->pdu_size >= server->min_offload)) { | |
| 4137 | + dw = kmalloc(sizeof(struct smb2_decrypt_work), GFP_KERNEL); | |
| 4138 | + if (dw == NULL) | |
| 4139 | + goto non_offloaded_decrypt; | |
| 4140 | + | |
| 4141 | + dw->buf = server->smallbuf; | |
| 4142 | + server->smallbuf = (char *)cifs_small_buf_get(); | |
| 4143 | + | |
| 4144 | + INIT_WORK(&dw->decrypt, smb2_decrypt_offload); | |
| 4145 | + | |
| 4146 | + dw->npages = npages; | |
| 4147 | + dw->server = server; | |
| 4148 | + dw->ppages = pages; | |
| 4149 | + dw->len = len; | |
| 4150 | + queue_work(cifsiod_wq, &dw->decrypt); | |
| 4151 | + *num_mids = 0; /* worker thread takes care of finding mid */ | |
| 4152 | + return -1; | |
| 4153 | + } | |
| 4154 | + | |
| 4155 | +non_offloaded_decrypt: | |
| 4048 | 4156 | rc = decrypt_raw_data(server, buf, server->vals->read_rsp_size, |
| 4049 | 4157 | pages, npages, len); |
| 4050 | 4158 | if (rc) |
| @@ -4129,7 +4237,7 @@ one_more: · 78 unmodified lines | ||
| 4129 | 4237 | } |
| 4130 | 4238 | |
| 4131 | 4239 | if (*num_mids >= MAX_COMPOUND) { |
| 4132 | − cifs_dbg(VFS, "too many PDUs in compound\n"); | |
| 4240 | + cifs_server_dbg(VFS, "too many PDUs in compound\n"); | |
| 4133 | 4241 | return -1; |
| 4134 | 4242 | } |
| 4135 | 4243 | bufs[*num_mids] = buf; |
| @@ -4175,7 +4283,7 @@ smb3_receive_transform(struct TCP_Server_Info *server, · 39 unmodified lines | ||
| 4175 | 4283 | |
| 4176 | 4284 | if (pdu_length < sizeof(struct smb2_transform_hdr) + |
| 4177 | 4285 | sizeof(struct smb2_sync_hdr)) { |
| 4178 | − cifs_dbg(VFS, "Transform message is too small (%u)\n", | |
| 4286 | + cifs_server_dbg(VFS, "Transform message is too small (%u)\n", | |
| 4179 | 4287 | pdu_length); |
| 4180 | 4288 | cifs_reconnect(server); |
| 4181 | 4289 | wake_up(&server->response_q); |
| @@ -4183,7 +4291,7 @@ smb3_receive_transform(struct TCP_Server_Info *server, · 1 unmodified line | ||
| 4183 | 4291 | } |
| 4184 | 4292 | |
| 4185 | 4293 | if (pdu_length < orig_len + sizeof(struct smb2_transform_hdr)) { |
| 4186 | − cifs_dbg(VFS, "Transform message is broken\n"); | |
| 4294 | + cifs_server_dbg(VFS, "Transform message is broken\n"); | |
| 4187 | 4295 | cifs_reconnect(server); |
| 4188 | 4296 | wake_up(&server->response_q); |
| 4189 | 4297 | return -ECONNABORTED; |
| @@ -4191,8 +4299,7 @@ smb3_receive_transform(struct TCP_Server_Info *server, · 1 unmodified line | ||
| 4191 | 4299 | |
| 4192 | 4300 | /* TODO: add support for compounds containing READ. */ |
| 4193 | 4301 | if (pdu_length > CIFSMaxBufSize + MAX_HEADER_SIZE(server)) { |
| 4194 | − *num_mids = 1; | |
| 4195 | − return receive_encrypted_read(server, &mids[0]); | |
| 4302 | + return receive_encrypted_read(server, &mids[0], num_mids); | |
| 4196 | 4303 | } |
| 4197 | 4304 | |
| 4198 | 4305 | return receive_encrypted_standard(server, mids, bufs, num_mids); |
| @@ -503,8 +503,7 @@ build_netname_ctxt(struct smb2_netname_neg_context *pneg_ctxt, char *hostname) · 502 unmodified lines | ||
| 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; |
| @@ -543,7 +542,7 @@ assemble_neg_contexts(struct smb2_negotiate_req *req, · 32 unmodified lines | ||
| 543 | 542 | |
| 544 | 543 | if (*total_len > 200) { |
| 545 | 544 | /* In case length corrupted don't want to overrun smb buffer */ |
| 546 | − cifs_dbg(VFS, "Bad frame length assembling neg contexts\n"); | |
| 545 | + cifs_server_dbg(VFS, "Bad frame length assembling neg contexts\n"); | |
| 547 | 546 | return; |
| 548 | 547 | } |
| 549 | 548 | |
| @@ -661,7 +660,7 @@ static int smb311_decode_neg_context(struct smb2_negotiate_rsp *rsp, · 111 unmodified lines | ||
| 661 | 660 | |
| 662 | 661 | cifs_dbg(FYI, "decoding %d negotiate contexts\n", ctxt_cnt); |
| 663 | 662 | if (len_of_smb <= offset) { |
| 664 | − cifs_dbg(VFS, "Invalid response: negotiate context offset\n"); | |
| 663 | + cifs_server_dbg(VFS, "Invalid response: negotiate context offset\n"); | |
| 665 | 664 | return -EINVAL; |
| 666 | 665 | } |
| 667 | 666 | |
| @@ -693,7 +692,7 @@ static int smb311_decode_neg_context(struct smb2_negotiate_rsp *rsp, · 25 unmodified lines | ||
| 693 | 692 | else if (pctx->ContextType == SMB2_POSIX_EXTENSIONS_AVAILABLE) |
| 694 | 693 | server->posix_ext_supported = true; |
| 695 | 694 | else |
| 696 | − cifs_dbg(VFS, "unknown negcontext of type %d ignored\n", | |
| 695 | + cifs_server_dbg(VFS, "unknown negcontext of type %d ignored\n", | |
| 697 | 696 | le16_to_cpu(pctx->ContextType)); |
| 698 | 697 | |
| 699 | 698 | if (rc) |
| @@ -818,7 +817,7 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) · 118 unmodified lines | ||
| 818 | 817 | req->Dialects[1] = cpu_to_le16(SMB302_PROT_ID); |
| 819 | 818 | req->DialectCount = cpu_to_le16(2); |
| 820 | 819 | total_len += 4; |
| 821 | − } else if (strcmp(ses->server->vals->version_string, | |
| 820 | + } else if (strcmp(server->vals->version_string, | |
| 822 | 821 | SMBDEFAULT_VERSION_STRING) == 0) { |
| 823 | 822 | req->Dialects[0] = cpu_to_le16(SMB21_PROT_ID); |
| 824 | 823 | req->Dialects[1] = cpu_to_le16(SMB30_PROT_ID); |
| @@ -841,16 +840,16 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) · 16 unmodified lines | ||
| 841 | 840 | else |
| 842 | 841 | req->SecurityMode = 0; |
| 843 | 842 | |
| 844 | − req->Capabilities = cpu_to_le32(ses->server->vals->req_capabilities); | |
| 843 | + req->Capabilities = cpu_to_le32(server->vals->req_capabilities); | |
| 845 | 844 | |
| 846 | 845 | /* ClientGUID must be zero for SMB2.02 dialect */ |
| 847 | − if (ses->server->vals->protocol_id == SMB20_PROT_ID) | |
| 846 | + if (server->vals->protocol_id == SMB20_PROT_ID) | |
| 848 | 847 | memset(req->ClientGUID, 0, SMB2_CLIENT_GUID_SIZE); |
| 849 | 848 | else { |
| 850 | 849 | memcpy(req->ClientGUID, server->client_guid, |
| 851 | 850 | SMB2_CLIENT_GUID_SIZE); |
| 852 | − if ((ses->server->vals->protocol_id == SMB311_PROT_ID) || | |
| 853 | − (strcmp(ses->server->vals->version_string, | |
| 851 | + if ((server->vals->protocol_id == SMB311_PROT_ID) || | |
| 852 | + (strcmp(server->vals->version_string, | |
| 854 | 853 | SMBDEFAULT_VERSION_STRING) == 0)) |
| 855 | 854 | assemble_neg_contexts(req, server, &total_len); |
| 856 | 855 | } |
| @@ -869,42 +868,42 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) · 12 unmodified lines | ||
| 869 | 868 | * cifs_stats_inc(&tcon->stats.smb2_stats.smb2_com_fail[SMB2...]); |
| 870 | 869 | */ |
| 871 | 870 | if (rc == -EOPNOTSUPP) { |
| 872 | − cifs_dbg(VFS, "Dialect not supported by server. Consider " | |
| 871 | + cifs_server_dbg(VFS, "Dialect not supported by server. Consider " | |
| 873 | 872 | "specifying vers=1.0 or vers=2.0 on mount for accessing" |
| 874 | 873 | " older servers\n"); |
| 875 | 874 | goto neg_exit; |
| 876 | 875 | } else if (rc != 0) |
| 877 | 876 | goto neg_exit; |
| 878 | 877 | |
| 879 | − if (strcmp(ses->server->vals->version_string, | |
| 878 | + if (strcmp(server->vals->version_string, | |
| 880 | 879 | SMB3ANY_VERSION_STRING) == 0) { |
| 881 | 880 | if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID)) { |
| 882 | − cifs_dbg(VFS, | |
| 881 | + cifs_server_dbg(VFS, | |
| 883 | 882 | "SMB2 dialect returned but not requested\n"); |
| 884 | 883 | return -EIO; |
| 885 | 884 | } else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) { |
| 886 | − cifs_dbg(VFS, | |
| 885 | + cifs_server_dbg(VFS, | |
| 887 | 886 | "SMB2.1 dialect returned but not requested\n"); |
| 888 | 887 | return -EIO; |
| 889 | 888 | } |
| 890 | − } else if (strcmp(ses->server->vals->version_string, | |
| 889 | + } else if (strcmp(server->vals->version_string, | |
| 891 | 890 | SMBDEFAULT_VERSION_STRING) == 0) { |
| 892 | 891 | if (rsp->DialectRevision == cpu_to_le16(SMB20_PROT_ID)) { |
| 893 | − cifs_dbg(VFS, | |
| 892 | + cifs_server_dbg(VFS, | |
| 894 | 893 | "SMB2 dialect returned but not requested\n"); |
| 895 | 894 | return -EIO; |
| 896 | 895 | } else if (rsp->DialectRevision == cpu_to_le16(SMB21_PROT_ID)) { |
| 897 | 896 | /* ops set to 3.0 by default for default so update */ |
| 898 | − ses->server->ops = &smb21_operations; | |
| 899 | − ses->server->vals = &smb21_values; | |
| 897 | + server->ops = &smb21_operations; | |
| 898 | + server->vals = &smb21_values; | |
| 900 | 899 | } else if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID)) { |
| 901 | − ses->server->ops = &smb311_operations; | |
| 902 | − ses->server->vals = &smb311_values; | |
| 900 | + server->ops = &smb311_operations; | |
| 901 | + server->vals = &smb311_values; | |
| 903 | 902 | } |
| 904 | 903 | } else if (le16_to_cpu(rsp->DialectRevision) != |
| 905 | − ses->server->vals->protocol_id) { | |
| 904 | + server->vals->protocol_id) { | |
| 906 | 905 | /* if requested single dialect ensure returned dialect matched */ |
| 907 | − cifs_dbg(VFS, "Illegal 0x%x dialect returned: not requested\n", | |
| 906 | + cifs_server_dbg(VFS, "Illegal 0x%x dialect returned: not requested\n", | |
| 908 | 907 | le16_to_cpu(rsp->DialectRevision)); |
| 909 | 908 | return -EIO; |
| 910 | 909 | } |
| @@ -922,7 +921,7 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) · 11 unmodified lines | ||
| 922 | 921 | else if (rsp->DialectRevision == cpu_to_le16(SMB311_PROT_ID)) |
| 923 | 922 | cifs_dbg(FYI, "negotiated smb3.1.1 dialect\n"); |
| 924 | 923 | else { |
| 925 | − cifs_dbg(VFS, "Illegal dialect returned by server 0x%x\n", | |
| 924 | + cifs_server_dbg(VFS, "Illegal dialect returned by server 0x%x\n", | |
| 926 | 925 | le16_to_cpu(rsp->DialectRevision)); |
| 927 | 926 | rc = -EIO; |
| 928 | 927 | goto neg_exit; |
| @@ -982,7 +981,7 @@ SMB2_negotiate(const unsigned int xid, struct cifs_ses *ses) · 53 unmodified lines | ||
| 982 | 981 | rc = smb311_decode_neg_context(rsp, server, |
| 983 | 982 | rsp_iov.iov_len); |
| 984 | 983 | else |
| 985 | − cifs_dbg(VFS, "Missing expected negotiate contexts\n"); | |
| 984 | + cifs_server_dbg(VFS, "Missing expected negotiate contexts\n"); | |
| 986 | 985 | } |
| 987 | 986 | neg_exit: |
| 988 | 987 | free_rsp_buf(resp_buftype, rsp); |
| @@ -996,11 +995,12 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon) · 7 unmodified lines | ||
| 996 | 995 | struct validate_negotiate_info_rsp *pneg_rsp = NULL; |
| 997 | 996 | u32 rsplen; |
| 998 | 997 | u32 inbuflen; /* max of 4 dialects */ |
| 998 | + struct TCP_Server_Info *server = tcon->ses->server; | |
| 999 | 999 | |
| 1000 | 1000 | cifs_dbg(FYI, "validate negotiate\n"); |
| 1001 | 1001 | |
| 1002 | 1002 | /* In SMB3.11 preauth integrity supersedes validate negotiate */ |
| 1003 | − if (tcon->ses->server->dialect == SMB311_PROT_ID) | |
| 1003 | + if (server->dialect == SMB311_PROT_ID) | |
| 1004 | 1004 | return 0; |
| 1005 | 1005 | |
| 1006 | 1006 | /* |
| @@ -1019,15 +1019,15 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon) · 12 unmodified lines | ||
| 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,7 +1040,7 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon) · 6 unmodified lines | ||
| 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,7 +1048,7 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon) · 1 unmodified line | ||
| 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,7 +1060,7 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon) · 5 unmodified lines | ||
| 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,18 +1076,18 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon) · 9 unmodified lines | ||
| 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,16 +1096,16 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon) · 2 unmodified lines | ||
| 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,7 +1114,7 @@ int smb3_validate_negotiate(const unsigned int xid, struct cifs_tcon *tcon) · 2 unmodified lines | ||
| 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,7 +1568,7 @@ SMB2_sess_setup(const unsigned int xid, struct cifs_ses *ses, · 447 unmodified lines | ||
| 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,10 +1661,11 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree, · 86 unmodified lines | ||
| 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); |
| @@ -1707,7 +1708,7 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree, · 36 unmodified lines | ||
| 1707 | 1708 | * unless it is guest or anonymous user. See MS-SMB2 3.2.5.3.1 |
| 1708 | 1709 | * (Samba servers don't always set the flag so also check if null user) |
| 1709 | 1710 | */ |
| 1710 | − if ((ses->server->dialect == SMB311_PROT_ID) && | |
| 1711 | + if ((server->dialect == SMB311_PROT_ID) && | |
| 1711 | 1712 | !smb3_encryption_required(tcon) && |
| 1712 | 1713 | !(ses->session_flags & |
| 1713 | 1714 | (SMB2_SESSION_FLAG_IS_GUEST|SMB2_SESSION_FLAG_IS_NULL)) && |
| @@ -1746,7 +1747,7 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree, · 32 unmodified lines | ||
| 1746 | 1747 | cifs_dbg(FYI, "connection to printer\n"); |
| 1747 | 1748 | break; |
| 1748 | 1749 | default: |
| 1749 | − cifs_dbg(VFS, "unknown share type %d\n", rsp->ShareType); | |
| 1750 | + cifs_server_dbg(VFS, "unknown share type %d\n", rsp->ShareType); | |
| 1750 | 1751 | rc = -EOPNOTSUPP; |
| 1751 | 1752 | goto tcon_error_exit; |
| 1752 | 1753 | } |
| @@ -1761,15 +1762,15 @@ SMB2_tcon(const unsigned int xid, struct cifs_ses *ses, const char *tree, · 8 unmodified lines | ||
| 1761 | 1762 | |
| 1762 | 1763 | if ((rsp->Capabilities & SMB2_SHARE_CAP_DFS) && |
| 1763 | 1764 | ((tcon->share_flags & SHI1005_FLAGS_DFS) == 0)) |
| 1764 | − cifs_dbg(VFS, "DFS capability contradicts DFS flag\n"); | |
| 1765 | + cifs_tcon_dbg(VFS, "DFS capability contradicts DFS flag\n"); | |
| 1765 | 1766 | |
| 1766 | 1767 | if (tcon->seal && |
| 1767 | − !(tcon->ses->server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION)) | |
| 1768 | − cifs_dbg(VFS, "Encryption is requested but not supported\n"); | |
| 1768 | + !(server->capabilities & SMB2_GLOBAL_CAP_ENCRYPTION)) | |
| 1769 | + cifs_tcon_dbg(VFS, "Encryption is requested but not supported\n"); | |
| 1769 | 1770 | |
| 1770 | 1771 | init_copy_chunk_defaults(tcon); |
| 1771 | − if (tcon->ses->server->ops->validate_negotiate) | |
| 1772 | − rc = tcon->ses->server->ops->validate_negotiate(xid, tcon); | |
| 1772 | + if (server->ops->validate_negotiate) | |
| 1773 | + rc = server->ops->validate_negotiate(xid, tcon); | |
| 1773 | 1774 | tcon_exit: |
| 1774 | 1775 | |
| 1775 | 1776 | free_rsp_buf(resp_buftype, rsp); |
| @@ -1778,7 +1779,7 @@ tcon_exit: · 2 unmodified lines | ||
| 1778 | 1779 | |
| 1779 | 1780 | tcon_error_exit: |
| 1780 | 1781 | if (rsp && rsp->sync_hdr.Status == STATUS_BAD_NETWORK_NAME) { |
| 1781 | − cifs_dbg(VFS, "BAD_NETWORK_NAME: %s\n", tree); | |
| 1782 | + cifs_tcon_dbg(VFS, "BAD_NETWORK_NAME: %s\n", tree); | |
| 1782 | 1783 | } |
| 1783 | 1784 | goto tcon_exit; |
| 1784 | 1785 | } |
| @@ -2458,7 +2459,7 @@ SMB2_open_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, __u8 *oplock, · 673 unmodified lines | ||
| 2458 | 2459 | iov[1].iov_len = uni_path_len; |
| 2459 | 2460 | iov[1].iov_base = path; |
| 2460 | 2461 | |
| 2461 | − if (!server->oplocks) | |
| 2462 | + if ((!server->oplocks) || (tcon->no_lease)) | |
| 2462 | 2463 | *oplock = SMB2_OPLOCK_LEVEL_NONE; |
| 2463 | 2464 | |
| 2464 | 2465 | if (!(server->capabilities & SMB2_GLOBAL_CAP_LEASING) || |
| @@ -2594,6 +2595,11 @@ SMB2_open(const unsigned int xid, struct cifs_open_parms *oparms, __le16 *path, · 129 unmodified lines | ||
| 2594 | 2595 | } |
| 2595 | 2596 | trace_smb3_open_err(xid, tcon->tid, ses->Suid, |
| 2596 | 2597 | oparms->create_options, oparms->desired_access, rc); |
| 2598 | + if (rc == -EREMCHG) { | |
| 2599 | + printk_once(KERN_WARNING "server share %s deleted\n", | |
| 2600 | + tcon->treeName); | |
| 2601 | + tcon->need_reconnect = true; | |
| 2602 | + } | |
| 2597 | 2603 | goto creat_exit; |
| 2598 | 2604 | } else |
| 2599 | 2605 | trace_smb3_open_done(xid, rsp->PersistentFileId, tcon->tid, |
| @@ -2742,6 +2748,7 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, · 142 unmodified lines | ||
| 2742 | 2748 | int resp_buftype = CIFS_NO_BUFFER; |
| 2743 | 2749 | int rc = 0; |
| 2744 | 2750 | int flags = 0; |
| 2751 | + struct TCP_Server_Info *server; | |
| 2745 | 2752 | |
| 2746 | 2753 | cifs_dbg(FYI, "SMB2 IOCTL\n"); |
| 2747 | 2754 | |
| @@ -2757,7 +2764,10 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, · 9 unmodified lines | ||
| 2757 | 2764 | else |
| 2758 | 2765 | return -EIO; |
| 2759 | 2766 | |
| 2760 | − if (!ses || !(ses->server)) | |
| 2767 | + if (!ses) | |
| 2768 | + return -EIO; | |
| 2769 | + server = ses->server; | |
| 2770 | + if (!server) | |
| 2761 | 2771 | return -EIO; |
| 2762 | 2772 | |
| 2763 | 2773 | if (smb3_encryption_required(tcon)) |
| @@ -2807,14 +2817,14 @@ SMB2_ioctl(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, · 43 unmodified lines | ||
| 2807 | 2817 | if (*plen == 0) |
| 2808 | 2818 | goto ioctl_exit; /* server returned no data */ |
| 2809 | 2819 | else if (*plen > rsp_iov.iov_len || *plen > 0xFF00) { |
| 2810 | − cifs_dbg(VFS, "srv returned invalid ioctl length: %d\n", *plen); | |
| 2820 | + cifs_tcon_dbg(VFS, "srv returned invalid ioctl length: %d\n", *plen); | |
| 2811 | 2821 | *plen = 0; |
| 2812 | 2822 | rc = -EIO; |
| 2813 | 2823 | goto ioctl_exit; |
| 2814 | 2824 | } |
| 2815 | 2825 | |
| 2816 | 2826 | if (rsp_iov.iov_len - *plen < le32_to_cpu(rsp->OutputOffset)) { |
| 2817 | − cifs_dbg(VFS, "Malformed ioctl resp: len %d offset %d\n", *plen, | |
| 2827 | + cifs_tcon_dbg(VFS, "Malformed ioctl resp: len %d offset %d\n", *plen, | |
| 2818 | 2828 | le32_to_cpu(rsp->OutputOffset)); |
| 2819 | 2829 | *plen = 0; |
| 2820 | 2830 | rc = -EIO; |
| @@ -2913,6 +2923,7 @@ SMB2_close_flags(const unsigned int xid, struct cifs_tcon *tcon, · 92 unmodified lines | ||
| 2913 | 2923 | rqst.rq_iov = iov; |
| 2914 | 2924 | rqst.rq_nvec = 1; |
| 2915 | 2925 | |
| 2926 | + trace_smb3_close_enter(xid, persistent_fid, tcon->tid, ses->Suid); | |
| 2916 | 2927 | rc = SMB2_close_init(tcon, &rqst, persistent_fid, volatile_fid); |
| 2917 | 2928 | if (rc) |
| 2918 | 2929 | goto close_exit; |
| @@ -2925,7 +2936,9 @@ SMB2_close_flags(const unsigned int xid, struct cifs_tcon *tcon, · 6 unmodified lines | ||
| 2925 | 2936 | trace_smb3_close_err(xid, persistent_fid, tcon->tid, ses->Suid, |
| 2926 | 2937 | rc); |
| 2927 | 2938 | goto close_exit; |
| 2928 | − } | |
| 2939 | + } else | |
| 2940 | + trace_smb3_close_done(xid, persistent_fid, tcon->tid, | |
| 2941 | + ses->Suid); | |
| 2929 | 2942 | |
| 2930 | 2943 | atomic_dec(&tcon->num_remote_opens); |
| 2931 | 2944 | |
| @@ -3055,12 +3068,16 @@ query_info(const unsigned int xid, struct cifs_tcon *tcon, · 123 unmodified lines | ||
| 3055 | 3068 | int rc = 0; |
| 3056 | 3069 | int resp_buftype = CIFS_NO_BUFFER; |
| 3057 | 3070 | struct cifs_ses *ses = tcon->ses; |
| 3071 | + struct TCP_Server_Info *server; | |
| 3058 | 3072 | int flags = 0; |
| 3059 | 3073 | bool allocated = false; |
| 3060 | 3074 | |
| 3061 | 3075 | cifs_dbg(FYI, "Query Info\n"); |
| 3062 | 3076 | |
| 3063 | − if (!ses || !(ses->server)) | |
| 3077 | + if (!ses) | |
| 3078 | + return -EIO; | |
| 3079 | + server = ses->server; | |
| 3080 | + if (!server) | |
| 3064 | 3081 | return -EIO; |
| 3065 | 3082 | |
| 3066 | 3083 | if (smb3_encryption_required(tcon)) |
| @@ -3098,7 +3115,7 @@ query_info(const unsigned int xid, struct cifs_tcon *tcon, · 31 unmodified lines | ||
| 3098 | 3115 | if (!*data) { |
| 3099 | 3116 | *data = kmalloc(*dlen, GFP_KERNEL); |
| 3100 | 3117 | if (!*data) { |
| 3101 | − cifs_dbg(VFS, | |
| 3118 | + cifs_tcon_dbg(VFS, | |
| 3102 | 3119 | "Error %d allocating memory for acl\n", |
| 3103 | 3120 | rc); |
| 3104 | 3121 | *dlen = 0; |
| @@ -3158,6 +3175,91 @@ SMB2_get_srv_num(const unsigned int xid, struct cifs_tcon *tcon, · 53 unmodified lines | ||
| 3158 | 3175 | (void **)&uniqueid, NULL); |
| 3159 | 3176 | } |
| 3160 | 3177 | |
| 3178 | +/* | |
| 3179 | + * CHANGE_NOTIFY Request is sent to get notifications on changes to a directory | |
| 3180 | + * See MS-SMB2 2.2.35 and 2.2.36 | |
| 3181 | + */ | |
| 3182 | + | |
| 3183 | +int | |
| 3184 | +SMB2_notify_init(const unsigned int xid, struct smb_rqst *rqst, | |
| 3185 | + struct cifs_tcon *tcon, u64 persistent_fid, u64 volatile_fid, | |
| 3186 | + u32 completion_filter, bool watch_tree) | |
| 3187 | +{ | |
| 3188 | + struct smb2_change_notify_req *req; | |
| 3189 | + struct kvec *iov = rqst->rq_iov; | |
| 3190 | + unsigned int total_len; | |
| 3191 | + int rc; | |
| 3192 | + | |
| 3193 | + rc = smb2_plain_req_init(SMB2_CHANGE_NOTIFY, tcon, (void **) &req, &total_len); | |
| 3194 | + if (rc) | |
| 3195 | + return rc; | |
| 3196 | + | |
| 3197 | + req->PersistentFileId = persistent_fid; | |
| 3198 | + req->VolatileFileId = volatile_fid; | |
| 3199 | + req->OutputBufferLength = SMB2_MAX_BUFFER_SIZE - MAX_SMB2_HDR_SIZE; | |
| 3200 | + req->CompletionFilter = cpu_to_le32(completion_filter); | |
| 3201 | + if (watch_tree) | |
| 3202 | + req->Flags = cpu_to_le16(SMB2_WATCH_TREE); | |
| 3203 | + else | |
| 3204 | + req->Flags = 0; | |
| 3205 | + | |
| 3206 | + iov[0].iov_base = (char *)req; | |
| 3207 | + iov[0].iov_len = total_len; | |
| 3208 | + | |
| 3209 | + return 0; | |
| 3210 | +} | |
| 3211 | + | |
| 3212 | +int | |
| 3213 | +SMB2_change_notify(const unsigned int xid, struct cifs_tcon *tcon, | |
| 3214 | + u64 persistent_fid, u64 volatile_fid, bool watch_tree, | |
| 3215 | + u32 completion_filter) | |
| 3216 | +{ | |
| 3217 | + struct cifs_ses *ses = tcon->ses; | |
| 3218 | + struct smb_rqst rqst; | |
| 3219 | + struct kvec iov[1]; | |
| 3220 | + struct kvec rsp_iov = {NULL, 0}; | |
| 3221 | + int resp_buftype = CIFS_NO_BUFFER; | |
| 3222 | + int flags = 0; | |
| 3223 | + int rc = 0; | |
| 3224 | + | |
| 3225 | + cifs_dbg(FYI, "change notify\n"); | |
| 3226 | + if (!ses || !(ses->server)) | |
| 3227 | + return -EIO; | |
| 3228 | + | |
| 3229 | + if (smb3_encryption_required(tcon)) | |
| 3230 | + flags |= CIFS_TRANSFORM_REQ; | |
| 3231 | + | |
| 3232 | + memset(&rqst, 0, sizeof(struct smb_rqst)); | |
| 3233 | + memset(&iov, 0, sizeof(iov)); | |
| 3234 | + rqst.rq_iov = iov; | |
| 3235 | + rqst.rq_nvec = 1; | |
| 3236 | + | |
| 3237 | + rc = SMB2_notify_init(xid, &rqst, tcon, persistent_fid, volatile_fid, | |
| 3238 | + completion_filter, watch_tree); | |
| 3239 | + if (rc) | |
| 3240 | + goto cnotify_exit; | |
| 3241 | + | |
| 3242 | + trace_smb3_notify_enter(xid, persistent_fid, tcon->tid, ses->Suid, | |
| 3243 | + (u8)watch_tree, completion_filter); | |
| 3244 | + rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov); | |
| 3245 | + | |
| 3246 | + if (rc != 0) { | |
| 3247 | + cifs_stats_fail_inc(tcon, SMB2_CHANGE_NOTIFY_HE); | |
| 3248 | + trace_smb3_notify_err(xid, persistent_fid, tcon->tid, ses->Suid, | |
| 3249 | + (u8)watch_tree, completion_filter, rc); | |
| 3250 | + } else | |
| 3251 | + trace_smb3_notify_done(xid, persistent_fid, tcon->tid, | |
| 3252 | + ses->Suid, (u8)watch_tree, completion_filter); | |
| 3253 | + | |
| 3254 | + cnotify_exit: | |
| 3255 | + if (rqst.rq_iov) | |
| 3256 | + cifs_small_buf_release(rqst.rq_iov[0].iov_base); /* request */ | |
| 3257 | + free_rsp_buf(resp_buftype, rsp_iov.iov_base); | |
| 3258 | + return rc; | |
| 3259 | +} | |
| 3260 | + | |
| 3261 | + | |
| 3262 | + | |
| 3161 | 3263 | /* |
| 3162 | 3264 | * This is a no-op for now. We're not really interested in the reply, but |
| 3163 | 3265 | * rather in the fact that the server sent one and that server->lstrp |
| @@ -3287,51 +3389,76 @@ SMB2_echo(struct TCP_Server_Info *server) · 123 unmodified lines | ||
| 3287 | 3389 | return rc; |
| 3288 | 3390 | } |
| 3289 | 3391 | |
| 3392 | +void | |
| 3393 | +SMB2_flush_free(struct smb_rqst *rqst) | |
| 3394 | +{ | |
| 3395 | + if (rqst && rqst->rq_iov) | |
| 3396 | + cifs_small_buf_release(rqst->rq_iov[0].iov_base); /* request */ | |
| 3397 | +} | |
| 3398 | + | |
| 3290 | 3399 | int |
| 3291 | −SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, | |
| 3292 | − u64 volatile_fid) | |
| 3400 | +SMB2_flush_init(const unsigned int xid, struct smb_rqst *rqst, | |
| 3401 | + struct cifs_tcon *tcon, u64 persistent_fid, u64 volatile_fid) | |
| 3293 | 3402 | { |
| 3294 | − struct smb_rqst rqst; | |
| 3295 | 3403 | struct smb2_flush_req *req; |
| 3296 | − struct cifs_ses *ses = tcon->ses; | |
| 3297 | − struct kvec iov[1]; | |
| 3298 | − struct kvec rsp_iov; | |
| 3299 | − int resp_buftype; | |
| 3300 | − int rc = 0; | |
| 3301 | − int flags = 0; | |
| 3404 | + struct kvec *iov = rqst->rq_iov; | |
| 3302 | 3405 | unsigned int total_len; |
| 3303 | − | |
| 3304 | − cifs_dbg(FYI, "Flush\n"); | |
| 3305 | − | |
| 3306 | − if (!ses || !(ses->server)) | |
| 3307 | − return -EIO; | |
| 3406 | + int rc; | |
| 3308 | 3407 | |
| 3309 | 3408 | rc = smb2_plain_req_init(SMB2_FLUSH, tcon, (void **) &req, &total_len); |
| 3310 | 3409 | if (rc) |
| 3311 | 3410 | return rc; |
| 3312 | 3411 | |
| 3313 | − if (smb3_encryption_required(tcon)) | |
| 3314 | − flags |= CIFS_TRANSFORM_REQ; | |
| 3315 | − | |
| 3316 | 3412 | req->PersistentFileId = persistent_fid; |
| 3317 | 3413 | req->VolatileFileId = volatile_fid; |
| 3318 | 3414 | |
| 3319 | 3415 | iov[0].iov_base = (char *)req; |
| 3320 | 3416 | iov[0].iov_len = total_len; |
| 3321 | 3417 | |
| 3418 | + return 0; | |
| 3419 | +} | |
| 3420 | + | |
| 3421 | +int | |
| 3422 | +SMB2_flush(const unsigned int xid, struct cifs_tcon *tcon, u64 persistent_fid, | |
| 3423 | + u64 volatile_fid) | |
| 3424 | +{ | |
| 3425 | + struct cifs_ses *ses = tcon->ses; | |
| 3426 | + struct smb_rqst rqst; | |
| 3427 | + struct kvec iov[1]; | |
| 3428 | + struct kvec rsp_iov = {NULL, 0}; | |
| 3429 | + int resp_buftype = CIFS_NO_BUFFER; | |
| 3430 | + int flags = 0; | |
| 3431 | + int rc = 0; | |
| 3432 | + | |
| 3433 | + cifs_dbg(FYI, "flush\n"); | |
| 3434 | + if (!ses || !(ses->server)) | |
| 3435 | + return -EIO; | |
| 3436 | + | |
| 3437 | + if (smb3_encryption_required(tcon)) | |
| 3438 | + flags |= CIFS_TRANSFORM_REQ; | |
| 3439 | + | |
| 3322 | 3440 | memset(&rqst, 0, sizeof(struct smb_rqst)); |
| 3441 | + memset(&iov, 0, sizeof(iov)); | |
| 3323 | 3442 | rqst.rq_iov = iov; |
| 3324 | 3443 | rqst.rq_nvec = 1; |
| 3325 | 3444 | |
| 3445 | + rc = SMB2_flush_init(xid, &rqst, tcon, persistent_fid, volatile_fid); | |
| 3446 | + if (rc) | |
| 3447 | + goto flush_exit; | |
| 3448 | + | |
| 3449 | + trace_smb3_flush_enter(xid, persistent_fid, tcon->tid, ses->Suid); | |
| 3326 | 3450 | rc = cifs_send_recv(xid, ses, &rqst, &resp_buftype, flags, &rsp_iov); |
| 3327 | − cifs_small_buf_release(req); | |
| 3328 | 3451 | |
| 3329 | 3452 | if (rc != 0) { |
| 3330 | 3453 | cifs_stats_fail_inc(tcon, SMB2_FLUSH_HE); |
| 3331 | 3454 | trace_smb3_flush_err(xid, persistent_fid, tcon->tid, ses->Suid, |
| 3332 | 3455 | rc); |
| 3333 | − } | |
| 3456 | + } else | |
| 3457 | + trace_smb3_flush_done(xid, persistent_fid, tcon->tid, | |
| 3458 | + ses->Suid); | |
| 3334 | 3459 | |
| 3460 | + flush_exit: | |
| 3461 | + SMB2_flush_free(&rqst); | |
| 3335 | 3462 | free_rsp_buf(resp_buftype, rsp_iov.iov_base); |
| 3336 | 3463 | return rc; |
| 3337 | 3464 | } |
| @@ -3446,8 +3573,8 @@ smb2_readv_callback(struct mid_q_entry *mid) · 108 unmodified lines | ||
| 3446 | 3573 | struct smb2_sync_hdr *shdr = |
| 3447 | 3574 | (struct smb2_sync_hdr *)rdata->iov[0].iov_base; |
| 3448 | 3575 | struct cifs_credits credits = { .value = 0, .instance = 0 }; |
| 3449 | − struct smb_rqst rqst = { .rq_iov = rdata->iov, | |
| 3450 | − .rq_nvec = 2, | |
| 3576 | + struct smb_rqst rqst = { .rq_iov = &rdata->iov[1], | |
| 3577 | + .rq_nvec = 1, | |
| 3451 | 3578 | .rq_pages = rdata->pages, |
| 3452 | 3579 | .rq_offset = rdata->page_offset, |
| 3453 | 3580 | .rq_npages = rdata->nr_pages, |
| @@ -3468,7 +3595,7 @@ smb2_readv_callback(struct mid_q_entry *mid) · 14 unmodified lines | ||
| 3468 | 3595 | |
| 3469 | 3596 | rc = smb2_verify_signature(&rqst, server); |
| 3470 | 3597 | if (rc) |
| 3471 | − cifs_dbg(VFS, "SMB signature verification returned error = %d\n", | |
| 3598 | + cifs_tcon_dbg(VFS, "SMB signature verification returned error = %d\n", | |
| 3472 | 3599 | rc); |
| 3473 | 3600 | } |
| 3474 | 3601 | /* FIXME: should this be counted toward the initiating task? */ |
| @@ -3595,7 +3722,7 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms, · 120 unmodified lines | ||
| 3595 | 3722 | unsigned int *nbytes, char **buf, int *buf_type) |
| 3596 | 3723 | { |
| 3597 | 3724 | struct smb_rqst rqst; |
| 3598 | − int resp_buftype, rc = -EACCES; | |
| 3725 | + int resp_buftype, rc; | |
| 3599 | 3726 | struct smb2_read_plain_req *req = NULL; |
| 3600 | 3727 | struct smb2_read_rsp *rsp = NULL; |
| 3601 | 3728 | struct kvec iov[1]; |
| @@ -4058,7 +4185,7 @@ SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon, · 456 unmodified lines | ||
| 4058 | 4185 | info_buf_size = sizeof(SEARCH_ID_FULL_DIR_INFO) - 1; |
| 4059 | 4186 | break; |
| 4060 | 4187 | default: |
| 4061 | − cifs_dbg(VFS, "info level %u isn't supported\n", | |
| 4188 | + cifs_tcon_dbg(VFS, "info level %u isn't supported\n", | |
| 4062 | 4189 | srch_inf->info_level); |
| 4063 | 4190 | rc = -EINVAL; |
| 4064 | 4191 | goto qdir_exit; |
| @@ -4149,7 +4276,7 @@ SMB2_query_directory(const unsigned int xid, struct cifs_tcon *tcon, · 84 unmodified lines | ||
| 4149 | 4276 | else if (resp_buftype == CIFS_SMALL_BUFFER) |
| 4150 | 4277 | srch_inf->smallBuf = true; |
| 4151 | 4278 | else |
| 4152 | − cifs_dbg(VFS, "illegal search buffer type\n"); | |
| 4279 | + cifs_tcon_dbg(VFS, "illegal search buffer type\n"); | |
| 4153 | 4280 | |
| 4154 | 4281 | trace_smb3_query_dir_done(xid, persistent_fid, tcon->tid, |
| 4155 | 4282 | tcon->ses->Suid, index, srch_inf->entries_in_buffer); |
| @@ -143,7 +143,9 @@ struct smb2_transform_hdr { · 142 unmodified lines | ||
| 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) |
| @@ -158,6 +158,10 @@ extern int SMB2_close_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, · 157 unmodified lines | ||
| 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); |
| @@ -176,7 +176,7 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) · 175 unmodified lines | ||
| 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,21 +185,21 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) · 2 unmodified lines | ||
| 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,7 +215,7 @@ smb2_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) · 9 unmodified lines | ||
| 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,68 +239,69 @@ static int generate_key(struct cifs_ses *ses, struct kvec label, · 17 unmodified lines | ||
| 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 | |
| @@ -436,7 +437,7 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) · 129 unmodified lines | ||
| 436 | 437 | |
| 437 | 438 | ses = smb2_find_smb_ses(server, shdr->SessionId); |
| 438 | 439 | if (!ses) { |
| 439 | − cifs_dbg(VFS, "%s: Could not find session\n", __func__); | |
| 440 | + cifs_server_dbg(VFS, "%s: Could not find session\n", __func__); | |
| 440 | 441 | return 0; |
| 441 | 442 | } |
| 442 | 443 | |
| @@ -446,7 +447,7 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) · 3 unmodified lines | ||
| 446 | 447 | rc = crypto_shash_setkey(server->secmech.cmacaes, |
| 447 | 448 | ses->smb3signingkey, SMB2_CMACAES_SIZE); |
| 448 | 449 | if (rc) { |
| 449 | − cifs_dbg(VFS, "%s: Could not set key for cmac aes\n", __func__); | |
| 450 | + cifs_server_dbg(VFS, "%s: Could not set key for cmac aes\n", __func__); | |
| 450 | 451 | return rc; |
| 451 | 452 | } |
| 452 | 453 | |
| @@ -457,7 +458,7 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) · 4 unmodified lines | ||
| 457 | 458 | */ |
| 458 | 459 | rc = crypto_shash_init(shash); |
| 459 | 460 | if (rc) { |
| 460 | − cifs_dbg(VFS, "%s: Could not init cmac aes\n", __func__); | |
| 461 | + cifs_server_dbg(VFS, "%s: Could not init cmac aes\n", __func__); | |
| 461 | 462 | return rc; |
| 462 | 463 | } |
| 463 | 464 | |
| @@ -473,7 +474,7 @@ smb3_calc_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) · 9 unmodified lines | ||
| 473 | 474 | rc = crypto_shash_update(shash, iov[0].iov_base, |
| 474 | 475 | iov[0].iov_len); |
| 475 | 476 | if (rc) { |
| 476 | − cifs_dbg(VFS, "%s: Could not update with payload\n", | |
| 477 | + cifs_server_dbg(VFS, "%s: Could not update with payload\n", | |
| 477 | 478 | __func__); |
| 478 | 479 | return rc; |
| 479 | 480 | } |
| @@ -521,6 +522,7 @@ smb2_verify_signature(struct smb_rqst *rqst, struct TCP_Server_Info *server) · 41 unmodified lines | ||
| 521 | 522 | if ((shdr->Command == SMB2_NEGOTIATE) || |
| 522 | 523 | (shdr->Command == SMB2_SESSION_SETUP) || |
| 523 | 524 | (shdr->Command == SMB2_OPLOCK_BREAK) || |
| 525 | + server->ignore_signature || | |
| 524 | 526 | (!server->session_estab)) |
| 525 | 527 | return 0; |
| 526 | 528 | |
| @@ -665,7 +667,7 @@ smb2_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server, · 138 unmodified lines | ||
| 665 | 667 | |
| 666 | 668 | rc = smb2_verify_signature(&rqst, server); |
| 667 | 669 | if (rc) |
| 668 | − cifs_dbg(VFS, "SMB signature verification returned error = %d\n", | |
| 670 | + cifs_server_dbg(VFS, "SMB signature verification returned error = %d\n", | |
| 669 | 671 | rc); |
| 670 | 672 | } |
| 671 | 673 | |
| @@ -739,7 +741,7 @@ smb3_crypto_aead_allocate(struct TCP_Server_Info *server) · 67 unmodified lines | ||
| 739 | 741 | else |
| 740 | 742 | tfm = crypto_alloc_aead("ccm(aes)", 0, 0); |
| 741 | 743 | if (IS_ERR(tfm)) { |
| 742 | − cifs_dbg(VFS, "%s: Failed to alloc encrypt aead\n", | |
| 744 | + cifs_server_dbg(VFS, "%s: Failed to alloc encrypt aead\n", | |
| 743 | 745 | __func__); |
| 744 | 746 | return PTR_ERR(tfm); |
| 745 | 747 | } |
| @@ -754,7 +756,7 @@ smb3_crypto_aead_allocate(struct TCP_Server_Info *server) · 8 unmodified lines | ||
| 754 | 756 | if (IS_ERR(tfm)) { |
| 755 | 757 | crypto_free_aead(server->secmech.ccmaesencrypt); |
| 756 | 758 | server->secmech.ccmaesencrypt = NULL; |
| 757 | − cifs_dbg(VFS, "%s: Failed to alloc decrypt aead\n", | |
| 759 | + cifs_server_dbg(VFS, "%s: Failed to alloc decrypt aead\n", | |
| 758 | 760 | __func__); |
| 759 | 761 | return PTR_ERR(tfm); |
| 760 | 762 | } |
| @@ -117,6 +117,41 @@ DEFINE_SMB3_RW_DONE_EVENT(falloc_done); · 116 unmodified lines | ||
| 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, |
| @@ -200,6 +235,8 @@ DEFINE_EVENT(smb3_inf_enter_class, smb3_##name, \ · 77 unmodified lines | ||
| 200 | 235 | |
| 201 | 236 | DEFINE_SMB3_INF_ENTER_EVENT(query_info_enter); |
| 202 | 237 | DEFINE_SMB3_INF_ENTER_EVENT(query_info_done); |
| 238 | +DEFINE_SMB3_INF_ENTER_EVENT(notify_enter); | |
| 239 | +DEFINE_SMB3_INF_ENTER_EVENT(notify_done); | |
| 203 | 240 | |
| 204 | 241 | DECLARE_EVENT_CLASS(smb3_inf_err_class, |
| 205 | 242 | TP_PROTO(unsigned int xid, |
| @@ -246,6 +283,7 @@ DEFINE_EVENT(smb3_inf_err_class, smb3_##name, \ · 40 unmodified lines | ||
| 246 | 283 | |
| 247 | 284 | DEFINE_SMB3_INF_ERR_EVENT(query_info_err); |
| 248 | 285 | DEFINE_SMB3_INF_ERR_EVENT(set_info_err); |
| 286 | +DEFINE_SMB3_INF_ERR_EVENT(notify_err); | |
| 249 | 287 | DEFINE_SMB3_INF_ERR_EVENT(fsctl_err); |
| 250 | 288 | |
| 251 | 289 | DECLARE_EVENT_CLASS(smb3_inf_compound_enter_class, |
| @@ -118,7 +118,7 @@ DeleteMidQEntry(struct mid_q_entry *midEntry) · 117 unmodified lines | ||
| 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,7 +232,7 @@ smb_send_kvec(struct TCP_Server_Info *server, struct msghdr *smb_msg, · 107 unmodified lines | ||
| 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,7 +246,7 @@ smb_send_kvec(struct TCP_Server_Info *server, struct msghdr *smb_msg, · 7 unmodified lines | ||
| 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,7 +440,7 @@ unmask: · 187 unmodified lines | ||
| 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,8 +473,8 @@ smb_send_rqst(struct TCP_Server_Info *server, int num_rqst, · 26 unmodified lines | ||
| 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,6 +532,8 @@ wait_for_free_credits(struct TCP_Server_Info *server, const int num_credits, · 51 unmodified lines | ||
| 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); |
| @@ -548,7 +550,7 @@ wait_for_free_credits(struct TCP_Server_Info *server, const int num_credits, · 10 unmodified lines | ||
| 548 | 550 | if (!rc) { |
| 549 | 551 | trace_smb3_credit_timeout(server->CurrentMid, |
| 550 | 552 | server->hostname, num_credits); |
| 551 | − cifs_dbg(VFS, "wait timed out after %d ms\n", | |
| 553 | + cifs_server_dbg(VFS, "wait timed out after %d ms\n", | |
| 552 | 554 | timeout); |
| 553 | 555 | return -ENOTSUPP; |
| 554 | 556 | } |
| @@ -589,7 +591,7 @@ wait_for_free_credits(struct TCP_Server_Info *server, const int num_credits, · 34 unmodified lines | ||
| 589 | 591 | trace_smb3_credit_timeout( |
| 590 | 592 | server->CurrentMid, |
| 591 | 593 | server->hostname, num_credits); |
| 592 | − cifs_dbg(VFS, "wait timed out after %d ms\n", | |
| 594 | + cifs_server_dbg(VFS, "wait timed out after %d ms\n", | |
| 593 | 595 | timeout); |
| 594 | 596 | return -ENOTSUPP; |
| 595 | 597 | } |
| @@ -608,6 +610,8 @@ wait_for_free_credits(struct TCP_Server_Info *server, const int num_credits, · 12 unmodified lines | ||
| 608 | 610 | if ((flags & CIFS_TIMEOUT_MASK) != CIFS_BLOCKING_OP) { |
| 609 | 611 | *credits -= num_credits; |
| 610 | 612 | server->in_flight += num_credits; |
| 613 | + if (server->in_flight > server->max_in_flight) | |
| 614 | + server->max_in_flight = server->in_flight; | |
| 611 | 615 | *instance = server->reconnect_instance; |
| 612 | 616 | } |
| 613 | 617 | spin_unlock(&server->req_lock); |
| @@ -869,7 +873,7 @@ cifs_sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server) · 255 unmodified lines | ||
| 869 | 873 | break; |
| 870 | 874 | default: |
| 871 | 875 | list_del_init(&mid->qhead); |
| 872 | − cifs_dbg(VFS, "%s: invalid mid state mid=%llu state=%d\n", | |
| 876 | + cifs_server_dbg(VFS, "%s: invalid mid state mid=%llu state=%d\n", | |
| 873 | 877 | __func__, mid->mid, mid->mid_state); |
| 874 | 878 | rc = -EIO; |
| 875 | 879 | } |
| @@ -910,7 +914,7 @@ cifs_check_receive(struct mid_q_entry *mid, struct TCP_Server_Info *server, · 34 unmodified lines | ||
| 910 | 914 | rc = cifs_verify_signature(&rqst, server, |
| 911 | 915 | mid->sequence_number); |
| 912 | 916 | if (rc) |
| 913 | − cifs_dbg(VFS, "SMB signature verification returned error = %d\n", | |
| 917 | + cifs_server_dbg(VFS, "SMB signature verification returned error = %d\n", | |
| 914 | 918 | rc); |
| 915 | 919 | } |
| 916 | 920 | |
| @@ -1107,7 +1111,7 @@ compound_send_recv(const unsigned int xid, struct cifs_ses *ses, · 190 unmodified lines | ||
| 1107 | 1111 | } |
| 1108 | 1112 | if (rc != 0) { |
| 1109 | 1113 | for (; i < num_rqst; i++) { |
| 1110 | − cifs_dbg(VFS, "Cancelling wait for mid %llu cmd: %d\n", | |
| 1114 | + cifs_server_dbg(VFS, "Cancelling wait for mid %llu cmd: %d\n", | |
| 1111 | 1115 | midQ[i]->mid, le16_to_cpu(midQ[i]->command)); |
| 1112 | 1116 | send_cancel(server, &rqst[i], midQ[i]); |
| 1113 | 1117 | spin_lock(&GlobalMid_Lock); |
| @@ -1242,17 +1246,19 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, · 128 unmodified lines | ||
| 1242 | 1246 | struct kvec iov = { .iov_base = in_buf, .iov_len = len }; |
| 1243 | 1247 | struct smb_rqst rqst = { .rq_iov = &iov, .rq_nvec = 1 }; |
| 1244 | 1248 | struct cifs_credits credits = { .value = 1, .instance = 0 }; |
| 1249 | + struct TCP_Server_Info *server; | |
| 1245 | 1250 | |
| 1246 | 1251 | if (ses == NULL) { |
| 1247 | 1252 | cifs_dbg(VFS, "Null smb session\n"); |
| 1248 | 1253 | return -EIO; |
| 1249 | 1254 | } |
| 1250 | − if (ses->server == NULL) { | |
| 1255 | + server = ses->server; | |
| 1256 | + if (server == NULL) { | |
| 1251 | 1257 | cifs_dbg(VFS, "Null tcp session\n"); |
| 1252 | 1258 | return -EIO; |
| 1253 | 1259 | } |
| 1254 | 1260 | |
| 1255 | − if (ses->server->tcpStatus == CifsExiting) | |
| 1261 | + if (server->tcpStatus == CifsExiting) | |
| 1256 | 1262 | return -ENOENT; |
| 1257 | 1263 | |
| 1258 | 1264 | /* Ensure that we do not send more than 50 overlapping requests |
| @@ -1260,12 +1266,12 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, · 1 unmodified line | ||
| 1260 | 1266 | use ses->maxReq */ |
| 1261 | 1267 | |
| 1262 | 1268 | if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { |
| 1263 | − cifs_dbg(VFS, "Illegal length, greater than maximum frame, %d\n", | |
| 1269 | + cifs_server_dbg(VFS, "Illegal length, greater than maximum frame, %d\n", | |
| 1264 | 1270 | len); |
| 1265 | 1271 | return -EIO; |
| 1266 | 1272 | } |
| 1267 | 1273 | |
| 1268 | − rc = wait_for_free_request(ses->server, flags, &credits.instance); | |
| 1274 | + rc = wait_for_free_request(server, flags, &credits.instance); | |
| 1269 | 1275 | if (rc) |
| 1270 | 1276 | return rc; |
| 1271 | 1277 | |
| @@ -1273,70 +1279,70 @@ SendReceive(const unsigned int xid, struct cifs_ses *ses, · 1 unmodified line | ||
| 1273 | 1279 | and avoid races inside tcp sendmsg code that could cause corruption |
| 1274 | 1280 | of smb data */ |
| 1275 | 1281 | |
| 1276 | − mutex_lock(&ses->server->srv_mutex); | |
| 1282 | + mutex_lock(&server->srv_mutex); | |
| 1277 | 1283 | |
| 1278 | 1284 | rc = allocate_mid(ses, in_buf, &midQ); |
| 1279 | 1285 | if (rc) { |
| 1280 | 1286 | mutex_unlock(&ses->server->srv_mutex); |
| 1281 | 1287 | /* Update # of requests on wire to server */ |
| 1282 | − add_credits(ses->server, &credits, 0); | |
| 1288 | + add_credits(server, &credits, 0); | |
| 1283 | 1289 | return rc; |
| 1284 | 1290 | } |
| 1285 | 1291 | |
| 1286 | − rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number); | |
| 1292 | + rc = cifs_sign_smb(in_buf, server, &midQ->sequence_number); | |
| 1287 | 1293 | if (rc) { |
| 1288 | − mutex_unlock(&ses->server->srv_mutex); | |
| 1294 | + mutex_unlock(&server->srv_mutex); | |
| 1289 | 1295 | goto out; |
| 1290 | 1296 | } |
| 1291 | 1297 | |
| 1292 | 1298 | midQ->mid_state = MID_REQUEST_SUBMITTED; |
| 1293 | 1299 | |
| 1294 | − cifs_in_send_inc(ses->server); | |
| 1295 | − rc = smb_send(ses->server, in_buf, len); | |
| 1296 | − cifs_in_send_dec(ses->server); | |
| 1300 | + cifs_in_send_inc(server); | |
| 1301 | + rc = smb_send(server, in_buf, len); | |
| 1302 | + cifs_in_send_dec(server); | |
| 1297 | 1303 | cifs_save_when_sent(midQ); |
| 1298 | 1304 | |
| 1299 | 1305 | if (rc < 0) |
| 1300 | − ses->server->sequence_number -= 2; | |
| 1306 | + server->sequence_number -= 2; | |
| 1301 | 1307 | |
| 1302 | − mutex_unlock(&ses->server->srv_mutex); | |
| 1308 | + mutex_unlock(&server->srv_mutex); | |
| 1303 | 1309 | |
| 1304 | 1310 | if (rc < 0) |
| 1305 | 1311 | goto out; |
| 1306 | 1312 | |
| 1307 | − rc = wait_for_response(ses->server, midQ); | |
| 1313 | + rc = wait_for_response(server, midQ); | |
| 1308 | 1314 | if (rc != 0) { |
| 1309 | − send_cancel(ses->server, &rqst, midQ); | |
| 1315 | + send_cancel(server, &rqst, midQ); | |
| 1310 | 1316 | spin_lock(&GlobalMid_Lock); |
| 1311 | 1317 | if (midQ->mid_state == MID_REQUEST_SUBMITTED) { |
| 1312 | 1318 | /* no longer considered to be "in-flight" */ |
| 1313 | 1319 | midQ->callback = DeleteMidQEntry; |
| 1314 | 1320 | spin_unlock(&GlobalMid_Lock); |
| 1315 | − add_credits(ses->server, &credits, 0); | |
| 1321 | + add_credits(server, &credits, 0); | |
| 1316 | 1322 | return rc; |
| 1317 | 1323 | } |
| 1318 | 1324 | spin_unlock(&GlobalMid_Lock); |
| 1319 | 1325 | } |
| 1320 | 1326 | |
| 1321 | − rc = cifs_sync_mid_result(midQ, ses->server); | |
| 1327 | + rc = cifs_sync_mid_result(midQ, server); | |
| 1322 | 1328 | if (rc != 0) { |
| 1323 | − add_credits(ses->server, &credits, 0); | |
| 1329 | + add_credits(server, &credits, 0); | |
| 1324 | 1330 | return rc; |
| 1325 | 1331 | } |
| 1326 | 1332 | |
| 1327 | 1333 | if (!midQ->resp_buf || !out_buf || |
| 1328 | 1334 | midQ->mid_state != MID_RESPONSE_RECEIVED) { |
| 1329 | 1335 | rc = -EIO; |
| 1330 | − cifs_dbg(VFS, "Bad MID state?\n"); | |
| 1336 | + cifs_server_dbg(VFS, "Bad MID state?\n"); | |
| 1331 | 1337 | goto out; |
| 1332 | 1338 | } |
| 1333 | 1339 | |
| 1334 | 1340 | *pbytes_returned = get_rfc1002_length(midQ->resp_buf); |
| 1335 | 1341 | memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4); |
| 1336 | − rc = cifs_check_receive(midQ, ses->server, 0); | |
| 1342 | + rc = cifs_check_receive(midQ, server, 0); | |
| 1337 | 1343 | out: |
| 1338 | 1344 | cifs_delete_mid(midQ); |
| 1339 | − add_credits(ses->server, &credits, 0); | |
| 1345 | + add_credits(server, &credits, 0); | |
| 1340 | 1346 | |
| 1341 | 1347 | return rc; |
| 1342 | 1348 | } |
| @@ -1379,19 +1385,21 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, · 36 unmodified lines | ||
| 1379 | 1385 | struct kvec iov = { .iov_base = in_buf, .iov_len = len }; |
| 1380 | 1386 | struct smb_rqst rqst = { .rq_iov = &iov, .rq_nvec = 1 }; |
| 1381 | 1387 | unsigned int instance; |
| 1388 | + struct TCP_Server_Info *server; | |
| 1382 | 1389 | |
| 1383 | 1390 | if (tcon == NULL || tcon->ses == NULL) { |
| 1384 | 1391 | cifs_dbg(VFS, "Null smb session\n"); |
| 1385 | 1392 | return -EIO; |
| 1386 | 1393 | } |
| 1387 | 1394 | ses = tcon->ses; |
| 1395 | + server = ses->server; | |
| 1388 | 1396 | |
| 1389 | − if (ses->server == NULL) { | |
| 1397 | + if (server == NULL) { | |
| 1390 | 1398 | cifs_dbg(VFS, "Null tcp session\n"); |
| 1391 | 1399 | return -EIO; |
| 1392 | 1400 | } |
| 1393 | 1401 | |
| 1394 | − if (ses->server->tcpStatus == CifsExiting) | |
| 1402 | + if (server->tcpStatus == CifsExiting) | |
| 1395 | 1403 | return -ENOENT; |
| 1396 | 1404 | |
| 1397 | 1405 | /* Ensure that we do not send more than 50 overlapping requests |
| @@ -1399,12 +1407,12 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, · 1 unmodified line | ||
| 1399 | 1407 | use ses->maxReq */ |
| 1400 | 1408 | |
| 1401 | 1409 | if (len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) { |
| 1402 | − cifs_dbg(VFS, "Illegal length, greater than maximum frame, %d\n", | |
| 1410 | + cifs_tcon_dbg(VFS, "Illegal length, greater than maximum frame, %d\n", | |
| 1403 | 1411 | len); |
| 1404 | 1412 | return -EIO; |
| 1405 | 1413 | } |
| 1406 | 1414 | |
| 1407 | − rc = wait_for_free_request(ses->server, CIFS_BLOCKING_OP, &instance); | |
| 1415 | + rc = wait_for_free_request(server, CIFS_BLOCKING_OP, &instance); | |
| 1408 | 1416 | if (rc) |
| 1409 | 1417 | return rc; |
| 1410 | 1418 | |
| @@ -1412,31 +1420,31 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, · 1 unmodified line | ||
| 1412 | 1420 | and avoid races inside tcp sendmsg code that could cause corruption |
| 1413 | 1421 | of smb data */ |
| 1414 | 1422 | |
| 1415 | − mutex_lock(&ses->server->srv_mutex); | |
| 1423 | + mutex_lock(&server->srv_mutex); | |
| 1416 | 1424 | |
| 1417 | 1425 | rc = allocate_mid(ses, in_buf, &midQ); |
| 1418 | 1426 | if (rc) { |
| 1419 | − mutex_unlock(&ses->server->srv_mutex); | |
| 1427 | + mutex_unlock(&server->srv_mutex); | |
| 1420 | 1428 | return rc; |
| 1421 | 1429 | } |
| 1422 | 1430 | |
| 1423 | − rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number); | |
| 1431 | + rc = cifs_sign_smb(in_buf, server, &midQ->sequence_number); | |
| 1424 | 1432 | if (rc) { |
| 1425 | 1433 | cifs_delete_mid(midQ); |
| 1426 | − mutex_unlock(&ses->server->srv_mutex); | |
| 1434 | + mutex_unlock(&server->srv_mutex); | |
| 1427 | 1435 | return rc; |
| 1428 | 1436 | } |
| 1429 | 1437 | |
| 1430 | 1438 | midQ->mid_state = MID_REQUEST_SUBMITTED; |
| 1431 | − cifs_in_send_inc(ses->server); | |
| 1432 | − rc = smb_send(ses->server, in_buf, len); | |
| 1433 | − cifs_in_send_dec(ses->server); | |
| 1439 | + cifs_in_send_inc(server); | |
| 1440 | + rc = smb_send(server, in_buf, len); | |
| 1441 | + cifs_in_send_dec(server); | |
| 1434 | 1442 | cifs_save_when_sent(midQ); |
| 1435 | 1443 | |
| 1436 | 1444 | if (rc < 0) |
| 1437 | − ses->server->sequence_number -= 2; | |
| 1445 | + server->sequence_number -= 2; | |
| 1438 | 1446 | |
| 1439 | − mutex_unlock(&ses->server->srv_mutex); | |
| 1447 | + mutex_unlock(&server->srv_mutex); | |
| 1440 | 1448 | |
| 1441 | 1449 | if (rc < 0) { |
| 1442 | 1450 | cifs_delete_mid(midQ); |
| @@ -1444,21 +1452,21 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, · 1 unmodified line | ||
| 1444 | 1452 | } |
| 1445 | 1453 | |
| 1446 | 1454 | /* Wait for a reply - allow signals to interrupt. */ |
| 1447 | − rc = wait_event_interruptible(ses->server->response_q, | |
| 1455 | + rc = wait_event_interruptible(server->response_q, | |
| 1448 | 1456 | (!(midQ->mid_state == MID_REQUEST_SUBMITTED)) || |
| 1449 | − ((ses->server->tcpStatus != CifsGood) && | |
| 1450 | − (ses->server->tcpStatus != CifsNew))); | |
| 1457 | + ((server->tcpStatus != CifsGood) && | |
| 1458 | + (server->tcpStatus != CifsNew))); | |
| 1451 | 1459 | |
| 1452 | 1460 | /* Were we interrupted by a signal ? */ |
| 1453 | 1461 | if ((rc == -ERESTARTSYS) && |
| 1454 | 1462 | (midQ->mid_state == MID_REQUEST_SUBMITTED) && |
| 1455 | − ((ses->server->tcpStatus == CifsGood) || | |
| 1456 | − (ses->server->tcpStatus == CifsNew))) { | |
| 1463 | + ((server->tcpStatus == CifsGood) || | |
| 1464 | + (server->tcpStatus == CifsNew))) { | |
| 1457 | 1465 | |
| 1458 | 1466 | if (in_buf->Command == SMB_COM_TRANSACTION2) { |
| 1459 | 1467 | /* POSIX lock. We send a NT_CANCEL SMB to cause the |
| 1460 | 1468 | blocking lock to return. */ |
| 1461 | − rc = send_cancel(ses->server, &rqst, midQ); | |
| 1469 | + rc = send_cancel(server, &rqst, midQ); | |
| 1462 | 1470 | if (rc) { |
| 1463 | 1471 | cifs_delete_mid(midQ); |
| 1464 | 1472 | return rc; |
| @@ -1477,9 +1485,9 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, · 12 unmodified lines | ||
| 1477 | 1485 | } |
| 1478 | 1486 | } |
| 1479 | 1487 | |
| 1480 | − rc = wait_for_response(ses->server, midQ); | |
| 1488 | + rc = wait_for_response(server, midQ); | |
| 1481 | 1489 | if (rc) { |
| 1482 | − send_cancel(ses->server, &rqst, midQ); | |
| 1490 | + send_cancel(server, &rqst, midQ); | |
| 1483 | 1491 | spin_lock(&GlobalMid_Lock); |
| 1484 | 1492 | if (midQ->mid_state == MID_REQUEST_SUBMITTED) { |
| 1485 | 1493 | /* no longer considered to be "in-flight" */ |
| @@ -1494,20 +1502,20 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifs_tcon *tcon, · 8 unmodified lines | ||
| 1494 | 1502 | rstart = 1; |
| 1495 | 1503 | } |
| 1496 | 1504 | |
| 1497 | − rc = cifs_sync_mid_result(midQ, ses->server); | |
| 1505 | + rc = cifs_sync_mid_result(midQ, server); | |
| 1498 | 1506 | if (rc != 0) |
| 1499 | 1507 | return rc; |
| 1500 | 1508 | |
| 1501 | 1509 | /* rcvd frame is ok */ |
| 1502 | 1510 | if (out_buf == NULL || midQ->mid_state != MID_RESPONSE_RECEIVED) { |
| 1503 | 1511 | rc = -EIO; |
| 1504 | − cifs_dbg(VFS, "Bad MID state?\n"); | |
| 1512 | + cifs_tcon_dbg(VFS, "Bad MID state?\n"); | |
| 1505 | 1513 | goto out; |
| 1506 | 1514 | } |
| 1507 | 1515 | |
| 1508 | 1516 | *pbytes_returned = get_rfc1002_length(midQ->resp_buf); |
| 1509 | 1517 | memcpy(out_buf, midQ->resp_buf, *pbytes_returned + 4); |
| 1510 | − rc = cifs_check_receive(midQ, ses->server, 0); | |
| 1518 | + rc = cifs_check_receive(midQ, server, 0); | |
| 1511 | 1519 | out: |
| 1512 | 1520 | cifs_delete_mid(midQ); |
| 1513 | 1521 | if (rstart && rc == -EACCES) |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | ||
| 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), |