diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-24 14:37:18 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-12-24 14:37:18 -0500 |
| commit | 1dd5c6b15372c7c127c509afa9a816bad5feed3b (patch) | |
| tree | 163e4e43d4e8f8fdfb70cc14379e01b5b09b40af | |
| parent | 3a77fa854477a12fc543a69d00ff8a42adefc586 (diff) | |
| parent | 374402a2a1dfbbee8ab1a5a32ec4887bf8c15d52 (diff) | |
Merge branch 'for-next' of git://git.samba.org/sfrench/cifs-2.6
Pull cifs fixes from Steve French:
"This ncludes various cifs/smb3 bug fixes, mostly for stable as well.
In the next week I expect that Germano will have some reconnection
fixes, and also I expect to have the remaining pieces of the snapshot
enablement and SMB3 ACLs, but wanted to get this set of bug fixes in"
* 'for-next' of git://git.samba.org/sfrench/cifs-2.6:
cifs_get_root shouldn't use path with tree name
Fix default behaviour for empty domains and add domainauto option
cifs: use %16phN for formatting md5 sum
cifs: Fix smbencrypt() to stop pointing a scatterlist at the stack
CIFS: Fix a possible double locking of mutex during reconnect
CIFS: Fix a possible memory corruption during reconnect
CIFS: Fix a possible memory corruption in push locks
CIFS: Fix missing nls unload in smb2_reconnect()
CIFS: Decrease verbosity of ioctl call
SMB3: parsing for new snapshot timestamp mount parm
| -rw-r--r-- | fs/cifs/cifsencrypt.c | 14 | ||||
| -rw-r--r-- | fs/cifs/cifsfs.c | 2 | ||||
| -rw-r--r-- | fs/cifs/cifsglob.h | 8 | ||||
| -rw-r--r-- | fs/cifs/cifsproto.h | 6 | ||||
| -rw-r--r-- | fs/cifs/connect.c | 82 | ||||
| -rw-r--r-- | fs/cifs/dir.c | 4 | ||||
| -rw-r--r-- | fs/cifs/file.c | 8 | ||||
| -rw-r--r-- | fs/cifs/ioctl.c | 2 | ||||
| -rw-r--r-- | fs/cifs/link.c | 9 | ||||
| -rw-r--r-- | fs/cifs/smb2file.c | 2 | ||||
| -rw-r--r-- | fs/cifs/smb2pdu.c | 87 | ||||
| -rw-r--r-- | fs/cifs/smb2pdu.h | 2 | ||||
| -rw-r--r-- | fs/cifs/smb2proto.h | 1 | ||||
| -rw-r--r-- | fs/cifs/smbencrypt.c | 40 |
14 files changed, 177 insertions, 90 deletions
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index 5eb04129f938..66bd7fa9b7a6 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c | |||
| @@ -699,11 +699,15 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp) | |||
| 699 | 699 | ||
| 700 | if (ses->server->negflavor == CIFS_NEGFLAVOR_EXTENDED) { | 700 | if (ses->server->negflavor == CIFS_NEGFLAVOR_EXTENDED) { |
| 701 | if (!ses->domainName) { | 701 | if (!ses->domainName) { |
| 702 | rc = find_domain_name(ses, nls_cp); | 702 | if (ses->domainAuto) { |
| 703 | if (rc) { | 703 | rc = find_domain_name(ses, nls_cp); |
| 704 | cifs_dbg(VFS, "error %d finding domain name\n", | 704 | if (rc) { |
| 705 | rc); | 705 | cifs_dbg(VFS, "error %d finding domain name\n", |
| 706 | goto setup_ntlmv2_rsp_ret; | 706 | rc); |
| 707 | goto setup_ntlmv2_rsp_ret; | ||
| 708 | } | ||
| 709 | } else { | ||
| 710 | ses->domainName = kstrdup("", GFP_KERNEL); | ||
| 707 | } | 711 | } |
| 708 | } | 712 | } |
| 709 | } else { | 713 | } else { |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index e6efb9a88598..70f4e65fced2 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
| @@ -615,7 +615,7 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb) | |||
| 615 | return dget(sb->s_root); | 615 | return dget(sb->s_root); |
| 616 | 616 | ||
| 617 | full_path = cifs_build_path_to_root(vol, cifs_sb, | 617 | full_path = cifs_build_path_to_root(vol, cifs_sb, |
| 618 | cifs_sb_master_tcon(cifs_sb)); | 618 | cifs_sb_master_tcon(cifs_sb), 0); |
| 619 | if (full_path == NULL) | 619 | if (full_path == NULL) |
| 620 | return ERR_PTR(-ENOMEM); | 620 | return ERR_PTR(-ENOMEM); |
| 621 | 621 | ||
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 1f17f6bd7a60..7ea8a3393936 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
| @@ -514,6 +514,7 @@ struct smb_vol { | |||
| 514 | bool persistent:1; | 514 | bool persistent:1; |
| 515 | bool nopersistent:1; | 515 | bool nopersistent:1; |
| 516 | bool resilient:1; /* noresilient not required since not fored for CA */ | 516 | bool resilient:1; /* noresilient not required since not fored for CA */ |
| 517 | bool domainauto:1; | ||
| 517 | unsigned int rsize; | 518 | unsigned int rsize; |
| 518 | unsigned int wsize; | 519 | unsigned int wsize; |
| 519 | bool sockopt_tcp_nodelay:1; | 520 | bool sockopt_tcp_nodelay:1; |
| @@ -525,6 +526,7 @@ struct smb_vol { | |||
| 525 | struct sockaddr_storage srcaddr; /* allow binding to a local IP */ | 526 | struct sockaddr_storage srcaddr; /* allow binding to a local IP */ |
| 526 | struct nls_table *local_nls; | 527 | struct nls_table *local_nls; |
| 527 | unsigned int echo_interval; /* echo interval in secs */ | 528 | unsigned int echo_interval; /* echo interval in secs */ |
| 529 | __u64 snapshot_time; /* needed for timewarp tokens */ | ||
| 528 | unsigned int max_credits; /* smb3 max_credits 10 < credits < 60000 */ | 530 | unsigned int max_credits; /* smb3 max_credits 10 < credits < 60000 */ |
| 529 | }; | 531 | }; |
| 530 | 532 | ||
| @@ -646,6 +648,8 @@ struct TCP_Server_Info { | |||
| 646 | unsigned int max_read; | 648 | unsigned int max_read; |
| 647 | unsigned int max_write; | 649 | unsigned int max_write; |
| 648 | __u8 preauth_hash[512]; | 650 | __u8 preauth_hash[512]; |
| 651 | struct delayed_work reconnect; /* reconnect workqueue job */ | ||
| 652 | struct mutex reconnect_mutex; /* prevent simultaneous reconnects */ | ||
| 649 | #endif /* CONFIG_CIFS_SMB2 */ | 653 | #endif /* CONFIG_CIFS_SMB2 */ |
| 650 | unsigned long echo_interval; | 654 | unsigned long echo_interval; |
| 651 | }; | 655 | }; |
| @@ -827,6 +831,7 @@ struct cifs_ses { | |||
| 827 | enum securityEnum sectype; /* what security flavor was specified? */ | 831 | enum securityEnum sectype; /* what security flavor was specified? */ |
| 828 | bool sign; /* is signing required? */ | 832 | bool sign; /* is signing required? */ |
| 829 | bool need_reconnect:1; /* connection reset, uid now invalid */ | 833 | bool need_reconnect:1; /* connection reset, uid now invalid */ |
| 834 | bool domainAuto:1; | ||
| 830 | #ifdef CONFIG_CIFS_SMB2 | 835 | #ifdef CONFIG_CIFS_SMB2 |
| 831 | __u16 session_flags; | 836 | __u16 session_flags; |
| 832 | __u8 smb3signingkey[SMB3_SIGN_KEY_SIZE]; | 837 | __u8 smb3signingkey[SMB3_SIGN_KEY_SIZE]; |
| @@ -849,6 +854,7 @@ cap_unix(struct cifs_ses *ses) | |||
| 849 | struct cifs_tcon { | 854 | struct cifs_tcon { |
| 850 | struct list_head tcon_list; | 855 | struct list_head tcon_list; |
| 851 | int tc_count; | 856 | int tc_count; |
| 857 | struct list_head rlist; /* reconnect list */ | ||
| 852 | struct list_head openFileList; | 858 | struct list_head openFileList; |
| 853 | spinlock_t open_file_lock; /* protects list above */ | 859 | spinlock_t open_file_lock; /* protects list above */ |
| 854 | struct cifs_ses *ses; /* pointer to session associated with */ | 860 | struct cifs_ses *ses; /* pointer to session associated with */ |
| @@ -922,6 +928,7 @@ struct cifs_tcon { | |||
| 922 | bool broken_posix_open; /* e.g. Samba server versions < 3.3.2, 3.2.9 */ | 928 | bool broken_posix_open; /* e.g. Samba server versions < 3.3.2, 3.2.9 */ |
| 923 | bool broken_sparse_sup; /* if server or share does not support sparse */ | 929 | bool broken_sparse_sup; /* if server or share does not support sparse */ |
| 924 | bool need_reconnect:1; /* connection reset, tid now invalid */ | 930 | bool need_reconnect:1; /* connection reset, tid now invalid */ |
| 931 | bool need_reopen_files:1; /* need to reopen tcon file handles */ | ||
| 925 | bool use_resilient:1; /* use resilient instead of durable handles */ | 932 | bool use_resilient:1; /* use resilient instead of durable handles */ |
| 926 | bool use_persistent:1; /* use persistent instead of durable handles */ | 933 | bool use_persistent:1; /* use persistent instead of durable handles */ |
| 927 | #ifdef CONFIG_CIFS_SMB2 | 934 | #ifdef CONFIG_CIFS_SMB2 |
| @@ -932,6 +939,7 @@ struct cifs_tcon { | |||
| 932 | __u32 maximal_access; | 939 | __u32 maximal_access; |
| 933 | __u32 vol_serial_number; | 940 | __u32 vol_serial_number; |
| 934 | __le64 vol_create_time; | 941 | __le64 vol_create_time; |
| 942 | __u64 snapshot_time; /* for timewarp tokens - timestamp of snapshot */ | ||
| 935 | __u32 ss_flags; /* sector size flags */ | 943 | __u32 ss_flags; /* sector size flags */ |
| 936 | __u32 perf_sector_size; /* best sector size for perf */ | 944 | __u32 perf_sector_size; /* best sector size for perf */ |
| 937 | __u32 max_chunks; | 945 | __u32 max_chunks; |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index ced0e42ce460..c7b3c841e660 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
| @@ -63,7 +63,8 @@ extern void exit_cifs_spnego(void); | |||
| 63 | extern char *build_path_from_dentry(struct dentry *); | 63 | extern char *build_path_from_dentry(struct dentry *); |
| 64 | extern char *cifs_build_path_to_root(struct smb_vol *vol, | 64 | extern char *cifs_build_path_to_root(struct smb_vol *vol, |
| 65 | struct cifs_sb_info *cifs_sb, | 65 | struct cifs_sb_info *cifs_sb, |
| 66 | struct cifs_tcon *tcon); | 66 | struct cifs_tcon *tcon, |
| 67 | int add_treename); | ||
| 67 | extern char *build_wildcard_path_from_dentry(struct dentry *direntry); | 68 | extern char *build_wildcard_path_from_dentry(struct dentry *direntry); |
| 68 | extern char *cifs_compose_mount_options(const char *sb_mountdata, | 69 | extern char *cifs_compose_mount_options(const char *sb_mountdata, |
| 69 | const char *fullpath, const struct dfs_info3_param *ref, | 70 | const char *fullpath, const struct dfs_info3_param *ref, |
| @@ -206,6 +207,9 @@ extern void cifs_add_pending_open_locked(struct cifs_fid *fid, | |||
| 206 | struct tcon_link *tlink, | 207 | struct tcon_link *tlink, |
| 207 | struct cifs_pending_open *open); | 208 | struct cifs_pending_open *open); |
| 208 | extern void cifs_del_pending_open(struct cifs_pending_open *open); | 209 | extern void cifs_del_pending_open(struct cifs_pending_open *open); |
| 210 | extern void cifs_put_tcp_session(struct TCP_Server_Info *server, | ||
| 211 | int from_reconnect); | ||
| 212 | extern void cifs_put_tcon(struct cifs_tcon *tcon); | ||
| 209 | 213 | ||
| 210 | #if IS_ENABLED(CONFIG_CIFS_DFS_UPCALL) | 214 | #if IS_ENABLED(CONFIG_CIFS_DFS_UPCALL) |
| 211 | extern void cifs_dfs_release_automount_timer(void); | 215 | extern void cifs_dfs_release_automount_timer(void); |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index f7563c88c917..b822bf364c2b 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
| @@ -53,6 +53,9 @@ | |||
| 53 | #include "nterr.h" | 53 | #include "nterr.h" |
| 54 | #include "rfc1002pdu.h" | 54 | #include "rfc1002pdu.h" |
| 55 | #include "fscache.h" | 55 | #include "fscache.h" |
| 56 | #ifdef CONFIG_CIFS_SMB2 | ||
| 57 | #include "smb2proto.h" | ||
| 58 | #endif | ||
| 56 | 59 | ||
| 57 | #define CIFS_PORT 445 | 60 | #define CIFS_PORT 445 |
| 58 | #define RFC1001_PORT 139 | 61 | #define RFC1001_PORT 139 |
| @@ -89,6 +92,7 @@ enum { | |||
| 89 | Opt_multiuser, Opt_sloppy, Opt_nosharesock, | 92 | Opt_multiuser, Opt_sloppy, Opt_nosharesock, |
| 90 | Opt_persistent, Opt_nopersistent, | 93 | Opt_persistent, Opt_nopersistent, |
| 91 | Opt_resilient, Opt_noresilient, | 94 | Opt_resilient, Opt_noresilient, |
| 95 | Opt_domainauto, | ||
| 92 | 96 | ||
| 93 | /* Mount options which take numeric value */ | 97 | /* Mount options which take numeric value */ |
| 94 | Opt_backupuid, Opt_backupgid, Opt_uid, | 98 | Opt_backupuid, Opt_backupgid, Opt_uid, |
| @@ -96,6 +100,7 @@ enum { | |||
| 96 | Opt_dirmode, Opt_port, | 100 | Opt_dirmode, Opt_port, |
| 97 | Opt_rsize, Opt_wsize, Opt_actimeo, | 101 | Opt_rsize, Opt_wsize, Opt_actimeo, |
| 98 | Opt_echo_interval, Opt_max_credits, | 102 | Opt_echo_interval, Opt_max_credits, |
| 103 | Opt_snapshot, | ||
| 99 | 104 | ||
| 100 | /* Mount options which take string value */ | 105 | /* Mount options which take string value */ |
| 101 | Opt_user, Opt_pass, Opt_ip, | 106 | Opt_user, Opt_pass, Opt_ip, |
| @@ -177,6 +182,7 @@ static const match_table_t cifs_mount_option_tokens = { | |||
| 177 | { Opt_nopersistent, "nopersistenthandles"}, | 182 | { Opt_nopersistent, "nopersistenthandles"}, |
| 178 | { Opt_resilient, "resilienthandles"}, | 183 | { Opt_resilient, "resilienthandles"}, |
| 179 | { Opt_noresilient, "noresilienthandles"}, | 184 | { Opt_noresilient, "noresilienthandles"}, |
| 185 | { Opt_domainauto, "domainauto"}, | ||
| 180 | 186 | ||
| 181 | { Opt_backupuid, "backupuid=%s" }, | 187 | { Opt_backupuid, "backupuid=%s" }, |
| 182 | { Opt_backupgid, "backupgid=%s" }, | 188 | { Opt_backupgid, "backupgid=%s" }, |
| @@ -192,6 +198,7 @@ static const match_table_t cifs_mount_option_tokens = { | |||
| 192 | { Opt_actimeo, "actimeo=%s" }, | 198 | { Opt_actimeo, "actimeo=%s" }, |
| 193 | { Opt_echo_interval, "echo_interval=%s" }, | 199 | { Opt_echo_interval, "echo_interval=%s" }, |
| 194 | { Opt_max_credits, "max_credits=%s" }, | 200 | { Opt_max_credits, "max_credits=%s" }, |
| 201 | { Opt_snapshot, "snapshot=%s" }, | ||
| 195 | 202 | ||
| 196 | { Opt_blank_user, "user=" }, | 203 | { Opt_blank_user, "user=" }, |
| 197 | { Opt_blank_user, "username=" }, | 204 | { Opt_blank_user, "username=" }, |
| @@ -1500,6 +1507,9 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, | |||
| 1500 | case Opt_noresilient: | 1507 | case Opt_noresilient: |
| 1501 | vol->resilient = false; /* already the default */ | 1508 | vol->resilient = false; /* already the default */ |
| 1502 | break; | 1509 | break; |
| 1510 | case Opt_domainauto: | ||
| 1511 | vol->domainauto = true; | ||
| 1512 | break; | ||
| 1503 | 1513 | ||
| 1504 | /* Numeric Values */ | 1514 | /* Numeric Values */ |
| 1505 | case Opt_backupuid: | 1515 | case Opt_backupuid: |
| @@ -1602,6 +1612,14 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, | |||
| 1602 | } | 1612 | } |
| 1603 | vol->echo_interval = option; | 1613 | vol->echo_interval = option; |
| 1604 | break; | 1614 | break; |
| 1615 | case Opt_snapshot: | ||
| 1616 | if (get_option_ul(args, &option)) { | ||
| 1617 | cifs_dbg(VFS, "%s: Invalid snapshot time\n", | ||
| 1618 | __func__); | ||
| 1619 | goto cifs_parse_mount_err; | ||
| 1620 | } | ||
| 1621 | vol->snapshot_time = option; | ||
| 1622 | break; | ||
| 1605 | case Opt_max_credits: | 1623 | case Opt_max_credits: |
| 1606 | if (get_option_ul(args, &option) || (option < 20) || | 1624 | if (get_option_ul(args, &option) || (option < 20) || |
| 1607 | (option > 60000)) { | 1625 | (option > 60000)) { |
| @@ -2101,8 +2119,8 @@ cifs_find_tcp_session(struct smb_vol *vol) | |||
| 2101 | return NULL; | 2119 | return NULL; |
| 2102 | } | 2120 | } |
| 2103 | 2121 | ||
| 2104 | static void | 2122 | void |
| 2105 | cifs_put_tcp_session(struct TCP_Server_Info *server) | 2123 | cifs_put_tcp_session(struct TCP_Server_Info *server, int from_reconnect) |
| 2106 | { | 2124 | { |
| 2107 | struct task_struct *task; | 2125 | struct task_struct *task; |
| 2108 | 2126 | ||
| @@ -2119,6 +2137,19 @@ cifs_put_tcp_session(struct TCP_Server_Info *server) | |||
| 2119 | 2137 | ||
| 2120 | cancel_delayed_work_sync(&server->echo); | 2138 | cancel_delayed_work_sync(&server->echo); |
| 2121 | 2139 | ||
| 2140 | #ifdef CONFIG_CIFS_SMB2 | ||
| 2141 | if (from_reconnect) | ||
| 2142 | /* | ||
| 2143 | * Avoid deadlock here: reconnect work calls | ||
| 2144 | * cifs_put_tcp_session() at its end. Need to be sure | ||
| 2145 | * that reconnect work does nothing with server pointer after | ||
| 2146 | * that step. | ||
| 2147 | */ | ||
| 2148 | cancel_delayed_work(&server->reconnect); | ||
| 2149 | else | ||
| 2150 | cancel_delayed_work_sync(&server->reconnect); | ||
| 2151 | #endif | ||
| 2152 | |||
| 2122 | spin_lock(&GlobalMid_Lock); | 2153 | spin_lock(&GlobalMid_Lock); |
| 2123 | server->tcpStatus = CifsExiting; | 2154 | server->tcpStatus = CifsExiting; |
| 2124 | spin_unlock(&GlobalMid_Lock); | 2155 | spin_unlock(&GlobalMid_Lock); |
| @@ -2183,6 +2214,10 @@ cifs_get_tcp_session(struct smb_vol *volume_info) | |||
| 2183 | INIT_LIST_HEAD(&tcp_ses->tcp_ses_list); | 2214 | INIT_LIST_HEAD(&tcp_ses->tcp_ses_list); |
| 2184 | INIT_LIST_HEAD(&tcp_ses->smb_ses_list); | 2215 | INIT_LIST_HEAD(&tcp_ses->smb_ses_list); |
| 2185 | INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request); | 2216 | INIT_DELAYED_WORK(&tcp_ses->echo, cifs_echo_request); |
| 2217 | #ifdef CONFIG_CIFS_SMB2 | ||
| 2218 | INIT_DELAYED_WORK(&tcp_ses->reconnect, smb2_reconnect_server); | ||
| 2219 | mutex_init(&tcp_ses->reconnect_mutex); | ||
| 2220 | #endif | ||
| 2186 | memcpy(&tcp_ses->srcaddr, &volume_info->srcaddr, | 2221 | memcpy(&tcp_ses->srcaddr, &volume_info->srcaddr, |
| 2187 | sizeof(tcp_ses->srcaddr)); | 2222 | sizeof(tcp_ses->srcaddr)); |
| 2188 | memcpy(&tcp_ses->dstaddr, &volume_info->dstaddr, | 2223 | memcpy(&tcp_ses->dstaddr, &volume_info->dstaddr, |
| @@ -2341,7 +2376,7 @@ cifs_put_smb_ses(struct cifs_ses *ses) | |||
| 2341 | spin_unlock(&cifs_tcp_ses_lock); | 2376 | spin_unlock(&cifs_tcp_ses_lock); |
| 2342 | 2377 | ||
| 2343 | sesInfoFree(ses); | 2378 | sesInfoFree(ses); |
| 2344 | cifs_put_tcp_session(server); | 2379 | cifs_put_tcp_session(server, 0); |
| 2345 | } | 2380 | } |
| 2346 | 2381 | ||
| 2347 | #ifdef CONFIG_KEYS | 2382 | #ifdef CONFIG_KEYS |
| @@ -2515,7 +2550,7 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) | |||
| 2515 | mutex_unlock(&ses->session_mutex); | 2550 | mutex_unlock(&ses->session_mutex); |
| 2516 | 2551 | ||
| 2517 | /* existing SMB ses has a server reference already */ | 2552 | /* existing SMB ses has a server reference already */ |
| 2518 | cifs_put_tcp_session(server); | 2553 | cifs_put_tcp_session(server, 0); |
| 2519 | free_xid(xid); | 2554 | free_xid(xid); |
| 2520 | return ses; | 2555 | return ses; |
| 2521 | } | 2556 | } |
| @@ -2549,6 +2584,8 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) | |||
| 2549 | if (!ses->domainName) | 2584 | if (!ses->domainName) |
| 2550 | goto get_ses_fail; | 2585 | goto get_ses_fail; |
| 2551 | } | 2586 | } |
| 2587 | if (volume_info->domainauto) | ||
| 2588 | ses->domainAuto = volume_info->domainauto; | ||
| 2552 | ses->cred_uid = volume_info->cred_uid; | 2589 | ses->cred_uid = volume_info->cred_uid; |
| 2553 | ses->linux_uid = volume_info->linux_uid; | 2590 | ses->linux_uid = volume_info->linux_uid; |
| 2554 | 2591 | ||
| @@ -2587,7 +2624,7 @@ static int match_tcon(struct cifs_tcon *tcon, const char *unc) | |||
| 2587 | } | 2624 | } |
| 2588 | 2625 | ||
| 2589 | static struct cifs_tcon * | 2626 | static struct cifs_tcon * |
| 2590 | cifs_find_tcon(struct cifs_ses *ses, const char *unc) | 2627 | cifs_find_tcon(struct cifs_ses *ses, struct smb_vol *volume_info) |
| 2591 | { | 2628 | { |
| 2592 | struct list_head *tmp; | 2629 | struct list_head *tmp; |
| 2593 | struct cifs_tcon *tcon; | 2630 | struct cifs_tcon *tcon; |
| @@ -2595,8 +2632,14 @@ cifs_find_tcon(struct cifs_ses *ses, const char *unc) | |||
| 2595 | spin_lock(&cifs_tcp_ses_lock); | 2632 | spin_lock(&cifs_tcp_ses_lock); |
| 2596 | list_for_each(tmp, &ses->tcon_list) { | 2633 | list_for_each(tmp, &ses->tcon_list) { |
| 2597 | tcon = list_entry(tmp, struct cifs_tcon, tcon_list); | 2634 | tcon = list_entry(tmp, struct cifs_tcon, tcon_list); |
| 2598 | if (!match_tcon(tcon, unc)) | 2635 | if (!match_tcon(tcon, volume_info->UNC)) |
| 2599 | continue; | 2636 | continue; |
| 2637 | |||
| 2638 | #ifdef CONFIG_CIFS_SMB2 | ||
| 2639 | if (tcon->snapshot_time != volume_info->snapshot_time) | ||
| 2640 | continue; | ||
| 2641 | #endif /* CONFIG_CIFS_SMB2 */ | ||
| 2642 | |||
| 2600 | ++tcon->tc_count; | 2643 | ++tcon->tc_count; |
| 2601 | spin_unlock(&cifs_tcp_ses_lock); | 2644 | spin_unlock(&cifs_tcp_ses_lock); |
| 2602 | return tcon; | 2645 | return tcon; |
| @@ -2605,7 +2648,7 @@ cifs_find_tcon(struct cifs_ses *ses, const char *unc) | |||
| 2605 | return NULL; | 2648 | return NULL; |
| 2606 | } | 2649 | } |
| 2607 | 2650 | ||
| 2608 | static void | 2651 | void |
| 2609 | cifs_put_tcon(struct cifs_tcon *tcon) | 2652 | cifs_put_tcon(struct cifs_tcon *tcon) |
| 2610 | { | 2653 | { |
| 2611 | unsigned int xid; | 2654 | unsigned int xid; |
| @@ -2637,7 +2680,7 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info) | |||
| 2637 | int rc, xid; | 2680 | int rc, xid; |
| 2638 | struct cifs_tcon *tcon; | 2681 | struct cifs_tcon *tcon; |
| 2639 | 2682 | ||
| 2640 | tcon = cifs_find_tcon(ses, volume_info->UNC); | 2683 | tcon = cifs_find_tcon(ses, volume_info); |
| 2641 | if (tcon) { | 2684 | if (tcon) { |
| 2642 | cifs_dbg(FYI, "Found match on UNC path\n"); | 2685 | cifs_dbg(FYI, "Found match on UNC path\n"); |
| 2643 | /* existing tcon already has a reference */ | 2686 | /* existing tcon already has a reference */ |
| @@ -2658,6 +2701,22 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb_vol *volume_info) | |||
| 2658 | goto out_fail; | 2701 | goto out_fail; |
| 2659 | } | 2702 | } |
| 2660 | 2703 | ||
| 2704 | if (volume_info->snapshot_time) { | ||
| 2705 | #ifdef CONFIG_CIFS_SMB2 | ||
| 2706 | if (ses->server->vals->protocol_id == 0) { | ||
| 2707 | cifs_dbg(VFS, | ||
| 2708 | "Use SMB2 or later for snapshot mount option\n"); | ||
| 2709 | rc = -EOPNOTSUPP; | ||
| 2710 | goto out_fail; | ||
| 2711 | } else | ||
| 2712 | tcon->snapshot_time = volume_info->snapshot_time; | ||
| 2713 | #else | ||
| 2714 | cifs_dbg(VFS, "Snapshot mount option requires SMB2 support\n"); | ||
| 2715 | rc = -EOPNOTSUPP; | ||
| 2716 | goto out_fail; | ||
| 2717 | #endif /* CONFIG_CIFS_SMB2 */ | ||
| 2718 | } | ||
| 2719 | |||
| 2661 | tcon->ses = ses; | 2720 | tcon->ses = ses; |
| 2662 | if (volume_info->password) { | 2721 | if (volume_info->password) { |
| 2663 | tcon->password = kstrdup(volume_info->password, GFP_KERNEL); | 2722 | tcon->password = kstrdup(volume_info->password, GFP_KERNEL); |
| @@ -3707,7 +3766,8 @@ remote_path_check: | |||
| 3707 | /* | 3766 | /* |
| 3708 | * cifs_build_path_to_root works only when we have a valid tcon | 3767 | * cifs_build_path_to_root works only when we have a valid tcon |
| 3709 | */ | 3768 | */ |
| 3710 | full_path = cifs_build_path_to_root(volume_info, cifs_sb, tcon); | 3769 | full_path = cifs_build_path_to_root(volume_info, cifs_sb, tcon, |
| 3770 | tcon->Flags & SMB_SHARE_IS_IN_DFS); | ||
| 3711 | if (full_path == NULL) { | 3771 | if (full_path == NULL) { |
| 3712 | rc = -ENOMEM; | 3772 | rc = -ENOMEM; |
| 3713 | goto mount_fail_check; | 3773 | goto mount_fail_check; |
| @@ -3793,7 +3853,7 @@ mount_fail_check: | |||
| 3793 | else if (ses) | 3853 | else if (ses) |
| 3794 | cifs_put_smb_ses(ses); | 3854 | cifs_put_smb_ses(ses); |
| 3795 | else | 3855 | else |
| 3796 | cifs_put_tcp_session(server); | 3856 | cifs_put_tcp_session(server, 0); |
| 3797 | bdi_destroy(&cifs_sb->bdi); | 3857 | bdi_destroy(&cifs_sb->bdi); |
| 3798 | } | 3858 | } |
| 3799 | 3859 | ||
| @@ -4104,7 +4164,7 @@ cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid) | |||
| 4104 | ses = cifs_get_smb_ses(master_tcon->ses->server, vol_info); | 4164 | ses = cifs_get_smb_ses(master_tcon->ses->server, vol_info); |
| 4105 | if (IS_ERR(ses)) { | 4165 | if (IS_ERR(ses)) { |
| 4106 | tcon = (struct cifs_tcon *)ses; | 4166 | tcon = (struct cifs_tcon *)ses; |
| 4107 | cifs_put_tcp_session(master_tcon->ses->server); | 4167 | cifs_put_tcp_session(master_tcon->ses->server, 0); |
| 4108 | goto out; | 4168 | goto out; |
| 4109 | } | 4169 | } |
| 4110 | 4170 | ||
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 789ff1df2d8d..2c227a99f369 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
| @@ -47,7 +47,7 @@ renew_parental_timestamps(struct dentry *direntry) | |||
| 47 | 47 | ||
| 48 | char * | 48 | char * |
| 49 | cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb, | 49 | cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb, |
| 50 | struct cifs_tcon *tcon) | 50 | struct cifs_tcon *tcon, int add_treename) |
| 51 | { | 51 | { |
| 52 | int pplen = vol->prepath ? strlen(vol->prepath) + 1 : 0; | 52 | int pplen = vol->prepath ? strlen(vol->prepath) + 1 : 0; |
| 53 | int dfsplen; | 53 | int dfsplen; |
| @@ -59,7 +59,7 @@ cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb, | |||
| 59 | return full_path; | 59 | return full_path; |
| 60 | } | 60 | } |
| 61 | 61 | ||
| 62 | if (tcon->Flags & SMB_SHARE_IS_IN_DFS) | 62 | if (add_treename) |
| 63 | dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1); | 63 | dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1); |
| 64 | else | 64 | else |
| 65 | dfsplen = 0; | 65 | dfsplen = 0; |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 7f5f6176c6f1..18a1e1d6671f 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
| @@ -777,6 +777,11 @@ cifs_reopen_persistent_handles(struct cifs_tcon *tcon) | |||
| 777 | struct list_head *tmp1; | 777 | struct list_head *tmp1; |
| 778 | struct list_head tmp_list; | 778 | struct list_head tmp_list; |
| 779 | 779 | ||
| 780 | if (!tcon->use_persistent || !tcon->need_reopen_files) | ||
| 781 | return; | ||
| 782 | |||
| 783 | tcon->need_reopen_files = false; | ||
| 784 | |||
| 780 | cifs_dbg(FYI, "Reopen persistent handles"); | 785 | cifs_dbg(FYI, "Reopen persistent handles"); |
| 781 | INIT_LIST_HEAD(&tmp_list); | 786 | INIT_LIST_HEAD(&tmp_list); |
| 782 | 787 | ||
| @@ -793,7 +798,8 @@ cifs_reopen_persistent_handles(struct cifs_tcon *tcon) | |||
| 793 | 798 | ||
| 794 | list_for_each_safe(tmp, tmp1, &tmp_list) { | 799 | list_for_each_safe(tmp, tmp1, &tmp_list) { |
| 795 | open_file = list_entry(tmp, struct cifsFileInfo, rlist); | 800 | open_file = list_entry(tmp, struct cifsFileInfo, rlist); |
| 796 | cifs_reopen_file(open_file, false /* do not flush */); | 801 | if (cifs_reopen_file(open_file, false /* do not flush */)) |
| 802 | tcon->need_reopen_files = true; | ||
| 797 | list_del_init(&open_file->rlist); | 803 | list_del_init(&open_file->rlist); |
| 798 | cifsFileInfo_put(open_file); | 804 | cifsFileInfo_put(open_file); |
| 799 | } | 805 | } |
diff --git a/fs/cifs/ioctl.c b/fs/cifs/ioctl.c index 9f51b81119f2..001528781b6b 100644 --- a/fs/cifs/ioctl.c +++ b/fs/cifs/ioctl.c | |||
| @@ -189,7 +189,7 @@ long cifs_ioctl(struct file *filep, unsigned int command, unsigned long arg) | |||
| 189 | xid = get_xid(); | 189 | xid = get_xid(); |
| 190 | 190 | ||
| 191 | cifs_sb = CIFS_SB(inode->i_sb); | 191 | cifs_sb = CIFS_SB(inode->i_sb); |
| 192 | cifs_dbg(VFS, "cifs ioctl 0x%x\n", command); | 192 | cifs_dbg(FYI, "cifs ioctl 0x%x\n", command); |
| 193 | switch (command) { | 193 | switch (command) { |
| 194 | case FS_IOC_GETFLAGS: | 194 | case FS_IOC_GETFLAGS: |
| 195 | if (pSMBFile == NULL) | 195 | if (pSMBFile == NULL) |
diff --git a/fs/cifs/link.c b/fs/cifs/link.c index d031af8d3d4d..c4d996f78e1c 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c | |||
| @@ -45,13 +45,8 @@ | |||
| 45 | (CIFS_MF_SYMLINK_LINK_OFFSET + CIFS_MF_SYMLINK_LINK_MAXLEN) | 45 | (CIFS_MF_SYMLINK_LINK_OFFSET + CIFS_MF_SYMLINK_LINK_MAXLEN) |
| 46 | 46 | ||
| 47 | #define CIFS_MF_SYMLINK_LEN_FORMAT "XSym\n%04u\n" | 47 | #define CIFS_MF_SYMLINK_LEN_FORMAT "XSym\n%04u\n" |
| 48 | #define CIFS_MF_SYMLINK_MD5_FORMAT \ | 48 | #define CIFS_MF_SYMLINK_MD5_FORMAT "%16phN\n" |
| 49 | "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x\n" | 49 | #define CIFS_MF_SYMLINK_MD5_ARGS(md5_hash) md5_hash |
| 50 | #define CIFS_MF_SYMLINK_MD5_ARGS(md5_hash) \ | ||
| 51 | md5_hash[0], md5_hash[1], md5_hash[2], md5_hash[3], \ | ||
| 52 | md5_hash[4], md5_hash[5], md5_hash[6], md5_hash[7], \ | ||
| 53 | md5_hash[8], md5_hash[9], md5_hash[10], md5_hash[11],\ | ||
| 54 | md5_hash[12], md5_hash[13], md5_hash[14], md5_hash[15] | ||
| 55 | 50 | ||
| 56 | static int | 51 | static int |
| 57 | symlink_hash(unsigned int link_len, const char *link_str, u8 *md5_hash) | 52 | symlink_hash(unsigned int link_len, const char *link_str, u8 *md5_hash) |
diff --git a/fs/cifs/smb2file.c b/fs/cifs/smb2file.c index f9e766f464be..b2aff0c6f22c 100644 --- a/fs/cifs/smb2file.c +++ b/fs/cifs/smb2file.c | |||
| @@ -260,7 +260,7 @@ smb2_push_mandatory_locks(struct cifsFileInfo *cfile) | |||
| 260 | * and check it for zero before using. | 260 | * and check it for zero before using. |
| 261 | */ | 261 | */ |
| 262 | max_buf = tlink_tcon(cfile->tlink)->ses->server->maxBuf; | 262 | max_buf = tlink_tcon(cfile->tlink)->ses->server->maxBuf; |
| 263 | if (!max_buf) { | 263 | if (max_buf < sizeof(struct smb2_lock_element)) { |
| 264 | free_xid(xid); | 264 | free_xid(xid); |
| 265 | return -EINVAL; | 265 | return -EINVAL; |
| 266 | } | 266 | } |
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 5ca5ea4668a1..87457227812c 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c | |||
| @@ -250,16 +250,19 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon) | |||
| 250 | } | 250 | } |
| 251 | 251 | ||
| 252 | cifs_mark_open_files_invalid(tcon); | 252 | cifs_mark_open_files_invalid(tcon); |
| 253 | if (tcon->use_persistent) | ||
| 254 | tcon->need_reopen_files = true; | ||
| 253 | 255 | ||
| 254 | rc = SMB2_tcon(0, tcon->ses, tcon->treeName, tcon, nls_codepage); | 256 | rc = SMB2_tcon(0, tcon->ses, tcon->treeName, tcon, nls_codepage); |
| 255 | mutex_unlock(&tcon->ses->session_mutex); | 257 | mutex_unlock(&tcon->ses->session_mutex); |
| 256 | 258 | ||
| 257 | if (tcon->use_persistent) | ||
| 258 | cifs_reopen_persistent_handles(tcon); | ||
| 259 | |||
| 260 | cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc); | 259 | cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc); |
| 261 | if (rc) | 260 | if (rc) |
| 262 | goto out; | 261 | goto out; |
| 262 | |||
| 263 | if (smb2_command != SMB2_INTERNAL_CMD) | ||
| 264 | queue_delayed_work(cifsiod_wq, &server->reconnect, 0); | ||
| 265 | |||
| 263 | atomic_inc(&tconInfoReconnectCount); | 266 | atomic_inc(&tconInfoReconnectCount); |
| 264 | out: | 267 | out: |
| 265 | /* | 268 | /* |
| @@ -280,7 +283,7 @@ out: | |||
| 280 | case SMB2_CHANGE_NOTIFY: | 283 | case SMB2_CHANGE_NOTIFY: |
| 281 | case SMB2_QUERY_INFO: | 284 | case SMB2_QUERY_INFO: |
| 282 | case SMB2_SET_INFO: | 285 | case SMB2_SET_INFO: |
| 283 | return -EAGAIN; | 286 | rc = -EAGAIN; |
| 284 | } | 287 | } |
| 285 | unload_nls(nls_codepage); | 288 | unload_nls(nls_codepage); |
| 286 | return rc; | 289 | return rc; |
| @@ -1972,6 +1975,55 @@ smb2_echo_callback(struct mid_q_entry *mid) | |||
| 1972 | add_credits(server, credits_received, CIFS_ECHO_OP); | 1975 | add_credits(server, credits_received, CIFS_ECHO_OP); |
| 1973 | } | 1976 | } |
| 1974 | 1977 | ||
| 1978 | void smb2_reconnect_server(struct work_struct *work) | ||
| 1979 | { | ||
| 1980 | struct TCP_Server_Info *server = container_of(work, | ||
| 1981 | struct TCP_Server_Info, reconnect.work); | ||
| 1982 | struct cifs_ses *ses; | ||
| 1983 | struct cifs_tcon *tcon, *tcon2; | ||
| 1984 | struct list_head tmp_list; | ||
| 1985 | int tcon_exist = false; | ||
| 1986 | |||
| 1987 | /* Prevent simultaneous reconnects that can corrupt tcon->rlist list */ | ||
| 1988 | mutex_lock(&server->reconnect_mutex); | ||
| 1989 | |||
| 1990 | INIT_LIST_HEAD(&tmp_list); | ||
| 1991 | cifs_dbg(FYI, "Need negotiate, reconnecting tcons\n"); | ||
| 1992 | |||
| 1993 | spin_lock(&cifs_tcp_ses_lock); | ||
| 1994 | list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) { | ||
| 1995 | list_for_each_entry(tcon, &ses->tcon_list, tcon_list) { | ||
| 1996 | if (tcon->need_reconnect || tcon->need_reopen_files) { | ||
| 1997 | tcon->tc_count++; | ||
| 1998 | list_add_tail(&tcon->rlist, &tmp_list); | ||
| 1999 | tcon_exist = true; | ||
| 2000 | } | ||
| 2001 | } | ||
| 2002 | } | ||
| 2003 | /* | ||
| 2004 | * Get the reference to server struct to be sure that the last call of | ||
| 2005 | * cifs_put_tcon() in the loop below won't release the server pointer. | ||
| 2006 | */ | ||
| 2007 | if (tcon_exist) | ||
| 2008 | server->srv_count++; | ||
| 2009 | |||
| 2010 | spin_unlock(&cifs_tcp_ses_lock); | ||
| 2011 | |||
| 2012 | list_for_each_entry_safe(tcon, tcon2, &tmp_list, rlist) { | ||
| 2013 | if (!smb2_reconnect(SMB2_INTERNAL_CMD, tcon)) | ||
| 2014 | cifs_reopen_persistent_handles(tcon); | ||
| 2015 | list_del_init(&tcon->rlist); | ||
| 2016 | cifs_put_tcon(tcon); | ||
| 2017 | } | ||
| 2018 | |||
| 2019 | cifs_dbg(FYI, "Reconnecting tcons finished\n"); | ||
| 2020 | mutex_unlock(&server->reconnect_mutex); | ||
| 2021 | |||
| 2022 | /* now we can safely release srv struct */ | ||
| 2023 | if (tcon_exist) | ||
| 2024 | cifs_put_tcp_session(server, 1); | ||
| 2025 | } | ||
| 2026 | |||
| 1975 | int | 2027 | int |
| 1976 | SMB2_echo(struct TCP_Server_Info *server) | 2028 | SMB2_echo(struct TCP_Server_Info *server) |
| 1977 | { | 2029 | { |
| @@ -1984,32 +2036,11 @@ SMB2_echo(struct TCP_Server_Info *server) | |||
| 1984 | cifs_dbg(FYI, "In echo request\n"); | 2036 | cifs_dbg(FYI, "In echo request\n"); |
| 1985 | 2037 | ||
| 1986 | if (server->tcpStatus == CifsNeedNegotiate) { | 2038 | if (server->tcpStatus == CifsNeedNegotiate) { |
| 1987 | struct list_head *tmp, *tmp2; | 2039 | /* No need to send echo on newly established connections */ |
| 1988 | struct cifs_ses *ses; | 2040 | queue_delayed_work(cifsiod_wq, &server->reconnect, 0); |
| 1989 | struct cifs_tcon *tcon; | 2041 | return rc; |
| 1990 | |||
| 1991 | cifs_dbg(FYI, "Need negotiate, reconnecting tcons\n"); | ||
| 1992 | spin_lock(&cifs_tcp_ses_lock); | ||
| 1993 | list_for_each(tmp, &server->smb_ses_list) { | ||
| 1994 | ses = list_entry(tmp, struct cifs_ses, smb_ses_list); | ||
| 1995 | list_for_each(tmp2, &ses->tcon_list) { | ||
| 1996 | tcon = list_entry(tmp2, struct cifs_tcon, | ||
| 1997 | tcon_list); | ||
| 1998 | /* add check for persistent handle reconnect */ | ||
| 1999 | if (tcon && tcon->need_reconnect) { | ||
| 2000 | spin_unlock(&cifs_tcp_ses_lock); | ||
| 2001 | rc = smb2_reconnect(SMB2_ECHO, tcon); | ||
| 2002 | spin_lock(&cifs_tcp_ses_lock); | ||
| 2003 | } | ||
| 2004 | } | ||
| 2005 | } | ||
| 2006 | spin_unlock(&cifs_tcp_ses_lock); | ||
| 2007 | } | 2042 | } |
| 2008 | 2043 | ||
| 2009 | /* if no session, renegotiate failed above */ | ||
| 2010 | if (server->tcpStatus == CifsNeedNegotiate) | ||
| 2011 | return -EIO; | ||
| 2012 | |||
| 2013 | rc = small_smb2_init(SMB2_ECHO, NULL, (void **)&req); | 2044 | rc = small_smb2_init(SMB2_ECHO, NULL, (void **)&req); |
| 2014 | if (rc) | 2045 | if (rc) |
| 2015 | return rc; | 2046 | return rc; |
diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index fd3709e8de33..dc0d141f33e2 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h | |||
| @@ -80,6 +80,8 @@ | |||
| 80 | #define SMB2_SET_INFO cpu_to_le16(SMB2_SET_INFO_HE) | 80 | #define SMB2_SET_INFO cpu_to_le16(SMB2_SET_INFO_HE) |
| 81 | #define SMB2_OPLOCK_BREAK cpu_to_le16(SMB2_OPLOCK_BREAK_HE) | 81 | #define SMB2_OPLOCK_BREAK cpu_to_le16(SMB2_OPLOCK_BREAK_HE) |
| 82 | 82 | ||
| 83 | #define SMB2_INTERNAL_CMD cpu_to_le16(0xFFFF) | ||
| 84 | |||
| 83 | #define NUMBER_OF_SMB2_COMMANDS 0x0013 | 85 | #define NUMBER_OF_SMB2_COMMANDS 0x0013 |
| 84 | 86 | ||
| 85 | /* BB FIXME - analyze following length BB */ | 87 | /* BB FIXME - analyze following length BB */ |
diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h index eb2cde2f64ba..f2d511a6971b 100644 --- a/fs/cifs/smb2proto.h +++ b/fs/cifs/smb2proto.h | |||
| @@ -96,6 +96,7 @@ extern int smb2_open_file(const unsigned int xid, | |||
| 96 | extern int smb2_unlock_range(struct cifsFileInfo *cfile, | 96 | extern int smb2_unlock_range(struct cifsFileInfo *cfile, |
| 97 | struct file_lock *flock, const unsigned int xid); | 97 | struct file_lock *flock, const unsigned int xid); |
| 98 | extern int smb2_push_mandatory_locks(struct cifsFileInfo *cfile); | 98 | extern int smb2_push_mandatory_locks(struct cifsFileInfo *cfile); |
| 99 | extern void smb2_reconnect_server(struct work_struct *work); | ||
| 99 | 100 | ||
| 100 | /* | 101 | /* |
| 101 | * SMB2 Worker functions - most of protocol specific implementation details | 102 | * SMB2 Worker functions - most of protocol specific implementation details |
diff --git a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c index 699b7868108f..c12bffefa3c9 100644 --- a/fs/cifs/smbencrypt.c +++ b/fs/cifs/smbencrypt.c | |||
| @@ -23,7 +23,7 @@ | |||
| 23 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 23 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| 24 | */ | 24 | */ |
| 25 | 25 | ||
| 26 | #include <crypto/skcipher.h> | 26 | #include <linux/crypto.h> |
| 27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
| 28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
| 29 | #include <linux/fs.h> | 29 | #include <linux/fs.h> |
| @@ -69,46 +69,22 @@ str_to_key(unsigned char *str, unsigned char *key) | |||
| 69 | static int | 69 | static int |
| 70 | smbhash(unsigned char *out, const unsigned char *in, unsigned char *key) | 70 | smbhash(unsigned char *out, const unsigned char *in, unsigned char *key) |
| 71 | { | 71 | { |
| 72 | int rc; | ||
| 73 | unsigned char key2[8]; | 72 | unsigned char key2[8]; |
| 74 | struct crypto_skcipher *tfm_des; | 73 | struct crypto_cipher *tfm_des; |
| 75 | struct scatterlist sgin, sgout; | ||
| 76 | struct skcipher_request *req; | ||
| 77 | 74 | ||
| 78 | str_to_key(key, key2); | 75 | str_to_key(key, key2); |
| 79 | 76 | ||
| 80 | tfm_des = crypto_alloc_skcipher("ecb(des)", 0, CRYPTO_ALG_ASYNC); | 77 | tfm_des = crypto_alloc_cipher("des", 0, 0); |
| 81 | if (IS_ERR(tfm_des)) { | 78 | if (IS_ERR(tfm_des)) { |
| 82 | rc = PTR_ERR(tfm_des); | ||
| 83 | cifs_dbg(VFS, "could not allocate des crypto API\n"); | ||
| 84 | goto smbhash_err; | ||
| 85 | } | ||
| 86 | |||
| 87 | req = skcipher_request_alloc(tfm_des, GFP_KERNEL); | ||
| 88 | if (!req) { | ||
| 89 | rc = -ENOMEM; | ||
| 90 | cifs_dbg(VFS, "could not allocate des crypto API\n"); | 79 | cifs_dbg(VFS, "could not allocate des crypto API\n"); |
| 91 | goto smbhash_free_skcipher; | 80 | return PTR_ERR(tfm_des); |
| 92 | } | 81 | } |
| 93 | 82 | ||
| 94 | crypto_skcipher_setkey(tfm_des, key2, 8); | 83 | crypto_cipher_setkey(tfm_des, key2, 8); |
| 95 | 84 | crypto_cipher_encrypt_one(tfm_des, out, in); | |
| 96 | sg_init_one(&sgin, in, 8); | 85 | crypto_free_cipher(tfm_des); |
| 97 | sg_init_one(&sgout, out, 8); | ||
| 98 | 86 | ||
| 99 | skcipher_request_set_callback(req, 0, NULL, NULL); | 87 | return 0; |
| 100 | skcipher_request_set_crypt(req, &sgin, &sgout, 8, NULL); | ||
| 101 | |||
| 102 | rc = crypto_skcipher_encrypt(req); | ||
| 103 | if (rc) | ||
| 104 | cifs_dbg(VFS, "could not encrypt crypt key rc: %d\n", rc); | ||
| 105 | |||
| 106 | skcipher_request_free(req); | ||
| 107 | |||
| 108 | smbhash_free_skcipher: | ||
| 109 | crypto_free_skcipher(tfm_des); | ||
| 110 | smbhash_err: | ||
| 111 | return rc; | ||
| 112 | } | 88 | } |
| 113 | 89 | ||
| 114 | static int | 90 | static int |
